mirror of
				https://projects.vdr-developer.org/git/vdr-plugin-scraper2vdr.git
				synced 2023-10-19 15:58:31 +00:00 
			
		
		
		
	Version 0.1.5 - introduced new DB API
This commit is contained in:
		
							
								
								
									
										3
									
								
								HISTORY
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								HISTORY
									
									
									
									
									
								
							@@ -33,3 +33,6 @@ Version 0.1.3
 | 
			
		||||
 | 
			
		||||
Version 0.1.4
 | 
			
		||||
- 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 <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include <openssl/md5.h> // MD5_*
 | 
			
		||||
@@ -280,5 +281,147 @@ class LogDuration
 | 
			
		||||
      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
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,8 @@
 | 
			
		||||
 | 
			
		||||
#include "common.h"
 | 
			
		||||
 | 
			
		||||
#define EPG_PLUGIN_SEM_KEY 0x3db00001
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Config
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								lib/db.c
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								lib/db.c
									
									
									
									
									
								
							@@ -512,6 +512,7 @@ int   cDbConnection::dbPort = 3306;
 | 
			
		||||
char* cDbConnection::dbUser = 0;
 | 
			
		||||
char* cDbConnection::dbPass = 0;
 | 
			
		||||
char* cDbConnection::dbName = 0;
 | 
			
		||||
Sem*  cDbConnection::sem = 0;
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Object
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										86
									
								
								lib/db.h
									
									
									
									
									
								
							
							
						
						
									
										86
									
								
								lib/db.h
									
									
									
									
									
								
							@@ -8,11 +8,15 @@
 | 
			
		||||
#ifndef __DB_H
 | 
			
		||||
#define __DB_H
 | 
			
		||||
 | 
			
		||||
#include <linux/unistd.h>
 | 
			
		||||
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
 | 
			
		||||
#include <mysql/mysql.h>
 | 
			
		||||
 | 
			
		||||
#include <list>
 | 
			
		||||
