diff options
author | Jochen Dolze <vdr@dolze.de> | 2012-04-21 10:15:21 +0200 |
---|---|---|
committer | Jochen Dolze <vdr@dolze.de> | 2012-04-21 10:15:21 +0200 |
commit | 67c3cadd815a179880f44470eff16032d2cfb2fd (patch) | |
tree | 6e7a5b44f79b9cbd3a07f9f16115f68c2a5da1ec | |
parent | f0f09d02993596a3f3620c2c7de23a53b3303078 (diff) | |
download | vdr-plugin-xmltv2vdr-67c3cadd815a179880f44470eff16032d2cfb2fd.tar.gz vdr-plugin-xmltv2vdr-67c3cadd815a179880f44470eff16032d2cfb2fd.tar.bz2 |
Added logging to file with -l
-rw-r--r-- | import.cpp | 712 | ||||
-rw-r--r-- | import.h | 19 | ||||
-rw-r--r-- | parse.cpp | 55 | ||||
-rw-r--r-- | source.cpp | 175 | ||||
-rw-r--r-- | source.h | 14 | ||||
-rw-r--r-- | xmltv2vdr.cpp | 517 | ||||
-rw-r--r-- | xmltv2vdr.h | 66 |
7 files changed, 711 insertions, 847 deletions
@@ -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; } @@ -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); }; @@ -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; } @@ -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); @@ -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() { |