summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJochen Dolze <vdr@dolze.de>2012-04-21 10:15:21 +0200
committerJochen Dolze <vdr@dolze.de>2012-04-21 10:15:21 +0200
commit67c3cadd815a179880f44470eff16032d2cfb2fd (patch)
tree6e7a5b44f79b9cbd3a07f9f16115f68c2a5da1ec
parentf0f09d02993596a3f3620c2c7de23a53b3303078 (diff)
downloadvdr-plugin-xmltv2vdr-67c3cadd815a179880f44470eff16032d2cfb2fd.tar.gz
vdr-plugin-xmltv2vdr-67c3cadd815a179880f44470eff16032d2cfb2fd.tar.bz2
Added logging to file with -l
-rw-r--r--import.cpp712
-rw-r--r--import.h19
-rw-r--r--parse.cpp55
-rw-r--r--source.cpp175
-rw-r--r--source.h14
-rw-r--r--xmltv2vdr.cpp517
-rw-r--r--xmltv2vdr.h66
7 files changed, 711 insertions, 847 deletions
diff --git a/import.cpp b/import.cpp
index c63de59..1282275 100644
--- a/import.cpp
+++ b/import.cpp
@@ -19,6 +19,7 @@
#include "xmltv2vdr.h"
#include "import.h"
#include "event.h"
+#include "debug.h"
extern char *strcatrealloc(char *, const char*);
@@ -172,7 +173,7 @@ cEvent *cImport::SearchVDREvent(cEPGSource *source, cSchedule* schedule, cXMLTVE
if (diff<=maxdiff)
{
if (!WasChanged(p))
- source->Tlog("found '%s' for '%s'",p->Title(),conv->Convert(xevent->Title()));
+ tsyslogs(source,"found '%s' for '%s'",p->Title(),conv->Convert(xevent->Title()));
f=p;
maxdiff=diff;
}
@@ -239,10 +240,33 @@ char *cImport::Add2Description(char *description, const char *Name, int Value)
return description;
}
-char *cImport::AddEOT2Description(char *description)
+char *cImport::AddEOT2Description(char *description, bool checkutf8)
{
- const char nbsp[]={0xc2,0xa0,0};
- description=strcatrealloc(description,nbsp);
+ const char nbspUTF8[]={0xc2,0xa0,0};
+ const char nbsp[]={0xa0,0};
+
+ if (checkutf8)
+ {
+ if (!codeset)
+ {
+ description=strcatrealloc(description,nbspUTF8);
+ }
+ else
+ {
+ if (strncasecmp(codeset,"UTF-8",5))
+ {
+ description=strcatrealloc(description,nbsp);
+ }
+ else
+ {
+ description=strcatrealloc(description,nbspUTF8);
+ }
+ }
+ }
+ else
+ {
+ description=strcatrealloc(description,nbspUTF8);
+ }
return description;
}
@@ -250,14 +274,12 @@ bool cImport::WasChanged(cEvent* Event)
{
if (!Event) return false;
if (!Event->Description()) return false;
- int len=strlen(Event->Description());
- if (len<1) return false;
- if ((uchar)(Event->Description()[len-1])==0xA0) return true;
- return false;
+ if (!strchr(Event->Description(),0xA0)) return false;
+ return true;
}
bool cImport::PutEvent(cEPGSource *Source, sqlite3 *Db, cSchedule* Schedule,
- cEvent *Event, cXMLTVEvent *xEvent,int Flags, int Option)
+ cEvent *Event, cXMLTVEvent *xEvent,int Flags)
{
if (!Source) return false;
if (!Db) return false;
@@ -295,7 +317,7 @@ bool cImport::PutEvent(cEPGSource *Source, sqlite3 *Db, cSchedule* Schedule,
strftime(from,sizeof(from)-1,"%b %d %H:%M",&tm);
localtime_r(&end,&tm);
strftime(till,sizeof(till)-1,"%b %d %H:%M",&tm);
- Source->Elog("cannot add '%s'@%s-%s",xEvent->Title(),from,till);
+ esyslogs(Source,"cannot add '%s'@%s-%s",xEvent->Title(),from,till);
time_t pstart=prev->StartTime();
time_t pstop=prev->EndTime();
@@ -303,7 +325,7 @@ bool cImport::PutEvent(cEPGSource *Source, sqlite3 *Db, cSchedule* Schedule,
strftime(from,sizeof(from)-1,"%b %d %H:%M",&tm);
localtime_r(&pstop,&tm);
strftime(till,sizeof(till)-1,"%b %d %H:%M",&tm);
- Source->Elog("found '%s'@%s-%s",prev->Title(),from,till);
+ esyslogs(Source,"found '%s'@%s-%s",prev->Title(),from,till);
time_t nstart=next->StartTime();
time_t nstop=next->EndTime();
@@ -311,7 +333,7 @@ bool cImport::PutEvent(cEPGSource *Source, sqlite3 *Db, cSchedule* Schedule,
strftime(from,sizeof(from)-1,"%b %d %H:%M",&tm);
localtime_r(&nstop,&tm);
strftime(till,sizeof(till)-1,"%b %d %H:%M",&tm);
- Source->Elog("found '%s'@%s-%s",next->Title(),from,till);
+ esyslogs(Source,"found '%s'@%s-%s",next->Title(),from,till);
return false;
}
@@ -325,7 +347,7 @@ bool cImport::PutEvent(cEPGSource *Source, sqlite3 *Db, cSchedule* Schedule,
strftime(from,sizeof(from)-1,"%b %d %H:%M",&tm);
localtime_r(&end,&tm);
strftime(till,sizeof(till)-1,"%b %d %H:%M",&tm);
- Source->Elog("cannot add '%s'@%s-%s",xEvent->Title(),from,till);
+ esyslogs(Source,"cannot add '%s'@%s-%s",xEvent->Title(),from,till);
time_t nstart=next->StartTime();
time_t nstop=next->EndTime();
@@ -333,7 +355,7 @@ bool cImport::PutEvent(cEPGSource *Source, sqlite3 *Db, cSchedule* Schedule,
strftime(from,sizeof(from)-1,"%b %d %H:%M",&tm);
localtime_r(&nstop,&tm);
strftime(till,sizeof(till)-1,"%b %d %H:%M",&tm);
- Source->Elog("found '%s'@%s-%s",next->Title(),from,till);
+ esyslogs(Source,"found '%s'@%s-%s",next->Title(),from,till);
return false;
}
else
@@ -352,7 +374,7 @@ bool cImport::PutEvent(cEPGSource *Source, sqlite3 *Db, cSchedule* Schedule,
strftime(from,sizeof(from)-1,"%b %d %H:%M",&tm);
localtime_r(&end,&tm);
strftime(till,sizeof(till)-1,"%b %d %H:%M",&tm);
- Source->Elog("cannot add '%s'@%s-%s",xEvent->Title(),from,till);
+ esyslogs(Source,"cannot add '%s'@%s-%s",xEvent->Title(),from,till);
time_t pstart=prev->StartTime();
time_t pstop=prev->EndTime();
@@ -360,7 +382,7 @@ bool cImport::PutEvent(cEPGSource *Source, sqlite3 *Db, cSchedule* Schedule,
strftime(from,sizeof(from)-1,"%b %d %H:%M",&tm);
localtime_r(&pstop,&tm);
strftime(till,sizeof(till)-1,"%b %d %H:%M",&tm);
- Source->Elog("found '%s'@%s-%s",prev->Title(),from,till);
+ esyslogs(Source,"found '%s'@%s-%s",prev->Title(),from,till);
return false;
}
else
@@ -387,11 +409,14 @@ bool cImport::PutEvent(cEPGSource *Source, sqlite3 *Db, cSchedule* Schedule,
Event->SetTableID(0);
Schedule->AddEvent(Event);
Schedule->Sort();
- localtime_r(&start,&tm);
- strftime(from,sizeof(from)-1,"%b %d %H:%M",&tm);
- localtime_r(&end,&tm);
- strftime(till,sizeof(till)-1,"%b %d %H:%M",&tm);
- Source->Tlog("adding '%s'@%s-%s",xEvent->Title(),from,till);
+ if (Source->Trace())
+ {
+ localtime_r(&start,&tm);
+ strftime(from,sizeof(from)-1,"%b %d %H:%M",&tm);
+ localtime_r(&end,&tm);
+ strftime(till,sizeof(till)-1,"%b %d %H:%M",&tm);
+ tsyslogs(Source,"adding '%s'@%s-%s",xEvent->Title(),from,till);
+ }
}
else
{
@@ -406,7 +431,7 @@ bool cImport::PutEvent(cEPGSource *Source, sqlite3 *Db, cSchedule* Schedule,
{
if (!strcasecmp(xEvent->ShortText(),Event->Title()))
{
- Source->Tlog("title and subtitle equal, clearing subtitle");
+ tsyslogs(Source,"title and subtitle equal, clearing subtitle");
Event->SetShortText(NULL);
}
else
@@ -421,309 +446,306 @@ bool cImport::PutEvent(cEPGSource *Source, sqlite3 *Db, cSchedule* Schedule,
}
}
- if (Option!=IMPORT_SHORTTEXT)
+ char *description=NULL;
+ if (((Flags & USE_LONGTEXT)==USE_LONGTEXT) || ((Flags & OPT_APPEND)==OPT_APPEND))
{
- char *description=NULL;
- if (((Flags & USE_LONGTEXT)==USE_LONGTEXT) || ((Flags & OPT_APPEND)==OPT_APPEND))
+ if (xEvent->Description() && (strlen(xEvent->Description())>0))
{
- if (xEvent->Description() && (strlen(xEvent->Description())>0))
- {
- description=strdup(xEvent->Description());
- }
+ description=strdup(xEvent->Description());
}
+ }
- if (!description && xEvent->EITDescription() && (strlen(xEvent->EITDescription())>0))
- {
- description=strdup(xEvent->EITDescription());
- }
+ if (!description && xEvent->EITDescription() && (strlen(xEvent->EITDescription())>0))
+ {
+ description=strdup(xEvent->EITDescription());
+ }
- if (!description && Event->Description() && (strlen(Event->Description())>0))
- {
- if (WasChanged(Event)) return true;
- UpdateXMLTVEvent(Source,Db,Event,xEvent->EventID(),Event->EventID(),Event->Description());
- description=strdup(Event->Description());
- }
+ if (!description && Event->Description() && (strlen(Event->Description())>0))
+ {
+ if (WasChanged(Event)) return true;
+ UpdateXMLTVEvent(Source,Db,Event,xEvent);
+ description=strdup(Event->Description());
+ }
- if (description) description=Add2Description(description,"\n");
+ if (description) description=Add2Description(description,"\n");
- if ((Flags & USE_CREDITS)==USE_CREDITS)
+ if ((Flags & USE_CREDITS)==USE_CREDITS)
+ {
+ cXMLTVStringList *credits=xEvent->Credits();
+ if (credits->Size())
{
- cXMLTVStringList *credits=xEvent->Credits();
- if (credits->Size())
+ cTEXTMapping *oldtext=NULL;
+ for (int i=0; i<credits->Size(); i++)
{
- cTEXTMapping *oldtext=NULL;
- for (int i=0; i<credits->Size(); i++)
+ char *ctype=strdup((*credits)[i]);
+ if (ctype)
{
- char *ctype=strdup((*credits)[i]);
- if (ctype)
+ char *cval=strchr(ctype,'|');
+ if (cval)
{
- char *cval=strchr(ctype,'|');
- if (cval)
+ *cval=0;
+ cval++;
+ bool add=true;
+ if (((Flags & CREDITS_ACTORS)!=CREDITS_ACTORS) &&
+ (!strcasecmp(ctype,"actor"))) add=false;
+ if (((Flags & CREDITS_DIRECTORS)!=CREDITS_DIRECTORS) &&
+ (!strcasecmp(ctype,"director"))) add=false;
+ if (((Flags & CREDITS_OTHERS)!=CREDITS_OTHERS) &&
+ (add) && (strcasecmp(ctype,"actor")) &&
+ (strcasecmp(ctype,"director"))) add=false;
+ if (add)
{
- *cval=0;
- cval++;
- bool add=true;
- if (((Flags & CREDITS_ACTORS)!=CREDITS_ACTORS) &&
- (!strcasecmp(ctype,"actor"))) add=false;
- if (((Flags & CREDITS_DIRECTORS)!=CREDITS_DIRECTORS) &&
- (!strcasecmp(ctype,"director"))) add=false;
- if (((Flags & CREDITS_OTHERS)!=CREDITS_OTHERS) &&
- (add) && (strcasecmp(ctype,"actor")) &&
- (strcasecmp(ctype,"director"))) add=false;
- if (add)
+ cTEXTMapping *text=texts->GetMap(ctype);
+ if ((Flags & CREDITS_LIST)==CREDITS_LIST)
{
- cTEXTMapping *text=texts->GetMap(ctype);
- if ((Flags & CREDITS_LIST)==CREDITS_LIST)
+ if (oldtext!=text)
{
- if (oldtext!=text)
+ if (oldtext)
{
- if (oldtext)
- {
- description=RemoveLastCharFromDescription(description);
- description=RemoveLastCharFromDescription(description);
- description=Add2Description(description,"\n");
- }
- description=Add2Description(description,text->Value());
- description=Add2Description(description,": ");
+ description=RemoveLastCharFromDescription(description);
+ description=RemoveLastCharFromDescription(description);
+ description=Add2Description(description,"\n");
}
- description=Add2Description(description,cval);
- description=Add2Description(description,", ");
+ description=Add2Description(description,text->Value());
+ description=Add2Description(description,": ");
}
- else
+ description=Add2Description(description,cval);
+ description=Add2Description(description,", ");
+ }
+ else
+ {
+ if (text)
{
- if (text)
- {
- description=Add2Description(description,text->Value(),cval);
- }
+ description=Add2Description(description,text->Value(),cval);
}
- oldtext=text;
}
+ oldtext=text;
}
- free(ctype);
}
- }
- if ((oldtext) && ((Flags & CREDITS_LIST)==CREDITS_LIST))
- {
- description=RemoveLastCharFromDescription(description);
- description=RemoveLastCharFromDescription(description);
- description=Add2Description(description,"\n");
+ free(ctype);
}
}
- }
-
- if ((Flags & USE_COUNTRYDATE)==USE_COUNTRYDATE)
- {
- if (xEvent->Country())
+ if ((oldtext) && ((Flags & CREDITS_LIST)==CREDITS_LIST))
{
- cTEXTMapping *text=texts->GetMap("country");
- if (text) description=Add2Description(description,text->Value(),xEvent->Country());
+ description=RemoveLastCharFromDescription(description);
+ description=RemoveLastCharFromDescription(description);
+ description=Add2Description(description,"\n");
}
+ }
+ }
- if (xEvent->Year())
- {
- cTEXTMapping *text=texts->GetMap("year");
- if (text) description=Add2Description(description,text->Value(),xEvent->Year());
- }
+ if ((Flags & USE_COUNTRYDATE)==USE_COUNTRYDATE)
+ {
+ if (xEvent->Country())
+ {
+ cTEXTMapping *text=texts->GetMap("country");
+ if (text) description=Add2Description(description,text->Value(),xEvent->Country());
}
- if (((Flags & USE_ORIGTITLE)==USE_ORIGTITLE) && (xEvent->OrigTitle()))
+
+ if (xEvent->Year())
{
- cTEXTMapping *text=texts->GetMap("originaltitle");
- if (text) description=Add2Description(description,text->Value(),xEvent->OrigTitle());
+ cTEXTMapping *text=texts->GetMap("year");
+ if (text) description=Add2Description(description,text->Value(),xEvent->Year());
}
- if (((Flags & USE_CATEGORIES)==USE_CATEGORIES) && (xEvent->Category()->Size()))
+ }
+ if (((Flags & USE_ORIGTITLE)==USE_ORIGTITLE) && (xEvent->OrigTitle()))
+ {
+ cTEXTMapping *text=texts->GetMap("originaltitle");
+ if (text) description=Add2Description(description,text->Value(),xEvent->OrigTitle());
+ }
+ if (((Flags & USE_CATEGORIES)==USE_CATEGORIES) && (xEvent->Category()->Size()))
+ {
+ cTEXTMapping *text=texts->GetMap("category");
+ if (text)
{
- cTEXTMapping *text=texts->GetMap("category");
- if (text)
+ cXMLTVStringList *categories=xEvent->Category();
+ description=Add2Description(description,text->Value(),(*categories)[0]);
+ for (int i=1; i<categories->Size(); i++)
{
- cXMLTVStringList *categories=xEvent->Category();
- description=Add2Description(description,text->Value(),(*categories)[0]);
- for (int i=1; i<categories->Size(); i++)
- {
- // prevent duplicates
- if (strcasecmp((*categories)[i],(*categories)[i-1]))
- description=Add2Description(description,text->Value(),(*categories)[i]);
- }
+ // prevent duplicates
+ if (strcasecmp((*categories)[i],(*categories)[i-1]))
+ description=Add2Description(description,text->Value(),(*categories)[i]);
}
}
+ }
- if (((Flags & USE_VIDEO)==USE_VIDEO) && (xEvent->Video()->Size()))
+ if (((Flags & USE_VIDEO)==USE_VIDEO) && (xEvent->Video()->Size()))
+ {
+ cTEXTMapping *text=texts->GetMap("video");
+ if (text)
{
- cTEXTMapping *text=texts->GetMap("video");
- if (text)
+ description=Add2Description(description,text->Value());
+ description=Add2Description(description,": ");
+ cXMLTVStringList *video=xEvent->Video();
+ for (int i=0; i<video->Size(); i++)
{
- description=Add2Description(description,text->Value());
- description=Add2Description(description,": ");
- cXMLTVStringList *video=xEvent->Video();
- for (int i=0; i<video->Size(); i++)
+ char *vtype=strdup((*video)[i]);
+ if (vtype)
{
- char *vtype=strdup((*video)[i]);
- if (vtype)
+ char *vval=strchr(vtype,'|');
+ if (vval)
{
- char *vval=strchr(vtype,'|');
- if (vval)
- {
- *vval=0;
- vval++;
+ *vval=0;
+ vval++;
- if (i)
- {
- description=Add2Description(description,", ");
- }
+ if (i)
+ {
+ description=Add2Description(description,", ");
+ }
- if (!strcasecmp(vtype,"colour"))
- {
- if (!strcasecmp(vval,"no"))
- {
- cTEXTMapping *text=texts->GetMap("blacknwhite");
- description=Add2Description(description,text->Value());
- }
- }
- else
+ if (!strcasecmp(vtype,"colour"))
+ {
+ if (!strcasecmp(vval,"no"))
{
- description=Add2Description(description,vval);
+ cTEXTMapping *text=texts->GetMap("blacknwhite");
+ description=Add2Description(description,text->Value());
}
}
- free(vtype);
+ else
+ {
+ description=Add2Description(description,vval);
+ }
}
+ free(vtype);
}
- description=Add2Description(description,"\n");
}
+ description=Add2Description(description,"\n");
}
+ }
- if ((Flags & USE_AUDIO)==USE_AUDIO)
+ if ((Flags & USE_AUDIO)==USE_AUDIO)
+ {
+ if (xEvent->Audio())
{
- if (xEvent->Audio())
+ cTEXTMapping *text=texts->GetMap("audio");
+ if (text)
{
- cTEXTMapping *text=texts->GetMap("audio");
- if (text)
- {
- description=Add2Description(description,text->Value());
- description=Add2Description(description,": ");
+ description=Add2Description(description,text->Value());
+ description=Add2Description(description,": ");
- if ((!strcasecmp(xEvent->Audio(),"mono")) || (!strcasecmp(xEvent->Audio(),"stereo")))
+ if ((!strcasecmp(xEvent->Audio(),"mono")) || (!strcasecmp(xEvent->Audio(),"stereo")))
+ {
+ description=Add2Description(description,xEvent->Audio());
+ description=Add2Description(description,"\n");
+ }
+ else
+ {
+ cTEXTMapping *text=texts->GetMap(xEvent->Audio());
+ if (text)
{
- description=Add2Description(description,xEvent->Audio());
+ description=Add2Description(description,text->Value());
description=Add2Description(description,"\n");
}
- else
- {
- cTEXTMapping *text=texts->GetMap(xEvent->Audio());
- if (text)
- {
- description=Add2Description(description,text->Value());
- description=Add2Description(description,"\n");
- }
- }
}
}
}
- if ((Flags & USE_SEASON)==USE_SEASON)
+ }
+ if ((Flags & USE_SEASON)==USE_SEASON)
+ {
+ if (xEvent->Season())
{
- if (xEvent->Season())
- {
- cTEXTMapping *text=texts->GetMap("season");
- if (text) description=Add2Description(description,text->Value(),xEvent->Season());
- }
-
- if (xEvent->Episode())
- {
- cTEXTMapping *text=texts->GetMap("episode");
- if (text) description=Add2Description(description,text->Value(),xEvent->Episode());
- }
+ cTEXTMapping *text=texts->GetMap("season");
+ if (text) description=Add2Description(description,text->Value(),xEvent->Season());
}
- if (((Flags & USE_RATING)==USE_RATING) && (xEvent->Rating()->Size()))
+ if (xEvent->Episode())
{
+ cTEXTMapping *text=texts->GetMap("episode");
+ if (text) description=Add2Description(description,text->Value(),xEvent->Episode());
+ }
+ }
+
+ if (((Flags & USE_RATING)==USE_RATING) && (xEvent->Rating()->Size()))
+ {
#if VDRVERSNUM < 10711 && !EPGHANDLER
- Flags|=OPT_RATING_TEXT; // always add to text if we dont have the internal tag!
+ Flags|=OPT_RATING_TEXT; // always add to text if we dont have the internal tag!
#endif
- if ((Flags & OPT_RATING_TEXT)==OPT_RATING_TEXT)
+ if ((Flags & OPT_RATING_TEXT)==OPT_RATING_TEXT)
+ {
+ cXMLTVStringList *rating=xEvent->Rating();
+ for (int i=0; i<rating->Size(); i++)
{
- cXMLTVStringList *rating=xEvent->Rating();
- for (int i=0; i<rating->Size(); i++)
+ char *rtype=strdup((*rating)[i]);
+ if (rtype)
{
- char *rtype=strdup((*rating)[i]);
- if (rtype)
+ char *rval=strchr(rtype,'|');
+ if (rval)
{
- char *rval=strchr(rtype,'|');
- if (rval)
- {
- *rval=0;
- rval++;
+ *rval=0;
+ rval++;
- description=Add2Description(description,rtype);
- description=Add2Description(description,": ");
- description=Add2Description(description,rval);
- description=Add2Description(description,"\n");
- }
- free(rtype);
+ description=Add2Description(description,rtype);
+ description=Add2Description(description,": ");
+ description=Add2Description(description,rval);
+ description=Add2Description(description,"\n");
}
+ free(rtype);
}
}
}
+ }
- if (((Flags & USE_STARRATING)==USE_STARRATING) && (xEvent->StarRating()->Size()))
+ if (((Flags & USE_STARRATING)==USE_STARRATING) && (xEvent->StarRating()->Size()))
+ {
+ cTEXTMapping *text=texts->GetMap("starrating");
+ if (text)
{
- cTEXTMapping *text=texts->GetMap("starrating");
- if (text)
+ description=Add2Description(description,text->Value());
+ description=Add2Description(description,": ");
+ cXMLTVStringList *starrating=xEvent->StarRating();
+ for (int i=0; i<starrating->Size(); i++)
{
- description=Add2Description(description,text->Value());
- description=Add2Description(description,": ");
- cXMLTVStringList *starrating=xEvent->StarRating();
- for (int i=0; i<starrating->Size(); i++)
+ char *rtype=strdup((*starrating)[i]);
+ if (rtype)
{
- char *rtype=strdup((*starrating)[i]);
- if (rtype)
+ char *rval=strchr(rtype,'|');
+ if (rval)
{
- char *rval=strchr(rtype,'|');
- if (rval)
- {
- *rval=0;
- rval++;
+ *rval=0;
+ rval++;
- if (i)
- {
- description=Add2Description(description,", ");
- }
- if (strcasecmp(rtype,"*"))
- {
- description=Add2Description(description,rtype);
- description=Add2Description(description," ");
- }
- description=Add2Description(description,rval);
+ if (i)
+ {
+ description=Add2Description(description,", ");
}
- free(rtype);
+ if (strcasecmp(rtype,"*"))
+ {
+ description=Add2Description(description,rtype);
+ description=Add2Description(description," ");
+ }
+ description=Add2Description(description,rval);
}
+ free(rtype);
}
- description=Add2Description(description,"\n");
}
+ description=Add2Description(description,"\n");
}
+ }
- if (((Flags & USE_REVIEW)==USE_REVIEW) && (xEvent->Review()->Size()))
+ if (((Flags & USE_REVIEW)==USE_REVIEW) && (xEvent->Review()->Size()))
+ {
+ cTEXTMapping *text=texts->GetMap("review");
+ if (text)
{
- cTEXTMapping *text=texts->GetMap("review");
- if (text)
+ cXMLTVStringList *review=xEvent->Review();
+ for (int i=0; i<review->Size(); i++)
{
- cXMLTVStringList *review=xEvent->Review();
- for (int i=0; i<review->Size(); i++)
- {
- description=Add2Description(description,text->Value(),(*review)[i]);
- }
+ description=Add2Description(description,text->Value(),(*review)[i]);
}
}
+ }
- if (description)
+ if (description)
+ {
+ description=RemoveLastCharFromDescription(description);
+ description=AddEOT2Description(description);
+ const char *dp=conv->Convert(description);
+ if (!Event->Description() || strcmp(Event->Description(),dp))
{
- description=RemoveLastCharFromDescription(description);
- description=AddEOT2Description(description);
- const char *dp=conv->Convert(description);
- if (!Event->Description() || strcmp(Event->Description(),dp))
- {
- Event->SetDescription(dp);
- changed|=CHANGED_DESCRIPTION;
- }
- free(description);
+ Event->SetDescription(dp);
+ changed|=CHANGED_DESCRIPTION;
}
+ free(description);
}
#if VDRVERSNUM >= 10711 || EPGHANDLER
@@ -740,25 +762,44 @@ bool cImport::PutEvent(cEPGSource *Source, sqlite3 *Db, cSchedule* Schedule,
event->SetTableID(0); // prevent EIT EPG to update this event
#endif
- if ((!append) && (changed))
+ if (!append && changed)
{
- start=Event->StartTime();
- end=Event->EndTime();
- localtime_r(&start,&tm);
- strftime(from,sizeof(from)-1,"%b %d %H:%M",&tm);
- localtime_r(&end,&tm);
- strftime(till,sizeof(till)-1,"%b %d %H:%M",&tm);
- switch (changed)
+
+ if ((changed==CHANGED_SHORTTEXT) && (WasChanged(Event)==false))
{
- case CHANGED_SHORTTEXT:
- Source->Tlog("changing shorttext of '%s'@%s-%s",Event->Title(),from,till);
- break;
- case CHANGED_DESCRIPTION:
- Source->Tlog("changing description of '%s'@%s-%s",Event->Title(),from,till);
- break;
- case CHANGED_ALL:
- Source->Tlog("changing stext+descr of '%s'@%s-%s",Event->Title(),from,till);
- break;
+ description=strdup(Event->Description());
+ if (description)
+ {
+ description=AddEOT2Description(description,true);
+ tsyslogs(Source,"{%i} adding EOT to '%s'",Event->EventID(),Event->Title());
+ Event->SetDescription(description);
+ free(description);
+ }
+ }
+
+ if (Source->Trace())
+ {
+ start=Event->StartTime();
+ end=Event->EndTime();
+ localtime_r(&start,&tm);
+ strftime(from,sizeof(from)-1,"%b %d %H:%M",&tm);
+ localtime_r(&end,&tm);
+ strftime(till,sizeof(till)-1,"%b %d %H:%M",&tm);
+ switch (changed)
+ {
+ case CHANGED_SHORTTEXT:
+ tsyslogs(Source,"{%i} changing shorttext (%s) of '%s'@%s-%s",Event->EventID(),
+ Event->ShortText(),Event->Title(),from,till);
+ break;
+ case CHANGED_DESCRIPTION:
+ tsyslogs(Source,"{%i} changing description of '%s'@%s-%s",Event->EventID(),
+ Event->Title(),from,till);
+ break;
+ case CHANGED_ALL:
+ tsyslogs(Source,"{%i} changing stext (%s)+descr of '%s'@%s-%s",Event->EventID(),
+ Event->ShortText(),Event->Title(),from,till);
+ break;
+ }
}
}
return true;
@@ -857,7 +898,7 @@ cXMLTVEvent *cImport::PrepareAndReturn(sqlite3 *db, char *sql)
int ret=sqlite3_prepare_v2(db,sql,strlen(sql),&stmt,NULL);
if (ret!=SQLITE_OK)
{
- esyslog("xmltv2vdr: ERROR %i %s",ret,sqlite3_errmsg(db));
+ esyslog("%i %s",ret,sqlite3_errmsg(db));
free(sql);
return NULL;
}
@@ -916,6 +957,7 @@ cXMLTVEvent *cImport::AddXMLTVEvent(cEPGSource *Source,sqlite3 *Db, const char *
if (!cParse::FetchSeasonEpisode(conv,epdir,Event->Title(),
Event->ShortText(),season,episode))
{
+ tsyslogs(Source,"no season/episode found for '%s'/'%s'",Event->Title(),Event->ShortText());
free(epdir);
iconv_close(conv);
return NULL;
@@ -924,7 +966,7 @@ cXMLTVEvent *cImport::AddXMLTVEvent(cEPGSource *Source,sqlite3 *Db, const char *
cXMLTVEvent *xevent = new cXMLTVEvent();
if (!xevent)
{
- Source->Elog("out of memory");
+ esyslogs(Source,"out of memory");
free(epdir);
iconv_close(conv);
return NULL;
@@ -953,7 +995,7 @@ cXMLTVEvent *cImport::AddXMLTVEvent(cEPGSource *Source,sqlite3 *Db, const char *
char *errmsg;
if (sqlite3_exec(Db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
- Source->Elog("%s",errmsg);
+ esyslogs(Source,"%s",errmsg);
sqlite3_free(errmsg);
delete xevent;
xevent=NULL;
@@ -963,22 +1005,28 @@ cXMLTVEvent *cImport::AddXMLTVEvent(cEPGSource *Source,sqlite3 *Db, const char *
return xevent;
}
-bool cImport::UpdateXMLTVEvent(cEPGSource *Source, sqlite3 *Db, const cEvent *Event,
- tEventID EventID, tEventID EITEventID, const char *EITDescription)
+bool cImport::UpdateXMLTVEvent(cEPGSource *Source, sqlite3 *Db, const cEvent *Event, cXMLTVEvent *xEvent)
{
if (!Source) return false;
if (!Db) return false;
if (!Event) return false;
+ if (!xEvent) return false;
+
+ if (Event->Description())
+ {
+ xEvent->SetEITDescription(Event->Description());
+ }
+ xEvent->SetEITEventID(Event->EventID());
if (!Begin(Source,Db)) return false;
char *sql=NULL;
- if (EITDescription)
+ if (Event->Description())
{
- char *eitdescription=strdup(EITDescription);
+ char *eitdescription=strdup(Event->Description());
if (!eitdescription)
{
- Source->Elog("out of memory");
+ esyslogs(Source,"out of memory");
return false;
}
@@ -993,43 +1041,45 @@ bool cImport::UpdateXMLTVEvent(cEPGSource *Source, sqlite3 *Db, const cEvent *Ev
}
if (asprintf(&sql,"update epg set eiteventid=%li, eitdescription='%s' where eventid=%li and src='%s'",
- (long int) EITEventID,eitdescription,(long int) EventID,Source->Name())==-1)
+ (long int) Event->EventID(),eitdescription,(long int) xEvent->EventID(),Source->Name())==-1)
{
free(eitdescription);
- Source->Elog("out of memory");
+ esyslogs(Source,"out of memory");
return false;
}
free(eitdescription);
-
- if (Event)
- {
- struct tm tm;
- char from[80];
- char till[80];
- time_t start,end;
- start=Event->StartTime();
- end=Event->EndTime();
- localtime_r(&start,&tm);
- strftime(from,sizeof(from)-1,"%b %d %H:%M",&tm);
- localtime_r(&end,&tm);
- strftime(till,sizeof(till)-1,"%b %d %H:%M",&tm);
- Source->Tlog("updating description of '%s'@%s-%s in db",Event->Title(),from,till);
- }
}
else
{
if (asprintf(&sql,"update epg set eiteventid=%li where eventid=%li and src='%s'",
- (long int) EITEventID,(long int) EventID,Source->Name())==-1)
+ (long int) Event->EventID(),(long int) xEvent->EventID(),Source->Name())==-1)
{
- Source->Elog("out of memory");
+ esyslogs(Source,"out of memory");
return false;
}
}
+ if (Source->Trace())
+ {
+ struct tm tm;
+ char from[80];
+ char till[80];
+ time_t start,end;
+ start=Event->StartTime();
+ end=Event->EndTime();
+ localtime_r(&start,&tm);
+ strftime(from,sizeof(from)-1,"%b %d %H:%M",&tm);
+ localtime_r(&end,&tm);
+ strftime(till,sizeof(till)-1,"%b %d %H:%M",&tm);
+ tsyslogs(Source,"{%i} updating %s of '%s'@%s-%s in db",Event->EventID(),
+ Event->Description() ? "eitdescription/eiteventid" :
+ "eiteventid",Event->Title(),from,till);
+ }
+
char *errmsg;
if (sqlite3_exec(Db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
- Source->Elog("%s -> %s",sql,errmsg);
+ esyslogs(Source,"%s -> %s",sql,errmsg);
free(sql);
sqlite3_free(errmsg);
return false;
@@ -1039,7 +1089,7 @@ bool cImport::UpdateXMLTVEvent(cEPGSource *Source, sqlite3 *Db, const cEvent *Ev
return true;
}
-cXMLTVEvent *cImport::SearchXMLTVEvent(sqlite3 **Db, const char *ChannelID, const cEvent *Event)
+cXMLTVEvent *cImport::SearchXMLTVEvent(sqlite3 **Db,const char *ChannelID, const cEvent *Event)
{
if (!Event) return NULL;
if (!Db) return NULL;
@@ -1048,7 +1098,7 @@ cXMLTVEvent *cImport::SearchXMLTVEvent(sqlite3 **Db, const char *ChannelID, cons
// we need READWRITE because the epg.db maybe updated later
if (sqlite3_open_v2(epgfile,Db,SQLITE_OPEN_READWRITE,NULL)!=SQLITE_OK)
{
- esyslog("xmltv2vdr: ERROR failed to open %s",epgfile);
+ esyslog("failed to open %s",epgfile);
*Db=NULL;
return NULL;
}
@@ -1062,7 +1112,7 @@ cXMLTVEvent *cImport::SearchXMLTVEvent(sqlite3 **Db, const char *ChannelID, cons
"mixing,src,eiteventid,eitdescription from epg where eiteventid=%li and channelid='%s' " \
"order by srcidx asc limit 1;",(long int) Event->EventID(),ChannelID)==-1)
{
- esyslog("xmltv2vdr: ERROR out of memory");
+ esyslog("out of memory");
return NULL;
}
@@ -1076,7 +1126,7 @@ cXMLTVEvent *cImport::SearchXMLTVEvent(sqlite3 **Db, const char *ChannelID, cons
char *sqltitle=strdup(Event->Title());
if (!sqltitle)
{
- esyslog("xmltv2vdr: ERROR out of memory");
+ esyslog("out of memory");
return NULL;
}
@@ -1102,7 +1152,7 @@ cXMLTVEvent *cImport::SearchXMLTVEvent(sqlite3 **Db, const char *ChannelID, cons
Event->StartTime()+eventTimeDiff,sqltitle,ChannelID)==-1)
{
free(sqltitle);
- esyslog("xmltv2vdr: ERROR out of memory");
+ esyslog("out of memory");
return NULL;
}
free(sqltitle);
@@ -1122,7 +1172,7 @@ bool cImport::Begin(cEPGSource *Source, sqlite3 *Db)
char *errmsg;
if (sqlite3_exec(Db,"BEGIN",NULL,NULL,&errmsg)!=SQLITE_OK)
{
- Source->Elog("sqlite3: BEGIN -> %s",errmsg);
+ esyslogs(Source,"sqlite3: BEGIN -> %s",errmsg);
sqlite3_free(errmsg);
return false;
}
@@ -1144,11 +1194,11 @@ bool cImport::Commit(cEPGSource *Source, sqlite3 *Db)
{
if (Source)
{
- Source->Elog("sqlite3: COMMIT -> %s",errmsg);
+ esyslogs(Source,"sqlite3: COMMIT -> %s",errmsg);
}
else
{
- esyslog("sqlite3: ERROR COMMIT -> %s",errmsg);
+ esyslog("sqlite3: COMMIT -> %s",errmsg);
}
sqlite3_free(errmsg);
return false;
@@ -1167,10 +1217,31 @@ int cImport::Process(cEPGSource *Source, cEPGExecutor &myExecutor)
time_t endoneday=begin+86400;
#endif
+ cSchedulesLock *schedulesLock=NULL;
+ const cSchedules *schedules=NULL;
+
+ int l=0;
+ while (l<300)
+ {
+ if (schedulesLock) delete schedulesLock;
+ schedulesLock = new cSchedulesLock(true,200); // wait up to 60 secs for lock!
+ schedules = cSchedules::Schedules(*schedulesLock);
+ if (!myExecutor.StillRunning())
+ {
+ delete schedulesLock;
+ isyslogs(Source,"request to stop from vdr");
+ return 0;
+ }
+ if (schedules) break;
+ l++;
+ }
+
+ dsyslogs(Source,"importing from db");
sqlite3 *db=NULL;
- if (sqlite3_open_v2(epgfile,&db,SQLITE_OPEN_READWRITE,NULL)!=SQLITE_OK)
+ if (sqlite3_open(epgfile,&db)!=SQLITE_OK)
{
- Source->Elog("failed to open %s",epgfile);
+ esyslogs(Source,"failed to open %s",epgfile);
+ delete schedulesLock;
return 141;
}
@@ -1182,7 +1253,8 @@ int cImport::Process(cEPGSource *Source, cEPGExecutor &myExecutor)
" and src='%s';",begin,begin,end,Source->Name())==-1)
{
sqlite3_close(db);
- Source->Elog("out of memory");
+ esyslogs(Source,"out of memory");
+ delete schedulesLock;
return 134;
}
@@ -1190,14 +1262,13 @@ int cImport::Process(cEPGSource *Source, cEPGExecutor &myExecutor)
if (sqlite3_prepare_v2(db,sql,strlen(sql),&stmt,NULL)!=SQLITE_OK)
{
sqlite3_close(db);
- Source->Elog("failed to prepare %s",sql);
+ esyslogs(Source,"failed to prepare %s",sql);
free(sql);
+ delete schedulesLock;
return 141;
}
free(sql);
- cSchedulesLock *schedulesLock=NULL;
- const cSchedules *schedules=NULL;
int lerr=0;
int cnt=0;
for (;;)
@@ -1211,7 +1282,7 @@ int cImport::Process(cEPGSource *Source, cEPGExecutor &myExecutor)
if (!map)
{
if (lerr!=IMPORT_NOMAPPING)
- Source->Elog("no mapping for channelid %s",xevent.ChannelID());
+ esyslogs(Source,"no mapping for channelid %s",xevent.ChannelID());
lerr=IMPORT_NOMAPPING;
continue;
}
@@ -1225,36 +1296,18 @@ int cImport::Process(cEPGSource *Source, cEPGExecutor &myExecutor)
if (!channel)
{
if (lerr!=IMPORT_NOCHANNEL)
- Source->Elog("channel %s not found in channels.conf",
- *map->ChannelIDs()[i].ToString());
+ esyslogs(Source,"channel %s not found in channels.conf",
+ *map->ChannelIDs()[i].ToString());
lerr=IMPORT_NOCHANNEL;
continue;
}
- int l=0;
- while (l<300)
- {
- if (schedulesLock) delete schedulesLock;
- schedulesLock = new cSchedulesLock(true,200); // wait up to 60 secs for lock!
- schedules = cSchedules::Schedules(*schedulesLock);
- if (schedules) break;
- if (!myExecutor.StillRunning())
- {
- delete schedulesLock;
- Source->Ilog("request to stop from vdr");
- sqlite3_finalize(stmt);
- sqlite3_close(db);
- return 0;
- }
- l++;
- }
-
cSchedule* schedule = (cSchedule *) schedules->GetSchedule(channel,addevents);
if (!schedule)
{
if (lerr!=IMPORT_NOSCHEDULE)
- Source->Elog("cannot get schedule for channel %s%s",
- channel->Name(),addevents ? "" : " - try add option");
+ esyslogs(Source,"cannot get schedule for channel %s%s",
+ channel->Name(),addevents ? "" : " - try add option");
lerr=IMPORT_NOSCHEDULE;
continue;
}
@@ -1263,7 +1316,7 @@ int cImport::Process(cEPGSource *Source, cEPGExecutor &myExecutor)
if (addevents && event && (event->EventID() != xevent.EventID()))
{
- Source->Elog("found another event with different eventid");
+ esyslogs(Source,"found another event with different eventid");
int newflags=map->Flags();
newflags &=~OPT_APPEND;
map->ChangeFlags(newflags);
@@ -1274,9 +1327,6 @@ int cImport::Process(cEPGSource *Source, cEPGExecutor &myExecutor)
#endif
PutEvent(Source, db, schedule, event, &xevent, map->Flags());
cnt++;
-
- delete schedulesLock;
- schedulesLock=NULL;
}
}
}
@@ -1288,11 +1338,12 @@ int cImport::Process(cEPGSource *Source, cEPGExecutor &myExecutor)
if (Commit(Source,db))
{
- Source->Dlog("processed %i xmltv events",cnt);
+ dsyslogs(Source,"processed %i xmltv events",cnt);
}
sqlite3_finalize(stmt);
sqlite3_close(db);
+ delete schedulesLock;
return 0;
}
@@ -1303,23 +1354,30 @@ cImport::cImport(const char *EPGFile, cEPGMappings* Maps, cTEXTMappings *Texts)
pendingtransaction=false;
epgfile=EPGFile;
- char *CodeSet=NULL;
+ char *codeset=NULL;
if (setlocale(LC_CTYPE,""))
- CodeSet=nl_langinfo(CODESET);
+ codeset=strdup(nl_langinfo(CODESET));
else
{
char *LangEnv=getenv("LANG");
if (LangEnv)
{
- CodeSet=strchr(LangEnv,'.');
- if (CodeSet)
- CodeSet++;
+ codeset=strdup(strchr(LangEnv,'.'));
+ if (codeset)
+ codeset++; // skip dot
}
}
- conv = new cCharSetConv("UTF-8",CodeSet ? CodeSet : "US-ASCII//TRANSLIT");
+ if (!codeset)
+ {
+ codeset=strdup("US-ASCII//TRANSLIT");
+ }
+ isyslog("codeset is '%s'",codeset);
+ conv = new cCharSetConv("UTF-8",codeset);
+
}
cImport::~cImport()
{
+ if (codeset) free(codeset);
delete conv;
}
diff --git a/import.h b/import.h
index 787ce12..5750fec 100644
--- a/import.h
+++ b/import.h
@@ -16,13 +16,6 @@
#include "source.h"
#include "maps.h"
-enum
-{
- IMPORT_ALL=0,
- IMPORT_DESCRIPTION,
- IMPORT_SHORTTEXT
-};
-
class cEPGSource;
class cEPGExecutor;
@@ -47,13 +40,14 @@ private:
cEPGMappings *maps;
cTEXTMappings *texts;
cCharSetConv *conv;
+ char *codeset;
bool pendingtransaction;
const char *epgfile;
char *RemoveLastCharFromDescription(char *description);
char *Add2Description(char *description, const char *value);
char *Add2Description(char *description, const char *name, const char *value);
char *Add2Description(char *description, const char *name, int value);
- char *AddEOT2Description(char *description);
+ char *AddEOT2Description(char *description, bool checkutf8=false);
struct split split(char *in, char delim);
cEvent *GetEventBefore(cSchedule* schedule, time_t start);
cEvent *SearchVDREvent(cEPGSource *source, cSchedule* schedule, cXMLTVEvent *event);
@@ -67,12 +61,11 @@ public:
bool Begin(cEPGSource *Source, sqlite3 *Db);
bool Commit(cEPGSource *Source, sqlite3 *Db);
bool PutEvent(cEPGSource *Source, sqlite3 *Db, cSchedule* Schedule, cEvent *Event,
- cXMLTVEvent *xEvent, int Flags, int Option=IMPORT_ALL);
- bool UpdateXMLTVEvent(cEPGSource *Source, sqlite3 *Db, const cEvent *Event,
- tEventID EventID, tEventID EITEventID, const char *EITDescription=NULL);
+ cXMLTVEvent *xEvent, int Flags);
+ bool UpdateXMLTVEvent(cEPGSource *Source, sqlite3 *Db, const cEvent *Event, cXMLTVEvent *xEvent);
cXMLTVEvent *SearchXMLTVEvent(sqlite3 **Db, const char *ChannelID, const cEvent *Event);
- cXMLTVEvent *AddXMLTVEvent(cEPGSource *Source, sqlite3 *Db, const char *ChannelID,
- const cEvent *Event, const char *EITDescription);
+ cXMLTVEvent *AddXMLTVEvent(cEPGSource *Source, sqlite3 *Db, const char *ChannelID,
+ const cEvent *Event, const char *EITDescription);
bool WasChanged(cEvent *Event);
};
diff --git a/parse.cpp b/parse.cpp
index 3eefaf5..3610a98 100644
--- a/parse.cpp
+++ b/parse.cpp
@@ -22,6 +22,7 @@
#include "xmltv2vdr.h"
#include "parse.h"
+#include "debug.h"
// -------------------------------------------------------
@@ -514,7 +515,7 @@ bool cParse::FetchEvent(xmlNodePtr enode)
}
else
{
- source->Elog("unknown element %s, please report!",node->name);
+ esyslogs(source,"unknown element %s, please report!",node->name);
}
}
node=node->next;
@@ -535,27 +536,51 @@ int cParse::Process(cEPGExecutor &myExecutor,char *buffer, int bufsize)
if (!buffer) return 134;
if (!bufsize) return 134;
+ cSchedulesLock *schedulesLock=NULL;
+ const cSchedules *schedules=NULL;
+
+ int l=0;
+ while (l<300)
+ {
+ if (schedulesLock) delete schedulesLock;
+ schedulesLock = new cSchedulesLock(true,200); // wait up to 60 secs for lock!
+ schedules = cSchedules::Schedules(*schedulesLock);
+ if (!myExecutor.StillRunning())
+ {
+ delete schedulesLock;
+ isyslogs(source,"request to stop from vdr");
+ return 0;
+ }
+ if (schedules) break;
+ l++;
+ }
+
+ dsyslogs(source,"parsing output");
+
xmlDocPtr xmltv;
xmltv=xmlReadMemory(buffer,bufsize,NULL,NULL,0);
if (!xmltv)
{
- source->Elog("failed to parse xmltv");
+ esyslogs(source,"failed to parse xmltv");
+ delete schedulesLock;
return 141;
}
xmlNodePtr rootnode=xmlDocGetRootElement(xmltv);
if (!rootnode)
{
- source->Elog("no rootnode in xmltv");
+ esyslogs(source,"no rootnode in xmltv");
xmlFreeDoc(xmltv);
+ delete schedulesLock;
return 141;
}
sqlite3 *db=NULL;
if (sqlite3_open(epgfile,&db)!=SQLITE_OK)
{
- source->Elog("failed to open or create %s",epgfile);
+ esyslogs(source,"failed to open or create %s",epgfile);
xmlFreeDoc(xmltv);
+ delete schedulesLock;
return 141;
}
@@ -579,10 +604,11 @@ int cParse::Process(cEPGExecutor &myExecutor,char *buffer, int bufsize)
char *errmsg;
if (sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
- source->Elog("createdb: %s",errmsg);
+ esyslogs(source,"createdb: %s",errmsg);
sqlite3_free(errmsg);
sqlite3_close(db);
xmlFreeDoc(xmltv);
+ delete schedulesLock;
return 141;
}
@@ -590,6 +616,7 @@ int cParse::Process(cEPGExecutor &myExecutor,char *buffer, int bufsize)
xmlNodePtr node=rootnode->xmlChildrenNode;
int lerr=0;
+ int cnt=0;
while (node)
{
if (node->type!=XML_ELEMENT_NODE)
@@ -606,7 +633,7 @@ int cParse::Process(cEPGExecutor &myExecutor,char *buffer, int bufsize)
if (!channelid)
{
if (lerr!=PARSE_NOCHANNELID)
- source->Elog("missing channelid in xmltv file");
+ esyslogs(source,"missing channelid in xmltv file");
lerr=PARSE_NOCHANNELID;
node=node->next;
continue;
@@ -615,7 +642,7 @@ int cParse::Process(cEPGExecutor &myExecutor,char *buffer, int bufsize)
if (!map)
{
if (lerr!=PARSE_NOMAPPING)
- source->Elog("no mapping for channelid %s",channelid);
+ esyslogs(source,"no mapping for channelid %s",channelid);
lerr=PARSE_NOMAPPING;
xmlFree(channelid);
node=node->next;
@@ -644,7 +671,7 @@ int cParse::Process(cEPGExecutor &myExecutor,char *buffer, int bufsize)
if (!starttime)
{
if (lerr!=PARSE_XMLTVERR)
- source->Elog("no starttime, check xmltv file");
+ esyslogs(source,"no starttime, check xmltv file");
lerr=PARSE_XMLTVERR;
xmlFree(channelid);
node=node->next;
@@ -665,7 +692,7 @@ int cParse::Process(cEPGExecutor &myExecutor,char *buffer, int bufsize)
if (!FetchEvent(node)) // sets xevent
{
- source->Tlog("failed to fetch event");
+ tsyslogs(source,"failed to fetch event");
node=node->next;
xmlFree(channelid);
continue;
@@ -674,30 +701,34 @@ int cParse::Process(cEPGExecutor &myExecutor,char *buffer, int bufsize)
const char *sql=xevent.GetSQL(source->Name(),source->Index(),(const char *) channelid);
if (sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
- source->Elog("sqlite3: %s",errmsg);
+ tsyslogs(source,"sqlite3: %s",errmsg);
sqlite3_free(errmsg);
xmlFree(channelid);
break;
}
xmlFree(channelid);
+ cnt++;
node=node->next;
if (!myExecutor.StillRunning())
{
- source->Ilog("request to stop from vdr");
+ isyslogs(source,"request to stop from vdr");
break;
}
}
+ dsyslogs(source,"processed %i xmltv events",cnt);
+
if (sqlite3_exec(db,"COMMIT; ANALYZE epg;",NULL,NULL,&errmsg)!=SQLITE_OK)
{
- source->Elog("sqlite3: %s",errmsg);
+ esyslogs(source,"sqlite3: %s",errmsg);
sqlite3_free(errmsg);
}
sqlite3_close(db);
xmlFreeDoc(xmltv);
+ delete schedulesLock;
return 0;
}
diff --git a/source.cpp b/source.cpp
index 64a6866..2a7c031 100644
--- a/source.cpp
+++ b/source.cpp
@@ -13,6 +13,7 @@
#include "xmltv2vdr.h"
#include "source.h"
#include "extpipe.h"
+#include "debug.h"
cEPGChannel::cEPGChannel(const char *Name, bool InUse)
{
@@ -33,37 +34,32 @@ int cEPGChannel::Compare(const cListObject &ListObject) const
// -------------------------------------------------------------
-cEPGExecutor::cEPGExecutor(cPluginXmltv2vdr *Plugin,cEPGSources *Sources) : cThread("xmltv2vdr importer")
+cEPGExecutor::cEPGExecutor(cEPGSources *Sources) : cThread("xmltv2vdr importer")
{
- baseplugin=Plugin;
sources=Sources;
}
void cEPGExecutor::Action()
{
if (!sources) return;
- if (!baseplugin) return;
SetPriority(19);
if (ioprio_set(1,getpid(),7 | 3 << 13)==-1)
{
- esyslog("xmltv2vdr: failed to set ioprio to 3,7");
+ esyslog("failed to set ioprio to 3,7");
}
for (cEPGSource *epgs=sources->First(); epgs; epgs=sources->Next(epgs))
{
if (epgs->RunItNow())
{
- // if timer thread is runnung, wait till it's stopped
- baseplugin->Wait4TimerThreadAndSetup();
-
int retries=0;
while (retries<=2)
{
int ret=epgs->Execute(*this);
if ((ret>0) && (ret<126) && (retries<2))
{
- epgs->Dlog("waiting 60 seconds");
+ dsyslogs(epgs,"waiting 60 seconds");
int l=0;
while (l<300)
{
@@ -73,7 +69,7 @@ void cEPGExecutor::Action()
nanosleep(&req,NULL);
if (!Running())
{
- epgs->Ilog("request to stop from vdr");
+ isyslogs(epgs,"request to stop from vdr");
return;
}
l++;
@@ -82,7 +78,7 @@ void cEPGExecutor::Action()
}
if ((retries==2) || (!ret)) break;
}
- if (retries>=2) epgs->Elog("skipping after %i retries",retries);
+ if (retries>=2) esyslogs(epgs,"skipping after %i retries",retries);
}
}
@@ -105,7 +101,7 @@ cEPGSource::cEPGSource(const char *Name, const char *ConfDir, const char *EPGFil
{
if (strcmp(Name,EITSOURCE))
{
- dsyslog("xmltv2vdr: '%s' added epgsource",Name);
+ dsyslog("'%s' added epgsource",Name);
}
name=strdup(Name);
confdir=ConfDir;
@@ -126,7 +122,7 @@ cEPGSource::cEPGSource(const char *Name, const char *ConfDir, const char *EPGFil
ready2parse=ReadConfig();
parse=new cParse(EPGFile,this, Maps);
import=new cImport(EPGFile,Maps,Texts);
- Dlog("is%sready2parse",(ready2parse && parse) ? " " : " not ");
+ dsyslogs(this,"is%sready2parse",(ready2parse && parse) ? " " : " not ");
}
else
{
@@ -141,7 +137,7 @@ cEPGSource::~cEPGSource()
{
if (strcmp(name,EITSOURCE))
{
- dsyslog("xmltv2vdr: '%s' epgsource removed",name);
+ dsyslog("'%s' epgsource removed",name);
}
free((void *) name);
if (pin) free((void *) pin);
@@ -192,17 +188,17 @@ bool cEPGSource::ReadConfig()
char *fname=NULL;
if (asprintf(&fname,"%s/%s",EPGSOURCES,name)==-1)
{
- Elog("out of memory");
+ esyslogs(this,"out of memory");
return false;
}
FILE *f=fopen(fname,"r");
if (!f)
{
- Elog("cannot read config file %s",fname);
+ esyslogs(this,"cannot read config file %s",fname);
free(fname);
return false;
}
- Dlog("reading source config");
+ dsyslogs(this,"reading source config");
size_t lsize;
char *line=NULL;
int linenr=1;
@@ -212,12 +208,12 @@ bool cEPGSource::ReadConfig()
{
if (!strncmp(line,"pipe",4))
{
- Dlog("is providing data through a pipe");
+ dsyslogs(this,"is providing data through a pipe");
usepipe=true;
}
else
{
- Dlog("is providing data through a file");
+ dsyslogs(this,"is providing data through a file");
usepipe=false;
}
char *ndt=strchr(line,';');
@@ -233,7 +229,7 @@ bool cEPGSource::ReadConfig()
}
int h,m;
sscanf(ndt,"%02i:%02i",&h,&m);
- Dlog("updates data @%02i:%02i",h,m);
+ dsyslogs(this,"updates data @%02i:%02i",h,m);
m+=10;
if (m>60)
{
@@ -247,7 +243,7 @@ bool cEPGSource::ReadConfig()
pn=compactspace(pn);
if (pn[0]=='1')
{
- Dlog("is needing a pin");
+ dsyslogs(this,"is needing a pin");
needpin=true;
}
}
@@ -267,7 +263,7 @@ bool cEPGSource::ReadConfig()
{
daysmax=atoi(line);
}
- Dlog("daysmax=%i",daysmax);
+ dsyslogs(this,"daysmax=%i",daysmax);
}
if (linenr>2)
{
@@ -299,7 +295,7 @@ bool cEPGSource::ReadConfig()
if (asprintf(&fname,"%s/%s",confdir,name)==-1)
{
- Elog("out of memory");
+ esyslogs(this,"out of memory");
return false;
}
f=fopen(fname,"r+");
@@ -307,7 +303,7 @@ bool cEPGSource::ReadConfig()
{
if (errno!=ENOENT)
{
- Elog("cannot read config file %s",fname);
+ esyslogs(this,"cannot read config file %s",fname);
free(fname);
return true;
}
@@ -315,7 +311,7 @@ bool cEPGSource::ReadConfig()
free(fname);
return true;
}
- Dlog("reading plugin config");
+ dsyslogs(this,"reading plugin config");
line=NULL;
linenr=1;
while (getline(&line,&lsize,f)!=-1)
@@ -327,17 +323,17 @@ bool cEPGSource::ReadConfig()
if (strcmp(line,"#no pin"))
{
ChangePin(line);
- Dlog("pin set");
+ dsyslogs(this,"pin set");
}
}
if (linenr==2)
{
int reserve;
sscanf(line,"%2d;%1d;%3d;%10d",&daysinadvance,&reserve,&exec_weekday,&exec_time);
- Dlog("daysinadvance=%i",daysinadvance);
- Dlog("weekdays=%s",*cTimer::PrintDay(0,exec_weekday,true));
+ dsyslogs(this,"daysinadvance=%i",daysinadvance);
+ dsyslogs(this,"weekdays=%s",*cTimer::PrintDay(0,exec_weekday,true));
time_t nrt=NextRunTime();
- Dlog("nextrun on %s",ctime(&nrt));
+ dsyslogs(this,"nextrun on %s",ctime(&nrt));
}
if (linenr>2)
{
@@ -370,15 +366,15 @@ int cEPGSource::ReadOutput(char *&result, size_t &l)
char *fname=NULL;
if (asprintf(&fname,"%s/%s.xmltv",EPGSOURCES,name)==-1)
{
- Elog("out of memory");
+ esyslogs(this,"out of memory");
return 134;
}
- Dlog("reading from '%s'",fname);
+ dsyslogs(this,"reading from '%s'",fname);
int fd=open(fname,O_RDONLY);
if (fd==-1)
{
- Elog("failed to open '%s'",fname);
+ esyslogs(this,"failed to open '%s'",fname);
free(fname);
return 157;
}
@@ -386,7 +382,7 @@ int cEPGSource::ReadOutput(char *&result, size_t &l)
struct stat statbuf;
if (fstat(fd,&statbuf)==-1)
{
- Elog("failed to stat '%s'",fname);
+ esyslogs(this,"failed to stat '%s'",fname);
close(fd);
free(fname);
return 157;
@@ -397,12 +393,12 @@ int cEPGSource::ReadOutput(char *&result, size_t &l)
{
close(fd);
free(fname);
- Elog("out of memory");
+ esyslogs(this,"out of memory");
return 134;
}
if (read(fd,result,statbuf.st_size)!=statbuf.st_size)
{
- Elog("failed to read '%s'",fname);
+ esyslogs(this,"failed to read '%s'",fname);
ret=149;
free(result);
result=NULL;
@@ -414,7 +410,6 @@ int cEPGSource::ReadOutput(char *&result, size_t &l)
int cEPGSource::Import(cEPGExecutor &myExecutor)
{
- Dlog("importing from db");
return import->Process(this,myExecutor);
}
@@ -438,7 +433,7 @@ int cEPGSource::Execute(cEPGExecutor &myExecutor)
char *cmd=NULL;
if (asprintf(&cmd,"%s %i '%s'",name,daysinadvance,pin ? pin : "")==-1)
{
- Elog("out of memory");
+ esyslogs(this,"out of memory");
return 134;
}
@@ -453,7 +448,7 @@ int cEPGSource::Execute(cEPGExecutor &myExecutor)
if (!ncmd)
{
free(cmd);
- Elog("out of memory");
+ esyslogs(this,"out of memory");
return 134;
}
cmd=ncmd;
@@ -467,7 +462,7 @@ int cEPGSource::Execute(cEPGExecutor &myExecutor)
if (!cu)
{
free(cmd);
- Ilog("no channels, please configure source");
+ isyslogs(this,"no channels, please configure source");
return 0;
}
@@ -502,7 +497,7 @@ int cEPGSource::Execute(cEPGExecutor &myExecutor)
pe++;
}
}
- Ilog("%s",pcmd);
+ isyslogs(this,"%s",pcmd);
}
free(pcmd);
}
@@ -510,11 +505,11 @@ int cEPGSource::Execute(cEPGExecutor &myExecutor)
if (!p.Open(cmd))
{
free(cmd);
- Elog("failed to open pipe");
+ esyslogs(this,"failed to open pipe");
return 141;
}
free(cmd);
- Dlog("executing epgsource");
+ dsyslogs(this,"executing epgsource");
running=true;
int fdsopen=2;
@@ -591,14 +586,14 @@ int cEPGSource::Execute(cEPGExecutor &myExecutor)
p.Close(status);
if (r_out) free(r_out);
if (r_err) free(r_err);
- Ilog("request to stop from vdr");
+ isyslogs(this,"request to stop from vdr");
running=false;
return 0;
}
}
else
{
- Elog("failed polling");
+ esyslogs(this,"failed polling");
break;
}
}
@@ -613,18 +608,17 @@ int cEPGSource::Execute(cEPGExecutor &myExecutor)
int returncode=WEXITSTATUS(status);
if ((!returncode) && (r_out))
{
- Dlog("parsing output");
ret=parse->Process(myExecutor,r_out,l_out);
}
else
{
- Elog("epgsource returned %i",returncode);
+ esyslogs(this,"epgsource returned %i",returncode);
ret=returncode;
}
}
else
{
- Elog("failed to execute");
+ esyslogs(this,"failed to execute");
ret=126;
}
}
@@ -641,14 +635,13 @@ int cEPGSource::Execute(cEPGExecutor &myExecutor)
ret=ReadOutput(result,l);
if ((!ret) && (result))
{
- Dlog("parsing output");
ret=parse->Process(myExecutor,result,l);
}
if (result) free(result);
}
else
{
- Elog("epgsource returned %i",returncode);
+ esyslogs(this,"epgsource returned %i",returncode);
ret=returncode;
}
}
@@ -669,7 +662,7 @@ int cEPGSource::Execute(cEPGExecutor &myExecutor)
{
if (strcmp(last,pch))
{
- Elog("%s",pch);
+ esyslogs(this,"%s",pch);
last=pch;
}
pch=strtok_r(NULL,"\n",&saveptr);
@@ -695,7 +688,7 @@ void cEPGSource::Store(void)
if (asprintf(&fname1,"%s/%s",confdir,name)==-1) return;
if (asprintf(&fname2,"%s/%s.new",confdir,name)==-1)
{
- Elog("out of memory");
+ esyslogs(this,"out of memory");
free(fname1);
return;
}
@@ -703,7 +696,7 @@ void cEPGSource::Store(void)
FILE *w=fopen(fname2,"w+");
if (!w)
{
- Elog("cannot create %s",fname2);
+ esyslogs(this,"cannot create %s",fname2);
unlink(fname2);
free(fname1);
free(fname2);
@@ -739,17 +732,14 @@ void cEPGSource::Store(void)
free(fname2);
}
-void cEPGSource::add2Log(const char Prefix, const char *line)
+void cEPGSource::Add2Log(struct tm *Tm, const char Prefix, const char *Line)
{
- if (!line) return;
+ if (!Line) return;
- struct tm tm;
- time_t now=time(NULL);
- localtime_r(&now,&tm);
char dt[30];
- strftime(dt,sizeof(dt)-1,"%H:%M ",&tm);
+ strftime(dt,sizeof(dt)-1,"%H:%M ",Tm);
- loglen+=strlen(line)+3+strlen(dt);
+ loglen+=strlen(Line)+3+strlen(dt);
char *nptr=(char *) realloc(Log,loglen);
if (nptr)
{
@@ -760,68 +750,12 @@ void cEPGSource::add2Log(const char Prefix, const char *line)
prefix[1]=0;
strcat(Log,prefix);
strcat(Log,dt);
- strcat(Log,line);
+ strcat(Log,Line);
strcat(Log,"\n");
Log[loglen-1]=0;
}
}
-void cEPGSource::Elog(const char *format, ...)
-{
- va_list ap;
- char fmt[255];
- if (snprintf(fmt,sizeof(fmt),"xmltv2vdr: '%s' ERROR %s",name,format)==-1) return;
- va_start(ap, format);
- char *ptr;
- if (vasprintf(&ptr,fmt,ap)==-1) return;
- va_end(ap);
- esyslog(ptr);
- add2Log('E',ptr+20+strlen(name));
- free(ptr);
-}
-
-void cEPGSource::Tlog(const char *format, ...)
-{
- va_list ap;
- char fmt[255];
- if (snprintf(fmt,sizeof(fmt),"xmltv2vdr: '%s' %s",name,format)==-1) return;
- va_start(ap, format);
- char *ptr;
- if (vasprintf(&ptr,fmt,ap)==-1) return;
- va_end(ap);
- //tsyslog(ptr);
- add2Log('D',ptr+14+strlen(name));
- free(ptr);
-}
-
-void cEPGSource::Dlog(const char *format, ...)
-{
- va_list ap;
- char fmt[255];
- if (snprintf(fmt,sizeof(fmt),"xmltv2vdr: '%s' %s",name,format)==-1) return;
- va_start(ap, format);
- char *ptr;
- if (vasprintf(&ptr,fmt,ap)==-1) return;
- va_end(ap);
- dsyslog(ptr);
- add2Log('D',ptr+14+strlen(name));
- free(ptr);
-}
-
-void cEPGSource::Ilog(const char *format, ...)
-{
- va_list ap;
- char fmt[255];
- if (snprintf(fmt,sizeof(fmt),"xmltv2vdr: '%s' %s",name,format)==-1) return;
- va_start(ap, format);
- char *ptr;
- if (vasprintf(&ptr,fmt,ap)==-1) return;
- va_end(ap);
- isyslog(ptr);
- add2Log('I',ptr+14+strlen(name));
- free(ptr);
-}
-
// -------------------------------------------------------------
bool cEPGSources::Exists(const char* Name)
@@ -903,6 +837,7 @@ void cEPGSources::ReadIn(const char *ConfDir, const char *EpgFile, cEPGMappings
while (dirent=readdir(dir))
{
if (strchr(&dirent->d_name[0],'.')) continue;
+ if (dirent->d_type==4) continue;
if (!Exists(dirent->d_name))
{
char *path=NULL;
@@ -916,7 +851,7 @@ void cEPGSources::ReadIn(const char *ConfDir, const char *EpgFile, cEPGMappings
char id[5];
if (read(fd,id,4)!=4)
{
- esyslog("xmltv2vdr: cannot read config file '%s'",dirent->d_name);
+ esyslog("cannot read config file '%s'",dirent->d_name);
}
else
{
@@ -927,19 +862,19 @@ void cEPGSources::ReadIn(const char *ConfDir, const char *EpgFile, cEPGMappings
}
else
{
- dsyslog("xmltv2vdr: ignoring non config file '%s'",dirent->d_name);
+ dsyslog("ignoring non config file '%s'",dirent->d_name);
}
close(fd);
}
}
else
{
- esyslog("xmltv2vdr: cannot open config file '%s'",dirent->d_name);
+ esyslog("cannot open config file '%s'",dirent->d_name);
}
}
else
{
- esyslog("xmltv2vdr: cannot access config file '%s'",dirent->d_name);
+ esyslog("cannot access config file '%s'",dirent->d_name);
}
free(path);
}
@@ -971,7 +906,7 @@ void cEPGSources::ReadIn(const char *ConfDir, const char *EpgFile, cEPGMappings
{
if (disable)
{
- isyslog("xmltv2vdr: disabling source '%s'",Get(oldpos)->Name());
+ isyslog("disabling source '%s'",Get(oldpos)->Name());
Get(oldpos)->Disable();
}
if (oldpos!=newpos) Move(oldpos,newpos);
diff --git a/source.h b/source.h
index 94aab8a..d78a5f2 100644
--- a/source.h
+++ b/source.h
@@ -13,6 +13,7 @@
#include "maps.h"
#include "import.h"
#include "parse.h"
+#include "debug.h"
#define EPGSOURCES "/var/lib/epgsources" // NEVER (!) CHANGE THIS
@@ -65,7 +66,6 @@ private:
int exec_time;
int daysmax;
int lastretcode;
- void add2Log(const char prefix, const char *line);
bool ReadConfig();
int ReadOutput(char *&result, size_t &l);
cEPGChannels channels;
@@ -73,6 +73,10 @@ public:
cEPGSource(const char *Name,const char *ConfDir,const char *EPGFile,
cEPGMappings *Maps, cTEXTMappings *Texts);
~cEPGSource();
+ bool Trace()
+ {
+ return (logfile!=NULL);
+ }
int Execute(cEPGExecutor &myExecutor);
int Import(cEPGExecutor &myExecutor);
bool RunItNow();
@@ -142,10 +146,7 @@ public:
if (pin) free((void *) pin);
pin=strdup(NewPin);
}
- void Tlog(const char *format, ...);
- void Dlog(const char *format, ...);
- void Elog(const char *format, ...);
- void Ilog(const char *format, ...);
+ void Add2Log(struct tm *Tm, const char Prefix, const char *Line);
bool Active()
{
return running;
@@ -171,9 +172,8 @@ class cEPGExecutor : public cThread
{
private:
cEPGSources *sources;
- cPluginXmltv2vdr *baseplugin;
public:
- cEPGExecutor(cPluginXmltv2vdr *Plugin, cEPGSources *Sources);
+ cEPGExecutor(cEPGSources *Sources);
bool StillRunning()
{
return Running();
diff --git a/xmltv2vdr.cpp b/xmltv2vdr.cpp
index 48899a0..e8430b5 100644
--- a/xmltv2vdr.cpp
+++ b/xmltv2vdr.cpp
@@ -9,10 +9,11 @@
#include <vdr/videodir.h>
#include <unistd.h>
#include <getopt.h>
-#include <pthread.h>
+#include <stdarg.h>
#include "setup.h"
#include "xmltv2vdr.h"
+#include "debug.h"
int ioprio_set(int which, int who, int ioprio)
{
@@ -37,60 +38,97 @@ int ioprio_set(int which, int who, int ioprio)
}
}
-// -------------------------------------------------------------
+char *logfile=NULL;
-cEPGHandlerState::cEPGHandlerState()
+void logger(cEPGSource *source, char logtype, const char* format, ...)
{
- xevent=NULL;
- Clear();
-}
+ va_list ap;
+ char fmt[255];
+ if (source && logtype!='T')
+ {
+ if (logtype=='E')
+ {
+ if (snprintf(fmt,sizeof(fmt),"xmltv2vdr: '%s' ERROR %s",source->Name(),format)==-1) return;
+ }
+ else
+ {
+ if (snprintf(fmt,sizeof(fmt),"xmltv2vdr: '%s' %s",source->Name(),format)==-1) return;
+ }
+ }
+ else
+ {
+ if (logtype=='E')
+ {
+ snprintf(fmt,sizeof(fmt),"xmltv2vdr: ERROR %s",format);
+ }
+ else
+ {
+ snprintf(fmt,sizeof(fmt),"xmltv2vdr: %s",format);
+ }
+ }
-cEPGHandlerState::~cEPGHandlerState()
-{
- Clear();
-}
+ va_start(ap, format);
+ char *ptr;
+ if (vasprintf(&ptr,fmt,ap)==-1) return;
+ va_end(ap);
-void cEPGHandlerState::Clear()
-{
- if (xevent)
+ struct tm tm;
+ if (logfile || source)
{
- delete xevent;
- xevent=NULL;
+ time_t now=time(NULL);
+ localtime_r(&now,&tm);
}
- source=NULL;
- flags=0;
-}
+ char *crlf=strchr(ptr,'\n');
+ if (crlf) *crlf=0;
+ crlf=strchr(ptr,'\r');
+ if (crlf) *crlf=0;
-void cEPGHandlerState::Set(cEPGSource* Source, cXMLTVEvent* xEvent, int Flags)
-{
- Clear();
- source=Source;
- xevent=xEvent;
- flags=Flags;
- if (ioprio_set(1,getpid(),7 | 3 << 13)==-1)
+ if (source && logtype!='T')
{
- esyslog("xmltv2vdr: failed to set ioprio to 3,7");
+ source->Add2Log(&tm,logtype,ptr);
}
-}
-bool cEPGHandlerState::isSame(tEventID EventID)
-{
- if (!xevent) return false;
- if (xevent->EITEventID()==EventID) return true;
- return false;
+ if (logfile)
+ {
+ char dt[30];
+ strftime(dt,sizeof(dt)-1,"%b %d %H:%M:%S",&tm);
+
+ FILE *l=fopen(logfile,"a+");
+ if (l)
+ {
+ fprintf(l,"%s [%i] %s\n",dt,cThread::ThreadId(),ptr);
+ fclose(l);
+ }
+ }
+ switch (logtype)
+ {
+ case 'E':
+ if (SysLogLevel>0) syslog_with_tid(LOG_ERR,"%s",ptr);
+ break;
+ case 'I':
+ if (SysLogLevel>1) syslog_with_tid(LOG_ERR,"%s",ptr);
+ break;
+ case 'D':
+ if (SysLogLevel>2) syslog_with_tid(LOG_ERR,"%s",ptr);
+ break;
+ default:
+ break;
+ }
+
+ free(ptr);
}
// -------------------------------------------------------------
-cEPGHandler::cEPGHandler(cPluginXmltv2vdr *Plugin, const char *EpgFile, cEPGSources *Sources,
+cEPGHandler::cEPGHandler(const char *EpgFile, cEPGSources *Sources,
cEPGMappings *Maps, cTEXTMappings *Texts)
{
- baseplugin=Plugin;
epall=false;
maps=Maps;
sources=Sources;
db=NULL;
+ epgfile = EpgFile;
import = new cImport(EpgFile,Maps,Texts);
}
@@ -106,27 +144,76 @@ bool cEPGHandler::IgnoreChannel(const cChannel* Channel)
return maps->IgnoreChannel(Channel);
}
-bool cEPGHandler::FixEpgBugs(cEvent* Event)
+bool cEPGHandler::check4proc(cEvent *event, bool &spth)
{
- if (!Event) return false;
- if (!maps) return false;
+ if (!event) return false;
if (!import) return false;
- if (!baseplugin) return false;
+ /*
+ if (import->WasChanged(event)) {
+ tsyslog("{%i} already seen %s",Event->EventID(),Event->Title());
+ }
+ */
+ if (!maps) return false;
+ struct stat statbuf;
+ if (stat(epgfile,&statbuf)==-1) return false; // no database? -> exit immediately
+ if (!statbuf.st_size) return false; // no database? -> exit immediately
- bool special_epall_timer_handling=false;
- if (!maps->ProcessChannel(Event->ChannelID()))
+ spth=false;
+ if (!maps->ProcessChannel(event->ChannelID()))
{
if (!epall) return false;
- if (!Event->HasTimer()) return false;
- if (!Event->ShortText()) return false;
- special_epall_timer_handling=true;
+ if (!event->HasTimer()) return false;
+ if (!event->ShortText()) return false;
+ spth=true;
}
+ return true;
+}
+
+bool cEPGHandler::SetShortText(cEvent* Event, const char* ShortText)
+{
+ bool notused;
+ if (!check4proc(Event,notused)) return false;
- if (!baseplugin->IsIdle(false))
+ if (import->WasChanged(Event))
{
- if (import->WasChanged(Event)) return true;
- return false;
+ // ok we already changed this event!
+ tsyslog("{%i} already seen stext %s",Event->EventID(),Event->Title());
+ return true;
}
+ if (!ShortText) return true; // prevent setting empty shorttext
+ if (!strlen(ShortText)) return true; // prevent setting empty shorttext
+ tsyslog("{%i} setting stext (%s) of %s",Event->EventID(),ShortText,Event->Title());
+ return false;
+}
+
+bool cEPGHandler::SetDescription(cEvent* Event, const char* Description)
+{
+ bool notused;
+ if (!check4proc(Event,notused)) return false;
+
+ if (import->WasChanged(Event))
+ {
+ // ok we already changed this event!
+ if (!Description) return true; // prevent setting nothing to description
+ int len=strlen(Description);
+ if (strncasecmp(Event->Description(),Description,len))
+ {
+ // eit description changed -> set it
+ tsyslog("{%i} changing descr of %s",Event->EventID(),Event->Title());
+ return false;
+ }
+ tsyslog("{%i} already seen descr %s",Event->EventID(),Event->Title());
+ return true;
+ }
+ tsyslog("{%i} setting descr of %s",Event->EventID(),Event->Title());
+ return false;
+}
+
+
+bool cEPGHandler::HandleEvent(cEvent* Event)
+{
+ bool special_epall_timer_handling=false;
+ if (!check4proc(Event,special_epall_timer_handling)) return false;
int Flags=0;
const char *ChannelID;
@@ -134,24 +221,38 @@ bool cEPGHandler::FixEpgBugs(cEvent* Event)
if (special_epall_timer_handling)
{
cChannel *chan=Channels.GetByChannelID(Event->ChannelID());
- if (!chan) return false;
+ if (!chan)
+ {
+ tsyslog("no channel for %s",*Event->ChannelID().ToString());
+ return false;
+ }
Flags=USE_SEASON;
ChannelID=chan->Name();
}
else
{
cEPGMapping *map=maps->GetMap(Event->ChannelID());
- if (!map) return false;
+ if (!map)
+ {
+ tsyslog("no map for channel %s",*Event->ChannelID().ToString());
+ return false;
+ }
Flags=map->Flags();
ChannelID=map->ChannelName();
}
+ if (ioprio_set(1,getpid(),7 | 3 << 13)==-1)
+ {
+ tsyslog("failed to set ioprio to 3,7");
+ }
+
cEPGSource *source=NULL;
cXMLTVEvent *xevent=import->SearchXMLTVEvent(&db,ChannelID,Event);
if (!xevent)
{
if (!epall) return false;
source=sources->GetSource(EITSOURCE);
+ if (!source) tsyslog("no source for %s",EITSOURCE);
xevent=import->AddXMLTVEvent(source,db,ChannelID,Event,Event->Description());
if (!xevent) return false;
}
@@ -161,6 +262,7 @@ bool cEPGHandler::FixEpgBugs(cEvent* Event)
}
if (!source)
{
+ tsyslog("no source for %s",xevent->Source());
delete xevent;
return false;
}
@@ -169,17 +271,12 @@ bool cEPGHandler::FixEpgBugs(cEvent* Event)
if (!xevent->EITEventID()) update=true;
if (!xevent->EITDescription() && Event->Description()) update=true;
- if (xevent->EITDescription() && Event->Description() &&
+ if (xevent->EITDescription() && Event->Description() && !import->WasChanged(Event) &&
strcasecmp(xevent->EITDescription(),Event->Description())) update=true;
if (update)
{
- if (!import->UpdateXMLTVEvent(source,db,Event,xevent->EventID(),
- Event->EventID(),Event->Description()))
- {
- delete xevent;
- return false;
- }
+ import->UpdateXMLTVEvent(source,db,Event,xevent); // ignore errors
}
import->PutEvent(source,db,(cSchedule *) Event->Schedule(),Event,xevent,Flags);
@@ -187,213 +284,6 @@ bool cEPGHandler::FixEpgBugs(cEvent* Event)
return false; // let VDR fix the bugs!
}
-
-/*
-bool cEPGHandler::SetDescription(cEvent* Event, const char* Description)
-{
- if (!Event) return false;
- if (!maps) return false;
- if (!import) return false;
- if (!baseplugin) return false;
-
- if (!last.isSame(Event->EventID()))
- {
- last.Clear();
- bool special_epall_timer_handling=false;
- if (!maps->ProcessChannel(Event->ChannelID()))
- {
- if (!epall) return false;
- if (!Event->HasTimer()) return false;
- if (!Event->ShortText()) return false;
- special_epall_timer_handling=true;
- }
-
- if (!baseplugin->IsIdle(false))
- {
- if (import->WasChanged(Event)) return true;
- return false;
- }
-
- int Flags=0;
- const char *ChannelID;
-
- if (special_epall_timer_handling)
- {
- cChannel *chan=Channels.GetByChannelID(Event->ChannelID());
- if (!chan) return false;
- Flags=USE_SEASON;
- ChannelID=chan->Name();
- }
- else
- {
- cEPGMapping *map=maps->GetMap(Event->ChannelID());
- if (!map) return false;
- Flags=map->Flags();
- ChannelID=map->ChannelName();
- }
-
- cXMLTVEvent *xevent=import->SearchXMLTVEvent(&db,ChannelID,Event);
- cEPGSource *source=NULL;
- if (!xevent)
- {
- if (!epall) return false;
- source=sources->GetSource(EITSOURCE);
- xevent=import->AddXMLTVEvent(source,db,ChannelID,Event,Description);
- if (!xevent) return false;
- }
- else
- {
- source=sources->GetSource(xevent->Source());
- }
- if (!source) return false;
- last.Set(source,xevent,Flags);
- }
- else
- {
- if (!baseplugin->IsIdle(false))
- {
- if (import->WasChanged(Event)) return true;
- return false;
- }
- }
-
- bool update=false;
-
- if (!last.xEvent()->EITEventID()) update=true;
- if (!last.xEvent()->EITDescription() && Description) update=true;
- if (last.xEvent()->EITDescription() && Description &&
- strcasecmp(last.xEvent()->EITDescription(),Description)) update=true;
-
- if (update)
- {
- if (!import->UpdateXMLTVEvent(last.Source(),db,Event,last.xEvent()->EventID(),
- Event->EventID(),Description))
- {
- return false;
- }
- }
-
- return import->PutEvent(last.Source(),db,
- (cSchedule *) Event->Schedule(),
- Event,last.xEvent(),last.Flags(),IMPORT_DESCRIPTION);
-}
-
-bool cEPGHandler::SetContents(cEvent* UNUSED(Event), uchar* UNUSED(Contents))
-{
- return false;
-}
-
-bool cEPGHandler::SetParentalRating(cEvent* Event, int ParentalRating)
-{
- if (!Event) return false;
- if (!maps) return false;
- if (!import) return false;
-
- if (!last.isSame(Event->EventID()))
- {
- last.Clear();
-
- if (!maps->ProcessChannel(Event->ChannelID())) return false;
-
- if (!baseplugin->IsIdle(false))
- {
- if (import->WasChanged(Event)) return true;
- return false;
- }
-
- cEPGMapping *map=maps->GetMap(Event->ChannelID());
- if (!map) return false;
-
- cXMLTVEvent *xevent=import->SearchXMLTVEvent(&db,map->ChannelName(),Event);
- if (!xevent) return false;
-
- cEPGSource *source=sources->GetSource(xevent->Source());
- if (!source)
- {
- delete xevent;
- return false;
- }
-
- if (!xevent->EITEventID())
- {
- if (!import->UpdateXMLTVEvent(source,db,Event,xevent->EventID(),Event->EventID()))
- {
- delete xevent;
- return false;
- }
- }
- last.Set(source,xevent,map->Flags());
- }
- else
- {
- if (!baseplugin->IsIdle(false))
- {
- if (import->WasChanged(Event)) return true;
- return false;
- }
- }
-
- if (ParentalRating>last.xEvent()->ParentalRating()) return false; // use dvb value
- if (Event->ParentalRating()!=last.xEvent()->ParentalRating())
- {
- last.Source()->Tlog("changing rating of '%s'",Event->Title());
- Event->SetParentalRating(last.xEvent()->ParentalRating());
- }
- return true;
-}
-
-bool cEPGHandler::SetShortText(cEvent* Event, const char* UNUSED(ShortText))
-{
- if (!Event) return false;
- if (!maps) return false;
- if (!import) return false;
-
- if (!last.isSame(Event->EventID()))
- {
- last.Clear();
- if (!maps->ProcessChannel(Event->ChannelID())) return false;
-
- if (!baseplugin->IsIdle(false))
- {
- if (import->WasChanged(Event)) return true;
- return false;
- }
- cEPGMapping *map=maps->GetMap(Event->ChannelID());
- if (!map) return false;
-
- cXMLTVEvent *xevent=import->SearchXMLTVEvent(&db,map->ChannelName(),Event);
- if (!xevent) return false;
-
- cEPGSource *source=sources->GetSource(xevent->Source());
- if (!source)
- {
- delete xevent;
- return false;
- }
-
- if (!xevent->EITEventID()) import->UpdateXMLTVEvent(source,db,Event,xevent->EventID(),
- Event->EventID());
- last.Set(source,xevent,map->Flags());
- }
- else
- {
- if (!baseplugin->IsIdle(false))
- {
- if (import->WasChanged(Event)) return true;
- return false;
- }
- }
-
- bool ret=import->PutEvent(last.Source(),db,(cSchedule *) Event->Schedule(),Event,last.xEvent(),
- last.Flags(),IMPORT_SHORTTEXT);
- if (!ret)
- {
- dsyslog("xmltv2vdr: failed to put event shorttext!");
- }
- return ret;
-}
-*/
-
bool cEPGHandler::SortSchedule(cSchedule* UNUSED(Schedule))
{
if (db)
@@ -427,11 +317,13 @@ void cEPGTimer::Action()
SetPriority(19);
if (ioprio_set(1,getpid(),7 | 3 << 13)==-1)
{
- esyslog("xmltv2vdr: failed to set ioprio to 3,7");
+ dsyslog("failed to set ioprio to 3,7");
}
- cSchedulesLock *schedulesLock = new cSchedulesLock(true,2000); // wait up to 2 secs for lock!
- const cSchedules *schedules = cSchedules::Schedules(*schedulesLock);
+ cSchedulesLock *schedulesLock = NULL;
+ const cSchedules *schedules = NULL;
+ schedulesLock = new cSchedulesLock(true,10); // wait 10ms for lock!
+ schedules = cSchedules::Schedules(*schedulesLock);
if (!schedules)
{
delete schedulesLock;
@@ -463,8 +355,7 @@ void cEPGTimer::Action()
cSchedule* schedule = (cSchedule *) schedules->GetSchedule(chan,false);
if (schedule)
{
- import->PutEvent(source,db,schedule,
- event,xevent,USE_SEASON,IMPORT_DESCRIPTION);
+ import->PutEvent(source,db,schedule,event,xevent,USE_SEASON);
}
delete xevent;
}
@@ -482,11 +373,21 @@ void cEPGTimer::Action()
cHouseKeeping::cHouseKeeping(const char *EPGFile): cThread("xmltv2vdr housekeeping")
{
- epgfile=EPGFile;;
+ epgfile=EPGFile;
}
void cHouseKeeping::Action()
{
+ cSchedulesLock *schedulesLock = NULL;
+ const cSchedules *schedules = NULL;
+ schedulesLock = new cSchedulesLock(true,10); // wait 10ms for lock!
+ schedules = cSchedules::Schedules(*schedulesLock);
+ if (!schedules)
+ {
+ delete schedulesLock;
+ return;
+ }
+
sqlite3 *db=NULL;
if (sqlite3_open_v2(epgfile,&db,SQLITE_OPEN_READWRITE,NULL)==SQLITE_OK)
{
@@ -496,7 +397,7 @@ void cHouseKeeping::Action()
char *errmsg;
if (sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
- esyslog("xmltv2vdr: %s",errmsg);
+ esyslog("%s",errmsg);
sqlite3_free(errmsg);
}
else
@@ -504,7 +405,7 @@ void cHouseKeeping::Action()
int changes=sqlite3_changes(db);
if (changes)
{
- isyslog("xmltv2vdr: removed %i old entries from db",changes);
+ isyslog("removed %i old entries from db",changes);
sqlite3_exec(db,"VACCUM;",NULL,NULL,NULL);
}
}
@@ -512,17 +413,19 @@ void cHouseKeeping::Action()
}
}
sqlite3_close(db);
+ delete schedulesLock;
}
// -------------------------------------------------------------
-cPluginXmltv2vdr::cPluginXmltv2vdr(void) : epgexecutor(this, &epgsources)
+cPluginXmltv2vdr::cPluginXmltv2vdr(void) : epgexecutor(&epgsources)
{
// Initialize any member variables here.
// DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL
// VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT!
confdir=NULL;
epgfile=NULL;
+ logfile=NULL;
srcorder=NULL;
epghandler=NULL;
epgtimer=NULL;
@@ -567,40 +470,9 @@ cPluginXmltv2vdr::~cPluginXmltv2vdr()
#endif
}
-bool cPluginXmltv2vdr::IsIdle(bool IncludeHandler)
-{
- if (IncludeHandler)
- {
- if (!insetup && !epgexecutor.Active() && (!epgtimer->Active()) && (!epghandler->Active())) return true;
- }
- else
- {
- if (!insetup && !epgexecutor.Active() && (!epgtimer->Active())) return true;
- }
- return false;
-}
-
-void cPluginXmltv2vdr::Wait4TimerThreadAndSetup()
-{
- if (epgtimer->Active())
- {
- dsyslog("xmltv2vdr: wait for timer thread");
- pthread_join(epgtimer->ThreadId(),NULL);
- }
- if (insetup)
- {
- dsyslog("xmltv2vdr: wait for setup change");
- while (insetup)
- {
- usleep(200000);
- }
- }
-}
-
bool cPluginXmltv2vdr::EPGSourceMove(int From, int To)
{
if (From==To) return false;
- if (epgexecutor.Active() || epgtimer->Active() || epghandler->Active()) return true;
sqlite3 *db=NULL;
if (sqlite3_open_v2(epgfile,&db,SQLITE_OPEN_READWRITE,NULL)==SQLITE_OK)
@@ -634,7 +506,10 @@ const char *cPluginXmltv2vdr::CommandLineHelp(void)
// Return a string that describes all known command line options.
return " -E FILE, --epgfile=FILE write the EPG data into the given FILE (default is\n"
" 'epg.db' in the video directory) - best performance\n"
- " if located on a ramdisk\n";
+ " if located on a ramdisk\n"
+ " -l FILE --logfile=FILE write trace logs into the given FILE (default is\n"
+ " no trace log\n";
+
}
bool cPluginXmltv2vdr::ProcessArgs(int argc, char *argv[])
@@ -642,20 +517,25 @@ bool cPluginXmltv2vdr::ProcessArgs(int argc, char *argv[])
// Command line argument processing
static struct option long_options[] =
{
- { "epgfile", required_argument, NULL, 'E'
- },
+ { "epgfile", required_argument, NULL, 'E'},
+ { "logfile", required_argument, NULL, 'l'},
{ 0,0,0,0 }
};
int c;
- while ((c = getopt_long(argc, argv, "E:", long_options, NULL)) != -1)
+ while ((c = getopt_long(argc, argv, "E:l:", long_options, NULL)) != -1)
{
switch (c)
{
case 'E':
if (epgfile) free(epgfile);
epgfile=strdup(optarg);
- isyslog("xmltv2vdr: using file '%s' for epgdata",optarg);
+ isyslog("using file '%s' for epgdata",optarg);
+ break;
+ case 'l':
+ if (logfile) free(logfile);
+ logfile=strdup(optarg);
+ isyslog("using file '%s' for log",optarg);
break;
default:
return false;
@@ -681,12 +561,15 @@ bool cPluginXmltv2vdr::Start(void)
}
cParse::InitLibXML();
+ dbmutex=sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
+ if (!dbmutex) return false;
+
ReadInEPGSources();
- epghandler = new cEPGHandler(this,epgfile,&epgsources,&epgmappings,&textmappings);
+ epghandler = new cEPGHandler(epgfile,&epgsources,&epgmappings,&textmappings);
epgtimer = new cEPGTimer(epgfile,&epgsources,&epgmappings,&textmappings);
housekeeping = new cHouseKeeping(epgfile);
- if (sqlite3_threadsafe()==0) esyslog("xmltv2vdr: ERROR sqlite3 not threadsafe!");
+ if (sqlite3_threadsafe()==0) esyslog("sqlite3 not threadsafe!");
return true;
}
@@ -702,6 +585,10 @@ void cPluginXmltv2vdr::Stop(void)
epgmappings.Remove();
textmappings.Remove();
cParse::CleanupLibXML();
+ if (dbmutex)
+ {
+ sqlite3_mutex_free(dbmutex);
+ }
if (confdir)
{
free(confdir);
@@ -712,6 +599,11 @@ void cPluginXmltv2vdr::Stop(void)
free(epgfile);
epgfile=NULL;
}
+ if (logfile)
+ {
+ free(logfile);
+ logfile=NULL;
+ }
if (srcorder)
{
free(srcorder);
@@ -725,7 +617,7 @@ void cPluginXmltv2vdr::Housekeeping(void)
time_t now=time(NULL);
if (now>(last_housetime_t+3600))
{
- if (IsIdle() && (housekeeping))
+ if (housekeeping)
{
struct stat statbuf;
if (stat(epgfile,&statbuf)!=-1)
@@ -757,10 +649,7 @@ void cPluginXmltv2vdr::MainThreadHook(void)
{
if (now>=(last_epcheck_t+600))
{
- if (IsIdle())
- {
- epgtimer->Start();
- }
+ epgtimer->Start();
last_epcheck_t=(now/600)*600;
}
}
diff --git a/xmltv2vdr.h b/xmltv2vdr.h
index ce431b2..419e4cc 100644
--- a/xmltv2vdr.h
+++ b/xmltv2vdr.h
@@ -36,29 +36,19 @@ public:
{
return false;
}
- virtual bool FixEpgBugs(cEvent *UNUSED(Event))
+ virtual bool SetShortText(cEvent *UNUSED(Event),const char *UNUSED(ShortText))
{
return false;
}
- /*
- virtual bool SetDescription(cEvent *UNUSED(Event), const char *UNUSED(Description))
+ virtual bool SetDescription(cEvent *UNUSED(Event),const char *UNUSED(Description))
{
return false;
}
- virtual bool SetContents(cEvent *UNUSED(Event), uchar *UNUSED(Contents))
+ virtual bool HandleEvent(cEvent *UNUSED(Event))
{
return false;
}
- virtual bool SetParentalRating(cEvent *UNUSED(Event), int UNUSED(ParentalRating))
- {
- return false;
- }
- virtual bool SetShortText(cEvent *UNUSED(Event), const char *UNUSED(ShortText))
- {
- return false;
- }
- */
- virtual bool SortSchedule(cSchedule *Schedule)
+ virtual bool SortSchedule(cSchedule *UNUSED(Schedule))
{
return false;
}
@@ -69,45 +59,19 @@ class cEPGSources;
class cImport;
class cPluginXmltv2vdr;
-class cEPGHandlerState
-{
-private:
- cXMLTVEvent *xevent;
- cEPGSource *source;
- int flags;
-public:
- cEPGHandlerState();
- ~cEPGHandlerState();
- void Clear();
- void Set(cEPGSource *Source, cXMLTVEvent *xEvent, int Flags);
- bool isSame(tEventID EventID);
- cXMLTVEvent *xEvent()
- {
- return xevent;
- }
- cEPGSource *Source()
- {
- return source;
- }
- int Flags()
- {
- return flags;
- }
-};
-
class cEPGHandler : public cEpgHandler
{
private:
- cPluginXmltv2vdr *baseplugin;
cEPGMappings *maps;
cEPGSources *sources;
cImport *import;
+ const char *epgfile;
bool epall;
sqlite3 *db;
void closedb(void);
- //cEPGHandlerState last;
+ bool check4proc(cEvent *event, bool &spth);
public:
- cEPGHandler(cPluginXmltv2vdr *Plugin, const char *EpgFile, cEPGSources *Sources,
+ cEPGHandler(const char *EpgFile, cEPGSources *Sources,
cEPGMappings *Maps, cTEXTMappings *Texts);
void SetEPAll(bool Value)
{
@@ -119,13 +83,9 @@ public:
}
virtual ~cEPGHandler();
virtual bool IgnoreChannel(const cChannel *Channel);
- virtual bool FixEpgBugs(cEvent *Event);
- /*
- virtual bool SetDescription(cEvent *Event, const char *Description);
- virtual bool SetContents(cEvent *Event, uchar *Contents);
- virtual bool SetParentalRating(cEvent *Event, int ParentalRating);
- virtual bool SetShortText(cEvent *Event, const char *ShortText);
- */
+ virtual bool SetShortText(cEvent *Event,const char *ShortText);
+ virtual bool SetDescription(cEvent *Event,const char *Description);
+ virtual bool HandleEvent(cEvent *Event);
virtual bool SortSchedule(cSchedule *Schedule);
};
@@ -137,8 +97,7 @@ private:
cEPGMappings *maps;
cImport *import;
public:
- cEPGTimer(const char *EpgFile, cEPGSources *Sources, cEPGMappings *Maps,
- cTEXTMappings *Texts);
+ cEPGTimer(const char *EpgFile, cEPGSources *Sources, cEPGMappings *Maps,cTEXTMappings *Texts);
bool StillRunning()
{
return Running();
@@ -169,6 +128,7 @@ private:
cEPGMappings epgmappings;
cEPGSources epgsources;
cTEXTMappings textmappings;
+ sqlite3_mutex *dbmutex;
time_t last_housetime_t;
time_t last_maintime_t;
time_t last_epcheck_t;
@@ -204,8 +164,6 @@ public:
{
epgsources.ReadIn(confdir,epgfile,&epgmappings,&textmappings,srcorder,Reload);
}
- void Wait4TimerThreadAndSetup();
- bool IsIdle(bool IncludeHandler=true);
bool EPGSourceMove(int From, int To);
int EPGSourceCount()
{