From ca71c83e5d68f7995442c5c3a9f0d61fed1d2224 Mon Sep 17 00:00:00 2001 From: louis Date: Fri, 9 May 2014 01:05:21 +0200 Subject: [PATCH] Version 0.1.2 --- HISTORY | 11 + Makefile | 13 +- lib/Makefile | 11 +- lib/common.c | 426 +++++++++++++++++- lib/common.h | 116 ++++- lib/config.c | 6 + lib/config.h | 7 + lib/db.c | 122 ++++- lib/db.h | 72 ++- lib/tabledef.c | 2 +- lib/tabledef.h | 8 +- moviedbmovie.c | 258 +++++------ moviedbmovie.h | 196 ++++---- scraper2vdr.h | 114 ++--- scrapmanager.c | 1164 ++++++++++++++++++++++++------------------------ scrapmanager.h | 162 +++---- services.h | 386 ++++++++-------- setup.c | 7 +- tools.c | 358 +++++++-------- tools.h | 62 +-- tvdbseries.c | 578 ++++++++++++------------ tvdbseries.h | 286 ++++++------ update.c | 973 +++++++++++++++++++++------------------- update.h | 28 +- 24 files changed, 3061 insertions(+), 2305 deletions(-) diff --git a/HISTORY b/HISTORY index 7fbbe23..a1dfdee 100644 --- a/HISTORY +++ b/HISTORY @@ -14,3 +14,14 @@ Version 0.1.0 - fixed bug that scraped events are not displayed randomly Version 0.1.1 + +- update of db api +- prepare statements only once +- added statement statistic +- minor changes +- changed mail loop timing +- added path detection for libmysql +- fixed epgd state detection +- added cppcheck to Makefile + +Version 0.1.2 diff --git a/Makefile b/Makefile index 209effe..d2dd336 100644 --- a/Makefile +++ b/Makefile @@ -25,7 +25,7 @@ TMPDIR ?= /tmp ### The compiler options: export CFLAGS = $(call PKGCFG,cflags) -export CXXFLAGS = $(call PKGCFG,cxxflags) +export CXXFLAGS = $(call PKGCFG,cxxflags) -Wno-unused-result -Wunused-value -Wunused-variable -Wreturn-type -Wuninitialized -Wsign-compare ### The version number of VDR's plugin API: @@ -35,7 +35,7 @@ APIVERSION = $(call PKGCFG,apiversion) -include $(PLGCFG) -LIBS = -lmysqlclient_r -luuid +LIBS = $(shell mysql_config --libs_r) -luuid ### The name of the distribution archive: @@ -48,9 +48,9 @@ SOFILE = libvdr-$(PLUGIN).so ### Includes and Defines (add further entries here): -INCLUDES += +INCLUDES += $(shell mysql_config --include) -DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"' +DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"' -DLOG_PREFIX='"$(PLUGIN): "' DEFINES += -DVDR_PLUGIN -DUSEUUID ifeq ($(IMAGELIB), imagemagick) @@ -129,4 +129,7 @@ dist: $(I18Npo) clean clean: @-rm -f $(PODIR)/*.mo $(PODIR)/*.pot - @-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~ + @-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~ lib/*~ + +cppchk: + cppcheck --template="{file}:{line}:{severity}:{message}" --quiet --force *.c *.h lib/*.c lib/*.h diff --git a/lib/Makefile b/lib/Makefile index f27782b..0716ea6 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -1,7 +1,14 @@ +BASELIBS = -lrt -lz -lmysqlclient -lcurl -luuid +BASELIBS += $(shell mysql_config --libs) + +CFLAGS += $(shell mysql_config --include) all: - g++ -ggdb -DPLGDIR='"."' test.c common.c config.c db.c tabledef.c -lrt -lz -lmysqlclient -o t + g++ -ggdb -DPLGDIR='"."' $(CFLAGS) test.c dbdict.c common.c config.c db.c tabledef.c $(BASELIBS) -o t + +demo: demo.c + g++ -ggdb -DUSEUUID -DPLGDIR='"."' $(CFLAGS) demo.c common.c db.c tabledef.c config.c $(BASELIBS) -o demo clean: - rm -f *.o *.a *~ core + rm -f *.o *.a *~ core demo diff --git a/lib/common.c b/lib/common.c index f3a0436..b5130a7 100644 --- a/lib/common.c +++ b/lib/common.c @@ -6,6 +6,7 @@ */ #include +#include #ifdef USEUUID # include @@ -17,6 +18,7 @@ #include #include #include +#include #ifdef USELIBARCHIVE # include @@ -54,7 +56,7 @@ void tell(int eloquence, const char* format, ...) va_start(ap, format); #ifdef VDR_PLUGIN - snprintf(t, sizeBuffer, "scraper2vdr: "); + snprintf(t, sizeBuffer, LOG_PREFIX); #endif vsnprintf(t+strlen(t), sizeBuffer-strlen(t), format, ap); @@ -62,10 +64,18 @@ void tell(int eloquence, const char* format, ...) if (EPG2VDRConfig.logstdout) { char buf[50+TB]; - time_t now; - time(&now); - strftime(buf, 50, "%y.%m.%d %H:%M:%S", localtime(&now)); + timeval tp; + + gettimeofday(&tp, 0); + + tm* tm = localtime(&tp.tv_sec); + + sprintf(buf,"%2.2d:%2.2d:%2.2d,%3.3ld ", + tm->tm_hour, tm->tm_min, tm->tm_sec, + tp.tv_usec / 1000); + printf("%s %s\n", buf, t); + } else syslog(LOG_ERR, "%s", t); @@ -73,6 +83,36 @@ void tell(int eloquence, const char* format, ...) va_end(ap); } +//*************************************************************************** +// Save Realloc +//*************************************************************************** + +char* srealloc(void* ptr, size_t size) +{ + void* n = realloc(ptr, size); + + if (!n) + { + free(ptr); + ptr = 0; + } + + return (char*)n; +} + +//*************************************************************************** +// us now +//*************************************************************************** + +double usNow() +{ + struct timeval tp; + + gettimeofday(&tp, 0); + + return tp.tv_sec * 1000000.0 + tp.tv_usec; +} + //*************************************************************************** // Host ID //*************************************************************************** @@ -121,6 +161,38 @@ void toUpper(std::string& str) free(dest); } +//*************************************************************************** +// To Case (UTF-8 save) +//*************************************************************************** + +const char* toCase(Case cs, char* str) +{ + char* s = str; + int lenSrc = strlen(str); + + int csSrc; // size of character + + for (int ps = 0; ps < lenSrc; ps += csSrc) + { + csSrc = max(mblen(&s[ps], lenSrc-ps), 1); + + if (csSrc == 1) + s[ps] = cs == cUpper ? toupper(s[ps]) : tolower(s[ps]); + else if (csSrc == 2 && s[ps] == (char)0xc3 && s[ps+1] >= (char)0xa0) + { + s[ps] = s[ps]; + s[ps+1] = cs == cUpper ? toupper(s[ps+1]) : tolower(s[ps+1]); + } + else + { + for (int i = 0; i < csSrc; i++) + s[ps+i] = s[ps+i]; + } + } + + return str; +} + void removeChars(std::string& str, const char* ignore) { const char* s = str.c_str(); @@ -329,6 +401,86 @@ const char* c2s(char c, char* buf) return buf; } +//*************************************************************************** +// Store To File +//*************************************************************************** + +int storeToFile(const char* filename, const char* data, int size) +{ + FILE* fout; + + if ((fout = fopen(filename, "w+"))) + { + fwrite(data, sizeof(char), size, fout); + fclose(fout); + } + else + { + tell(0, "Error, can't store '%s' to filesystem '%s'", filename, strerror(errno)); + return fail; + } + + return success; +} + +//*************************************************************************** +// Load From File +//*************************************************************************** + +int loadFromFile(const char* infile, MemoryStruct* data) +{ + FILE* fin; + struct stat sb; + + data->clear(); + + if (!fileExists(infile)) + { + tell(0, "File '%s' not found'", infile); + return fail; + } + + if (stat(infile, &sb) < 0) + { + tell(0, "Can't get info of '%s', error was '%s'", infile, strerror(errno)); + return fail; + } + + if ((fin = fopen(infile, "r"))) + { + const char* sfx = suffixOf(infile); + + data->size = sb.st_size; + data->modTime = sb.st_mtime; + data->memory = (char*)malloc(data->size); + fread(data->memory, sizeof(char), data->size, fin); + fclose(fin); + sprintf(data->tag, "%ld", data->size); + + if (strcmp(sfx, "gz") == 0) + sprintf(data->contentEncoding, "gzip"); + + if (strcmp(sfx, "js") == 0) + sprintf(data->contentType, "application/javascript"); + + else if (strcmp(sfx, "png") == 0 || strcmp(sfx, "jpg") == 0 || strcmp(sfx, "gif") == 0) + sprintf(data->contentType, "image/%s", sfx); + + else if (strcmp(sfx, "ico") == 0) + strcpy(data->contentType, "image/x-icon"); + + else + sprintf(data->contentType, "text/%s", sfx); + } + else + { + tell(0, "Error, can't open '%s' for reading, error was '%s'", infile, strerror(errno)); + return fail; + } + + return success; +} + //*************************************************************************** // TOOLS //*************************************************************************** @@ -338,6 +490,33 @@ int isEmpty(const char* str) return !str || !*str; } +const char* notNull(const char* str) +{ + if (!str) + return ""; + + return str; +} + +int isZero(const char* str) +{ + const char* p = str; + + while (p && *p) + { + if (*p != '0') + return no; + + p++; + } + + return yes; +} + +//*************************************************************************** +// +//*************************************************************************** + char* sstrcpy(char* dest, const char* src, int max) { if (!dest || !src) @@ -356,11 +535,21 @@ int isLink(const char* path) if (lstat(path, &sb) == 0) return S_ISLNK(sb.st_mode); - tell(0, "Error: Detecting state for '%s' failed, error was '%m'", path); + tell(0, "Error: Detecting state for '%s' failed, error was '%s'", path, strerror(errno)); return false; } +const char* suffixOf(const char* path) +{ + const char* p; + + if (path && (p = strrchr(path, '.'))) + return p+1; + + return ""; +} + int fileSize(const char* path) { struct stat sb; @@ -368,9 +557,21 @@ int fileSize(const char* path) if (lstat(path, &sb) == 0) return sb.st_size; - tell(0, "Error: Detecting state for '%s' failed, error was '%m'", path); + tell(0, "Error: Detecting state for '%s' failed, error was '%s'", path, strerror(errno)); - return false; + return 0; +} + +time_t fileModTime(const char* path) +{ + struct stat sb; + + if (lstat(path, &sb) == 0) + return sb.st_mtime; + + tell(0, "Error: Detecting state for '%s' failed, error was '%s'", path, strerror(errno)); + + return 0; } @@ -390,7 +591,7 @@ int createLink(const char* link, const char* dest, int force) if (symlink(dest, link) != 0) { - tell(0, "Failed to create symlink '%s', error was '%m'", link); + tell(0, "Failed to create symlink '%s', error was '%s'", link, strerror(errno)); return fail; } } @@ -408,7 +609,7 @@ int removeFile(const char* filename) if (unlink(filename) != 0) { - tell(0, "Can't remove file '%s', '%m'", filename); + tell(0, "Can't remove file '%s', '%s'", filename, strerror(errno)); return 1; } @@ -432,7 +633,7 @@ int chkDir(const char* path) if (mkdir(path, ACCESSPERMS) == -1) { - tell(0, "Can't create directory '%m'"); + tell(0, "Can't create directory '%s'", strerror(errno)); return fail; } } @@ -541,6 +742,63 @@ int gunzip(MemoryStruct* zippedData, MemoryStruct* unzippedData) return success; } +//*************************************************************************** +// gzip +//*************************************************************************** + +int _gzip(Bytef* dest, uLongf* destLen, const Bytef* source, uLong sourceLen) +{ + z_stream stream; + int res; + + stream.next_in = (Bytef *)source; + stream.avail_in = (uInt)sourceLen; + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + if ((res = deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 + 16, 8, Z_DEFAULT_STRATEGY)) != Z_OK) + return res; + + res = deflate(&stream, Z_FINISH); + + if (res != Z_STREAM_END) + { + deflateEnd(&stream); + return res == Z_OK ? Z_BUF_ERROR : res; + } + + *destLen = stream.total_out; + res = deflateEnd(&stream); + + return res; +} + +int gzip(MemoryStruct* data, MemoryStruct* zippedData) +{ + int res; + uLong sizeMax = compressBound(data->size) + 512; + + zippedData->clear(); + zippedData->memory = (char*)malloc(sizeMax); + + if ((res = _gzip((Bytef*)zippedData->memory, &sizeMax, (Bytef*)data->memory, data->size)) != Z_OK) + { + tellZipError(res, " during compression", ""); + return fail; + } + + zippedData->copyAttributes(data); + zippedData->size = sizeMax; + sprintf(zippedData->contentEncoding, "gzip"); + + return success; +} + //************************************************************************* // tellZipError //************************************************************************* @@ -554,11 +812,11 @@ void tellZipError(int errorCode, const char* op, const char* msg) { case Z_OK: return; case Z_STREAM_END: return; - case Z_MEM_ERROR: tell(0, "Error: Not enough memory to unzip file%s!\n", op); return; - case Z_BUF_ERROR: tell(0, "Error: Couldn't unzip data due to output buffer size problem%s!\n", op); return; + case Z_MEM_ERROR: tell(0, "Error: Not enough memory to zip/unzip file%s!\n", op); return; + case Z_BUF_ERROR: tell(0, "Error: Couldn't zip/unzip data due to output buffer size problem%s!\n", op); return; case Z_DATA_ERROR: tell(0, "Error: Zipped input data corrupted%s! Details: %s\n", op, msg); return; case Z_STREAM_ERROR: tell(0, "Error: Invalid stream structure%s. Details: %s\n", op, msg); return; - default: tell(0, "Error: Couldn't unzip data for unknown reason (%6d)%s!\n", errorCode, op); return; + default: tell(0, "Error: Couldn't zip/unzip data for unknown reason (%6d)%s!\n", errorCode, op); return; } } @@ -659,7 +917,7 @@ int unzip(const char* file, const char* filter, char*& buffer, int& size, char* if (r != ARCHIVE_OK) { - tell(0, "Error: Open '%s' failed - %m", file); + tell(0, "Error: Open '%s' failed - %s", file, strerror(errno)); return 1; } @@ -720,13 +978,13 @@ LogDuration::LogDuration(const char* aMessage, int aLogLevel) LogDuration::~LogDuration() { - tell(logLevel, "duration '%s' was (%dms)", + tell(logLevel, "duration '%s' was (%ldms)", message, cTimeMs::Now() - durationStart); } void LogDuration::show(const char* label) { - tell(logLevel, "elapsed '%s' at '%s' was (%dms)", + tell(logLevel, "elapsed '%s' at '%s' was (%ldms)", message, label, cTimeMs::Now() - durationStart); } @@ -785,7 +1043,7 @@ int createMd5OfFile(const char* path, const char* name, md5* md5) if (!(f = fopen(file, "r"))) { - tell(0, "Fatal: Can't access '%s'; %m", file); + tell(0, "Fatal: Can't access '%s'; %s", file, strerror(errno)); free(file); return fail; } @@ -810,3 +1068,137 @@ int createMd5OfFile(const char* path, const char* name, md5* md5) } #endif // USEMD5 + +//*************************************************************************** +// Url Unescape +//*************************************************************************** +/* + * The buffer pointed to by @dst must be at least strlen(@src) bytes. + * Decoding stops at the first character from @src that decodes to null. + + * Path normalization will remove redundant slashes and slash+dot sequences, + * as well as removing path components when slash+dot+dot is found. It will + * keep the root slash (if one was present) and will stop normalization + * at the first questionmark found (so query parameters won't be normalized). + * + * @param dst destination buffer + * @param src source buffer + * @param normalize perform path normalization if nonzero + * @return number of valid characters in @dst + */ + +int urlUnescape(char* dst, const char* src, int normalize) +{ +// CURL* curl; +// int resultSize; + +// if (curl_global_init(CURL_GLOBAL_ALL) != 0) +// { +// tell(0, "Error, something went wrong with curl_global_init()"); + +// return fail; +// } + +// curl = curl_easy_init(); + +// if (!curl) +// { +// tell(0, "Error, unable to get handle from curl_easy_init()"); + +// return fail; +// } + +// dst = curl_easy_unescape(curl, src, strlen(src), &resultSize); + +// tell(0, " [%.40s]", src); + +// tell(0, "res size %d [%.40s]", resultSize, dst); +// return resultSize; + + char* org_dst = dst; + int slash_dot_dot = 0; + char ch, a, b; + + a = 0; + + do { + ch = *src++; + + if (ch == '%' && isxdigit(a = src[0]) && isxdigit(b = src[1])) + { + if (a < 'A') + a -= '0'; + else if + (a < 'a') a -= 'A' - 10; + else + a -= 'a' - 10; + + if (b < 'A') + b -= '0'; + else if (b < 'a') + b -= 'A' - 10; + else + b -= 'a' - 10; + + ch = 16 * a + b; + src += 2; + } + + if (normalize) + { + switch (ch) + { + case '/': // compress consecutive slashes and remove slash-dot + if (slash_dot_dot < 3) + { + + dst -= slash_dot_dot; + slash_dot_dot = 1; + break; + } + // fall-through + + case '?': // at start of query, stop normalizing + if (ch == '?') + normalize = 0; + + // fall-through + + case '\0': // remove trailing slash-dot-(dot) + if (slash_dot_dot > 1) + { + dst -= slash_dot_dot; + + // remove parent directory if it was two dots + + if (slash_dot_dot == 3) + while (dst > org_dst && *--dst != '/') + ; // empty body + slash_dot_dot = (ch == '/') ? 1 : 0; + + // keep the root slash if any + + if (!slash_dot_dot && dst == org_dst && *dst == '/') + ++dst; + + } + break; + + case '.': + if (slash_dot_dot == 1 || slash_dot_dot == 2) + { + ++slash_dot_dot; + break; + } + // fall-through + + default: + slash_dot_dot = 0; + } + } + + *dst++ = ch; + } while(ch); + + return (dst - org_dst) - 1; +} diff --git a/lib/common.h b/lib/common.h index 614dfe6..1829471 100644 --- a/lib/common.h +++ b/lib/common.h @@ -10,6 +10,7 @@ #include // uint_64_t #include +#include #include #include // MD5_* @@ -25,7 +26,7 @@ #endif //*************************************************************************** -// +// Misc //*************************************************************************** #ifndef VDR_PLUGIN @@ -56,49 +57,106 @@ enum Misc tmeSecondsPerDay = 24 * tmeSecondsPerHour }; +enum Case +{ + cUpper, + cLower +}; + +const char* toCase(Case cs, char* str); + //*************************************************************************** // Tell //*************************************************************************** -void tell(int eloquence, const char* format, ...); +void __attribute__ ((format(printf, 2, 3))) tell(int eloquence, const char* format, ...); //*************************************************************************** -// MemoryStruct for curl callbacks +// +//*************************************************************************** + +char* srealloc(void* ptr, size_t size); + +//*************************************************************************** +// MemoryStruct //*************************************************************************** struct MemoryStruct { - MemoryStruct() { memory = 0; clear(); } - ~MemoryStruct() { clear(); } + public: - // data + MemoryStruct() { expireAt = time(0); memory = 0; clear(); } + MemoryStruct(const MemoryStruct* o) + { + size = o->size; + memory = (char*)malloc(size); + memcpy(memory, o->memory, size); - char* memory; - size_t size; + copyAttributes(o); + } + + void copyAttributes(const MemoryStruct* o) + { + strcpy(tag, o->tag); + strcpy(name, o->name); + strcpy(contentType, o->contentType); + strcpy(contentEncoding, o->contentEncoding); + strcpy(mimeType, o->mimeType); + headerOnly = o->headerOnly; + modTime = o->modTime; + expireAt = o->expireAt; + } + + ~MemoryStruct() { clear(); } + + int append(const char* buf, int len) + { + memory = srealloc(memory, size+len); + memcpy(memory+size, buf, len); + size += len; - // tag attribute + return success; + } - char tag[100]; // the tag to be compared - char name[100]; // content name (filename) - int headerOnly; - - int isEmpty() { return memory == 0; } - - void clear() - { - free(memory); - memory = 0; - size = 0; - *tag = 0; - *name = 0; - headerOnly = no; - } + // data + + char* memory; + size_t size; + + // tag attribute + + char tag[100]; // the tag to be compared + char name[100]; // content name (filename) + char contentType[100]; // e.g. text/html + char mimeType[100]; // + char contentEncoding[100]; // + int headerOnly; + time_t modTime; + time_t expireAt; + + int isEmpty() { return memory == 0; } + + void clear() + { + free(memory); + memory = 0; + size = 0; + *tag = 0; + *name = 0; + *contentType = 0; + *contentEncoding = 0; + *mimeType = 0; + modTime = time(0); + // !!!! expireAt = time(0); + headerOnly = no; + } }; //*************************************************************************** // Tools //*************************************************************************** +double usNow(); unsigned int getHostId(); const char* getHostName(); const char* getFirstIp(); @@ -120,14 +178,23 @@ std::string num2Str(int num); std::string l2pTime(time_t t); std::string ms2Dur(uint64_t t); const char* c2s(char c, char* buf); +int urlUnescape(char* dst, const char* src, int normalize = yes); + +int storeToFile(const char* filename, const char* data, int size); +int loadFromFile(const char* infile, MemoryStruct* data); int fileExists(const char* path); int fileSize(const char* path); +time_t fileModTime(const char* path); int createLink(const char* link, const char* dest, int force); int isLink(const char* path); +const char* suffixOf(const char* path); int isEmpty(const char* str); +const char* notNull(const char* str); +int isZero(const char* str); int removeFile(const char* filename); int chkDir(const char* path); +int downloadFile(const char* url, int& size, MemoryStruct* data, int timeout = 30, const char* userAgent = "libcurl-agent/1.0"); #ifdef USELIBXML xsltStylesheetPtr loadXSLT(const char* name, const char* path, int utf8); @@ -145,6 +212,7 @@ int chkDir(const char* path); //*************************************************************************** int gunzip(MemoryStruct* zippedData, MemoryStruct* unzippedData); +int gzip(MemoryStruct* data, MemoryStruct* zippedData); void tellZipError(int errorCode, const char* op, const char* msg); #ifdef USELIBARCHIVE diff --git a/lib/config.c b/lib/config.c index 9ca25f1..d53a26a 100644 --- a/lib/config.c +++ b/lib/config.c @@ -44,10 +44,13 @@ cEPG2VDRConfig::cEPG2VDRConfig(void) scheduleBoot = no; #else sstrcpy(cachePath, "/var/cache/epgd", sizeof(cachePath)); + sstrcpy(httpPath, "/var/epgd/www", sizeof(httpPath)); sstrcpy(pluginPath, PLGDIR, sizeof(pluginPath)); sstrcpy(epgView, "eventsview.sql", sizeof(epgView)); + sstrcpy(theTvDBView, "thetvdbview.sql", sizeof(epgView)); updateThreshold = 200; maintanance = no; + httpPort = 9999; #endif sstrcpy(dbHost, "localhost", sizeof(dbHost)); @@ -60,4 +63,7 @@ cEPG2VDRConfig::cEPG2VDRConfig(void) loglevel = 1; uuid[0] = 0; + + scrapEpg = yes; + scrapRecordings = yes; } diff --git a/lib/config.h b/lib/config.h index e0c729c..026d9f7 100644 --- a/lib/config.h +++ b/lib/config.h @@ -47,10 +47,13 @@ struct cEPG2VDRConfig int scheduleBoot; #else char cachePath[256+TB]; + char httpPath[256+TB]; char pluginPath[256+TB]; char epgView[100+TB]; + char theTvDBView[100+TB]; int updateThreshold; int maintanance; + int httpPort; #endif char dbHost[100+TB]; @@ -66,6 +69,10 @@ struct cEPG2VDRConfig int mainmenuFullupdate; int masterMode; char uuid[sizeUuid+TB]; + + int scrapEpg; + int scrapRecordings; + }; extern cEPG2VDRConfig EPG2VDRConfig; diff --git a/lib/db.c b/lib/db.c index 97214dc..b5e2911 100644 --- a/lib/db.c +++ b/lib/db.c @@ -7,7 +7,7 @@ #include -#include +#include #include "db.h" @@ -17,6 +17,8 @@ // DB Statement //*************************************************************************** +int cDbStatement::explain = no; + cDbStatement::cDbStatement(cDbTable* aTable) { table = aTable; @@ -30,6 +32,14 @@ cDbStatement::cDbStatement(cDbTable* aTable) affected = 0; metaResult = 0; bindPrefix = 0; + firstExec = yes; + + callsPeriod = 0; + callsTotal = 0; + duration = 0; + + if (connection) + connection->statements.append(this); } cDbStatement::cDbStatement(cDbConnection* aConnection, const char* stmt) @@ -45,6 +55,22 @@ cDbStatement::cDbStatement(cDbConnection* aConnection, const char* stmt) affected = 0; metaResult = 0; bindPrefix = 0; + firstExec = yes; + + callsPeriod = 0; + callsTotal = 0; + duration = 0; + + if (connection) + connection->statements.append(this); +} + +cDbStatement::~cDbStatement() +{ + if (connection) + connection->statements.remove(this); + + clear(); } //*************************************************************************** @@ -61,11 +87,43 @@ int cDbStatement::execute(int noResult) if (!stmt) return connection->errorSql(connection, "execute(missing statement)"); +// if (explain && firstExec) +// { +// firstExec = no; + +// if (strstr(stmtTxt.c_str(), "select ")) +// { +// MYSQL_RES* result; +// MYSQL_ROW row; +// string q = "explain " + stmtTxt; + +// if (connection->query(q.c_str()) != success) +// connection->errorSql(connection, "explain ", 0); +// else if ((result = mysql_store_result(connection->getMySql()))) +// { +// while ((row = mysql_fetch_row(result))) +// { +// tell(0, "EXPLAIN: %s) %s %s %s %s %s %s %s %s %s", +// row[0], row[1], row[2], row[3], +// row[4], row[5], row[6], row[7], row[8], row[9]); +// } + +// mysql_free_result(result); +// } +// } +// } + // tell(0, "execute %d [%s]", stmt, stmtTxt.c_str()); + long start = usNow(); + if (mysql_stmt_execute(stmt)) return connection->errorSql(connection, "execute(stmt_execute)", stmt, stmtTxt.c_str()); + duration += usNow() - start; + callsPeriod++; + callsTotal++; + // out binding - if needed if (outCount && !noResult) @@ -270,7 +328,7 @@ int cDbStatement::appendBinding(cDbValue* value, BindType bt) if (!bindings) *bindings = (MYSQL_BIND*)malloc(count * sizeof(MYSQL_BIND)); else - *bindings = (MYSQL_BIND*)realloc(*bindings, count * sizeof(MYSQL_BIND)); + *bindings = (MYSQL_BIND*)srealloc(*bindings, count * sizeof(MYSQL_BIND)); newBinding = &((*bindings)[count-1]); @@ -360,6 +418,22 @@ int cDbStatement::prepare() return success; } +//*************************************************************************** +// Show Statistic +//*************************************************************************** + +void cDbStatement::showStat() +{ + if (callsPeriod) + { + tell(0, "calls %4ld in %6.2fms; total %4ld [%s]", + callsPeriod, duration/1000, callsTotal, stmtTxt.c_str()); + + callsPeriod = 0; + duration = 0; + } +} + //*************************************************************************** // cDbService //*************************************************************************** @@ -382,6 +456,50 @@ const char* cDbService::toString(FieldFormat t) return formats[t]; } +const char* cDbService::dictFormats[] = +{ + "int", + "uint", + "ascii", + "text", + "mlob", + "float", + "datetime", + + 0 +}; + +cDbService::FieldFormat cDbService::toDictFormat(const char* format) +{ + for (int i = 0; i < ffCount; i++) + if (strcasecmp(dictFormats[i], format) == 0) + return (FieldFormat)i; + + return ffUnknown; +} + +const char* cDbService::types[] = +{ + "data", + "primary", + "meta", + "calc", + "autoinc", + + 0 +}; + +cDbService::FieldType cDbService::toType(const char* type) +{ + // #TODO !!! + + for (int i = 0; i < 3; i++) + if (strcasecmp(types[i], type) == 0) + return (FieldType)i; + + return ftUnknown; +} + //*************************************************************************** // Class cDbTable //*************************************************************************** diff --git a/lib/db.h b/lib/db.h index 8a365fd..34a2a62 100644 --- a/lib/db.h +++ b/lib/db.h @@ -13,11 +13,11 @@ #include #include #include - -#include - #include +#include +#include + #include "common.h" class cDbTable; @@ -40,6 +40,8 @@ class cDbService enum FieldFormat { + ffUnknown = na, + ffInt, ffUInt, ffAscii, // -> VARCHAR @@ -52,6 +54,8 @@ class cDbService enum FieldType { + ftUnknown = na, + ftData = 1, ftPrimary = 2, ftMeta = 4, @@ -90,7 +94,12 @@ class cDbService }; static const char* toString(FieldFormat t); + static FieldFormat toDictFormat(const char* format); static const char* formats[]; + static const char* dictFormats[]; + + static FieldType toType(const char* type); + static const char* types[]; }; typedef cDbService cDBS; @@ -374,8 +383,7 @@ class cDbStatement : public cDbService cDbStatement(cDbTable* aTable); cDbStatement(cDbConnection* aConnection, const char* stmt = ""); - - virtual ~cDbStatement() { clear(); } + virtual ~cDbStatement(); int execute(int noResult = no); int find(); @@ -404,6 +412,12 @@ class cDbStatement : public cDbService int getResultCount(); const char* asText() { return stmtTxt.c_str(); } + void showStat(); + + // data + + static int explain; // debug explain + private: void clear(); @@ -415,11 +429,49 @@ class cDbStatement : public cDbService cDbConnection* connection; cDbTable* table; int inCount; - MYSQL_BIND* inBind; // to db + MYSQL_BIND* inBind; // to db int outCount; - MYSQL_BIND* outBind; // from db (result) + MYSQL_BIND* outBind; // from db (result) MYSQL_RES* metaResult; const char* bindPrefix; + int firstExec; // debug explain + + unsigned long callsPeriod; + unsigned long callsTotal; + double duration; +}; + +//*************************************************************************** +// cDbStatements +//*************************************************************************** + +class cDbStatements +{ + public: + + cDbStatements() { statisticPeriod = time(0); } + ~cDbStatements() {}; + + void append(cDbStatement* s) { statements.push_back(s); } + void remove(cDbStatement* s) { statements.remove(s); } + + void showStat() + { + tell(0, "Statement statistic of last %ld seconds:", statisticPeriod); + + for (std::list::iterator it = statements.begin() ; it != statements.end(); ++it) + { + if (*it) + (*it)->showStat(); + } + + statisticPeriod = time(0); + } + + private: + + time_t statisticPeriod; + std::list statements; }; //*************************************************************************** @@ -628,7 +680,7 @@ class cDbConnection { nread += res; size += 1000; - buffer = (char*)realloc(buffer, size+1); + buffer = srealloc(buffer, size+1); } fclose(f); @@ -704,6 +756,8 @@ class cDbConnection int errorSql(cDbConnection* mysql, const char* prefix, MYSQL_STMT* stmt = 0, const char* stmtTxt = 0); + void showStat() { statements.showStat(); } + static int init() { if (mysql_library_init(0, 0, 0)) @@ -729,6 +783,8 @@ class cDbConnection MYSQL* mysql; + cDbStatements statements; // all statements of this connection + private: int initialized; diff --git a/lib/tabledef.c b/lib/tabledef.c index 0e388f1..d9826f5 100644 --- a/lib/tabledef.c +++ b/lib/tabledef.c @@ -19,8 +19,8 @@ const char* cEpgdState::states[] = "busy (events)", "busy (match)", - "busy (images)", "busy (scraping)", + "busy (images)", 0 }; diff --git a/lib/tabledef.h b/lib/tabledef.h index 614e311..9936f4e 100644 --- a/lib/tabledef.h +++ b/lib/tabledef.h @@ -26,14 +26,17 @@ class cEpgdState esStandby, esStopped, + // handler pause on this states! + esBusy, esBusyEvents = esBusy, esBusyMatch, + esBusyScraping, + + // handler don't pause on this states! esBusyImages, - esBusyScraping, - esCount }; @@ -78,6 +81,7 @@ class cUpdateState static const char* getDeletable() { return "'A','L','P','R','I'"; } static const char* getNeeded() { return "'A','L','P','C','D','R'"; } + static const char* getVisible() { return "'A','L','P'"; } // checks fpr c++ code diff --git a/moviedbmovie.c b/moviedbmovie.c index c1485c3..24070e1 100644 --- a/moviedbmovie.c +++ b/moviedbmovie.c @@ -1,130 +1,130 @@ -#define __STL_CONFIG_H -#include "lib/common.h" -#include "moviedbmovie.h" - -using namespace std; - -cMovieDbMovie::cMovieDbMovie(void) { - title = ""; - originalTitle = ""; - tagline = ""; - overview = ""; - adult = false; - collectionID = 0; - collectionName = ""; - budget = 0; - revenue = 0; - genres = ""; - homepage = ""; - imdbid = ""; - releaseDate = ""; - runtime = 0; - popularity = 0.0; - voteAverage = 0.0; -} - -cMovieDbMovie::~cMovieDbMovie() { - for (map::iterator it = actors.begin(); it != actors.end(); it++) { - cMovieActor *a = (cMovieActor*)it->second; - delete a; - } - for (map::iterator it = medias.begin(); it != medias.end(); it++) { - cMovieMedia *m = (cMovieMedia*)it->second; - delete m; - } -} - -void cMovieDbMovie::InsertMedia(cMovieMedia *media) { - medias.insert(pair(media->mediaType, media)); -} - -void cMovieDbMovie::InsertActor(cMovieActor *actor) { - cMovieMedia *m = new cMovieMedia(); - actor->actorThumb = m; - actors.insert(pair(actor->id, actor)); -} - -vector cMovieDbMovie::GetActorIDs(void) { - vector IDs; - for (map::iterator it = actors.begin(); it != actors.end(); it++) { - cMovieActor *a = it->second; - IDs.push_back(a->id); - } - return IDs; -} - -void cMovieDbMovie::SetActorThumbSize(int actorId, int imgWidth, int imgHeight) { - map::iterator hit = actors.find(actorId); - if (hit != actors.end()) { - cMovieActor *a = hit->second; - if (!a->actorThumb) - return; - cMovieMedia *thumb = a->actorThumb; - thumb->width = imgWidth; - thumb->height = imgHeight; - thumb->mediaType = mmActorThumb; - } -} - -void cMovieDbMovie::SetActorPath(int actorId, string path) { - map::iterator hit = actors.find(actorId); - if (hit != actors.end()) { - cMovieActor *a = hit->second; - if (!a->actorThumb) - return; - a->actorThumb->path = path; - } -} - -bool cMovieDbMovie::GetMedia(mediaMovies mediatype, cTvMedia *p) { - map::iterator hit = medias.find(mediatype); - if (hit == medias.end()) - return false; - cMovieMedia *pStored = hit->second; - p->path = pStored->path; - p->width = pStored->width; - p->height = pStored->height; - return true; -} - -void cMovieDbMovie::GetActors(vector *a) { - for (map::iterator it = actors.begin(); it != actors.end(); it++) { - cMovieActor *aStored = it->second; - cActor act; - act.name = aStored->name; - act.role = aStored->role; - if (aStored->actorThumb) { - act.actorThumb.width = aStored->actorThumb->width; - act.actorThumb.height = aStored->actorThumb->height; - act.actorThumb.path = aStored->actorThumb->path; - } - a->push_back(act); - } -} - -void cMovieDbMovie::Dump(void) { - tell(0, "--------------------------- Movie Info ----------------------------------"); - tell(0, "title %s, ID: %d", title.c_str(), id); - tell(0, "Orig. Title: %s", originalTitle.c_str()); - tell(0, "Tagline: %s", tagline.c_str()); - tell(0, "Overview: %s", overview.c_str()); - tell(0, "Collection: %s", collectionName.c_str()); - tell(0, "Genre: %s", genres.c_str()); - tell(0, "Popularity: %f", popularity); - tell(0, "--------------------------- Actors ----------------------------------"); - for (map::iterator it = actors.begin(); it != actors.end(); it++) { - cMovieActor *a = it->second; - tell(0, "Actor %d, Name: %s, Role %s", a->id, a->name.c_str(), a->role.c_str()); - if (a->actorThumb) { - tell(0, "thmbWidth %d, thmbHeight %d", a->actorThumb->width, a->actorThumb->height); - tell(0, "Path %s", a->actorThumb->path.c_str()); - } - } - tell(0, "--------------------------- Media ----------------------------------"); - for (map::iterator it = medias.begin(); it != medias.end(); it++) { - cMovieMedia *m = it->second; - tell(0, "Media %d", m->mediaType); - tell(0, "width %d, height %d", m->width, m->height); - tell(0, "Path %s", m->path.c_str()); - } +#define __STL_CONFIG_H +#include "lib/common.h" +#include "moviedbmovie.h" + +using namespace std; + +cMovieDbMovie::cMovieDbMovie(void) { + title = ""; + originalTitle = ""; + tagline = ""; + overview = ""; + adult = false; + collectionID = 0; + collectionName = ""; + budget = 0; + revenue = 0; + genres = ""; + homepage = ""; + imdbid = ""; + releaseDate = ""; + runtime = 0; + popularity = 0.0; + voteAverage = 0.0; +} + +cMovieDbMovie::~cMovieDbMovie() { + for (map::iterator it = actors.begin(); it != actors.end(); it++) { + cMovieActor *a = (cMovieActor*)it->second; + delete a; + } + for (map::iterator it = medias.begin(); it != medias.end(); it++) { + cMovieMedia *m = (cMovieMedia*)it->second; + delete m; + } +} + +void cMovieDbMovie::InsertMedia(cMovieMedia *media) { + medias.insert(pair(media->mediaType, media)); +} + +void cMovieDbMovie::InsertActor(cMovieActor *actor) { + cMovieMedia *m = new cMovieMedia(); + actor->actorThumb = m; + actors.insert(pair(actor->id, actor)); +} + +vector cMovieDbMovie::GetActorIDs(void) { + vector IDs; + for (map::iterator it = actors.begin(); it != actors.end(); it++) { + cMovieActor *a = it->second; + IDs.push_back(a->id); + } + return IDs; +} + +void cMovieDbMovie::SetActorThumbSize(int actorId, int imgWidth, int imgHeight) { + map::iterator hit = actors.find(actorId); + if (hit != actors.end()) { + cMovieActor *a = hit->second; + if (!a->actorThumb) + return; + cMovieMedia *thumb = a->actorThumb; + thumb->width = imgWidth; + thumb->height = imgHeight; + thumb->mediaType = mmActorThumb; + } +} + +void cMovieDbMovie::SetActorPath(int actorId, string path) { + map::iterator hit = actors.find(actorId); + if (hit != actors.end()) { + cMovieActor *a = hit->second; + if (!a->actorThumb) + return; + a->actorThumb->path = path; + } +} + +bool cMovieDbMovie::GetMedia(mediaMovies mediatype, cTvMedia *p) { + map::iterator hit = medias.find(mediatype); + if (hit == medias.end()) + return false; + cMovieMedia *pStored = hit->second; + p->path = pStored->path; + p->width = pStored->width; + p->height = pStored->height; + return true; +} + +void cMovieDbMovie::GetActors(vector *a) { + for (map::iterator it = actors.begin(); it != actors.end(); it++) { + cMovieActor *aStored = it->second; + cActor act; + act.name = aStored->name; + act.role = aStored->role; + if (aStored->actorThumb) { + act.actorThumb.width = aStored->actorThumb->width; + act.actorThumb.height = aStored->actorThumb->height; + act.actorThumb.path = aStored->actorThumb->path; + } + a->push_back(act); + } +} + +void cMovieDbMovie::Dump(void) { + tell(0, "--------------------------- Movie Info ----------------------------------"); + tell(0, "title %s, ID: %d", title.c_str(), id); + tell(0, "Orig. Title: %s", originalTitle.c_str()); + tell(0, "Tagline: %s", tagline.c_str()); + tell(0, "Overview: %s", overview.c_str()); + tell(0, "Collection: %s", collectionName.c_str()); + tell(0, "Genre: %s", genres.c_str()); + tell(0, "Popularity: %f", popularity); + tell(0, "--------------------------- Actors ----------------------------------"); + for (map::iterator it = actors.begin(); it != actors.end(); it++) { + cMovieActor *a = it->second; + tell(0, "Actor %d, Name: %s, Role %s", a->id, a->name.c_str(), a->role.c_str()); + if (a->actorThumb) { + tell(0, "thmbWidth %d, thmbHeight %d", a->actorThumb->width, a->actorThumb->height); + tell(0, "Path %s", a->actorThumb->path.c_str()); + } + } + tell(0, "--------------------------- Media ----------------------------------"); + for (map::iterator it = medias.begin(); it != medias.end(); it++) { + cMovieMedia *m = it->second; + tell(0, "Media %d", m->mediaType); + tell(0, "width %d, height %d", m->width, m->height); + tell(0, "Path %s", m->path.c_str()); + } } \ No newline at end of file diff --git a/moviedbmovie.h b/moviedbmovie.h index d53f7b0..998e3ca 100644 --- a/moviedbmovie.h +++ b/moviedbmovie.h @@ -1,98 +1,98 @@ -#ifndef __TVSCRAPER_MOVIEDBMOVIE_H -#define __TVSCRAPER_MOVIEDBMOVIE_H - -#include -#include -#include -#include -#include -#include -#include -#include "services.h" - -using namespace std; - -enum mediaMovies { - mmPoster, - mmFanart, - mmCollectionPoster, - mmCollectionFanart, - mmActorThumb, - mmPosterThumb, -}; - -// --- cMovieMedia ------------------------------------------------------------- -class cMovieMedia { -public: - cMovieMedia(void) { - path = ""; - mediaType = mmPoster; - width = 0; - height = 0; - }; - ~cMovieMedia(void) { - }; - string path; - int mediaType; - int width; - int height; -}; - -// --- cMovieActor ------------------------------------------------------------- -class cMovieActor { -public: - cMovieActor(void) { - id = 0; - name = ""; - role = ""; - actorThumb = NULL; - }; - ~cMovieActor(void) { - if (actorThumb) - delete actorThumb; - }; - int id; - string name; - string role; - cMovieMedia *actorThumb; -}; - -// --- cMovieDbMovie ------------------------------------------------------------- - -class cMovieDbMovie { -private: - map actors; - map medias; -public: - cMovieDbMovie(void); - virtual ~cMovieDbMovie(void); - int id; - string title; - string originalTitle; - string tagline; - string overview; - bool adult; - int collectionID; - string collectionName; - int budget; - int revenue; - string genres; - string homepage; - string imdbid; - string releaseDate; - int runtime; - float popularity; - float voteAverage; - void InsertActor(cMovieActor *actor); - void InsertMedia(cMovieMedia *media); - vector GetActorIDs(void); - void SetActorThumbSize(int actorId, int imgWidth, int imgHeight); - void SetActorPath(int actorId, string path); - //Getter for Serivice Calls - bool GetMedia(mediaMovies mediatype, cTvMedia *p); - void GetActors(vector *a); - void Dump(); -}; - - -#endif //__TVSCRAPER_TVDBSERIES_H +#ifndef __TVSCRAPER_MOVIEDBMOVIE_H +#define __TVSCRAPER_MOVIEDBMOVIE_H + +#include +#include +#include +#include +#include +#include +#include +#include "services.h" + +using namespace std; + +enum mediaMovies { + mmPoster, + mmFanart, + mmCollectionPoster, + mmCollectionFanart, + mmActorThumb, + mmPosterThumb, +}; + +// --- cMovieMedia ------------------------------------------------------------- +class cMovieMedia { +public: + cMovieMedia(void) { + path = ""; + mediaType = mmPoster; + width = 0; + height = 0; + }; + ~cMovieMedia(void) { + }; + string path; + int mediaType; + int width; + int height; +}; + +// --- cMovieActor ------------------------------------------------------------- +class cMovieActor { +public: + cMovieActor(void) { + id = 0; + name = ""; + role = ""; + actorThumb = NULL; + }; + ~cMovieActor(void) { + if (actorThumb) + delete actorThumb; + }; + int id; + string name; + string role; + cMovieMedia *actorThumb; +}; + +// --- cMovieDbMovie ------------------------------------------------------------- + +class cMovieDbMovie { +private: + map actors; + map medias; +public: + cMovieDbMovie(void); + virtual ~cMovieDbMovie(void); + int id; + string title; + string originalTitle; + string tagline; + string overview; + bool adult; + int collectionID; + string collectionName; + int budget; + int revenue; + string genres; + string homepage; + string imdbid; + string releaseDate; + int runtime; + float popularity; + float voteAverage; + void InsertActor(cMovieActor *actor); + void InsertMedia(cMovieMedia *media); + vector GetActorIDs(void); + void SetActorThumbSize(int actorId, int imgWidth, int imgHeight); + void SetActorPath(int actorId, string path); + //Getter for Serivice Calls + bool GetMedia(mediaMovies mediatype, cTvMedia *p); + void GetActors(vector *a); + void Dump(); +}; + + +#endif //__TVSCRAPER_TVDBSERIES_H diff --git a/scraper2vdr.h b/scraper2vdr.h index 6e9b048..ce9cc42 100644 --- a/scraper2vdr.h +++ b/scraper2vdr.h @@ -1,57 +1,57 @@ -#ifndef __SCRAPER2VDR_H -#define __SCRAPER2VDR_H - -#include -#include -#include "lib/common.h" -#include "config.h" -#include "setup.h" -#include "scrapmanager.h" -#include "update.h" -#include "services.h" - -//*************************************************************************** -// Constants -//*************************************************************************** -static const char *VERSION = "0.1.1"; -static const char *DESCRIPTION = "'scraper2vdr' plugin"; -static const char *MAINMENUENTRY = "Scraper2Vdr"; - -//*************************************************************************** -// Globals -//*************************************************************************** -cScraper2VdrConfig config; - -//*************************************************************************** -// cPluginScraper2vdr -//*************************************************************************** - -class cPluginScraper2vdr : public cPlugin { -private: - cScrapManager *scrapManager; - cUpdate *update; -public: - cPluginScraper2vdr(void); - virtual ~cPluginScraper2vdr(); - virtual const char *Version(void) { return VERSION; } - virtual const char *Description(void) { return DESCRIPTION; } - virtual const char *CommandLineHelp(void); - virtual bool ProcessArgs(int argc, char *argv[]); - virtual bool Initialize(void); - virtual bool Start(void); - virtual void Stop(void); - virtual void Housekeeping(void); - virtual void MainThreadHook(void); - virtual cString Active(void); - virtual time_t WakeupTime(void); - virtual const char *MainMenuEntry(void) { return (config.mainMenuEntry)?MAINMENUENTRY:NULL; } - virtual cOsdObject *MainMenuAction(void); - virtual cMenuSetupPage *SetupMenu(void); - virtual bool SetupParse(const char *Name, const char *Value); - virtual bool Service(const char *Id, void *Data = NULL); - virtual const char **SVDRPHelpPages(void); - virtual cString SVDRPCommand(const char *Command, const char *Option, int &ReplyCode); -}; - -//*************************************************************************** -#endif // __SCRAPER2VDR_H +#ifndef __SCRAPER2VDR_H +#define __SCRAPER2VDR_H + +#include +#include +#include "lib/common.h" +#include "config.h" +#include "setup.h" +#include "scrapmanager.h" +#include "update.h" +#include "services.h" + +//*************************************************************************** +// Constants +//*************************************************************************** +static const char *VERSION = "0.1.2"; +static const char *DESCRIPTION = "'scraper2vdr' plugin"; +static const char *MAINMENUENTRY = "Scraper2Vdr"; + +//*************************************************************************** +// Globals +//*************************************************************************** +cScraper2VdrConfig config; + +//*************************************************************************** +// cPluginScraper2vdr +//*************************************************************************** + +class cPluginScraper2vdr : public cPlugin { +private: + cScrapManager *scrapManager; + cUpdate *update; +public: + cPluginScraper2vdr(void); + virtual ~cPluginScraper2vdr(); + virtual const char *Version(void) { return VERSION; } + virtual const char *Description(void) { return DESCRIPTION; } + virtual const char *CommandLineHelp(void); + virtual bool ProcessArgs(int argc, char *argv[]); + virtual bool Initialize(void); + virtual bool Start(void); + virtual void Stop(void); + virtual void Housekeeping(void); + virtual void MainThreadHook(void); + virtual cString Active(void); + virtual time_t WakeupTime(void); + virtual const char *MainMenuEntry(void) { return (config.mainMenuEntry)?MAINMENUENTRY:NULL; } + virtual cOsdObject *MainMenuAction(void); + virtual cMenuSetupPage *SetupMenu(void); + virtual bool SetupParse(const char *Name, const char *Value); + virtual bool Service(const char *Id, void *Data = NULL); + virtual const char **SVDRPHelpPages(void); + virtual cString SVDRPCommand(const char *Command, const char *Option, int &ReplyCode); +}; + +//*************************************************************************** +#endif // __SCRAPER2VDR_H diff --git a/scrapmanager.c b/scrapmanager.c index 8a0925c..b3f9af8 100644 --- a/scrapmanager.c +++ b/scrapmanager.c @@ -1,581 +1,583 @@ -#define __STL_v_H -#include -#include "tools.h" -#include "config.h" -#include "scrapmanager.h" - -using namespace std; - -extern cScraper2VdrConfig config; - -bool operator<(const sEventsKey& l, const sEventsKey& r) { - if (l.eventId != r.eventId) - return (l.eventId < r.eventId); - int comp = l.channelId.compare(r.channelId); - if (comp < 0) - return true; - return false; -} - -bool operator<(const sRecordingsKey& l, const sRecordingsKey& r) { - if (l.recStart != r.recStart) - return (l.recStart < r.recStart); - int comp = l.recPath.compare(r.recPath); - if (comp < 0) - return true; - return false; -} - -cScrapManager::cScrapManager(void) { - -} - -cScrapManager::~cScrapManager(void) { - for (map::iterator it = series.begin(); it != series.end(); it++) { - cTVDBSeries *s = (cTVDBSeries*)it->second; - delete s; - } - series.clear(); - for (map::iterator it = movies.begin(); it != movies.end(); it++) { - cMovieDbMovie *m = (cMovieDbMovie*)it->second; - delete m; - } - movies.clear(); -} - -void cScrapManager::InitIterator(bool isRec) { - if (!isRec) - eventsIterator = events.begin(); - else - recIterator = recordings.begin(); -} - -sEventsValue cScrapManager::GetEventInformation(int eventId, string channelId) { - sEventsKey k; - k.eventId = eventId; - k.channelId = channelId; - sEventsValue emptyVal; - emptyVal.seriesId = 0; - emptyVal.episodeId = 0; - emptyVal.movieId = 0; - emptyVal.isNew = false; - map::iterator hit = events.find(k); - if (hit != events.end()) - return hit->second; - return emptyVal; -} - - -void cScrapManager::AddEvent(int eventId, string channelId, int seriesId, int episodeId, int movieId) { - sEventsKey k; - k.eventId = eventId; - k.channelId = channelId; - sEventsValue v; - v.seriesId = seriesId; - v.episodeId = episodeId; - v.movieId = movieId; - v.isNew = true; - events.insert(pair(k, v)); -} - -bool cScrapManager::GetNextSeries(bool isRec, int &seriesId, int &episodeId) { - bool next = false; - if (!isRec) { - while (eventsIterator != events.end()) { - next = true; - sEventsValue ev = eventsIterator->second; - if (ev.isNew && (ev.seriesId > 0)) { - seriesId = ev.seriesId; - episodeId = ev.episodeId; - eventsIterator->second.isNew = false; - eventsIterator++; - break; - } - eventsIterator++; - next = false; - } - } else { - while (recIterator != recordings.end()) { - next = true; - sEventsValue ev = recIterator->second; - if (ev.isNew && (ev.seriesId > 0)) { - seriesId = ev.seriesId; - episodeId = ev.episodeId; - recIterator->second.isNew = false; - recIterator++; - break; - } - recIterator++; - next = false; - } - - } - return next; -} - -bool cScrapManager::GetNextMovie(bool isRec, int &movieId) { - bool next = false; - if (!isRec) { - while (eventsIterator != events.end()) { - next = true; - sEventsValue ev = eventsIterator->second; - if (ev.isNew && (ev.movieId > 0)) { - movieId = ev.movieId; - eventsIterator->second.isNew = false; - eventsIterator++; - break; - } - eventsIterator++; - next = false; - } - } else { - while (recIterator != recordings.end()) { - next = true; - sEventsValue ev = recIterator->second; - if (ev.isNew && (ev.movieId > 0)) { - movieId = ev.movieId; - recIterator->second.isNew = false; - recIterator++; - break; - } - recIterator++; - next = false; - } - } - return next; -} - -cTVDBSeries *cScrapManager::GetSeries(int seriesId) { - map::iterator hit = series.find(seriesId); - if (hit == series.end()) - return NULL; - return hit->second; -} - -cMovieDbMovie *cScrapManager::GetMovie(int movieId) { - map::iterator hit = movies.find(movieId); - if (hit == movies.end()) - return NULL; - return hit->second; -} - -cTVDBSeries *cScrapManager::AddSeries(cTableSeries* tSeries) { - cTVDBSeries *s = new cTVDBSeries(); - s->id = tSeries->getIntValue(cTableSeries::fiSeriesId); - s->name = tSeries->getStrValue(cTableSeries::fiSeriesName); - s->overview = tSeries->getStrValue(cTableSeries::fiSeriesOverview); - s->firstAired = tSeries->getStrValue(cTableSeries::fiSeriesFirstAired); - s->network = tSeries->getStrValue(cTableSeries::fiSeriesNetwork); - string genre = replaceString(tSeries->getStrValue(cTableSeries::fiSeriesGenre), "|", ", "); - s->genre = genre; - s->rating = tSeries->getFloatValue(cTableSeries::fiSeriesRating); - s->status = tSeries->getStrValue(cTableSeries::fiSeriesStatus); - series.insert(pair(tSeries->getIntValue(cTableSeries::fiSeriesId), s)); - return s; -} - -cMovieDbMovie *cScrapManager::AddMovie(cTableMovies* tMovies) { - cMovieDbMovie *m = new cMovieDbMovie(); - m->id = tMovies->getIntValue(cTableMovies::fiMovieId); - m->title = tMovies->getStrValue(cTableMovies::fiTitle); - m->originalTitle = tMovies->getStrValue(cTableMovies::fiOriginalTitle); - m->tagline = tMovies->getStrValue(cTableMovies::fiTagline); - m->overview = tMovies->getStrValue(cTableMovies::fiOverview); - m->adult = tMovies->getIntValue(cTableMovies::fiIsAdult); - m->collectionName = tMovies->getStrValue(cTableMovies::fiCollectionName); - m->budget = tMovies->getIntValue(cTableMovies::fiBudget); - m->revenue = tMovies->getIntValue(cTableMovies::fiRevenue); - string genre = replaceString(tMovies->getStrValue(cTableMovies::fiGenres), "|", ","); - m->genres = genre; - m->homepage = tMovies->getStrValue(cTableMovies::fiHomepage); - m->releaseDate = tMovies->getStrValue(cTableMovies::fiReleaaseDate); - m->runtime = tMovies->getIntValue(cTableMovies::fiRuntime); - m->popularity = tMovies->getFloatValue(cTableMovies::fiPopularity); - m->voteAverage = tMovies->getFloatValue(cTableMovies::fiVoteAverage); - movies.insert(pair(tMovies->getIntValue(cTableMovies::fiMovieId), m)); - return m; -} - -void cScrapManager::AddSeriesEpisode(cTVDBSeries *series, cTableSeriesEpisode* tEpisodes) { - cTVDBEpisode *e = new cTVDBEpisode(); - e->id = tEpisodes->getIntValue(cTableSeriesEpisode::fiEpisodeId); - e->name = tEpisodes->getStrValue(cTableSeriesEpisode::fiEpisodeName); - e->number = tEpisodes->getIntValue(cTableSeriesEpisode::fiEpisodeNumber); - e->season = tEpisodes->getIntValue(cTableSeriesEpisode::fiSeasonNumber); - e->overview = tEpisodes->getStrValue(cTableSeriesEpisode::fiEpisodeOverview); - e->firstAired = tEpisodes->getStrValue(cTableSeriesEpisode::fiEpisodeFirstAired); - string guestStars = replaceString(tEpisodes->getStrValue(cTableSeriesEpisode::fiEpisodeGuestStars), "|", ", "); - e->guestStars = guestStars; - e->rating = tEpisodes->getFloatValue(cTableSeriesEpisode::fiEpisodeRating); - series->InsertEpisode(e); -} - -void cScrapManager::AddSeriesActor(cTVDBSeries *series, cTableSeriesActor* tActors) { - cTVDBActor *a = new cTVDBActor(); - a->id = tActors->getIntValue(cTableSeriesActor::fiActorId); - a->name = tActors->getStrValue(cTableSeriesActor::fiActorName); - a->role = tActors->getStrValue(cTableSeriesActor::fiActorRole); - series->InsertActor(a); -} - -void cScrapManager::AddMovieMedia(cMovieDbMovie *movie, cTableMovieMedia* tMovieMedia, string path) { - cMovieMedia *m = new cMovieMedia(); - m->mediaType = tMovieMedia->getIntValue(cTableMovieMedia::fiMediaType); - m->width = tMovieMedia->getIntValue(cTableMovieMedia::fiMediaWidth); - m->height = tMovieMedia->getIntValue(cTableMovieMedia::fiMediaHeight); - m->path = path; - movie->InsertMedia(m); -} - - -void cScrapManager::AddMovieActor(cMovieDbMovie *movie, cTableMovieActor* tActor, string role) { - cMovieActor *a = new cMovieActor(); - a->id = tActor->getIntValue(cTableMovieActor::fiActorId); - a->name = tActor->getStrValue(cTableMovieActor::fiActorName); - a->role = role; - movie->InsertActor(a); -} - -bool cScrapManager::AddRecording(int recStart, string recPath, int seriesId, int episodeId, int movieId) { - sRecordingsKey k; - k.recStart = recStart; - k.recPath = recPath; - //check if recording already exists - map::iterator hit = recordings.find(k); - if (hit != recordings.end()) { - sEventsValue v = hit->second; - if ((v.seriesId == seriesId) && (v.episodeId == episodeId) && (v.movieId == movieId)) - return false; - else - recordings.erase(hit); - } - sEventsValue v; - v.seriesId = seriesId; - v.episodeId = episodeId; - v.movieId = movieId; - v.isNew = true; - recordings.insert(pair(k, v)); - return true; -} - -bool cScrapManager::RecordingExists(int recStart, string recPath) { - sRecordingsKey k; - k.recStart = recStart; - k.recPath = recPath; - map::iterator hit = recordings.find(k); - if (hit != recordings.end()) - return true; - return false; -} - -bool cScrapManager::SeriesInUse(int seriesId) { - map::iterator hit = series.find(seriesId); - if (hit != series.end()) - return true; - return false; -} - -bool cScrapManager::MovieInUse(int movieId) { - map::iterator hit = movies.find(movieId); - if (hit != movies.end()) - return true; - return false; -} - -void cScrapManager::DumpSeries(void) { - int numSeries = 0; - map::iterator it; - for (it = events.begin(); it != events.end(); it++) { - sEventsKey key = it->first; - sEventsValue ev = it->second; - if (ev.seriesId > 0) { - const cEvent *event = NULL; - const cChannel *c = NULL; - cSchedulesLock lock; - cSchedules *s = (cSchedules *)cSchedules::Schedules(lock); - if (s) { - tChannelID cID = tChannelID::FromString(key.channelId.c_str()); - c = Channels.GetByChannelID(cID); - const cSchedule *schedule = s->GetSchedule(cID); - if (schedule) { - event = schedule->GetEvent(key.eventId); - } - } - if (event) { - tell(0, "series (tvdbID %d, episodeId %d), Event (EventID %d): %s, %s: %s (%s)", ev.seriesId, - ev.episodeId, - key.eventId, - *event->GetDateString(), - *event->GetTimeString(), - event->Title(), - c?(c->Name()):"unknown channel"); - } else { - tell(0, "series (tvdbID %d, episodeId %d), Event (EventID %d): No VDR Event found", ev.seriesId, ev.episodeId, key.eventId); - } - numSeries++; - } - } - tell(0, "Keeping %d series in memory", numSeries); -} - -void cScrapManager::DumpMovies(void) { - int numMovies = 0; - map::iterator it; - for (it = events.begin(); it != events.end(); it++) { - sEventsKey key = it->first; - sEventsValue ev = it->second; - if (ev.movieId > 0) { - const cEvent *event = NULL; - const cChannel *c = NULL; - cSchedulesLock lock; - cSchedules *s = (cSchedules *)cSchedules::Schedules(lock); - if (s) { - tChannelID cID = tChannelID::FromString(key.channelId.c_str()); - c = Channels.GetByChannelID(cID); - const cSchedule *schedule = s->GetSchedule(cID); - if (schedule) { - event = schedule->GetEvent(key.eventId); - } - } - if (event) { - tell(0, "movie (moviedbId %d), Event (EventID %d): %s, %s: %s (%s)", ev.movieId, - key.eventId, - *event->GetDateString(), - *event->GetTimeString(), - event->Title(), - c?(c->Name()):"unknown channel"); - } else { - tell(0, "movie (moviedbId %d), Event (EventID %d): No VDR Event found", ev.movieId, key.eventId); - } - numMovies++; - } - } - tell(0, "Keeping %d movies in memory", numMovies); -} - -void cScrapManager::DumpRecordings(void) { - tell(0, "%d recordings in memory:", recordings.size()); - for (map::iterator it = recordings.begin(); it != recordings.end(); it++) { - sRecordingsKey key = it->first; - sEventsValue val = it->second; - if (val.seriesId > 0) { - tell(0, "series (tvdbID %d, episodeId %d): %s", val.seriesId, val.episodeId, key.recPath.c_str()); - } else if (val.movieId) { - tell(0, "movie (moviedbID %d): %s", val.movieId, key.recPath.c_str()); - } else { - tell(0, "unknown recording: %s", key.recPath.c_str()); - } - } -} - -bool cScrapManager::GetEventType(ScraperGetEventType *call) { - if (config.debug) { - tell(0, "scraper2vdr plugin service call GetEventType called"); - } - sEventsValue v; - if (call->event) { - sEventsKey k; - k.eventId = call->event->EventID(); - k.channelId = *(call->event->ChannelID().ToString()); - map::iterator hit = events.find(k); - if (hit == events.end()) { - if (config.debug) { - tell(0, "no event found for eventID %d, channelID %s", k.eventId, k.channelId.c_str()); - } - return false; - } - if (config.debug) - tell(0, "event found for eventID %d, channelID %s", k.eventId, k.channelId.c_str()); - v = hit->second; - } else if (call->recording) { - sRecordingsKey k; - k.recStart = call->recording->Start(); - k.recPath = getRecPath(call->recording); - map::iterator hit = recordings.find(k); - if (hit == recordings.end()) { - if (config.debug) { - tell(0, "no recording found for recStart %d, recPath %s", k.recStart, k.recPath.c_str()); - } - return false; - } - v = hit->second; - if (config.debug) { - tell(0, "recording found for recStart %d, recPath %s", k.recStart, k.recPath.c_str()); - } - } - if (v.seriesId > 0) { - call->type = tSeries; - if (config.debug) - tell(0, "series detected, seriesId %d, episodeId %d", v.seriesId, v.episodeId); - } else if (v.movieId > 0) { - call->type = tMovie; - if (config.debug) - tell(0, "movie detected, movieId %d", v.movieId); - } else { - if (config.debug) - tell(0, "unvalid entry"); - call->type = tNone; - return false; - } - call->seriesId = v.seriesId; - call->episodeId = v.episodeId; - call->movieId = v.movieId; - return true; -} - -bool cScrapManager::GetSeries(cSeries *s) { - map::iterator hit = series.find(s->seriesId); - if (hit == series.end()) - return false; - cTVDBSeries *sStored = hit->second; - s->name = sStored->name; - s->overview = sStored->overview; - s->firstAired = sStored->firstAired; - s->network = sStored->network; - s->genre = sStored->genre; - s->rating = sStored->rating; - s->status = sStored->status; - //Episode - if (s->episodeId > 0) { - sStored->GetEpisode(s->episodeId, &s->episode); - sStored->GetSeasonPoster(s->episodeId, &s->seasonPoster); - } - //Media - sStored->GetPosters(&s->posters); - sStored->GetBanners(&s->banners); - sStored->GetFanart(&s->fanarts); - //Actors - sStored->GetActors(&s->actors); - return true; -} - -bool cScrapManager::GetMovie(cMovie *m) { - map::iterator hit = movies.find(m->movieId); - if (hit == movies.end()) - return false; - cMovieDbMovie *mStored = hit->second; - m->title = mStored->title; - m->originalTitle = mStored->originalTitle; - m->tagline = mStored->tagline; - m->overview = mStored->overview; - m->adult = mStored->adult; - m->collectionName = mStored->collectionName; - m->budget = mStored->budget; - m->revenue = mStored->revenue; - m->genres = mStored->genres; - m->homepage = mStored->homepage; - m->releaseDate = mStored->releaseDate; - m->runtime = mStored->runtime; - m->popularity = mStored->popularity; - m->voteAverage = mStored->voteAverage; - //Media - mStored->GetMedia(mmPoster, &m->poster); - mStored->GetMedia(mmFanart, &m->fanart); - mStored->GetMedia(mmCollectionPoster, &m->collectionPoster); - mStored->GetMedia(mmCollectionFanart, &m->collectionFanart); - //Actors - mStored->GetActors(&m->actors); - return true; -} - -bool cScrapManager::GetPosterBanner(ScraperGetPosterBanner *call) { - sEventsKey k; - k.eventId = call->event->EventID(); - k.channelId = *(call->event->ChannelID().ToString()); - map::iterator hit = events.find(k); - if (hit == events.end()) - return false; - sEventsValue v = hit->second; - if (v.seriesId > 0) { - call->type = tSeries; - map::iterator hitSeries = series.find(v.seriesId); - if (hitSeries == series.end()) - return false; - cTVDBSeries *s = hitSeries->second; - bool found = s->GetRandomBanner(&call->banner); - if (v.episodeId > 0) { - s->GetSeasonPoster(v.episodeId, &call->poster); - } - return found; - } else if (v.movieId > 0) { - call->type = tMovie; - map::iterator hitMovies = movies.find(v.movieId); - if (hitMovies == movies.end()) - return false; - cMovieDbMovie *m = hitMovies->second; - return m->GetMedia(mmPoster, &call->poster); - } else { - call->type = tNone; - } - return false; -} - -bool cScrapManager::GetPoster(ScraperGetPoster *call) { - sEventsValue v; - if (call->event) { - sEventsKey k; - k.eventId = call->event->EventID(); - k.channelId = *(call->event->ChannelID().ToString()); - map::iterator hit = events.find(k); - if (hit == events.end()) - return false; - v = hit->second; - } else if (call->recording) { - sRecordingsKey k; - k.recStart = call->recording->Start(); - k.recPath = getRecPath(call->recording); - map::iterator hit = recordings.find(k); - if (hit == recordings.end()) - return false; - v = hit->second; - } - if (v.seriesId > 0) { - map::iterator hitSeries = series.find(v.seriesId); - if (hitSeries == series.end()) - return false; - cTVDBSeries *s = hitSeries->second; - return s->GetPoster(&call->poster); - } else if (v.movieId > 0) { - map::iterator hitMovies = movies.find(v.movieId); - if (hitMovies == movies.end()) - return false; - cMovieDbMovie *m = hitMovies->second; - return m->GetMedia(mmPoster, &call->poster); - } - -} - -bool cScrapManager::GetPosterThumb(ScraperGetPosterThumb *call) { - sEventsValue v; - if (call->event) { - sEventsKey k; - k.eventId = call->event->EventID(); - k.channelId = *(call->event->ChannelID().ToString()); - map::iterator hit = events.find(k); - if (hit == events.end()) - return false; - v = hit->second; - } else if (call->recording) { - sRecordingsKey k; - k.recStart = call->recording->Start(); - k.recPath = getRecPath(call->recording); - map::iterator hit = recordings.find(k); - if (hit == recordings.end()) - return false; - v = hit->second; - } - if (v.seriesId > 0) { - map::iterator hitSeries = series.find(v.seriesId); - if (hitSeries == series.end()) - return false; - cTVDBSeries *s = hitSeries->second; - return s->GetPosterThumb(&call->poster); - } else if (v.movieId > 0) { - map::iterator hitMovies = movies.find(v.movieId); - if (hitMovies == movies.end()) - return false; - cMovieDbMovie *m = hitMovies->second; - return m->GetMedia(mmPosterThumb, &call->poster); - } - return false; -} +#define __STL_v_H +#include +#include "tools.h" +#include "config.h" +#include "scrapmanager.h" + +using namespace std; + +extern cScraper2VdrConfig config; + +bool operator<(const sEventsKey& l, const sEventsKey& r) { + if (l.eventId != r.eventId) + return (l.eventId < r.eventId); + int comp = l.channelId.compare(r.channelId); + if (comp < 0) + return true; + return false; +} + +bool operator<(const sRecordingsKey& l, const sRecordingsKey& r) { + if (l.recStart != r.recStart) + return (l.recStart < r.recStart); + int comp = l.recPath.compare(r.recPath); + if (comp < 0) + return true; + return false; +} + +cScrapManager::cScrapManager(void) { + +} + +cScrapManager::~cScrapManager(void) { + for (map::iterator it = series.begin(); it != series.end(); it++) { + cTVDBSeries *s = (cTVDBSeries*)it->second; + delete s; + } + series.clear(); + for (map::iterator it = movies.begin(); it != movies.end(); it++) { + cMovieDbMovie *m = (cMovieDbMovie*)it->second; + delete m; + } + movies.clear(); +} + +void cScrapManager::InitIterator(bool isRec) { + if (!isRec) + eventsIterator = events.begin(); + else + recIterator = recordings.begin(); +} + +sEventsValue cScrapManager::GetEventInformation(int eventId, string channelId) { + sEventsKey k; + k.eventId = eventId; + k.channelId = channelId; + sEventsValue emptyVal; + emptyVal.seriesId = 0; + emptyVal.episodeId = 0; + emptyVal.movieId = 0; + emptyVal.isNew = false; + map::iterator hit = events.find(k); + if (hit != events.end()) + return hit->second; + return emptyVal; +} + + +void cScrapManager::AddEvent(int eventId, string channelId, int seriesId, int episodeId, int movieId) { + sEventsKey k; + k.eventId = eventId; + k.channelId = channelId; + sEventsValue v; + v.seriesId = seriesId; + v.episodeId = episodeId; + v.movieId = movieId; + v.isNew = true; + events.insert(pair(k, v)); +} + +bool cScrapManager::GetNextSeries(bool isRec, int &seriesId, int &episodeId) { + bool next = false; + if (!isRec) { + while (eventsIterator != events.end()) { + next = true; + sEventsValue ev = eventsIterator->second; + if (ev.isNew && (ev.seriesId > 0)) { + seriesId = ev.seriesId; + episodeId = ev.episodeId; + eventsIterator->second.isNew = false; + eventsIterator++; + break; + } + eventsIterator++; + next = false; + } + } else { + while (recIterator != recordings.end()) { + next = true; + sEventsValue ev = recIterator->second; + if (ev.isNew && (ev.seriesId > 0)) { + seriesId = ev.seriesId; + episodeId = ev.episodeId; + recIterator->second.isNew = false; + recIterator++; + break; + } + recIterator++; + next = false; + } + + } + return next; +} + +bool cScrapManager::GetNextMovie(bool isRec, int &movieId) { + bool next = false; + if (!isRec) { + while (eventsIterator != events.end()) { + next = true; + sEventsValue ev = eventsIterator->second; + if (ev.isNew && (ev.movieId > 0)) { + movieId = ev.movieId; + eventsIterator->second.isNew = false; + eventsIterator++; + break; + } + eventsIterator++; + next = false; + } + } else { + while (recIterator != recordings.end()) { + next = true; + sEventsValue ev = recIterator->second; + if (ev.isNew && (ev.movieId > 0)) { + movieId = ev.movieId; + recIterator->second.isNew = false; + recIterator++; + break; + } + recIterator++; + next = false; + } + } + return next; +} + +cTVDBSeries *cScrapManager::GetSeries(int seriesId) { + map::iterator hit = series.find(seriesId); + if (hit == series.end()) + return NULL; + return hit->second; +} + +cMovieDbMovie *cScrapManager::GetMovie(int movieId) { + map::iterator hit = movies.find(movieId); + if (hit == movies.end()) + return NULL; + return hit->second; +} + +cTVDBSeries *cScrapManager::AddSeries(cTableSeries* tSeries) { + cTVDBSeries *s = new cTVDBSeries(); + s->id = tSeries->getIntValue(cTableSeries::fiSeriesId); + s->name = tSeries->getStrValue(cTableSeries::fiSeriesName); + s->overview = tSeries->getStrValue(cTableSeries::fiSeriesOverview); + s->firstAired = tSeries->getStrValue(cTableSeries::fiSeriesFirstAired); + s->network = tSeries->getStrValue(cTableSeries::fiSeriesNetwork); + string genre = replaceString(tSeries->getStrValue(cTableSeries::fiSeriesGenre), "|", ", "); + s->genre = genre; + s->rating = tSeries->getFloatValue(cTableSeries::fiSeriesRating); + s->status = tSeries->getStrValue(cTableSeries::fiSeriesStatus); + series.insert(pair(tSeries->getIntValue(cTableSeries::fiSeriesId), s)); + return s; +} + +cMovieDbMovie *cScrapManager::AddMovie(cTableMovies* tMovies) { + cMovieDbMovie *m = new cMovieDbMovie(); + m->id = tMovies->getIntValue(cTableMovies::fiMovieId); + m->title = tMovies->getStrValue(cTableMovies::fiTitle); + m->originalTitle = tMovies->getStrValue(cTableMovies::fiOriginalTitle); + m->tagline = tMovies->getStrValue(cTableMovies::fiTagline); + m->overview = tMovies->getStrValue(cTableMovies::fiOverview); + m->adult = tMovies->getIntValue(cTableMovies::fiIsAdult); + m->collectionName = tMovies->getStrValue(cTableMovies::fiCollectionName); + m->budget = tMovies->getIntValue(cTableMovies::fiBudget); + m->revenue = tMovies->getIntValue(cTableMovies::fiRevenue); + string genre = replaceString(tMovies->getStrValue(cTableMovies::fiGenres), "|", ","); + m->genres = genre; + m->homepage = tMovies->getStrValue(cTableMovies::fiHomepage); + m->releaseDate = tMovies->getStrValue(cTableMovies::fiReleaaseDate); + m->runtime = tMovies->getIntValue(cTableMovies::fiRuntime); + m->popularity = tMovies->getFloatValue(cTableMovies::fiPopularity); + m->voteAverage = tMovies->getFloatValue(cTableMovies::fiVoteAverage); + movies.insert(pair(tMovies->getIntValue(cTableMovies::fiMovieId), m)); + return m; +} + +void cScrapManager::AddSeriesEpisode(cTVDBSeries *series, cTableSeriesEpisode* tEpisodes) { + cTVDBEpisode *e = new cTVDBEpisode(); + e->id = tEpisodes->getIntValue(cTableSeriesEpisode::fiEpisodeId); + e->name = tEpisodes->getStrValue(cTableSeriesEpisode::fiEpisodeName); + e->number = tEpisodes->getIntValue(cTableSeriesEpisode::fiEpisodeNumber); + e->season = tEpisodes->getIntValue(cTableSeriesEpisode::fiSeasonNumber); + e->overview = tEpisodes->getStrValue(cTableSeriesEpisode::fiEpisodeOverview); + e->firstAired = tEpisodes->getStrValue(cTableSeriesEpisode::fiEpisodeFirstAired); + string guestStars = replaceString(tEpisodes->getStrValue(cTableSeriesEpisode::fiEpisodeGuestStars), "|", ", "); + e->guestStars = guestStars; + e->rating = tEpisodes->getFloatValue(cTableSeriesEpisode::fiEpisodeRating); + series->InsertEpisode(e); +} + +void cScrapManager::AddSeriesActor(cTVDBSeries *series, cTableSeriesActor* tActors) { + cTVDBActor *a = new cTVDBActor(); + a->id = tActors->getIntValue(cTableSeriesActor::fiActorId); + a->name = tActors->getStrValue(cTableSeriesActor::fiActorName); + a->role = tActors->getStrValue(cTableSeriesActor::fiActorRole); + series->InsertActor(a); +} + +void cScrapManager::AddMovieMedia(cMovieDbMovie *movie, cTableMovieMedia* tMovieMedia, string path) { + cMovieMedia *m = new cMovieMedia(); + m->mediaType = tMovieMedia->getIntValue(cTableMovieMedia::fiMediaType); + m->width = tMovieMedia->getIntValue(cTableMovieMedia::fiMediaWidth); + m->height = tMovieMedia->getIntValue(cTableMovieMedia::fiMediaHeight); + m->path = path; + movie->InsertMedia(m); +} + + +void cScrapManager::AddMovieActor(cMovieDbMovie *movie, cTableMovieActor* tActor, string role) { + cMovieActor *a = new cMovieActor(); + a->id = tActor->getIntValue(cTableMovieActor::fiActorId); + a->name = tActor->getStrValue(cTableMovieActor::fiActorName); + a->role = role; + movie->InsertActor(a); +} + +bool cScrapManager::AddRecording(int recStart, string recPath, int seriesId, int episodeId, int movieId) { + sRecordingsKey k; + k.recStart = recStart; + k.recPath = recPath; + //check if recording already exists + map::iterator hit = recordings.find(k); + if (hit != recordings.end()) { + sEventsValue v = hit->second; + if ((v.seriesId == seriesId) && (v.episodeId == episodeId) && (v.movieId == movieId)) + return false; + else + recordings.erase(hit); + } + sEventsValue v; + v.seriesId = seriesId; + v.episodeId = episodeId; + v.movieId = movieId; + v.isNew = true; + recordings.insert(pair(k, v)); + return true; +} + +bool cScrapManager::RecordingExists(int recStart, string recPath) { + sRecordingsKey k; + k.recStart = recStart; + k.recPath = recPath; + map::iterator hit = recordings.find(k); + if (hit != recordings.end()) + return true; + return false; +} + +bool cScrapManager::SeriesInUse(int seriesId) { + map::iterator hit = series.find(seriesId); + if (hit != series.end()) + return true; + return false; +} + +bool cScrapManager::MovieInUse(int movieId) { + map::iterator hit = movies.find(movieId); + if (hit != movies.end()) + return true; + return false; +} + +void cScrapManager::DumpSeries(void) { + int numSeries = 0; + map::iterator it; + for (it = events.begin(); it != events.end(); it++) { + sEventsKey key = it->first; + sEventsValue ev = it->second; + if (ev.seriesId > 0) { + const cEvent *event = NULL; + const cChannel *c = NULL; + cSchedulesLock lock; + cSchedules *s = (cSchedules *)cSchedules::Schedules(lock); + if (s) { + tChannelID cID = tChannelID::FromString(key.channelId.c_str()); + c = Channels.GetByChannelID(cID); + const cSchedule *schedule = s->GetSchedule(cID); + if (schedule) { + event = schedule->GetEvent(key.eventId); + } + } + if (event) { + tell(0, "series (tvdbID %d, episodeId %d), Event (EventID %d): %s, %s: %s (%s)", ev.seriesId, + ev.episodeId, + key.eventId, + *event->GetDateString(), + *event->GetTimeString(), + event->Title(), + c?(c->Name()):"unknown channel"); + } else { + tell(0, "series (tvdbID %d, episodeId %d), Event (EventID %d): No VDR Event found", ev.seriesId, ev.episodeId, key.eventId); + } + numSeries++; + } + } + tell(0, "Keeping %d series in memory", numSeries); +} + +void cScrapManager::DumpMovies(void) { + int numMovies = 0; + map::iterator it; + for (it = events.begin(); it != events.end(); it++) { + sEventsKey key = it->first; + sEventsValue ev = it->second; + if (ev.movieId > 0) { + const cEvent *event = NULL; + const cChannel *c = NULL; + cSchedulesLock lock; + cSchedules *s = (cSchedules *)cSchedules::Schedules(lock); + if (s) { + tChannelID cID = tChannelID::FromString(key.channelId.c_str()); + c = Channels.GetByChannelID(cID); + const cSchedule *schedule = s->GetSchedule(cID); + if (schedule) { + event = schedule->GetEvent(key.eventId); + } + } + if (event) { + tell(0, "movie (moviedbId %d), Event (EventID %d): %s, %s: %s (%s)", ev.movieId, + key.eventId, + *event->GetDateString(), + *event->GetTimeString(), + event->Title(), + c?(c->Name()):"unknown channel"); + } else { + tell(0, "movie (moviedbId %d), Event (EventID %d): No VDR Event found", ev.movieId, key.eventId); + } + numMovies++; + } + } + tell(0, "Keeping %d movies in memory", numMovies); +} + +void cScrapManager::DumpRecordings(void) { + tell(0, "%ld recordings in memory:", recordings.size()); + for (map::iterator it = recordings.begin(); it != recordings.end(); it++) { + sRecordingsKey key = it->first; + sEventsValue val = it->second; + if (val.seriesId > 0) { + tell(0, "series (tvdbID %d, episodeId %d): %s", val.seriesId, val.episodeId, key.recPath.c_str()); + } else if (val.movieId) { + tell(0, "movie (moviedbID %d): %s", val.movieId, key.recPath.c_str()); + } else { + tell(0, "unknown recording: %s", key.recPath.c_str()); + } + } +} + +bool cScrapManager::GetEventType(ScraperGetEventType *call) { + if (config.debug) { + tell(0, "scraper2vdr plugin service call GetEventType called"); + } + sEventsValue v; + memset(&v, 0, sizeof(sEventsValue)); + if (call->event) { + sEventsKey k; + k.eventId = call->event->EventID(); + k.channelId = *(call->event->ChannelID().ToString()); + map::iterator hit = events.find(k); + if (hit == events.end()) { + if (config.debug) { + tell(0, "no event found for eventID %d, channelID %s", k.eventId, k.channelId.c_str()); + } + return false; + } + if (config.debug) + tell(0, "event found for eventID %d, channelID %s", k.eventId, k.channelId.c_str()); + v = hit->second; + } else if (call->recording) { + sRecordingsKey k; + k.recStart = call->recording->Start(); + k.recPath = getRecPath(call->recording); + map::iterator hit = recordings.find(k); + if (hit == recordings.end()) { + if (config.debug) { + tell(0, "no recording found for recStart %d, recPath %s", k.recStart, k.recPath.c_str()); + } + return false; + } + v = hit->second; + if (config.debug) { + tell(0, "recording found for recStart %d, recPath %s", k.recStart, k.recPath.c_str()); + } + } + if (v.seriesId > 0) { + call->type = tSeries; + if (config.debug) + tell(0, "series detected, seriesId %d, episodeId %d", v.seriesId, v.episodeId); + } else if (v.movieId > 0) { + call->type = tMovie; + if (config.debug) + tell(0, "movie detected, movieId %d", v.movieId); + } else { + if (config.debug) + tell(0, "unvalid entry"); + call->type = tNone; + return false; + } + call->seriesId = v.seriesId; + call->episodeId = v.episodeId; + call->movieId = v.movieId; + return true; +} + +bool cScrapManager::GetSeries(cSeries *s) { + map::iterator hit = series.find(s->seriesId); + if (hit == series.end()) + return false; + cTVDBSeries *sStored = hit->second; + s->name = sStored->name; + s->overview = sStored->overview; + s->firstAired = sStored->firstAired; + s->network = sStored->network; + s->genre = sStored->genre; + s->rating = sStored->rating; + s->status = sStored->status; + //Episode + if (s->episodeId > 0) { + sStored->GetEpisode(s->episodeId, &s->episode); + sStored->GetSeasonPoster(s->episodeId, &s->seasonPoster); + } + //Media + sStored->GetPosters(&s->posters); + sStored->GetBanners(&s->banners); + sStored->GetFanart(&s->fanarts); + //Actors + sStored->GetActors(&s->actors); + return true; +} + +bool cScrapManager::GetMovie(cMovie *m) { + map::iterator hit = movies.find(m->movieId); + if (hit == movies.end()) + return false; + cMovieDbMovie *mStored = hit->second; + m->title = mStored->title; + m->originalTitle = mStored->originalTitle; + m->tagline = mStored->tagline; + m->overview = mStored->overview; + m->adult = mStored->adult; + m->collectionName = mStored->collectionName; + m->budget = mStored->budget; + m->revenue = mStored->revenue; + m->genres = mStored->genres; + m->homepage = mStored->homepage; + m->releaseDate = mStored->releaseDate; + m->runtime = mStored->runtime; + m->popularity = mStored->popularity; + m->voteAverage = mStored->voteAverage; + //Media + mStored->GetMedia(mmPoster, &m->poster); + mStored->GetMedia(mmFanart, &m->fanart); + mStored->GetMedia(mmCollectionPoster, &m->collectionPoster); + mStored->GetMedia(mmCollectionFanart, &m->collectionFanart); + //Actors + mStored->GetActors(&m->actors); + return true; +} + +bool cScrapManager::GetPosterBanner(ScraperGetPosterBanner *call) { + sEventsKey k; + k.eventId = call->event->EventID(); + k.channelId = *(call->event->ChannelID().ToString()); + map::iterator hit = events.find(k); + if (hit == events.end()) + return false; + sEventsValue v = hit->second; + if (v.seriesId > 0) { + call->type = tSeries; + map::iterator hitSeries = series.find(v.seriesId); + if (hitSeries == series.end()) + return false; + cTVDBSeries *s = hitSeries->second; + bool found = s->GetRandomBanner(&call->banner); + if (v.episodeId > 0) { + s->GetSeasonPoster(v.episodeId, &call->poster); + } + return found; + } else if (v.movieId > 0) { + call->type = tMovie; + map::iterator hitMovies = movies.find(v.movieId); + if (hitMovies == movies.end()) + return false; + cMovieDbMovie *m = hitMovies->second; + return m->GetMedia(mmPoster, &call->poster); + } else { + call->type = tNone; + } + return false; +} + +bool cScrapManager::GetPoster(ScraperGetPoster *call) { + sEventsValue v; + if (call->event) { + sEventsKey k; + k.eventId = call->event->EventID(); + k.channelId = *(call->event->ChannelID().ToString()); + map::iterator hit = events.find(k); + if (hit == events.end()) + return false; + v = hit->second; + } else if (call->recording) { + sRecordingsKey k; + k.recStart = call->recording->Start(); + k.recPath = getRecPath(call->recording); + map::iterator hit = recordings.find(k); + if (hit == recordings.end()) + return false; + v = hit->second; + } + if (v.seriesId > 0) { + map::iterator hitSeries = series.find(v.seriesId); + if (hitSeries == series.end()) + return false; + cTVDBSeries *s = hitSeries->second; + return s->GetPoster(&call->poster); + } else if (v.movieId > 0) { + map::iterator hitMovies = movies.find(v.movieId); + if (hitMovies == movies.end()) + return false; + cMovieDbMovie *m = hitMovies->second; + return m->GetMedia(mmPoster, &call->poster); + } + + return true; +} + +bool cScrapManager::GetPosterThumb(ScraperGetPosterThumb *call) { + sEventsValue v; + if (call->event) { + sEventsKey k; + k.eventId = call->event->EventID(); + k.channelId = *(call->event->ChannelID().ToString()); + map::iterator hit = events.find(k); + if (hit == events.end()) + return false; + v = hit->second; + } else if (call->recording) { + sRecordingsKey k; + k.recStart = call->recording->Start(); + k.recPath = getRecPath(call->recording); + map::iterator hit = recordings.find(k); + if (hit == recordings.end()) + return false; + v = hit->second; + } + if (v.seriesId > 0) { + map::iterator hitSeries = series.find(v.seriesId); + if (hitSeries == series.end()) + return false; + cTVDBSeries *s = hitSeries->second; + return s->GetPosterThumb(&call->poster); + } else if (v.movieId > 0) { + map::iterator hitMovies = movies.find(v.movieId); + if (hitMovies == movies.end()) + return false; + cMovieDbMovie *m = hitMovies->second; + return m->GetMedia(mmPosterThumb, &call->poster); + } + return false; +} diff --git a/scrapmanager.h b/scrapmanager.h index c5b5782..6899a2f 100644 --- a/scrapmanager.h +++ b/scrapmanager.h @@ -1,81 +1,81 @@ -#ifndef __SCRAPMANAGER_H -#define __SCRAPMANAGER_H - -#include -#include -#include -#include -#include - -#include "lib/common.h" -#include "lib/db.h" -#include "lib/tabledef.h" - -#include "services.h" -#include "tvdbseries.h" -#include "moviedbmovie.h" - -using namespace std; - -struct sEventsKey { - int eventId; - string channelId; -}; - -struct sEventsValue { - int seriesId; - int episodeId; - int movieId; - bool isNew; -}; - -struct sRecordingsKey { - int recStart; - string recPath; -}; - -class cScrapManager { - private: - map events; - map::iterator eventsIterator; - map recordings; - map::iterator recIterator; - map series; - map movies; - public: - cScrapManager(void); - virtual ~cScrapManager(void); - //Series and Movies Handling - void AddEvent(int eventId, string channelId, int seriesId, int episodeId, int movieId); - void InitIterator(bool isRec); - int GetNumSeries(void) { return series.size(); }; - int GetNumMovies(void) { return movies.size(); }; - sEventsValue GetEventInformation(int eventId, string channelId); - bool GetNextSeries(bool isRec, int &seriesId, int &episodeId); - bool GetNextMovie(bool isRec, int &movieId); - cTVDBSeries *GetSeries(int seriesId); - cMovieDbMovie *GetMovie(int movieId); - cTVDBSeries *AddSeries(cTableSeries* tSeries); - cMovieDbMovie *AddMovie(cTableMovies* tMovies); - void AddSeriesEpisode(cTVDBSeries *series, cTableSeriesEpisode* tEpisodes); - void AddSeriesActor(cTVDBSeries *series, cTableSeriesActor* tActors); - void AddMovieActor(cMovieDbMovie *movie, cTableMovieActor* tActor, string role); - void AddMovieMedia(cMovieDbMovie *movie, cTableMovieMedia* tMovieMedia, string path); - //Recording Handling - bool AddRecording(int recStart, string recPath, int seriesId, int episodeId, int movieId); - bool RecordingExists(int recStart, string recPath); - bool SeriesInUse(int seriesId); - bool MovieInUse(int movieId); - //Debug - void DumpSeries(void); - void DumpMovies(void); - void DumpRecordings(void); - //Service Calls - bool GetEventType(ScraperGetEventType *call); - bool GetSeries(cSeries *series); - bool GetMovie(cMovie *movie); - bool GetPosterBanner(ScraperGetPosterBanner *call); - bool GetPoster(ScraperGetPoster *call); - bool GetPosterThumb(ScraperGetPosterThumb *call); -}; -#endif //__SCRAPMANAGER_H +#ifndef __SCRAPMANAGER_H +#define __SCRAPMANAGER_H + +#include +#include +#include +#include +#include + +#include "lib/common.h" +#include "lib/db.h" +#include "lib/tabledef.h" + +#include "services.h" +#include "tvdbseries.h" +#include "moviedbmovie.h" + +using namespace std; + +struct sEventsKey { + int eventId; + string channelId; +}; + +struct sEventsValue { + int seriesId; + int episodeId; + int movieId; + bool isNew; +}; + +struct sRecordingsKey { + int recStart; + string recPath; +}; + +class cScrapManager { + private: + map events; + map::iterator eventsIterator; + map recordings; + map::iterator recIterator; + map series; + map movies; + public: + cScrapManager(void); + virtual ~cScrapManager(void); + //Series and Movies Handling + void AddEvent(int eventId, string channelId, int seriesId, int episodeId, int movieId); + void InitIterator(bool isRec); + int GetNumSeries(void) { return series.size(); }; + int GetNumMovies(void) { return movies.size(); }; + sEventsValue GetEventInformation(int eventId, string channelId); + bool GetNextSeries(bool isRec, int &seriesId, int &episodeId); + bool GetNextMovie(bool isRec, int &movieId); + cTVDBSeries *GetSeries(int seriesId); + cMovieDbMovie *GetMovie(int movieId); + cTVDBSeries *AddSeries(cTableSeries* tSeries); + cMovieDbMovie *AddMovie(cTableMovies* tMovies); + void AddSeriesEpisode(cTVDBSeries *series, cTableSeriesEpisode* tEpisodes); + void AddSeriesActor(cTVDBSeries *series, cTableSeriesActor* tActors); + void AddMovieActor(cMovieDbMovie *movie, cTableMovieActor* tActor, string role); + void AddMovieMedia(cMovieDbMovie *movie, cTableMovieMedia* tMovieMedia, string path); + //Recording Handling + bool AddRecording(int recStart, string recPath, int seriesId, int episodeId, int movieId); + bool RecordingExists(int recStart, string recPath); + bool SeriesInUse(int seriesId); + bool MovieInUse(int movieId); + //Debug + void DumpSeries(void); + void DumpMovies(void); + void DumpRecordings(void); + //Service Calls + bool GetEventType(ScraperGetEventType *call); + bool GetSeries(cSeries *series); + bool GetMovie(cMovie *movie); + bool GetPosterBanner(ScraperGetPosterBanner *call); + bool GetPoster(ScraperGetPoster *call); + bool GetPosterThumb(ScraperGetPosterThumb *call); +}; +#endif //__SCRAPMANAGER_H diff --git a/services.h b/services.h index 703d077..570c350 100644 --- a/services.h +++ b/services.h @@ -1,194 +1,194 @@ -#ifndef __SCRAPER2VDRSERVICES_H -#define __SCRAPER2VDRSERVICES_H - -#include -#include - -enum tvType { - tSeries, - tMovie, - tNone, -}; - -/********************************************************************* -* Helper Structures -*********************************************************************/ -class cTvMedia { -public: - cTvMedia(void) { - path = ""; - width = height = 0; - }; - std::string path; - int width; - int height; -}; - -class cEpisode { -public: - cEpisode(void) { - number = 0; - season = 0; - name = ""; - firstAired = ""; - guestStars = ""; - overview = ""; - rating = 0.0; - }; - int number; - int season; - std::string name; - std::string firstAired; - std::string guestStars; - std::string overview; - float rating; - cTvMedia episodeImage; -}; - -class cActor { -public: - cActor(void) { - name = ""; - role = ""; - }; - std::string name; - std::string role; - cTvMedia actorThumb; -}; - -/********************************************************************* -* Data Structures for Service Calls -*********************************************************************/ - -// Data structure for service "GetEventType" -class ScraperGetEventType { -public: - ScraperGetEventType(void) { - event = NULL; - recording = NULL; - type = tNone; - movieId = 0; - seriesId = 0; - episodeId = 0; - }; -// in - const cEvent *event; // check type for this event - const cRecording *recording; // or for this recording -//out - tvType type; //typeSeries or typeMovie - int movieId; - int seriesId; - int episodeId; -}; - -//Data structure for full series and episode information -class cMovie { -public: - cMovie(void) { - title = ""; - originalTitle = ""; - tagline = ""; - overview = ""; - adult = false; - collectionName = ""; - budget = 0; - revenue = 0; - genres = ""; - homepage = ""; - releaseDate = ""; - runtime = 0; - popularity = 0.0; - voteAverage = 0.0; - }; -//IN - int movieId; // movieId fetched from ScraperGetEventType -//OUT - std::string title; - std::string originalTitle; - std::string tagline; - std::string overview; - bool adult; - std::string collectionName; - int budget; - int revenue; - std::string genres; - std::string homepage; - std::string releaseDate; - int runtime; - float popularity; - float voteAverage; - cTvMedia poster; - cTvMedia fanart; - cTvMedia collectionPoster; - cTvMedia collectionFanart; - std::vector actors; -}; - -//Data structure for full series and episode information -class cSeries { -public: - cSeries(void) { - seriesId = 0; - episodeId = 0; - name = ""; - overview = ""; - firstAired = ""; - network = ""; - genre = ""; - rating = 0.0; - status = ""; - }; -//IN - int seriesId; // seriesId fetched from ScraperGetEventType - int episodeId; // episodeId fetched from ScraperGetEventType -//OUT - std::string name; - std::string overview; - std::string firstAired; - std::string network; - std::string genre; - float rating; - std::string status; - cEpisode episode; - std::vector actors; - std::vector posters; - std::vector banners; - std::vector fanarts; - cTvMedia seasonPoster; -}; - -// Data structure for service "GetPosterBanner" -class ScraperGetPosterBanner { -public: - ScraperGetPosterBanner(void) { - type = tNone; - }; -// in - const cEvent *event; // check type for this event -//out - tvType type; //typeSeries or typeMovie - cTvMedia poster; - cTvMedia banner; -}; - -// Data structure for service "GetPoster" -class ScraperGetPoster { -public: -// in - const cEvent *event; // check type for this event - const cRecording *recording; // or for this recording -//out - cTvMedia poster; -}; - -// Data structure for service "GetPosterThumb" -class ScraperGetPosterThumb { -public: -// in - const cEvent *event; // check type for this event - const cRecording *recording; // or for this recording -//out - cTvMedia poster; -}; - +#ifndef __SCRAPER2VDRSERVICES_H +#define __SCRAPER2VDRSERVICES_H + +#include +#include + +enum tvType { + tSeries, + tMovie, + tNone, +}; + +/********************************************************************* +* Helper Structures +*********************************************************************/ +class cTvMedia { +public: + cTvMedia(void) { + path = ""; + width = height = 0; + }; + std::string path; + int width; + int height; +}; + +class cEpisode { +public: + cEpisode(void) { + number = 0; + season = 0; + name = ""; + firstAired = ""; + guestStars = ""; + overview = ""; + rating = 0.0; + }; + int number; + int season; + std::string name; + std::string firstAired; + std::string guestStars; + std::string overview; + float rating; + cTvMedia episodeImage; +}; + +class cActor { +public: + cActor(void) { + name = ""; + role = ""; + }; + std::string name; + std::string role; + cTvMedia actorThumb; +}; + +/********************************************************************* +* Data Structures for Service Calls +*********************************************************************/ + +// Data structure for service "GetEventType" +class ScraperGetEventType { +public: + ScraperGetEventType(void) { + event = NULL; + recording = NULL; + type = tNone; + movieId = 0; + seriesId = 0; + episodeId = 0; + }; +// in + const cEvent *event; // check type for this event + const cRecording *recording; // or for this recording +//out + tvType type; //typeSeries or typeMovie + int movieId; + int seriesId; + int episodeId; +}; + +//Data structure for full series and episode information +class cMovie { +public: + cMovie(void) { + title = ""; + originalTitle = ""; + tagline = ""; + overview = ""; + adult = false; + collectionName = ""; + budget = 0; + revenue = 0; + genres = ""; + homepage = ""; + releaseDate = ""; + runtime = 0; + popularity = 0.0; + voteAverage = 0.0; + }; +//IN + int movieId; // movieId fetched from ScraperGetEventType +//OUT + std::string title; + std::string originalTitle; + std::string tagline; + std::string overview; + bool adult; + std::string collectionName; + int budget; + int revenue; + std::string genres; + std::string homepage; + std::string releaseDate; + int runtime; + float popularity; + float voteAverage; + cTvMedia poster; + cTvMedia fanart; + cTvMedia collectionPoster; + cTvMedia collectionFanart; + std::vector actors; +}; + +//Data structure for full series and episode information +class cSeries { +public: + cSeries(void) { + seriesId = 0; + episodeId = 0; + name = ""; + overview = ""; + firstAired = ""; + network = ""; + genre = ""; + rating = 0.0; + status = ""; + }; +//IN + int seriesId; // seriesId fetched from ScraperGetEventType + int episodeId; // episodeId fetched from ScraperGetEventType +//OUT + std::string name; + std::string overview; + std::string firstAired; + std::string network; + std::string genre; + float rating; + std::string status; + cEpisode episode; + std::vector actors; + std::vector posters; + std::vector banners; + std::vector fanarts; + cTvMedia seasonPoster; +}; + +// Data structure for service "GetPosterBanner" +class ScraperGetPosterBanner { +public: + ScraperGetPosterBanner(void) { + type = tNone; + }; +// in + const cEvent *event; // check type for this event +//out + tvType type; //typeSeries or typeMovie + cTvMedia poster; + cTvMedia banner; +}; + +// Data structure for service "GetPoster" +class ScraperGetPoster { +public: +// in + const cEvent *event; // check type for this event + const cRecording *recording; // or for this recording +//out + cTvMedia poster; +}; + +// Data structure for service "GetPosterThumb" +class ScraperGetPosterThumb { +public: +// in + const cEvent *event; // check type for this event + const cRecording *recording; // or for this recording +//out + cTvMedia poster; +}; + #endif //__SCRAPER2VDRSERVICES_H \ No newline at end of file diff --git a/setup.c b/setup.c index e9bd7b4..0ab826d 100644 --- a/setup.c +++ b/setup.c @@ -1,3 +1,6 @@ + +#include "lib/config.h" + #include "setup.h" extern cScraper2VdrConfig config; @@ -39,7 +42,7 @@ void cScraper2VdrSetup::Setup(void) { } eOSState cScraper2VdrSetup::ProcessKey(eKeys Key) { - bool hadSubMenu = HasSubMenu(); + // bool hadSubMenu = HasSubMenu(); eOSState state = cMenuSetupPage::ProcessKey(Key); if (Key == kOk) { tmpConfig.mysqlHost = host; @@ -77,4 +80,6 @@ void cScraper2VdrSetup::Store(void) { SetupStore("mysqlDBUser", tmpConfig.mysqlDBUser.c_str()); SetupStore("mysqlDBPass", tmpConfig.mysqlDBPass.c_str()); SetupStore("debug", tmpConfig.debug); + + EPG2VDRConfig.loglevel = tmpConfig.debug ? 2 : 1; } diff --git a/tools.c b/tools.c index c9e94f4..0cd5e2b 100644 --- a/tools.c +++ b/tools.c @@ -1,179 +1,179 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "lib/common.h" -#include "tools.h" - -using namespace std; -using namespace Magick; - -bool CreateDirectory(string dir) { - mkdir(dir.c_str(), 0775); - //check if successfull - DIR *pDir; - bool exists = false; - pDir = opendir(dir.c_str()); - if (pDir != NULL) { - exists = true; - closedir(pDir); - } - return exists; -} - -bool FileExists(string filename, bool isImage) { - ifstream ifile(filename.c_str()); - if (ifile) { - //a valid image should be larger then 500 bytes - ifile.seekg (0, ifile.end); - int length = ifile.tellg(); - int minimumLength = isImage ? 500 : 1; - if (length > minimumLength) - return true; - } - return false; -} - -bool CheckDirExists(const char* dirName) { - struct statfs statfsbuf; - if (statfs(dirName,&statfsbuf)==-1) return false; - if ((statfsbuf.f_type!=0x01021994) && (statfsbuf.f_type!=0x28cd3d45)) return false; - if (access(dirName,R_OK|W_OK)==-1) return false; - return true; - -} - -void DeleteFile(string filename) { - remove(filename.c_str()); -} - -void DeleteDirectory(string dirname) { - DIR *dir; - struct dirent *entry; - if ((dir = opendir (dirname.c_str())) != NULL) { - while ((entry = readdir (dir)) != NULL) { - string file = entry->d_name; - if (!file.compare(".")) - continue; - if (!file.compare("..")) - continue; - string delFile = dirname + "/" + file; - DeleteFile(delFile); - } - closedir (dir); - } - rmdir(dirname.c_str()); -} - -string TwoFoldersHigher(string folder) { - unsigned found = folder.find_last_of("/"); - if (found != string::npos) { - string firstDirRemoved = folder.substr(0,found); - unsigned found2 = firstDirRemoved.find_last_of("/"); - if (found2 != string::npos) { - return firstDirRemoved.substr(0,found2); - } - } - return ""; -} - - -// trim from start -string <rim(string &s) { - s.erase(s.begin(), find_if(s.begin(), s.end(), not1(ptr_fun(isspace)))); - return s; -} - -// trim from end -string &rtrim(string &s) { - s.erase(find_if(s.rbegin(), s.rend(), not1(ptr_fun(isspace))).base(), s.end()); - return s; -} - -// trim from both ends -string &trim(string &s) { - return ltrim(rtrim(s)); -} - -void toLower(string &s) { - transform(s.begin(), s.end(), s.begin(), ::tolower); -} - -bool isNumber(const string& s) { - string::const_iterator it = s.begin(); - while (it != s.end() && isdigit(*it)) ++it; - return !s.empty() && it == s.end(); -} - -string replaceString(string content, string search, string repl) { - size_t pos = 0; - while((pos = content.find(search, pos)) != std::string::npos) { - if (pos > 3 && pos < content.size() - 2) { - content.replace(pos, search.length(), repl); - } else { - content.replace(pos, search.length(), ""); - } - pos += repl.length(); - } - return content; -} - -string getRecPath(const cRecording *rec) { - if (!rec) - return ""; - string recPath = rec->FileName(); - if (recPath.size() > 200) - recPath = recPath.substr(0, 199); - return recPath; -} - - -/**************************************************************************************** -* SPLTSTRING -****************************************************************************************/ -// split: receives a char delimiter; returns a vector of strings -// By default ignores repeated delimiters, unless argument rep == 1. -vector& splitstring::split(char delim, int rep) { - if (!flds.empty()) flds.clear(); // empty vector if necessary - string work = data(); - string buf = ""; - int i = 0; - while (i < work.length()) { - if (work[i] != delim) - buf += work[i]; - else if (rep == 1) { - flds.push_back(buf); - buf = ""; - } else if (buf.length() > 0) { - flds.push_back(buf); - buf = ""; - } - i++; - } - if (!buf.empty()) - flds.push_back(buf); - return flds; -} - -void CreateThumbnail(string sourcePath, string destPath, int origWidth, int origHeight, int shrinkFactor) { - if (sourcePath.size() < 5 || destPath.size() < 5 || shrinkFactor < 2) - return; - - int thumbWidth = origWidth / shrinkFactor; - int thumbHeight = origHeight / shrinkFactor; - - InitializeMagick(NULL); - Image buffer; - try { - buffer.read(sourcePath.c_str()); - buffer.sample(Geometry(thumbWidth, thumbHeight)); - buffer.write(destPath.c_str()); - } catch( ... ) {} -} \ No newline at end of file +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lib/common.h" +#include "tools.h" + +using namespace std; +using namespace Magick; + +bool CreateDirectory(string dir) { + mkdir(dir.c_str(), 0775); + //check if successfull + DIR *pDir; + bool exists = false; + pDir = opendir(dir.c_str()); + if (pDir != NULL) { + exists = true; + closedir(pDir); + } + return exists; +} + +bool FileExists(string filename, bool isImage) { + ifstream ifile(filename.c_str()); + if (ifile) { + //a valid image should be larger then 500 bytes + ifile.seekg (0, ifile.end); + int length = ifile.tellg(); + int minimumLength = isImage ? 500 : 1; + if (length > minimumLength) + return true; + } + return false; +} + +bool CheckDirExists(const char* dirName) { + struct statfs statfsbuf; + if (statfs(dirName,&statfsbuf)==-1) return false; + if ((statfsbuf.f_type!=0x01021994) && (statfsbuf.f_type!=0x28cd3d45)) return false; + if (access(dirName,R_OK|W_OK)==-1) return false; + return true; + +} + +void DeleteFile(string filename) { + remove(filename.c_str()); +} + +void DeleteDirectory(string dirname) { + DIR *dir; + struct dirent *entry; + if ((dir = opendir (dirname.c_str())) != NULL) { + while ((entry = readdir (dir)) != NULL) { + string file = entry->d_name; + if (!file.compare(".")) + continue; + if (!file.compare("..")) + continue; + string delFile = dirname + "/" + file; + DeleteFile(delFile); + } + closedir (dir); + } + rmdir(dirname.c_str()); +} + +string TwoFoldersHigher(string folder) { + unsigned found = folder.find_last_of("/"); + if (found != string::npos) { + string firstDirRemoved = folder.substr(0,found); + unsigned found2 = firstDirRemoved.find_last_of("/"); + if (found2 != string::npos) { + return firstDirRemoved.substr(0,found2); + } + } + return ""; +} + + +// trim from start +string <rim(string &s) { + s.erase(s.begin(), find_if(s.begin(), s.end(), not1(ptr_fun(isspace)))); + return s; +} + +// trim from end +string &rtrim(string &s) { + s.erase(find_if(s.rbegin(), s.rend(), not1(ptr_fun(isspace))).base(), s.end()); + return s; +} + +// trim from both ends +string &trim(string &s) { + return ltrim(rtrim(s)); +} + +void toLower(string &s) { + transform(s.begin(), s.end(), s.begin(), ::tolower); +} + +bool isNumber(const string& s) { + string::const_iterator it = s.begin(); + while (it != s.end() && isdigit(*it)) ++it; + return !s.empty() && it == s.end(); +} + +string replaceString(string content, string search, string repl) { + size_t pos = 0; + while((pos = content.find(search, pos)) != std::string::npos) { + if (pos > 3 && pos < content.size() - 2) { + content.replace(pos, search.length(), repl); + } else { + content.replace(pos, search.length(), ""); + } + pos += repl.length(); + } + return content; +} + +string getRecPath(const cRecording *rec) { + if (!rec) + return ""; + string recPath = rec->FileName(); + if (recPath.size() > 200) + recPath = recPath.substr(0, 199); + return recPath; +} + + +/**************************************************************************************** +* SPLTSTRING +****************************************************************************************/ +// split: receives a char delimiter; returns a vector of strings +// By default ignores repeated delimiters, unless argument rep == 1. +vector& splitstring::split(char delim, int rep) { + if (!flds.empty()) flds.clear(); // empty vector if necessary + string work = data(); + string buf = ""; + unsigned int i = 0; + while (i < work.length()) { + if (work[i] != delim) + buf += work[i]; + else if (rep == 1) { + flds.push_back(buf); + buf = ""; + } else if (buf.length() > 0) { + flds.push_back(buf); + buf = ""; + } + i++; + } + if (!buf.empty()) + flds.push_back(buf); + return flds; +} + +void CreateThumbnail(string sourcePath, string destPath, int origWidth, int origHeight, int shrinkFactor) { + if (sourcePath.size() < 5 || destPath.size() < 5 || shrinkFactor < 2) + return; + + int thumbWidth = origWidth / shrinkFactor; + int thumbHeight = origHeight / shrinkFactor; + + InitializeMagick(NULL); + Image buffer; + try { + buffer.read(sourcePath.c_str()); + buffer.sample(Geometry(thumbWidth, thumbHeight)); + buffer.write(destPath.c_str()); + } catch( ... ) {} +} diff --git a/tools.h b/tools.h index 02af2b0..76a806a 100644 --- a/tools.h +++ b/tools.h @@ -1,32 +1,32 @@ -#include -#include - -using namespace std; - -//Filesystem Functions -bool CreateDirectory(string dir); -bool FileExists(string filename, bool isImage = true); -bool CheckDirExists(const char* dirName); -void DeleteFile(string filename); -void DeleteDirectory(string dirname); -string TwoFoldersHigher(string folder); - -//String Functions -string <rim(string &s); -string &rtrim(string &s); -string &trim(string &s); -void toLower(string &s); -bool isNumber(const string& s); -string replaceString(string content, string search, string repl); - -string getRecPath(const cRecording *rec); - -class splitstring : public string { - vector flds; -public: - splitstring(const char *s) : string(s) { }; - vector& split(char delim, int rep=0); -}; - -//Image Functions +#include +#include + +using namespace std; + +//Filesystem Functions +bool CreateDirectory(string dir); +bool FileExists(string filename, bool isImage = true); +bool CheckDirExists(const char* dirName); +void DeleteFile(string filename); +void DeleteDirectory(string dirname); +string TwoFoldersHigher(string folder); + +//String Functions +string <rim(string &s); +string &rtrim(string &s); +string &trim(string &s); +void toLower(string &s); +bool isNumber(const string& s); +string replaceString(string content, string search, string repl); + +string getRecPath(const cRecording *rec); + +class splitstring : public string { + vector flds; +public: + splitstring(const char *s) : string(s) { }; + vector& split(char delim, int rep=0); +}; + +//Image Functions void CreateThumbnail(string sourcePath, string destPath, int origWidth, int origHeight, int shrinkFactor); \ No newline at end of file diff --git a/tvdbseries.c b/tvdbseries.c index 96bde06..4fc2192 100644 --- a/tvdbseries.c +++ b/tvdbseries.c @@ -1,289 +1,289 @@ -#define __STL_CONFIG_H -#include "lib/common.h" -#include "tvdbseries.h" - -using namespace std; - -cTVDBSeries::cTVDBSeries(void) { - id = 0; - name = ""; - overview = ""; - firstAired = ""; - network = ""; - genre = ""; - rating = 0.0; - status = ""; - posterThumb = NULL; -} - -cTVDBSeries::~cTVDBSeries() { - for (map::iterator it = actors.begin(); it != actors.end(); it++) { - cTVDBActor *a = (cTVDBActor*)it->second; - delete a; - } - for (map::iterator it = episodes.begin(); it != episodes.end(); it++) { - cTVDBEpisode *e = (cTVDBEpisode*)it->second; - delete e; - } - for (vector::iterator it = posters.begin(); it != posters.end(); it++) { - cTVDBMedia *p = *it; - delete p; - } - for (vector::iterator it = banners.begin(); it != banners.end(); it++) { - cTVDBMedia *b = *it; - delete b; - } - for (vector::iterator it = fanart.begin(); it != fanart.end(); it++) { - cTVDBMedia *f = *it; - delete f; - } - for (map::iterator it = seasonPosters.begin(); it != seasonPosters.end(); it++) { - cTVDBMedia *s = (cTVDBMedia*)it->second; - delete s; - } - for (map::iterator it = seasonPosterThumbs.begin(); it != seasonPosterThumbs.end(); it++) { - cTVDBMedia *s = (cTVDBMedia*)it->second; - delete s; - } - if (posterThumb) - delete posterThumb; -} - -void cTVDBSeries::InsertEpisode(cTVDBEpisode *episode) { - map::iterator hit = episodes.find(episode->id); - if (hit != episodes.end()) - delete episode; - else - episodes.insert(pair(episode->id, episode)); -} - -void cTVDBSeries::InsertEpisodeImage(int episodeId, int width, int height, string path) { - map::iterator hit = episodes.find(episodeId); - if (hit != episodes.end()) { - cTVDBEpisode *e = hit->second; - cTVDBMedia *m = new cTVDBMedia(); - m->width = width; - m->height = height; - m->path = path; - m->mediaType = msEpisodePic; - e->episodeImage = m; - } -} - -void cTVDBSeries::InsertActor(cTVDBActor *actor) { - actors.insert(pair(actor->id, actor)); -} - -void cTVDBSeries::InsertActorThumb(int actorId, int imgWidth, int imgHeight, string path) { - map::iterator hit = actors.find(actorId); - if (hit != actors.end()) { - cTVDBActor *a = hit->second; - cTVDBMedia *m = new cTVDBMedia(); - m->width = imgWidth; - m->height = imgHeight; - m->path = path; - m->mediaType = msActorThumb; - a->actorThumb = m; - } -} - -void cTVDBSeries::InsertMedia(int mediaType, int imgWidth, int imgHeight, string path, int season) { - cTVDBMedia *media = new cTVDBMedia(); - media->width = imgWidth; - media->height = imgHeight; - media->path = path; - media->mediaType = mediaType; - switch (mediaType) { - case msPoster1: - case msPoster2: - case msPoster3: - posters.push_back(media); - break; - case msFanart1: - case msFanart2: - case msFanart3: - fanart.push_back(media); - break; - case msBanner1: - case msBanner2: - case msBanner3: - banners.push_back(media); - case msSeasonPoster: - seasonPosters.insert(pair(season, media)); - break; - case msPosterThumb: - posterThumb = media; - break; - case msSeasonPosterThumb: - seasonPosterThumbs.insert(pair(season, media)); - break; - default: - break; - } -} - -void cTVDBSeries::GetEpisode(int episodeId, cEpisode *e) { - map::iterator hit = episodes.find(episodeId); - if (hit == episodes.end()) - return; - cTVDBEpisode *eStored = hit->second; - e->number = eStored->number; - e->season = eStored->season; - e->name = eStored->name; - e->firstAired = eStored->firstAired; - e->guestStars = eStored->guestStars; - e->overview = eStored->overview; - e->rating = eStored->rating; - if (eStored->episodeImage) { - e->episodeImage.path = eStored->episodeImage->path; - e->episodeImage.width = eStored->episodeImage->width; - e->episodeImage.height = eStored->episodeImage->height; - } -} - -void cTVDBSeries::GetPosters(vector *p) { - for (vector::iterator it = posters.begin(); it != posters.end(); it++) { - cTVDBMedia *mStored = *it; - cTvMedia m; - m.path = mStored->path; - m.width = mStored->width; - m.height = mStored->height; - p->push_back(m); - } -} - -bool cTVDBSeries::GetPoster(cTvMedia *p) { - if (posters.size() > 0) { - p->path = posters[0]->path; - p->width = posters[0]->width; - p->height = posters[0]->height; - return true; - } - return false; -} - -bool cTVDBSeries::GetPosterThumb(cTvMedia *p) { - if (posterThumb) { - p->path = posterThumb->path; - p->width = posterThumb->width; - p->height = posterThumb->height; - return true; - } - return false; -} - -void cTVDBSeries::GetBanners(vector *b) { - for (vector::iterator it = banners.begin(); it != banners.end(); it++) { - cTVDBMedia *bStored = *it; - cTvMedia m; - m.path = bStored->path; - m.width = bStored->width; - m.height = bStored->height; - b->push_back(m); - } -} - -bool cTVDBSeries::GetRandomBanner(cTvMedia *b) { - int numBanners = banners.size(); - if (numBanners == 0) - return false; - srand((unsigned)time(NULL)); - int banner = rand()%numBanners; - cTVDBMedia *bStored = banners[banner]; - b->path = bStored->path; - b->width = bStored->width; - b->height = bStored->height; - return true; -} - -void cTVDBSeries::GetFanart(vector *f) { - for (vector::iterator it = fanart.begin(); it != fanart.end(); it++) { - cTVDBMedia *fStored = *it; - cTvMedia m; - m.path = fStored->path; - m.width = fStored->width; - m.height = fStored->height; - f->push_back(m); - } -} - -void cTVDBSeries::GetSeasonPoster(int episodeId, cTvMedia *sp) { - map::iterator hit = episodes.find(episodeId); - if (hit == episodes.end()) - return; - cTVDBEpisode *e = hit->second; - map::iterator hit2 = seasonPosters.find(e->season); - if (hit2 == seasonPosters.end()) - return; - cTVDBMedia *spStored = hit2->second; - sp->width = spStored->width; - sp->height = spStored->height; - sp->path = spStored->path; -} - -void cTVDBSeries::GetActors(vector *a) { - for (map::iterator it = actors.begin(); it != actors.end(); it++) { - cTVDBActor *aStored = it->second; - cActor act; - act.name = aStored->name; - act.role = aStored->role; - if (aStored->actorThumb) { - act.actorThumb.width = aStored->actorThumb->width; - act.actorThumb.height = aStored->actorThumb->height; - act.actorThumb.path = aStored->actorThumb->path; - } - a->push_back(act); - } -} - -void cTVDBSeries::Dump(void) { - tell(0, "--------------------------- Series Info ----------------------------------"); - tell(0, "series %s, ID: %d", name.c_str(), id); - tell(0, "Overview: %s", overview.c_str()); - tell(0, "FirstAired: %s", firstAired.c_str()); - tell(0, "Network: %s", network.c_str()); - tell(0, "Status: %s", status.c_str()); - tell(0, "Genre: %s", genre.c_str()); - tell(0, "Rating: %f", rating); - tell(0, "--------------------------- Media ----------------------------------"); - for (vector::iterator it = posters.begin(); it != posters.end(); it++) { - cTVDBMedia *m = *it; - tell(0, "Poster %d, Path: %s", m->mediaType, m->path.c_str()); - tell(0, "width %d, height %d", m->width, m->height); - } - for (vector::iterator it = banners.begin(); it != banners.end(); it++) { - cTVDBMedia *m = *it; - tell(0, "Banner %d, Path: %s", m->mediaType, m->path.c_str()); - tell(0, "width %d, height %d", m->width, m->height); - } - for (vector::iterator it = fanart.begin(); it != fanart.end(); it++) { - cTVDBMedia *m = *it; - tell(0, "Fanart %d, Path: %s", m->mediaType, m->path.c_str()); - tell(0, "width %d, height %d", m->width, m->height); - } - tell(0, "--------------------------- Episodes ----------------------------------"); - for (map::iterator it = episodes.begin(); it != episodes.end(); it++) { - cTVDBEpisode *e = it->second; - tell(0, "Episode %d, Name: %s", e->id, e->name.c_str()); - if (e->episodeImage) { - tell(0, "Episode Image: %d x %d, Path: %s", e->episodeImage->width, e->episodeImage->height, e->episodeImage->path.c_str()); - } - } - tell(0, "--------------------------- Season Posters ----------------------------------"); - for (map::iterator it = seasonPosters.begin(); it != seasonPosters.end(); it++) { - int season = it->first; - cTVDBMedia *m = it->second; - tell(0, "Season %d, %d x %d, Path: %s", season, m->width, m->height, m->path.c_str()); - } - tell(0, "--------------------------- Actors ----------------------------------"); - for (map::iterator it = actors.begin(); it != actors.end(); it++) { - cTVDBActor *a = it->second; - tell(0, "Actor %d, Name: %s, Role %s", a->id, a->name.c_str(), a->role.c_str()); - if (a->actorThumb) { - tell(0, "Thumb: %d x %d, Path: %s", a->actorThumb->width, a->actorThumb->height, a->actorThumb->path.c_str()); - } - } - if (posterThumb) { - tell(0, "posterThumb path %s, width %d, height %d", posterThumb->path.c_str(), posterThumb->width, posterThumb->height); - } -} +#define __STL_CONFIG_H +#include "lib/common.h" +#include "tvdbseries.h" + +using namespace std; + +cTVDBSeries::cTVDBSeries(void) { + id = 0; + name = ""; + overview = ""; + firstAired = ""; + network = ""; + genre = ""; + rating = 0.0; + status = ""; + posterThumb = NULL; +} + +cTVDBSeries::~cTVDBSeries() { + for (map::iterator it = actors.begin(); it != actors.end(); it++) { + cTVDBActor *a = (cTVDBActor*)it->second; + delete a; + } + for (map::iterator it = episodes.begin(); it != episodes.end(); it++) { + cTVDBEpisode *e = (cTVDBEpisode*)it->second; + delete e; + } + for (vector::iterator it = posters.begin(); it != posters.end(); it++) { + cTVDBMedia *p = *it; + delete p; + } + for (vector::iterator it = banners.begin(); it != banners.end(); it++) { + cTVDBMedia *b = *it; + delete b; + } + for (vector::iterator it = fanart.begin(); it != fanart.end(); it++) { + cTVDBMedia *f = *it; + delete f; + } + for (map::iterator it = seasonPosters.begin(); it != seasonPosters.end(); it++) { + cTVDBMedia *s = (cTVDBMedia*)it->second; + delete s; + } + for (map::iterator it = seasonPosterThumbs.begin(); it != seasonPosterThumbs.end(); it++) { + cTVDBMedia *s = (cTVDBMedia*)it->second; + delete s; + } + if (posterThumb) + delete posterThumb; +} + +void cTVDBSeries::InsertEpisode(cTVDBEpisode *episode) { + map::iterator hit = episodes.find(episode->id); + if (hit != episodes.end()) + delete episode; + else + episodes.insert(pair(episode->id, episode)); +} + +void cTVDBSeries::InsertEpisodeImage(int episodeId, int width, int height, string path) { + map::iterator hit = episodes.find(episodeId); + if (hit != episodes.end()) { + cTVDBEpisode *e = hit->second; + cTVDBMedia *m = new cTVDBMedia(); + m->width = width; + m->height = height; + m->path = path; + m->mediaType = msEpisodePic; + e->episodeImage = m; + } +} + +void cTVDBSeries::InsertActor(cTVDBActor *actor) { + actors.insert(pair(actor->id, actor)); +} + +void cTVDBSeries::InsertActorThumb(int actorId, int imgWidth, int imgHeight, string path) { + map::iterator hit = actors.find(actorId); + if (hit != actors.end()) { + cTVDBActor *a = hit->second; + cTVDBMedia *m = new cTVDBMedia(); + m->width = imgWidth; + m->height = imgHeight; + m->path = path; + m->mediaType = msActorThumb; + a->actorThumb = m; + } +} + +void cTVDBSeries::InsertMedia(int mediaType, int imgWidth, int imgHeight, string path, int season) { + cTVDBMedia *media = new cTVDBMedia(); + media->width = imgWidth; + media->height = imgHeight; + media->path = path; + media->mediaType = mediaType; + switch (mediaType) { + case msPoster1: + case msPoster2: + case msPoster3: + posters.push_back(media); + break; + case msFanart1: + case msFanart2: + case msFanart3: + fanart.push_back(media); + break; + case msBanner1: + case msBanner2: + case msBanner3: + banners.push_back(media); + case msSeasonPoster: + seasonPosters.insert(pair(season, media)); + break; + case msPosterThumb: + posterThumb = media; + break; + case msSeasonPosterThumb: + seasonPosterThumbs.insert(pair(season, media)); + break; + default: + break; + } +} + +void cTVDBSeries::GetEpisode(int episodeId, cEpisode *e) { + map::iterator hit = episodes.find(episodeId); + if (hit == episodes.end()) + return; + cTVDBEpisode *eStored = hit->second; + e->number = eStored->number; + e->season = eStored->season; + e->name = eStored->name; + e->firstAired = eStored->firstAired; + e->guestStars = eStored->guestStars; + e->overview = eStored->overview; + e->rating = eStored->rating; + if (eStored->episodeImage) { + e->episodeImage.path = eStored->episodeImage->path; + e->episodeImage.width = eStored->episodeImage->width; + e->episodeImage.height = eStored->episodeImage->height; + } +} + +void cTVDBSeries::GetPosters(vector *p) { + for (vector::iterator it = posters.begin(); it != posters.end(); it++) { + cTVDBMedia *mStored = *it; + cTvMedia m; + m.path = mStored->path; + m.width = mStored->width; + m.height = mStored->height; + p->push_back(m); + } +} + +bool cTVDBSeries::GetPoster(cTvMedia *p) { + if (posters.size() > 0) { + p->path = posters[0]->path; + p->width = posters[0]->width; + p->height = posters[0]->height; + return true; + } + return false; +} + +bool cTVDBSeries::GetPosterThumb(cTvMedia *p) { + if (posterThumb) { + p->path = posterThumb->path; + p->width = posterThumb->width; + p->height = posterThumb->height; + return true; + } + return false; +} + +void cTVDBSeries::GetBanners(vector *b) { + for (vector::iterator it = banners.begin(); it != banners.end(); it++) { + cTVDBMedia *bStored = *it; + cTvMedia m; + m.path = bStored->path; + m.width = bStored->width; + m.height = bStored->height; + b->push_back(m); + } +} + +bool cTVDBSeries::GetRandomBanner(cTvMedia *b) { + int numBanners = banners.size(); + if (numBanners == 0) + return false; + srand((unsigned)time(NULL)); + int banner = rand()%numBanners; + cTVDBMedia *bStored = banners[banner]; + b->path = bStored->path; + b->width = bStored->width; + b->height = bStored->height; + return true; +} + +void cTVDBSeries::GetFanart(vector *f) { + for (vector::iterator it = fanart.begin(); it != fanart.end(); it++) { + cTVDBMedia *fStored = *it; + cTvMedia m; + m.path = fStored->path; + m.width = fStored->width; + m.height = fStored->height; + f->push_back(m); + } +} + +void cTVDBSeries::GetSeasonPoster(int episodeId, cTvMedia *sp) { + map::iterator hit = episodes.find(episodeId); + if (hit == episodes.end()) + return; + cTVDBEpisode *e = hit->second; + map::iterator hit2 = seasonPosters.find(e->season); + if (hit2 == seasonPosters.end()) + return; + cTVDBMedia *spStored = hit2->second; + sp->width = spStored->width; + sp->height = spStored->height; + sp->path = spStored->path; +} + +void cTVDBSeries::GetActors(vector *a) { + for (map::iterator it = actors.begin(); it != actors.end(); it++) { + cTVDBActor *aStored = it->second; + cActor act; + act.name = aStored->name; + act.role = aStored->role; + if (aStored->actorThumb) { + act.actorThumb.width = aStored->actorThumb->width; + act.actorThumb.height = aStored->actorThumb->height; + act.actorThumb.path = aStored->actorThumb->path; + } + a->push_back(act); + } +} + +void cTVDBSeries::Dump(void) { + tell(0, "--------------------------- Series Info ----------------------------------"); + tell(0, "series %s, ID: %d", name.c_str(), id); + tell(0, "Overview: %s", overview.c_str()); + tell(0, "FirstAired: %s", firstAired.c_str()); + tell(0, "Network: %s", network.c_str()); + tell(0, "Status: %s", status.c_str()); + tell(0, "Genre: %s", genre.c_str()); + tell(0, "Rating: %f", rating); + tell(0, "--------------------------- Media ----------------------------------"); + for (vector::iterator it = posters.begin(); it != posters.end(); it++) { + cTVDBMedia *m = *it; + tell(0, "Poster %d, Path: %s", m->mediaType, m->path.c_str()); + tell(0, "width %d, height %d", m->width, m->height); + } + for (vector::iterator it = banners.begin(); it != banners.end(); it++) { + cTVDBMedia *m = *it; + tell(0, "Banner %d, Path: %s", m->mediaType, m->path.c_str()); + tell(0, "width %d, height %d", m->width, m->height); + } + for (vector::iterator it = fanart.begin(); it != fanart.end(); it++) { + cTVDBMedia *m = *it; + tell(0, "Fanart %d, Path: %s", m->mediaType, m->path.c_str()); + tell(0, "width %d, height %d", m->width, m->height); + } + tell(0, "--------------------------- Episodes ----------------------------------"); + for (map::iterator it = episodes.begin(); it != episodes.end(); it++) { + cTVDBEpisode *e = it->second; + tell(0, "Episode %d, Name: %s", e->id, e->name.c_str()); + if (e->episodeImage) { + tell(0, "Episode Image: %d x %d, Path: %s", e->episodeImage->width, e->episodeImage->height, e->episodeImage->path.c_str()); + } + } + tell(0, "--------------------------- Season Posters ----------------------------------"); + for (map::iterator it = seasonPosters.begin(); it != seasonPosters.end(); it++) { + int season = it->first; + cTVDBMedia *m = it->second; + tell(0, "Season %d, %d x %d, Path: %s", season, m->width, m->height, m->path.c_str()); + } + tell(0, "--------------------------- Actors ----------------------------------"); + for (map::iterator it = actors.begin(); it != actors.end(); it++) { + cTVDBActor *a = it->second; + tell(0, "Actor %d, Name: %s, Role %s", a->id, a->name.c_str(), a->role.c_str()); + if (a->actorThumb) { + tell(0, "Thumb: %d x %d, Path: %s", a->actorThumb->width, a->actorThumb->height, a->actorThumb->path.c_str()); + } + } + if (posterThumb) { + tell(0, "posterThumb path %s, width %d, height %d", posterThumb->path.c_str(), posterThumb->width, posterThumb->height); + } +} diff --git a/tvdbseries.h b/tvdbseries.h index 7d44929..3db02e0 100644 --- a/tvdbseries.h +++ b/tvdbseries.h @@ -1,143 +1,143 @@ -#ifndef __TVSCRAPER_TVDBSERIES_H -#define __TVSCRAPER_TVDBSERIES_H - -#include -#include -#include -#include -#include -#include -#include -#include "services.h" - -using namespace std; - -enum mediaSeries { - msBanner1, - msBanner2, - msBanner3, - msPoster1, - msPoster2, - msPoster3, - msSeasonPoster, - msFanart1, - msFanart2, - msFanart3, - msEpisodePic, - msActorThumb, - msPosterThumb, - msSeasonPosterThumb, -}; - -// --- cTVDBMedia ------------------------------------------------------------- -class cTVDBMedia { -public: - cTVDBMedia(void) { - path = ""; - mediaType = msBanner1; - width = 0; - height = 0; - }; - ~cTVDBMedia(void) { - }; - string path; - int mediaType; - int width; - int height; -}; - -// --- cTVDBEpisode ------------------------------------------------------------- -class cTVDBEpisode { -public: - cTVDBEpisode(void) { - id = 0; - number = 0; - season = 0; - name = ""; - firstAired = ""; - guestStars = ""; - overview = ""; - rating = 0.0; - episodeImage = NULL; - }; - ~cTVDBEpisode(void) { - if (episodeImage) - delete episodeImage; - }; - int id; - int number; - int season; - string name; - string firstAired; - string guestStars; - string overview; - float rating; - cTVDBMedia *episodeImage; -}; - -// --- cTVDBActor ------------------------------------------------------------- -class cTVDBActor { -public: - cTVDBActor(void) { - id = 0; - name = ""; - role = ""; - thumbWidth = 0; - thumbHeight = 0; - actorThumb = NULL; - }; - ~cTVDBActor(void) { - if (actorThumb) - delete actorThumb; - }; - int id; - string name; - string role; - int thumbWidth; - int thumbHeight; - cTVDBMedia *actorThumb; -}; - -// --- cTVDBSeries ------------------------------------------------------------- - -class cTVDBSeries { -private: - map episodes; - map actors; - vector posters; - vector banners; - vector fanart; - map seasonPosters; - map seasonPosterThumbs; - cTVDBMedia *posterThumb; -public: - cTVDBSeries(void); - virtual ~cTVDBSeries(void); - int id; - string name; - string overview; - string firstAired; - string network; - string genre; - float rating; - string status; - void InsertEpisode(cTVDBEpisode *episode); - void InsertEpisodeImage(int episodeId, int width, int height, string path); - void InsertActor(cTVDBActor *actor); - void InsertActorThumb(int actorId, int imgWidth, int imgHeight, string path); - void InsertMedia(int mediaType, int imgWidth, int imgHeight, string path, int season = 0); - //Getter for Serivice Calls - void GetEpisode(int episodeId, cEpisode *e); - void GetPosters(vector *p); - bool GetPoster(cTvMedia *p); - bool GetPosterThumb(cTvMedia *p); - void GetBanners(vector *b); - bool GetRandomBanner(cTvMedia *b); - void GetFanart(vector *f); - void GetSeasonPoster(int episodeId, cTvMedia *sp); - void GetActors(vector *a); - void Dump(void); -}; - - -#endif //__TVSCRAPER_TVDBSERIES_H +#ifndef __TVSCRAPER_TVDBSERIES_H +#define __TVSCRAPER_TVDBSERIES_H + +#include +#include +#include +#include +#include +#include +#include +#include "services.h" + +using namespace std; + +enum mediaSeries { + msBanner1, + msBanner2, + msBanner3, + msPoster1, + msPoster2, + msPoster3, + msSeasonPoster, + msFanart1, + msFanart2, + msFanart3, + msEpisodePic, + msActorThumb, + msPosterThumb, + msSeasonPosterThumb, +}; + +// --- cTVDBMedia ------------------------------------------------------------- +class cTVDBMedia { +public: + cTVDBMedia(void) { + path = ""; + mediaType = msBanner1; + width = 0; + height = 0; + }; + ~cTVDBMedia(void) { + }; + string path; + int mediaType; + int width; + int height; +}; + +// --- cTVDBEpisode ------------------------------------------------------------- +class cTVDBEpisode { +public: + cTVDBEpisode(void) { + id = 0; + number = 0; + season = 0; + name = ""; + firstAired = ""; + guestStars = ""; + overview = ""; + rating = 0.0; + episodeImage = NULL; + }; + ~cTVDBEpisode(void) { + if (episodeImage) + delete episodeImage; + }; + int id; + int number; + int season; + string name; + string firstAired; + string guestStars; + string overview; + float rating; + cTVDBMedia *episodeImage; +}; + +// --- cTVDBActor ------------------------------------------------------------- +class cTVDBActor { +public: + cTVDBActor(void) { + id = 0; + name = ""; + role = ""; + thumbWidth = 0; + thumbHeight = 0; + actorThumb = NULL; + }; + ~cTVDBActor(void) { + if (actorThumb) + delete actorThumb; + }; + int id; + string name; + string role; + int thumbWidth; + int thumbHeight; + cTVDBMedia *actorThumb; +}; + +// --- cTVDBSeries ------------------------------------------------------------- + +class cTVDBSeries { +private: + map episodes; + map actors; + vector posters; + vector banners; + vector fanart; + map seasonPosters; + map seasonPosterThumbs; + cTVDBMedia *posterThumb; +public: + cTVDBSeries(void); + virtual ~cTVDBSeries(void); + int id; + string name; + string overview; + string firstAired; + string network; + string genre; + float rating; + string status; + void InsertEpisode(cTVDBEpisode *episode); + void InsertEpisodeImage(int episodeId, int width, int height, string path); + void InsertActor(cTVDBActor *actor); + void InsertActorThumb(int actorId, int imgWidth, int imgHeight, string path); + void InsertMedia(int mediaType, int imgWidth, int imgHeight, string path, int season = 0); + //Getter for Serivice Calls + void GetEpisode(int episodeId, cEpisode *e); + void GetPosters(vector *p); + bool GetPoster(cTvMedia *p); + bool GetPosterThumb(cTvMedia *p); + void GetBanners(vector *b); + bool GetRandomBanner(cTvMedia *b); + void GetFanart(vector *f); + void GetSeasonPoster(int episodeId, cTvMedia *sp); + void GetActors(vector *a); + void Dump(void); +}; + + +#endif //__TVSCRAPER_TVDBSERIES_H diff --git a/update.c b/update.c index 0e4be7d..addc14b 100644 --- a/update.c +++ b/update.c @@ -5,6 +5,8 @@ #include #include +#include "lib/config.h" + #include "config.h" #include "tools.h" #include "update.h" @@ -24,6 +26,21 @@ cUpdate::cUpdate(cScrapManager *manager) : cThread("update thread started") { tMovieActors = NULL; tMovieMedia = NULL; tRecordings = NULL; + + selectReadScrapedEventsInit = 0; + selectReadScrapedEvents = 0; + selectImg = 0; + selectSeasonPoster = 0; + selectActors = 0; + selectActorThumbs = 0; + selectSeriesMedia = 0; + selectMovieActors = 0; + selectMovieActorThumbs = 0; + selectMovieMedia = 0; + selectMediaMovie = 0; + selectRecordings = 0; + selectCleanupRecordings = 0; + scrapManager = manager; imgPathSeries = config.imageDir + "/series"; imgPathMovies = config.imageDir + "/movies"; @@ -44,6 +61,7 @@ cUpdate::cUpdate(cScrapManager *manager) : cThread("update thread started") { } else { tell(0, "Reseting locale for LC_CTYPE failed."); } + cDbConnection::setEncoding(withutf8 ? "utf8": "latin1"); cDbConnection::setHost(config.mysqlHost.c_str()); cDbConnection::setPort(config.mysqlPort); @@ -51,36 +69,20 @@ cUpdate::cUpdate(cScrapManager *manager) : cThread("update thread started") { cDbConnection::setUser(config.mysqlDBUser.c_str()); cDbConnection::setPass(config.mysqlDBPass.c_str()); cDbTable::setConfPath(cPlugin::ConfigDirectory("epg2vdr/")); + + EPG2VDRConfig.loglevel = config.debug ? 2 : 1; } cUpdate::~cUpdate() { if (loopActive) Stop(); - if (vdrDb) - delete vdrDb; - if (tEvents) - delete tEvents; - if (tSeries) - delete tSeries; - if (tEpisodes) - tEpisodes; - if (tSeriesMedia) - delete tSeriesMedia; - if (tSeriesActors) - delete tSeriesActors; - if (tMovies) - delete tMovies; - if (tMovieActor) - delete tMovieActor; - if (tMovieActors) - delete tMovieActors; - if (tMovieMedia) - delete tMovieMedia; - if (tRecordings) - delete tRecordings; exitDb(); } +// global field definitions + +cDBS::FieldDef imageSizeDef = { "media_content", cDBS::ffUInt, 0, 999, cDBS::ftData }; + int cUpdate::initDb() { int status = success; if (!connection) @@ -120,12 +122,269 @@ int cUpdate::initDb() { tRecordings = new cTableRecordings(connection); if (tRecordings->open() != success) return fail; + + // -------------------- + // prepare statements + + // + + selectReadScrapedEventsInit = new cDbStatement(tEvents); + selectReadScrapedEventsInit->build("select "); + selectReadScrapedEventsInit->bind(cTableEvents::fiEventId, cDBS::bndOut); + selectReadScrapedEventsInit->bind(cTableEvents::fiChannelId, cDBS::bndOut, ", "); + selectReadScrapedEventsInit->bind(cTableEvents::fiMasterId, cDBS::bndOut, ", "); + selectReadScrapedEventsInit->bind(cTableEvents::fiScrSeriesId, cDBS::bndOut, ", "); + selectReadScrapedEventsInit->bind(cTableEvents::fiScrSeriesEpisode, cDBS::bndOut, ", "); + selectReadScrapedEventsInit->bind(cTableEvents::fiScrMovieId, cDBS::bndOut, ", "); + selectReadScrapedEventsInit->bind(cTableEvents::fiScrSp, cDBS::bndOut, ", "); + selectReadScrapedEventsInit->build(" from %s where ", tEvents->TableName()); + selectReadScrapedEventsInit->build(" ((%s is not null and %s > 0) ", + tEvents->getField(cTableEvents::fiScrSeriesId)->name, + tEvents->getField(cTableEvents::fiScrSeriesId)->name); + selectReadScrapedEventsInit->build(" or (%s is not null and %s > 0)) ", + tEvents->getField(cTableEvents::fiScrMovieId)->name, + tEvents->getField(cTableEvents::fiScrMovieId)->name); + selectReadScrapedEventsInit->build(" order by %s", tEvents->getField(cTableEvents::fiInsSp)->name); + + status += selectReadScrapedEventsInit->prepare(); + + // + + selectReadScrapedEvents = new cDbStatement(tEvents); + selectReadScrapedEvents->build("select "); + selectReadScrapedEvents->bind(cTableEvents::fiEventId, cDBS::bndOut); + selectReadScrapedEvents->bind(cTableEvents::fiChannelId, cDBS::bndOut, ", "); + selectReadScrapedEvents->bind(cTableEvents::fiMasterId, cDBS::bndOut, ", "); + selectReadScrapedEvents->bind(cTableEvents::fiScrSeriesId, cDBS::bndOut, ", "); + selectReadScrapedEvents->bind(cTableEvents::fiScrSeriesEpisode, cDBS::bndOut, ", "); + selectReadScrapedEvents->bind(cTableEvents::fiScrMovieId, cDBS::bndOut, ", "); + selectReadScrapedEvents->bind(cTableEvents::fiScrSp, cDBS::bndOut, ", "); + selectReadScrapedEvents->build(" from %s where ", tEvents->TableName()); + selectReadScrapedEvents->build(" ((%s is not null and %s > 0) ", + tEvents->getField(cTableEvents::fiScrSeriesId)->name, + tEvents->getField(cTableEvents::fiScrSeriesId)->name); + selectReadScrapedEvents->build(" or (%s is not null and %s > 0)) ", + tEvents->getField(cTableEvents::fiScrMovieId)->name, + tEvents->getField(cTableEvents::fiScrMovieId)->name); + selectReadScrapedEvents->bind(cTableEvents::fiScrSp, cDBS::bndIn | cDBS::bndSet, " and "); + selectReadScrapedEvents->build(" order by %s", tEvents->getField(cTableEvents::fiInsSp)->name); + + status += selectReadScrapedEvents->prepare(); + + // select image + + imageSize.setField(&imageSizeDef); + selectImg = new cDbStatement(tSeriesMedia); + selectImg->build("select "); + selectImg->bind(cTableSeriesMedia::fiMediaWidth, cDBS::bndOut); + selectImg->bind(cTableSeriesMedia::fiMediaHeight, cDBS::bndOut, ", "); + selectImg->bind(cTableSeriesMedia::fiMediaContent, cDBS::bndOut, ", "); + selectImg->build(", length("); + selectImg->bind(&imageSize, cDBS::bndOut); + selectImg->build(")"); + selectImg->build(" from %s where ", tSeriesMedia->TableName()); + selectImg->bind(cTableSeriesMedia::fiSeriesId, cDBS::bndIn | cDBS::bndSet); + selectImg->bind(cTableSeriesMedia::fiEpisodeId, cDBS::bndIn | cDBS::bndSet, " and "); + status += selectImg->prepare(); + + // select poster image + + posterSize.setField(&imageSizeDef); + selectSeasonPoster = new cDbStatement(tSeriesMedia); + selectSeasonPoster->build("select "); + selectSeasonPoster->bind(cTableSeriesMedia::fiMediaWidth, cDBS::bndOut); + selectSeasonPoster->bind(cTableSeriesMedia::fiMediaHeight, cDBS::bndOut, ", "); + selectSeasonPoster->bind(cTableSeriesMedia::fiMediaContent, cDBS::bndOut, ", "); + selectSeasonPoster->build(", length("); + selectSeasonPoster->bind(&posterSize, cDBS::bndOut); + selectSeasonPoster->build(")"); + selectSeasonPoster->build(" from %s where ", tSeriesMedia->TableName()); + selectSeasonPoster->bind(cTableSeriesMedia::fiSeriesId, cDBS::bndIn | cDBS::bndSet); + selectSeasonPoster->bind(cTableSeriesMedia::fiSeasonNumber, cDBS::bndIn | cDBS::bndSet, " and "); + selectSeasonPoster->bind(cTableSeriesMedia::fiMediaType, cDBS::bndIn | cDBS::bndSet, " and "); + status += selectSeasonPoster->prepare(); + + // select actor + + series_id.setField(tSeriesMedia->getField(cTableSeriesMedia::fiSeriesId)); + selectActors = new cDbStatement(tSeriesActors); + selectActors->build("select "); + selectActors->setBindPrefix("series_actor."); + selectActors->bind(cTableSeriesActor::fiActorId, cDBS::bndOut); + selectActors->bind(cTableSeriesActor::fiActorName, cDBS::bndOut, ", "); + selectActors->bind(cTableSeriesActor::fiActorRole, cDBS::bndOut, ", "); + selectActors->clrBindPrefix(); + selectActors->build(" from %s, %s where ", tSeriesActors->TableName(), tSeriesMedia->TableName()); + selectActors->build(" %s.%s = %s.%s ", tSeriesActors->TableName(), + tSeriesActors->getField(cTableSeriesActor::fiActorId)->name, + tSeriesMedia->TableName(), + tSeriesMedia->getField(cTableSeriesMedia::fiActorId)->name); + selectActors->setBindPrefix("series_media."); + selectActors->bind(&series_id, cDBS::bndIn | cDBS::bndSet, " and "); + selectActors->build(" order by %s, %s asc", tSeriesActors->getField(cTableSeriesActor::fiSortOrder)->name, + tSeriesActors->getField(cTableSeriesActor::fiActorRole)->name); + status += selectActors->prepare(); + + // select actor thumbs + + actorImageSize.setField(&imageSizeDef); + selectActorThumbs = new cDbStatement(tSeriesMedia); + selectActorThumbs->build("select "); + selectActorThumbs->bind(cTableSeriesMedia::fiMediaWidth, cDBS::bndOut); + selectActorThumbs->bind(cTableSeriesMedia::fiMediaHeight, cDBS::bndOut, ", "); + selectActorThumbs->bind(cTableSeriesMedia::fiMediaContent, cDBS::bndOut, ", "); + selectActorThumbs->build(", length("); + selectActorThumbs->bind(&actorImageSize, cDBS::bndOut); + selectActorThumbs->build(")"); + selectActorThumbs->build(" from %s where ", tSeriesMedia->TableName()); + selectActorThumbs->bind(cTableSeriesMedia::fiActorId, cDBS::bndIn | cDBS::bndSet); + status += selectActorThumbs->prepare(); + + // + + selectSeriesMedia = new cDbStatement(tSeriesMedia); + selectSeriesMedia->build("select "); + selectSeriesMedia->bind(cTableSeriesMedia::fiMediaWidth, cDBS::bndOut); + selectSeriesMedia->bind(cTableSeriesMedia::fiMediaHeight, cDBS::bndOut, ", "); + selectSeriesMedia->bind(cTableSeriesMedia::fiMediaType, cDBS::bndOut, ", "); + selectSeriesMedia->build(" from %s where ", tSeriesMedia->TableName()); + selectSeriesMedia->bind(cTableSeriesMedia::fiSeriesId, cDBS::bndIn | cDBS::bndSet); + selectSeriesMedia->build(" and %s in (%d, %d, %d, %d, %d, %d, %d, %d, %d)", + tSeriesMedia->getField(cTableSeriesMedia::fiMediaType)->name, + msPoster1, msPoster2, msPoster3, + msFanart1, msFanart2, msFanart3, + msBanner1, msBanner2, msBanner3); + status += selectSeriesMedia->prepare(); + + // + + actorRole.setField(tMovieActors->getField(cTableMovieActors::fiRole)); + actorMovie.setField(tMovieActors->getField(cTableMovieActors::fiMovieId)); + thbWidth.setField(tMovieMedia->getField(cTableMovieMedia::fiMediaWidth)); + thbHeight.setField(tMovieMedia->getField(cTableMovieMedia::fiMediaHeight)); + + selectMovieActors = new cDbStatement(tMovieActor); + selectMovieActors->build("select "); + selectMovieActors->setBindPrefix("act."); + selectMovieActors->bind(cTableMovieActor::fiActorId, cDBS::bndOut); + selectMovieActors->bind(cTableMovieActor::fiActorName, cDBS::bndOut, ", "); + selectMovieActors->setBindPrefix("role."); + selectMovieActors->bind(&actorRole, cDBS::bndOut, ", "); + selectMovieActors->setBindPrefix("thumb."); + selectMovieActors->bind(&thbWidth, cDBS::bndOut, ", "); + selectMovieActors->bind(&thbHeight, cDBS::bndOut, ", "); + selectMovieActors->clrBindPrefix(); + selectMovieActors->build(" from %s act, %s role, %s thumb where ", + tMovieActor->TableName(), tMovieActors->TableName(), tMovieMedia->TableName()); + selectMovieActors->build("act.%s = role.%s ", + tMovieActor->getField(cTableMovieActor::fiActorId)->name, + tMovieActors->getField(cTableMovieActors::fiActorId)->name); + selectMovieActors->build(" and role.%s = thumb.%s ", + tMovieActors->getField(cTableMovieActors::fiActorId)->name, + tMovieMedia->getField(cTableMovieMedia::fiActorId)->name); + selectMovieActors->setBindPrefix("role."); + selectMovieActors->bind(&actorMovie, cDBS::bndIn | cDBS::bndSet, " and "); + status += selectMovieActors->prepare(); + + // + + selectMovieActorThumbs = new cDbStatement(tMovieMedia); + selectMovieActorThumbs->build("select "); + selectMovieActorThumbs->bind(cTableMovieMedia::fiMediaContent, cDBS::bndOut); + selectMovieActorThumbs->build(", length("); + selectMovieActorThumbs->bind(&imageSize, cDBS::bndOut); + selectMovieActorThumbs->build(")"); + selectMovieActorThumbs->build(" from %s where ", tMovieMedia->TableName()); + selectMovieActorThumbs->bind(cTableMovieMedia::fiActorId, cDBS::bndIn | cDBS::bndSet); + status += selectMovieActorThumbs->prepare(); + + // + + selectMovieMedia = new cDbStatement(tMovieMedia); + selectMovieMedia->build("select "); + selectMovieMedia->bind(cTableMovieMedia::fiMediaWidth, cDBS::bndOut); + selectMovieMedia->bind(cTableMovieMedia::fiMediaHeight, cDBS::bndOut, ", "); + selectMovieMedia->bind(cTableMovieMedia::fiMediaType, cDBS::bndOut, ", "); + selectMovieMedia->build(" from %s where ", tMovieMedia->TableName()); + selectMovieMedia->bind(cTableMovieMedia::fiMovieId, cDBS::bndIn | cDBS::bndSet); + selectMovieMedia->build(" and %s in (%d, %d, %d, %d)", + tMovieMedia->getField(cTableMovieMedia::fiMediaType)->name, + mmPoster, + mmFanart, + mmCollectionPoster, + mmCollectionFanart); + status += selectMovieMedia->prepare(); + + // + + selectMediaMovie = new cDbStatement(tMovieMedia); + selectMediaMovie->build("select "); + selectMediaMovie->bind(cTableMovieMedia::fiMediaContent, cDBS::bndOut); + selectMediaMovie->build(", length("); + selectMediaMovie->bind(&imageSize, cDBS::bndOut); + selectMediaMovie->build(")"); + selectMediaMovie->build(" from %s where ", tMovieMedia->TableName()); + selectMediaMovie->bind(cTableMovieMedia::fiMovieId, cDBS::bndIn | cDBS::bndSet); + selectMediaMovie->bind(cTableMovieMedia::fiMediaType, cDBS::bndIn | cDBS::bndSet, " and "); + status += selectMediaMovie->prepare(); + + // + + selectRecordings = new cDbStatement(tRecordings); + selectRecordings->build("select "); + selectRecordings->bind(cTableRecordings::fiRecPath, cDBS::bndOut); + selectRecordings->bind(cTableRecordings::fiRecStart, cDBS::bndOut, ", "); + selectRecordings->bind(cTableRecordings::fiMovieId, cDBS::bndOut, ", "); + selectRecordings->bind(cTableRecordings::fiSeriesId, cDBS::bndOut, ", "); + selectRecordings->bind(cTableRecordings::fiEpisodeId, cDBS::bndOut, ", "); + selectRecordings->build(" from %s where ", tRecordings->TableName()); + selectRecordings->bind(cTableRecordings::fiUuid, cDBS::bndIn | cDBS::bndSet); + selectRecordings->build(" and %s = 0", tRecordings->getField(cTableRecordings::fiScrapNew)->name); + status += selectRecordings->prepare(); + + // + + selectCleanupRecordings = new cDbStatement(tRecordings); + selectCleanupRecordings->build("select "); + selectCleanupRecordings->bind(cTableRecordings::fiRecPath, cDBS::bndOut); + selectCleanupRecordings->bind(cTableRecordings::fiRecStart, cDBS::bndOut, ", "); + selectCleanupRecordings->build(" from %s where ", tRecordings->TableName()); + selectCleanupRecordings->bind(cTableRecordings::fiUuid, cDBS::bndIn | cDBS::bndSet); + status += selectCleanupRecordings->prepare(); + return status; } int cUpdate::exitDb() { - delete connection; - connection = 0; + + delete selectReadScrapedEvents; selectReadScrapedEvents = 0; + delete selectReadScrapedEventsInit; selectReadScrapedEventsInit = 0; + delete selectImg; selectImg = 0; + delete selectSeasonPoster; selectSeasonPoster = 0; + delete selectActors; selectActors = 0; + delete selectActorThumbs; selectActorThumbs = 0; + delete selectSeriesMedia; selectSeriesMedia = 0; + delete selectMovieActors; selectMovieActors = 0; + delete selectMovieActorThumbs; selectMovieActorThumbs = 0; + delete selectMovieMedia; selectMovieMedia = 0; + delete selectMediaMovie; selectMediaMovie = 0; + delete selectRecordings; selectRecordings = 0; + delete selectCleanupRecordings; selectCleanupRecordings = 0; + + delete vdrDb; vdrDb = 0; + delete tEvents; tEvents = 0; + delete tSeries; tSeries = 0; + delete tEpisodes; tEpisodes = 0; + delete tSeriesMedia; tSeriesMedia = 0; + delete tSeriesActors; tSeriesActors = 0; + delete tMovies; tMovies = 0; + delete tMovieActor; tMovieActor = 0; + delete tMovieActors; tMovieActors = 0; + delete tMovieMedia; tMovieMedia = 0; + delete tRecordings; tRecordings = 0; + + delete connection; connection = 0; + return done; } @@ -157,51 +416,34 @@ int cUpdate::CheckConnection(int& timeout) { } bool cUpdate::CheckEpgdBusy(void) { - vdrDb->clear(); - vdrDb->setValue(cTableVdrs::fiUuid, EPGDNAME); - if (vdrDb->find()) { - Es::State epgdState = cEpgdState::toState(vdrDb->getStrValue(cTableVdrs::fiState)); - if (epgdState >= cEpgdState::esBusy) - return true; - } - return false; + int busy = false; + vdrDb->clear(); + vdrDb->setValue(cTableVdrs::fiUuid, EPGDNAME); + + if (vdrDb->find()) { + Es::State epgdState = cEpgdState::toState(vdrDb->getStrValue(cTableVdrs::fiState)); + // ignore esBusyImages until we don't write this table + if (epgdState >= cEpgdState::esBusy && epgdState < cEpgdState::esBusyImages) + busy = true; + } + + vdrDb->reset(); + return busy; } int cUpdate::ReadScrapedEvents(void) { - int status = success; - cDbStatement *select = new cDbStatement(tEvents); - select->build("select "); - select->bind(cTableEvents::fiEventId, cDBS::bndOut); - select->bind(cTableEvents::fiChannelId, cDBS::bndOut, ", "); - select->bind(cTableEvents::fiMasterId, cDBS::bndOut, ", "); - select->bind(cTableEvents::fiScrSeriesId, cDBS::bndOut, ", "); - select->bind(cTableEvents::fiScrSeriesEpisode, cDBS::bndOut, ", "); - select->bind(cTableEvents::fiScrMovieId, cDBS::bndOut, ", "); - select->bind(cTableEvents::fiScrSp, cDBS::bndOut, ", "); - select->build(" from %s where ", tEvents->TableName()); - select->build(" ((%s is not null and %s > 0) ", - tEvents->getField(cTableEvents::fiScrSeriesId)->name, - tEvents->getField(cTableEvents::fiScrSeriesId)->name); - select->build(" or (%s is not null and %s > 0)) ", - tEvents->getField(cTableEvents::fiScrMovieId)->name, - tEvents->getField(cTableEvents::fiScrMovieId)->name); - if (lastScrap > 0) { - select->build(" and %s > %d", - tEvents->getField(cTableEvents::fiScrSp)->name, - lastScrap); - } - select->build(" order by %s", tEvents->getField(cTableEvents::fiInsSp)->name); - status += select->prepare(); - if (status != success) { - delete select; - return 0; - } int eventId = 0; int seriesId = 0; int episodeId = 0; int movieId = 0; string channelId = ""; int numNew = 0; + + cDbStatement* select = lastScrap > 0 ? selectReadScrapedEvents : selectReadScrapedEventsInit; + + tEvents->clear(); + tEvents->setValue(cTableEvents::fiScrSp, lastScrap); + for (int res = select->find(); res; res = select->fetch() && Running()) { eventId = tEvents->getIntValue(cTableEvents::fiMasterId); channelId = tEvents->getStrValue(cTableEvents::fiChannelId); @@ -212,8 +454,9 @@ int cUpdate::ReadScrapedEvents(void) { lastScrap = max(lastScrap, (int)tEvents->getIntValue(cTableEvents::fiScrSp)); numNew++; } + select->freeResult(); - delete select; + return numNew; } @@ -247,7 +490,7 @@ int cUpdate::ReadSeries(bool isRec) { isNew = false; } if (series) { - stringstream sPath; + stringstream sPath(""); sPath << imgPathSeries << "/" << seriesId; string seriesPath = sPath.str(); if (episodeId) { @@ -264,7 +507,6 @@ int cUpdate::ReadSeries(bool isRec) { } void cUpdate::ReadEpisode(int episodeId, cTVDBSeries *series, string path) { - int status = success; tEpisodes->clear(); tEpisodes->setValue(cTableSeriesEpisode::fiEpisodeId, episodeId); int res = tEpisodes->find(); @@ -279,39 +521,20 @@ void cUpdate::ReadEpisode(int episodeId, cTVDBSeries *series, string path) { } void cUpdate::LoadEpisodeImage(cTVDBSeries *series, int episodeId, string path) { - int status = success; - stringstream iPath; + stringstream iPath(""); iPath << path << "/" << "episode_" << episodeId << ".jpg"; string imgPath = iPath.str(); bool imgExists = FileExists(imgPath); if (!imgExists) if (!CreateDirectory(path)) return; + tSeriesMedia->clear(); - cDbValue imageSize; - cDBS::FieldDef imageSizeDef = { "media_content", cDBS::ffUInt, 0, 999, cDBS::ftData }; - imageSize.setField(&imageSizeDef); - cDbStatement *selectImg = new cDbStatement(tSeriesMedia); - selectImg->build("select "); - selectImg->bind(cTableSeriesMedia::fiMediaWidth, cDBS::bndOut); - selectImg->bind(cTableSeriesMedia::fiMediaHeight, cDBS::bndOut, ", "); - if (!imgExists) { - selectImg->bind(cTableSeriesMedia::fiMediaContent, cDBS::bndOut, ", "); - selectImg->build(", length("); - selectImg->bind(&imageSize, cDBS::bndOut); - selectImg->build(")"); - } - selectImg->build(" from %s where ", tSeriesMedia->TableName()); - selectImg->bind(cTableSeriesMedia::fiSeriesId, cDBS::bndIn | cDBS::bndSet); - selectImg->bind(cTableSeriesMedia::fiEpisodeId, cDBS::bndIn | cDBS::bndSet, " and "); - status += selectImg->prepare(); - if (status != success) { - delete selectImg; - return; - } tSeriesMedia->setValue(cTableSeriesMedia::fiSeriesId, series->id); tSeriesMedia->setValue(cTableSeriesMedia::fiEpisodeId, episodeId); + int res = selectImg->find(); + if (res) { if (!imgExists) { int size = imageSize.getIntValue(); @@ -324,15 +547,14 @@ void cUpdate::LoadEpisodeImage(cTVDBSeries *series, int episodeId, string path) int imgHeight = tSeriesMedia->getIntValue(cTableSeriesMedia::fiMediaHeight); series->InsertEpisodeImage(episodeId, imgWidth, imgHeight, imgPath); } + selectImg->freeResult(); - delete selectImg; } void cUpdate::LoadSeasonPoster(cTVDBSeries *series, int season, string path) { - int status = success; - stringstream iPath; + stringstream iPath(""); iPath << path << "/" << "season_" << season << ".jpg"; - stringstream tPath; + stringstream tPath(""); tPath << path << "/" << "season_" << season << "_thumb.jpg"; string imgPath = iPath.str(); string thumbPath = tPath.str(); @@ -340,36 +562,17 @@ void cUpdate::LoadSeasonPoster(cTVDBSeries *series, int season, string path) { if (!imgExists) if (!CreateDirectory(path)) return; + tSeriesMedia->clear(); - cDbValue imageSize; - cDBS::FieldDef imageSizeDef = { "media_content", cDBS::ffUInt, 0, 999, cDBS::ftData }; - imageSize.setField(&imageSizeDef); - cDbStatement *selectImg = new cDbStatement(tSeriesMedia); - selectImg->build("select "); - selectImg->bind(cTableSeriesMedia::fiMediaWidth, cDBS::bndOut); - selectImg->bind(cTableSeriesMedia::fiMediaHeight, cDBS::bndOut, ", "); - if (!imgExists) { - selectImg->bind(cTableSeriesMedia::fiMediaContent, cDBS::bndOut, ", "); - selectImg->build(", length("); - selectImg->bind(&imageSize, cDBS::bndOut); - selectImg->build(")"); - } - selectImg->build(" from %s where ", tSeriesMedia->TableName()); - selectImg->bind(cTableSeriesMedia::fiSeriesId, cDBS::bndIn | cDBS::bndSet); - selectImg->bind(cTableSeriesMedia::fiSeasonNumber, cDBS::bndIn | cDBS::bndSet, " and "); - selectImg->bind(cTableSeriesMedia::fiMediaType, cDBS::bndIn | cDBS::bndSet, " and "); - status += selectImg->prepare(); - if (status != success) { - delete selectImg; - return; - } tSeriesMedia->setValue(cTableSeriesMedia::fiSeriesId, series->id); tSeriesMedia->setValue(cTableSeriesMedia::fiSeasonNumber, season); tSeriesMedia->setValue(cTableSeriesMedia::fiMediaType, msSeasonPoster); - int res = selectImg->find(); + + int res = selectSeasonPoster->find(); + if (res) { if (!imgExists) { - int size = imageSize.getIntValue(); + int size = posterSize.getIntValue(); if (FILE* fh = fopen(imgPath.c_str(), "w")) { fwrite(tSeriesMedia->getStrValue(cTableSeriesMedia::fiMediaContent), 1, size, fh); fclose(fh); @@ -383,80 +586,39 @@ void cUpdate::LoadSeasonPoster(cTVDBSeries *series, int season, string path) { series->InsertMedia(msSeasonPoster, imgWidth, imgHeight, imgPath, season); series->InsertMedia(msSeasonPosterThumb, imgWidth/2, imgHeight/2, thumbPath, season); } - selectImg->freeResult(); - delete selectImg; + + selectSeasonPoster->freeResult(); } void cUpdate::ReadSeriesActors(cTVDBSeries *series, string path) { - int status = success; tSeriesActors->clear(); - cDbValue series_id; - series_id.setField(tSeriesMedia->getField(cTableSeriesMedia::fiSeriesId)); series_id.setValue(series->id); - cDbStatement *selectActors = new cDbStatement(tSeriesActors); - selectActors->build("select "); - selectActors->setBindPrefix("series_actor."); - selectActors->bind(cTableSeriesActor::fiActorId, cDBS::bndOut); - selectActors->bind(cTableSeriesActor::fiActorName, cDBS::bndOut, ", "); - selectActors->bind(cTableSeriesActor::fiActorRole, cDBS::bndOut, ", "); - selectActors->clrBindPrefix(); - selectActors->build(" from %s, %s where ", tSeriesActors->TableName(), tSeriesMedia->TableName()); - selectActors->build(" %s.%s = %s.%s ", tSeriesActors->TableName(), - tSeriesActors->getField(cTableSeriesActor::fiActorId)->name, - tSeriesMedia->TableName(), - tSeriesMedia->getField(cTableSeriesMedia::fiActorId)->name); - selectActors->setBindPrefix("series_media."); - selectActors->bind(&series_id, cDBS::bndIn | cDBS::bndSet, " and "); - selectActors->build(" order by %s, %s asc", tSeriesActors->getField(cTableSeriesActor::fiSortOrder)->name, - tSeriesActors->getField(cTableSeriesActor::fiActorRole)->name); - status += selectActors->prepare(); - if (status != success) { - delete selectActors; - return; - } + for (int res = selectActors->find(); res; res = selectActors->fetch()) { scrapManager->AddSeriesActor(series, tSeriesActors); LoadSeriesActorThumb(series, tSeriesActors->getIntValue(cTableSeriesActor::fiActorId), path); } + selectActors->freeResult(); - delete selectActors; } void cUpdate::LoadSeriesActorThumb(cTVDBSeries *series, int actorId, string path) { - int status = success; - stringstream iPath; + stringstream iPath(""); iPath << path << "/" << "actor_" << actorId << ".jpg"; string imgPath = iPath.str(); bool imgExists = FileExists(imgPath); if (!imgExists) if (!CreateDirectory(path)) return; - cDbValue imageSize; - cDBS::FieldDef imageSizeDef = { "media_content", cDBS::ffUInt, 0, 999, cDBS::ftData }; - imageSize.setField(&imageSizeDef); + tSeriesMedia->clear(); - cDbStatement *selectActorThumbs = new cDbStatement(tSeriesMedia); - selectActorThumbs->build("select "); - selectActorThumbs->bind(cTableSeriesMedia::fiMediaWidth, cDBS::bndOut); - selectActorThumbs->bind(cTableSeriesMedia::fiMediaHeight, cDBS::bndOut, ", "); - if (!imgExists) { - selectActorThumbs->bind(cTableSeriesMedia::fiMediaContent, cDBS::bndOut, ", "); - selectActorThumbs->build(", length("); - selectActorThumbs->bind(&imageSize, cDBS::bndOut); - selectActorThumbs->build(")"); - } - selectActorThumbs->build(" from %s where ", tSeriesMedia->TableName()); - selectActorThumbs->bind(cTableSeriesMedia::fiActorId, cDBS::bndIn | cDBS::bndSet); - status += selectActorThumbs->prepare(); - if (status != success) { - delete selectActorThumbs; - return; - } tSeriesMedia->setValue(cTableSeriesMedia::fiActorId, actorId); + int res = selectActorThumbs->find(); + if (res) { if (!imgExists) { - int size = imageSize.getIntValue(); + int size = actorImageSize.getIntValue(); if (FILE* fh = fopen(imgPath.c_str(), "w")) { fwrite(tSeriesMedia->getStrValue(cTableSeriesMedia::fiMediaContent), 1, size, fh); fclose(fh); @@ -466,52 +628,34 @@ void cUpdate::LoadSeriesActorThumb(cTVDBSeries *series, int actorId, string path int tmbHeight = tSeriesMedia->getIntValue(cTableSeriesMedia::fiMediaHeight); series->InsertActorThumb(actorId, tmbWidth, tmbHeight, imgPath); } + selectActorThumbs->freeResult(); - delete selectActorThumbs; } -void cUpdate::LoadSeriesMedia(cTVDBSeries *series, string path) { - int status = success; - tSeriesMedia->clear(); - cDbStatement *selectImg = new cDbStatement(tSeriesMedia); - selectImg->build("select "); - selectImg->bind(cTableSeriesMedia::fiMediaWidth, cDBS::bndOut); - selectImg->bind(cTableSeriesMedia::fiMediaHeight, cDBS::bndOut, ", "); - selectImg->bind(cTableSeriesMedia::fiMediaType, cDBS::bndOut, ", "); - selectImg->build(" from %s where ", tSeriesMedia->TableName()); - selectImg->bind(cTableSeriesMedia::fiSeriesId, cDBS::bndIn | cDBS::bndSet); - selectImg->build(" and %s in (%d, %d, %d, %d, %d, %d, %d, %d, %d)", - tSeriesMedia->getField(cTableSeriesMedia::fiMediaType)->name, - msPoster1, msPoster2, msPoster3, - msFanart1, msFanart2, msFanart3, - msBanner1, msBanner2, msBanner3); - status += selectImg->prepare(); - if (status != success) { - delete selectImg; - return; - } - tSeriesMedia->setValue(cTableSeriesMedia::fiSeriesId, series->id); - for (int res = selectImg->find(); res; res = selectImg->fetch()) { - int mediaType = tSeriesMedia->getIntValue(cTableSeriesMedia::fiMediaType); - int mediaWidth = tSeriesMedia->getIntValue(cTableSeriesMedia::fiMediaWidth); - int mediaHeight = tSeriesMedia->getIntValue(cTableSeriesMedia::fiMediaHeight); - string mediaPath = LoadMediaSeries(series->id, mediaType, path, mediaWidth, mediaHeight); - series->InsertMedia(mediaType, mediaWidth, mediaHeight, mediaPath); - if (mediaType == msPoster1) { - string thumbPath = path + "/poster_thumb.jpg"; - series->InsertMedia(msPosterThumb, mediaWidth/5, mediaHeight/5, thumbPath); - } - } - selectImg->freeResult(); - delete selectImg; +void cUpdate::LoadSeriesMedia(cTVDBSeries *series, string path) { + tSeriesMedia->clear(); + tSeriesMedia->setValue(cTableSeriesMedia::fiSeriesId, series->id); + + for (int res = selectSeriesMedia->find(); res; res = selectSeriesMedia->fetch()) { + int mediaType = tSeriesMedia->getIntValue(cTableSeriesMedia::fiMediaType); + int mediaWidth = tSeriesMedia->getIntValue(cTableSeriesMedia::fiMediaWidth); + int mediaHeight = tSeriesMedia->getIntValue(cTableSeriesMedia::fiMediaHeight); + string mediaPath = LoadMediaSeries(series->id, mediaType, path, mediaWidth, mediaHeight); + series->InsertMedia(mediaType, mediaWidth, mediaHeight, mediaPath); + if (mediaType == msPoster1) { + string thumbPath = path + "/poster_thumb.jpg"; + series->InsertMedia(msPosterThumb, mediaWidth/5, mediaHeight/5, thumbPath); + } + } + + selectSeriesMedia->freeResult(); } string cUpdate::LoadMediaSeries(int seriesId, int mediaType, string path, int width, int height) { - int status = success; - stringstream iPath; + stringstream iPath(""); iPath << path << "/"; bool createThumb = false; - stringstream tPath; + stringstream tPath(""); tPath << path << "/"; switch (mediaType) { case msPoster1: @@ -556,26 +700,11 @@ string cUpdate::LoadMediaSeries(int seriesId, int mediaType, string path, int wi } if (!CreateDirectory(path)) return ""; + tSeriesMedia->clear(); - cDbValue imageSize; - cDBS::FieldDef imageSizeDef = { "media_content", cDBS::ffUInt, 0, 999, cDBS::ftData }; - imageSize.setField(&imageSizeDef); - cDbStatement *selectImg = new cDbStatement(tSeriesMedia); - selectImg->build("select "); - selectImg->bind(cTableSeriesMedia::fiMediaContent, cDBS::bndOut); - selectImg->build(", length("); - selectImg->bind(&imageSize, cDBS::bndOut); - selectImg->build(")"); - selectImg->build(" from %s where ", tSeriesMedia->TableName()); - selectImg->bind(cTableSeriesMedia::fiSeriesId, cDBS::bndIn | cDBS::bndSet); - selectImg->bind(cTableSeriesMedia::fiMediaType, cDBS::bndIn | cDBS::bndSet, " and "); - status += selectImg->prepare(); - if (status != success) { - delete selectImg; - return ""; - } tSeriesMedia->setValue(cTableSeriesMedia::fiSeriesId, seriesId); tSeriesMedia->setValue(cTableSeriesMedia::fiMediaType, mediaType); + int res = selectImg->find(); if (res) { int size = imageSize.getIntValue(); @@ -587,8 +716,8 @@ string cUpdate::LoadMediaSeries(int seriesId, int mediaType, string path, int wi CreateThumbnail(imgPath, thumbPath, width, height, 5); } } + selectImg->freeResult(); - delete selectImg; return imgPath; } @@ -599,8 +728,7 @@ string cUpdate::LoadMediaSeries(int seriesId, int mediaType, string path, int wi int cUpdate::ReadMovies(bool isRec) { scrapManager->InitIterator(isRec); int movieId = 0; - int i=0; - + if (!CreateDirectory(config.imageDir)) return 0; if (!CreateDirectory(imgPathMovies)) @@ -617,7 +745,7 @@ int cUpdate::ReadMovies(bool isRec) { if (!res) continue; movie = scrapManager->AddMovie(tMovies); - stringstream mPath; + stringstream mPath(""); mPath << imgPathMovies << "/" << movieId; string moviePath = mPath.str(); ReadMovieActors(movie); @@ -629,71 +757,24 @@ int cUpdate::ReadMovies(bool isRec) { } void cUpdate::ReadMovieActors(cMovieDbMovie *movie) { - int status = success; - cDbValue actorRole; - cDbValue actorMovie; - cDbValue thbWidth; - cDbValue thbHeight; - actorRole.setField(tMovieActors->getField(cTableMovieActors::fiRole)); - actorMovie.setField(tMovieActors->getField(cTableMovieActors::fiMovieId)); - thbWidth.setField(tMovieMedia->getField(cTableMovieMedia::fiMediaWidth)); - thbHeight.setField(tMovieMedia->getField(cTableMovieMedia::fiMediaHeight)); - cDbStatement *selectActors = new cDbStatement(tMovieActor); - selectActors->build("select "); - selectActors->setBindPrefix("act."); - selectActors->bind(cTableMovieActor::fiActorId, cDBS::bndOut); - selectActors->bind(cTableMovieActor::fiActorName, cDBS::bndOut, ", "); - selectActors->setBindPrefix("role."); - selectActors->bind(&actorRole, cDBS::bndOut, ", "); - selectActors->setBindPrefix("thumb."); - selectActors->bind(&thbWidth, cDBS::bndOut, ", "); - selectActors->bind(&thbHeight, cDBS::bndOut, ", "); - selectActors->clrBindPrefix(); - selectActors->build(" from %s act, %s role, %s thumb where ", - tMovieActor->TableName(), tMovieActors->TableName(), tMovieMedia->TableName()); - selectActors->build("act.%s = role.%s ", - tMovieActor->getField(cTableMovieActor::fiActorId)->name, - tMovieActors->getField(cTableMovieActors::fiActorId)->name); - selectActors->build(" and role.%s = thumb.%s ", - tMovieActors->getField(cTableMovieActors::fiActorId)->name, - tMovieMedia->getField(cTableMovieMedia::fiActorId)->name); - selectActors->setBindPrefix("role."); - selectActors->bind(&actorMovie, cDBS::bndIn | cDBS::bndSet, " and "); - status += selectActors->prepare(); - if (status != success) { - delete selectActors; - return; - } + tMovieActor->clear(); + tMovieMedia->clear(); actorMovie.setValue(movie->id); - for (int res = selectActors->find(); res; res = selectActors->fetch()) { + + for (int res = selectMovieActors->find(); res; res = selectMovieActors->fetch()) { scrapManager->AddMovieActor(movie, tMovieActor, actorRole.getStrValue()); int tmbWidth = thbWidth.getIntValue(); int tmbHeight = thbHeight.getIntValue(); movie->SetActorThumbSize(tMovieActor->getIntValue(cTableMovieActor::fiActorId), tmbWidth, tmbHeight); } - selectActors->freeResult(); - delete selectActors; + + selectMovieActors->freeResult(); } void cUpdate::LoadMovieActorThumbs(cMovieDbMovie *movie) { - int status = success; - cDbValue imageSize; - cDBS::FieldDef imageSizeDef = { "media_content", cDBS::ffUInt, 0, 999, cDBS::ftData }; - imageSize.setField(&imageSizeDef); tMovieMedia->clear(); - cDbStatement *selectActorThumbs = new cDbStatement(tMovieMedia); - selectActorThumbs->build("select "); - selectActorThumbs->bind(cTableMovieMedia::fiMediaContent, cDBS::bndOut); - selectActorThumbs->build(", length("); - selectActorThumbs->bind(&imageSize, cDBS::bndOut); - selectActorThumbs->build(")"); - selectActorThumbs->build(" from %s where ", tMovieMedia->TableName()); - selectActorThumbs->bind(cTableMovieMedia::fiActorId, cDBS::bndIn | cDBS::bndSet); - status += selectActorThumbs->prepare(); - if (status != success) { - delete selectActorThumbs; - return; - } + imageSize.setField(&imageSizeDef); + string movieActorsPath = imgPathMovies + "/actors"; if (!CreateDirectory(movieActorsPath)) return; @@ -701,13 +782,13 @@ void cUpdate::LoadMovieActorThumbs(cMovieDbMovie *movie) { vector IDs = movie->GetActorIDs(); for (vector::iterator it = IDs.begin(); it != IDs.end(); it++) { int actorId = (int)*it; - stringstream tName; + stringstream tName(""); tName << "actor_" << actorId << ".jpg"; string thumbName = tName.str(); string thumbFullPath = movieActorsPath + "/" + thumbName; if (!FileExists(thumbFullPath)) { tMovieMedia->setValue(cTableMovieMedia::fiActorId, actorId); - int res = selectActorThumbs->find(); + int res = selectMovieActorThumbs->find(); if (res) { int size = imageSize.getIntValue(); if (FILE* fh = fopen(thumbFullPath.c_str(), "w")) { @@ -720,33 +801,15 @@ void cUpdate::LoadMovieActorThumbs(cMovieDbMovie *movie) { movie->SetActorPath(actorId, thumbFullPath); } } - selectActorThumbs->freeResult(); - delete selectActorThumbs; + + selectMovieActorThumbs->freeResult(); } void cUpdate::LoadMovieMedia(cMovieDbMovie *movie, string moviePath) { - int status = success; tMovieMedia->clear(); - cDbStatement *selectImg = new cDbStatement(tMovieMedia); - selectImg->build("select "); - selectImg->bind(cTableMovieMedia::fiMediaWidth, cDBS::bndOut); - selectImg->bind(cTableMovieMedia::fiMediaHeight, cDBS::bndOut, ", "); - selectImg->bind(cTableMovieMedia::fiMediaType, cDBS::bndOut, ", "); - selectImg->build(" from %s where ", tMovieMedia->TableName()); - selectImg->bind(cTableMovieMedia::fiMovieId, cDBS::bndIn | cDBS::bndSet); - selectImg->build(" and %s in (%d, %d, %d, %d)", - tMovieMedia->getField(cTableMovieMedia::fiMediaType)->name, - mmPoster, - mmFanart, - mmCollectionPoster, - mmCollectionFanart); - status += selectImg->prepare(); - if (status != success) { - delete selectImg; - return; - } tMovieMedia->setValue(cTableMovieMedia::fiMovieId, movie->id); - for (int res = selectImg->find(); res; res = selectImg->fetch()) { + + for (int res = selectMovieMedia->find(); res; res = selectMovieMedia->fetch()) { int mediaType = tMovieMedia->getIntValue(cTableMovieMedia::fiMediaType); int mediaWidth = tMovieMedia->getIntValue(cTableMovieMedia::fiMediaWidth); int mediaHeight = tMovieMedia->getIntValue(cTableMovieMedia::fiMediaHeight); @@ -761,18 +824,16 @@ void cUpdate::LoadMovieMedia(cMovieDbMovie *movie, string moviePath) { m->path = moviePath + "/poster_thumb.jpg"; movie->InsertMedia(m); } - } - selectImg->freeResult(); - delete selectImg; + + selectMovieMedia->freeResult(); } string cUpdate::LoadMediaMovie(int movieId, int mediaType, string path, int width, int height) { - int status = success; - stringstream iPath; + stringstream iPath(""); iPath << path << "/"; bool createThumb = false; - stringstream tPath; + stringstream tPath(""); tPath << path << "/"; switch (mediaType) { case mmPoster: @@ -802,27 +863,13 @@ string cUpdate::LoadMediaMovie(int movieId, int mediaType, string path, int widt } if (!CreateDirectory(path)) return imgPath; + tMovieMedia->clear(); - cDbValue imageSize; - cDBS::FieldDef imageSizeDef = { "media_content", cDBS::ffUInt, 0, 999, cDBS::ftData }; imageSize.setField(&imageSizeDef); - cDbStatement *selectImg = new cDbStatement(tMovieMedia); - selectImg->build("select "); - selectImg->bind(cTableMovieMedia::fiMediaContent, cDBS::bndOut); - selectImg->build(", length("); - selectImg->bind(&imageSize, cDBS::bndOut); - selectImg->build(")"); - selectImg->build(" from %s where ", tMovieMedia->TableName()); - selectImg->bind(cTableMovieMedia::fiMovieId, cDBS::bndIn | cDBS::bndSet); - selectImg->bind(cTableMovieMedia::fiMediaType, cDBS::bndIn | cDBS::bndSet, " and "); - status += selectImg->prepare(); - if (status != success) { - delete selectImg; - return ""; - } tMovieMedia->setValue(cTableMovieMedia::fiMovieId, movieId); tMovieMedia->setValue(cTableMovieMedia::fiMediaType, mediaType); - int res = selectImg->find(); + + int res = selectMediaMovie->find(); if (res) { int size = imageSize.getIntValue(); if (FILE* fh = fopen(imgPath.c_str(), "w")) { @@ -833,37 +880,21 @@ string cUpdate::LoadMediaMovie(int movieId, int mediaType, string path, int widt CreateThumbnail(imgPath, thumbPath, width, height, 4); } } - selectImg->freeResult(); - delete selectImg; + + selectMediaMovie->freeResult(); return imgPath; } //*************************************************************************** // RECORDINGS //*************************************************************************** + int cUpdate::ReadRecordings(void) { - int status = success; - cDbStatement *select = new cDbStatement(tRecordings); - select->build("select "); - select->bind(cTableRecordings::fiRecPath, cDBS::bndOut); - select->bind(cTableRecordings::fiRecStart, cDBS::bndOut, ", "); - select->bind(cTableRecordings::fiMovieId, cDBS::bndOut, ", "); - select->bind(cTableRecordings::fiSeriesId, cDBS::bndOut, ", "); - select->bind(cTableRecordings::fiEpisodeId, cDBS::bndOut, ", "); - select->build(" from %s where ", tRecordings->TableName()); - select->bind(cTableRecordings::fiUuid, cDBS::bndIn | cDBS::bndSet); - select->build(" and %s = 0", tRecordings->getField(cTableRecordings::fiScrapNew)->name); - - status += select->prepare(); - if (status != success) { - delete select; - return 0; - } - tRecordings->clear(); tRecordings->setValue(cTableRecordings::fiUuid, config.uuid.c_str()); int numRecs = 0; - for (int res = select->find(); res; res = select->fetch()) { + + for (int res = selectRecordings->find(); res; res = selectRecordings->fetch()) { int recStart = tRecordings->getIntValue(cTableRecordings::fiRecStart); string recPath = tRecordings->getStrValue(cTableRecordings::fiRecPath); int movieId = tRecordings->getIntValue(cTableRecordings::fiMovieId); @@ -873,8 +904,8 @@ int cUpdate::ReadRecordings(void) { if (isNew) numRecs++; } - select->freeResult(); - delete select; + + selectRecordings->freeResult(); return numRecs; } @@ -934,7 +965,7 @@ int cUpdate::ScanVideoDirScrapInfo(void) { for (cRecording *rec = Recordings.First(); rec; rec = Recordings.Next(rec)) { int recStart = rec->Start(); string recPath = getRecPath(rec); - bool recExists = LoadRecording(recStart, recPath); + /* bool recExists = */ LoadRecording(recStart, recPath); int scrapInfoMovieID = 0; int scrapInfoSeriesID = 0; int scrapInfoEpisodeID = 0; @@ -975,13 +1006,13 @@ bool cUpdate::ScrapInfoChanged(int scrapInfoMovieID, int scrapInfoSeriesID, int } void cUpdate::ReadScrapInfo(string recDir, int &scrapInfoMovieID, int &scrapInfoSeriesID, int &scrapInfoEpisodeID) { - stringstream sInfoName; + stringstream sInfoName(""); sInfoName << recDir << "/" << config.recScrapInfoName; string scrapInfoName = sInfoName.str(); if (!FileExists(scrapInfoName, false)) { string twoHigher = TwoFoldersHigher(recDir); if (twoHigher.size() > 0) { - stringstream sInfoNameAlt; + stringstream sInfoNameAlt(""); sInfoNameAlt << twoHigher << "/" << config.recScrapInfoName; scrapInfoName = sInfoNameAlt.str(); if (!FileExists(scrapInfoName, false)) { @@ -1119,168 +1150,187 @@ int cUpdate::CleanupMovies(void) { } int cUpdate::CleanupRecordings(void) { - //delete all not anymore existing recordings in database - int status = success; - cDbStatement *select = new cDbStatement(tRecordings); - select->build("select "); - select->bind(cTableRecordings::fiRecPath, cDBS::bndOut); - select->bind(cTableRecordings::fiRecStart, cDBS::bndOut, ", "); - select->build(" from %s where ", tRecordings->TableName()); - select->bind(cTableRecordings::fiUuid, cDBS::bndIn | cDBS::bndSet); - - status += select->prepare(); - if (status != success) { - delete select; - return 0; - } + // delete all not anymore existing recordings in database tRecordings->clear(); tRecordings->setValue(cTableRecordings::fiUuid, config.uuid.c_str()); int numRecsDeleted = 0; - for (int res = select->find(); res; res = select->fetch()) { + + for (int res = selectCleanupRecordings->find(); res; res = selectCleanupRecordings->fetch()) { int recStart = tRecordings->getIntValue(cTableRecordings::fiRecStart); string recPath = tRecordings->getStrValue(cTableRecordings::fiRecPath); if (!Recordings.GetByName(recPath.c_str())) { - stringstream delWhere; + stringstream delWhere(""); delWhere << "uuid = '" << config.uuid << "' and rec_path = '" << recPath << "' and rec_start = " << recStart; tRecordings->deleteWhere(delWhere.str().c_str()); numRecsDeleted++; } } - select->freeResult(); - delete select; + selectCleanupRecordings->freeResult(); return numRecsDeleted; } - //*************************************************************************** // Action //*************************************************************************** -void cUpdate::Action() { +void cUpdate::Action() +{ tell(0, "Update thread started (pid=%d)", getpid()); mutex.Lock(); loopActive = yes; - int sleep = 10; + + int worked = no; + int sleep = 60; int scanFreq = 60 * 2; int scanNewRecFreq = 60 * 5; int scanNewRecDBFreq = 60 * 5; int cleanUpFreq = 60 * 10; + forceUpdate = true; forceRecordingUpdate = true; + time_t lastScan = time(0); time_t lastScanNewRec = time(0); time_t lastScanNewRecDB = time(0); time_t lastCleanup = time(0); bool init = true; - while (loopActive && Running()) { - int reconnectTimeout; //set by checkConnection - if (CheckConnection(reconnectTimeout) != success) { - waitCondition.TimedWait(mutex, reconnectTimeout*1000); - continue; - } - //Update Recordings from Database - if (forceRecordingUpdate || (time(0) - lastScanNewRecDB > scanNewRecDBFreq) && Running()) { - if (!init && CheckEpgdBusy()) - continue; - int numNewRecs = ReadRecordings(); - if (numNewRecs > 0) { - int numSeries = ReadSeries(true); - int numMovies = ReadMovies(true); - tell(0, "Loaded %d new Recordings from Database, %d series, %d movies", numNewRecs, numSeries, numMovies); - } - forceRecordingUpdate = false; + + while (loopActive && Running()) + { + int reconnectTimeout; // set by checkConnection + + waitCondition.TimedWait(mutex, init ? sleep*500 : sleep*1000); + + if (CheckConnection(reconnectTimeout) != success) + continue; + + // auch beim init auf den epgd warten, wenn der gerade busy ist müssen die sich User etwas gedulden ;) + + if (CheckEpgdBusy()) + { + tell(1, "epgd busy, trying again in %d seconds ...", sleep); + continue; } - //Update Events - if (!config.headless && (forceUpdate || (time(0) - lastScan > scanFreq)) && Running()) { - if (!init && CheckEpgdBusy()) - continue; - int numNewEvents = ReadScrapedEvents(); - if (numNewEvents > 0) { - tell(0, "Loaded %d new scraped Events from Database", numNewEvents); - } else { - lastScan = time(0); - forceUpdate = false; - init = false; - continue; - } - tell(0, "Loading new Movies from Database..."); - time_t now = time(0); - int numNewMovies = ReadMovies(false); - int dur = time(0) - now; - tell(0, "Loaded %d new Movies in %ds from Database", numNewMovies, dur); + // Update Recordings from Database - tell(0, "Loading new Series and Episodes from Database..."); - now = time(0); - int numNewSeries = ReadSeries(false); - dur = time(0) - now; - tell(0, "Loaded %d new Series and Episodes in %ds from Database", numNewSeries, dur); + if (forceRecordingUpdate || (time(0) - lastScanNewRecDB > scanNewRecDBFreq) && Running()) + { + worked++; + int numNewRecs = ReadRecordings(); + lastScanNewRecDB = time(0); - lastScan = time(0); - forceUpdate = false; + if (numNewRecs > 0) + { + int numSeries = ReadSeries(true); + int numMovies = ReadMovies(true); + tell(0, "Loaded %d new Recordings from Database, %d series, %d movies", numNewRecs, numSeries, numMovies); + } + + forceRecordingUpdate = false; } - //Scan new recordings - if ((init || forceVideoDirUpdate || (time(0) - lastScanNewRec > scanNewRecFreq)) && Running()) { - if (CheckEpgdBusy()) { - waitCondition.TimedWait(mutex, 1000); - continue; - } - static int recState = 0; - if (Recordings.StateChanged(recState)) { - tell(0, "Searching for new recordings because of Recordings State Change..."); - int newRecs = ScanVideoDir(); - tell(0, "found %d new recordings", newRecs); - } - lastScanNewRec = time(0); - forceVideoDirUpdate = false; - } + // Update Events + if (!config.headless && (forceUpdate || (time(0) - lastScan > scanFreq)) && Running()) + { + worked++; + int numNewEvents = ReadScrapedEvents(); + + if (numNewEvents > 0) + { + tell(0, "Loaded %d new scraped Events from Database", numNewEvents); + } + else + { + lastScan = time(0); + forceUpdate = false; + init = false; + continue; + } + + tell(0, "Loading new Movies from Database..."); + time_t now = time(0); + worked++; + int numNewMovies = ReadMovies(false); + int dur = time(0) - now; + tell(0, "Loaded %d new Movies in %ds from Database", numNewMovies, dur); + + tell(0, "Loading new Series and Episodes from Database..."); + now = time(0); + worked++; + int numNewSeries = ReadSeries(false); + dur = time(0) - now; + tell(0, "Loaded %d new Series and Episodes in %ds from Database", numNewSeries, dur); + + lastScan = time(0); + forceUpdate = false; + } + + // Scan new recordings + + if ((init || forceVideoDirUpdate || (time(0) - lastScanNewRec > scanNewRecFreq)) && Running()) + { + static int recState = 0; + + if (Recordings.StateChanged(recState)) + { + tell(0, "Searching for new recordings because of Recordings State Change..."); + worked++; + int newRecs = ScanVideoDir(); + tell(0, "found %d new recordings", newRecs); + } + + lastScanNewRec = time(0); + forceVideoDirUpdate = false; + } + init = false; + + // Scan Video dir for scrapinfo files - //Scan Video dir for scrapinfo files - if (forceScrapInfoUpdate) { - if (CheckEpgdBusy()) { - tell(0, "epgd busy, try again in 1s..."); - waitCondition.TimedWait(mutex, 1000); - continue; - } - tell(0, "Checking for new or updated scrapinfo files in recordings..."); - int numUpdated = ScanVideoDirScrapInfo(); - tell(0, "found %d new or updated scrapinfo files", numUpdated); - forceScrapInfoUpdate = false; + if (forceScrapInfoUpdate) + { + worked++; + tell(0, "Checking for new or updated scrapinfo files in recordings..."); + int numUpdated = ScanVideoDirScrapInfo(); + tell(0, "found %d new or updated scrapinfo files", numUpdated); + forceScrapInfoUpdate = false; } - //Cleanup - if ((time(0) - lastCleanup > cleanUpFreq) && Running()){ - if (CheckEpgdBusy()) { - waitCondition.TimedWait(mutex, 1000); - continue; - } - int seriesDeleted = CleanupSeries(); - int moviesDeleted = CleanupMovies(); - if (seriesDeleted > 0 || moviesDeleted > 0) { - tell(0, "Deleted %d outdated series image folders", seriesDeleted); - tell(0, "Deleted %d outdated movie image folders", moviesDeleted); - } - lastCleanup = time(0); + // Cleanup + + if ((time(0) - lastCleanup > cleanUpFreq) && Running()) + { + worked++; + int seriesDeleted = CleanupSeries(); + int moviesDeleted = CleanupMovies(); + + if (seriesDeleted > 0 || moviesDeleted > 0) + { + tell(0, "Deleted %d outdated series image folders", seriesDeleted); + tell(0, "Deleted %d outdated movie image folders", moviesDeleted); + } + + lastCleanup = time(0); } - //Cleanup Recording DB - if (forceCleanupRecordingDb) { - if (CheckEpgdBusy()) { - waitCondition.TimedWait(mutex, 1000); - continue; - } + // Cleanup Recording DB + + if (forceCleanupRecordingDb) + { + worked++; tell(0, "Cleaning up recordings in database..."); int recsDeleted = CleanupRecordings(); tell(0, "Deleted %d not anymore existing recordings in database", recsDeleted); forceCleanupRecordingDb = false; } + + if (worked && config.debug) + connection->showStat(); - waitCondition.TimedWait(mutex, sleep*1000); - + worked = no; } loopActive = no; @@ -1290,6 +1340,7 @@ void cUpdate::Action() { //*************************************************************************** // External trigggering of Actions //*************************************************************************** + void cUpdate::ForceUpdate(void) { tell(0, "full update from database forced"); forceUpdate = true; diff --git a/update.h b/update.h index c529fda..484dc3c 100644 --- a/update.h +++ b/update.h @@ -1,7 +1,6 @@ #ifndef __UPDATE_H #define __UPDATE_H -#include #include #include @@ -71,6 +70,33 @@ class cUpdate : public cThread { int CleanupSeries(void); int CleanupMovies(void); int CleanupRecordings(void); + + // statements + + cDbStatement* selectReadScrapedEventsInit; + cDbStatement* selectReadScrapedEvents; + cDbStatement* selectImg; + cDbStatement* selectSeasonPoster; + cDbStatement* selectActors; + cDbStatement* selectActorThumbs; + cDbStatement* selectSeriesMedia; + cDbStatement* selectMovieActors; + cDbStatement* selectMovieActorThumbs; + cDbStatement* selectMovieMedia; + cDbStatement* selectMediaMovie; + cDbStatement* selectRecordings; + cDbStatement* selectCleanupRecordings; + + cDbValue imageSize; + cDbValue posterSize; + cDbValue series_id; + cDbValue actorImageSize; + + cDbValue actorRole; + cDbValue actorMovie; + cDbValue thbWidth; + cDbValue thbHeight; + public: cUpdate(cScrapManager *manager); virtual ~cUpdate(void);