mirror of
https://projects.vdr-developer.org/git/vdr-plugin-scraper2vdr.git
synced 2023-10-19 17:58:31 +02:00
Version 0.1.5 - introduced new DB API
This commit is contained in:
parent
74969a32d8
commit
f2167b1467
3
HISTORY
3
HISTORY
@ -33,3 +33,6 @@ Version 0.1.3
|
|||||||
|
|
||||||
Version 0.1.4
|
Version 0.1.4
|
||||||
- added ScraperGetPosterBannerV2 Service
|
- added ScraperGetPosterBannerV2 Service
|
||||||
|
|
||||||
|
Versionn 0.1.5
|
||||||
|
- introduced new DB API
|
||||||
|
143
lib/common.h
143
lib/common.h
@ -11,6 +11,7 @@
|
|||||||
#include <stdint.h> // uint_64_t
|
#include <stdint.h> // uint_64_t
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <openssl/md5.h> // MD5_*
|
#include <openssl/md5.h> // MD5_*
|
||||||
@ -280,5 +281,147 @@ class LogDuration
|
|||||||
int logLevel;
|
int logLevel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// Semaphore
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
#include <sys/sem.h>
|
||||||
|
|
||||||
|
class Sem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
Sem(key_t aKey)
|
||||||
|
{
|
||||||
|
locked = no;
|
||||||
|
key = aKey;
|
||||||
|
|
||||||
|
if ((id = semget(key, 1, 0666 | IPC_CREAT)) == -1)
|
||||||
|
tell(0, "Error: Can't get semaphore, errno (%d) '%s'",
|
||||||
|
errno, strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
~Sem()
|
||||||
|
{
|
||||||
|
if (locked)
|
||||||
|
v();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------
|
||||||
|
// get lock
|
||||||
|
|
||||||
|
int p()
|
||||||
|
{
|
||||||
|
sembuf sops[2];
|
||||||
|
|
||||||
|
sops[0].sem_num = 0;
|
||||||
|
sops[0].sem_op = 0; // wait for lock
|
||||||
|
sops[0].sem_flg = SEM_UNDO;
|
||||||
|
|
||||||
|
sops[1].sem_num = 0;
|
||||||
|
sops[1].sem_op = 1; // increment
|
||||||
|
sops[1].sem_flg = SEM_UNDO | IPC_NOWAIT;
|
||||||
|
|
||||||
|
if (semop(id, sops, 2) == -1)
|
||||||
|
{
|
||||||
|
tell(0, "Error: Can't lock semaphore, errno (%d) '%s'",
|
||||||
|
errno, strerror(errno));
|
||||||
|
|
||||||
|
return fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
locked = yes;
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------
|
||||||
|
// increment
|
||||||
|
|
||||||
|
int inc()
|
||||||
|
{
|
||||||
|
sembuf sops[1];
|
||||||
|
|
||||||
|
sops[0].sem_num = 0;
|
||||||
|
sops[0].sem_op = 1; // increment
|
||||||
|
sops[0].sem_flg = SEM_UNDO | IPC_NOWAIT;
|
||||||
|
|
||||||
|
if (semop(id, sops, 1) == -1)
|
||||||
|
{
|
||||||
|
if (errno != EAGAIN)
|
||||||
|
tell(0, "Error: Can't lock semaphore, errno was (%d) '%s'",
|
||||||
|
errno, strerror(errno));
|
||||||
|
|
||||||
|
return fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
locked = yes;
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------
|
||||||
|
// decrement
|
||||||
|
|
||||||
|
int dec()
|
||||||
|
{
|
||||||
|
return v();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------
|
||||||
|
// check
|
||||||
|
|
||||||
|
int check()
|
||||||
|
{
|
||||||
|
sembuf sops[1];
|
||||||
|
|
||||||
|
sops[0].sem_num = 0;
|
||||||
|
sops[0].sem_op = 0;
|
||||||
|
sops[0].sem_flg = SEM_UNDO | IPC_NOWAIT;
|
||||||
|
|
||||||
|
if (semop(id, sops, 1) == -1)
|
||||||
|
{
|
||||||
|
if (errno != EAGAIN)
|
||||||
|
tell(0, "Error: Can't lock semaphore, errno was (%d) '%s'",
|
||||||
|
errno, strerror(errno));
|
||||||
|
|
||||||
|
return fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------
|
||||||
|
// release lock
|
||||||
|
|
||||||
|
int v()
|
||||||
|
{
|
||||||
|
sembuf sops;
|
||||||
|
|
||||||
|
sops.sem_num = 0;
|
||||||
|
sops.sem_op = -1; // release control
|
||||||
|
sops.sem_flg = SEM_UNDO | IPC_NOWAIT;
|
||||||
|
|
||||||
|
if (semop(id, &sops, 1) == -1)
|
||||||
|
{
|
||||||
|
if (errno != EAGAIN)
|
||||||
|
tell(0, "Error: Can't unlock semaphore, errno (%d) '%s'",
|
||||||
|
errno, strerror(errno));
|
||||||
|
|
||||||
|
return fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
locked = no;
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
key_t key;
|
||||||
|
int id;
|
||||||
|
int locked;
|
||||||
|
};
|
||||||
|
|
||||||
//***************************************************************************
|
//***************************************************************************
|
||||||
#endif //___COMMON_H
|
#endif //___COMMON_H
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
#define EPG_PLUGIN_SEM_KEY 0x3db00001
|
||||||
|
|
||||||
//***************************************************************************
|
//***************************************************************************
|
||||||
// Config
|
// Config
|
||||||
//***************************************************************************
|
//***************************************************************************
|
||||||
|
1
lib/db.c
1
lib/db.c
@ -512,6 +512,7 @@ int cDbConnection::dbPort = 3306;
|
|||||||
char* cDbConnection::dbUser = 0;
|
char* cDbConnection::dbUser = 0;
|
||||||
char* cDbConnection::dbPass = 0;
|
char* cDbConnection::dbPass = 0;
|
||||||
char* cDbConnection::dbName = 0;
|
char* cDbConnection::dbName = 0;
|
||||||
|
Sem* cDbConnection::sem = 0;
|
||||||
|
|
||||||
//***************************************************************************
|
//***************************************************************************
|
||||||
// Object
|
// Object
|
||||||
|
94
lib/db.h
94
lib/db.h
@ -8,11 +8,15 @@
|
|||||||
#ifndef __DB_H
|
#ifndef __DB_H
|
||||||
#define __DB_H
|
#define __DB_H
|
||||||
|
|
||||||
|
#include <linux/unistd.h>
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include <mysql/mysql.h>
|
#include <mysql/mysql.h>
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
@ -550,13 +554,11 @@ class cDbConnection
|
|||||||
|
|
||||||
virtual ~cDbConnection()
|
virtual ~cDbConnection()
|
||||||
{
|
{
|
||||||
if (mysql)
|
close();
|
||||||
{
|
|
||||||
mysql_close(mysql);
|
|
||||||
mysql_thread_end();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int isConnected() { return getMySql() > 0; }
|
||||||
|
|
||||||
int attachConnection()
|
int attachConnection()
|
||||||
{
|
{
|
||||||
static int first = yes;
|
static int first = yes;
|
||||||
@ -565,14 +567,16 @@ class cDbConnection
|
|||||||
{
|
{
|
||||||
connectDropped = yes;
|
connectDropped = yes;
|
||||||
|
|
||||||
|
tell(0, "Calling mysql_init(%ld)", syscall(__NR_gettid));
|
||||||
|
|
||||||
if (!(mysql = mysql_init(0)))
|
if (!(mysql = mysql_init(0)))
|
||||||
return errorSql(this, "attachConnection(init)");
|
return errorSql(this, "attachConnection(init)");
|
||||||
|
|
||||||
if (!mysql_real_connect(mysql, dbHost,
|
if (!mysql_real_connect(mysql, dbHost,
|
||||||
dbUser, dbPass, dbName, dbPort, 0, 0))
|
dbUser, dbPass, dbName, dbPort, 0, 0))
|
||||||
{
|
{
|
||||||
mysql_close(mysql);
|
close();
|
||||||
mysql = 0;
|
|
||||||
tell(0, "Error, connecting to database at '%s' on port (%d) failed",
|
tell(0, "Error, connecting to database at '%s' on port (%d) failed",
|
||||||
dbHost, dbPort);
|
dbHost, dbPort);
|
||||||
|
|
||||||
@ -601,19 +605,25 @@ class cDbConnection
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
void detachConnection()
|
void close()
|
||||||
{
|
{
|
||||||
attached--;
|
if (mysql)
|
||||||
|
|
||||||
if (!attached)
|
|
||||||
{
|
{
|
||||||
|
tell(0, "Closing mysql connection and calling mysql_thread_end(%ld)", syscall(__NR_gettid));
|
||||||
|
|
||||||
mysql_close(mysql);
|
mysql_close(mysql);
|
||||||
mysql_thread_end();
|
mysql_thread_end();
|
||||||
mysql = 0;
|
mysql = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int isConnected() { return getMySql() > 0; }
|
void detachConnection()
|
||||||
|
{
|
||||||
|
attached--;
|
||||||
|
|
||||||
|
if (!attached)
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
int check()
|
int check()
|
||||||
{
|
{
|
||||||
@ -724,12 +734,7 @@ class cDbConnection
|
|||||||
MYSQL* getMySql()
|
MYSQL* getMySql()
|
||||||
{
|
{
|
||||||
if (connectDropped && mysql)
|
if (connectDropped && mysql)
|
||||||
{
|
close();
|
||||||
mysql_close(mysql);
|
|
||||||
mysql_thread_end();
|
|
||||||
mysql = 0;
|
|
||||||
attached = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mysql;
|
return mysql;
|
||||||
}
|
}
|
||||||
@ -756,22 +761,59 @@ class cDbConnection
|
|||||||
|
|
||||||
int errorSql(cDbConnection* mysql, const char* prefix, MYSQL_STMT* stmt = 0, const char* stmtTxt = 0);
|
int errorSql(cDbConnection* mysql, const char* prefix, MYSQL_STMT* stmt = 0, const char* stmtTxt = 0);
|
||||||
|
|
||||||
void showStat(const char* name = "") { statements.showStat(name); }
|
void showStat(const char* name = "") { statements.showStat(name); }
|
||||||
|
|
||||||
static int init()
|
// -----------------------------------------------------------
|
||||||
|
// init() and exit() must exactly called 'once' per process
|
||||||
|
|
||||||
|
static int init(key_t semKey)
|
||||||
{
|
{
|
||||||
if (mysql_library_init(0, 0, 0))
|
if (semKey && !sem)
|
||||||
|
sem = new Sem(semKey);
|
||||||
|
|
||||||
|
if (!sem || sem->check() == success)
|
||||||
{
|
{
|
||||||
tell(0, "Error: mysql_library_init failed");
|
// call only once per process
|
||||||
return fail; // return errorSql(0, "init(library_init)");
|
|
||||||
|
if (sem)
|
||||||
|
tell(1, "Info: Calling mysql_library_init()");
|
||||||
|
|
||||||
|
if (mysql_library_init(0, 0, 0))
|
||||||
|
{
|
||||||
|
tell(0, "Error: mysql_library_init() failed");
|
||||||
|
return fail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else if (sem)
|
||||||
|
{
|
||||||
|
tell(1, "Info: Skipping calling mysql_library_init(), it's already done!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sem)
|
||||||
|
sem->inc(); // count usage per process
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int exit()
|
static int exit()
|
||||||
{
|
{
|
||||||
mysql_library_end();
|
mysql_thread_end();
|
||||||
|
|
||||||
|
if (sem)
|
||||||
|
sem->dec();
|
||||||
|
|
||||||
|
if (!sem || sem->check() == success)
|
||||||
|
{
|
||||||
|
if (sem)
|
||||||
|
tell(1, "Info: Released the last usage of mysql_lib, calling mysql_library_end() now");
|
||||||
|
|
||||||
|
mysql_library_end();
|
||||||
|
}
|
||||||
|
else if (sem)
|
||||||
|
{
|
||||||
|
tell(1, "Info: The mysql_lib is still in use, skipping mysql_library_end() call");
|
||||||
|
}
|
||||||
|
|
||||||
free(dbHost);
|
free(dbHost);
|
||||||
free(dbUser);
|
free(dbUser);
|
||||||
free(dbPass);
|
free(dbPass);
|
||||||
@ -792,6 +834,8 @@ class cDbConnection
|
|||||||
int inTact;
|
int inTact;
|
||||||
int connectDropped;
|
int connectDropped;
|
||||||
|
|
||||||
|
static Sem* sem;
|
||||||
|
|
||||||
static char* encoding;
|
static char* encoding;
|
||||||
|
|
||||||
// connecting data
|
// connecting data
|
||||||
|
@ -15,7 +15,7 @@ const char* logPrefix = "demo";
|
|||||||
|
|
||||||
void initConnection()
|
void initConnection()
|
||||||
{
|
{
|
||||||
cDbConnection::init();
|
cDbConnection::init(0x3db00012);
|
||||||
|
|
||||||
cDbConnection::setEncoding("utf8");
|
cDbConnection::setEncoding("utf8");
|
||||||
cDbConnection::setHost("localhost");
|
cDbConnection::setHost("localhost");
|
||||||
|
@ -117,9 +117,9 @@ cDbService::FieldDef cTableEvents::fields[] =
|
|||||||
|
|
||||||
// episodes (constable)
|
// episodes (constable)
|
||||||
|
|
||||||
{ "episode", ffAscii, 250, fiEpisode, ftData },
|
// { "episodecompname", ffAscii, 250, fiEpisode, ftData },
|
||||||
{ "episodepart", ffAscii, 250, fiEpisodePart, ftData },
|
// { "episodecomppartname", ffAscii, 250, fiEpisodePart, ftData },
|
||||||
{ "episodelang", ffAscii, 3, fiEpisodeLang, ftData },
|
// { "episodelang", ffAscii, 3, fiEpisodeLang, ftData },
|
||||||
|
|
||||||
// tv scraper
|
// tv scraper
|
||||||
|
|
||||||
|
@ -251,9 +251,9 @@ class cTableEvents : public cDbTable
|
|||||||
fiExtEpNum,
|
fiExtEpNum,
|
||||||
fiImageCount,
|
fiImageCount,
|
||||||
|
|
||||||
fiEpisode,
|
// fiEpisode,
|
||||||
fiEpisodePart,
|
// fiEpisodePart,
|
||||||
fiEpisodeLang,
|
// fiEpisodeLang,
|
||||||
|
|
||||||
fiScrSeriesId,
|
fiScrSeriesId,
|
||||||
fiScrSeriesEpisode,
|
fiScrSeriesEpisode,
|
||||||
|
@ -21,7 +21,7 @@ const char* logPrefix = "test";
|
|||||||
|
|
||||||
void initConnection()
|
void initConnection()
|
||||||
{
|
{
|
||||||
cDbConnection::init();
|
cDbConnection::init(0x3db00011);
|
||||||
|
|
||||||
cDbConnection::setEncoding("utf8");
|
cDbConnection::setEncoding("utf8");
|
||||||
cDbConnection::setHost("localhost");
|
cDbConnection::setHost("localhost");
|
||||||
|
@ -6,7 +6,10 @@
|
|||||||
* $Id$
|
* $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "lib/config.h"
|
||||||
|
|
||||||
#include "scraper2vdr.h"
|
#include "scraper2vdr.h"
|
||||||
|
|
||||||
const char* logPrefix = LOG_PREFIX;
|
const char* logPrefix = LOG_PREFIX;
|
||||||
|
|
||||||
#if defined (APIVERSNUM) && (APIVERSNUM < 10600)
|
#if defined (APIVERSNUM) && (APIVERSNUM < 10600)
|
||||||
@ -80,7 +83,7 @@ eOSState cScraper2VdrPluginMenu::ProcessKey(eKeys key) {
|
|||||||
//***************************************************************************
|
//***************************************************************************
|
||||||
|
|
||||||
cPluginScraper2vdr::cPluginScraper2vdr(void) {
|
cPluginScraper2vdr::cPluginScraper2vdr(void) {
|
||||||
cDbConnection::init();
|
cDbConnection::init(EPG_PLUGIN_SEM_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
cPluginScraper2vdr::~cPluginScraper2vdr() {
|
cPluginScraper2vdr::~cPluginScraper2vdr() {
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
//***************************************************************************
|
//***************************************************************************
|
||||||
// Constants
|
// Constants
|
||||||
//***************************************************************************
|
//***************************************************************************
|
||||||
static const char *VERSION = "0.1.4";
|
static const char *VERSION = "0.1.5";
|
||||||
static const char *DESCRIPTION = "'scraper2vdr' plugin";
|
static const char *DESCRIPTION = "'scraper2vdr' plugin";
|
||||||
static const char *MAINMENUENTRY = "Scraper2Vdr";
|
static const char *MAINMENUENTRY = "Scraper2Vdr";
|
||||||
|
|
||||||
|
@ -354,7 +354,7 @@ void cScrapManager::DumpMovies(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cScrapManager::DumpRecordings(void) {
|
void cScrapManager::DumpRecordings(void) {
|
||||||
tell(0, "%d recordings in memory:", recordings.size());
|
tell(0, "%ld recordings in memory:", recordings.size());
|
||||||
for (map<sRecordingsKey, sEventsValue>::iterator it = recordings.begin(); it != recordings.end(); it++) {
|
for (map<sRecordingsKey, sEventsValue>::iterator it = recordings.begin(); it != recordings.end(); it++) {
|
||||||
sRecordingsKey key = it->first;
|
sRecordingsKey key = it->first;
|
||||||
sEventsValue val = it->second;
|
sEventsValue val = it->second;
|
||||||
@ -481,6 +481,7 @@ bool cScrapManager::GetMovie(cMovie *m) {
|
|||||||
|
|
||||||
bool cScrapManager::GetPosterBanner(ScraperGetPosterBanner *call) {
|
bool cScrapManager::GetPosterBanner(ScraperGetPosterBanner *call) {
|
||||||
sEventsValue v;
|
sEventsValue v;
|
||||||
|
v.episodeId = 0;
|
||||||
if (call->event) {
|
if (call->event) {
|
||||||
sEventsKey k;
|
sEventsKey k;
|
||||||
k.eventId = call->event->EventID();
|
k.eventId = call->event->EventID();
|
||||||
@ -516,6 +517,7 @@ bool cScrapManager::GetPosterBanner(ScraperGetPosterBanner *call) {
|
|||||||
|
|
||||||
bool cScrapManager::GetPosterBannerV2(ScraperGetPosterBannerV2 *call) {
|
bool cScrapManager::GetPosterBannerV2(ScraperGetPosterBannerV2 *call) {
|
||||||
sEventsValue v;
|
sEventsValue v;
|
||||||
|
v.episodeId = 0;
|
||||||
if (call->event) {
|
if (call->event) {
|
||||||
sEventsKey k;
|
sEventsKey k;
|
||||||
k.eventId = call->event->EventID();
|
k.eventId = call->event->EventID();
|
||||||
|
3
update.c
3
update.c
@ -77,7 +77,6 @@ cUpdate::cUpdate(cScrapManager *manager) : cThread("update thread started", true
|
|||||||
cUpdate::~cUpdate() {
|
cUpdate::~cUpdate() {
|
||||||
if (loopActive)
|
if (loopActive)
|
||||||
Stop();
|
Stop();
|
||||||
exitDb();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// global field definitions
|
// global field definitions
|
||||||
@ -1356,6 +1355,8 @@ void cUpdate::Action()
|
|||||||
|
|
||||||
worked = no;
|
worked = no;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exitDb(); // don't call exit in dtor, outside from thread!!
|
||||||
loopActive = no;
|
loopActive = no;
|
||||||
tell(0, "Update thread ended (pid=%d)", getpid());
|
tell(0, "Update thread ended (pid=%d)", getpid());
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user