summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HISTORY11
-rw-r--r--Makefile13
-rw-r--r--lib/Makefile11
-rw-r--r--lib/common.c426
-rw-r--r--lib/common.h122
-rw-r--r--lib/config.c6
-rw-r--r--lib/config.h7
-rw-r--r--lib/db.c122
-rw-r--r--lib/db.h70
-rw-r--r--lib/tabledef.c2
-rw-r--r--lib/tabledef.h8
-rw-r--r--moviedbmovie.c258
-rw-r--r--moviedbmovie.h196
-rw-r--r--scraper2vdr.h114
-rw-r--r--scrapmanager.c1164
-rw-r--r--scrapmanager.h162
-rw-r--r--services.h386
-rw-r--r--setup.c7
-rw-r--r--tools.c358
-rw-r--r--tools.h62
-rw-r--r--tvdbseries.c578
-rw-r--r--tvdbseries.h286
-rw-r--r--update.c975
-rw-r--r--update.h28
24 files changed, 3064 insertions, 2308 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 <sys/stat.h>
+#include <sys/time.h>
#ifdef USEUUID
# include <uuid/uuid.h>
@@ -17,6 +18,7 @@
#include <syslog.h>
#include <unistd.h>
#include <zlib.h>
+#include <errno.h>
#ifdef USELIBARCHIVE
# include <archive.h>
@@ -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);
@@ -74,6 +84,36 @@ void tell(int eloquence, const char* format, ...)
}
//***************************************************************************
+// 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();
@@ -330,6 +402,86 @@ const char* c2s(char c, char* 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 "<null>";
+
+ 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 <stdint.h> // uint_64_t
#include <stdlib.h>
+#include <string.h>
#include <string>
#include <openssl/md5.h> // 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
+//
//***************************************************************************
-struct MemoryStruct
-{
- MemoryStruct() { memory = 0; clear(); }
- ~MemoryStruct() { clear(); }
-
- // data
+char* srealloc(void* ptr, size_t size);
- char* memory;
- size_t size;
-
- // tag attribute
-
- char tag[100]; // the tag to be compared
- char name[100]; // content name (filename)
- int headerOnly;
+//***************************************************************************
+// MemoryStruct
+//***************************************************************************
- int isEmpty() { return memory == 0; }
+struct MemoryStruct
+{
+ public:
- void clear()
- {
- free(memory);
- memory = 0;
- size = 0;
- *tag = 0;
- *name = 0;
- headerOnly = no;
- }
+ MemoryStruct() { expireAt = time(0); memory = 0; clear(); }
+ MemoryStruct(const MemoryStruct* o)
+ {
+ size = o->size;
+ memory = (char*)malloc(size);
+ memcpy(memory, o->memory, 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;
+
+ return success;
+ }
+
+ // 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 <stdio.h>
-#include <mysql/errmsg.h>
+#include <errmsg.h>
#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]);
@@ -361,6 +419,22 @@ int cDbStatement::prepare()
}
//***************************************************************************
+// 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 <stdio.h>
#include <stdarg.h>
#include <errno.h>
+#include <mysql/mysql.h>
+#include <list>
#include <sstream>
-#include <mysql/mysql.h>
-
#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<cDbStatement*>::iterator it = statements.begin() ; it != statements.end(); ++it)
+ {
+ if (*it)
+ (*it)->showStat();
+ }
+
+ statisticPeriod = time(0);
+ }
+
+ private:
+
+ time_t statisticPeriod;
+ std::list<cDbStatement*> 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,13 +26,16 @@ class cEpgdState
esStandby,
esStopped,
+ // handler pause on this states!
+
esBusy,
esBusyEvents = esBusy,
esBusyMatch,
+ esBusyScraping,
- esBusyImages,
+ // handler don't pause on this states!
- esBusyScraping,
+ esBusyImages,
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<int, cMovieActor*>::iterator it = actors.begin(); it != actors.end(); it++) {
- cMovieActor *a = (cMovieActor*)it->second;
- delete a;
- }
- for (map<int, cMovieMedia*>::iterator it = medias.begin(); it != medias.end(); it++) {
- cMovieMedia *m = (cMovieMedia*)it->second;
- delete m;
- }
-}
-
-void cMovieDbMovie::InsertMedia(cMovieMedia *media) {
- medias.insert(pair<int, cMovieMedia*>(media->mediaType, media));
-}
-
-void cMovieDbMovie::InsertActor(cMovieActor *actor) {
- cMovieMedia *m = new cMovieMedia();
- actor->actorThumb = m;
- actors.insert(pair<int, cMovieActor*>(actor->id, actor));
-}
-
-vector<int> cMovieDbMovie::GetActorIDs(void) {
- vector<int> IDs;
- for (map<int, cMovieActor*>::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<int, cMovieActor*>::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<int, cMovieActor*>::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<int, cMovieMedia*>::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<cActor> *a) {
- for (map<int, cMovieActor*>::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<int, cMovieActor*>::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<int, cMovieMedia*>::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<int, cMovieActor*>::iterator it = actors.begin(); it != actors.end(); it++) {
+ cMovieActor *a = (cMovieActor*)it->second;
+ delete a;
+ }
+ for (map<int, cMovieMedia*>::iterator it = medias.begin(); it != medias.end(); it++) {
+ cMovieMedia *m = (cMovieMedia*)it->second;
+ delete m;
+ }
+}
+
+void cMovieDbMovie::InsertMedia(cMovieMedia *media) {
+ medias.insert(pair<int, cMovieMedia*>(media->mediaType, media));
+}
+
+void cMovieDbMovie::InsertActor(cMovieActor *actor) {
+ cMovieMedia *m = new cMovieMedia();
+ actor->actorThumb = m;
+ actors.insert(pair<int, cMovieActor*>(actor->id, actor));
+}
+
+vector<int> cMovieDbMovie::GetActorIDs(void) {
+ vector<int> IDs;
+ for (map<int, cMovieActor*>::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<int, cMovieActor*>::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<int, cMovieActor*>::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<int, cMovieMedia*>::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<cActor> *a) {
+ for (map<int, cMovieActor*>::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<int, cMovieActor*>::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<int, cMovieMedia*>::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 <iostream>
-#include <string>
-#include <vector>
-#include <map>
-#include <set>
-#include <utility>
-#include <algorithm>
-#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<int, cMovieActor*> actors;
- map<int, cMovieMedia*> 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<int> 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<cActor> *a);
- void Dump();
-};
-
-
-#endif //__TVSCRAPER_TVDBSERIES_H
+#ifndef __TVSCRAPER_MOVIEDBMOVIE_H
+#define __TVSCRAPER_MOVIEDBMOVIE_H
+
+#include <iostream>
+#include <string>
+#include <vector>
+#include <map>
+#include <set>
+#include <utility>
+#include <algorithm>
+#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<int, cMovieActor*> actors;
+ map<int, cMovieMedia*> 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<int> 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<cActor> *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 <getopt.h>
-#include <vdr/plugin.h>
-#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 <getopt.h>
+#include <vdr/plugin.h>
+#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 <vdr/recording.h>
-#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<int, cTVDBSeries*>::iterator it = series.begin(); it != series.end(); it++) {
- cTVDBSeries *s = (cTVDBSeries*)it->second;
- delete s;
- }
- series.clear();
- for (map<int, cMovieDbMovie*>::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<sEventsKey, sEventsValue>::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<sEventsKey, sEventsValue>(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<int, cTVDBSeries*>::iterator hit = series.find(seriesId);
- if (hit == series.end())
- return NULL;
- return hit->second;
-}
-
-cMovieDbMovie *cScrapManager::GetMovie(int movieId) {
- map<int, cMovieDbMovie*>::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<int, cTVDBSeries*>(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<int, cMovieDbMovie*>(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<sRecordingsKey, sEventsValue>::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<sRecordingsKey, sEventsValue>(k, v));
- return true;
-}
-
-bool cScrapManager::RecordingExists(int recStart, string recPath) {
- sRecordingsKey k;
- k.recStart = recStart;
- k.recPath = recPath;
- map<sRecordingsKey, sEventsValue>::iterator hit = recordings.find(k);
- if (hit != recordings.end())
- return true;
- return false;
-}
-
-bool cScrapManager::SeriesInUse(int seriesId) {
- map<int, cTVDBSeries*>::iterator hit = series.find(seriesId);
- if (hit != series.end())
- return true;
- return false;
-}
-
-bool cScrapManager::MovieInUse(int movieId) {
- map<int, cMovieDbMovie*>::iterator hit = movies.find(movieId);
- if (hit != movies.end())
- return true;
- return false;
-}
-
-void cScrapManager::DumpSeries(void) {
- int numSeries = 0;
- map<sEventsKey, sEventsValue>::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<sEventsKey, sEventsValue>::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<sRecordingsKey, sEventsValue>::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<sEventsKey, sEventsValue>::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<sRecordingsKey, sEventsValue>::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<int, cTVDBSeries*>::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<int, cMovieDbMovie*>::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<sEventsKey, sEventsValue>::iterator hit = events.find(k);
- if (hit == events.end())
- return false;
- sEventsValue v = hit->second;
- if (v.seriesId > 0) {
- call->type = tSeries;
- map<int, cTVDBSeries*>::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<int, cMovieDbMovie*>::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<sEventsKey, sEventsValue>::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<sRecordingsKey, sEventsValue>::iterator hit = recordings.find(k);
- if (hit == recordings.end())
- return false;
- v = hit->second;
- }
- if (v.seriesId > 0) {
- map<int, cTVDBSeries*>::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<int, cMovieDbMovie*>::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<sEventsKey, sEventsValue>::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<sRecordingsKey, sEventsValue>::iterator hit = recordings.find(k);
- if (hit == recordings.end())
- return false;
- v = hit->second;
- }
- if (v.seriesId > 0) {
- map<int, cTVDBSeries*>::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<int, cMovieDbMovie*>::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 <vdr/recording.h>
+#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<int, cTVDBSeries*>::iterator it = series.begin(); it != series.end(); it++) {
+ cTVDBSeries *s = (cTVDBSeries*)it->second;
+ delete s;
+ }
+ series.clear();
+ for (map<int, cMovieDbMovie*>::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<sEventsKey, sEventsValue>::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<sEventsKey, sEventsValue>(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<int, cTVDBSeries*>::iterator hit = series.find(seriesId);
+ if (hit == series.end())
+ return NULL;
+ return hit->second;
+}
+
+cMovieDbMovie *cScrapManager::GetMovie(int movieId) {
+ map<int, cMovieDbMovie*>::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<int, cTVDBSeries*>(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<int, cMovieDbMovie*>(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<sRecordingsKey, sEventsValue>::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<sRecordingsKey, sEventsValue>(k, v));
+ return true;
+}
+
+bool cScrapManager::RecordingExists(int recStart, string recPath) {
+ sRecordingsKey k;
+ k.recStart = recStart;
+ k.recPath = recPath;
+ map<sRecordingsKey, sEventsValue>::iterator hit = recordings.find(k);
+ if (hit != recordings.end())
+ return true;
+ return false;
+}
+
+bool cScrapManager::SeriesInUse(int seriesId) {
+ map<int, cTVDBSeries*>::iterator hit = series.find(seriesId);
+ if (hit != series.end())
+ return true;
+ return false;
+}
+
+bool cScrapManager::MovieInUse(int movieId) {
+ map<int, cMovieDbMovie*>::iterator hit = movies.find(movieId);
+ if (hit != movies.end())
+ return true;
+ return false;
+}
+
+void cScrapManager::DumpSeries(void) {
+ int numSeries = 0;
+ map<sEventsKey, sEventsValue>::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<sEventsKey, sEventsValue>::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<sRecordingsKey, sEventsValue>::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<sEventsKey, sEventsValue>::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<sRecordingsKey, sEventsValue>::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<int, cTVDBSeries*>::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<int, cMovieDbMovie*>::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<sEventsKey, sEventsValue>::iterator hit = events.find(k);
+ if (hit == events.end())
+ return false;
+ sEventsValue v = hit->second;
+ if (v.seriesId > 0) {
+ call->type = tSeries;
+ map<int, cTVDBSeries*>::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<int, cMovieDbMovie*>::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<sEventsKey, sEventsValue>::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<sRecordingsKey, sEventsValue>::iterator hit = recordings.find(k);
+ if (hit == recordings.end())
+ return false;
+ v = hit->second;
+ }
+ if (v.seriesId > 0) {
+ map<int, cTVDBSeries*>::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<int, cMovieDbMovie*>::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<sEventsKey, sEventsValue>::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<sRecordingsKey, sEventsValue>::iterator hit = recordings.find(k);
+ if (hit == recordings.end())
+ return false;
+ v = hit->second;
+ }
+ if (v.seriesId > 0) {
+ map<int, cTVDBSeries*>::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<int, cMovieDbMovie*>::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 <vector>
-#include <map>
-#include <set>
-#include <utility>
-#include <algorithm>
-
-#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<sEventsKey, sEventsValue> events;
- map<sEventsKey, sEventsValue>::iterator eventsIterator;
- map<sRecordingsKey, sEventsValue> recordings;
- map<sRecordingsKey, sEventsValue>::iterator recIterator;
- map<int, cTVDBSeries*> series;
- map<int, cMovieDbMovie*> 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 <vector>
+#include <map>
+#include <set>
+#include <utility>
+#include <algorithm>
+
+#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<sEventsKey, sEventsValue> events;
+ map<sEventsKey, sEventsValue>::iterator eventsIterator;
+ map<sRecordingsKey, sEventsValue> recordings;
+ map<sRecordingsKey, sEventsValue>::iterator recIterator;
+ map<int, cTVDBSeries*> series;
+ map<int, cMovieDbMovie*> 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 <vdr/epg.h>
-#include <vdr/recording.h>
-
-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<cActor> 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<cActor> actors;
- std::vector<cTvMedia> posters;
- std::vector<cTvMedia> banners;
- std::vector<cTvMedia> 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 <vdr/epg.h>
+#include <vdr/recording.h>
+
+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<cActor> 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<cActor> actors;
+ std::vector<cTvMedia> posters;
+ std::vector<cTvMedia> banners;
+ std::vector<cTvMedia> 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 <sys/stat.h>
-#include <sys/types.h>
-#include <sys/vfs.h>
-#include <dirent.h>
-#include <fstream>
-#include <algorithm>
-#include <functional>
-#include <cctype>
-#include <locale>
-#include <Magick++.h>
-#include <vdr/plugin.h>
-#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 &ltrim(string &s) {
- s.erase(s.begin(), find_if(s.begin(), s.end(), not1(ptr_fun<int, int>(isspace))));
- return s;
-}
-
-// trim from end
-string &rtrim(string &s) {
- s.erase(find_if(s.rbegin(), s.rend(), not1(ptr_fun<int, int>(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<string>& 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 <sys/stat.h>
+#include <sys/types.h>
+#include <sys/vfs.h>
+#include <dirent.h>
+#include <fstream>
+#include <algorithm>
+#include <functional>
+#include <cctype>
+#include <locale>
+#include <Magick++.h>
+#include <vdr/plugin.h>
+#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 &ltrim(string &s) {
+ s.erase(s.begin(), find_if(s.begin(), s.end(), not1(ptr_fun<int, int>(isspace))));
+ return s;
+}
+
+// trim from end
+string &rtrim(string &s) {
+ s.erase(find_if(s.rbegin(), s.rend(), not1(ptr_fun<int, int>(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<string>& 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 <vector>
-#include <string>
-
-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 &ltrim(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<string> flds;
-public:
- splitstring(const char *s) : string(s) { };
- vector<string>& split(char delim, int rep=0);
-};
-
-//Image Functions
+#include <vector>
+#include <string>
+
+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 &ltrim(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<string> flds;
+public:
+ splitstring(const char *s) : string(s) { };
+ vector<string>& 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<int, cTVDBActor*>::iterator it = actors.begin(); it != actors.end(); it++) {
- cTVDBActor *a = (cTVDBActor*)it->second;
- delete a;
- }
- for (map<int, cTVDBEpisode*>::iterator it = episodes.begin(); it != episodes.end(); it++) {
- cTVDBEpisode *e = (cTVDBEpisode*)it->second;
- delete e;
- }
- for (vector<cTVDBMedia*>::iterator it = posters.begin(); it != posters.end(); it++) {
- cTVDBMedia *p = *it;
- delete p;
- }
- for (vector<cTVDBMedia*>::iterator it = banners.begin(); it != banners.end(); it++) {
- cTVDBMedia *b = *it;
- delete b;
- }
- for (vector<cTVDBMedia*>::iterator it = fanart.begin(); it != fanart.end(); it++) {
- cTVDBMedia *f = *it;
- delete f;
- }
- for (map<int, cTVDBMedia*>::iterator it = seasonPosters.begin(); it != seasonPosters.end(); it++) {
- cTVDBMedia *s = (cTVDBMedia*)it->second;
- delete s;
- }
- for (map<int, cTVDBMedia*>::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<int, cTVDBEpisode*>::iterator hit = episodes.find(episode->id);
- if (hit != episodes.end())
- delete episode;
- else
- episodes.insert(pair<int, cTVDBEpisode*>(episode->id, episode));
-}
-
-void cTVDBSeries::InsertEpisodeImage(int episodeId, int width, int height, string path) {
- map<int, cTVDBEpisode*>::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<int, cTVDBActor*>(actor->id, actor));
-}
-
-void cTVDBSeries::InsertActorThumb(int actorId, int imgWidth, int imgHeight, string path) {
- map<int, cTVDBActor*>::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<int, cTVDBMedia*>(season, media));
- break;
- case msPosterThumb:
- posterThumb = media;
- break;
- case msSeasonPosterThumb:
- seasonPosterThumbs.insert(pair<int, cTVDBMedia*>(season, media));
- break;
- default:
- break;
- }
-}
-
-void cTVDBSeries::GetEpisode(int episodeId, cEpisode *e) {
- map<int, cTVDBEpisode*>::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<cTvMedia> *p) {
- for (vector<cTVDBMedia*>::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<cTvMedia> *b) {
- for (vector<cTVDBMedia*>::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<cTvMedia> *f) {
- for (vector<cTVDBMedia*>::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<int, cTVDBEpisode*>::iterator hit = episodes.find(episodeId);
- if (hit == episodes.end())
- return;
- cTVDBEpisode *e = hit->second;
- map<int, cTVDBMedia*>::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<cActor> *a) {
- for (map<int, cTVDBActor*>::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<cTVDBMedia*>::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<cTVDBMedia*>::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<cTVDBMedia*>::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<int, cTVDBEpisode*>::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<int, cTVDBMedia*>::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<int, cTVDBActor*>::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<int, cTVDBActor*>::iterator it = actors.begin(); it != actors.end(); it++) {
+ cTVDBActor *a = (cTVDBActor*)it->second;
+ delete a;
+ }
+ for (map<int, cTVDBEpisode*>::iterator it = episodes.begin(); it != episodes.end(); it++) {
+ cTVDBEpisode *e = (cTVDBEpisode*)it->second;
+ delete e;
+ }
+ for (vector<cTVDBMedia*>::iterator it = posters.begin(); it != posters.end(); it++) {
+ cTVDBMedia *p = *it;
+ delete p;
+ }
+ for (vector<cTVDBMedia*>::iterator it = banners.begin(); it != banners.end(); it++) {
+ cTVDBMedia *b = *it;
+ delete b;
+ }
+ for (vector<cTVDBMedia*>::iterator it = fanart.begin(); it != fanart.end(); it++) {
+ cTVDBMedia *f = *it;
+ delete f;
+ }
+ for (map<int, cTVDBMedia*>::iterator it = seasonPosters.begin(); it != seasonPosters.end(); it++) {
+ cTVDBMedia *s = (cTVDBMedia*)it->second;
+ delete s;
+ }
+ for (map<int, cTVDBMedia*>::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<int, cTVDBEpisode*>::iterator hit = episodes.find(episode->id);
+ if (hit != episodes.end())
+ delete episode;
+ else
+ episodes.insert(pair<int, cTVDBEpisode*>(episode->id, episode));
+}
+
+void cTVDBSeries::InsertEpisodeImage(int episodeId, int width, int height, string path) {
+ map<int, cTVDBEpisode*>::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<int, cTVDBActor*>(actor->id, actor));
+}
+
+void cTVDBSeries::InsertActorThumb(int actorId, int imgWidth, int imgHeight, string path) {
+ map<int, cTVDBActor*>::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<int, cTVDBMedia*>(season, media));
+ break;
+ case msPosterThumb:
+ posterThumb = media;
+ break;
+ case msSeasonPosterThumb:
+ seasonPosterThumbs.insert(pair<int, cTVDBMedia*>(season, media));
+ break;
+ default:
+ break;
+ }
+}
+
+void cTVDBSeries::GetEpisode(int episodeId, cEpisode *e) {
+ map<int, cTVDBEpisode*>::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<cTvMedia> *p) {
+ for (vector<cTVDBMedia*>::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<cTvMedia> *b) {
+ for (vector<cTVDBMedia*>::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<cTvMedia> *f) {
+ for (vector<cTVDBMedia*>::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<int, cTVDBEpisode*>::iterator hit = episodes.find(episodeId);
+ if (hit == episodes.end())
+ return;
+ cTVDBEpisode *e = hit->second;
+ map<int, cTVDBMedia*>::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<cActor> *a) {
+ for (map<int, cTVDBActor*>::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<cTVDBMedia*>::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<cTVDBMedia*>::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<cTVDBMedia*>::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<int, cTVDBEpisode*>::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<int, cTVDBMedia*>::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<int, cTVDBActor*>::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 <iostream>
-#include <string>
-#include <vector>
-#include <map>
-#include <set>
-#include <utility>
-#include <algorithm>
-#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<int, cTVDBEpisode*> episodes;
- map<int, cTVDBActor*> actors;
- vector<cTVDBMedia*> posters;
- vector<cTVDBMedia*> banners;
- vector<cTVDBMedia*> fanart;
- map<int, cTVDBMedia*> seasonPosters;
- map<int, cTVDBMedia*> 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<cTvMedia> *p);
- bool GetPoster(cTvMedia *p);
- bool GetPosterThumb(cTvMedia *p);
- void GetBanners(vector<cTvMedia> *b);
- bool GetRandomBanner(cTvMedia *b);
- void GetFanart(vector<cTvMedia> *f);
- void GetSeasonPoster(int episodeId, cTvMedia *sp);
- void GetActors(vector<cActor> *a);
- void Dump(void);
-};
-
-
-#endif //__TVSCRAPER_TVDBSERIES_H
+#ifndef __TVSCRAPER_TVDBSERIES_H
+#define __TVSCRAPER_TVDBSERIES_H
+
+#include <iostream>
+#include <string>
+#include <vector>
+#include <map>
+#include <set>
+#include <utility>
+#include <algorithm>
+#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<int, cTVDBEpisode*> episodes;
+ map<int, cTVDBActor*> actors;
+ vector<cTVDBMedia*> posters;
+ vector<cTVDBMedia*> banners;
+ vector<cTVDBMedia*> fanart;
+ map<int, cTVDBMedia*> seasonPosters;
+ map<int, cTVDBMedia*> 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<cTvMedia> *p);
+ bool GetPoster(cTvMedia *p);
+ bool GetPosterThumb(cTvMedia *p);
+ void GetBanners(vector<cTvMedia> *b);
+ bool GetRandomBanner(cTvMedia *b);
+ void GetFanart(vector<cTvMedia> *f);
+ void GetSeasonPoster(int episodeId, cTvMedia *sp);
+ void GetActors(vector<cActor> *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 <vdr/tools.h>
#include <vdr/plugin.h>
+#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<int> IDs = movie->GetActorIDs();
for (vector<int>::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;
- }
+int cUpdate::ReadRecordings(void) {
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);
-
- 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);
-
- lastScan = time(0);
- forceUpdate = false;
+ // Update Recordings from Database
+
+ if (forceRecordingUpdate || (time(0) - lastScanNewRecDB > scanNewRecDBFreq) && Running())
+ {
+ worked++;
+ int numNewRecs = ReadRecordings();
+ lastScanNewRecDB = time(0);
+
+ 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 <mysql/mysql.h>
#include <map>
#include <vdr/thread.h>
@@ -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);