diff options
| -rw-r--r-- | HISTORY | 1 | ||||
| -rw-r--r-- | config.c | 5 | ||||
| -rw-r--r-- | libcore/helpers.c | 4 | ||||
| -rw-r--r-- | libcore/libxmlwrapper.c | 9 | ||||
| -rw-r--r-- | libcore/libxmlwrapper.h | 2 | ||||
| -rw-r--r-- | libcore/skinrepo.c | 253 | ||||
| -rw-r--r-- | libcore/skinrepo.h | 16 | ||||
| -rw-r--r-- | skins/skinrepositories.xml | 281 |
8 files changed, 148 insertions, 423 deletions
@@ -389,3 +389,4 @@ Version 0.6.0 Version 0.6.1 +- changed skinrepository from static file to github repository @@ -94,7 +94,7 @@ void cDesignerConfig::ReadSkinFolder(cString &skinFolder, vector<string> *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<xmlNodePtr> 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::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()); - return; - } - - root = xmlDocGetRootElement(doc); - if (root == NULL) { - return; +void cSkinRepos::Init(string path) { + string repoPath = path + repoFolder; + if (FolderExists(repoPath)) { + PullRepoGit(repoPath); + } else { + InitRepoGit(repoPath); } +} - if (xmlStrcmp(root->name, (const xmlChar *) "skinrepositories")) { +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; } - - 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; - } - if (xmlStrcmp(node->name, (const xmlChar *) "skinrepo")) { + string filePath = repoPath + fileName; + if (! ReadXMLFile(filePath.c_str(), false) ) { + esyslog("skindesigner: error reading skinrepo %s", filePath.c_str()); continue; } - ReadRepository(node->xmlChildrenNode); - node = node->next; + if (! SetDocument() ) + continue; + 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); - } - } - child = child->next; + } else if (CheckNodeName("url")) { + if (GetNodeValue(value)) { + repo->SetUrl(value); + } + } else if (CheckNodeName("author")) { + if (GetNodeValue(value)) { + repo->SetAuthor(value); } - //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; + } else if (CheckNodeName("specialfonts")) { + if (!LevelDown()) + continue; + do { + if (CheckNodeName("font")) { + if (GetNodeValue(value)) { + repo->SetSpecialFont(value); + } } - 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; + } + 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); } - repos.push_back(repo); } +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 <vector> #include <map> #include <set> -#include <libxml/parser.h> -#include <libxml/tree.h> -#include <libxml/xmlerror.h> +#include "../libcore/libxmlwrapper.h" #include <vdr/plugin.h> 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<string, string>(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<cSkinRepo*> repos; vector<cSkinRepo*>::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 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<skinrepositories> - <skinrepo> - <name>blackhole</name> - <type>git</type> - <url>https://github.com/louisbraun/blackhole.git</url> - <author>Louis</author> - <screenshots> - <screenshot> - <description>Main Menu</description> - <url>http://projects.vdr-developer.org/attachments/1848/blackhole_displaymenumain.jpg</url> - </screenshot> - <screenshot> - <description>Display Channel</description> - <url>http://projects.vdr-developer.org/attachments/1847/blackhole_displaychannel.jpg</url> - </screenshot> - <screenshot> - <description>Schedules What's on now</description> - <url>http://projects.vdr-developer.org/attachments/1849/blackhole_displaymenuwhatsonnow.jpg</url> - </screenshot> - <screenshot> - <description>Detailed EPG</description> - <url>http://projects.vdr-developer.org/attachments/1850/blackhole_displaymenudetailepg.jpg</url> - </screenshot> - </screenshots> - <specialfonts> - <font>Source Sans Pro</font> - <font>DS-Digital</font> - </specialfonts> - <supportedplugins> - <plugin>TVGuideNG</plugin> - <plugin>Weatherforecast</plugin> - </supportedplugins> - </skinrepo> - <skinrepo> - <name>blackholefrodo</name> - <type>git</type> - <url>https://github.com/FrodoVDR/blackholefrodo.git</url> - <author>Frodo</author> - <screenshots> - <screenshot> - <description>Main Menu</description> - <url>http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=37513&h=5b10aaaa10a6cbfa38406a9b0adc8d583d2a1216</url> - </screenshot> - <screenshot> - <description>Display Channel</description> - <url>http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=37512&h=71d73685a2ed65f15bf4e6832ec8fedddedc10c1</url> - </screenshot> - <screenshot> - <description>Schedules What's on now</description> - <url>http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=37499&h=29ce2d7dada437bfd3094ad2284d9f7f134a340a</url> - </screenshot> - </screenshots> - <specialfonts> - <font>Source Sans Pro</font> - <font>DS-Digital</font> - </specialfonts> - <supportedplugins> - <plugin>TVGuideNG</plugin> - <plugin>Weatherforecast</plugin> - </supportedplugins> - </skinrepo> - <skinrepo> - <name>blackholePerlbo</name> - <type>zip</type> - <url>https://dl.dropboxusercontent.com/u/75246204/blackholePerlbo13-03.zip</url> - <author>Perlbo</author> - <screenshots> - <screenshot> - <description>Main Menu</description> - <url>http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=37408&h=2d8d5a38498dd2e6acd0b4a3de516c6f2538bdb1</url> - </screenshot> - <screenshot> - <description>Display Channel</description> - <url>http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=37405&h=588321ab0575f04633224bb46f14c409d20b738d</url> - </screenshot> - <screenshot> - <description>Schedules What's on now</description> - <url>http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=37452&h=f13ea3c79e79c1976d9e1c702f291a3e4267b791</url> - </screenshot> - </screenshots> - <specialfonts> - <font>Source Sans Pro</font> - <font>DS-Digital</font> - </specialfonts> - <supportedplugins> - <plugin>TVGuideNG</plugin> - <plugin>Weatherforecast</plugin> - </supportedplugins> - </skinrepo> - <skinrepo> - <name>elchi</name> - <type>git</type> - <url>https://github.com/CReimer/skinElchi.git</url> - <author>Copperhead</author> - <screenshots> - <screenshot> - <description>Main Menu</description> - <url>http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=36776&h=b381995ab32a3c7bc5894aa8724ba326a9f57569</url> - </screenshot> - <screenshot> - <description>Display Channel</description> - <url>http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=36775&h=a6e51ee4a923d78ae1b7e2945c013f083c86043b</url> - </screenshot> - <screenshot> - <description>Display Replay</description> - <url>http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=36777&h=cd278e4a65ef6baca8118a5395dbbb01273b69938</url> - </screenshot> - </screenshots> - <supportedplugins> - <plugin>---</plugin> - </supportedplugins> - </skinrepo> - <skinrepo> - <name>glassy</name> - <type>git</type> - <url>https://github.com/BooStars/glassy.git</url> - <author>Boostar</author> - <screenshots> - <screenshot> - <description>Main Menu</description> - <url>http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=37718&h=1f500078ad81623f1b35307d907bdea0cd37744c</url> - </screenshot> - </screenshots> - <specialfonts> - <font>VDRSymbols Sans</font> - </specialfonts> - <supportedplugins> - <plugin>Weatherforecast</plugin> - </supportedplugins> - </skinrepo> - <skinrepo> - <name>glasslike</name> - <type>git</type> - <url>https://github.com/Vectra130/skindesigner_glasslike.git</url> - <author>Vectra130</author> - <screenshots> - <screenshot> - <description>Main Menu</description> - <url>http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=38254&h=56c0cb6791762169bd3bc373092a5c6ccbaa850d</url> - </screenshot> - <screenshot> - <description>Display Channel</description> - <url>http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=38255&h=9f05b071ded697f3857edfca500a5e37c390baf9</url> - </screenshot> - <screenshot> - <description>Schedules What's on</description> - <url>http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=38260&h=fac7685e2b434a65734f07625ac5f3456ba7c514</url> - </screenshot> - </screenshots> - <specialfonts> - <font>Roboto</font> - <font>DS-Digital</font> - </specialfonts> - <supportedplugins> - <plugin>TVGuideNG</plugin> - <plugin>Weatherforecast</plugin> - </supportedplugins> - </skinrepo> - <skinrepo> - <name>Holo</name> - <type>git</type> - <url>https://github.com/CReimer/Holo</url> - <author>Copperhead</author> - <screenshots> - <screenshot> - <description>Main Menu</description> - <url>http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=36917&h=e2a3805a9d469cc7ca25ba4a084a4a92cd2ccacf</url> - </screenshot> - <screenshot> - <description>Display Channel</description> - <url>http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=36916&h=0b7a5c02f6daabaf3f834c3e7e236c83e024a371</url> - </screenshot> - <screenshot> - <description>Schedules What's on now</description> - <url>http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=36918&h=dadd572da35571042362b36d8abe6745f2500e08</url> - </screenshot> - </screenshots> - <specialfonts> - <font>Roboto</font> - </specialfonts> - <supportedplugins> - <plugin>---</plugin> - </supportedplugins> - </skinrepo> - <skinrepo> - <name>nopacity</name> - <type>git</type> - <url>https://github.com/louisbraun/nopacity.git</url> - <author>Louis</author> - <supportedplugins> - <plugin>Weatherforecast</plugin> - <plugin>TVGuideNG</plugin> - </supportedplugins> - </skinrepo> - <skinrepo> - <name>shady</name> - <type>git</type> - <url>https://github.com/tomsax56/shady.git</url> - <author>tomas</author> - <screenshots> - <screenshot> - <description>Main Menu</description> - <url>http://www.anthra.de/images-shady/screenshots/main4.jpg</url> - </screenshot> - <screenshot> - <description>Schedules</description> - <url>http://www.anthra.de/images-shady/screenshots/schedules.png</url> - </screenshot> - <screenshot> - <description>TV Guide NG</description> - <url>http://www.anthra.de/images-shady/screenshots/tvgng1.png</url> - </screenshot> - </screenshots> - <specialfonts> - <font>VDROpen Sans Light</font> - <font>VDROpen Sans Semibold</font> - </specialfonts> - <supportedplugins> - <plugin>Weatherforecast</plugin> - <plugin>TVGuideNG</plugin> - <plugin>PlexPlugin</plugin> - </supportedplugins> - </skinrepo> - <skinrepo> - <name>tryouts</name> - <type>git</type> - <url>https://github.com/BooStars/tryouts</url> - <author>Boostar</author> - <screenshots> - <screenshot> - <description>Main Menu</description> - <url>http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=37055&h=c4f6715489e506408cca04f67a2263cd4db9ab7d</url> - </screenshot> - <screenshot> - <description>Display Channel</description> - <url>http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=37056&h=e7cd1c6d2bd8042b6c08629c8f5d4711e8196e5f</url> - </screenshot> - <screenshot> - <description>Schedules What's on now</description> - <url>http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=37068&h=5d649990035ac65c80e39c3bbdf29482425eba60</url> - </screenshot> - </screenshots> - <specialfonts> - <font>VDRSymbols Sans</font> - </specialfonts> - <supportedplugins> - <plugin>Weatherforecast</plugin> - <plugin>TVGuideNG</plugin> - </supportedplugins> - </skinrepo> - <skinrepo> - <name>vectra</name> - <type>git</type> - <url>https://github.com/Vectra130/skindesigner_vectraskin.git</url> - <author>Vectra130</author> - <screenshots> - <screenshot> - <description>Main Menu</description> - <url>http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=37726&h=dd861361cf88222974f90d87ba29d43e4b8df088</url> - </screenshot> - <screenshot> - <description>Display Channel</description> - <url>http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=37388&h=91fbd820c01249b10c8bb717b86e8a36b8f98213</url> - </screenshot> - <screenshot> - <description>Schedules What's on</description> - <url>http://www.vdr-portal.de/index.php?page=Attachment&attachmentID=37390&h=6e185acf961c5cfeb07f4ac95aba38e65ef60e53</url> - </screenshot> - </screenshots> - <specialfonts> - <font>Roboto</font> - <font>DS-Digital</font> - </specialfonts> - <supportedplugins> - <plugin>Weatherforecast</plugin> - <plugin>TVGuideNG</plugin> - </supportedplugins> - </skinrepo> -</skinrepositories> |
