summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HISTORY.h9
-rw-r--r--TODO2
-rw-r--r--configs/epg.dat115
-rw-r--r--epg2vdr.c2
-rw-r--r--menu.c36
-rw-r--r--menu.h3
-rw-r--r--menusched.c31
-rw-r--r--po/de_DE.po5
-rw-r--r--po/it_IT.po5
-rw-r--r--recording.c17
-rw-r--r--status.c2
-rw-r--r--timer.c136
-rw-r--r--update.c31
-rw-r--r--update.h18
14 files changed, 338 insertions, 74 deletions
diff --git a/HISTORY.h b/HISTORY.h
index 385a819..df9c9ba 100644
--- a/HISTORY.h
+++ b/HISTORY.h
@@ -5,10 +5,10 @@
*
*/
-#define _VERSION "1.1.81"
-#define VERSION_DATE "29.01.2018"
+#define _VERSION "1.1.82"
+#define VERSION_DATE "09.02.2018"
-#define DB_API 5
+#define DB_API 6
#ifdef GIT_REV
# define VERSION _VERSION "-GIT" GIT_REV
@@ -19,6 +19,9 @@
/*
* ------------------------------------
+2018-02-09 version 1.1.82 (horchi)
+ - added: Switch timer
+
2018-01-29 version 1.1.81 (horchi)
- bugfix: Fixed possible crash on recording update without longdescription
- change: More readable error message on DBAPI mismatch (thx to Lars!)
diff --git a/TODO b/TODO
index 3fd95d1..6fe82dd 100644
--- a/TODO
+++ b/TODO
@@ -4,4 +4,4 @@
- anlegen eines Suchtimer über das event
- timer mit action 'C' auch ohne vdruuid übernehmen
-- db Verbindungssaten ohne Neustart übernehmen \ No newline at end of file
+- db Verbindungsdaten ohne Neustart übernehmen
diff --git a/configs/epg.dat b/configs/epg.dat
index 1b3884d..8d3ce74 100644
--- a/configs/epg.dat
+++ b/configs/epg.dat
@@ -1,6 +1,6 @@
// --------------------------------------------------------------------------
//
-// Table Dictionary for EPG Daemon and related Plugins
+// Database Dictionary for EPG Daemon and related Plugins
//
// --------------------------------------------------------------------------
// See the README file for copyright information and how to reach the author
@@ -487,56 +487,57 @@ Index useevents
Table recordinglist
{
- MD5PATH "" md5path Ascii 40 Primary,
- STARTTIME "" starttime UInt 0 Primary,
- OWNER "uuid of vdr" owner Ascii 40 Primary,
-
- INSSP "" inssp Int 10 Meta,
- UPDSP "" updsp Int 10 Meta,
- LASTIFOUPD "" lastifoupd Int 10 Meta,
-
- VDRUUID "" vdruuid Ascii 40 Data,
- PATH "" path Ascii 1000 Data,
- NAME "" name Ascii 1000 Data,
- FOLDER "" folder Ascii 1000 Data,
- TITLE "" title Ascii 200 Data,
- SHORTTEXT "" shorttext Ascii 300 Data,
- LONGDESCRIPTION "" longdescription MText 25000 Data,
- DESCRIPTION "" description MText 25000 Data,
- DURATION "" duration UInt 0 Data,
- FSK "" fsk UInt 1 Data,
-
- EVENTID "useid" eventid UInt 0 Data,
- CHANNELID "" channelid Ascii 50 Data,
- CHANNELNAME "just a copy" channelname Ascii 100 Data,
-
- STATE "" state Ascii 1 Data,
- INUSE "" inuse UInt 1 Data,
- JOB "" job Ascii 1 Data,
+ MD5PATH "" md5path Ascii 40 Primary,
+ STARTTIME "" starttime UInt 0 Primary,
+ OWNER "uuid of vdr" owner Ascii 40 Primary,
+
+ INSSP "" inssp Int 10 Meta,
+ UPDSP "" updsp Int 10 Meta,
+ LASTIFOUPD "" lastifoupd Int 10 Meta,
+
+ IMGID "md5 of title/shorttext" imgid Ascii 40 Data,
+ VDRUUID "" vdruuid Ascii 40 Data,
+ PATH "" path Ascii 1000 Data,
+ NAME "" name Ascii 1000 Data,
+ FOLDER "" folder Ascii 1000 Data,
+ TITLE "" title Ascii 200 Data,
+ SHORTTEXT "" shorttext Ascii 300 Data,
+ LONGDESCRIPTION "" longdescription MText 25000 Data,
+ DESCRIPTION "" description MText 25000 Data,
+ DURATION "" duration UInt 0 Data,
+ FSK "" fsk UInt 1 Data,
+
+ EVENTID "useid" eventid UInt 0 Data,
+ CHANNELID "" channelid Ascii 50 Data,
+ CHANNELNAME "just a copy" channelname Ascii 100 Data,
+
+ STATE "" state Ascii 1 Data,
+ INUSE "" inuse UInt 1 Data,
+ JOB "" job Ascii 1 Data,
// enriched by 'external' data of events
- ACTOR "" actor MText 5000 Data,
- AUDIO "" audio Ascii 50 Data,
- CATEGORY "" category Ascii 50 Data,
- COUNTRY "" country Ascii 50 Data,
- DIRECTOR "" director Text 1000 Data,
- FLAGS "" flags Ascii 100 Data,
- GENRE "" genre Ascii 100 Data,
- MUSIC "" music Ascii 250 Data,
- PRODUCER "" producer Text 1000 Data,
- SCREENPLAY "" screenplay Ascii 500 Data,
- SHORTREVIEW "" shortreview Ascii 500 Data,
- TIPP "" tipp Ascii 250 Data,
- TOPIC "" topic Ascii 1000 Data,
- YEAR "" year Ascii 10 Data,
- RATING "" rating Ascii 250 Data,
- NUMRATING "" numrating Int 2 Data,
- TXTRATING "" txtrating Ascii 100 Data,
- MODERATOR "" moderator Ascii 250 Data,
- OTHER "" other Text 2000 Data,
- GUEST "" guest Text 1000 Data,
- CAMERA "" camera Text 1000 Data,
+ ACTOR "" actor MText 5000 Data,
+ AUDIO "" audio Ascii 50 Data,
+ CATEGORY "" category Ascii 50 Data,
+ COUNTRY "" country Ascii 50 Data,
+ DIRECTOR "" director Text 1000 Data,
+ FLAGS "" flags Ascii 100 Data,
+ GENRE "" genre Ascii 100 Data,
+ MUSIC "" music Ascii 250 Data,
+ PRODUCER "" producer Text 1000 Data,
+ SCREENPLAY "" screenplay Ascii 500 Data,
+ SHORTREVIEW "" shortreview Ascii 500 Data,
+ TIPP "" tipp Ascii 250 Data,
+ TOPIC "" topic Ascii 1000 Data,
+ YEAR "" year Ascii 10 Data,
+ RATING "" rating Ascii 250 Data,
+ NUMRATING "" numrating Int 2 Data,
+ TXTRATING "" txtrating Ascii 100 Data,
+ MODERATOR "" moderator Ascii 250 Data,
+ OTHER "" other Text 2000 Data,
+ GUEST "" guest Text 1000 Data,
+ CAMERA "" camera Text 1000 Data,
// episode reference
@@ -564,6 +565,24 @@ Table recordinglist
}
// ----------------------------------------------------------------
+// Recording Images
+// ----------------------------------------------------------------
+
+Table recordingimages
+{
+ IMGID "md5 of title/shorttext" imgid Ascii 40 Primary,
+ LFN "" lfn UInt 0 Primary,
+
+ INSSP "" inssp Int 0 Meta,
+ UPDSP "" updsp Int 0 Meta,
+
+ TITLE "" title Ascii 200 Data,
+ SHORTTEXT "" shorttext Ascii 300 Data,
+
+ IMAGE "" image Mlob 512000 Data,
+}
+
+// ----------------------------------------------------------------
// Table RecordingDirs
// ----------------------------------------------------------------
diff --git a/epg2vdr.c b/epg2vdr.c
index f56ccb3..f51dc53 100644
--- a/epg2vdr.c
+++ b/epg2vdr.c
@@ -476,6 +476,8 @@ int cPluginEPG2VDR::initDb()
timerDb->getField("ACTIVE")->getDbName(),
timerDb->getField("STATE")->getDbName(),
timerDb->getField("STATE")->getDbName());
+ selectTimers->build(" and t.%s = '%c'",
+ timerDb->getField("TYPE")->getDbName(), ttRecord);
selectTimers->build(" and t.%s = v.%s order by t.%s",
timerDb->getField("VDRUUID")->getDbName(),
vdrDb->getField("UUID")->getDbName(),
diff --git a/menu.c b/menu.c
index d24a92a..ee1aebb 100644
--- a/menu.c
+++ b/menu.c
@@ -667,6 +667,7 @@ int cMenuDb::modifyTimer(cDbRow* timerRow, const char* destUuid)
timerDb->setValue("VDRUUID", destUuid);
timerDb->setCharValue("ACTION", taCreate);
timerDb->setValue("SOURCE", Epg2VdrConfig.uuid);
+ timerDb->setCharValue("TYPE", ttRecord);
timerDb->insert();
tell(0, "Created 'move' request for timer (%d) at vdr '%s'",
@@ -681,6 +682,7 @@ int cMenuDb::modifyTimer(cDbRow* timerRow, const char* destUuid)
timerDb->setCharValue("ACTION", knownTimer ? taModify : taCreate);
timerDb->getValue("STATE")->setNull();
timerDb->setValue("SOURCE", Epg2VdrConfig.uuid);
+ timerDb->setCharValue("TYPE", ttRecord);
if (!knownTimer)
timerDb->setValue("NAMINGMODE", tnmAuto);
@@ -702,10 +704,38 @@ int cMenuDb::modifyTimer(cDbRow* timerRow, const char* destUuid)
}
//***************************************************************************
+// Create Switch Timer
+//***************************************************************************
+
+int cMenuDb::createSwitchTimer(const cEvent* event)
+{
+ int timerMatch = tmNone;
+ int remote = no;
+
+ // alredy or nearly started?
+
+ if (!event || event->StartTime() <= time(0)+tmeSecondsPerMinute)
+ return done;
+
+ // already created?
+
+ if (lookupTimer(event, timerMatch, remote))
+ return done;
+
+ cDbRow* timerRow = newTimerRowFromEvent(event);
+ createTimer(timerRow, Epg2VdrConfig.uuid, ttView);
+
+ tell(0, "Switch timer for '%s' at '%s' created",
+ event->Title(), l2pTime(event->StartTime()).c_str());
+
+ return done;
+}
+
+//***************************************************************************
// Create Timer
//***************************************************************************
-int cMenuDb::createTimer(cDbRow* timerRow, const char* destUuid)
+int cMenuDb::createTimer(cDbRow* timerRow, const char* destUuid, int type)
{
long int manualTimer2Done;
@@ -717,11 +747,13 @@ int cMenuDb::createTimer(cDbRow* timerRow, const char* destUuid)
timerDb->copyValues(timerRow, cDBS::ftData);
timerDb->setValue("VDRUUID", destUuid);
+ timerDb->setCharValue("TYPE", type);
+ // timerDb->setCharValue("ACTIVE", type != ttView); // #TODO will this better?
timerDb->setCharValue("ACTION", taCreate);
timerDb->setValue("SOURCE", Epg2VdrConfig.uuid);
timerDb->setValue("NAMINGMODE", tnmAuto);
- if (manualTimer2Done)
+ if (manualTimer2Done && type != ttView)
{
useeventsDb->clear();
useeventsDb->setValue("USEID", timerRow->getIntValue("EVENTID"));
diff --git a/menu.h b/menu.h
index 23442f2..704c120 100644
--- a/menu.h
+++ b/menu.h
@@ -74,7 +74,8 @@ class cMenuDb : public cParameters
// timer db
- int createTimer(cDbRow* timerRow, const char* destUuid);
+ int createSwitchTimer(const cEvent* event);
+ int createTimer(cDbRow* timerRow, const char* destUuid, int type = ttRecord);
int modifyTimer(cDbRow* timerRow, const char* destUuid = 0);
int deleteTimer(long timerid);
diff --git a/menusched.c b/menusched.c
index bcbb3fe..7c79502 100644
--- a/menusched.c
+++ b/menusched.c
@@ -49,6 +49,7 @@ cEpgCommandMenu::cEpgCommandMenu(const char* title, cMenuDb* db, const cMenuEpgS
cOsdMenu::Add(new cOsdItem(hk(tr("Search matching Events")), osUser1));
cOsdMenu::Add(new cOsdItem(hk(tr("Search matching Recordings")), osUser2));
cOsdMenu::Add(new cOsdItem(hk(tr("Searchtimers")), osUser3));
+ cOsdMenu::Add(new cOsdItem(hk(tr("Switch Timer")), osUser4));
SetHelp(0, 0, 0, 0);
@@ -77,7 +78,18 @@ eOSState cEpgCommandMenu::ProcessKey(eKeys key)
break;
}
- case osUser3: return AddSubMenu(new cMenuEpgSearchTimers());
+ case osUser3:
+ {
+ return AddSubMenu(new cMenuEpgSearchTimers());
+ }
+
+ case osUser4:
+ {
+ if (item)
+ menuDb->createSwitchTimer(item->event);
+
+ return osBack;
+ }
default: ;
}
@@ -1028,13 +1040,13 @@ eOSState cMenuEpgWhatsOn::Record()
menuDb->getParameter(menuDb->user.c_str(), "timerDefaultVDRuuid", timerDefaultVDRuuid);
- // Menü bei 'aktuellem' Event Timer Dialog öffen -> #TODO
+ // // Menü bei 'aktuellem' Event Timer Dialog öffen -> #TODO
- if (timer && timer->Event() && timer->Event()->StartTime() < time(0) + NEWTIMERLIMIT)
- {
- // timer = newTimerObjectFromRow(timerRow, xxxxx);
- // return AddSubMenu(new cMenuEpgEditTimer(menuDb, timer));
- }
+ // if (item->event && item->event->StartTime() < time(0) + NEWTIMERLIMIT)
+ // {
+ // // timer = newTimerObjectFromRow(timerRow, xxxxx);
+ // // return AddSubMenu(new cMenuEpgEditTimer(menuDb, timer));
+ // }
// ansonsten direkt anlegen
@@ -1119,7 +1131,10 @@ eOSState cMenuEpgWhatsOn::ProcessKey(eKeys Key)
case k4: // Umschalt Timer erstellen
{
- break;
+ if (cMenuEpgScheduleItem* mi = (cMenuEpgScheduleItem*)Get(Current()))
+ menuDb->createSwitchTimer(mi->event);
+
+ return osContinue;
}
case kRecord:
diff --git a/po/de_DE.po b/po/de_DE.po
index fc7f868..7253b39 100644
--- a/po/de_DE.po
+++ b/po/de_DE.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.5.7\n"
"Report-Msgid-Bugs-To: <vdr@jwendel.de>\n"
-"POT-Creation-Date: 2017-03-24 07:25+0100\n"
+"POT-Creation-Date: 2018-02-09 11:16+0100\n"
"PO-Revision-Date: 2009-08-27 21:40+0200\n"
"Last-Translator: Klaus Schmidinger <kls@cadsoft.de>\n"
"Language-Team: <vdr@linuxtv.org>\n"
@@ -178,6 +178,9 @@ msgstr ""
msgid "Searchtimers"
msgstr ""
+msgid "Switch Timer"
+msgstr ""
+
msgid "Matching recordings"
msgstr "Vergleiche Aufnahmen"
diff --git a/po/it_IT.po b/po/it_IT.po
index 77ebd5a..078b72f 100644
--- a/po/it_IT.po
+++ b/po/it_IT.po
@@ -9,7 +9,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.5.7\n"
"Report-Msgid-Bugs-To: <vdr@jwendel.de>\n"
-"POT-Creation-Date: 2017-03-24 07:25+0100\n"
+"POT-Creation-Date: 2018-02-09 11:16+0100\n"
"PO-Revision-Date: 2009-08-27 21:45+0100\n"
"Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n"
"Language-Team: <vdr@linuxtv.org>\n"
@@ -183,6 +183,9 @@ msgstr ""
msgid "Searchtimers"
msgstr ""
+msgid "Switch Timer"
+msgstr ""
+
msgid "Matching recordings"
msgstr ""
diff --git a/recording.c b/recording.c
index e572f2b..2de582e 100644
--- a/recording.c
+++ b/recording.c
@@ -481,6 +481,23 @@ int cUpdate::updateRecordingTable(int fullReload)
recordingListDb->store();
}
+ // check recording image table
+
+ if (!recordingListDb->getValue("IMGID")->isEmpty())
+ {
+ recordingImagesDb->setValue("IMGID", recordingListDb->getStrValue("IMGID"));
+ recordingImagesDb->setValue("LFN", 1);
+
+ if (!recordingImagesDb->find())
+ {
+ // we don't have a image, check filesystem
+
+
+ }
+
+ recordingImagesDb->reset();
+ }
+
count++;
recordingListDb->reset();
}
diff --git a/status.c b/status.c
index 6acd011..d8275ec 100644
--- a/status.c
+++ b/status.c
@@ -16,7 +16,7 @@
#define LOC_INDEXFILESUFFIX "/index"
-bool IsPesRecording(const cRecording *pRecording)
+bool IsPesRecording(const cRecording* pRecording)
{
#if VDRVERSNUM < 10703
return true;
diff --git a/timer.c b/timer.c
index 5faa03f..958bff9 100644
--- a/timer.c
+++ b/timer.c
@@ -13,10 +13,74 @@
#include "service.h"
//***************************************************************************
+// Check Switch Timer
+//***************************************************************************
+
+int cUpdate::checkSwitchTimer()
+{
+ cMutexLock lock(&swTimerMutex);
+
+ for (auto it = switchTimers.begin(); it != switchTimers.end(); )
+ {
+ SwitchTimer* swTimer = &(it->second);
+
+ if (time(0) < swTimer->start)
+ {
+ it++;
+ continue;
+ }
+
+ tChannelID channelId = tChannelID::FromString(swTimer->channelId.c_str());
+
+#if APIVERSNUM >= 20301
+ LOCK_CHANNELS_READ;
+ const cChannels* channels = Channels;
+ const cChannel* channel = channels->GetByChannelID(channelId, true);
+#else
+ cChannels* channels = &Channels;
+ cChannel* channel = channels->GetByChannelID(channelId, true);
+#endif
+
+ if (!channel)
+ {
+ tell(0, "Switching to channel '%s' failed, channel not found!", swTimer->channelId.c_str());
+ }
+ else
+ {
+ tell(0, "Switching to channel '%s'", channel->Name());
+
+ if (!cDevice::PrimaryDevice()->SwitchChannel(channel, true))
+ Skins.Message(mtError, tr("Can't switch channel!"));
+ }
+
+ timerDb->clear();
+ timerDb->setValue("ID", it->first);
+ timerDb->setValue("VDRUUID", Epg2VdrConfig.uuid);
+
+ if (timerDb->find())
+ {
+ timerDb->setCharValue("ACTION", taAssumed);
+ timerDb->setCharValue("STATE", tsFinished);
+ timerDb->store();
+ }
+ else
+ {
+ tell(0, "Can't find timer '%ld', ignoring update of record", it->first);
+ }
+
+ timerDb->reset();
+
+ it = switchTimers.erase(it);
+ }
+
+ return done;
+}
+
+//***************************************************************************
// Has Timer Changed
//***************************************************************************
-int cUpdate::timerChanged()
+int cUpdate::hasTimerChanged()
{
int maxSp = 0;
int changed = no;
@@ -48,6 +112,10 @@ int cUpdate::performTimerJobs()
int deleteCount = 0;
uint64_t start = cTimeMs::Now();
+ // switch timers ...
+
+ takeSwitchTimer();
+
tell(1, "Checking pending timer actions ..");
// check if timer pending
@@ -66,6 +134,8 @@ int cUpdate::performTimerJobs()
selectPendingTimerActions->freeResult();
}
+ // recording timers ...
+
GET_TIMERS_WRITE(timers); // get timers lock
GET_CHANNELS_READ(channels); // get channels lock
@@ -367,6 +437,64 @@ int cUpdate::performTimerJobs()
}
//***************************************************************************
+// Take Switch Timer
+//***************************************************************************
+
+int cUpdate::takeSwitchTimer()
+{
+ cMutexLock lock(&swTimerMutex);
+
+ tell(1, "Checking switch timer actions ..");
+
+ // iterate pending switch timers ...
+
+ timerDb->clear();
+ timerDb->setValue("VDRUUID", Epg2VdrConfig.uuid);
+
+ for (int f = selectSwitchTimerActions->find(); f && dbConnected(); f = selectSwitchTimerActions->fetch())
+ {
+ long timerid = timerDb->getIntValue("ID");
+
+ // to old?
+
+ if (time(0) > timerDb->getIntValue("_STARTTIME"))
+ {
+ // to old, set to 'Finished'
+
+ timerDb->setCharValue("ACTION", taAssumed);
+ timerDb->setCharValue("STATE", tsFinished);
+ timerDb->store();
+ continue;
+ }
+
+ // if already in list, ignore
+
+ auto it = switchTimers.find(timerid);
+
+ if (it != switchTimers.end())
+ continue;
+
+ // not in map, create
+
+ tell(1, "Got switch timer (%ld) for channel '%s' at '%s'",
+ timerDb->getIntValue("ID"), timerDb->getStrValue("CHANNELID"),
+ l2pTime(timerDb->getIntValue("_STARTTIME") - tmeSecondsPerMinute).c_str());
+
+ switchTimers[timerid].eventId = timerDb->getIntValue("EVENTID");
+ switchTimers[timerid].channelId = timerDb->getStrValue("CHANNELID");
+ switchTimers[timerid].start = timerDb->getIntValue("_STARTTIME") - tmeSecondsPerMinute;
+
+ timerDb->setCharValue("ACTION", taAssumed);
+ timerDb->setCharValue("STATE", tsPending);
+ timerDb->store();
+ }
+
+ selectSwitchTimerActions->freeResult();
+
+ return done;
+}
+
+//***************************************************************************
// Timer Done to Failed
//***************************************************************************
@@ -444,6 +572,11 @@ int cUpdate::updateTimerTable()
if (!timerDb->getValue("ACTION")->isEmpty() && !timerDb->hasCharValue("ACTION", taAssumed))
continue;
+ // ignore switch timer here
+
+ if (timerDb->hasCharValue("TYPE", ttView))
+ continue;
+
// count my timers to detect truncated (epmty) table
// on empty table ignore known timer ids
@@ -526,6 +659,7 @@ int cUpdate::updateTimerTable()
if (insert)
{
+ timerDb->setCharValue("TYPE", ttRecord);
timerDb->setCharValue("STATE", tsPending);
timerDb->insert();
diff --git a/update.c b/update.c
index 6b8ef0f..eee6ded 100644
--- a/update.c
+++ b/update.c
@@ -122,6 +122,7 @@ cUpdate::cUpdate(cPluginEPG2VDR* aPlugin)
timerDoneDb = 0;
recordingDirDb = 0;
recordingListDb = 0;
+ recordingImagesDb = 0;
selectMasterVdr = 0;
selectAllImages = 0;
@@ -140,6 +141,7 @@ cUpdate::cUpdate(cPluginEPG2VDR* aPlugin)
selectTimerByDoneId = 0;
selectMaxUpdSp = 0;
selectPendingTimerActions = 0;
+ selectSwitchTimerActions = 0;
viewDescription = 0;
viewMergeSource = 0;
@@ -330,6 +332,9 @@ int cUpdate::initDb()
recordingListDb = new cDbTable(connection, "recordinglist");
if (recordingListDb->open() != success) return fail;
+ recordingImagesDb = new cDbTable(connection, "recordingimages");
+ if (recordingImagesDb->open() != success) return fail;
+
if ((status = cParameters::initDb(connection)) != success)
return status;
@@ -641,11 +646,29 @@ int cUpdate::initDb()
timerDb->getField("ACTION")->getDbName(),
timerDb->getField("ACTION")->getDbName(),
timerDb->getField("ACTION")->getDbName());
+ selectPendingTimerActions->build(" and %s != '%c'",
+ timerDb->getField("TYPE")->getDbName(), ttView);
selectPendingTimerActions->bind("VDRUUID", cDBS::bndIn | cDBS::bndSet, " and (");
selectPendingTimerActions->build(" or %s = 'any')", timerDb->getField("VDRUUID")->getDbName());
status += selectPendingTimerActions->prepare();
+ // select * from timers
+ // where
+ // action != 'A' and action != 'F' and action is not null // !taAssumed and !taFailed
+ // and (vdruuid = ? or vdruuid = 'any')
+
+ selectSwitchTimerActions = new cDbStatement(timerDb);
+
+ selectSwitchTimerActions->build("select ");
+ selectSwitchTimerActions->bindAllOut();
+ selectSwitchTimerActions->build(" from %s where ", timerDb->TableName());
+ selectSwitchTimerActions->build("%s != '%c'", timerDb->getField("STATE")->getDbName(), tsFinished);
+ selectSwitchTimerActions->build(" and %s = '%c'", timerDb->getField("TYPE")->getDbName(), ttView);
+ selectSwitchTimerActions->bind("VDRUUID", cDBS::bndIn | cDBS::bndSet, " and ");
+
+ status += selectSwitchTimerActions->prepare();
+
// delete from timers where
// eventid = ?
@@ -758,6 +781,7 @@ int cUpdate::exitDb()
delete selectTimerByDoneId; selectTimerByDoneId = 0;
delete selectMaxUpdSp; selectMaxUpdSp = 0;
delete selectPendingTimerActions; selectPendingTimerActions = 0;
+ delete selectSwitchTimerActions; selectSwitchTimerActions = 0;
delete vdrDb; vdrDb = 0;
delete mapDb; mapDb = 0;
@@ -772,6 +796,7 @@ int cUpdate::exitDb()
delete timerDoneDb; timerDoneDb = 0;
delete recordingDirDb; recordingDirDb = 0;
delete recordingListDb; recordingListDb = 0;
+ delete recordingImagesDb; recordingImagesDb = 0;
delete viewDescription; viewDescription = 0;
delete viewMergeSource; viewMergeSource = 0;
@@ -1223,6 +1248,10 @@ void cUpdate::Action()
if (checkConnection(reconnectTimeout) != success)
continue;
+ // switch timer
+
+ checkSwitchTimer();
+
// recording stuff
if (dbConnected() && updateRecFolderOptionTrigger)
@@ -1276,7 +1305,7 @@ void cUpdate::Action()
updateTimerTable();
if (dbConnected())
- timerChanged();
+ hasTimerChanged();
}
// if triggered externally or updates pending
diff --git a/update.h b/update.h
index aca9a87..a9be6c7 100644
--- a/update.h
+++ b/update.h
@@ -144,10 +144,11 @@ class cUpdate : public cThread, public cStatus, public cParameters
private:
- struct TimerId
+ struct SwitchTimer
{
- unsigned int eventId;
- char channelId[100];
+ long eventId;
+ std::string channelId;
+ time_t start;
};
// struct to store a recording action delieverd by the status interface
@@ -195,7 +196,9 @@ class cUpdate : public cThread, public cStatus, public cParameters
int performTimerJobs();
int recordingChanged();
int updateTimerDone(int timerid, int doneid, char state);
- int timerChanged();
+ int hasTimerChanged();
+ int takeSwitchTimer();
+ int checkSwitchTimer();
// recording stuff
@@ -226,6 +229,7 @@ class cUpdate : public cThread, public cStatus, public cParameters
char imageExtension[3+TB];
cMutex timerMutex;
+ cMutex swTimerMutex;
int dbReconnectTriggered;
int timerJobsUpdateTriggered;
int timerTableUpdateTriggered;
@@ -257,6 +261,7 @@ class cUpdate : public cThread, public cStatus, public cParameters
cDbTable* compDb;
cDbTable* recordingDirDb;
cDbTable* recordingListDb;
+ cDbTable* recordingImagesDb;
cDbStatement* selectMasterVdr;
cDbStatement* selectAllImages;
@@ -271,6 +276,7 @@ class cUpdate : public cThread, public cStatus, public cParameters
cDbStatement* selectRecordings;
cDbStatement* selectRecForInfoUpdate;
cDbStatement* selectPendingTimerActions;
+ cDbStatement* selectSwitchTimerActions;
cDbStatement* selectTimerByEvent;
cDbStatement* selectTimerById;
cDbStatement* selectTimerByDoneId;
@@ -288,9 +294,9 @@ class cUpdate : public cThread, public cStatus, public cParameters
cDbValue* viewMergeSource;
cDbValue* viewLongDescription;
- std::queue<std::string> pendingNewRecordings; // recordings to store details (obsolete if pendingRecordingActions implemented finally)
+ std::queue<std::string> pendingNewRecordings; // recordings to store details (obsolete if pendingRecordingActions implemented finally)
std::queue<RecordingAction> pendingRecordingActions; // recordings actions (start/stop)
- std::vector<TimerId> deletedTimers;
+ std::map<long,SwitchTimer> switchTimers;
static const char* auxFields[];
};