mirror of
https://projects.vdr-developer.org/git/vdr-plugin-scraper2vdr.git
synced 2023-10-19 17:58:31 +02:00
added lib files
This commit is contained in:
parent
9ebafce3fd
commit
5d7fb01f67
176
lib/curl.c
Normal file
176
lib/curl.c
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
/*
|
||||||
|
* curl.c:
|
||||||
|
*
|
||||||
|
* See the README file for copyright information and how to reach the author.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// Callbacks
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
static size_t WriteMemoryCallback(void* ptr, size_t size, size_t nmemb, void* data)
|
||||||
|
{
|
||||||
|
size_t realsize = size * nmemb;
|
||||||
|
struct MemoryStruct* mem = (struct MemoryStruct*)data;
|
||||||
|
|
||||||
|
if (mem->memory)
|
||||||
|
mem->memory = (char*)realloc(mem->memory, mem->size + realsize + 1);
|
||||||
|
else
|
||||||
|
mem->memory = (char*)malloc(mem->size + realsize + 1);
|
||||||
|
|
||||||
|
if (mem->memory)
|
||||||
|
{
|
||||||
|
memcpy (&(mem->memory[mem->size]), ptr, realsize);
|
||||||
|
mem->size += realsize;
|
||||||
|
mem->memory[mem->size] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return realsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t WriteHeaderCallback(void* ptr, size_t size, size_t nmemb, void* data)
|
||||||
|
{
|
||||||
|
size_t realsize = size * nmemb;
|
||||||
|
struct MemoryStruct* mem = (struct MemoryStruct*)data;
|
||||||
|
char* p;
|
||||||
|
|
||||||
|
if (ptr)
|
||||||
|
{
|
||||||
|
// get filename
|
||||||
|
{
|
||||||
|
// Content-Disposition: attachment; filename="20140103_20140103_de_qy.zip"
|
||||||
|
|
||||||
|
const char* attribute = "Content-disposition: ";
|
||||||
|
|
||||||
|
if ((p = strcasestr((char*)ptr, attribute)))
|
||||||
|
{
|
||||||
|
if (p = strcasestr(p, "filename="))
|
||||||
|
{
|
||||||
|
p += strlen("filename=");
|
||||||
|
|
||||||
|
tell(4, "found filename at [%s]", p);
|
||||||
|
|
||||||
|
if (*p == '"')
|
||||||
|
p++;
|
||||||
|
|
||||||
|
sprintf(mem->name, "%s", p);
|
||||||
|
|
||||||
|
if ((p = strchr(mem->name, '\n')))
|
||||||
|
*p = 0;
|
||||||
|
|
||||||
|
if ((p = strchr(mem->name, '\r')))
|
||||||
|
*p = 0;
|
||||||
|
|
||||||
|
if ((p = strchr(mem->name, '"')))
|
||||||
|
*p = 0;
|
||||||
|
|
||||||
|
tell(4, "set name to '%s'", mem->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// since some sources update "ETag" an "Last-Modified:" without changing the contents
|
||||||
|
// we have to use "Content-Length:" to check for updates :(
|
||||||
|
{
|
||||||
|
const char* attribute = "Content-Length: ";
|
||||||
|
|
||||||
|
if ((p = strcasestr((char*)ptr, attribute)))
|
||||||
|
{
|
||||||
|
sprintf(mem->tag, "%s", p+strlen(attribute));
|
||||||
|
|
||||||
|
if ((p = strchr(mem->tag, '\n')))
|
||||||
|
*p = 0;
|
||||||
|
|
||||||
|
if ((p = strchr(mem->tag, '\r')))
|
||||||
|
*p = 0;
|
||||||
|
|
||||||
|
if ((p = strchr(mem->tag, '"')))
|
||||||
|
*p = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return realsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// Download File
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
int downloadFile(const char* url, int& size, MemoryStruct* data, int timeout, const char* userAgent)
|
||||||
|
{
|
||||||
|
CURL* curl_handle;
|
||||||
|
long code;
|
||||||
|
CURLcode res = CURLE_OK;
|
||||||
|
|
||||||
|
size = 0;
|
||||||
|
|
||||||
|
// init curl
|
||||||
|
|
||||||
|
if (curl_global_init(CURL_GLOBAL_ALL) != 0)
|
||||||
|
{
|
||||||
|
tell(0, "Error, something went wrong with curl_global_init()");
|
||||||
|
|
||||||
|
return fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_handle = curl_easy_init();
|
||||||
|
|
||||||
|
if (!curl_handle)
|
||||||
|
{
|
||||||
|
tell(0, "Error, unable to get handle from curl_easy_init()");
|
||||||
|
|
||||||
|
return fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EPG2VDRConfig.useproxy)
|
||||||
|
{
|
||||||
|
curl_easy_setopt(curl_handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
|
||||||
|
curl_easy_setopt(curl_handle, CURLOPT_PROXY, EPG2VDRConfig.httpproxy); // Specify HTTP proxy
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_easy_setopt(curl_handle, CURLOPT_URL, url); // Specify URL to get
|
||||||
|
curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 0); // don't follow redirects
|
||||||
|
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); // Send all data to this function
|
||||||
|
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void*)data); // Pass our 'data' struct to the callback function
|
||||||
|
curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, WriteHeaderCallback); // Send header to this function
|
||||||
|
curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER, (void*)data); // Pass some header details to this struct
|
||||||
|
curl_easy_setopt(curl_handle, CURLOPT_MAXFILESIZE, 100*1024*1024); // Set maximum file size to get (bytes)
|
||||||
|
curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1); // No progress meter
|
||||||
|
curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1); // No signaling
|
||||||
|
curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, timeout); // Set timeout
|
||||||
|
curl_easy_setopt(curl_handle, CURLOPT_NOBODY, data->headerOnly ? 1 : 0); //
|
||||||
|
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, userAgent); // Some servers don't like requests
|
||||||
|
// that are made without a user-agent field
|
||||||
|
// perform http-get
|
||||||
|
|
||||||
|
if ((res = curl_easy_perform(curl_handle)) != 0)
|
||||||
|
{
|
||||||
|
data->clear();
|
||||||
|
|
||||||
|
tell(1, "Error, download failed; %s (%d)",
|
||||||
|
curl_easy_strerror(res), res);
|
||||||
|
curl_easy_cleanup(curl_handle); // Cleanup curl stuff
|
||||||
|
|
||||||
|
return fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_easy_getinfo(curl_handle, CURLINFO_HTTP_CODE, &code);
|
||||||
|
curl_easy_cleanup(curl_handle); // cleanup curl stuff
|
||||||
|
|
||||||
|
if (code == 404)
|
||||||
|
{
|
||||||
|
data->clear();
|
||||||
|
return fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = data->size;
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
158
lib/dbdict.c
Normal file
158
lib/dbdict.c
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
/*
|
||||||
|
* dbdict.c
|
||||||
|
*
|
||||||
|
* See the README file for copyright information and how to reach the author.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "dbdict.h"
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// cDbDict
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
cDbDict::cDbDict()
|
||||||
|
{
|
||||||
|
inside = no;
|
||||||
|
}
|
||||||
|
|
||||||
|
cDbDict::~cDbDict()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// In
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
int cDbDict::in(const char* file)
|
||||||
|
{
|
||||||
|
FILE* f;
|
||||||
|
char* line = 0;
|
||||||
|
size_t size = 0;
|
||||||
|
char* path;
|
||||||
|
|
||||||
|
asprintf(&path, "%s", file);
|
||||||
|
|
||||||
|
f = fopen(path, "r");
|
||||||
|
|
||||||
|
while (getline(&line, &size, f) > 0)
|
||||||
|
{
|
||||||
|
char* p = strstr(line, "//");
|
||||||
|
|
||||||
|
if (p) *p = 0;
|
||||||
|
|
||||||
|
allTrim(line);
|
||||||
|
|
||||||
|
if (isEmpty(line))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (atLine(line) != success)
|
||||||
|
{
|
||||||
|
tell(0, "Found unexpected definition '%s', aborting", line);
|
||||||
|
free(path);
|
||||||
|
return fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
free(line);
|
||||||
|
free(path);
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// At Line
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
int cDbDict::atLine(const char* line)
|
||||||
|
{
|
||||||
|
const char* p;
|
||||||
|
|
||||||
|
if (p = strcasestr(line, "Table"))
|
||||||
|
{
|
||||||
|
char tableName[100];
|
||||||
|
|
||||||
|
p += strlen("Table");
|
||||||
|
strcpy(tableName, p);
|
||||||
|
tell(0, "Table: '%s'", tableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (strchr(line, '{'))
|
||||||
|
inside = yes;
|
||||||
|
|
||||||
|
else if (strchr(line, '}'))
|
||||||
|
inside = no;
|
||||||
|
|
||||||
|
else if (inside)
|
||||||
|
parseField(line);
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// Get Token
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
int getToken(const char*& p, char* token, int size)
|
||||||
|
{
|
||||||
|
char* dest = token;
|
||||||
|
int num = 0;
|
||||||
|
|
||||||
|
while (*p && *p == ' ')
|
||||||
|
p++;
|
||||||
|
|
||||||
|
while (*p && *p != ' ' && num < size)
|
||||||
|
{
|
||||||
|
if (*p == '"')
|
||||||
|
p++;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*dest++ = *p++;
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*dest = 0;
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// Parse Field
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
int cDbDict::parseField(const char* line)
|
||||||
|
{
|
||||||
|
const int sizeTokenMax = 100;
|
||||||
|
FieldDef f;
|
||||||
|
char token[sizeTokenMax+TB];
|
||||||
|
const char* p = line;
|
||||||
|
|
||||||
|
// tell(0, "Got: '%s'", p);
|
||||||
|
|
||||||
|
for (int i = 0; i < dtCount; i++)
|
||||||
|
{
|
||||||
|
if (getToken(p, token, sizeTokenMax) != success)
|
||||||
|
{
|
||||||
|
tell(0, "Errot: can't parse line [%s]", line);
|
||||||
|
return fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
case dtName: f.name = strdup(token); break;
|
||||||
|
case dtDescription: break;
|
||||||
|
case dtFormat: f.format = toDictFormat(token); break;
|
||||||
|
case dtSize: f.size = atoi(token); break;
|
||||||
|
case dtType: f.type = toType(token); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
free((char*)f.name); // böser cast ...
|
||||||
|
|
||||||
|
tell(0, "token %d -> '%s'", i, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
52
lib/dbdict.h
Normal file
52
lib/dbdict.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* dbdict.h
|
||||||
|
*
|
||||||
|
* See the README file for copyright information and how to reach the author.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DBDICT_H
|
||||||
|
#define __DBDICT_H
|
||||||
|
|
||||||
|
#include "db.h"
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// cDbDict
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
class cDbDict : public cDbService
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// declarations
|
||||||
|
|
||||||
|
enum DictToken
|
||||||
|
{
|
||||||
|
dtName,
|
||||||
|
dtDescription,
|
||||||
|
dtFormat,
|
||||||
|
dtSize,
|
||||||
|
dtType,
|
||||||
|
|
||||||
|
dtCount
|
||||||
|
};
|
||||||
|
|
||||||
|
cDbDict();
|
||||||
|
virtual ~cDbDict();
|
||||||
|
|
||||||
|
int in(const char* file);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
int atLine(const char* line);
|
||||||
|
int parseField(const char* line);
|
||||||
|
|
||||||
|
// data
|
||||||
|
|
||||||
|
int inside;
|
||||||
|
static FieldDef fields[];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __DBDICT_H
|
279
lib/demo.c
Normal file
279
lib/demo.c
Normal file
@ -0,0 +1,279 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#include "db.h"
|
||||||
|
#include "tabledef.h"
|
||||||
|
|
||||||
|
cDbConnection* connection = 0;
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// Init Connection
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
void initConnection()
|
||||||
|
{
|
||||||
|
cDbConnection::init();
|
||||||
|
|
||||||
|
cDbConnection::setEncoding("utf8");
|
||||||
|
cDbConnection::setHost("localhost");
|
||||||
|
|
||||||
|
cDbConnection::setPort(3306);
|
||||||
|
cDbConnection::setName("epg2vdr");
|
||||||
|
cDbConnection::setUser("epg2vdr");
|
||||||
|
cDbConnection::setPass("epg");
|
||||||
|
cDbTable::setConfPath("/etc/epgd/");
|
||||||
|
|
||||||
|
connection = new cDbConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
void exitConnection()
|
||||||
|
{
|
||||||
|
cDbConnection::exit();
|
||||||
|
|
||||||
|
if (connection)
|
||||||
|
delete connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
//
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
int demoStatement()
|
||||||
|
{
|
||||||
|
int status = success;
|
||||||
|
|
||||||
|
cTableEvents* eventsDb = new cTableEvents(connection);
|
||||||
|
|
||||||
|
tell(0, "------------------- attach table ---------------");
|
||||||
|
|
||||||
|
// open table (attach)
|
||||||
|
|
||||||
|
if (eventsDb->open() != success)
|
||||||
|
return fail;
|
||||||
|
|
||||||
|
tell(0, "---------------- prepare select statement -------------");
|
||||||
|
|
||||||
|
// vorbereiten (prepare) eines statement, am besten einmal bei programmstart!
|
||||||
|
// ----------
|
||||||
|
// select eventid, compshorttext, episodepart, episodelang
|
||||||
|
// from events
|
||||||
|
// where eventid > ?
|
||||||
|
|
||||||
|
cDbStatement* selectByCompTitle = new cDbStatement(eventsDb);
|
||||||
|
|
||||||
|
status += selectByCompTitle->build("select ");
|
||||||
|
status += selectByCompTitle->bind(cTableEvents::fiEventId, cDBS::bndOut);
|
||||||
|
status += selectByCompTitle->bind(cTableEvents::fiChannelId, cDBS::bndOut, ", ");
|
||||||
|
status += selectByCompTitle->bind(cTableEvents::fiTitle, cDBS::bndOut, ", ");
|
||||||
|
status += selectByCompTitle->build(" from %s where ", eventsDb->TableName());
|
||||||
|
status += selectByCompTitle->bindCmp(0, cTableEvents::fiEventId, 0, ">");
|
||||||
|
|
||||||
|
status += selectByCompTitle->prepare(); // prepare statement
|
||||||
|
|
||||||
|
if (status != success)
|
||||||
|
{
|
||||||
|
// prepare sollte oracle fehler ausgegeben haben!
|
||||||
|
|
||||||
|
delete eventsDb;
|
||||||
|
delete selectByCompTitle;
|
||||||
|
|
||||||
|
return fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
tell(0, "------------------ prepare done ----------------------");
|
||||||
|
|
||||||
|
tell(0, "------------------ create some rows ----------------------");
|
||||||
|
|
||||||
|
eventsDb->clear(); // alle values löschen
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
char* title;
|
||||||
|
asprintf(&title, "title %d", i);
|
||||||
|
|
||||||
|
eventsDb->setValue(cTableEvents::fiEventId, 800 + i * 100);
|
||||||
|
eventsDb->setValue(cTableEvents::fiChannelId, "xxx-yyyy-zzz");
|
||||||
|
eventsDb->setValue(cTableEvents::fiTitle, title);
|
||||||
|
|
||||||
|
eventsDb->store(); // store -> select mit anschl. update oder insert je nachdem ob dier PKey bereits vorhanden ist
|
||||||
|
// eventsDb->insert(); // sofern man schon weiß das es ein insert ist
|
||||||
|
// eventsDb->update(); // sofern man schon weiß das der Datensatz vorhanden ist
|
||||||
|
|
||||||
|
free(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
tell(0, "------------------ done ----------------------");
|
||||||
|
|
||||||
|
tell(0, "-------- select all where eventid > 1000 -------------");
|
||||||
|
|
||||||
|
eventsDb->clear(); // alle values löschen
|
||||||
|
eventsDb->setValue(cTableEvents::fiEventId, 1000);
|
||||||
|
|
||||||
|
for (int f = selectByCompTitle->find(); f; f = selectByCompTitle->fetch())
|
||||||
|
{
|
||||||
|
tell(0, "id: %ld", eventsDb->getIntValue(cTableEvents::fiEventId));
|
||||||
|
tell(0, "channel: %s", eventsDb->getStrValue(cTableEvents::fiChannelId));
|
||||||
|
tell(0, "titel: %s", eventsDb->getStrValue(cTableEvents::fiTitle));
|
||||||
|
}
|
||||||
|
|
||||||
|
// freigeben der Ergebnissmenge !!
|
||||||
|
|
||||||
|
selectByCompTitle->freeResult();
|
||||||
|
|
||||||
|
// folgendes am programmende
|
||||||
|
|
||||||
|
delete eventsDb; // implizietes close (detach)
|
||||||
|
delete selectByCompTitle; // statement freigeben (auch gegen die DB)
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// Join
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
int joinDemo()
|
||||||
|
{
|
||||||
|
int status = success;
|
||||||
|
|
||||||
|
// grundsätzlich genügt hier auch eine Tabelle, für die anderen sind cDbValue Instanzen außreichend
|
||||||
|
// so ist es etwas einfacher die cDbValues zu initialisieren.
|
||||||
|
// Ich habe statische "virtual FieldDef* getFieldDef(int f)" Methode in der Tabellenklassen geplant
|
||||||
|
// um ohne Instanz der cTable ein Feld einfach initialisieren zu können
|
||||||
|
|
||||||
|
cTableEvents* eventsDb = new cTableEvents(connection);
|
||||||
|
cTableImageRefs* imageRefDb = new cTableImageRefs(connection);
|
||||||
|
cTableImages* imageDb = new cTableImages(connection);
|
||||||
|
|
||||||
|
tell(0, "------------------- attach table ---------------");
|
||||||
|
|
||||||
|
// open table (attach)
|
||||||
|
|
||||||
|
if (eventsDb->open() != success)
|
||||||
|
return fail;
|
||||||
|
|
||||||
|
if (imageDb->open() != success)
|
||||||
|
return fail;
|
||||||
|
|
||||||
|
if (imageRefDb->open() != success)
|
||||||
|
return fail;
|
||||||
|
|
||||||
|
tell(0, "---------------- prepare select statement -------------");
|
||||||
|
|
||||||
|
// all images
|
||||||
|
|
||||||
|
cDbStatement* selectAllImages = new cDbStatement(imageRefDb);
|
||||||
|
|
||||||
|
// prepare fields
|
||||||
|
|
||||||
|
cDbValue imageUpdSp;
|
||||||
|
cDbValue imageSize;
|
||||||
|
cDbValue masterId;
|
||||||
|
|
||||||
|
cDBS::FieldDef imageSizeDef = { "image", cDBS::ffUInt, 0, 999, cDBS::ftData }; // eine Art ein Feld zu erzeugen
|
||||||
|
imageSize.setField(&imageSizeDef); // eine andere Art ein Feld zu erzeugen ...
|
||||||
|
imageUpdSp.setField(imageDb->getField(cTableImages::fiUpdSp));
|
||||||
|
masterId.setField(eventsDb->getField(cTableEvents::fiMasterId));
|
||||||
|
|
||||||
|
// select e.masterid, r.imagename, r.eventid, r.lfn, length(i.image)
|
||||||
|
// from imagerefs r, images i, events e
|
||||||
|
// where i.imagename = r.imagename
|
||||||
|
// and e.eventid = r.eventid
|
||||||
|
// and (i.updsp > ? or r.updsp > ?)
|
||||||
|
|
||||||
|
selectAllImages->build("select ");
|
||||||
|
selectAllImages->setBindPrefix("e.");
|
||||||
|
selectAllImages->bind(&masterId, cDBS::bndOut);
|
||||||
|
selectAllImages->setBindPrefix("r.");
|
||||||
|
selectAllImages->bind(cTableImageRefs::fiImgName, cDBS::bndOut, ", ");
|
||||||
|
selectAllImages->bind(cTableImageRefs::fiEventId, cDBS::bndOut, ", ");
|
||||||
|
selectAllImages->bind(cTableImageRefs::fiLfn, cDBS::bndOut, ", ");
|
||||||
|
selectAllImages->setBindPrefix("i.");
|
||||||
|
selectAllImages->build(", length(");
|
||||||
|
selectAllImages->bind(&imageSize, cDBS::bndOut);
|
||||||
|
selectAllImages->build(")");
|
||||||
|
selectAllImages->clrBindPrefix();
|
||||||
|
selectAllImages->build(" from %s r, %s i, %s e where ",
|
||||||
|
imageRefDb->TableName(), imageDb->TableName(), eventsDb->TableName());
|
||||||
|
selectAllImages->build("e.%s = r.%s and i.%s = r.%s and (",
|
||||||
|
eventsDb->getField(cTableEvents::fiEventId)->name,
|
||||||
|
imageRefDb->getField(cTableImageRefs::fiEventId)->name,
|
||||||
|
imageDb->getField(cTableImages::fiImgName)->name,
|
||||||
|
imageRefDb->getField(cTableImageRefs::fiImgName)->name);
|
||||||
|
selectAllImages->bindCmp("i", &imageUpdSp, ">");
|
||||||
|
selectAllImages->build(" or ");
|
||||||
|
selectAllImages->bindCmp("r", cTableImageRefs::fiUpdSp, 0, ">");
|
||||||
|
selectAllImages->build(")");
|
||||||
|
|
||||||
|
status += selectAllImages->prepare();
|
||||||
|
|
||||||
|
if (status != success)
|
||||||
|
{
|
||||||
|
// prepare sollte oracle fehler ausgegeben haben!
|
||||||
|
|
||||||
|
delete eventsDb;
|
||||||
|
delete imageDb;
|
||||||
|
delete imageRefDb;
|
||||||
|
delete selectAllImages;
|
||||||
|
|
||||||
|
return fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
tell(0, "------------------ prepare done ----------------------");
|
||||||
|
|
||||||
|
tell(0, "------------------ select ----------------------");
|
||||||
|
|
||||||
|
time_t since = time(0) - 60 * 60;
|
||||||
|
imageRefDb->clear();
|
||||||
|
imageRefDb->setValue(cTableImageRefs::fiUpdSp, since);
|
||||||
|
imageUpdSp.setValue(since);
|
||||||
|
|
||||||
|
for (int res = selectAllImages->find(); res; res = selectAllImages->fetch())
|
||||||
|
{
|
||||||
|
// so kommst du an die Werte der unterschgiedlichen Tabellen
|
||||||
|
|
||||||
|
// int eventid = masterId.getIntValue();
|
||||||
|
// const char* imageName = imageRefDb->getStrValue(cTableImageRefs::fiImgName);
|
||||||
|
// int lfn = imageRefDb->getIntValue(cTableImageRefs::fiLfn);
|
||||||
|
// int size = imageSize.getIntValue();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// freigeben der Ergebnissmenge !!
|
||||||
|
|
||||||
|
selectAllImages->freeResult();
|
||||||
|
|
||||||
|
// folgendes am programmende
|
||||||
|
|
||||||
|
delete eventsDb; // implizietes close (detach)
|
||||||
|
delete imageDb;
|
||||||
|
delete imageRefDb;
|
||||||
|
delete selectAllImages; // statement freigeben (auch gegen die DB)
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// Main
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
EPG2VDRConfig.logstdout = yes;
|
||||||
|
EPG2VDRConfig.loglevel = 2;
|
||||||
|
|
||||||
|
initConnection();
|
||||||
|
|
||||||
|
// demoStatement();
|
||||||
|
// joinDemo();
|
||||||
|
|
||||||
|
tell(0, "uuid: '%s'", getUniqueId());
|
||||||
|
|
||||||
|
exitConnection();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
190
lib/imgtools.c
Normal file
190
lib/imgtools.c
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
/*
|
||||||
|
* imgtools.c
|
||||||
|
*
|
||||||
|
* See the README file for copyright information and how to reach the author.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "imgtools.h"
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// Image converting stuff
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
int fromJpeg(Imlib_Image& image, unsigned char* buffer, int size)
|
||||||
|
{
|
||||||
|
struct jpeg_decompress_struct cinfo;
|
||||||
|
struct jpeg_error_mgr jerr;
|
||||||
|
int w, h;
|
||||||
|
DATA8 *ptr, *line[16], *data;
|
||||||
|
DATA32 *ptr2, *dest;
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
cinfo.err = jpeg_std_error(&jerr);
|
||||||
|
|
||||||
|
jpeg_create_decompress(&cinfo);
|
||||||
|
jpeg_mem_src(&cinfo, buffer, size);
|
||||||
|
jpeg_read_header(&cinfo, TRUE);
|
||||||
|
cinfo.do_fancy_upsampling = FALSE;
|
||||||
|
cinfo.do_block_smoothing = FALSE;
|
||||||
|
|
||||||
|
jpeg_start_decompress(&cinfo);
|
||||||
|
|
||||||
|
w = cinfo.output_width;
|
||||||
|
h = cinfo.output_height;
|
||||||
|
|
||||||
|
image = imlib_create_image(w, h);
|
||||||
|
imlib_context_set_image(image);
|
||||||
|
|
||||||
|
dest = ptr2 = imlib_image_get_data();
|
||||||
|
data = (DATA8*)malloc(w * 16 * cinfo.output_components);
|
||||||
|
|
||||||
|
for (int i = 0; i < cinfo.rec_outbuf_height; i++)
|
||||||
|
line[i] = data + (i * w * cinfo.output_components);
|
||||||
|
|
||||||
|
for (int l = 0; l < h; l += cinfo.rec_outbuf_height)
|
||||||
|
{
|
||||||
|
jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
|
||||||
|
int scans = cinfo.rec_outbuf_height;
|
||||||
|
|
||||||
|
if (h - l < scans)
|
||||||
|
scans = h - l;
|
||||||
|
|
||||||
|
ptr = data;
|
||||||
|
|
||||||
|
for (y = 0; y < scans; y++)
|
||||||
|
{
|
||||||
|
for (x = 0; x < w; x++)
|
||||||
|
{
|
||||||
|
*ptr2 = (0xff000000) | ((ptr[0]) << 16) | ((ptr[1]) << 8) | (ptr[2]);
|
||||||
|
ptr += cinfo.output_components;
|
||||||
|
ptr2++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
imlib_image_put_back_data(dest);
|
||||||
|
|
||||||
|
jpeg_finish_decompress(&cinfo);
|
||||||
|
jpeg_destroy_decompress(&cinfo);
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
long toJpeg(Imlib_Image image, MemoryStruct* data, int quality)
|
||||||
|
{
|
||||||
|
struct jpeg_compress_struct cinfo = { 0 };
|
||||||
|
struct jpeg_error_mgr jerr;
|
||||||
|
DATA32* ptr;
|
||||||
|
DATA8* buf;
|
||||||
|
long unsigned int size = data->size;
|
||||||
|
|
||||||
|
imlib_context_set_image(image);
|
||||||
|
|
||||||
|
data->clear();
|
||||||
|
|
||||||
|
cinfo.err = jpeg_std_error(&jerr);
|
||||||
|
|
||||||
|
jpeg_create_compress(&cinfo);
|
||||||
|
jpeg_mem_dest(&cinfo, (unsigned char**)(&data->memory), &size);
|
||||||
|
|
||||||
|
cinfo.image_width = imlib_image_get_width();
|
||||||
|
cinfo.image_height = imlib_image_get_height();
|
||||||
|
cinfo.input_components = 3;
|
||||||
|
cinfo.in_color_space = JCS_RGB;
|
||||||
|
|
||||||
|
jpeg_set_defaults(&cinfo);
|
||||||
|
jpeg_set_quality(&cinfo, quality, TRUE);
|
||||||
|
jpeg_start_compress(&cinfo, TRUE);
|
||||||
|
|
||||||
|
// get data pointer
|
||||||
|
|
||||||
|
if (!(ptr = imlib_image_get_data_for_reading_only()))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// allocate a small buffer to convert image data */
|
||||||
|
|
||||||
|
buf = (DATA8*)malloc(imlib_image_get_width() * 3 * sizeof(DATA8));
|
||||||
|
|
||||||
|
while (cinfo.next_scanline < cinfo.image_height)
|
||||||
|
{
|
||||||
|
// convert scanline from ARGB to RGB packed
|
||||||
|
|
||||||
|
for (int j = 0, i = 0; i < imlib_image_get_width(); i++)
|
||||||
|
{
|
||||||
|
buf[j++] = ((*ptr) >> 16) & 0xff;
|
||||||
|
buf[j++] = ((*ptr) >> 8) & 0xff;
|
||||||
|
buf[j++] = ((*ptr)) & 0xff;
|
||||||
|
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write scanline
|
||||||
|
|
||||||
|
jpeg_write_scanlines(&cinfo, (JSAMPROW*)(&buf), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
jpeg_finish_compress(&cinfo);
|
||||||
|
jpeg_destroy_compress(&cinfo);
|
||||||
|
|
||||||
|
return data->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int scaleImageToJpegBuffer(Imlib_Image image, MemoryStruct* data, int width, int height)
|
||||||
|
{
|
||||||
|
if (width && height)
|
||||||
|
{
|
||||||
|
Imlib_Image scaledImage;
|
||||||
|
|
||||||
|
imlib_context_set_image(image);
|
||||||
|
|
||||||
|
int imgWidth = imlib_image_get_width();
|
||||||
|
int imgHeight = imlib_image_get_height();
|
||||||
|
double ratio = (double)imgWidth / (double)imgHeight;
|
||||||
|
|
||||||
|
if ((double)width/(double)imgWidth < (double)height/(double)imgHeight)
|
||||||
|
height = (int)((double)width / ratio);
|
||||||
|
else
|
||||||
|
width = (int)((double)height * ratio);
|
||||||
|
|
||||||
|
scaledImage = imlib_create_image(width, height);
|
||||||
|
imlib_context_set_image(scaledImage);
|
||||||
|
|
||||||
|
imlib_context_set_color(240, 240, 240, 255);
|
||||||
|
imlib_image_fill_rectangle(0, 0, width, height);
|
||||||
|
|
||||||
|
imlib_blend_image_onto_image(image, 0, 0, 0,
|
||||||
|
imgWidth, imgHeight, 0, 0,
|
||||||
|
width, height);
|
||||||
|
|
||||||
|
toJpeg(scaledImage, data, 70);
|
||||||
|
|
||||||
|
imlib_context_set_image(scaledImage);
|
||||||
|
imlib_free_image();
|
||||||
|
|
||||||
|
tell(1, "Scaled image to %d/%d, now %d bytes", width, height, (int)data->size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
toJpeg(image, data, 70);
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
int scaleJpegBuffer(MemoryStruct* data, int width, int height)
|
||||||
|
{
|
||||||
|
Imlib_Image image;
|
||||||
|
|
||||||
|
fromJpeg(image, (unsigned char*)data->memory, data->size);
|
||||||
|
|
||||||
|
scaleImageToJpegBuffer(image, data, width, height);
|
||||||
|
|
||||||
|
imlib_context_set_image(image);
|
||||||
|
imlib_free_image();
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
28
lib/imgtools.h
Normal file
28
lib/imgtools.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* imgtools.c
|
||||||
|
*
|
||||||
|
* See the README file for copyright information and how to reach the author.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __IMGTOOLS_H
|
||||||
|
#define __IMGTOOLS_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <jpeglib.h>
|
||||||
|
#include <Imlib2.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// Image Manipulating
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
int fromJpeg(Imlib_Image& image, unsigned char* buffer, int size);
|
||||||
|
long toJpeg(Imlib_Image image, MemoryStruct* data, int quality);
|
||||||
|
int scaleImageToJpegBuffer(Imlib_Image image, MemoryStruct* data, int width = 0, int height = 0);
|
||||||
|
int scaleJpegBuffer(MemoryStruct* data, int width = 0, int height = 0);
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
#endif // __IMGTOOLS_H
|
458
lib/test.c
Normal file
458
lib/test.c
Normal file
@ -0,0 +1,458 @@
|
|||||||
|
|
||||||
|
#include <stdint.h> // uint_64_t
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "common.h"
|
||||||
|
#include "db.h"
|
||||||
|
#include "tabledef.h"
|
||||||
|
#include "dbdict.h"
|
||||||
|
|
||||||
|
cDbConnection* connection = 0;
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
//
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
class cTimeMs
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
uint64_t begin;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
cTimeMs(int Ms = 0);
|
||||||
|
static uint64_t Now(void);
|
||||||
|
void Set(int Ms = 0);
|
||||||
|
bool TimedOut(void);
|
||||||
|
uint64_t Elapsed(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// Init Connection
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
void initConnection()
|
||||||
|
{
|
||||||
|
cDbConnection::init();
|
||||||
|
|
||||||
|
cDbConnection::setEncoding("utf8");
|
||||||
|
cDbConnection::setHost("localhost");
|
||||||
|
cDbConnection::setPort(EPG2VDRConfig.dbPort);
|
||||||
|
cDbConnection::setName(EPG2VDRConfig.dbName);
|
||||||
|
cDbConnection::setUser(EPG2VDRConfig.dbUser);
|
||||||
|
cDbConnection::setPass(EPG2VDRConfig.dbPass);
|
||||||
|
cDbTable::setConfPath("/etc/epgd/");
|
||||||
|
|
||||||
|
connection = new cDbConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
void exitConnection()
|
||||||
|
{
|
||||||
|
cDbConnection::exit();
|
||||||
|
|
||||||
|
if (connection)
|
||||||
|
delete connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
//
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
void chkCompress()
|
||||||
|
{
|
||||||
|
std::string s = "_+*!#?=&%$< Hallo TEIL Hallo Folge ";
|
||||||
|
|
||||||
|
printf("'%s'\n", s.c_str());
|
||||||
|
prepareCompressed(s);
|
||||||
|
printf("'%s'\n", s.c_str());
|
||||||
|
|
||||||
|
s = "Place Vendôme - Heiße Diamanten";
|
||||||
|
printf("'%s'\n", s.c_str());
|
||||||
|
prepareCompressed(s);
|
||||||
|
printf("'%s'\n", s.c_str());
|
||||||
|
|
||||||
|
s = "Halöö älter";
|
||||||
|
printf("'%s'\n", s.c_str());
|
||||||
|
prepareCompressed(s);
|
||||||
|
printf("'%s'\n", s.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
//
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
void chkStatement1()
|
||||||
|
{
|
||||||
|
cDbTable* epgDb = new cTableEvents(connection);
|
||||||
|
|
||||||
|
if (epgDb->open() != success)
|
||||||
|
{
|
||||||
|
tell(0, "Could not access database '%s:%d' (%s)",
|
||||||
|
cDbConnection::getHost(), cDbConnection::getPort(), epgDb->TableName());
|
||||||
|
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
tell(0, "---------------------------------------------------");
|
||||||
|
|
||||||
|
// prepare statement to mark wasted DVB events
|
||||||
|
|
||||||
|
cDbValue* endTime = new cDbValue("starttime+duration", cDBS::ffInt, 10);
|
||||||
|
cDbStatement* updateDelFlg = new cDbStatement(epgDb);
|
||||||
|
|
||||||
|
// update events set delflg = ?, updsp = ?
|
||||||
|
// where channelid = ? and source = ?
|
||||||
|
// and starttime+duration > ?
|
||||||
|
// and starttime < ?
|
||||||
|
// and (tableid > ? or (tableid = ? and version <> ?))
|
||||||
|
|
||||||
|
updateDelFlg->build("update %s set ", epgDb->TableName());
|
||||||
|
updateDelFlg->bind(cTableEvents::fiDelFlg, cDBS::bndIn | cDBS::bndSet);
|
||||||
|
updateDelFlg->bind(cTableEvents::fiUpdSp, cDBS::bndIn | cDBS::bndSet, ", ");
|
||||||
|
updateDelFlg->build(" where ");
|
||||||
|
updateDelFlg->bind(cTableEvents::fiChannelId, cDBS::bndIn | cDBS::bndSet);
|
||||||
|
updateDelFlg->bind(cTableEvents::fiSource, cDBS::bndIn | cDBS::bndSet, " and ");
|
||||||
|
|
||||||
|
updateDelFlg->bindCmp(0, endTime, ">", " and ");
|
||||||
|
|
||||||
|
updateDelFlg->bindCmp(0, cTableEvents::fiStartTime, 0, "<" , " and ");
|
||||||
|
updateDelFlg->bindCmp(0, cTableEvents::fiTableId, 0, ">" , " and (");
|
||||||
|
updateDelFlg->bindCmp(0, cTableEvents::fiTableId, 0, "=" , " or (");
|
||||||
|
updateDelFlg->bindCmp(0, cTableEvents::fiVersion, 0, "<>" , " and ");
|
||||||
|
updateDelFlg->build("));");
|
||||||
|
|
||||||
|
updateDelFlg->prepare();
|
||||||
|
|
||||||
|
tell(0, "---------------------------------------------------");
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
//
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
void chkStatement2()
|
||||||
|
{
|
||||||
|
cDbTable* imageRefDb = new cTableImageRefs(connection);
|
||||||
|
cDbTable* imageDb = new cTableImages(connection);
|
||||||
|
|
||||||
|
if (imageRefDb->open() != success)
|
||||||
|
return ;
|
||||||
|
|
||||||
|
if (imageDb->open() != success)
|
||||||
|
return ;
|
||||||
|
|
||||||
|
tell(0, "---------------------------------------------------");
|
||||||
|
|
||||||
|
cDbStatement* selectAllImages = new cDbStatement(imageRefDb);
|
||||||
|
|
||||||
|
cDbValue imageData;
|
||||||
|
imageData.setField(imageDb->getField(cTableImages::fiImage));
|
||||||
|
|
||||||
|
// select r.imagename, r.eventid, r.lfn, i.image from imagerefs r, images i
|
||||||
|
// where r.imagename = i.imagename and i.image is not null;
|
||||||
|
|
||||||
|
selectAllImages->build("select ");
|
||||||
|
selectAllImages->setBindPrefix("r.");
|
||||||
|
selectAllImages->bind(cTableImageRefs::fiImgName, cDBS::bndOut);
|
||||||
|
selectAllImages->bind(cTableImageRefs::fiEventId, cDBS::bndOut, ", ");
|
||||||
|
selectAllImages->bind(cTableImageRefs::fiLfn, cDBS::bndOut, ", ");
|
||||||
|
selectAllImages->setBindPrefix("i.");
|
||||||
|
selectAllImages->bind(&imageData, cDBS::bndOut, ",");
|
||||||
|
selectAllImages->clrBindPrefix();
|
||||||
|
selectAllImages->build(" from %s r, %s i where ", imageRefDb->TableName(), imageDb->TableName());
|
||||||
|
selectAllImages->build("r.%s = i.%s and i.%s is not null;",
|
||||||
|
imageRefDb->getField(cTableImageRefs::fiImgName)->name,
|
||||||
|
imageDb->getField(cTableImages::fiImgName)->name,
|
||||||
|
imageDb->getField(cTableImages::fiImage)->name);
|
||||||
|
|
||||||
|
selectAllImages->prepare();
|
||||||
|
|
||||||
|
|
||||||
|
tell(0, "---------------------------------------------------");
|
||||||
|
|
||||||
|
//delete s;
|
||||||
|
delete imageRefDb;
|
||||||
|
delete imageDb;
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
//
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
void chkStatement3()
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
int lcount = 0;
|
||||||
|
|
||||||
|
cDbTable* epgDb = new cTableEvents(connection);
|
||||||
|
cDbTable* mapDb = new cTableChannelMap(connection);
|
||||||
|
|
||||||
|
if (epgDb->open() != success)
|
||||||
|
return ;
|
||||||
|
|
||||||
|
if (mapDb->open() != success)
|
||||||
|
return ;
|
||||||
|
|
||||||
|
tell(0, "---------------------------------------------------");
|
||||||
|
|
||||||
|
cDbStatement* s = new cDbStatement(epgDb);
|
||||||
|
|
||||||
|
s->build("select ");
|
||||||
|
s->setBindPrefix("e.");
|
||||||
|
s->bind(cTableEvents::fiEventId, cDBS::bndOut);
|
||||||
|
s->bind(cTableEvents::fiChannelId, cDBS::bndOut, ", ");
|
||||||
|
s->bind(cTableEvents::fiSource, cDBS::bndOut, ", ");
|
||||||
|
s->bind(cTableEvents::fiDelFlg, cDBS::bndOut, ", ");
|
||||||
|
s->bind(cTableEvents::fiFileRef, cDBS::bndOut, ", ");
|
||||||
|
s->bind(cTableEvents::fiTableId, cDBS::bndOut, ", ");
|
||||||
|
s->bind(cTableEvents::fiVersion, cDBS::bndOut, ", ");
|
||||||
|
s->bind(cTableEvents::fiTitle, cDBS::bndOut, ", ");
|
||||||
|
s->bind(cTableEvents::fiShortText, cDBS::bndOut, ", ");
|
||||||
|
s->bind(cTableEvents::fiStartTime, cDBS::bndOut, ", ");
|
||||||
|
s->bind(cTableEvents::fiDuration, cDBS::bndOut, ", ");
|
||||||
|
s->bind(cTableEvents::fiParentalRating, cDBS::bndOut, ", ");
|
||||||
|
s->bind(cTableEvents::fiVps, cDBS::bndOut, ", ");
|
||||||
|
s->bind(cTableEvents::fiDescription, cDBS::bndOut, ", ");
|
||||||
|
s->clrBindPrefix();
|
||||||
|
s->build(" from eventsview e, %s m where ", mapDb->TableName());
|
||||||
|
s->build("e.%s = m.%s and e.%s = m.%s and ",
|
||||||
|
epgDb->getField(cTableEvents::fiChannelId)->name,
|
||||||
|
mapDb->getField(cTableChannelMap::fiChannelName)->name,
|
||||||
|
epgDb->getField(cTableEvents::fiSource)->name,
|
||||||
|
mapDb->getField(cTableChannelMap::fiSource)->name);
|
||||||
|
s->bindCmp("e", cTableEvents::fiUpdSp, 0, ">");
|
||||||
|
s->build(" order by m.%s;", mapDb->getField(cTableChannelMap::fiChannelName)->name);
|
||||||
|
|
||||||
|
s->prepare();
|
||||||
|
|
||||||
|
epgDb->clear();
|
||||||
|
epgDb->setValue(cTableEvents::fiUpdSp, (double)0);
|
||||||
|
epgDb->setValue(cTableEvents::fiSource, "vdr"); // used by selectUpdEventsByChannel
|
||||||
|
epgDb->setValue(cTableEvents::fiChannelId, "xxxxxxxxxxxxx"); // used by selectUpdEventsByChannel
|
||||||
|
|
||||||
|
int channels = 0;
|
||||||
|
char chan[100]; *chan = 0;
|
||||||
|
|
||||||
|
tell(0, "---------------------------------------------------");
|
||||||
|
|
||||||
|
for (int found = s->find(); found; found = s->fetch())
|
||||||
|
{
|
||||||
|
if (!*chan || strcmp(chan, epgDb->getStrValue(cTableEvents::fiChannelId)) != 0)
|
||||||
|
{
|
||||||
|
if (*chan)
|
||||||
|
tell(0, "processed %-20s with %d events", chan, count - lcount);
|
||||||
|
|
||||||
|
lcount = count;
|
||||||
|
channels++;
|
||||||
|
strcpy(chan, epgDb->getStrValue(cTableEvents::fiChannelId));
|
||||||
|
|
||||||
|
tell(0, "processing %-20s now", chan);
|
||||||
|
}
|
||||||
|
|
||||||
|
tell(0, "-> '%s' - (%ld)", epgDb->getStrValue(cTableEvents::fiChannelId),
|
||||||
|
epgDb->getIntValue(cTableEvents::fiEventId));
|
||||||
|
|
||||||
|
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
s->freeResult();
|
||||||
|
|
||||||
|
tell(0, "---------------------------------------------------");
|
||||||
|
tell(0, "updated %d channels and %d events", channels, count);
|
||||||
|
tell(0, "---------------------------------------------------");
|
||||||
|
|
||||||
|
delete s;
|
||||||
|
delete epgDb;
|
||||||
|
delete mapDb;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cTimeMs ---------------------------------------------------------------
|
||||||
|
|
||||||
|
cTimeMs::cTimeMs(int Ms)
|
||||||
|
{
|
||||||
|
if (Ms >= 0)
|
||||||
|
Set(Ms);
|
||||||
|
else
|
||||||
|
begin = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t cTimeMs::Now(void)
|
||||||
|
{
|
||||||
|
#define MIN_RESOLUTION 5 // ms
|
||||||
|
static bool initialized = false;
|
||||||
|
static bool monotonic = false;
|
||||||
|
struct timespec tp;
|
||||||
|
if (!initialized) {
|
||||||
|
// check if monotonic timer is available and provides enough accurate resolution:
|
||||||
|
if (clock_getres(CLOCK_MONOTONIC, &tp) == 0) {
|
||||||
|
// long Resolution = tp.tv_nsec;
|
||||||
|
// require a minimum resolution:
|
||||||
|
if (tp.tv_sec == 0 && tp.tv_nsec <= MIN_RESOLUTION * 1000000) {
|
||||||
|
if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) {
|
||||||
|
monotonic = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tell(0, "cTimeMs: clock_gettime(CLOCK_MONOTONIC) failed");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tell(0, "cTimeMs: not using monotonic clock - resolution is too bad (%ld s %ld ns)", tp.tv_sec, tp.tv_nsec);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tell(0, "cTimeMs: clock_getres(CLOCK_MONOTONIC) failed");
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
if (monotonic) {
|
||||||
|
if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
|
||||||
|
return (uint64_t(tp.tv_sec)) * 1000 + tp.tv_nsec / 1000000;
|
||||||
|
tell(0, "cTimeMs: clock_gettime(CLOCK_MONOTONIC) failed");
|
||||||
|
monotonic = false;
|
||||||
|
// fall back to gettimeofday()
|
||||||
|
}
|
||||||
|
struct timeval t;
|
||||||
|
if (gettimeofday(&t, NULL) == 0)
|
||||||
|
return (uint64_t(t.tv_sec)) * 1000 + t.tv_usec / 1000;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cTimeMs::Set(int Ms)
|
||||||
|
{
|
||||||
|
begin = Now() + Ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cTimeMs::TimedOut(void)
|
||||||
|
{
|
||||||
|
return Now() >= begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t cTimeMs::Elapsed(void)
|
||||||
|
{
|
||||||
|
return Now() - begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
//
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
void chkStatement4()
|
||||||
|
{
|
||||||
|
cDbTable* eventDb = new cTableEvents(connection);
|
||||||
|
if (eventDb->open() != success) return;
|
||||||
|
|
||||||
|
cDbTable* imageRefDb = new cTableImageRefs(connection);
|
||||||
|
if (imageRefDb->open() != success) return;
|
||||||
|
|
||||||
|
cDbTable* imageDb = new cTableImages(connection);
|
||||||
|
if (imageDb->open() != success) return;
|
||||||
|
|
||||||
|
// select e.masterid, r.imagename, r.eventid, r.lfn, i.image
|
||||||
|
// from imagerefs r, images i, events e
|
||||||
|
// where r.imagename = i.imagename
|
||||||
|
// and e.eventid = r.eventid,
|
||||||
|
// and i.image is not null
|
||||||
|
// and (i.updsp > ? or r.updsp > ?);
|
||||||
|
|
||||||
|
cDBS::FieldDef masterFld = { "masterid", cDBS::ffUInt, 0, 999, cDBS::ftData };
|
||||||
|
cDbValue masterId;
|
||||||
|
cDbValue imageData;
|
||||||
|
cDbValue imageUpdSp;
|
||||||
|
|
||||||
|
masterId.setField(&masterFld);
|
||||||
|
imageData.setField(imageDb->getField(cTableImages::fiImage));
|
||||||
|
imageUpdSp.setField(imageDb->getField(cTableImages::fiUpdSp));
|
||||||
|
|
||||||
|
cDbStatement* selectAllImages = new cDbStatement(imageRefDb);
|
||||||
|
|
||||||
|
selectAllImages->build("select ");
|
||||||
|
selectAllImages->setBindPrefix("e.");
|
||||||
|
selectAllImages->bind(&masterId, cDBS::bndOut);
|
||||||
|
selectAllImages->setBindPrefix("r.");
|
||||||
|
selectAllImages->bind(cTableImageRefs::fiImgName, cDBS::bndOut, ", ");
|
||||||
|
selectAllImages->bind(cTableImageRefs::fiEventId, cDBS::bndOut, ", ");
|
||||||
|
selectAllImages->bind(cTableImageRefs::fiLfn, cDBS::bndOut, ", ");
|
||||||
|
selectAllImages->setBindPrefix("i.");
|
||||||
|
selectAllImages->bind(&imageData, cDBS::bndOut, ", ");
|
||||||
|
selectAllImages->clrBindPrefix();
|
||||||
|
selectAllImages->build(" from %s r, %s i, %s e where ",
|
||||||
|
imageRefDb->TableName(), imageDb->TableName(), eventDb->TableName());
|
||||||
|
selectAllImages->build("e.%s = r.%s and i.%s = r.%s and i.%s is not null and (",
|
||||||
|
eventDb->getField(cTableEvents::fiEventId)->name,
|
||||||
|
imageRefDb->getField(cTableImageRefs::fiEventId)->name,
|
||||||
|
imageDb->getField(cTableImageRefs::fiImgName)->name,
|
||||||
|
imageRefDb->getField(cTableImageRefs::fiImgName)->name,
|
||||||
|
imageDb->getField(cTableImages::fiImage)->name);
|
||||||
|
selectAllImages->bindCmp("i", &imageUpdSp, ">");
|
||||||
|
selectAllImages->build(" or ");
|
||||||
|
selectAllImages->bindCmp("r", cTableImageRefs::fiUpdSp, 0, ">");
|
||||||
|
selectAllImages->build(");");
|
||||||
|
|
||||||
|
selectAllImages->prepare();
|
||||||
|
|
||||||
|
imageRefDb->clear();
|
||||||
|
imageRefDb->setValue(cTableImageRefs::fiUpdSp, 1377733333L);
|
||||||
|
imageUpdSp.setValue(1377733333L);
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
for (int res = selectAllImages->find(); res; res = selectAllImages->fetch())
|
||||||
|
{
|
||||||
|
count ++;
|
||||||
|
}
|
||||||
|
tell(0,"%d", count);
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// Main
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
EPG2VDRConfig.logstdout = yes;
|
||||||
|
EPG2VDRConfig.loglevel = 2;
|
||||||
|
|
||||||
|
setlocale(LC_CTYPE, "");
|
||||||
|
char* lang = setlocale(LC_CTYPE, 0);
|
||||||
|
|
||||||
|
if (lang)
|
||||||
|
{
|
||||||
|
tell(0, "Set locale to '%s'", lang);
|
||||||
|
|
||||||
|
if ((strcasestr(lang, "UTF-8") != 0) || (strcasestr(lang, "UTF8") != 0))
|
||||||
|
tell(0, "detected UTF-8");
|
||||||
|
else
|
||||||
|
tell(0, "no UTF-8");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tell(0, "Reseting locale for LC_CTYPE failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cDbDict* dict = new cDbDict();
|
||||||
|
|
||||||
|
dict->in("../epg.dat");
|
||||||
|
|
||||||
|
delete dict;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
initConnection();
|
||||||
|
|
||||||
|
chkCompress();
|
||||||
|
|
||||||
|
tell(0, "duration was: '%s'", ms2Dur(2340).c_str());
|
||||||
|
|
||||||
|
// chkStatement1();
|
||||||
|
// chkStatement2();
|
||||||
|
// chkStatement3();
|
||||||
|
// chkStatement4();
|
||||||
|
|
||||||
|
exitConnection();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user