diff options
author | horchi <vdr@jwendel.de> | 2017-03-05 16:39:28 +0100 |
---|---|---|
committer | horchi <vdr@jwendel.de> | 2017-03-05 16:39:28 +0100 |
commit | e2a48d8701f91b8e24fbe9e99e91eb72a87bb749 (patch) | |
tree | 726f70554b4ca985a09ef6e30a7fdc8df089993c /scraper/thetvdbscraper | |
download | vdr-epg-daemon-e2a48d8701f91b8e24fbe9e99e91eb72a87bb749.tar.gz vdr-epg-daemon-e2a48d8701f91b8e24fbe9e99e91eb72a87bb749.tar.bz2 |
git init1.1.103
Diffstat (limited to 'scraper/thetvdbscraper')
-rw-r--r-- | scraper/thetvdbscraper/thetvdbscraper.c | 188 | ||||
-rw-r--r-- | scraper/thetvdbscraper/thetvdbscraper.h | 39 | ||||
-rw-r--r-- | scraper/thetvdbscraper/tvdbactor.c | 66 | ||||
-rw-r--r-- | scraper/thetvdbscraper/tvdbactor.h | 54 | ||||
-rw-r--r-- | scraper/thetvdbscraper/tvdbepisode.c | 147 | ||||
-rw-r--r-- | scraper/thetvdbscraper/tvdbepisode.h | 45 | ||||
-rw-r--r-- | scraper/thetvdbscraper/tvdbmedia.c | 202 | ||||
-rw-r--r-- | scraper/thetvdbscraper/tvdbmedia.h | 111 | ||||
-rw-r--r-- | scraper/thetvdbscraper/tvdbmirrors.c | 88 | ||||
-rw-r--r-- | scraper/thetvdbscraper/tvdbmirrors.h | 32 | ||||
-rw-r--r-- | scraper/thetvdbscraper/tvdbseries.c | 281 | ||||
-rw-r--r-- | scraper/thetvdbscraper/tvdbseries.h | 69 |
12 files changed, 1322 insertions, 0 deletions
diff --git a/scraper/thetvdbscraper/thetvdbscraper.c b/scraper/thetvdbscraper/thetvdbscraper.c new file mode 100644 index 0000000..e83690c --- /dev/null +++ b/scraper/thetvdbscraper/thetvdbscraper.c @@ -0,0 +1,188 @@ + +#include "../../lib/curl.h" +#include "thetvdbscraper.h" + +using namespace std; + +cTVDBScraper::cTVDBScraper(string language) { + apiKey = "E9DBB94CA50832ED"; + baseURL = "thetvdb.com"; + this->language = language; + mirrors = NULL; + xmlInitParser(); +} + +cTVDBScraper::~cTVDBScraper() { + if (mirrors) + delete mirrors; +} + +cTVDBSeries *cTVDBScraper::ScrapInitial(string seriesName) { + cTVDBSeries *series = NULL; + int seriesID = ReadSeries(seriesName); + if (seriesID) { + series = new cTVDBSeries(seriesID, language, apiKey, mirrors); + } + return series; +} + +cTVDBSeries *cTVDBScraper::GetSeries(int seriesID) { + return new cTVDBSeries(seriesID, language, apiKey, mirrors); +} + +cTVDBEpisode *cTVDBScraper::GetEpisode(int episodeID) { + return new cTVDBEpisode(episodeID, language, apiKey, mirrors); +} + +bool cTVDBScraper::Connect(void) { + stringstream url; + url << baseURL << "/api/" << apiKey << "/mirrors.xml"; + string mirrorsXML; + bool ok = false; + if (curl.GetUrl(url.str().c_str(), &mirrorsXML)) { + mirrors = new cTVDBMirrors(); + ok = mirrors->ParseXML(mirrorsXML); + } + return ok; +} + +int cTVDBScraper::GetServerTime(void) { + string url = "http://thetvdb.com/api/Updates.php?type=none"; + string serverTimeXML; + if (!curl.GetUrl(url.c_str(), &serverTimeXML)) { + return 0; + } + xmlDoc *doc = SetXMLDoc(serverTimeXML); + if (doc == NULL) + return 0; + //Root Element has to be <Items> + xmlNode *node = NULL; + node = xmlDocGetRootElement(doc); + if (!(node && !xmlStrcmp(node->name, (const xmlChar *)"Items"))) { + xmlFreeDoc(doc); + return 0; + } + 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 *)"Time")) { + node = cur_node; + break; + } else { + node = NULL; + } + } + if (!node) { + xmlFreeDoc(doc); + return 0; + } + xmlChar *node_content = xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1); + int serverTime = atoi((const char *)node_content); + xmlFree(node_content); + xmlFreeDoc(doc); + return serverTime; +} + +bool cTVDBScraper::GetUpdatedSeriesandEpisodes(set<int> *updatedSeries, set<int> *updatedEpisodes, int lastScrap) { + stringstream url; + url << "http://thetvdb.com/api/Updates.php?type=all&time=" << lastScrap; + string updatedXML; + if (!curl.GetUrl(url.str().c_str(), &updatedXML)) { + return false; + } + xmlDoc *doc = SetXMLDoc(updatedXML); + if (doc == NULL) + return false; + //Root Element has to be <Items> + xmlNode *node = NULL; + node = xmlDocGetRootElement(doc); + if (!(node && !xmlStrcmp(node->name, (const xmlChar *)"Items"))) { + xmlFreeDoc(doc); + return false; + } + + xmlNode *cur_node = node->children; + for (; cur_node; cur_node = cur_node->next) { + if ((cur_node->type == XML_ELEMENT_NODE) && !xmlStrcmp(cur_node->name, (const xmlChar *)"Series")) { + xmlChar *node_content = xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1); + int seriesId = atoi((const char *)node_content); + xmlFree(node_content); + updatedSeries->insert(seriesId); + } else if ((cur_node->type == XML_ELEMENT_NODE) && !xmlStrcmp(cur_node->name, (const xmlChar *)"Episode")) { + xmlChar *node_content = xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1); + int episodeId = atoi((const char *)node_content); + xmlFree(node_content); + updatedEpisodes->insert(episodeId); + } + } + xmlFreeDoc(doc); + return true; +} + + +int cTVDBScraper::ReadSeries(string seriesName) { + int seriesID = 0; + stringstream url; + string seriesXML; + char* escUrl = curl.EscapeUrl(seriesName.c_str()); + + url << mirrors->GetMirrorXML() << "/api/GetSeries.php?seriesname=" << escUrl << "&language=" << language.c_str(); + curl.Free(escUrl); + + if (curl.GetUrl(url.str().c_str(), &seriesXML)) + seriesID = ParseXML(seriesXML); + + return seriesID; +} + +int cTVDBScraper::ParseXML(string xml) { + int seriesID = 0; + xmlDoc *doc = SetXMLDoc(xml); + if (doc == NULL) + return seriesID; + //Root Element has to be <Data> + xmlNode *node = NULL; + node = xmlDocGetRootElement(doc); + if (!(node && !xmlStrcmp(node->name, (const xmlChar *)"Data"))) { + xmlFreeDoc(doc); + return seriesID; + } + //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) { + xmlFreeDoc(doc); + return seriesID; + } + //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); + xmlFree(node_content); + break; + } + xmlFree(node_content); + } + } + xmlFreeDoc(doc); + return seriesID; +} + +xmlDoc *cTVDBScraper::SetXMLDoc(string xml) { + xmlDoc *doc = xmlReadMemory(xml.c_str(), xml.size(), "noname.xml", NULL, 0); + return doc; +} diff --git a/scraper/thetvdbscraper/thetvdbscraper.h b/scraper/thetvdbscraper/thetvdbscraper.h new file mode 100644 index 0000000..051842c --- /dev/null +++ b/scraper/thetvdbscraper/thetvdbscraper.h @@ -0,0 +1,39 @@ +#ifndef __TVSCRAPER_TVDBSCRAPER_H +#define __TVSCRAPER_TVDBSCRAPER_H +#include <iostream> +#include <string> +#include <sstream> +#include <vector> +#include <map> +#include <set> +#include <libxml/parser.h> +#include <libxml/tree.h> +#include "tvdbseries.h" +#include "tvdbmirrors.h" + +using namespace std; + +// --- cTVDBScraper ------------------------------------------------------------- + +class cTVDBScraper { +private: + string apiKey; + string baseURL; + string language; + cTVDBMirrors *mirrors; + xmlDoc *SetXMLDoc(string xml); + int ParseXML(string xml); + int ReadSeries(string seriesName); +public: + cTVDBScraper(string language); + virtual ~cTVDBScraper(void); + bool Connect(void); + int GetServerTime(void); + cTVDBSeries *ScrapInitial(string seriesName); + bool GetUpdatedSeriesandEpisodes(set<int> *updatedSeries, set<int> *updatedEpisodes, int lastScrap); + cTVDBSeries *GetSeries(int seriesID); + cTVDBEpisode *GetEpisode(int episodeID); +}; + + +#endif //__TVSCRAPER_TVDBSCRAPER_H diff --git a/scraper/thetvdbscraper/tvdbactor.c b/scraper/thetvdbscraper/tvdbactor.c new file mode 100644 index 0000000..f64846a --- /dev/null +++ b/scraper/thetvdbscraper/tvdbactor.c @@ -0,0 +1,66 @@ +#include <iostream> +#include <string> +#include <sstream> +#include <vector> +#include <libxml/parser.h> +#include <libxml/tree.h> +#include "tvdbactor.h" + +using namespace std; + +cTVDBActors::cTVDBActors(string language, cTVDBMirrors *mirrors) { + this->language = language; + this->mirrors = mirrors; +} + +cTVDBActors::~cTVDBActors() { +} + +void cTVDBActors::ParseXML(string xml, vector<cTVDBActor*> *actors) { + xmlDoc *doc = xmlReadMemory(xml.c_str(), xml.size(), "noname.xml", NULL, 0); + if (doc == NULL) + return; + //Root Element has to be <Actors> + xmlNode *node = NULL; + node = xmlDocGetRootElement(doc); + if (!(node && !xmlStrcmp(node->name, (const xmlChar *)"Actors"))) { + xmlFreeDoc(doc); + 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")) { + cTVDBActor *actor = ReadEntry(doc, cur_node->children); + actors->push_back(actor); + } + } + xmlFreeDoc(doc); +} + +cTVDBActor *cTVDBActors::ReadEntry(xmlDoc *doc, 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->thumbUrl = mirrors->GetMirrorBanner() + (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; + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"id")) { + actor->id = atoi((const char *)node_content); + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"SortOrder")) { + actor->sortOrder = atoi((const char *)node_content); + } + xmlFree(node_content); + } + } + return actor; +}
\ No newline at end of file diff --git a/scraper/thetvdbscraper/tvdbactor.h b/scraper/thetvdbscraper/tvdbactor.h new file mode 100644 index 0000000..ed77199 --- /dev/null +++ b/scraper/thetvdbscraper/tvdbactor.h @@ -0,0 +1,54 @@ +#ifndef __TVSCRAPER_TVDBACTORS_H +#define __TVSCRAPER_TVDBACTORS_H + +#include <iostream> +#include <string> +#include <sstream> +#include <vector> +#include <libxml/parser.h> +#include <libxml/tree.h> +#include "tvdbmirrors.h" + +using namespace std; + +// --- cTVDBActor ------------------------------------------------------------- +class cTVDBActor { +public: + cTVDBActor(void) { + thumbUrl = ""; + name = ""; + role = ""; + id = 0; + sortOrder = 0; + thumbUrlWidth = 300; + thumbUrlHeight = 450; + }; + string thumbUrl; + int thumbUrlWidth; + int thumbUrlHeight; + string name; + string role; + int id; + int sortOrder; + void Dump() { + cout << "Actor name: " << name << ", ID: " << id << endl; + cout << "Actor role: " << role << endl; + cout << "Actor thumb: " << thumbUrl << endl; + cout << "Actor SortOrder: " << sortOrder << endl; + } +}; + +// --- cTVDBActors -------------------------------------------------------- + +class cTVDBActors { +private: + cTVDBMirrors *mirrors; + string language; + cTVDBActor *ReadEntry(xmlDoc *doc, xmlNode *node); +public: + cTVDBActors(string language, cTVDBMirrors *mirrors); + virtual ~cTVDBActors(void); + void ParseXML(string xml, vector<cTVDBActor*> *actors); +}; + +#endif //__TVSCRAPER_TVDBACTORS_H diff --git a/scraper/thetvdbscraper/tvdbepisode.c b/scraper/thetvdbscraper/tvdbepisode.c new file mode 100644 index 0000000..b9ac510 --- /dev/null +++ b/scraper/thetvdbscraper/tvdbepisode.c @@ -0,0 +1,147 @@ + +#include <iostream> +#include <string> +#include <sstream> +#include <vector> + +#include <libxml/parser.h> +#include <libxml/tree.h> + +#include "../../lib/curl.h" +#include "tvdbepisode.h" + +using namespace std; + +cTVDBEpisode::cTVDBEpisode(void) { + id = 0; + seriesID = 0; + number = 0; + season = 0; + combinedEpisode = 0; + combinedSeason = 0; + name = ""; + firstAired = ""; + guestStars = ""; + overview = ""; + rating = 0.0; + imageUrl = ""; + width = 400; + height = 225; + imgFlag = 0; + seasonId = 0; + lastUpdated = 0; +} + +cTVDBEpisode::cTVDBEpisode(int ID, string language, string apiKey, cTVDBMirrors *mirrors) { + this->language = language; + this->apiKey = apiKey; + this->mirrors = mirrors; + id = ID; + seriesID = 0; + number = 0; + season = 0; + combinedEpisode = 0; + combinedSeason = 0; + name = ""; + firstAired = ""; + guestStars = ""; + overview = ""; + rating = 0.0; + imageUrl = ""; + width = 400; + height = 225; + imgFlag = 0; + seasonId = 0; + lastUpdated = 0; +} + +void cTVDBEpisode::ReadEpisode(void) { + stringstream url; + url << mirrors->GetMirrorXML() << "/api/" << apiKey << "/episodes/" << id << "/" << language << ".xml"; + string episodeXML; + if (curl.GetUrl(url.str().c_str(), &episodeXML)) { + ParseXML(episodeXML); + } +} + +void cTVDBEpisode::ParseXML(string xml) { + xmlDoc *doc = xmlReadMemory(xml.c_str(), xml.size(), "noname.xml", NULL, 0); + if (doc == NULL) + return; + //Root Element has to be <Data> + xmlNode *node = NULL; + node = xmlDocGetRootElement(doc); + if (!(node && !xmlStrcmp(node->name, (const xmlChar *)"Data"))) { + xmlFreeDoc(doc); + return; + } + //Looping through episodes + 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 *)"Episode")) { + ReadEpisodeFromXML(doc, cur_node->children, mirrors); + } + } + xmlFreeDoc(doc); +} + +void cTVDBEpisode::ReadEpisodeFromXML(xmlDoc *myDoc, xmlNode *node, cTVDBMirrors *mirrors) { + xmlNode *cur_node = NULL; + xmlChar *node_content; + for (cur_node = node; cur_node; cur_node = cur_node->next) { + if (cur_node->type == XML_ELEMENT_NODE) { + node_content = xmlNodeListGetString(myDoc, cur_node->xmlChildrenNode, 1); + if (!node_content) + continue; + if (!xmlStrcmp(cur_node->name, (const xmlChar *)"id")) { + id = atoi((const char *)node_content); + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"EpisodeNumber")) { + number = atoi((const char *)node_content); + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"seriesid")) { + seriesID = atoi((const char *)node_content); + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"SeasonNumber")) { + season = atoi((const char *)node_content); + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Combined_episodenumber")) { + combinedEpisode = atoi((const char *)node_content); + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Combined_season")) { + combinedSeason = atoi((const char *)node_content); + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"EpisodeName")) { + name = (const char *)node_content; + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"FirstAired")) { + firstAired = (const char *)node_content; + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"GuestStars")) { + guestStars = (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 *)"Rating")) { + rating = atof((const char *)node_content); + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"filename")) { + imageUrl = mirrors->GetMirrorBanner() + (const char *)node_content; + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"thumb_width")) { + width = atoi((const char *)node_content); + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"thumb_height")) { + height = atoi((const char *)node_content); + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"EpImgFlag")) { + imgFlag = atoi((const char *)node_content); + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"seasonid")) { + seasonId = atoi((const char *)node_content); + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"lastupdated")) { + lastUpdated = atoi((const char *)node_content); + } + xmlFree(node_content); + } + } +} + +void cTVDBEpisode::Dump() { + cout << "----------------------------------------" << endl; + cout << "Season " << season << ", Episode " << number << ", Name: " << name << ", ID: " << id << ", SeasonID " << seasonId << endl; + cout << "combinedSeason: " << combinedSeason << ", combinedEpisode: " << combinedEpisode << endl; + cout << "First Aired: " << firstAired << endl; + cout << "Guest Stars: " << guestStars << endl; + cout << "Overview: " << overview << endl; + cout << "Rating: " << rating << endl; + cout << "imageUrl: " << imageUrl << ", Size: " << width << " x " << height << ", Flag: " << imgFlag << endl; + cout << "Last Update: " << lastUpdated << endl; +} diff --git a/scraper/thetvdbscraper/tvdbepisode.h b/scraper/thetvdbscraper/tvdbepisode.h new file mode 100644 index 0000000..945278b --- /dev/null +++ b/scraper/thetvdbscraper/tvdbepisode.h @@ -0,0 +1,45 @@ +#ifndef __TVSCRAPER_TVDBEPISODE_H +#define __TVSCRAPER_TVDBEPISODE_H + +#include <iostream> +#include <string> +#include <sstream> +#include <vector> +#include <libxml/parser.h> +#include <libxml/tree.h> +#include "tvdbmirrors.h" + +using namespace std; + +// --- cTVDBEpisode ------------------------------------------------------------- +class cTVDBEpisode { +private: + string apiKey; + cTVDBMirrors *mirrors; + string language; + void ParseXML(string xml); +public: + cTVDBEpisode(void); + cTVDBEpisode(int ID, string language, string apiKey, cTVDBMirrors *mirrors); + int id; + int seriesID; + int number; + int season; + int combinedSeason; + int combinedEpisode; + string name; + string firstAired; + string guestStars; + string overview; + float rating; + string imageUrl; + int width; + int height; + int imgFlag; + int seasonId; + int lastUpdated; + void ReadEpisode(void); + void ReadEpisodeFromXML(xmlDoc *myDoc, xmlNode *node, cTVDBMirrors *mirrors); + void Dump(); +}; +#endif //cTVDBEpisode diff --git a/scraper/thetvdbscraper/tvdbmedia.c b/scraper/thetvdbscraper/tvdbmedia.c new file mode 100644 index 0000000..7495f3b --- /dev/null +++ b/scraper/thetvdbscraper/tvdbmedia.c @@ -0,0 +1,202 @@ +#include "tvdbmedia.h" + +using namespace std; + +cTVDBSeriesMedia::cTVDBSeriesMedia(string language, cTVDBMirrors *mirrors) { + this->language = language; + fallbackLanguage = "en"; + this->mirrors = mirrors; +} + +cTVDBSeriesMedia::~cTVDBSeriesMedia() { +} + +void cTVDBSeriesMedia::ParseXML(string xml, vector<cTVDBBanner*> *banners, vector<cTVDBFanart*> *fanarts, vector<cTVDBPoster*> *posters, vector<cTVDBSeasonPoster*> *seasonPosters) { + xmlDoc *doc = xmlReadMemory(xml.c_str(), xml.size(), "noname.xml", NULL, 0); + this->banners = banners; + this->fanarts = fanarts; + this->posters = posters; + this->seasonPosters = seasonPosters; + if (doc == NULL) + return; + //Root Element has to be <Banners> + xmlNode *node = NULL; + node = xmlDocGetRootElement(doc); + if (!(node && !xmlStrcmp(node->name, (const xmlChar *)"Banners"))) { + xmlFreeDoc(doc); + 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(doc, cur_node->children); + } + } + xmlFreeDoc(doc); +} + +void cTVDBSeriesMedia::ReadEntry(xmlDoc *doc, xmlNode *node) { + xmlNode *cur_node = NULL; + 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 *)"BannerType")) { + + if (!xmlStrcmp(node_content, (const xmlChar *)"poster")) + ReadPoster(doc, node); + else if (!xmlStrcmp(node_content, (const xmlChar *)"fanart")) + ReadFanart(doc, node); + else if (!xmlStrcmp(node_content, (const xmlChar *)"series")) + ReadBanner(doc, node); + else if (!xmlStrcmp(node_content, (const xmlChar *)"season")) + ReadSeasonPoster(doc, node); + + } + xmlFree(node_content); + } + } +} + +void cTVDBSeriesMedia::ReadFanart(xmlDoc *doc, xmlNode *node) { + xmlNode *cur_node = NULL; + xmlChar *node_content; + cTVDBFanart *fanart = new cTVDBFanart(); + //default size + fanart->width = 1920; + fanart->height = 1080; + 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")) { + fanart->url = mirrors->GetMirrorBanner() + (const char *)node_content; + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Language")) { + fanart->language = (const char *)node_content; + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Rating")) { + fanart->rating = atof((const char *)node_content); + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"ThumbnailPath")) { + fanart->thumbUrl = mirrors->GetMirrorBanner() + (const char *)node_content; + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"BannerType2")) { + string fanartSize = (const char *)node_content; + size_t posX = fanartSize.find("x"); + fanart->width = atoi(fanartSize.substr(0, posX).c_str()); + fanart->height = atoi(fanartSize.substr(posX+1).c_str()); + } + xmlFree(node_content); + } + } + if ( (fanart->url.size() == 0) || + ((fanart->language.compare(language)) && (fanart->language.compare(fallbackLanguage)))) { + delete fanart; + return; + } + fanarts->push_back(fanart); +} + +void cTVDBSeriesMedia::ReadPoster(xmlDoc *doc, xmlNode *node) { + xmlNode *cur_node = NULL; + xmlChar *node_content; + cTVDBPoster *poster = new cTVDBPoster(); + //default size + poster->width = 400; + poster->height = 578; + 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")) { + poster->url = mirrors->GetMirrorBanner() + (const char *)node_content; + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Language")) { + poster->language = (const char *)node_content; + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Rating")) { + poster->rating = atof((const char *)node_content); + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"BannerType2")) { + string posterSize = (const char *)node_content; + size_t posX = posterSize.find("x"); + poster->width = atoi(posterSize.substr(0, posX).c_str()); + poster->height = atoi(posterSize.substr(posX+1).c_str()); + } + xmlFree(node_content); + } + } + if ( (poster->url.size() == 0) || + ((poster->language.compare(language)) && (poster->language.compare(fallbackLanguage)))) { + delete poster; + return; + } + posters->push_back(poster); +} + +void cTVDBSeriesMedia::ReadSeasonPoster(xmlDoc *doc, xmlNode *node) { + xmlNode *cur_node = NULL; + xmlChar *node_content; + cTVDBSeasonPoster *poster = new cTVDBSeasonPoster(); + poster->width = 400; + poster->height = 578; + bool add = true; + 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")) { + poster->url = mirrors->GetMirrorBanner() + (const char *)node_content; + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Language")) { + poster->language = (const char *)node_content; + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Rating")) { + poster->rating = atof((const char *)node_content); + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Season")) { + poster->season = atoi((const char *)node_content); + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"BannerType2")) { + string bt2 = (const char *)node_content; + if (!bt2.compare("seasonwide")) + add = false; + } + xmlFree(node_content); + } + } + if ( (poster->url.size() == 0) || + (poster->season == 0) || + (!add) || + ((poster->language.compare(language)) && (poster->language.compare(fallbackLanguage)))) { + delete poster; + return; + } + seasonPosters->push_back(poster); +} + +void cTVDBSeriesMedia::ReadBanner(xmlDoc *doc, xmlNode *node) { + xmlNode *cur_node = NULL; + xmlChar *node_content; + cTVDBBanner *banner = new cTVDBBanner(); + banner->width = 758; + banner->height = 140; + 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")) { + banner->url = mirrors->GetMirrorBanner() + (const char *)node_content; + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Language")) { + banner->language = (const char *)node_content; + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Rating")) { + banner->rating = atof((const char *)node_content); + } + xmlFree(node_content); + } + } + if ( (banner->url.size() == 0) || + ((banner->language.compare(language)) && (banner->language.compare(fallbackLanguage)))) { + delete banner; + return; + } + banners->push_back(banner); +} diff --git a/scraper/thetvdbscraper/tvdbmedia.h b/scraper/thetvdbscraper/tvdbmedia.h new file mode 100644 index 0000000..4277c39 --- /dev/null +++ b/scraper/thetvdbscraper/tvdbmedia.h @@ -0,0 +1,111 @@ +#ifndef __TVSCRAPER_TVDBMEDIA_H +#define __TVSCRAPER_TVDBMEDIA_H + +#include <iostream> +#include <string> +#include <sstream> +#include <vector> +#include <libxml/parser.h> +#include <libxml/tree.h> +#include "tvdbmirrors.h" + +using namespace std; + +// --- cTVDBMedia ------------------------------------------------------------- +class cTVDBMedia { +public: + cTVDBMedia(void) { + url = ""; + language = ""; + width = 0; + height = 0; + rating = 0.0; + }; + string url; + string language; + int width, height; + double rating; +}; + +// --- cTVDBFanart ------------------------------------------------------------- +class cTVDBFanart : public cTVDBMedia { +public: + cTVDBFanart(void) { + thumbUrl = ""; + }; + string thumbUrl; + void Dump() { + cout << "Url: " << url << endl; + cout << "Url Thumbnail: " << thumbUrl << endl; + cout << "Language: " << language << endl; + cout << "Size: " << width << " x " << height << endl; + cout << "Rating: " << rating << endl; + }; +}; + +// --- cTVDBPoster ------------------------------------------------------------- +class cTVDBPoster : public cTVDBMedia { +public: + cTVDBPoster(void) { + }; + void Dump() { + cout << "Url: " << url << endl; + cout << "Language: " << language << endl; + cout << "Size: " << width << " x " << height << endl; + cout << "Rating: " << rating << endl; + }; +}; + +// --- cTVDBSeasonPoster ------------------------------------------------------------- +class cTVDBSeasonPoster : public cTVDBMedia { +public: + cTVDBSeasonPoster(void) { + season = 0; + }; + int season; + void Dump() { + cout << "Url: " << url << endl; + cout << "Season: " << season << endl; + cout << "Language: " << language << endl; + cout << "Size: " << width << " x " << height << endl; + cout << "Rating: " << rating << endl; + }; +}; + +// --- cTVDBBanner ------------------------------------------------------------- +class cTVDBBanner : public cTVDBMedia { +public: + cTVDBBanner(void) { + }; + int season; + void Dump() { + cout << "Url: " << url << endl; + cout << "Language: " << language << endl; + cout << "Size: " << width << " x " << height << endl; + cout << "Rating: " << rating << endl; + }; +}; + +// --- cTVDBSeriesMedia -------------------------------------------------------- + +class cTVDBSeriesMedia { +private: + string language; + string fallbackLanguage; + cTVDBMirrors *mirrors; + vector<cTVDBBanner*> *banners; + vector<cTVDBFanart*> *fanarts; + vector<cTVDBPoster*> *posters; + vector<cTVDBSeasonPoster*> *seasonPosters; + void ReadEntry(xmlDoc *doc, xmlNode *node); + void ReadFanart(xmlDoc *doc, xmlNode *node); + void ReadPoster(xmlDoc *doc, xmlNode *node); + void ReadBanner(xmlDoc *doc, xmlNode *node); + void ReadSeasonPoster(xmlDoc *doc, xmlNode *node); +public: + cTVDBSeriesMedia(string language, cTVDBMirrors *mirrors); + virtual ~cTVDBSeriesMedia(void); + void ParseXML(string xml, vector<cTVDBBanner*> *banners, vector<cTVDBFanart*> *fanarts, vector<cTVDBPoster*> *posters, vector<cTVDBSeasonPoster*> *seasonPosters); +}; + +#endif //__TVSCRAPER_TVDBMEDIA_H diff --git a/scraper/thetvdbscraper/tvdbmirrors.c b/scraper/thetvdbscraper/tvdbmirrors.c new file mode 100644 index 0000000..2c063ec --- /dev/null +++ b/scraper/thetvdbscraper/tvdbmirrors.c @@ -0,0 +1,88 @@ +#include "tvdbmirrors.h" + +using namespace std; + +cTVDBMirrors::cTVDBMirrors(void) { +} + +cTVDBMirrors::~cTVDBMirrors() { +} + +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] + "/banners/"; +} + +string cTVDBMirrors::GetMirrorZip(void) { + if (zipmirrors.size() == 0) + return ""; + int randMirror = rand() % zipmirrors.size(); + return zipmirrors[randMirror]; +} + +bool cTVDBMirrors::ParseXML(string xml) { + xmlDoc *doc = xmlReadMemory(xml.c_str(), xml.size(), "noname.xml", NULL, 0); + 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"))) { + xmlFreeDoc(doc); + 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(doc, cur_node->children); + } + } + xmlFreeDoc(doc); + return ok; +} + +bool cTVDBMirrors::ReadEntry(xmlDoc *doc, 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/scraper/thetvdbscraper/tvdbmirrors.h b/scraper/thetvdbscraper/tvdbmirrors.h new file mode 100644 index 0000000..cf7dc62 --- /dev/null +++ b/scraper/thetvdbscraper/tvdbmirrors.h @@ -0,0 +1,32 @@ +#ifndef __TVSCRAPER_TVDBMIRRORS_H +#define __TVSCRAPER_TVDBMIRRORS_H + +#include <iostream> +#include <string> +#include <sstream> +#include <vector> +#include <libxml/parser.h> +#include <libxml/tree.h> + +using namespace std; + +// --- cTVDBMirrors ------------------------------------------------------------- + +class cTVDBMirrors { +private: + vector<string> xmlmirrors; + vector<string> bannermirrors; + vector<string> zipmirrors; + bool ReadEntry(xmlDoc *doc, xmlNode *node); + bool CreateMirror(string path, int typemask); +public: + cTVDBMirrors(void); + virtual ~cTVDBMirrors(void); + bool ParseXML(string xml); + string GetMirrorXML(void); + string GetMirrorBanner(void); + string GetMirrorZip(void); +}; + + +#endif //__TVSCRAPER_TVDBMIRRORS_H diff --git a/scraper/thetvdbscraper/tvdbseries.c b/scraper/thetvdbscraper/tvdbseries.c new file mode 100644 index 0000000..21dc78b --- /dev/null +++ b/scraper/thetvdbscraper/tvdbseries.c @@ -0,0 +1,281 @@ + +#include "../../lib/curl.h" +#include "tvdbseries.h" + +using namespace std; + +cTVDBSeries::cTVDBSeries(int ID, string language, string apiKey, cTVDBMirrors *mirrors) { + this->language = language; + this->apiKey = apiKey; + this->mirrors = mirrors; + seriesID = ID; + name = ""; + banner = ""; + fanart = ""; + poster = ""; + overview = ""; + firstAired = ""; + network = ""; + imbdid = ""; + genre = ""; + rating = 0.0; + status = ""; + currentEpisode = 0; + currentActor = 0; + currentFanart = 0; + currentPoster = 0; + currentSeasonPoster = 0; + currentBanner = 0; +} + +cTVDBSeries::~cTVDBSeries() { + for(std::vector<cTVDBEpisode*>::const_iterator it = episodes.begin(); it != episodes.end(); it++) { + delete *it; + } + episodes.clear(); + for(std::vector<cTVDBActor*>::const_iterator it = actors.begin(); it != actors.end(); it++) { + delete *it; + } + actors.clear(); + for(std::vector<cTVDBFanart*>::const_iterator it = fanarts.begin(); it != fanarts.end(); it++) { + delete *it; + } + fanarts.clear(); + for(std::vector<cTVDBPoster*>::const_iterator it = posters.begin(); it != posters.end(); it++) { + delete *it; + } + posters.clear(); + for(std::vector<cTVDBSeasonPoster*>::const_iterator it = seasonPosters.begin(); it != seasonPosters.end(); it++) { + delete *it; + } + seasonPosters.clear(); + for(std::vector<cTVDBBanner*>::const_iterator it = banners.begin(); it != banners.end(); it++) { + delete *it; + } + banners.clear(); +} + +bool cTVDBSeries::ReadSeries(void) { + stringstream url; + url << mirrors->GetMirrorXML() << "/api/" << apiKey << "/series/" << seriesID << "/all/" << language << ".xml"; + string seriesXML; + if (curl.GetUrl(url.str().c_str(), &seriesXML)) { + ParseXML(seriesXML); + return true; + } + return false; +} + +void cTVDBSeries::ReadMedia(void) { + stringstream url; + url << mirrors->GetMirrorXML() << "/api/" << apiKey << "/series/" << seriesID << "/banners.xml"; + string bannersXML; + if (curl.GetUrl(url.str().c_str(), &bannersXML)) { + cTVDBSeriesMedia med(language, mirrors); + med.ParseXML(bannersXML, &banners, &fanarts, &posters, &seasonPosters); + } +} + +void cTVDBSeries::ReadActors(void) { + stringstream url; + url << mirrors->GetMirrorXML() << "/api/" << apiKey << "/series/" << seriesID << "/actors.xml"; + string actorsXML; + if (curl.GetUrl(url.str().c_str(), &actorsXML)) { + cTVDBActors act(language, mirrors); + act.ParseXML(actorsXML, &actors); + } +} + +void cTVDBSeries::ParseXML(string xml) { + xmlDoc *doc = xmlReadMemory(xml.c_str(), xml.size(), "noname.xml", NULL, 0); + if (doc == NULL) + return; + //Root Element has to be <Data> + xmlNode *node = NULL; + node = xmlDocGetRootElement(doc); + if (!(node && !xmlStrcmp(node->name, (const xmlChar *)"Data"))) { + xmlFreeDoc(doc); + return; + } + //Looping through episodes + 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")) { + ReadSeriesData(doc, cur_node->children); + } else if ((cur_node->type == XML_ELEMENT_NODE) && !xmlStrcmp(cur_node->name, (const xmlChar *)"Episode")) { + cTVDBEpisode *episode = new cTVDBEpisode(); + episode->ReadEpisodeFromXML(doc, cur_node->children, mirrors); + episodes.push_back(episode); + } + } + xmlFreeDoc(doc); +} + +void cTVDBSeries::ReadSeriesData(xmlDoc *doc, xmlNode *node) { + xmlNode *cur_node = NULL; + 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 *)"FirstAired")) { + firstAired = (const char *)node_content; + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Genre")) { + genre = (const char *)node_content; + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"IMDB_ID")) { + imbdid = (const char *)node_content; + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Network")) { + network = (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 *)"Rating")) { + rating = atof((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 *)"Status")) { + status = (const char *)node_content; + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"banner")) { + banner = mirrors->GetMirrorBanner() + (const char *)node_content; + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"fanart")) { + fanart = mirrors->GetMirrorBanner() + (const char *)node_content; + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"poster")) { + poster = mirrors->GetMirrorBanner() + (const char *)node_content; + } else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"lastupdated")) { + lastUpdated = atoi((const char *)node_content); + } + xmlFree(node_content); + } + } +} + +cTVDBEpisode *cTVDBSeries::GetEpisode(void) { + int numEpisodes = episodes.size(); + if ((numEpisodes < 1) || (currentEpisode >= numEpisodes)) + return NULL; + cTVDBEpisode *epi = episodes[currentEpisode]; + currentEpisode++; + return epi; +} + +cTVDBActor *cTVDBSeries::GetActor(void) { + int numActors = actors.size(); + if ((numActors < 1) || (currentActor >= numActors)) + return NULL; + cTVDBActor *act = actors[currentActor]; + currentActor++; + return act; +} + +cTVDBFanart *cTVDBSeries::GetFanart(void) { + int numFanarts = fanarts.size(); + if ((numFanarts < 1) || (currentFanart >= numFanarts)) + return NULL; + cTVDBFanart *fan = fanarts[currentFanart]; + currentFanart++; + return fan; +} + +cTVDBPoster *cTVDBSeries::GetPoster(void) { + int numPosters = posters.size(); + if ((numPosters < 1) || (currentPoster >= numPosters)) + return NULL; + cTVDBPoster *pos = posters[currentPoster]; + currentPoster++; + return pos; +} + +cTVDBSeasonPoster *cTVDBSeries::GetSeasonPoster(void) { + int numSeasonPosters = seasonPosters.size(); + if ((numSeasonPosters < 1) || (currentSeasonPoster >= numSeasonPosters)) + return NULL; + cTVDBSeasonPoster *pos = seasonPosters[currentSeasonPoster]; + currentSeasonPoster++; + return pos; +} + +cTVDBSeasonPoster *cTVDBSeries::GetSeasonPoster(int season) { + int numSeasonPoster = seasonPosters.size(); + for (int i=0; i<numSeasonPoster; i++) { + if (seasonPosters[i]->season == season) + return seasonPosters[i]; + } + return NULL; +} + +cTVDBBanner *cTVDBSeries::GetBanner(void) { + int numBanners = banners.size(); + if ((numBanners < 1) || (currentBanner >= numBanners)) + return NULL; + cTVDBBanner *ban = banners[currentBanner]; + currentBanner++; + return ban; +} + +bool cTVDBSeries::GetPartAndSeason(int episodeId, int &season, int &part) { + for (vector<cTVDBEpisode*>::iterator ep = episodes.begin(); ep != episodes.end(); ep++) { + cTVDBEpisode *episode = *ep; + if(episode->id == episodeId) { + season = episode->season; + part = episode->number; + return true; + } + } + return false; +} + +void cTVDBSeries::Dump(int maxEntries) { + cout << "--------------------------- Series Info ----------------------------------" << endl; + cout << "series " << name << ", ID: " << seriesID <<endl; + cout << "Overview: " << overview << endl; + cout << "Banner: " << banner << endl; + cout << "Poster: " << poster << endl; + cout << "Fanart: " << fanart << endl; + cout << "imdb: " << imbdid << endl; + cout << "FirstAired: " << firstAired << endl; + cout << "Network: " << network << endl; + cout << "Status: " << status << endl; + cout << "lastUpdated: " << lastUpdated << endl; + cout << "Genre: " << genre << endl; + cout << "Rating: " << rating << endl; + + int size = episodes.size(); + cout << "--------------------------- " << size << " episodes ----------------------------------" << endl; + for (int i=0; i<size; i++) { + if (maxEntries && (i == maxEntries)) break; + episodes[i]->Dump(); + } + + size = actors.size(); + cout << "--------------------------- " << size << " actors ----------------------------------" << endl; + for (int i=0; i<size; i++) { + if (maxEntries && (i == maxEntries)) break; + actors[i]->Dump(); + } + + int numFanart = fanarts.size(); + cout << "--------------------------- " << numFanart << " fanarts ----------------------------------" << endl; + for (int i=0; i<numFanart; i++) { + if (maxEntries && (i == maxEntries)) break; + fanarts[i]->Dump(); + } + int numPoster = posters.size(); + cout << "--------------------------- " << numPoster << " posters ----------------------------------" << endl; + for (int i=0; i<numPoster; i++) { + if (maxEntries && (i == maxEntries)) break; + posters[i]->Dump(); + } + int numSeasonPoster = seasonPosters.size(); + cout << "--------------------------- " << numSeasonPoster << " season posters ---------------------------" << endl; + for (int i=0; i<numSeasonPoster; i++) { + if (maxEntries && (i == maxEntries)) break; + seasonPosters[i]->Dump(); + } + int numBanner = banners.size(); + cout << "--------------------------- " << numBanner << " banners ----------------------------------" << endl; + for (int i=0; i<numBanner; i++) { + if (maxEntries && (i == maxEntries)) break; + banners[i]->Dump(); + } +} diff --git a/scraper/thetvdbscraper/tvdbseries.h b/scraper/thetvdbscraper/tvdbseries.h new file mode 100644 index 0000000..bf7a84d --- /dev/null +++ b/scraper/thetvdbscraper/tvdbseries.h @@ -0,0 +1,69 @@ +#ifndef __TVSCRAPER_TVDBSERIES_H +#define __TVSCRAPER_TVDBSERIES_H + +#include <iostream> +#include <string> +#include <sstream> +#include <vector> +#include <libxml/parser.h> +#include <libxml/tree.h> +#include "tvdbmirrors.h" +#include "tvdbactor.h" +#include "tvdbmedia.h" +#include "tvdbepisode.h" + +using namespace std; + +// --- cTVDBSeries ------------------------------------------------------------- + +class cTVDBSeries { +private: + string apiKey; + cTVDBMirrors *mirrors; + string language; + vector<cTVDBEpisode*> episodes; + vector<cTVDBActor*> actors; + vector<cTVDBFanart*> fanarts; + vector<cTVDBPoster*> posters; + vector<cTVDBSeasonPoster*> seasonPosters; + vector<cTVDBBanner*> banners; + int currentEpisode; + int currentActor; + int currentFanart; + int currentPoster; + int currentSeasonPoster; + int currentBanner; + void ParseXML(string xml); + void ReadSeriesData(xmlDoc *doc, xmlNode *node); +public: + cTVDBSeries(int ID, string language, string apiKey, cTVDBMirrors *mirrors); + virtual ~cTVDBSeries(void); + bool ReadSeries(void); + void ReadMedia(void); + void ReadActors(void); + cTVDBEpisode *GetEpisode(void); + cTVDBActor *GetActor(void); + cTVDBFanart *GetFanart(void); + cTVDBPoster *GetPoster(void); + cTVDBSeasonPoster *GetSeasonPoster(void); + cTVDBSeasonPoster *GetSeasonPoster(int season); + cTVDBBanner *GetBanner(void); + bool GetPartAndSeason(int episodeId, int &season, int &part); + int seriesID; + int lastUpdated; + string name; + string banner; + string fanart; + string poster; + string overview; + string firstAired; + string network; + string imbdid; + string genre; + float rating; + string status; + void Dump(int maxEntries = 0); +}; + + +#endif //__TVSCRAPER_TVDBSERIES_H |