summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dist/epgdata2xmltv/epgdata2xmltv.xsl2
-rw-r--r--parse.cpp232
-rw-r--r--parse.h10
-rw-r--r--po/de_DE.po43
-rw-r--r--po/it_IT.po43
-rw-r--r--setup.cpp291
-rw-r--r--setup.h35
-rw-r--r--xmltv2vdr.cpp264
-rw-r--r--xmltv2vdr.h63
9 files changed, 756 insertions, 227 deletions
diff --git a/dist/epgdata2xmltv/epgdata2xmltv.xsl b/dist/epgdata2xmltv/epgdata2xmltv.xsl
index 4f68091..7eac71b 100644
--- a/dist/epgdata2xmltv/epgdata2xmltv.xsl
+++ b/dist/epgdata2xmltv/epgdata2xmltv.xsl
@@ -7,7 +7,7 @@
<xsl:template match="/">
<xsl:for-each select="//data[d2=$channelnum]">
-<xsl:sort select="d4"/>
+<!-- <xsl:sort select="d4"/> -->
<xsl:variable name="EVENTID">
<xsl:value-of select="d0"/>
</xsl:variable>
diff --git a/parse.cpp b/parse.cpp
index dc37265..58301fa 100644
--- a/parse.cpp
+++ b/parse.cpp
@@ -13,6 +13,7 @@
#include <unistd.h>
#include <locale.h>
#include <langinfo.h>
+#include <time.h>
#include "xmltv2vdr.h"
#include "parse.h"
@@ -22,7 +23,8 @@ extern char *strcatrealloc(char *dest, const char *src);
void cXMLTVEvent::SetTitle(const char *Title)
{
title = strcpyrealloc(title, Title);
- if (title) {
+ if (title)
+ {
title = compactspace(title);
}
}
@@ -332,7 +334,6 @@ char *cParse::RemoveNonASCII(const char *src)
cEvent *cParse::SearchEvent(cSchedule* schedule, cXMLTVEvent *xevent)
{
if (!xevent) return NULL;
- if (!xevent->Duration()) return NULL;
if (!xevent->StartTime()) return NULL;
if (!xevent->Title()) return NULL;
cEvent *f=NULL;
@@ -352,7 +353,8 @@ cEvent *cParse::SearchEvent(cSchedule* schedule, cXMLTVEvent *xevent)
if (f) return f;
// 3rd with StartTime +/- WaitTime
int maxdiff=INT_MAX;
- int eventTimeDiff=xevent->Duration()/4;
+ int eventTimeDiff=0;
+ if (xevent->Duration()) eventTimeDiff=xevent->Duration()/4;
if (eventTimeDiff<600) eventTimeDiff=600;
for (cEvent *p = schedule->Events()->First(); p; p = schedule->Events()->Next(p))
{
@@ -412,7 +414,7 @@ cEvent *cParse::SearchEvent(cSchedule* schedule, cXMLTVEvent *xevent)
if (diff<=maxdiff)
{
if (p->TableID()!=0)
- dsyslog("xmltv2vdr: '%s' found '%s' for '%s'",name,p->Title(),xevent->Title());
+ source->Dlog("found '%s' for '%s'",p->Title(),xevent->Title());
f=p;
maxdiff=diff;
}
@@ -423,43 +425,133 @@ cEvent *cParse::SearchEvent(cSchedule* schedule, cXMLTVEvent *xevent)
return f;
}
-bool cParse::PutEvent(cSchedule* schedule, cEvent *event, cXMLTVEvent *xevent, cEPGMapping *map,
- int mapindex)
+cEvent *cParse::GetEventBefore(cSchedule* schedule, time_t start)
+{
+ if (!schedule) return NULL;
+ if (!schedule->Events()) return NULL;
+ if (!schedule->Events()->Count()) return NULL;
+ cEvent *last=schedule->Events()->Last();
+ if ((last) && (last->StartTime()<start)) return last;
+ for (cEvent *p=schedule->Events()->First(); p; p=schedule->Events()->Next(p))
+ {
+ if (p->StartTime()>start)
+ {
+ return (cEvent *) p->Prev();
+ }
+ }
+ if (last) return last;
+ return NULL;
+}
+
+bool cParse::PutEvent(cSchedule* schedule, cEvent *event, cXMLTVEvent *xevent, cEPGMapping *map)
{
if (!schedule) return false;
if (!xevent) return false;
if (!map) return false;
- time_t start;
+ struct tm tm;
+ char from[80];
+ char till[80];
+ time_t start,end;
if (!event)
{
if ((map->Flags() & OPT_APPEND)==OPT_APPEND)
{
start=xevent->StartTime();
- /* checking the event sequence */
- cEvent *last=NULL;
- if (schedule->Index()) last=schedule->Events()->Last();
- if (last)
+ end=start+xevent->Duration();
+
+ /* checking the "space" for our new event */
+ cEvent *prev=GetEventBefore(schedule,start);
+ if (prev)
{
- if (start<last->StartTime())
+ if (cEvent *next=(cEvent *) prev->Next())
{
- esyslog("xmltv2vdr: '%s' ERROR xmltv data overlaps:",name);
- time_t lstart=last->StartTime();
- esyslog("xmltv2vdr: '%s' ERROR last event '%s' (%s) @%s", name,
- *schedule->ChannelID().ToString(),last->Title(),
- ctime(&lstart));
- esyslog("xmltv2vdr: '%s' ERROR next event '%s' (%s) @%s", name,
- *map->ChannelIDs()[mapindex].ToString(),xevent->Title(),
- ctime(&start));
- return false;
+ if (prev->EndTime()==next->StartTime())
+ {
+ 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->Elog("cannot add '%s'@%s-%s",xevent->Title(),from,till);
+
+ time_t pstart=prev->StartTime();
+ time_t pstop=prev->EndTime();
+ localtime_r(&pstart,&tm);
+ 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);
+
+ time_t nstart=next->StartTime();
+ time_t nstop=next->EndTime();
+ localtime_r(&nstart,&tm);
+ 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);
+ return false;
+ }
+
+ if (end>next->StartTime())
+ {
+ int diff=(int) difftime(prev->EndTime(),start);
+ if (diff>300)
+ {
+
+ 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->Elog("cannot add '%s'@%s-%s",xevent->Title(),from,till);
+
+ time_t nstart=next->StartTime();
+ time_t nstop=next->EndTime();
+ localtime_r(&nstart,&tm);
+ 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);
+ return false;
+ }
+ else
+ {
+ xevent->SetDuration(xevent->Duration()-diff);
+ }
+ }
}
- /* set duration, if it doesn't exist */
- if (!last->Duration()) last->SetDuration((int) difftime(start,
- last->StartTime()));
- if (start!=last->EndTime())
+
+ if (prev->EndTime()>start)
{
- esyslog("xmltv2vdr: '%s' detected gap of %is between events",name,
- (int) difftime(start,last->EndTime()));
+ int diff=(int) difftime(prev->EndTime(),start);
+ if (diff>300)
+ {
+ 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->Elog("cannot add '%s'@%s-%s",xevent->Title(),from,till);
+
+ time_t pstart=prev->StartTime();
+ time_t pstop=prev->EndTime();
+ localtime_r(&pstart,&tm);
+ 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);
+ return false;
+ }
+ else
+ {
+ prev->SetDuration(prev->Duration()-diff);
+ }
+ }
+
+ if (!xevent->Duration())
+ {
+ if (!prev->Duration())
+ {
+ prev->SetDuration(start-prev->StartTime());
+ }
}
}
/* add event */
@@ -473,7 +565,11 @@ bool cParse::PutEvent(cSchedule* schedule, cEvent *event, cXMLTVEvent *xevent, c
event->SetVersion(0);
schedule->AddEvent(event);
schedule->Sort();
- dsyslog("xmltv2vdr: '%s' adding event '%s' @%s",name,xevent->Title(),ctime(&start));
+ 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->Dlog("adding '%s'@%s-%s",xevent->Title(),from,till);
}
else
{
@@ -484,7 +580,12 @@ bool cParse::PutEvent(cSchedule* schedule, cEvent *event, cXMLTVEvent *xevent, c
{
if (event->TableID()==0) return true;
start=event->StartTime();
- dsyslog("xmltv2vdr: '%s' changing event '%s' @%s",name,event->Title(),ctime(&start));
+ 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->Dlog("changing '%s'@%s-%s",event->Title(),from,till);
}
if ((map->Flags() & USE_SHORTTEXT)==USE_SHORTTEXT)
{
@@ -492,7 +593,7 @@ bool cParse::PutEvent(cSchedule* schedule, cEvent *event, cXMLTVEvent *xevent, c
{
if (!strcmp(xevent->ShortText(),event->Title()))
{
- dsyslog("xmltv2vdr: '%s' title and subtitle equal, clearing subtitle",name);
+ source->Dlog("title and subtitle equal, clearing subtitle");
event->SetShortText("");
}
else
@@ -830,7 +931,7 @@ bool cParse::FetchEvent(xmlNodePtr enode)
}
else
{
- esyslog("xmltv2vdr: '%s' unknown element %s, please report!",name,node->name);
+ source->Elog("unknown element %s, please report!",node->name);
}
}
node=node->next;
@@ -865,26 +966,29 @@ int cParse::Process(cEPGExecutor &myExecutor,char *buffer, int bufsize)
xmlDocPtr xmltv;
xmltv=xmlReadMemory(buffer,bufsize,NULL,NULL,0);
- if (!xmltv) {
- esyslog("xmltv2vdr: '%s' ERROR failed to parse xmltv",name);
+ if (!xmltv)
+ {
+ source->Elog("failed to parse xmltv");
return 141;
}
xmlNodePtr rootnode=xmlDocGetRootElement(xmltv);
if (!rootnode)
{
- esyslog("xmltv2vdr: '%s' ERROR no rootnode in xmltv",name);
+ source->Elog("no rootnode in xmltv");
xmlFreeDoc(xmltv);
return 141;
}
const cSchedules *schedules=NULL;
int l=0;
- while (l<300) {
+ while (l<300)
+ {
cSchedulesLock schedulesLock(true,200); // wait up to 60 secs for lock!
schedules = cSchedules::Schedules(schedulesLock);
- if (!myExecutor.StillRunning()) {
- isyslog("xmltv2vdr: '%s' request to stop from vdr",name);
+ if (!myExecutor.StillRunning())
+ {
+ source->Ilog("request to stop from vdr");
return 0;
}
if (schedules) break;
@@ -893,7 +997,7 @@ int cParse::Process(cEPGExecutor &myExecutor,char *buffer, int bufsize)
if (!schedules)
{
- esyslog("xmltv2vdr: '%s' cannot get schedules now, trying later",name);
+ source->Elog("cannot get schedules now, trying later");
return 1;
}
@@ -917,7 +1021,7 @@ int cParse::Process(cEPGExecutor &myExecutor,char *buffer, int bufsize)
if (!channelid)
{
if (lerr!=PARSE_NOCHANNELID)
- esyslog("xmltv2vdr: '%s' ERROR missing channelid in xmltv file",name);
+ source->Elog("missing channelid in xmltv file");
lerr=PARSE_NOCHANNELID;
node=node->next;
continue;
@@ -926,7 +1030,7 @@ int cParse::Process(cEPGExecutor &myExecutor,char *buffer, int bufsize)
if (!map)
{
if (lerr!=PARSE_NOMAPPING)
- esyslog("xmltv2vdr: '%s' ERROR no mapping for channelid %s",name,channelid);
+ source->Elog("no mapping for channelid %s",channelid);
lerr=PARSE_NOMAPPING;
xmlFree(channelid);
node=node->next;
@@ -957,7 +1061,7 @@ int cParse::Process(cEPGExecutor &myExecutor,char *buffer, int bufsize)
if (!starttime)
{
if (lerr!=PARSE_XMLTVERR)
- esyslog("xmltv2vdr: ERROR '%s' no starttime, check xmltv file",name);
+ source->Elog("xmltv2vdr: '%s' no starttime, check xmltv file");
lerr=PARSE_XMLTVERR;
xmlFree(channelid);
node=node->next;
@@ -974,9 +1078,9 @@ int cParse::Process(cEPGExecutor &myExecutor,char *buffer, int bufsize)
if (oldmap!=map)
{
- dsyslog("xmltv2vdr: '%s' processing '%s'",name,channelid);
- dsyslog("xmltv2vdr: '%s' from %s",name,ctime(&begin));
- dsyslog("xmltv2vdr: '%s' till %s",name,ctime(&end));
+ source->Dlog("processing '%s'",channelid);
+ source->Dlog("from %s",ctime_r(&begin,(char *) &cbuf));
+ source->Dlog("till %s",ctime_r(&end,(char *) &cbuf));
}
oldmap=map;
xmlFree(channelid);
@@ -996,7 +1100,7 @@ int cParse::Process(cEPGExecutor &myExecutor,char *buffer, int bufsize)
if (stoptime) xevent.SetDuration(stoptime-starttime);
if (!FetchEvent(node)) // sets xevent
{
- dsyslog("xmltv2vdr: '%s' failed to fetch event",name);
+ source->Dlog("failed to fetch event");
node=node->next;
continue;
}
@@ -1009,8 +1113,8 @@ int cParse::Process(cEPGExecutor &myExecutor,char *buffer, int bufsize)
if (!channel)
{
if (lerr!=PARSE_NOCHANNEL)
- esyslog("xmltv2vdr: '%s' channel %s not found in channels.conf",
- name,*map->ChannelIDs()[i].ToString());
+ source->Elog("channel %s not found in channels.conf",
+ *map->ChannelIDs()[i].ToString());
lerr=PARSE_NOCHANNEL;
continue;
}
@@ -1018,23 +1122,24 @@ int cParse::Process(cEPGExecutor &myExecutor,char *buffer, int bufsize)
if (!schedule)
{
if (lerr!=PARSE_NOSCHEDULE)
- esyslog("xmltv2vdr: '%s' ERROR cannot get schedule for channel %s%s",
- name,channel->Name(),addevents ? "" : " - try add option");
+ source->Elog("cannot get schedule for channel %s%s",
+ channel->Name(),addevents ? "" : " - try add option");
lerr=PARSE_NOSCHEDULE;
continue;
}
if (addevents)
{
cEvent *event=SearchEvent(schedule,&xevent);
- PutEvent(schedule,event,&xevent,map,i);
+ if (!event)
+ PutEvent(schedule,event,&xevent,map);
}
else
{
if (!schedule->Index())
{
if (lerr!=PARSE_EMPTYSCHEDULE)
- esyslog("xmltv2vdr: '%s' ERROR cannot merge into empty epg (%s) - try add option",
- name,channel->Name());
+ source->Elog("cannot merge into empty epg (%s) - try add option",
+ channel->Name());
lerr=PARSE_EMPTYSCHEDULE;
}
else
@@ -1044,22 +1149,23 @@ int cParse::Process(cEPGExecutor &myExecutor,char *buffer, int bufsize)
{
if ((event=SearchEvent(schedule,&xevent)))
{
- PutEvent(schedule,event,&xevent,map,i);
+ PutEvent(schedule,event,&xevent,map);
}
else
{
time_t start=xevent.StartTime();
- esyslog("xmltv2vdr: '%s' cannot find existing event in epg.data for xmltv-event %s@%s",
- name,xevent.Title(),ctime(&start));
+ source->Elog("cannot find existing event in epg.data for xmltv-event %s@%s",
+ xevent.Title(),ctime_r(&start,(char *) &cbuf));
}
}
}
}
}
node=node->next;
- if (!myExecutor.StillRunning()) {
+ if (!myExecutor.StillRunning())
+ {
xmlFreeDoc(xmltv);
- isyslog("xmltv2vdr: '%s' request to stop from vdr",name);
+ source->Ilog("request to stop from vdr");
return 0;
}
}
@@ -1077,8 +1183,12 @@ void cParse::CleanupLibXML()
xmlCleanupParser();
}
-cParse::cParse(const char *Name, cEPGMappings *Maps, cTEXTMappings *Texts)
+cParse::cParse(cEPGSource *Source, cEPGMappings *Maps, cTEXTMappings *Texts)
{
+ source=Source;
+ maps=Maps;
+ texts=Texts;
+
char *CodeSet=NULL;
if (setlocale(LC_CTYPE,""))
CodeSet=nl_langinfo(CODESET);
@@ -1092,15 +1202,11 @@ cParse::cParse(const char *Name, cEPGMappings *Maps, cTEXTMappings *Texts)
CodeSet++;
}
}
- dsyslog("xmltv2vdr: '%s' vdr codeset is '%s'",Name,CodeSet ? CodeSet : "US-ASCII//TRANSLIT");
+ source->Dlog("vdr codeset is '%s'",CodeSet ? CodeSet : "US-ASCII//TRANSLIT");
conv = new cCharSetConv("UTF-8",CodeSet ? CodeSet : "US-ASCII//TRANSLIT");
- name=strdup(Name);
- maps=Maps;
- texts=Texts;
}
cParse::~cParse()
{
delete conv;
- free(name);
}
diff --git a/parse.h b/parse.h
index 90c24b0..3d4f1e0 100644
--- a/parse.h
+++ b/parse.h
@@ -16,6 +16,7 @@
#include "maps.h"
class cEPGExecutor;
+class cEPGSource;
class cXMLTVEvent
{
@@ -158,11 +159,12 @@ class cParse
};
private:
- char *name;
+ cEPGSource *source;
cEPGMappings *maps;
cTEXTMappings *texts;
cXMLTVEvent xevent;
cCharSetConv *conv;
+ char cbuf[80];
char *RemoveNonASCII(const char *src);
struct split split(char *in, char delim);
u_long DoSum(u_long sum, const char *buf, int nBytes);
@@ -171,10 +173,10 @@ private:
bool FetchEvent(xmlNodePtr node);
cEPGMapping *EPGMapping(const char *ChannelName);
cTEXTMapping *TEXTMapping(const char *Name);
- bool PutEvent(cSchedule* schedule,cEvent *event,cXMLTVEvent *xevent, cEPGMapping *map,
- int mapindex);
+ bool PutEvent(cSchedule* schedule,cEvent *event,cXMLTVEvent *xevent, cEPGMapping *map);
+ cEvent *GetEventBefore(cSchedule *schedule, time_t start);
public:
- cParse(const char *Name, cEPGMappings *Maps, cTEXTMappings *Texts);
+ cParse(cEPGSource *Source, cEPGMappings *Maps, cTEXTMappings *Texts);
~cParse();
int Process(cEPGExecutor &myExecutor, char *buffer, int bufsize);
static void InitLibXML();
diff --git a/po/de_DE.po b/po/de_DE.po
index 728c8ea..6e9f045 100644
--- a/po/de_DE.po
+++ b/po/de_DE.po
@@ -4,7 +4,7 @@ msgid ""
msgstr ""
"Project-Id-Version: vdr\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2011-08-01 00:24+0200\n"
+"POT-Creation-Date: 2011-08-07 18:55+0200\n"
"PO-Revision-Date: 2010-12-23 23:59+0100\n"
"Last-Translator: Jochen Dolze <vdr@dolze.de>\n"
"Language-Team: <vdr@linuxtv.org>\n"
@@ -16,15 +16,21 @@ msgstr ""
msgid "options"
msgstr "Optionen"
-msgid "update on start"
-msgstr "ausführen beim Start"
+msgid "update"
+msgstr "Ausführung"
-msgid "automatic wakeup"
-msgstr "automatisch Aufwachen"
+msgid "on time"
+msgstr "Zeitpunkt"
-msgid "execution time"
+msgid "on start"
+msgstr "beim Start"
+
+msgid "update at"
msgstr "Ausführung um"
+msgid "automatic wakeup"
+msgstr "automatisch Aufwachen"
+
msgid "text mapping"
msgstr "Textzuordnungen"
@@ -46,6 +52,9 @@ msgstr "hoch"
msgid "Button$Down"
msgstr "runter"
+msgid "Button$Log"
+msgstr "Log"
+
msgid "Button$Edit"
msgstr "editieren"
@@ -106,6 +115,27 @@ msgstr "Originaltitel"
msgid "credits"
msgstr "Mitwirkende"
+msgid "overview"
+msgstr "Übersicht"
+
+msgid "last execution"
+msgstr "Letzte Ausführung"
+
+msgid "active"
+msgstr "aktiv"
+
+msgid "log"
+msgstr "Logdatei"
+
+msgid "Button$Errors"
+msgstr "Fehler"
+
+msgid "Button$Info"
+msgstr "Info"
+
+msgid "Button$Debug"
+msgstr "Debug"
+
msgid "days in advance"
msgstr "Anzahl Tage"
@@ -201,3 +231,4 @@ msgstr "xmltv2vdr plugin ist noch aktiv"
msgid "Imports xmltv epg into vdr"
msgstr "Importiert xmltv epg in den VDR"
+
diff --git a/po/it_IT.po b/po/it_IT.po
index e9c0dac..deb796c 100644
--- a/po/it_IT.po
+++ b/po/it_IT.po
@@ -4,7 +4,7 @@ msgid ""
msgstr ""
"Project-Id-Version: vdr\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2011-08-01 00:24+0200\n"
+"POT-Creation-Date: 2011-08-07 18:55+0200\n"
"PO-Revision-Date: 2011-03-05 15:45+0100\n"
"Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n"
"Language-Team: <vdr@linuxtv.org>\n"
@@ -19,15 +19,21 @@ msgstr ""
msgid "options"
msgstr "Opzioni"
-msgid "update on start"
-msgstr "aggiorna all'avvio"
+msgid "update"
+msgstr ""
-msgid "automatic wakeup"
-msgstr "Risveglio automatico"
+msgid "on time"
+msgstr ""
-msgid "execution time"
+msgid "on start"
+msgstr ""
+
+msgid "update at"
msgstr "Ora esecuzione"
+msgid "automatic wakeup"
+msgstr "Risveglio automatico"
+
msgid "text mapping"
msgstr "Mappatura testo"
@@ -49,6 +55,9 @@ msgstr "Su"
msgid "Button$Down"
msgstr "Giu"
+msgid "Button$Log"
+msgstr ""
+
msgid "Button$Edit"
msgstr "Modifica"
@@ -109,6 +118,27 @@ msgstr "Titolo originale"
msgid "credits"
msgstr "Crediti"
+msgid "overview"
+msgstr ""
+
+msgid "last execution"
+msgstr ""
+
+msgid "active"
+msgstr ""
+
+msgid "log"
+msgstr ""
+
+msgid "Button$Errors"
+msgstr ""
+
+msgid "Button$Info"
+msgstr ""
+
+msgid "Button$Debug"
+msgstr ""
+
msgid "days in advance"
msgstr "Giorni in anticipo"
@@ -204,3 +234,4 @@ msgstr "Plugin XMLTV2VDR ancora in esecuzione"
msgid "Imports xmltv epg into vdr"
msgstr "Importa EPG di XMLTV in VDR"
+
diff --git a/setup.cpp b/setup.cpp
index d30289b..82d5b6f 100644
--- a/setup.cpp
+++ b/setup.cpp
@@ -8,9 +8,12 @@
#include "setup.h"
#include <vdr/osdbase.h>
+#include <time.h>
#define CHNUMWIDTH (numdigits(Channels.MaxNumber())+1)
+#define NewTitle(x) new cOsdItem(cString::sprintf("%s%s%s", "---- ",x," ----"),osUnknown,false)
+
char *strcatrealloc(char *dest, const char *src)
{
if (!src || !*src)
@@ -54,8 +57,8 @@ cMenuSetupXmltv2vdr::cMenuSetupXmltv2vdr(cPluginXmltv2vdr *Plugin)
{
baseplugin=Plugin;
sourcesBegin=sourcesEnd=mappingBegin=mappingEnd=mappingEntry=0;
- wakeup=baseplugin->WakeUp;
- upstart=baseplugin->UpStart;
+ wakeup=(int) baseplugin->WakeUp;
+ upstart=(int) baseplugin->UpStart;
exectime=baseplugin->ExecTime();
cs=NULL;
cm=NULL;
@@ -73,14 +76,19 @@ void cMenuSetupXmltv2vdr::Output(void)
if (!baseplugin) return;
int current=Current();
Clear();
- cOsdItem *first=newtitle(tr("options"));
+ cOsdItem *first=NewTitle(tr("options"));
Add(first,true);
- Add(new cMenuEditBoolItem(tr("update on start"),&upstart),true);
- Add(new cMenuEditBoolItem(tr("automatic wakeup"),&wakeup),true);
- Add(new cMenuEditTimeItem(tr("execution time"),&exectime),true);
+
+ Add(new cMenuEditBoolItem(tr("update"),&upstart,tr("on time"),tr("on start")),true);
+ updateEntry=Current();
+ if (!upstart)
+ {
+ Add(new cMenuEditTimeItem(tr("update at"),&exectime),true);
+ Add(new cMenuEditBoolItem(tr("automatic wakeup"),&wakeup),true);
+ }
Add(new cOsdItem(tr("text mapping")),true);
mappingEntry=Current();
- Add(newtitle(tr("epg sources")),true);
+ Add(NewTitle(tr("epg sources")),true);
if (!baseplugin->EPGSourceCount())
{
@@ -103,7 +111,7 @@ void cMenuSetupXmltv2vdr::Output(void)
}
sourcesEnd=Current();
- Add(newtitle(tr("epg source channels")),true);
+ Add(NewTitle(tr("epg source channels")),true);
generatesumchannellist();
mappingBegin=Current()+1;
for (int i=0; i<channels.Size(); i++)
@@ -114,8 +122,8 @@ void cMenuSetupXmltv2vdr::Output(void)
{
if (map->NumChannelIDs()) mapped=true;
}
- cString buffer = cString::sprintf ("%s:\t%s",channels[i],mapped ? tr("mapped") : "");
- Add (new cOsdItem (buffer),true);
+ cString buffer = cString::sprintf("%s:\t%s",channels[i],mapped ? tr("mapped") : "");
+ Add(new cOsdItem(buffer),true);
}
mappingEnd=Current();
@@ -164,12 +172,6 @@ void cMenuSetupXmltv2vdr::generatesumchannellist()
channels.Sort();
}
-cOsdItem *cMenuSetupXmltv2vdr::newtitle(const char *s)
-{
- cString buffer = cString::sprintf("---- %s ----", s);
- return new cOsdItem (buffer,osUnknown,false);
-}
-
void cMenuSetupXmltv2vdr::Store(void)
{
SetupStore("options.exectime",exectime);
@@ -201,24 +203,28 @@ eOSState cMenuSetupXmltv2vdr::edit()
return osUnknown;
}
-eOSState cMenuSetupXmltv2vdr::ProcessKey (eKeys Key)
+eOSState cMenuSetupXmltv2vdr::ProcessKey(eKeys Key)
{
eOSState state = cOsdMenu::ProcessKey(Key);
if (HasSubMenu()) return osContinue;
switch (state)
{
case osContinue:
+ if ((Key==kLeft) || (Key==kRight) || (Key==kLeft|k_Repeat) || (Key==kRight|k_Repeat))
+ {
+ if (Current()==updateEntry) Output();
+ }
if ((Key==kDown) || (Key==kUp) || (Key==kDown|k_Repeat) || (Key==kUp|k_Repeat))
{
if ((Current()>=sourcesBegin) && (Current()<=sourcesEnd))
{
if ((sourcesEnd-sourcesBegin)>0)
{
- SetHelp(NULL,tr("Button$Up"),tr("Button$Down"),tr("Button$Edit"));
+ SetHelp(tr("Button$Up"),tr("Button$Down"),tr("Button$Log"),tr("Button$Edit"));
}
else
{
- SetHelp(NULL,NULL,NULL,tr("Button$Edit"));
+ SetHelp(NULL,NULL,tr("Button$Log"),tr("Button$Edit"));
}
}
else if (Current()==mappingEntry)
@@ -246,6 +252,17 @@ eOSState cMenuSetupXmltv2vdr::ProcessKey (eKeys Key)
state=osBack;
}
}
+ if (Key==kYellow)
+ {
+ if ((Current()>=sourcesBegin) && (Current()<=sourcesEnd))
+ {
+ cEPGSource *src=baseplugin->EPGSource(Current()-sourcesBegin);
+ if (src)
+ {
+ return AddSubMenu(new cMenuSetupXmltv2vdrLog(baseplugin,src));
+ }
+ }
+ }
break;
default:
@@ -259,8 +276,8 @@ eOSState cMenuSetupXmltv2vdr::ProcessKey (eKeys Key)
cMenuSetupXmltv2vdrTextMap::cMenuSetupXmltv2vdrTextMap(cPluginXmltv2vdr *Plugin)
{
baseplugin=Plugin;
- SetSection(cString::sprintf("%s '%s' : %s",trVDR("Plugin"), baseplugin->Name(), tr("texts")));
SetPlugin(baseplugin);
+ SetSection(cString::sprintf("%s '%s' : %s",trVDR("Plugin"), baseplugin->Name(), tr("texts")));
cTEXTMapping *textmap;
@@ -414,17 +431,17 @@ cMenuSetupXmltv2vdrTextMap::cMenuSetupXmltv2vdrTextMap(cPluginXmltv2vdr *Plugin)
strcpy(category,tr("category"));
}
- Add(newtitle(tr("country and date")));
+ Add(NewTitle(tr("country and date")));
Add(new cMenuEditStrItem("country",country,sizeof(country)));
Add(new cMenuEditStrItem("date",date,sizeof(date)));
- Add(newtitle(tr("original title")));
+ Add(NewTitle(tr("original title")));
Add(new cMenuEditStrItem("originaltitle",originaltitle,sizeof(originaltitle)));
- Add(newtitle(tr("category")));
+ Add(NewTitle(tr("category")));
Add(new cMenuEditStrItem("category",category,sizeof(category)));
- Add(newtitle(tr("credits")));
+ Add(NewTitle(tr("credits")));
Add(new cMenuEditStrItem("actor",actor,sizeof(actor)));
Add(new cMenuEditStrItem("guest",guest,sizeof(guest)));
Add(new cMenuEditStrItem("director",director,sizeof(director)));
@@ -436,16 +453,10 @@ cMenuSetupXmltv2vdrTextMap::cMenuSetupXmltv2vdrTextMap(cPluginXmltv2vdr *Plugin)
Add(new cMenuEditStrItem("commentator",commentator,sizeof(commentator)));
Add(new cMenuEditStrItem("presenter",presenter,sizeof(presenter)));
- Add(newtitle(tr("review")));
+ Add(NewTitle(tr("review")));
Add(new cMenuEditStrItem("review",review,sizeof(review)));
}
-cOsdItem *cMenuSetupXmltv2vdrTextMap::newtitle(const char *s)
-{
- cString buffer = cString::sprintf("---- %s ----", s);
- return new cOsdItem (buffer,osUnknown,false);
-}
-
void cMenuSetupXmltv2vdrTextMap::Store()
{
if (!baseplugin) return;
@@ -605,6 +616,193 @@ void cMenuSetupXmltv2vdrTextMap::Store()
// --------------------------------------------------------------------------------------------------------
+void cMenuSetupXmltv2vdrLog::output(void)
+{
+ int cur=Current();
+ Clear();
+ Add(NewTitle(tr("overview")));
+ time_t lastexec=src->LastExecution();
+ if (lastexec)
+ {
+ struct tm tm;
+ localtime_r(&lastexec,&tm);
+ strftime(lastexec_str,sizeof(lastexec_str)-1,"%d %b %H:%M:%S",&tm);
+ }
+ cString last;
+ if (src->Active())
+ {
+ last=cString::sprintf("%s:\t%s",tr("last execution"),
+ tr("active"));
+ }
+ else
+ {
+ last=cString::sprintf("%s:\t%s",tr("last execution"),
+ lastexec ? lastexec_str : "-");
+ }
+ Add(new cOsdItem(last,osUnknown,true));
+
+ int tlen=strlen(3+tr("log"))+strlen(tr("Button$Errors"))+strlen(tr("Button$Info"))+strlen(tr("Button$Debug"));
+ char *ntitle=(char *) malloc(tlen);
+ if (ntitle)
+ {
+ strcpy(ntitle,tr("log"));
+ strcat(ntitle," (");
+
+ switch (level)
+ {
+ case VIEW_ERROR:
+ strcat(ntitle,tr("Button$Errors"));
+ break;
+ case VIEW_INFO:
+ strcat(ntitle,tr("Button$Info"));
+ break;
+ case VIEW_DEBUG:
+ strcat(ntitle,tr("Button$Debug"));
+ break;
+ }
+ strcat(ntitle,")");
+ Add(NewTitle(ntitle));
+ free(ntitle);
+
+ }
+ else
+ {
+ Add(NewTitle(tr("log")));
+ }
+
+ if (src && src->Log)
+ {
+ char *saveptr;
+ char *log=strdup(src->Log);
+ if (log)
+ {
+ char *pch=strtok_r(log,"\n",&saveptr);
+ while (pch)
+ {
+ bool outp=false;
+ if (level==VIEW_DEBUG) outp=true;
+ if ((level==VIEW_INFO) && ((pch[0]=='I') || (pch[0]=='E'))) outp=true;
+ if ((level==VIEW_ERROR) && (pch[0]=='E')) outp=true;
+ if (outp)
+ {
+ if (font->Width(pch+1)>width)
+ {
+ cTextWrapper wrap(pch+1,font,width);
+ for (int i=0; i<wrap.Lines();i++)
+ {
+ Add(new cOsdItem(wrap.GetLine(i),osUnknown,true));
+ }
+ }
+ else
+ {
+ Add(new cOsdItem(pch+1,osUnknown,true));
+ }
+ }
+ pch=strtok_r(NULL,"\n",&saveptr);
+ }
+ free(log);
+ }
+ }
+ if (cur>Count()) cur=Count();
+ SetCurrent(Get(cur));
+ Display();
+}
+
+cMenuSetupXmltv2vdrLog::cMenuSetupXmltv2vdrLog(cPluginXmltv2vdr *Plugin, cEPGSource *Source)
+ :cOsdMenu("",25)
+{
+ cString title=cString::sprintf("%s - %s '%s' : %s Log",
+ trVDR("Setup"),trVDR("Plugin"),
+ Plugin->Name(), Source->Name());
+ SetTitle(title);
+ src=Source;
+ SetHelp(tr("Button$Info"));
+
+ level=VIEW_ERROR;
+ width=0;
+ lastrefresh=(time_t) 0;
+ font=NULL;
+ cSkinDisplayMenu *disp=DisplayMenu();
+ if (disp)
+ {
+ width=disp->GetTextAreaWidth();
+ font=disp->GetTextAreaFont(false);
+ }
+ if (!width) width=Setup.OSDWidth;
+ if (!font) font=cFont::GetFont(fontOsd);
+
+ output();
+}
+
+eOSState cMenuSetupXmltv2vdrLog::ProcessKey(eKeys Key)
+{
+ eOSState state = cOsdMenu::ProcessKey(Key);
+ if (HasSubMenu()) return osContinue;
+ if (state==osUnknown)
+ {
+ switch (Key)
+ {
+ case kRed:
+ switch (level)
+ {
+ case VIEW_ERROR:
+ level=VIEW_INFO;
+ SetHelp(tr("Button$Debug"));
+ break;
+ case VIEW_INFO:
+ level=VIEW_DEBUG;
+ SetHelp(tr("Button$Errors"));
+ break;
+ case VIEW_DEBUG:
+ level=VIEW_ERROR;
+ SetHelp(tr("Button$Info"));
+ break;
+ }
+ output();
+ break;
+ case kGreen:
+ level = VIEW_INFO;
+ output();
+ break;
+ case kBlue:
+ level = VIEW_DEBUG;
+ output();
+ break;
+ case kNone:
+ if (src->Active())
+ {
+ if (time(NULL)>(lastrefresh+5))
+ {
+ output();
+ lastrefresh=time(NULL);
+ }
+ }
+ else
+ {
+ if (lastrefresh)
+ {
+ if (time(NULL)>(lastrefresh+5))
+ {
+ output();
+ lastrefresh=(time_t) 0;
+ }
+ }
+ }
+ break;
+ case kBack:
+ case kOk:
+ state=osBack;
+ break;
+ default:
+ break;
+ }
+ }
+ return state;
+}
+
+
+// --------------------------------------------------------------------------------------------------------
+
cMenuSetupXmltv2vdrChannelSource::cMenuSetupXmltv2vdrChannelSource(cPluginXmltv2vdr *Plugin, cMenuSetupXmltv2vdr *Menu, int Index)
{
menu=Menu;
@@ -618,7 +816,7 @@ cMenuSetupXmltv2vdrChannelSource::cMenuSetupXmltv2vdrChannelSource(cPluginXmltv2
SetSection(cString::sprintf("%s '%s' : %s",trVDR("Plugin"), baseplugin->Name(), epgsrc->Name()));
- Add(newtitle(tr("options")));
+ Add(NewTitle(tr("options")));
days=epgsrc->DaysInAdvance();
Add(new cMenuEditIntItem(tr("days in advance"),&days,1,epgsrc->DaysMax()));
if (epgsrc->NeedPin())
@@ -630,7 +828,7 @@ cMenuSetupXmltv2vdrChannelSource::cMenuSetupXmltv2vdrChannelSource(cPluginXmltv2
}
Add(new cMenuEditStrItem(tr("pin"),pin,sizeof(pin)));
}
- Add(newtitle(tr("channels provided")));
+ Add(NewTitle(tr("channels provided")));
cEPGChannels *channellist=epgsrc->ChannelList();
if (!channellist) return;
@@ -662,12 +860,6 @@ cMenuSetupXmltv2vdrChannelSource::~cMenuSetupXmltv2vdrChannelSource()
if (sel) delete [] sel;
}
-cOsdItem *cMenuSetupXmltv2vdrChannelSource::newtitle(const char *s)
-{
- cString buffer = cString::sprintf("---- %s ----", s);
- return new cOsdItem (buffer,osUnknown,false);
-}
-
void cMenuSetupXmltv2vdrChannelSource::Store(void)
{
if ((!baseplugin) || (!sel) || (!epgsrc)) return;
@@ -803,13 +995,7 @@ cOsdItem *cMenuSetupXmltv2vdrChannelMap::optionN(const char *s, int num)
cOsdItem *cMenuSetupXmltv2vdrChannelMap::option(const char *s, bool yesno)
{
cString buffer = cString::sprintf("%s:\t%s", s, yesno ? trVDR("yes") : trVDR("no"));
- return new cOsdItem (buffer,osUnknown,false);
-}
-
-cOsdItem *cMenuSetupXmltv2vdrChannelMap::newtitle(const char *s)
-{
- cString buffer = cString::sprintf("---- %s ----", s);
- return new cOsdItem (buffer,osUnknown,false);
+ return new cOsdItem(buffer,osUnknown,false);
}
void cMenuSetupXmltv2vdrChannelMap::output(void)
@@ -819,7 +1005,7 @@ void cMenuSetupXmltv2vdrChannelMap::output(void)
int current=Current();
Clear();
- cOsdItem *first=newtitle(tr("epg source channel options"));
+ cOsdItem *first=NewTitle(tr("epg source channel options"));
Add(first,true);
Add(new cMyMenuEditBitItem(tr("type of processing"),&flags,OPT_APPEND,tr("merge"),tr("create")),true);
@@ -862,7 +1048,7 @@ void cMenuSetupXmltv2vdrChannelMap::output(void)
Add(new cMyMenuEditBitItem(tr("vps"),&flags,OPT_VPS),true);
hasmaps=false;
- Add(newtitle(tr("epg source channel mappings")),true);
+ Add(NewTitle(tr("epg source channel mappings")),true);
for (int i=0; i<map->NumChannelIDs(); i++)
{
cChannel *chan=Channels.GetByChannelID(map->ChannelIDs()[i]);
@@ -872,7 +1058,9 @@ void cMenuSetupXmltv2vdrChannelMap::output(void)
Add(new cOsdItem(buffer),true);
if (!hasmaps) cm=Current();
hasmaps=true;
- } else {
+ }
+ else
+ {
// invalid channelid? remove from list
map->RemoveChannel(map->ChannelIDs()[i],true);
}
@@ -896,7 +1084,7 @@ void cMenuSetupXmltv2vdrChannelMap::output(void)
Display();
}
-eOSState cMenuSetupXmltv2vdrChannelMap::ProcessKey (eKeys Key)
+eOSState cMenuSetupXmltv2vdrChannelMap::ProcessKey(eKeys Key)
{
cOsdItem *item=NULL;
eOSState state = cOsdMenu::ProcessKey(Key);
@@ -1143,7 +1331,7 @@ bool cMenuSetupXmltv2vdrChannelsVDR::epgmappingexists(tChannelID channelid, cons
return false;
}
-eOSState cMenuSetupXmltv2vdrChannelsVDR::ProcessKey (eKeys Key)
+eOSState cMenuSetupXmltv2vdrChannelsVDR::ProcessKey(eKeys Key)
{
cOsdItem *item=NULL;
eOSState state = cOsdMenu::ProcessKey(Key);
@@ -1170,3 +1358,4 @@ eOSState cMenuSetupXmltv2vdrChannelsVDR::ProcessKey (eKeys Key)
}
return state;
}
+
diff --git a/setup.h b/setup.h
index b1a9b3e..4475f90 100644
--- a/setup.h
+++ b/setup.h
@@ -37,7 +37,7 @@ private:
int mappingBegin,mappingEnd;
int sourcesBegin,sourcesEnd;
int mappingEntry;
- cOsdItem *newtitle (const char *s);
+ int updateEntry;
eOSState edit(void);
void generatesumchannellist();
int exectime;
@@ -45,6 +45,7 @@ private:
int upstart;
public:
void Output(void);
+ static cOsdItem *NewTitle(const char *s);
void ClearCS()
{
cs=NULL;
@@ -83,7 +84,6 @@ private:
char guest[255];
char review[255];
char category[255];
- cOsdItem *newtitle (const char *s);
public:
cMenuSetupXmltv2vdrTextMap(cPluginXmltv2vdr *Plugin);
};
@@ -99,7 +99,6 @@ private:
int *sel;
int days;
char pin[255];
- cOsdItem *newtitle (const char *s);
public:
cMenuSetupXmltv2vdrChannelSource(cPluginXmltv2vdr *Plugin, cMenuSetupXmltv2vdr *Menu, int Index);
~cMenuSetupXmltv2vdrChannelSource();
@@ -125,7 +124,6 @@ private:
cString title;
const char *channel;
int getdaysmax();
- cOsdItem *newtitle (const char *s);
cOsdItem *optionN(const char *s, int num);
cOsdItem *option(const char *s, bool yesno);
void epgmappingreplace(cEPGMapping *newmapping);
@@ -152,6 +150,35 @@ public:
cMenuSetupXmltv2vdrChannelsVDR(cPluginXmltv2vdr *Plugin, cMenuSetupXmltv2vdrChannelMap *Map,
const char *Channel, cString Title);
virtual eOSState ProcessKey(eKeys Key);
+ virtual const char *MenuKind()
+ {
+ return "MenuChannels";
+ }
+};
+
+class cMenuSetupXmltv2vdrLog : public cOsdMenu
+{
+private:
+ enum
+ {
+ VIEW_ERROR=1,
+ VIEW_INFO,
+ VIEW_DEBUG
+ };
+ int level;
+ cEPGSource *src;
+ char lastexec_str[30];
+ void output(void);
+ int width;
+ time_t lastrefresh;
+ const cFont *font;
+public:
+ cMenuSetupXmltv2vdrLog(cPluginXmltv2vdr *Plugin, cEPGSource *Source);
+ virtual const char *MenuKind()
+ {
+ return "MenuLog";
+ }
+ virtual eOSState ProcessKey(eKeys Key);
};
#endif
diff --git a/xmltv2vdr.cpp b/xmltv2vdr.cpp
index 01e767b..64b79da 100644
--- a/xmltv2vdr.cpp
+++ b/xmltv2vdr.cpp
@@ -10,6 +10,7 @@
#include <time.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
+#include <stdarg.h>
#include "xmltv2vdr.h"
#include "parse.h"
#include "extpipe.h"
@@ -54,20 +55,22 @@ void cEPGExecutor::Action()
for (cEPGSource *epgs=sources->First(); epgs; epgs=sources->Next(epgs))
{
int retries=0;
- while (retries<2)
+ while (retries<=2)
{
ret=epgs->Execute(*this);
- if ((ret>0) && (ret<126))
+ if ((ret>0) && (ret<126) && (retries<2))
{
- dsyslog("xmltv2vdr: '%s' waiting 60 seconds",epgs->Name());
+ epgs->Dlog("waiting 60 seconds");
int l=0;
- while (l<300) {
+ while (l<300)
+ {
struct timespec req;
req.tv_sec=0;
req.tv_nsec=200000000; // 200ms
nanosleep(&req,NULL);
- if (!Running()) {
- isyslog("xmltv2vdr: '%s' request to stop from vdr",epgs->Name());
+ if (!Running())
+ {
+ epgs->Ilog("request to stop from vdr");
return;
}
l++;
@@ -79,7 +82,7 @@ void cEPGExecutor::Action()
break;
}
}
- if (retries>=2) esyslog("xmltv2vdr: '%s' ERROR skipping after %i retries",epgs->Name(),retries);
+ if (retries>=2) epgs->Elog("skipping after %i retries",retries);
if (!ret) break; // TODO: check if we must execute second/third source!
}
if (!ret) cSchedules::Cleanup(true);
@@ -93,12 +96,16 @@ cEPGSource::cEPGSource(const char *Name, const char *ConfDir, cEPGMappings *Maps
name=strdup(Name);
confdir=strdup(ConfDir);
pin=NULL;
+ Log=NULL;
+ loglen=0;
usepipe=false;
needpin=false;
+ running=false;
daysinadvance=0;
+ lastexec=(time_t) 0;
ready2parse=ReadConfig();
- parse=new cParse(Name, Maps, Texts);
- dsyslog("xmltv2vdr: '%s' is%sready2parse",Name,(ready2parse && parse) ? " " : " not ");
+ parse=new cParse(this, Maps, Texts);
+ Dlog("is%sready2parse",(ready2parse && parse) ? " " : " not ");
}
cEPGSource::~cEPGSource()
@@ -107,6 +114,7 @@ cEPGSource::~cEPGSource()
free((void *) name);
free((void *) confdir);
if (pin) free((void *) pin);
+ if (Log) free((void *) Log);
if (parse) delete parse;
}
@@ -115,17 +123,17 @@ bool cEPGSource::ReadConfig()
char *fname=NULL;
if (asprintf(&fname,"%s/%s",EPGSOURCES,name)==-1)
{
- esyslog("xmltv2vdr: '%s' out of memory",name);
+ Elog("out of memory");
return false;
}
FILE *f=fopen(fname,"r");
if (!f)
{
- esyslog("xmltv2vdr: '%s' ERROR cannot read config file %s",name,fname);
+ Elog("cannot read config file %s",fname);
free(fname);
return false;
}
- dsyslog("xmltv2vdr: '%s' reading source config",name);
+ Dlog("reading source config");
size_t lsize;
char *line=NULL;
int linenr=1;
@@ -135,12 +143,12 @@ bool cEPGSource::ReadConfig()
{
if (!strncmp(line,"pipe",4))
{
- dsyslog("xmltv2vdr: '%s' is providing data through a pipe",name);
+ Dlog("is providing data through a pipe");
usepipe=true;
}
else
{
- dsyslog("xmltv2vdr: '%s' is providing data through a file",name);
+ Dlog("is providing data through a file");
usepipe=false;
}
char *ndt=strchr(line,';');
@@ -156,14 +164,14 @@ bool cEPGSource::ReadConfig()
}
/*
newdatatime=atoi(ndt);
- if (!newdatatime) dsyslog("xmltv2vdr: '%s' updates source data @%02i:%02i",name,1,2);
+ if (!newdatatime) Dlog("updates source data @%02i:%02i",1,2);
*/
if (pn)
{
pn=compactspace(pn);
if (pn[0]=='1')
{
- dsyslog("xmltv2vdr: '%s' is needing a pin",name);
+ Dlog("is needing a pin");
needpin=true;
}
}
@@ -183,7 +191,7 @@ bool cEPGSource::ReadConfig()
{
daysmax=atoi(line);
}
- dsyslog("xmltv2vdr: '%s' daysmax=%i",name,daysmax);
+ Dlog("daysmax=%i",daysmax);
}
if (linenr>2)
{
@@ -198,7 +206,8 @@ bool cEPGSource::ReadConfig()
// backward compatibility
cname++;
}
- if (!strchr(cname,' ') && (strlen(cname)>0)) {
+ if (!strchr(cname,' ') && (strlen(cname)>0))
+ {
cEPGChannel *epgchannel= new cEPGChannel(cname,false);
if (epgchannel) channels.Add(epgchannel);
}
@@ -214,7 +223,7 @@ bool cEPGSource::ReadConfig()
if (asprintf(&fname,"%s/%s",confdir,name)==-1)
{
- esyslog("xmltv2vdr: '%s' out of memory",name);
+ Elog("out of memory");
return false;
}
f=fopen(fname,"r+");
@@ -222,7 +231,7 @@ bool cEPGSource::ReadConfig()
{
if (errno!=ENOENT)
{
- esyslog("xmltv2vdr: '%s' ERROR cannot read config file %s",name,fname);
+ Elog("cannot read config file %s",fname);
free(fname);
return true;
}
@@ -230,7 +239,7 @@ bool cEPGSource::ReadConfig()
free(fname);
return true;
}
- dsyslog("xmltv2vdr: '%s' reading plugin config",name);
+ Dlog("reading plugin config");
line=NULL;
linenr=1;
while (getline(&line,&lsize,f)!=-1)
@@ -242,13 +251,13 @@ bool cEPGSource::ReadConfig()
if (strcmp(line,"#no pin"))
{
ChangePin(line);
- dsyslog("xmltv2vdr: '%s' pin set",name);
+ Dlog("pin set");
}
}
if (linenr==2)
{
daysinadvance=atoi(line);
- dsyslog("xmltv2vdr: '%s' daysinadvance=%i",name,daysinadvance);
+ Dlog("daysinadvance=%i",daysinadvance);
}
if (linenr>2)
{
@@ -281,15 +290,15 @@ int cEPGSource::ReadOutput(char *&result, size_t &l)
char *fname=NULL;
if (asprintf(&fname,"%s/%s.xmltv",EPGSOURCES,name)==-1)
{
- esyslog("xmltv2vdr: '%s' ERROR out of memory",name);
+ Elog("out of memory");
return 134;
}
- dsyslog("xmltv2vdr: '%s' reading from '%s'",name,fname);
+ Dlog("reading from '%s'",fname);
int fd=open(fname,O_RDONLY);
if (fd==-1)
{
- esyslog("xmltv2vdr: '%s' ERROR failed to open '%s'",name,fname);
+ Elog("failed to open '%s'",fname);
free(fname);
return 157;
}
@@ -297,7 +306,7 @@ int cEPGSource::ReadOutput(char *&result, size_t &l)
struct stat statbuf;
if (fstat(fd,&statbuf)==-1)
{
- esyslog("xmltv2vdr: '%s' ERROR failed to stat '%s'",name,fname);
+ Elog("failed to stat '%s'",fname);
close(fd);
free(fname);
return 157;
@@ -308,7 +317,7 @@ int cEPGSource::ReadOutput(char *&result, size_t &l)
{
close(fd);
free(fname);
- esyslog("xmltv2vdr: '%s' ERROR out of memory",name);
+ Elog("out of memory");
return 134;
}
if (read(fd,result,statbuf.st_size)==statbuf.st_size)
@@ -316,7 +325,7 @@ int cEPGSource::ReadOutput(char *&result, size_t &l)
}
else
{
- esyslog("xmltv2vdr: '%s' ERROR failed to read '%s'",name,fname);
+ Elog("failed to read '%s'",fname);
ret=149;
}
free(result);
@@ -327,20 +336,24 @@ int cEPGSource::ReadOutput(char *&result, size_t &l)
int cEPGSource::Execute(cEPGExecutor &myExecutor)
{
-
if (!ready2parse) return false;
if (!parse) return false;
char *r_out=NULL;
char *r_err=NULL;
int l_out=0;
int l_err=0;
-
int ret=0;
+ if ((Log) && (lastexec)) {
+ free(Log);
+ Log=NULL;
+ loglen=0;
+ }
+
char *cmd=NULL;
if (asprintf(&cmd,"%s %i '%s'",name,daysinadvance,pin ? pin : "")==-1)
{
- esyslog("xmltv2vdr: '%s' ERROR out of memory",name);
+ Elog("out of memory");
return 134;
}
@@ -354,7 +367,7 @@ int cEPGSource::Execute(cEPGExecutor &myExecutor)
if (!ncmd)
{
free(cmd);
- esyslog("xmltv2vdr: '%s' ERROR out of memory",name);
+ Elog("out of memory");
return 134;
}
cmd=ncmd;
@@ -364,21 +377,37 @@ int cEPGSource::Execute(cEPGExecutor &myExecutor)
}
}
char *pcmd=strdup(cmd);
- if (pcmd) {
+ if (pcmd)
+ {
char *pa=strchr(pcmd,'\'');
char *pe=strchr(pa+1,'\'');
- if (pa && pe) {
+ if (pa && pe)
+ {
pa++;
for (char *c=pa; c<pe; c++)
{
- if (c==pa) {
+ if (c==pa)
+ {
*c='X';
- } else {
+ }
+ else
+ {
*c='@';
}
}
- // TODO: strip @
- isyslog("xmltv2vdr: '%s' %s",name,pcmd);
+ pe=pcmd;
+ while (*pe)
+ {
+ if (*pe=='@')
+ {
+ memmove(pe,pe+1,strlen(pe));
+ }
+ else
+ {
+ pe++;
+ }
+ }
+ Ilog("%s",pcmd);
}
free(pcmd);
}
@@ -386,23 +415,28 @@ int cEPGSource::Execute(cEPGExecutor &myExecutor)
if (!p.Open(cmd))
{
free(cmd);
- esyslog("xmltv2vdr: '%s' ERROR failed to open pipe",name);
+ Elog("failed to open pipe");
return 141;
}
free(cmd);
- dsyslog("xmltv2vdr: '%s' executing epgsource",name);
+ Dlog("executing epgsource");
+ running=true;
int fdsopen=2;
- while (fdsopen>0) {
+ while (fdsopen>0)
+ {
struct pollfd fds[2];
fds[0].fd=p.Out();
fds[0].events=POLLIN;
fds[1].fd=p.Err();
fds[1].events=POLLIN;
- if (poll(fds,2,500)>=0) {
- if (fds[0].revents & POLLIN) {
+ if (poll(fds,2,500)>=0)
+ {
+ if (fds[0].revents & POLLIN)
+ {
int n;
- if (ioctl(p.Out(),FIONREAD,&n)<0) {
+ if (ioctl(p.Out(),FIONREAD,&n)<0)
+ {
n=1;
}
r_out=(char *) realloc(r_out, l_out+n+1);
@@ -412,34 +446,42 @@ int cEPGSource::Execute(cEPGExecutor &myExecutor)
l_out+=l;
}
}
- if (fds[1].revents & POLLIN) {
+ if (fds[1].revents & POLLIN)
+ {
int n;
- if (ioctl(p.Err(),FIONREAD,&n)<0) {
+ if (ioctl(p.Err(),FIONREAD,&n)<0)
+ {
n=1;
}
r_err=(char *) realloc(r_err, l_err+n+1);
int l=read(p.Err(),r_err+l_err,n);
- if (l>0) {
+ if (l>0)
+ {
l_err+=l;
}
}
- if (fds[0].revents & POLLHUP) {
+ if (fds[0].revents & POLLHUP)
+ {
fdsopen--;
}
- if (fds[1].revents & POLLHUP) {
+ if (fds[1].revents & POLLHUP)
+ {
fdsopen--;
}
- if (!myExecutor.StillRunning()) {
+ if (!myExecutor.StillRunning())
+ {
int status;
p.Close(status);
if (r_out) free(r_out);
if (r_err) free(r_err);
- isyslog("xmltv2vdr: '%s' request to stop from vdr",name);
+ Ilog("request to stop from vdr");
+ running=false;
return 0;
}
-
- } else {
- esyslog("xmltv2vdr: '%s' ERROR polling",name);
+ }
+ else
+ {
+ Elog("failed polling");
break;
}
}
@@ -454,18 +496,19 @@ int cEPGSource::Execute(cEPGExecutor &myExecutor)
int returncode=WEXITSTATUS(status);
if ((!returncode) && (r_out))
{
- dsyslog("xmltv2vdr: '%s' parsing output",name);
+ //Dlog("xmltv2vdr: '%s' parsing output");
+ Dlog("parsing output");
ret=parse->Process(myExecutor,r_out,l_out);
}
else
{
- esyslog("xmltv2vdr: '%s' ERROR epgsource returned %i",name,returncode);
+ Elog("epgsource returned %i",returncode);
ret=returncode;
}
}
else
{
- esyslog("xmltv2vdr: '%s' ERROR failed to execute",name);
+ Elog("failed to execute");
ret=126;
}
}
@@ -480,28 +523,38 @@ int cEPGSource::Execute(cEPGExecutor &myExecutor)
size_t l;
char *result=NULL;
ret=ReadOutput(result,l);
- if ((!ret) && (result)) {
+ if ((!ret) && (result))
+ {
ret=parse->Process(myExecutor,result,l);
}
if (result) free(result);
}
else
{
- esyslog("xmltv2vdr: '%s' ERROR epgsource returned %i",name,returncode);
+ Elog("epgsource returned %i",returncode);
ret=returncode;
}
}
}
if (r_out) free(r_out);
- if (r_err) {
- char *pch=strtok(r_err,"\n");
- while (pch) {
- esyslog("xmltv2vdr: '%s' ERROR %s",name,pch);
- pch=strtok(NULL,"\n");
+ if (!ret) lastexec=time(NULL);
+ if (r_err)
+ {
+ char *saveptr;
+ char *pch=strtok_r(r_err,"\n",&saveptr);
+ char *last=(char *) "";
+ while (pch)
+ {
+ if (strcmp(last,pch))
+ {
+ Elog("%s",pch);
+ last=pch;
+ }
+ pch=strtok_r(NULL,"\n",&saveptr);
}
free(r_err);
}
-
+ running=false;
return ret;
}
@@ -520,7 +573,7 @@ void cEPGSource::Store(void)
if (asprintf(&fname1,"%s/%s",confdir,name)==-1) return;
if (asprintf(&fname2,"%s/%s.new",confdir,name)==-1)
{
- esyslog("xmltv2vdr: '%s' out of memory",name);
+ Elog("out of memory");
free(fname1);
return;
}
@@ -528,7 +581,7 @@ void cEPGSource::Store(void)
FILE *w=fopen(fname2,"w+");
if (!w)
{
- esyslog("xmltv2vdr: '%s' cannot create %s",name,fname2);
+ Elog("cannot create %s",fname2);
unlink(fname2);
free(fname1);
free(fname2);
@@ -564,6 +617,75 @@ void cEPGSource::Store(void)
free(fname2);
}
+void cEPGSource::add2Log(const char Prefix, const char *line)
+{
+ 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);
+
+ loglen+=strlen(line)+3+strlen(dt);
+ char *nptr=(char *) realloc(Log,loglen);
+ if (nptr)
+ {
+ if (!Log) nptr[0]=0;
+ Log=nptr;
+ char prefix[2];
+ prefix[0]=Prefix;
+ prefix[1]=0;
+ strcat(Log,prefix);
+ strcat(Log,dt);
+ 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+19+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+13+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+13+strlen(name));
+ free(ptr);
+}
+
// -------------------------------------------------------------
bool cPluginXmltv2vdr::epgsourceexists(const char *name)
@@ -692,7 +814,7 @@ cPluginXmltv2vdr::cPluginXmltv2vdr(void) : epgexecutor(&epgsources)
// VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT!
confdir=NULL;
WakeUp=0;
- UpStart=0;
+ UpStart=1;
last_exectime_t=0;
exectime=200;
SetExecTime(exectime);
@@ -745,6 +867,10 @@ bool cPluginXmltv2vdr::Start(void)
if (UpStart)
{
exectime_t=time(NULL)+60;
+ struct tm tm;
+ localtime_r(&exectime_t,&tm);
+ // prevent from getting startet again
+ exectime=tm.tm_hour*100+tm.tm_min;
}
else
{
diff --git a/xmltv2vdr.h b/xmltv2vdr.h
index 14bbf12..1067494 100644
--- a/xmltv2vdr.h
+++ b/xmltv2vdr.h
@@ -14,8 +14,8 @@
#include "maps.h"
#include "parse.h"
-static const char *VERSION = "0.0.1";
-static const char *DESCRIPTION = trNOOP ( "Imports xmltv epg into vdr" );
+static const char *VERSION = "0.0.2pre";
+static const char *DESCRIPTION = trNOOP("Imports xmltv epg into vdr");
class cEPGChannel : public cListObject
{
@@ -50,12 +50,16 @@ private:
const char *name;
const char *confdir;
const char *pin;
+ int loglen;
cParse *parse;
bool ready2parse;
bool usepipe;
bool needpin;
+ bool running;
int daysinadvance;
int daysmax;
+ time_t lastexec;
+ void add2Log(const char prefix, const char *line);
bool ReadConfig();
int ReadOutput(char *&result, size_t &l);
cEPGChannels channels;
@@ -65,6 +69,7 @@ public:
int Execute(cEPGExecutor &myExecutor);
void Store(void);
void ChangeChannelSelection(int *Selection);
+ char *Log;
cEPGChannels *ChannelList()
{
return &channels;
@@ -98,6 +103,17 @@ public:
if (pin) free((void *) pin);
pin=strdup(NewPin);
}
+ time_t LastExecution()
+ {
+ return lastexec;
+ }
+ void Dlog(const char *format, ...);
+ void Elog(const char *format, ...);
+ void Ilog(const char *format, ...);
+ bool Active()
+ {
+ return running;
+ }
};
class cEPGSources : public cList<cEPGSource> {};
@@ -108,13 +124,14 @@ private:
cEPGSources *sources;
public:
cEPGExecutor(cEPGSources *Sources);
- bool StillRunning() {
+ bool StillRunning()
+ {
return Running();
}
void Stop()
{
Cancel(3);
- }
+ }
virtual void Action();
};
@@ -167,32 +184,32 @@ public:
{
textmappings.Add(TextMap);
}
- cPluginXmltv2vdr ( void );
+ cPluginXmltv2vdr(void);
virtual ~cPluginXmltv2vdr();
- virtual const char *Version ( void )
+ virtual const char *Version(void)
{
return VERSION;
}
- virtual const char *Description ( void )
+ virtual const char *Description(void)
{
return tr(DESCRIPTION);
}
- virtual const char *CommandLineHelp ( void );
- virtual bool ProcessArgs ( int argc, char *argv[] );
- virtual bool Initialize ( void );
- virtual bool Start ( void );
- virtual void Stop ( void );
- virtual void Housekeeping ( void );
- virtual void MainThreadHook ( void );
- virtual cString Active ( void );
- virtual time_t WakeupTime ( void );
- virtual const char *MainMenuEntry ( void );
- virtual cOsdObject *MainMenuAction ( void );
- virtual cMenuSetupPage *SetupMenu ( void );
- virtual bool SetupParse ( const char *Name, const char *Value );
- virtual bool Service ( const char *Id, void *Data = NULL );
- virtual const char **SVDRPHelpPages ( void );
- virtual cString SVDRPCommand ( const char *Command, const char *Option, int &ReplyCode );
+ virtual const char *CommandLineHelp(void);
+ virtual bool ProcessArgs(int argc, char *argv[]);
+ virtual bool Initialize(void);
+ virtual bool Start(void);
+ virtual void Stop(void);
+ virtual void Housekeeping(void);
+ virtual void MainThreadHook(void);
+ virtual cString Active(void);
+ virtual time_t WakeupTime(void);
+ virtual const char *MainMenuEntry(void);
+ virtual cOsdObject *MainMenuAction(void);
+ virtual cMenuSetupPage *SetupMenu(void);
+ virtual bool SetupParse(const char *Name, const char *Value);
+ virtual bool Service(const char *Id, void *Data = NULL);
+ virtual const char **SVDRPHelpPages(void);
+ virtual cString SVDRPCommand(const char *Command, const char *Option, int &ReplyCode);
};
#endif