#include #include #include "skinrepo.h" #include "helpers.h" using namespace std; // --- cSkinRepo ------------------------------------------------------------- cSkinRepo::cSkinRepo(void) { name = ""; repoType = rtUndefined; action = eaUndefined; url = ""; author = "unknown"; minSDVersion = "0.0.1"; command = ""; command2 = ""; tempfile = ""; result = -1; skinPath = ""; themesPath = ""; } cSkinRepo::~cSkinRepo() { } bool cSkinRepo::Valid(void) { if (!name.size()) return false; if (repoType == rtUndefined) return false; if (!url.size()) return false; return true; } void cSkinRepo::Install(string path, string themesPath) { if (Running()) return; action = eaInstall; this->skinPath = path + name; this->themesPath = themesPath; if (repoType == rtGit) { command = *cString::sprintf("git clone --depth=1 --progress %s %s", url.c_str(), skinPath.c_str()); tempfile = *cString::sprintf("gitclone_%s_%ld.out", name.c_str(), time(0)); dsyslog("skindesigner: installing skin from Git, command: %s, logfile: %s", command.c_str(), tempfile.c_str()); Start(); } else if (repoType == rtZipUrl) { size_t hit = url.find_last_of('/'); if (hit == string::npos) return; string filename = url.substr(hit+1); command = *cString::sprintf("wget -P /tmp/ %s", url.c_str()); command2 = *cString::sprintf("unzip /tmp/%s -d %s", filename.c_str(), path.c_str()); dsyslog("skindesigner: installing skin from Zip, command: %s, %s", command.c_str(), command2.c_str()); Start(); } } void cSkinRepo::Update(string path) { if (Running()) return; action = eaUpdate; this->skinPath = path + name; if (repoType == rtGit) { command = *cString::sprintf("cd %s; git pull", skinPath.c_str()); tempfile = *cString::sprintf("gitpull_%s_%ld.out", name.c_str(), time(0)); dsyslog("skindesigner: updating skin from Git, command: %s, logfile: /tmp/%s", command.c_str(), tempfile.c_str()); Start(); } else if (repoType == rtZipUrl) { //TODO } } void cSkinRepo::Action(void) { if (command.size() < 1) return; if (tempfile.size() > 0) { command = *cString::sprintf("%s > /tmp/%s 2>&1", command.c_str(), tempfile.c_str()); } result = system (command.c_str()); if (result == 0 && command2.size() > 0) { result = system (command2.c_str()); } if (result == 0) { if (action == eaInstall) CreateThemeFiles(); dsyslog("skindesigner: %s successfully executed", command.c_str()); } else { esyslog("skindesigner: ERROR executing %s", command.c_str()); } } void cSkinRepo::CreateThemeFiles(void) { string availableThemesPath = skinPath + "/themes/"; DIR *folder = NULL; struct dirent *dirEntry; folder = opendir(availableThemesPath.c_str()); if (!folder) { return; } vector skinThemes; while (dirEntry = readdir(folder)) { string dirEntryName = dirEntry->d_name; int dirEntryType = dirEntry->d_type; if (!dirEntryName.compare(".") || !dirEntryName.compare("..") || dirEntryType != DT_DIR) continue; skinThemes.push_back(dirEntryName); } for (vector::iterator it = skinThemes.begin(); it != skinThemes.end(); it++) { string themeName = *it; string themeFileName = themesPath; themeFileName += name + "-" + themeName + ".theme"; if (FileExists(themeFileName)) { continue; } ofstream themeFile (themeFileName.c_str()); if (themeFile.is_open()) { themeFile << "Description = "; themeFile << themeName << "\n"; themeFile.close(); } } } bool cSkinRepo::SuccessfullyUpdated(void) { string logfilePath = "/tmp/" + tempfile; bool updated = true; string line; ifstream logfile(logfilePath.c_str()); if (logfile.is_open()) { while ( getline (logfile, line) ) { if (line.find("up-to-date") != string::npos) { updated = false; break; } } logfile.close(); } return updated; } void cSkinRepo::Debug() { string strRepoType = "Undefined"; if (repoType == rtGit) strRepoType = "Git"; else if (repoType == rtZipUrl) strRepoType = "ZipUrl"; dsyslog("skindesigner: --- skinrepo %s, Type %s ---", name.c_str(), strRepoType.c_str()); dsyslog("skindesigner: url %s", url.c_str()); dsyslog("skindesigner: author %s", author.c_str()); dsyslog("skindesigner: minimum Skindesigner Version required %s", minSDVersion.c_str()); if (specialFonts.size() > 0) { for (vector::iterator it = specialFonts.begin(); it != specialFonts.end(); it++) { dsyslog("skindesigner: special font %s", (*it).c_str()); } } if (supportedPlugins.size() > 0) { for (vector::iterator it = supportedPlugins.begin(); it != supportedPlugins.end(); it++) { dsyslog("skindesigner: supported plugin %s", (*it).c_str()); } } if (screenshots.size() > 0) { for (vector >::iterator it = screenshots.begin(); it != screenshots.end(); it++) { string desc = (it->first).c_str(); string url = (it->second).c_str(); dsyslog("skindesigner: screenshot \"%s\", url %s", desc.c_str(), url.c_str()); } } } // --- cSkinRepos ------------------------------------------------------------- cSkinRepos::cSkinRepos(void) { skinRepoUrl = "https://github.com/louisbraun/skinrepository.git"; repoFolder = "skinrepositories/"; } cSkinRepos::~cSkinRepos() { for (vector::iterator it = repos.begin(); it != repos.end(); it++) { delete (*it); } } void cSkinRepos::Init(string path) { string repoPath = path + repoFolder; if (FolderExists(repoPath)) { PullRepoGit(repoPath); } else { InitRepoGit(repoPath); } } void cSkinRepos::Read(string path) { string repoPath = path + repoFolder; DIR *folder = NULL; struct dirent *dirEntry; folder = opendir(repoPath.c_str()); if (!folder) { esyslog("skindesigner: no skinrepository folder available in %s", repoPath.c_str()); return; } while (dirEntry = readdir(folder)) { string fileName = dirEntry->d_name; if (!fileName.compare(".") || !fileName.compare("..") || !fileName.compare(".git")) continue; string filePath = repoPath + fileName; if (! ReadXMLFile(filePath.c_str(), false) ) { esyslog("skindesigner: error reading skinrepo %s", filePath.c_str()); continue; } if (! SetDocument() ) continue; if (!ParseRepository()) esyslog("skindesigner: error parsing skinrepository %s", filePath.c_str()); DeleteDocument(); } } cSkinRepo *cSkinRepos::GetRepo(string name) { for (vector::iterator it = repos.begin(); it != repos.end(); it++) { cSkinRepo *repo = (*it); if (!name.compare(repo->Name())) return repo; } return NULL; } cSkinRepo *cSkinRepos::GetNextRepo(void) { if (repoIt == repos.end()) return NULL; cSkinRepo *repo = *repoIt; repoIt++; return repo; } void cSkinRepos::Debug(void) { for (vector::iterator it = repos.begin(); it != repos.end(); it++) { (*it)->Debug(); } } bool cSkinRepos::ParseRepository(void) { if (!LevelDown()) return false; cSkinRepo *repo = new cSkinRepo(); do { string value = ""; if (CheckNodeName("name")) { if (GetNodeValue(value)) { repo->SetName(value); } } else if (CheckNodeName("type")) { if (GetNodeValue(value)) { eRepoType repoType = rtUndefined; if (!value.compare("git")) repoType = rtGit; else if (!value.compare("zip")) repoType = rtZipUrl; repo->SetRepoType(repoType); } } else if (CheckNodeName("url")) { if (GetNodeValue(value)) { repo->SetUrl(value); } } else if (CheckNodeName("author")) { if (GetNodeValue(value)) { repo->SetAuthor(value); } } else if (CheckNodeName("minimumskindesignerversion")) { if (GetNodeValue(value)) { repo->SetMinSDVersion(value); } } else if (CheckNodeName("specialfonts")) { if (!LevelDown()) continue; do { if (CheckNodeName("font")) { if (GetNodeValue(value)) { repo->SetSpecialFont(value); } } } while (NextNode()); LevelUp(); } else if (CheckNodeName("supportedplugins")) { if (!LevelDown()) continue; do { if (CheckNodeName("plugin")) { if (GetNodeValue(value)) { repo->SetSupportedPlugin(value); } } } while (NextNode()); LevelUp(); } else if (CheckNodeName("screenshots")) { if (!LevelDown()) { continue; } do { if (CheckNodeName("screenshot")) { if (!LevelDown()) { continue; } string desc = ""; string url = ""; do { if (CheckNodeName("description")) { GetNodeValue(desc); } else if (CheckNodeName("url")) { GetNodeValue(url); } } while (NextNode()); LevelUp(); if (desc.size() && url.size()) repo->SetScreenshot(desc, url); } } while (NextNode()); LevelUp(); } } while (NextNode()); LevelUp(); if (repo->Valid()) { repos.push_back(repo); return true; } return false; } void cSkinRepos::InitRepoGit(string path) { dsyslog("skindesigner: initiating skin repository %s", path.c_str()); CreateFolder(path); cString command = cString::sprintf("git clone --depth=1 %s %s", skinRepoUrl.c_str(), path.c_str()); int result = system (*command); if (result == 0) { dsyslog("skindesigner: skinrepository successfully initiated"); } else { esyslog("skindesigner: ERROR initiating skinrepository. Command: %s", *command); } } void cSkinRepos::PullRepoGit(string path) { dsyslog("skindesigner: updating skin repository %s", path.c_str()); cString command = *cString::sprintf("cd %s; git pull", path.c_str()); int result = system (*command); if (result == 0) { dsyslog("skindesigner: skinrepository successfully updated"); } else { esyslog("skindesigner: ERROR updating skinrepository. Command: %s", *command); } }