summaryrefslogtreecommitdiff
path: root/ttools.c
diff options
context:
space:
mode:
authorhorchi <vdr@jwendel.de>2017-03-05 14:51:57 +0100
committerhorchi <vdr@jwendel.de>2017-03-05 14:51:57 +0100
commit5eacf5bf36ddbac082a9e40a2bcdfd0f04fd3f9f (patch)
tree392875cb707b94aaba9d8941113eae35efaf2ec2 /ttools.c
downloadvdr-plugin-epg2vdr-5eacf5bf36ddbac082a9e40a2bcdfd0f04fd3f9f.tar.gz
vdr-plugin-epg2vdr-5eacf5bf36ddbac082a9e40a2bcdfd0f04fd3f9f.tar.bz2
commit of actual revision1.1.441.1.42
Diffstat (limited to 'ttools.c')
-rw-r--r--ttools.c583
1 files changed, 583 insertions, 0 deletions
diff --git a/ttools.c b/ttools.c
new file mode 100644
index 0000000..c30f960
--- /dev/null
+++ b/ttools.c
@@ -0,0 +1,583 @@
+/*
+ * ttools.c: EPG2VDR plugin for the Video Disk Recorder
+ *
+ * See the README file for copyright information and how to reach the author.
+ *
+ */
+
+#include <string>
+
+#include "update.h"
+#include "ttools.h"
+
+using namespace std;
+
+//***************************************************************************
+// Content Of Tag
+//***************************************************************************
+
+int contentOfTag(const char* tag, const char* xml, char* buf, int size)
+{
+ string sTag = "<" + string(tag) + ">";
+ string eTag = "</" + string(tag) + ">";
+
+ const char* s;
+ const char* e;
+
+ if (buf)
+ *buf = 0;
+
+ if ((s = strstr(xml, sTag.c_str())) && (e = strstr(xml, eTag.c_str())))
+ {
+ s += strlen(sTag.c_str());
+
+ if (buf)
+ sprintf(buf, "%.*s", (int)(e-s), s);
+
+ return success;
+ }
+
+ return fail;
+}
+
+//***************************************************************************
+// Content Value Of Tag
+//***************************************************************************
+
+int contentOfTag(const cTimer* timer, const char* tag, char* buf, int size)
+{
+ char epgaux[512+TB];
+
+ if (!timer || isEmpty(timer->Aux()))
+ return fail;
+
+ if (contentOfTag("epgd", timer->Aux(), epgaux, 512) != success)
+ return fail;
+
+ if (contentOfTag(tag, epgaux, buf, size) != success)
+ return fail;
+
+ return success;
+}
+
+int contentOfTag(const cTimer* timer, const char* tag, int& value)
+{
+ char epgaux[512+TB];
+ char buf[100+TB];
+
+ if (!timer || isEmpty(timer->Aux()))
+ return fail;
+
+ if (contentOfTag("epgd", timer->Aux(), epgaux, 512) != success)
+ return fail;
+
+ if (contentOfTag(tag, epgaux, buf, 100) != success)
+ return fail;
+
+ value = atoi(buf);
+
+ return success;
+}
+
+//***************************************************************************
+// Get Timer Id Of
+//***************************************************************************
+
+int getTimerIdOf(const cTimer* timer)
+{
+ char tid[100+TB];
+
+ if (!timer || isEmpty(timer->Aux()))
+ return na;
+
+ if (contentOfTag(timer, "timerid", tid, 100) != success)
+ return na;
+
+ return atoi(tid);
+}
+
+int getTimerIdOf(const char* aux)
+{
+ char tid[100+TB];
+ char epgaux[512+TB];
+
+ if (isEmpty(aux))
+ return na;
+
+ if (contentOfTag("epgd", aux, epgaux, 512) != success)
+ return fail;
+
+ if (contentOfTag("timerid", epgaux, tid, 100) != success)
+ return fail;
+
+ return atoi(tid);
+}
+
+//***************************************************************************
+// Remove Tag
+//***************************************************************************
+
+void removeTag(char* xml, const char* tag)
+{
+ string sTag = "<" + string(tag) + ">";
+ string eTag = "</" + string(tag) + ">";
+
+ const char* s;
+ const char* e;
+
+ if ((s = strstr(xml, sTag.c_str())) && (e = strstr(xml, eTag.c_str())))
+ {
+ char tmp[10000+TB];
+
+ e += strlen(eTag.c_str());
+
+ // sicher ist sicher ;)
+
+ if (e <= s)
+ return;
+
+ sprintf(tmp, "%.*s%s", int(s-xml), xml, e);
+
+ strcpy(xml, tmp);
+ }
+}
+
+//***************************************************************************
+// Insert Tag
+//***************************************************************************
+
+int insertTag(char* xml, const char* parent, const char* tag, int value)
+{
+ char* tmp;
+ string sTag = "<" + string(parent) + ">";
+ const char* s;
+
+ if ((s = strstr(xml, sTag.c_str())))
+ {
+ s += strlen(sTag.c_str());
+ asprintf(&tmp, "%.*s<%s>%d</%s>%s", int(s-xml), xml, tag, value, tag, s);
+ }
+ else
+ {
+ asprintf(&tmp, "%s<%s><%s>%d</%s></%s>", xml, parent, tag, value, tag, parent);
+ }
+
+ strcpy(xml, tmp);
+ free(tmp);
+
+ return success;
+}
+
+int insertTag(char* xml, const char* parent, const char* tag, const char* value)
+{
+ char* tmp;
+ string sTag = "<" + string(parent) + ">";
+ const char* s;
+
+ if ((s = strstr(xml, sTag.c_str())))
+ {
+ s += strlen(sTag.c_str());
+ asprintf(&tmp, "%.*s<%s>%s</%s>%s", int(s-xml), xml, tag, value, tag, s);
+ }
+ else
+ {
+ asprintf(&tmp, "%s<%s><%s>%s</%s></%s>", xml, parent, tag, value, tag, parent);
+ }
+
+ strcpy(xml, tmp);
+ free(tmp);
+
+ return success;
+}
+
+//***************************************************************************
+// Set Tag To
+//***************************************************************************
+
+int setTagTo(cTimer* timer, const char* tag, int value)
+{
+ char aux[10000+TB] = "";
+
+ if (!isEmpty(timer->Aux()))
+ strcpy(aux, timer->Aux());
+
+ removeTag(aux, tag);
+ insertTag(aux, "epgd", tag, value);
+
+ timer->SetAux(aux);
+
+ return done;
+}
+
+int setTagTo(cTimer* timer, const char* tag, const char* value)
+{
+ char aux[10000+TB] = "";
+
+ if (!isEmpty(timer->Aux()))
+ strcpy(aux, timer->Aux());
+
+ removeTag(aux, tag);
+ insertTag(aux, "epgd", tag, value);
+
+ timer->SetAux(aux);
+
+ return done;
+}
+
+//***************************************************************************
+// Set Timer Id
+//***************************************************************************
+
+int setTimerId(cTimer* timer, int tid)
+{
+ char aux[10000+TB] = "";
+
+ if (!isEmpty(timer->Aux()))
+ strcpy(aux, timer->Aux());
+
+ // remove old timerid - if exist
+
+ removeTag(aux, "timerid");
+ insertTag(aux, "epgd", "timerid", tid);
+
+ timer->SetAux(aux);
+
+ return done;
+}
+
+//***************************************************************************
+// Get Timer By Id
+//***************************************************************************
+
+cTimer* getTimerById(cTimers* timers, int timerid)
+{
+ for (cTimer* t = timers->First(); t; t = timers->Next(t))
+ if (timerid == getTimerIdOf(t))
+ return t;
+
+ return 0;
+}
+
+//***************************************************************************
+// Get Timer By Event
+//***************************************************************************
+
+cTimer* getTimerByEvent(cTimers* timers, const cEvent* event)
+{
+ cTimer* timer = 0;
+
+ eTimerMatch tm = tmNone;
+
+ timer = timers->GetMatch(event, &tm);
+
+ if (tm != tmFull)
+ timer = 0;
+
+ return timer;
+}
+
+//***************************************************************************
+// New Row From Event
+//***************************************************************************
+
+cDbRow* newTimerRowFromEvent(const cEvent* event)
+{
+ cTimer* timer = new cTimer(event);
+ cDbRow* timerRow = newRowFromTimer(timer);
+
+ delete timer;
+
+ return timerRow;
+}
+
+//***************************************************************************
+// New Row From Timer
+//***************************************************************************
+
+cDbRow* newRowFromTimer(const cTimer* timer)
+{
+ cDbRow* timerRow = new cDbRow("timers");
+
+ updateRowByTimer(timerRow, timer);
+
+ return timerRow;
+}
+
+//***************************************************************************
+// Update Row By Timer
+//***************************************************************************
+
+int updateRowByTimer(cDbRow* timerRow, const cTimer* t)
+{
+ int autotimerid = na;
+ int autotimerinssp = na;
+ int doneid = na;
+ int namingmode = na;
+ char tmplExpression[100+TB] = "";
+ int childLock = no;
+ int epgs = no;
+ char directory[512+TB] = "";
+ char source[40+TB] = "";
+ cString channelId = t->Event() ? t->Event()->ChannelID().ToString() : t->Channel()->GetChannelID().ToString();
+
+ contentOfTag(t, "autotimerid", autotimerid);
+ contentOfTag(t, "autotimerinssp", autotimerinssp);
+ contentOfTag(t, "doneid", doneid);
+ contentOfTag(t, "namingmode", namingmode);
+ contentOfTag(t, "template", tmplExpression, 100);
+ contentOfTag(t, "directory", directory, 512);
+ contentOfTag(t, "source", source, 40);
+
+ timerRow->setValue("VDRUUID", Epg2VdrConfig.uuid);
+ timerRow->setValue("EVENTID", t->Event() ? (long)t->Event()->EventID() : 0);
+ timerRow->setValue("_STARTTIME", t->Event() ? t->Event()->StartTime() : 0);
+ timerRow->setValue("CHANNELID", channelId);
+ timerRow->setValue("DAY", t->Day());
+ timerRow->setValue("STARTTIME", t->Start());
+ timerRow->setValue("ENDTIME", t->Stop());
+ timerRow->setValue("WEEKDAYS", t->WeekDays());
+ timerRow->setValue("PRIORITY", t->Priority());
+ timerRow->setValue("LIFETIME", t->Lifetime());
+ timerRow->setValue("VPS", t->HasFlags(tfVps) ? yes : no);
+ timerRow->setValue("ACTIVE", t->HasFlags(tfActive) ? yes : no);
+
+ timerRow->setValue("DIRECTORY", directory);
+
+ if (!isEmpty(directory) && strncmp(t->File(), directory, strlen(directory)) == 0)
+ {
+ int len = strlen(directory);
+
+ if (t->File()[len] == '~')
+ len++;
+
+ timerRow->setValue("FILE", t->File()+len);
+ }
+ else
+ timerRow->setValue("FILE", t->File());
+
+ if (namingmode != na)
+ timerRow->setValue("NAMINGMODE", namingmode);
+
+ if (!isEmpty(tmplExpression))
+ timerRow->setValue("TEMPLATE", tmplExpression);
+
+ if (autotimerinssp != na)
+ timerRow->setValue("AUTOTIMERINSSP", autotimerinssp);
+
+ if (autotimerid != na)
+ timerRow->setValue("AUTOTIMERID", autotimerid);
+
+ if (doneid != na)
+ timerRow->setValue("DONEID", doneid);
+
+ // AUX: "<epgsearch><channel>62 - TNTSerieHD</channel><searchtimer>Falling Skies</searchtimer><start>1411498680</start><stop>1411502100</stop><s-id>3</s-id><eventid>565129</eventid></epgsearch>
+ // AUX: <epgd>......</epgd><pin-plugin><protected>yes</protected></pin-plugin>"
+
+ if (t->Aux())
+ {
+ epgs = strstr(t->Aux(), "<epgsearch>") != 0;
+ childLock = strstr(t->Aux(), "<pin-plugin><protected>yes</protected></pin-plugin>") != 0;
+ }
+
+ timerRow->setValue("SOURCE", !isEmpty(source) ? source : epgs ? "epgs" : Epg2VdrConfig.uuid);
+ timerRow->setValue("CHILDLOCK", childLock);
+ timerRow->setValue("AUX", t->Aux()); // update aux also in table
+
+ return done;
+}
+
+//***************************************************************************
+// New Timer From Row
+//***************************************************************************
+
+cEpgTimer* newTimerObjectFromRow(cDbRow* timerRow, cDbRow* vdrRow)
+{
+ cEpgTimer* timer = 0;
+ const cEvent* event = 0;
+ cString buf;
+ tChannelID channelId = tChannelID::FromString(timerRow->getStrValue("CHANNELID"));
+ uint flags = tfNone;
+ char* file;
+
+#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
+ LOCK_CHANNELS_READ;
+ const cChannels* channels = Channels;
+ const cChannel* channel = channels->GetByChannelID(channelId);
+#else
+ cChannels* channels = &Channels;
+ const cChannel* channel = channels->GetByChannelID(channelId);
+#endif
+
+ const char* dir = timerRow->getStrValue("DIRECTORY");
+
+ file = strdup(timerRow->getStrValue("FILE"));
+ strReplace(file, ':', '|');
+
+ if (timerRow->getIntValue("VPS"))
+ flags |= tfVps;
+
+ if (timerRow->getIntValue("ACTIVE"))
+ flags |= tfActive;
+
+ if (timerRow->hasCharValue("STATE", tsRunning))
+ flags |= tfRecording;
+
+ timer = new cEpgTimer(no, no, channel);
+
+ buf = cString::sprintf("%d:%d:%s:%04d:%04d:%d:%d:%s%s%s:%s",
+ flags,
+ channel ? channel->Number() : 0,
+ (const char*)cTimer::PrintDay(timerRow->getIntValue("DAY"),
+ timerRow->getIntValue("WEEKDAYS"), yes),
+ (int)timerRow->getIntValue("STARTTIME"),
+ (int)timerRow->getIntValue("ENDTIME"),
+ (int)timerRow->getIntValue("PRIORITY"),
+ (int)timerRow->getIntValue("LIFETIME"),
+ !isEmpty(dir) ? dir : "",
+ !isEmpty(dir) && !isEmpty(file) ? "~" : "",
+ file,
+ timerRow->getStrValue("AUX"));
+
+ free(file);
+ timer->Parse(buf);
+
+ if (channel)
+ {
+#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
+ cStateKey schedulesKey;
+ const cSchedules* schedules = cSchedules::GetSchedulesRead(schedulesKey);
+#else
+ cSchedulesLock* schedulesLock = new cSchedulesLock(false);
+ const cSchedules* schedules = (cSchedules*)cSchedules::Schedules(*schedulesLock);
+#endif
+ if (schedules)
+ {
+ const cSchedule* schedule = schedules->GetSchedule(channel);
+
+ if (schedule)
+ event = schedule->GetEvent(timerRow->getIntValue("EVENTID"));
+ }
+
+#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
+ if (schedules) schedulesKey.Remove();
+#else
+ delete schedulesLock;
+#endif
+ }
+
+ if (event)
+ timer->SetEvent(event);
+
+ timer->setTimerId(timerRow->getIntValue("ID"));
+ timer->setEventId(timerRow->getIntValue("EVENTID"));
+ timer->setAction(!timerRow->getValue("ACTION")->isNull() ? timerRow->getStrValue("ACTION")[0] : ' ');
+ timer->setVdr(vdrRow->getStrValue("NAME"), vdrRow->getStrValue("UUID"), vdrRow->hasValue("STATE", "attached"));
+ timer->setState(!timerRow->getValue("STATE")->isNull() ? timerRow->getStrValue("STATE")[0] : ' ', timerRow->getStrValue("INFO"));
+
+#ifdef WITH_PIN
+ timer->SetFskProtection(timerRow->getIntValue("CHILDLOCK"));
+#endif
+
+ return timer;
+}
+
+//***************************************************************************
+// update Timer Object From Row
+//***************************************************************************
+
+int updateTimerObjectFromRow(cTimer* timer, cDbRow* timerRow, const cEvent* event)
+{
+ if (!timerRow->getValue("FILE")->isEmpty())
+ {
+ string path = "";
+
+ if (!timerRow->getValue("DIRECTORY")->isEmpty())
+ path = timerRow->getStrValue("DIRECTORY") + string("~");
+
+ if (!timerRow->getValue("FILE")->isEmpty())
+ path += timerRow->getStrValue("FILE");
+
+ timer->SetFile(path.c_str());
+ }
+ else if (!timerRow->getValue("DIRECTORY")->isEmpty())
+ {
+ string path = timerRow->getStrValue("DIRECTORY") + string("~") + string(timer->File());
+ timer->SetFile(path.c_str());
+ }
+ else if (!event)
+ {
+#if APIVERSNUM >= 20301
+ LOCK_CHANNELS_READ;
+ const cChannels* channels = Channels;
+#else
+ cChannels* channels = &Channels;
+#endif
+
+ tChannelID channelId = tChannelID::FromString(timerRow->getStrValue("CHANNELID"));
+ const cChannel* channel = channels->GetByChannelID(channelId);
+
+ timer->SetFile(channel->Name());
+ tell(0, "Missing file, using channel name instead '%s'", channel->Name());
+ }
+
+ if (!timerRow->getValue("DAY")->isNull())
+ timer->SetDay(timerRow->getIntValue("DAY"));
+
+ if (!timerRow->getValue("WEEKDAYS")->isNull())
+ timer->SetWeekDays(timerRow->getIntValue("WEEKDAYS"));
+
+ if (!timerRow->getValue("STARTTIME")->isNull())
+ timer->SetStart(timerRow->getIntValue("STARTTIME"));
+
+ if (!timerRow->getValue("ENDTIME")->isNull())
+ timer->SetStop(timerRow->getIntValue("ENDTIME"));
+
+ if (!timerRow->getValue("PRIORITY")->isNull())
+ timer->SetPriority(timerRow->getIntValue("PRIORITY"));
+
+ if (!timerRow->getValue("LIFETIME")->isNull())
+ timer->SetLifetime(timerRow->getIntValue("LIFETIME"));
+
+ if (!timerRow->getValue("VPS")->isNull())
+ {
+ if (timerRow->getIntValue("VPS"))
+ timer->SetFlags(tfVps);
+ else
+ timer->ClrFlags(tfVps);
+ }
+
+ if (timerRow->getIntValue("ACTIVE"))
+ timer->SetFlags(tfActive);
+ else
+ timer->ClrFlags(tfActive);
+
+ setTagTo(timer, "timerid", timerRow->getIntValue("ID"));
+
+ if (!timerRow->getValue("SOURCE")->isNull())
+ setTagTo(timer, "source", timerRow->getStrValue("SOURCE"));
+
+ if (!timerRow->getValue("DIRECTORY")->isEmpty())
+ setTagTo(timer, "directory", timerRow->getStrValue("DIRECTORY"));
+
+ if (!timerRow->getValue("NAMINGMODE")->isNull())
+ setTagTo(timer, "namingmode", timerRow->getIntValue("NAMINGMODE"));
+
+ if (!timerRow->getValue("TEMPLATE")->isNull())
+ setTagTo(timer, "template", timerRow->getStrValue("TEMPLATE"));
+
+ if (!timerRow->getValue("AUTOTIMERID")->isNull())
+ setTagTo(timer, "autotimerid", timerRow->getIntValue("AUTOTIMERID"));
+
+ if (!timerRow->getValue("DONEID")->isNull())
+ setTagTo(timer, "doneid", timerRow->getIntValue("DONEID"));
+
+ if (!timerRow->getValue("AUTOTIMERINSSP")->isNull())
+ setTagTo(timer, "autotimerinssp", timerRow->getStrValue("AUTOTIMERINSSP"));
+
+ if (!timerRow->getValue("EXPRESSION")->isNull())
+ setTagTo(timer, "expression", timerRow->getStrValue("EXPRESSION"));
+
+ timer->Matches(); // adjust times of timer
+
+ return done;
+}