@@ -550,13 +554,11 @@ class cDbConnection
 | 
			
		||||
 | 
			
		||||
      virtual ~cDbConnection()
 | 
			
		||||
      {
 | 
			
		||||
         if (mysql) 
 | 
			
		||||
         {
 | 
			
		||||
            mysql_close(mysql);
 | 
			
		||||
            mysql_thread_end();
 | 
			
		||||
         }
 | 
			
		||||
         close();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      int isConnected() { return getMySql() > 0; }
 | 
			
		||||
 | 
			
		||||
      int attachConnection()
 | 
			
		||||
      { 
 | 
			
		||||
         static int first = yes;
 | 
			
		||||
@@ -565,14 +567,16 @@ class cDbConnection
 | 
			
		||||
         {
 | 
			
		||||
            connectDropped = yes;
 | 
			
		||||
 | 
			
		||||
            tell(0, "Calling mysql_init(%ld)", syscall(__NR_gettid));
 | 
			
		||||
 | 
			
		||||
            if (!(mysql = mysql_init(0)))
 | 
			
		||||
               return errorSql(this, "attachConnection(init)");
 | 
			
		||||
 | 
			
		||||
            if (!mysql_real_connect(mysql, dbHost, 
 | 
			
		||||
                                    dbUser, dbPass, dbName, dbPort, 0, 0)) 
 | 
			
		||||
            {
 | 
			
		||||
               mysql_close(mysql);
 | 
			
		||||
               mysql = 0;
 | 
			
		||||
               close();
 | 
			
		||||
 | 
			
		||||
               tell(0, "Error, connecting to database at '%s' on port (%d) failed",
 | 
			
		||||
                    dbHost, dbPort);
 | 
			
		||||
 | 
			
		||||
@@ -601,19 +605,25 @@ class cDbConnection
 | 
			
		||||
         return success; 
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      void detachConnection()
 | 
			
		||||
      void close()
 | 
			
		||||
      {
 | 
			
		||||
         attached--;
 | 
			
		||||
         if (mysql)
 | 
			
		||||
         {
 | 
			
		||||
            tell(0, "Closing mysql connection and calling mysql_thread_end(%ld)", syscall(__NR_gettid));
 | 
			
		||||
 | 
			
		||||
         if (!attached)
 | 
			
		||||
         {
 | 
			
		||||
            mysql_close(mysql);
 | 
			
		||||
            mysql_thread_end();
 | 
			
		||||
            mysql = 0;
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      int isConnected() { return getMySql() > 0; }
 | 
			
		||||
      void detachConnection()
 | 
			
		||||
      { 
 | 
			
		||||
         attached--;
 | 
			
		||||
 | 
			
		||||
         if (!attached)
 | 
			
		||||
            close();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      int check()
 | 
			
		||||
      {
 | 
			
		||||
@@ -724,12 +734,7 @@ class cDbConnection
 | 
			
		||||
      MYSQL* getMySql()
 | 
			
		||||
      {
 | 
			
		||||
         if (connectDropped && mysql)
 | 
			
		||||
         {
 | 
			
		||||
            mysql_close(mysql);
 | 
			
		||||
            mysql_thread_end();
 | 
			
		||||
            mysql = 0;
 | 
			
		||||
            attached = 0;
 | 
			
		||||
         }
 | 
			
		||||
            close();
 | 
			
		||||
 | 
			
		||||
         return mysql; 
 | 
			
		||||
      }
 | 
			
		||||
@@ -758,20 +763,57 @@ class cDbConnection
 | 
			
		||||
 | 
			
		||||
      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 (semKey && !sem)
 | 
			
		||||
            sem = new Sem(semKey);
 | 
			
		||||
 | 
			
		||||
         if (!sem || sem->check() == success)
 | 
			
		||||
         {
 | 
			
		||||
            // call only once per process
 | 
			
		||||
 | 
			
		||||
            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;  // return errorSql(0, "init(library_init)");
 | 
			
		||||
               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;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      static int exit()
 | 
			
		||||
      {
 | 
			
		||||
         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(dbUser);
 | 
			
		||||
         free(dbPass);
 | 
			
		||||
@@ -792,6 +834,8 @@ class cDbConnection
 | 
			
		||||
      int inTact;
 | 
			
		||||
      int connectDropped;
 | 
			
		||||
 | 
			
		||||
      static Sem* sem;
 | 
			
		||||
 | 
			
		||||
      static char* encoding;
 | 
			
		||||
 | 
			
		||||
      // connecting data
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@ const char* logPrefix = "demo";
 | 
			
		||||
 | 
			
		||||
void initConnection()
 | 
			
		||||
{
 | 
			
		||||
   cDbConnection::init();
 | 
			
		||||
   cDbConnection::init(0x3db00012);
 | 
			
		||||
 | 
			
		||||
   cDbConnection::setEncoding("utf8");
 | 
			
		||||
   cDbConnection::setHost("localhost");
 | 
			
		||||
 
 | 
			
		||||
@@ -117,9 +117,9 @@ cDbService::FieldDef cTableEvents::fields[] =
 | 
			
		||||
 | 
			
		||||
   // episodes (constable)
 | 
			
		||||
 | 
			
		||||
   { "episode",          ffAscii,    250, fiEpisode,          ftData },
 | 
			
		||||
   { "episodepart",      ffAscii,    250, fiEpisodePart,      ftData },
 | 
			
		||||
   { "episodelang",      ffAscii,      3, fiEpisodeLang,      ftData },
 | 
			
		||||
//   { "episodecompname",          ffAscii,    250, fiEpisode,          ftData },
 | 
			
		||||
//   { "episodecomppartname",      ffAscii,    250, fiEpisodePart,      ftData },
 | 
			
		||||
//   { "episodelang",      ffAscii,      3, fiEpisodeLang,      ftData },
 | 
			
		||||
 | 
			
		||||
   // tv scraper
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -251,9 +251,9 @@ class cTableEvents : public cDbTable
 | 
			
		||||
         fiExtEpNum,
 | 
			
		||||
         fiImageCount,
 | 
			
		||||
 | 
			
		||||
         fiEpisode,
 | 
			
		||||
         fiEpisodePart,
 | 
			
		||||
         fiEpisodeLang,
 | 
			
		||||
//         fiEpisode,
 | 
			
		||||
//         fiEpisodePart,
 | 
			
		||||
//         fiEpisodeLang,
 | 
			
		||||
 | 
			
		||||
         fiScrSeriesId,
 | 
			
		||||
         fiScrSeriesEpisode,
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@ const char* logPrefix = "test";
 | 
			
		||||
 | 
			
		||||
void initConnection()
 | 
			
		||||
{
 | 
			
		||||
   cDbConnection::init();
 | 
			
		||||
   cDbConnection::init(0x3db00011);
 | 
			
		||||
 | 
			
		||||
   cDbConnection::setEncoding("utf8");
 | 
			
		||||
   cDbConnection::setHost("localhost");
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,10 @@
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "lib/config.h"
 | 
			
		||||
 | 
			
		||||
#include "scraper2vdr.h"
 | 
			
		||||
 | 
			
		||||
const char* logPrefix = LOG_PREFIX;
 | 
			
		||||
 | 
			
		||||
#if defined (APIVERSNUM) && (APIVERSNUM < 10600)
 | 
			
		||||
@@ -80,7 +83,7 @@ eOSState cScraper2VdrPluginMenu::ProcessKey(eKeys key) {
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
cPluginScraper2vdr::cPluginScraper2vdr(void) {
 | 
			
		||||
    cDbConnection::init();
 | 
			
		||||
    cDbConnection::init(EPG_PLUGIN_SEM_KEY);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cPluginScraper2vdr::~cPluginScraper2vdr() {
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Constants
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
static const char *VERSION        = "0.1.4";
 | 
			
		||||
static const char *VERSION        = "0.1.5";
 | 
			
		||||
static const char *DESCRIPTION    = "'scraper2vdr' plugin";
 | 
			
		||||
static const char *MAINMENUENTRY  = "Scraper2Vdr";
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -354,7 +354,7 @@ void cScrapManager::DumpMovies(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++) {
 | 
			
		||||
		sRecordingsKey key = it->first;
 | 
			
		||||
		sEventsValue val = it->second;
 | 
			
		||||
@@ -481,6 +481,7 @@ bool cScrapManager::GetMovie(cMovie *m) {
 | 
			
		||||
 | 
			
		||||
bool cScrapManager::GetPosterBanner(ScraperGetPosterBanner *call) {
 | 
			
		||||
    sEventsValue v;
 | 
			
		||||
    v.episodeId = 0;
 | 
			
		||||
    if (call->event) {
 | 
			
		||||
        sEventsKey k;
 | 
			
		||||
        k.eventId = call->event->EventID();
 | 
			
		||||
@@ -516,6 +517,7 @@ bool cScrapManager::GetPosterBanner(ScraperGetPosterBanner *call) {
 | 
			
		||||
 | 
			
		||||
bool cScrapManager::GetPosterBannerV2(ScraperGetPosterBannerV2 *call) {
 | 
			
		||||
    sEventsValue v;
 | 
			
		||||
    v.episodeId = 0;
 | 
			
		||||
    if (call->event) {
 | 
			
		||||
        sEventsKey k;
 | 
			
		||||
        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() {
 | 
			
		||||
    if (loopActive)
 | 
			
		||||
        Stop();
 | 
			
		||||
    exitDb();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// global field definitions
 | 
			
		||||
@@ -1356,6 +1355,8 @@ void cUpdate::Action()
 | 
			
		||||
 | 
			
		||||
        worked = no;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    exitDb();             // don't call exit in dtor, outside from thread!!
 | 
			
		||||
    loopActive = no;
 | 
			
		||||
    tell(0, "Update thread ended (pid=%d)", getpid());
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user