diff options
author | louis <louis.braun@gmx.de> | 2013-08-23 17:11:38 +0200 |
---|---|---|
committer | louis <louis.braun@gmx.de> | 2013-08-23 17:11:38 +0200 |
commit | 21c1ad1005e3415f8448a21f17ed3ba3be9715b8 (patch) | |
tree | e8cae7353b6047d1d1bd104ad54e5b15d0c85260 /thetvdbscraper | |
download | vdr-plugin-tvscraper-21c1ad1005e3415f8448a21f17ed3ba3be9715b8.tar.gz vdr-plugin-tvscraper-21c1ad1005e3415f8448a21f17ed3ba3be9715b8.tar.bz2 |
Initial Push Version 0.0.1
Diffstat (limited to 'thetvdbscraper')
-rw-r--r-- | thetvdbscraper/thetvdbscraper.c | 129 | ||||
-rw-r--r-- | thetvdbscraper/thetvdbscraper.h | 28 | ||||
-rw-r--r-- | thetvdbscraper/tvdbactors.c | 100 | ||||
-rw-r--r-- | thetvdbscraper/tvdbactors.h | 37 | ||||
-rw-r--r-- | thetvdbscraper/tvdbmedia.c | 149 | ||||
-rw-r--r-- | thetvdbscraper/tvdbmedia.h | 45 | ||||
-rw-r--r-- | thetvdbscraper/tvdbmirrors.c | 97 | ||||
-rw-r--r-- | thetvdbscraper/tvdbmirrors.h | 27 | ||||
-rw-r--r-- | thetvdbscraper/tvdbseries.c | 92 | ||||
-rw-r--r-- | thetvdbscraper/tvdbseries.h | 29 |
10 files changed, 733 insertions, 0 deletions
diff --git a/thetvdbscraper/thetvdbscraper.c b/thetvdbscraper/thetvdbscraper.c new file mode 100644 index 0000000..5695ba0 --- /dev/null +++ b/thetvdbscraper/thetvdbscraper.c @@ -0,0 +1,129 @@ +#include <string>
+#include <sstream>
+#include <vector>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include "thetvdbscraper.h"
+
+using namespace std;
+
+cTVDBScraper::cTVDBScraper(string baseDir, cTVScraperDB *db, string language) {
+ apiKey = "E9DBB94CA50832ED";
+ baseURL = "thetvdb.com";
+ this->baseDir = baseDir;
+ this->language = language;
+ this->db = db;
+ mirrors = NULL;
+}
+
+cTVDBScraper::~cTVDBScraper() {
+ if (mirrors)
+ delete mirrors;
+}
+
+void cTVDBScraper::Scrap(const cEvent *event, int recordingID) {
+ string seriesName = event->Title();
+ if (config.enableDebug)
+ esyslog("tvscraper: scrapping series \"%s\"", seriesName.c_str());
+ int eventID = (int)event->EventID();
+ cTVDBSeries *series = ReadSeries(seriesName);
+ cTVDBSeriesMedia *media = NULL;
+ cTVDBActors *actors = NULL;
+ if (!series)
+ return;
+ if (series->ID() < 1) {
+ if (config.enableDebug)
+ esyslog("tvscraper: nothing found for \"%s\"", seriesName.c_str());
+ return;
+ }
+ if (!db->SeriesExists(series->ID())) {
+ series->StoreDB(db);
+ media = ReadSeriesMedia(series->ID());
+ actors = ReadSeriesActors(series->ID());
+ if (actors)
+ actors->StoreDB(db, series->ID());
+ StoreMedia(series, media, actors);
+ }
+ if (!recordingID) {
+ time_t validTill = event->EndTime();
+ db->InsertEventSeries(eventID, validTill, series->ID());
+ } else {
+ db->InsertRecording(recordingID, series->ID(), 0);
+ }
+ delete series;
+ if (media)
+ delete media;
+ if (actors)
+ delete actors;
+ if (config.enableDebug)
+ esyslog("tvscraper: \"%s\" successfully scrapped, id %d", seriesName.c_str(), series->ID());
+}
+
+
+bool cTVDBScraper::Connect(void) {
+ stringstream url;
+ url << baseURL << "/api/" << apiKey << "/mirrors.xml";
+ string mirrorsXML;
+ if (CurlGetUrl(url.str().c_str(), &mirrorsXML)) {
+ mirrors = new cTVDBMirrors(mirrorsXML);
+ return mirrors->ParseXML();
+ }
+ return false;
+}
+
+cTVDBSeries *cTVDBScraper::ReadSeries(string seriesName) {
+ stringstream seriesEscape;
+ seriesEscape << "\"" << seriesName << "\"";
+ stringstream url;
+ url << mirrors->GetMirrorXML() << "/api/GetSeries.php?seriesname=" << CurlEscape(seriesEscape.str().c_str()) << "&language=" << language.c_str();
+ string seriesXML;
+ cTVDBSeries *series = NULL;
+ if (CurlGetUrl(url.str().c_str(), &seriesXML)) {
+ series = new cTVDBSeries(seriesXML);
+ series->ParseXML();
+ }
+ return series;
+}
+
+cTVDBSeriesMedia *cTVDBScraper::ReadSeriesMedia(int seriesID) {
+ stringstream url;
+ url << mirrors->GetMirrorXML() << "/api/" << apiKey << "/series/" << seriesID << "/banners.xml";
+ string bannersXML;
+ cTVDBSeriesMedia *media = NULL;
+ if (CurlGetUrl(url.str().c_str(), &bannersXML)) {
+ media = new cTVDBSeriesMedia(bannersXML, language);
+ media->ParseXML();
+ }
+ return media;
+}
+
+cTVDBActors *cTVDBScraper::ReadSeriesActors(int seriesID) {
+ stringstream url;
+ url << mirrors->GetMirrorXML() << "/api/" << apiKey << "/series/" << seriesID << "/actors.xml";
+ string actorsXML;
+ cTVDBActors *actors = NULL;
+ if (CurlGetUrl(url.str().c_str(), &actorsXML)) {
+ actors = new cTVDBActors(actorsXML, language);
+ actors->ParseXML();
+ }
+ return actors;
+}
+
+void cTVDBScraper::StoreMedia(cTVDBSeries *series, cTVDBSeriesMedia *media, cTVDBActors *actors) {
+ stringstream baseUrl;
+ baseUrl << mirrors->GetMirrorBanner() << "/banners/";
+ stringstream destDir;
+ destDir << baseDir << "/" << series->ID() << "/";
+ bool ok = CreateDirectory(destDir.str().c_str());
+ if (!ok)
+ return;
+ if (series) {
+ series->StoreBanner(baseUrl.str(), destDir.str());
+ }
+ if (media) {
+ media->Store(baseUrl.str(), destDir.str());
+ }
+ if (actors) {
+ actors->Store(baseUrl.str(), destDir.str());
+ }
+}
diff --git a/thetvdbscraper/thetvdbscraper.h b/thetvdbscraper/thetvdbscraper.h new file mode 100644 index 0000000..2659bdc --- /dev/null +++ b/thetvdbscraper/thetvdbscraper.h @@ -0,0 +1,28 @@ +#ifndef __TVSCRAPER_TVDBSCRAPER_H
+#define __TVSCRAPER_TVDBSCRAPER_H
+
+using namespace std;
+
+// --- cTVDBScraper -------------------------------------------------------------
+
+class cTVDBScraper {
+private:
+ string apiKey;
+ string baseURL;
+ string baseDir;
+ string language;
+ cTVScraperDB *db;
+ cTVDBMirrors *mirrors;
+ cTVDBSeries *ReadSeries(string seriesName);
+ cTVDBSeriesMedia *ReadSeriesMedia(int seriesID);
+ cTVDBActors *ReadSeriesActors(int seriesID);
+ void StoreMedia(cTVDBSeries *series, cTVDBSeriesMedia *media, cTVDBActors *actors);
+public:
+ cTVDBScraper(string baseDir, cTVScraperDB *db, string language);
+ virtual ~cTVDBScraper(void);
+ bool Connect(void);
+ void Scrap(const cEvent *event, int recordingID = 0);
+};
+
+
+#endif //__TVSCRAPER_TVDBSCRAPER_H
diff --git a/thetvdbscraper/tvdbactors.c b/thetvdbscraper/tvdbactors.c new file mode 100644 index 0000000..404cd38 --- /dev/null +++ b/thetvdbscraper/tvdbactors.c @@ -0,0 +1,100 @@ +#include <string>
+#include <sstream>
+#include <vector>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include "tvdbactors.h"
+
+using namespace std;
+
+cTVDBActors::cTVDBActors(string xml, string language) {
+ doc = NULL;
+ SetXMLDoc(xml);
+ this->language = language;
+}
+
+cTVDBActors::~cTVDBActors() {
+ xmlFreeDoc(doc);
+ actors.clear();
+}
+
+void cTVDBActors::SetXMLDoc(string xml) {
+ xmlInitParser();
+ doc = xmlReadMemory(xml.c_str(), strlen(xml.c_str()), "noname.xml", NULL, 0);
+}
+
+void cTVDBActors::ParseXML(void) {
+ if (doc == NULL)
+ return;
+ //Root Element has to be <Actors>
+ xmlNode *node = NULL;
+ node = xmlDocGetRootElement(doc);
+ if (!(node && !xmlStrcmp(node->name, (const xmlChar *)"Actors")))
+ return;
+ //Looping through actors
+ node = node->children;
+ xmlNode *cur_node = NULL;
+ for (cur_node = node; cur_node; cur_node = cur_node->next) {
+ if ((cur_node->type == XML_ELEMENT_NODE) && !xmlStrcmp(cur_node->name, (const xmlChar *)"Actor")) {
+ ReadEntry(cur_node->children);
+ }
+ }
+}
+
+void cTVDBActors::ReadEntry(xmlNode *node) {
+ xmlNode *cur_node = NULL;
+ xmlChar *node_content;
+ cTVDBActor *actor = new cTVDBActor();
+ for (cur_node = node; cur_node; cur_node = cur_node->next) {
+ if (cur_node->type == XML_ELEMENT_NODE) {
+ node_content = xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1);
+ if (!node_content)
+ continue;
+ if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Image")) {
+ actor->path = (const char *)node_content;
+ } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Name")) {
+ actor->name = (const char *)node_content;
+ } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Role")) {
+ actor->role = (const char *)node_content;
+ }
+ xmlFree(node_content);
+ }
+ }
+ actors.push_back(actor);
+}
+
+void cTVDBActors::StoreDB(cTVScraperDB *db, int series_id) {
+ int size = actors.size();
+ for (int i=0; i<size; i++) {
+ stringstream strThumb;
+ strThumb << "actor_" << i << ".jpg";
+ db->InsertActor(series_id, actors[i]->name, actors[i]->role, strThumb.str());
+ }
+}
+
+void cTVDBActors::Store(string baseUrl, string destDir) {
+ int size = actors.size();
+ string path;
+ string url;
+ for (int i=0; i<size; i++) {
+ stringstream strUrl;
+ strUrl << baseUrl << actors[i]->path;
+ url = strUrl.str();
+ stringstream fullPath;
+ fullPath << destDir << "actor_" << i << ".jpg";
+ path = fullPath.str();
+ if (actors[i]->path.size() > 0) {
+ CurlGetUrlFile(url.c_str(), path.c_str());
+ }
+ }
+}
+
+void cTVDBActors::Dump(bool verbose) {
+ int size = actors.size();
+ esyslog("tvscraper: read %d actor entries", size);
+ if (!verbose)
+ return;
+ for (int i=0; i<size; i++) {
+ esyslog("tvscraper: path %s, name: %s, role %s", actors[i]->path.c_str(), actors[i]->name.c_str(), actors[i]->role.c_str());
+ }
+}
\ No newline at end of file diff --git a/thetvdbscraper/tvdbactors.h b/thetvdbscraper/tvdbactors.h new file mode 100644 index 0000000..819d1d4 --- /dev/null +++ b/thetvdbscraper/tvdbactors.h @@ -0,0 +1,37 @@ +#ifndef __TVSCRAPER_TVDBACTORS_H
+#define __TVSCRAPER_TVDBACTORS_H
+
+using namespace std;
+
+// --- cTVDBActor -------------------------------------------------------------
+class cTVDBActor {
+public:
+ cTVDBActor(void) {
+ path = "";
+ name = "";
+ role = "";
+ };
+ string path;
+ string name;
+ string role;
+};
+
+// --- cTVDBActors --------------------------------------------------------
+
+class cTVDBActors {
+private:
+ xmlDoc *doc;
+ string language;
+ vector<cTVDBActor*> actors;
+ void SetXMLDoc(string xml);
+ void ReadEntry(xmlNode *node);
+public:
+ cTVDBActors(string xml, string language);
+ virtual ~cTVDBActors(void);
+ void ParseXML(void);
+ void StoreDB(cTVScraperDB *db, int series_id);
+ void Store(string baseUrl, string destDir);
+ void Dump(bool verbose);
+};
+
+#endif //__TVSCRAPER_TVDBACTORS_H
diff --git a/thetvdbscraper/tvdbmedia.c b/thetvdbscraper/tvdbmedia.c new file mode 100644 index 0000000..f9672b6 --- /dev/null +++ b/thetvdbscraper/tvdbmedia.c @@ -0,0 +1,149 @@ +#include <string>
+#include <sstream>
+#include <vector>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include "tvdbmedia.h"
+
+using namespace std;
+
+cTVDBSeriesMedia::cTVDBSeriesMedia(string xml, string language) {
+ doc = NULL;
+ SetXMLDoc(xml);
+ this->language = language;
+}
+
+cTVDBSeriesMedia::~cTVDBSeriesMedia() {
+ xmlFreeDoc(doc);
+ medias.clear();
+}
+
+void cTVDBSeriesMedia::SetXMLDoc(string xml) {
+ xmlInitParser();
+ doc = xmlReadMemory(xml.c_str(), strlen(xml.c_str()), "noname.xml", NULL, 0);
+}
+
+void cTVDBSeriesMedia::ParseXML(void) {
+ if (doc == NULL)
+ return;
+ //Root Element has to be <Banners>
+ xmlNode *node = NULL;
+ node = xmlDocGetRootElement(doc);
+ if (!(node && !xmlStrcmp(node->name, (const xmlChar *)"Banners")))
+ return;
+ //Looping through banners
+ node = node->children;
+ xmlNode *cur_node = NULL;
+ for (cur_node = node; cur_node; cur_node = cur_node->next) {
+ if ((cur_node->type == XML_ELEMENT_NODE) && !xmlStrcmp(cur_node->name, (const xmlChar *)"Banner")) {
+ ReadEntry(cur_node->children);
+ }
+ }
+}
+
+void cTVDBSeriesMedia::ReadEntry(xmlNode *node) {
+ xmlNode *cur_node = NULL;
+ xmlChar *node_content;
+ cTVDBMedia *media = new cTVDBMedia();
+ for (cur_node = node; cur_node; cur_node = cur_node->next) {
+ if (cur_node->type == XML_ELEMENT_NODE) {
+ node_content = xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1);
+ if (!node_content)
+ continue;
+ if (!xmlStrcmp(cur_node->name, (const xmlChar *)"BannerPath")) {
+ media->path = (const char *)node_content;
+ } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"BannerType")) {
+ if (!xmlStrcmp(node_content, (const xmlChar *)"poster"))
+ media->type = mediaPoster;
+ else if (!xmlStrcmp(node_content, (const xmlChar *)"fanart"))
+ media->type = mediaFanart;
+ else if (!xmlStrcmp(node_content, (const xmlChar *)"banner"))
+ media->type = mediaBanner;
+ else if (!xmlStrcmp(node_content, (const xmlChar *)"season"))
+ media->type = mediaSeason;
+ else
+ media->type = mediaUnknown;
+ } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Season")) {
+ media->season = atoi((const char *)node_content);
+ } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Language")) {
+ media->language = (const char *)node_content;
+ }
+ xmlFree(node_content);
+ }
+ }
+ if (media->type == mediaUnknown)
+ delete media;
+ else if ((media->type == mediaSeason) && (media->language).compare(language))
+ delete media;
+ else
+ medias.push_back(media);
+}
+
+void cTVDBSeriesMedia::Store(string baseUrl, string destDir) {
+ int size = medias.size();
+ string path;
+ string url;
+ int maxPix = 3;
+ int numFanart = 0;
+ int numPoster = 0;
+ int numSeason = 0;
+ int numBanner = 0;
+ for (int i=0; i<size; i++) {
+ if (medias[i]->path.size() == 0)
+ continue;
+ stringstream strUrl;
+ strUrl << baseUrl << medias[i]->path;
+ url = strUrl.str();
+ switch (medias[i]->type) {
+ case mediaFanart: {
+ if (numFanart >= maxPix)
+ continue;
+ stringstream fullPath;
+ fullPath << destDir << "fanart_" << numFanart << ".jpg";
+ path = fullPath.str();
+ numFanart++;
+ break; }
+ case mediaPoster: {
+ if (numPoster >= maxPix)
+ continue;
+ stringstream fullPath;
+ fullPath << destDir << "poster_" << numPoster << ".jpg";
+ path = fullPath.str();
+ numPoster++;
+ break; }
+ case mediaSeason: {
+ stringstream fullPath;
+ if (medias[i]->season > 0) {
+ fullPath << destDir << "season_poster_" << medias[i]->season << ".jpg";
+ } else {
+ if (numSeason >= maxPix)
+ continue;
+ fullPath << destDir << "season_" << numSeason << ".jpg";
+ numSeason++;
+ }
+ path = fullPath.str();
+ break; }
+ case mediaBanner: {
+ if (numBanner > 9)
+ continue;
+ stringstream fullPath;
+ fullPath << destDir << "banner_" << numBanner << ".jpg";
+ path = fullPath.str();
+ numBanner++;
+ break; }
+ default:
+ break;
+ }
+ CurlGetUrlFile(url.c_str(), path.c_str());
+ }
+}
+
+void cTVDBSeriesMedia::Dump(bool verbose) {
+ int size = medias.size();
+ esyslog("tvscraper: read %d banner entries", size);
+ if (!verbose)
+ return;
+ for (int i=0; i<size; i++) {
+ esyslog("tvscraper: type %d, path %s, lang: %s, season %d", medias[i]->type, medias[i]->path.c_str(), medias[i]->language.c_str(), medias[i]->season);
+ }
+}
\ No newline at end of file diff --git a/thetvdbscraper/tvdbmedia.h b/thetvdbscraper/tvdbmedia.h new file mode 100644 index 0000000..b9e9b0c --- /dev/null +++ b/thetvdbscraper/tvdbmedia.h @@ -0,0 +1,45 @@ +#ifndef __TVSCRAPER_TVDBMEDIA_H
+#define __TVSCRAPER_TVDBMEDIA_H
+
+using namespace std;
+
+enum mediaType {
+ mediaUnknown,
+ mediaPoster,
+ mediaFanart,
+ mediaSeason,
+ mediaBanner,
+};
+
+// --- cTVDBMedia -------------------------------------------------------------
+class cTVDBMedia {
+public:
+ cTVDBMedia(void) {
+ path = "";
+ language = "";
+ season = 0;
+ };
+ mediaType type;
+ string path;
+ string language;
+ int season;
+};
+
+// --- cTVDBSeriesMedia --------------------------------------------------------
+
+class cTVDBSeriesMedia {
+private:
+ xmlDoc *doc;
+ string language;
+ vector<cTVDBMedia*> medias;
+ void SetXMLDoc(string xml);
+ void ReadEntry(xmlNode *node);
+public:
+ cTVDBSeriesMedia(string xml, string language);
+ virtual ~cTVDBSeriesMedia(void);
+ void ParseXML(void);
+ void Store(string baseUrl, string destDir);
+ void Dump(bool verbose);
+};
+
+#endif //__TVSCRAPER_TVDBMEDIA_H
diff --git a/thetvdbscraper/tvdbmirrors.c b/thetvdbscraper/tvdbmirrors.c new file mode 100644 index 0000000..d0849c2 --- /dev/null +++ b/thetvdbscraper/tvdbmirrors.c @@ -0,0 +1,97 @@ +#include <string>
+#include <sstream>
+#include <vector>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include "tvdbmirrors.h"
+
+using namespace std;
+
+cTVDBMirrors::cTVDBMirrors(string xml) {
+ doc = NULL;
+ SetXMLDoc(xml);
+}
+
+cTVDBMirrors::~cTVDBMirrors() {
+ xmlFreeDoc(doc);
+}
+
+void cTVDBMirrors::SetXMLDoc(string xml) {
+ xmlInitParser();
+ doc = xmlReadMemory(xml.c_str(), strlen(xml.c_str()), "noname.xml", NULL, 0);
+}
+
+string cTVDBMirrors::GetMirrorXML(void) {
+ if (xmlmirrors.size() == 0)
+ return "";
+ int randMirror = rand() % xmlmirrors.size();
+ return xmlmirrors[randMirror];
+}
+string cTVDBMirrors::GetMirrorBanner(void) {
+ if (bannermirrors.size() == 0)
+ return "";
+ int randMirror = rand() % bannermirrors.size();
+ return bannermirrors[randMirror];
+}
+
+string cTVDBMirrors::GetMirrorZip(void) {
+ if (zipmirrors.size() == 0)
+ return "";
+ int randMirror = rand() % zipmirrors.size();
+ return zipmirrors[randMirror];
+}
+
+bool cTVDBMirrors::ParseXML(void) {
+ if (doc == NULL)
+ return false;
+ //Root Element has to be <Mirrors>
+ xmlNode *node = NULL;
+ node = xmlDocGetRootElement(doc);
+ if (!(node && !xmlStrcmp(node->name, (const xmlChar *)"Mirrors")))
+ return false;
+ //Loop through <Mirror>
+ node = node->children;
+ xmlNode *cur_node = NULL;
+ bool ok = false;
+ for (cur_node = node; cur_node; cur_node = cur_node->next) {
+ if ((cur_node->type == XML_ELEMENT_NODE) && !xmlStrcmp(cur_node->name, (const xmlChar *)"Mirror")) {
+ ok = ReadEntry(cur_node->children);
+ }
+ }
+ return ok;
+}
+
+bool cTVDBMirrors::ReadEntry(xmlNode *node) {
+ xmlNode *cur_node = NULL;
+ xmlChar *node_content;
+ string path = "";
+ int typemask = 0;
+ for (cur_node = node; cur_node; cur_node = cur_node->next) {
+ if (cur_node->type == XML_ELEMENT_NODE) {
+ node_content = xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1);
+ if (!node_content)
+ continue;
+ if (!xmlStrcmp(cur_node->name, (const xmlChar *)"mirrorpath")) {
+ path = (const char *)node_content;
+ } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"typemask")) {
+ typemask = atoi((const char *)node_content);
+ }
+ xmlFree(node_content);
+ }
+ }
+ return CreateMirror(path, typemask);
+}
+
+bool cTVDBMirrors::CreateMirror(string path, int typemask) {
+ if (path.size() < 1)
+ return false;
+ if (typemask < 1 || typemask > 7)
+ return false;
+ if (typemask & 1)
+ xmlmirrors.push_back(path);
+ if (typemask & 2)
+ bannermirrors.push_back(path);
+ if (typemask & 4)
+ zipmirrors.push_back(path);
+ return true;
+}
\ No newline at end of file diff --git a/thetvdbscraper/tvdbmirrors.h b/thetvdbscraper/tvdbmirrors.h new file mode 100644 index 0000000..67ad92c --- /dev/null +++ b/thetvdbscraper/tvdbmirrors.h @@ -0,0 +1,27 @@ +#ifndef __TVSCRAPER_TVDBMIRRORS_H
+#define __TVSCRAPER_TVDBMIRRORS_H
+
+using namespace std;
+
+// --- cTVDBMirrors -------------------------------------------------------------
+
+class cTVDBMirrors {
+private:
+ xmlDoc *doc;
+ vector<string> xmlmirrors;
+ vector<string> bannermirrors;
+ vector<string> zipmirrors;
+ void SetXMLDoc(string xml);
+ bool ReadEntry(xmlNode *node);
+ bool CreateMirror(string path, int typemask);
+public:
+ cTVDBMirrors(string xml);
+ virtual ~cTVDBMirrors(void);
+ bool ParseXML(void);
+ string GetMirrorXML(void);
+ string GetMirrorBanner(void);
+ string GetMirrorZip(void);
+};
+
+
+#endif //__TVSCRAPER_TVDBMIRRORS_H
diff --git a/thetvdbscraper/tvdbseries.c b/thetvdbscraper/tvdbseries.c new file mode 100644 index 0000000..b679e5e --- /dev/null +++ b/thetvdbscraper/tvdbseries.c @@ -0,0 +1,92 @@ +#include <string>
+#include <sstream>
+#include <vector>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include "tvdbseries.h"
+
+using namespace std;
+
+cTVDBSeries::cTVDBSeries(string xml) {
+ doc = NULL;
+ SetXMLDoc(xml);
+ seriesID = 0;
+ name = "";
+ banner = "";
+ overview = "";
+ imbdid = "";
+}
+
+cTVDBSeries::~cTVDBSeries() {
+ xmlFreeDoc(doc);
+}
+
+void cTVDBSeries::SetXMLDoc(string xml) {
+ xmlInitParser();
+ doc = xmlReadMemory(xml.c_str(), strlen(xml.c_str()), "noname.xml", NULL, 0);
+}
+
+void cTVDBSeries::ParseXML(void) {
+ if (doc == NULL)
+ return;
+ //Root Element has to be <Data>
+ xmlNode *node = NULL;
+ node = xmlDocGetRootElement(doc);
+ if (!(node && !xmlStrcmp(node->name, (const xmlChar *)"Data")))
+ return;
+ //Searching for <Series>
+ node = node->children;
+ xmlNode *cur_node = NULL;
+ for (cur_node = node; cur_node; cur_node = cur_node->next) {
+ if ((cur_node->type == XML_ELEMENT_NODE) && !xmlStrcmp(cur_node->name, (const xmlChar *)"Series")) {
+ node = cur_node;
+ break;
+ } else {
+ node = NULL;
+ }
+ }
+ if (!node)
+ return;
+ //now read the first series
+ node = node->children;
+ xmlChar *node_content;
+ for (cur_node = node; cur_node; cur_node = cur_node->next) {
+ if (cur_node->type == XML_ELEMENT_NODE) {
+ node_content = xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1);
+ if (!node_content)
+ continue;
+ if (!xmlStrcmp(cur_node->name, (const xmlChar *)"seriesid")) {
+ seriesID = atoi((const char *)node_content);
+ } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"SeriesName")) {
+ name = (const char *)node_content;
+ } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Overview")) {
+ overview = (const char *)node_content;
+ } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"banner")) {
+ banner = (const char *)node_content;
+ } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"IMDB_ID")) {
+ imbdid = (const char *)node_content;
+ }
+ xmlFree(node_content);
+ }
+ }
+}
+
+void cTVDBSeries::StoreDB(cTVScraperDB *db) {
+ db->InsertSeries(seriesID, name, overview);
+}
+
+void cTVDBSeries::StoreBanner(string baseUrl, string destDir) {
+ if (banner.size() == 0)
+ return;
+ stringstream strUrl;
+ strUrl << baseUrl << banner;
+ string url = strUrl.str();
+ stringstream fullPath;
+ fullPath << destDir << "banner.jpg";
+ string path = fullPath.str();
+ CurlGetUrlFile(url.c_str(), path.c_str());
+}
+
+void cTVDBSeries::Dump() {
+ esyslog("tvscraper: series %s, id: %d, overview %s, imdb %s", name.c_str(), seriesID, overview.c_str(), imbdid.c_str());
+}
diff --git a/thetvdbscraper/tvdbseries.h b/thetvdbscraper/tvdbseries.h new file mode 100644 index 0000000..98fb75d --- /dev/null +++ b/thetvdbscraper/tvdbseries.h @@ -0,0 +1,29 @@ +#ifndef __TVSCRAPER_TVDBSERIES_H
+#define __TVSCRAPER_TVDBSERIES_H
+
+using namespace std;
+
+// --- cTVDBSeries -------------------------------------------------------------
+
+class cTVDBSeries {
+private:
+ xmlDoc *doc;
+ int seriesID;
+ string name;
+ string banner;
+ string overview;
+ string imbdid;
+ void SetXMLDoc(string xml);
+public:
+ cTVDBSeries(string xml);
+ virtual ~cTVDBSeries(void);
+ void ParseXML(void);
+ int ID(void) { return seriesID; };
+ const char *Name(void) { return name.c_str(); };
+ void StoreDB(cTVScraperDB *db);
+ void StoreBanner(string baseUrl, string destDir);
+ void Dump();
+};
+
+
+#endif //__TVSCRAPER_TVDBSERIES_H
|