From 59875c10d77355d34b864445e63f635fcc60d853 Mon Sep 17 00:00:00 2001 From: horchi Date: Fri, 9 Feb 2018 17:15:09 +0100 Subject: 2018-02-09 version 1.1.82 (horchi)\n - added: Switch timer\n\n --- HISTORY.h | 9 ++-- TODO | 2 +- configs/epg.dat | 115 +++++++++++++++++++++++++++-------------------- epg2vdr.c | 2 + menu.c | 36 ++++++++++++++- menu.h | 3 +- menusched.c | 31 +++++++++---- po/de_DE.po | 5 ++- po/it_IT.po | 5 ++- recording.c | 17 +++++++ status.c | 2 +- timer.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- update.c | 31 ++++++++++++- update.h | 18 +++++--- 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 @@ -563,6 +564,24 @@ Table recordinglist SCRSP "" scrsp Int 0 Data, } +// ---------------------------------------------------------------- +// 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); @@ -701,11 +703,39 @@ int cMenuDb::modifyTimer(cDbRow* timerRow, const char* destUuid) return success; } +//*************************************************************************** +// 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: \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 \n" "Language-Team: \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: \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 \n" "Language-Team: \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 @@ -12,11 +12,75 @@ #include "ttools.h" #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 @@ -366,6 +436,64 @@ int cUpdate::performTimerJobs() return success; } +//*************************************************************************** +// 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 pendingNewRecordings; // recordings to store details (obsolete if pendingRecordingActions implemented finally) + std::queue pendingNewRecordings; // recordings to store details (obsolete if pendingRecordingActions implemented finally) std::queue pendingRecordingActions; // recordings actions (start/stop) - std::vector deletedTimers; + std::map switchTimers; static const char* auxFields[]; }; -- cgit v1.2.3