From bffafedbd3474901f005b43e3ddf37eef7752e9f Mon Sep 17 00:00:00 2001 From: louis Date: Sat, 11 Jul 2015 13:28:19 +0200 Subject: [PATCH] changed skinrepository from static file to github repository --- HISTORY | 1 + config.c | 5 +- libcore/helpers.c | 4 +- libcore/libxmlwrapper.c | 9 +- libcore/libxmlwrapper.h | 2 +- libcore/skinrepo.c | 257 +++++++++++++++++---------------- libcore/skinrepo.h | 16 ++- skins/skinrepositories.xml | 281 ------------------------------------- 8 files changed, 150 insertions(+), 425 deletions(-) delete mode 100644 skins/skinrepositories.xml diff --git a/HISTORY b/HISTORY index 66626f7..1b9ddf7 100644 --- a/HISTORY +++ b/HISTORY @@ -389,3 +389,4 @@ Version 0.6.0 Version 0.6.1 +- changed skinrepository from static file to github repository diff --git a/config.c b/config.c index af48c5a..eb178ce 100644 --- a/config.c +++ b/config.c @@ -94,7 +94,7 @@ void cDesignerConfig::ReadSkinFolder(cString &skinFolder, vector *contai while (dirEntry = readdir(folder)) { string dirEntryName = dirEntry->d_name; int dirEntryType = dirEntry->d_type; - if (!dirEntryName.compare(".") || !dirEntryName.compare("..") || dirEntryType != DT_DIR) + if (!dirEntryName.compare(".") || !dirEntryName.compare("..") || !dirEntryName.compare("skinrepositories") || dirEntryType != DT_DIR) continue; container->push_back(dirEntryName); } @@ -328,7 +328,8 @@ void cDesignerConfig::SetSkinSetupParameters(void) { } void cDesignerConfig::ReadSkinRepos(void) { - skinRepos.Read(*skinPath); + skinRepos.Init(*installerSkinPath); + skinRepos.Read(*installerSkinPath); dsyslog("skindesigner: read %d skinrepositories from %s", skinRepos.Count(), *skinPath); } diff --git a/libcore/helpers.c b/libcore/helpers.c index 6af7bcb..9fb0bdf 100644 --- a/libcore/helpers.c +++ b/libcore/helpers.c @@ -152,9 +152,7 @@ bool FirstFileInFolder(string &path, string &extension, string &fileName) { void CreateFolder(string &path) { cString command = cString::sprintf("mkdir -p %s", path.c_str()); int ok = system(*command); - if (!ok) { - esyslog("skindesigner: error creating folder %s", path.c_str()); - } + if (!ok) {} } // trim from start diff --git a/libcore/libxmlwrapper.c b/libcore/libxmlwrapper.c index 565c12c..0a93dfd 100644 --- a/libcore/libxmlwrapper.c +++ b/libcore/libxmlwrapper.c @@ -37,7 +37,7 @@ void cLibXMLWrapper::DeleteDocument(void) { nodeStack.pop(); } -bool cLibXMLWrapper::ReadXMLFile(const char *path) { +bool cLibXMLWrapper::ReadXMLFile(const char *path, bool validate) { if (!ctxt) { esyslog("skindesigner: Failed to allocate parser context"); return false; @@ -46,7 +46,11 @@ bool cLibXMLWrapper::ReadXMLFile(const char *path) { dsyslog("skindesigner: reading XML Template %s failed", path); return false; } - doc = xmlCtxtReadFile(ctxt, path, NULL, XML_PARSE_NOENT | XML_PARSE_DTDVALID); + if (validate) + doc = xmlCtxtReadFile(ctxt, path, NULL, XML_PARSE_NOENT | XML_PARSE_DTDVALID); + else + doc = xmlCtxtReadFile(ctxt, path, NULL, XML_PARSE_NOENT); + if (!doc) { dsyslog("skindesigner: reading XML Template %s failed", path); return false; @@ -180,5 +184,6 @@ bool cLibXMLWrapper::GetNodeValue(string &value) { xmlFree(val); return true; } + value = ""; return false; } diff --git a/libcore/libxmlwrapper.h b/libcore/libxmlwrapper.h index cb1872f..0ace267 100644 --- a/libcore/libxmlwrapper.h +++ b/libcore/libxmlwrapper.h @@ -24,7 +24,7 @@ private: stack nodeStack; protected: void DeleteDocument(void); - bool ReadXMLFile(const char *path); + bool ReadXMLFile(const char *path, bool validate = true); bool SetDocument(void); bool Validate(void); bool CheckNodeName(const char *name); diff --git a/libcore/skinrepo.c b/libcore/skinrepo.c index c6943f9..5979e57 100644 --- a/libcore/skinrepo.c +++ b/libcore/skinrepo.c @@ -24,6 +24,16 @@ cSkinRepo::cSkinRepo(void) { 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; @@ -178,8 +188,8 @@ void cSkinRepo::Debug() { // --- cSkinRepos ------------------------------------------------------------- cSkinRepos::cSkinRepos(void) { - repoFile = "skinrepositories.xml"; - doc = NULL; + skinRepoUrl = "https://github.com/louisbraun/skinrepository.git"; + repoFolder = "skinrepositories/"; } cSkinRepos::~cSkinRepos() { @@ -188,41 +198,40 @@ cSkinRepos::~cSkinRepos() { } } +void cSkinRepos::Init(string path) { + string repoPath = path + repoFolder; + if (FolderExists(repoPath)) { + PullRepoGit(repoPath); + } else { + InitRepoGit(repoPath); + } +} + void cSkinRepos::Read(string path) { - string filepath = path + repoFile; - xmlParserCtxtPtr ctxt = xmlNewParserCtxt(); - xmlNodePtr root = NULL; - - doc = xmlCtxtReadFile(ctxt, filepath.c_str(), NULL, XML_PARSE_NOENT); - if (doc == NULL) { - esyslog("skindesigner: ERROR: skinrepository file %s not loaded successfully.", filepath.c_str()); + 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; } - - root = xmlDocGetRootElement(doc); - if (root == NULL) { - return; - } - - if (xmlStrcmp(root->name, (const xmlChar *) "skinrepositories")) { - return; - } - - xmlNodePtr node = root->xmlChildrenNode; - while (node != NULL) { - if (node->type != XML_ELEMENT_NODE) { - node = node->next; + 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 (xmlStrcmp(node->name, (const xmlChar *) "skinrepo")) { + if (! SetDocument() ) continue; - } - ReadRepository(node->xmlChildrenNode); - node = node->next; + if (!ParseRepository()) + esyslog("skindesigner: error parsing skinrepository %s", filePath.c_str()); + DeleteDocument(); } - if (doc) xmlFreeDoc(doc); - xmlFreeParserCtxt(ctxt); } cSkinRepo *cSkinRepos::GetRepo(string name) { @@ -249,122 +258,112 @@ void cSkinRepos::Debug(void) { } } -void cSkinRepos::ReadRepository(xmlNodePtr node) { - if (!node) - return; +bool cSkinRepos::ParseRepository(void) { + if (!LevelDown()) + return false; + cSkinRepo *repo = new cSkinRepo(); - while (node != NULL) { - if (node->type != XML_ELEMENT_NODE) { - node = node->next; - continue; - } - - xmlChar *value = NULL; - //Repo Name - if (!xmlStrcmp(node->name, (const xmlChar *) "name")) { - value = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); - if (value) - repo->SetName((const char *)value); - //Repo Type - } else if (!xmlStrcmp(node->name, (const xmlChar *) "type")) { - value = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); - if (value) { + + do { + string value = ""; + if (CheckNodeName("name")) { + if (GetNodeValue(value)) { + repo->SetName(value); + } + } else if (CheckNodeName("type")) { + if (GetNodeValue(value)) { eRepoType repoType = rtUndefined; - if (!xmlStrcmp(value, (const xmlChar *) "git")) + if (!value.compare("git")) repoType = rtGit; - else if (!xmlStrcmp(value, (const xmlChar *) "zip")) + else if (!value.compare("zip")) repoType = rtZipUrl; repo->SetRepoType(repoType); } - //Repo URL - } else if (!xmlStrcmp(node->name, (const xmlChar *) "url")) { - value = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); - if (value) - repo->SetUrl((const char *)value); - //Skin Author - } else if (!xmlStrcmp(node->name, (const xmlChar *) "author")) { - value = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); - if (value) - repo->SetAuthor((const char *)value); - //Repo Specialfonts - } else if (!xmlStrcmp(node->name, (const xmlChar *) "specialfonts")) { - xmlNodePtr child = node->xmlChildrenNode; - while (child != NULL) { - if (child->type != XML_ELEMENT_NODE) { - child = child->next; - continue; - } - if (!xmlStrcmp(child->name, (const xmlChar *) "font")) { - xmlChar *fontvalue = NULL; - fontvalue = xmlNodeListGetString(doc, child->xmlChildrenNode, 1); - if (fontvalue) { - repo->SetSpecialFont((const char *)fontvalue); - xmlFree(fontvalue); + } else if (CheckNodeName("url")) { + if (GetNodeValue(value)) { + repo->SetUrl(value); + } + } else if (CheckNodeName("author")) { + if (GetNodeValue(value)) { + repo->SetAuthor(value); + } + } else if (CheckNodeName("specialfonts")) { + if (!LevelDown()) + continue; + do { + if (CheckNodeName("font")) { + if (GetNodeValue(value)) { + repo->SetSpecialFont(value); } } - child = child->next; - } - //Repo supported Plugins - } else if (!xmlStrcmp(node->name, (const xmlChar *) "supportedplugins")) { - xmlNodePtr child = node->xmlChildrenNode; - while (child != NULL) { - if (child->type != XML_ELEMENT_NODE) { - child = child->next; - continue; - } - if (!xmlStrcmp(child->name, (const xmlChar *) "plugin")) { - xmlChar *plugvalue = NULL; - plugvalue = xmlNodeListGetString(doc, child->xmlChildrenNode, 1); - if (plugvalue) { - repo->SetSupportedPlugin((const char *)plugvalue); - xmlFree(plugvalue); + } while (NextNode()); + LevelUp(); + } else if (CheckNodeName("supportedplugins")) { + if (!LevelDown()) + continue; + do { + if (CheckNodeName("plugin")) { + if (GetNodeValue(value)) { + repo->SetSupportedPlugin(value); } } - child = child->next; + } while (NextNode()); + LevelUp(); + } else if (CheckNodeName("screenshots")) { + if (!LevelDown()) { + continue; } - //Repo Screenshots - } else if (!xmlStrcmp(node->name, (const xmlChar *) "screenshots")) { - xmlNodePtr child = node->xmlChildrenNode; - while (child != NULL) { - if (child->type != XML_ELEMENT_NODE) { - child = child->next; - continue; - } - if (!xmlStrcmp(child->name, (const xmlChar *) "screenshot")) { - xmlNodePtr subchild = child->xmlChildrenNode; + do { + if (CheckNodeName("screenshot")) { + if (!LevelDown()) { + continue; + } string desc = ""; string url = ""; - while (subchild != NULL) { - if (subchild->type != XML_ELEMENT_NODE) { - subchild = subchild->next; - continue; + do { + if (CheckNodeName("description")) { + GetNodeValue(desc); + } else if (CheckNodeName("url")) { + GetNodeValue(url); } - xmlChar *screenshotvalue = NULL; - if (!xmlStrcmp(subchild->name, (const xmlChar *) "description")) { - screenshotvalue = xmlNodeListGetString(doc, subchild->xmlChildrenNode, 1); - if (screenshotvalue) { - desc = (const char *)screenshotvalue; - xmlFree(screenshotvalue); - } - } else if (!xmlStrcmp(subchild->name, (const xmlChar *) "url")) { - screenshotvalue = xmlNodeListGetString(doc, subchild->xmlChildrenNode, 1); - if (screenshotvalue) { - url = (const char *)screenshotvalue; - xmlFree(screenshotvalue); - } - } - subchild = subchild->next; - } - repo->SetScreenshot(desc, url); + } while (NextNode()); + LevelUp(); + if (desc.size() && url.size()) + repo->SetScreenshot(desc, url); } - child = child->next; - } + } while (NextNode()); + LevelUp(); } - if (value) - xmlFree(value); - node = node->next; - + } while (NextNode()); + LevelUp(); + if (repo->Valid()) { + repos.push_back(repo); + return true; } - repos.push_back(repo); + 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); + } +} diff --git a/libcore/skinrepo.h b/libcore/skinrepo.h index 9466a2a..d4cc88f 100644 --- a/libcore/skinrepo.h +++ b/libcore/skinrepo.h @@ -5,9 +5,7 @@ #include #include #include -#include -#include -#include +#include "../libcore/libxmlwrapper.h" #include using namespace std; @@ -55,6 +53,7 @@ public: void SetSpecialFont(string font) { specialFonts.push_back(font); }; void SetSupportedPlugin(string plugin) { supportedPlugins.push_back(plugin); }; void SetScreenshot(string desc, string url) { screenshots.push_back(pair(desc, url)); }; + bool Valid(void); eRepoType Type(void) { return repoType; }; string Name(void) { return name; }; string Author(void) { return author; }; @@ -72,16 +71,19 @@ public: // --- cSkinRepos ------------------------------------------------------------- -class cSkinRepos { +class cSkinRepos : public cLibXMLWrapper { private: - string repoFile; - xmlDocPtr doc; + string skinRepoUrl; + string repoFolder; vector repos; vector::iterator repoIt; - void ReadRepository(xmlNodePtr node); + bool ParseRepository(void); + void InitRepoGit(string path); + void PullRepoGit(string path); public: cSkinRepos(void); virtual ~cSkinRepos(void); + void Init(string path); void Read(string path); int Count(void) { return repos.size(); }; cSkinRepo *GetRepo(string name); diff --git a/skins/skinrepositories.xml b/skins/skinrepositories.xml deleted file mode 100644 index 6630ba7..0000000 --- a/skins/skinrepositories.xml +++ /dev/null @@ -1,281 +0,0 @@ - - - - - blackhole - git - https://github.com/louisbraun/blackhole.git - Louis - - - Main Menu - http://projects.vdr-developer.org/attachments/1848/blackhole_displaymenumain.jpg - - - Display Channel - http://projects.vdr-developer.org/attachments/1847/blackhole_displaychannel.jpg - - - Schedules What's on now - http://projects.vdr-developer.org/attachments/1849/blackhole_displaymenuwhatsonnow.jpg - - - Detailed EPG - http://projects.vdr-developer.org/attachments/1850/blackhole_displaymenudetailepg.jpg - - - - Source Sans Pro - DS-Digital - - - TVGuideNG - Weatherforecast - - - - blackholefrodo - git - https://github.com/FrodoVDR/blackholefrodo.git - Frodo - - - Main Menu - http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=37513&h=5b10aaaa10a6cbfa38406a9b0adc8d583d2a1216 - - - Display Channel - http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=37512&h=71d73685a2ed65f15bf4e6832ec8fedddedc10c1 - - - Schedules What's on now - http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=37499&h=29ce2d7dada437bfd3094ad2284d9f7f134a340a - - - - Source Sans Pro - DS-Digital - - - TVGuideNG - Weatherforecast - - - - blackholePerlbo - zip - https://dl.dropboxusercontent.com/u/75246204/blackholePerlbo13-03.zip - Perlbo - - - Main Menu - http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=37408&h=2d8d5a38498dd2e6acd0b4a3de516c6f2538bdb1 - - - Display Channel - http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=37405&h=588321ab0575f04633224bb46f14c409d20b738d - - - Schedules What's on now - http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=37452&h=f13ea3c79e79c1976d9e1c702f291a3e4267b791 - - - - Source Sans Pro - DS-Digital - - - TVGuideNG - Weatherforecast - - - - elchi - git - https://github.com/CReimer/skinElchi.git - Copperhead - - - Main Menu - http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=36776&h=b381995ab32a3c7bc5894aa8724ba326a9f57569 - - - Display Channel - http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=36775&h=a6e51ee4a923d78ae1b7e2945c013f083c86043b - - - Display Replay - http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=36777&h=cd278e4a65ef6baca8118a5395dbbb01273b69938 - - - - --- - - - - glassy - git - https://github.com/BooStars/glassy.git - Boostar - - - Main Menu - http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=37718&h=1f500078ad81623f1b35307d907bdea0cd37744c - - - - VDRSymbols Sans - - - Weatherforecast - - - - glasslike - git - https://github.com/Vectra130/skindesigner_glasslike.git - Vectra130 - - - Main Menu - http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=38254&h=56c0cb6791762169bd3bc373092a5c6ccbaa850d - - - Display Channel - http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=38255&h=9f05b071ded697f3857edfca500a5e37c390baf9 - - - Schedules What's on - http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=38260&h=fac7685e2b434a65734f07625ac5f3456ba7c514 - - - - Roboto - DS-Digital - - - TVGuideNG - Weatherforecast - - - - Holo - git - https://github.com/CReimer/Holo - Copperhead - - - Main Menu - http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=36917&h=e2a3805a9d469cc7ca25ba4a084a4a92cd2ccacf - - - Display Channel - http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=36916&h=0b7a5c02f6daabaf3f834c3e7e236c83e024a371 - - - Schedules What's on now - http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=36918&h=dadd572da35571042362b36d8abe6745f2500e08 - - - - Roboto - - - --- - - - - nopacity - git - https://github.com/louisbraun/nopacity.git - Louis - - Weatherforecast - TVGuideNG - - - - shady - git - https://github.com/tomsax56/shady.git - tomas - - - Main Menu - http://www.anthra.de/images-shady/screenshots/main4.jpg - - - Schedules - http://www.anthra.de/images-shady/screenshots/schedules.png - - - TV Guide NG - http://www.anthra.de/images-shady/screenshots/tvgng1.png - - - - VDROpen Sans Light - VDROpen Sans Semibold - - - Weatherforecast - TVGuideNG - PlexPlugin - - - - tryouts - git - https://github.com/BooStars/tryouts - Boostar - - - Main Menu - http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=37055&h=c4f6715489e506408cca04f67a2263cd4db9ab7d - - - Display Channel - http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=37056&h=e7cd1c6d2bd8042b6c08629c8f5d4711e8196e5f - - - Schedules What's on now - http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=37068&h=5d649990035ac65c80e39c3bbdf29482425eba60 - - - - VDRSymbols Sans - - - Weatherforecast - TVGuideNG - - - - vectra - git - https://github.com/Vectra130/skindesigner_vectraskin.git - Vectra130 - - - Main Menu - http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=37726&h=dd861361cf88222974f90d87ba29d43e4b8df088 - - - Display Channel - http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=37388&h=91fbd820c01249b10c8bb717b86e8a36b8f98213 - - - Schedules What's on - http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=37390&h=6e185acf961c5cfeb07f4ac95aba38e65ef60e53 - - - - Roboto - DS-Digital - - - Weatherforecast - TVGuideNG - - -