diff options
author | horchi <vdr@jwendel.de> | 2017-03-05 14:51:57 +0100 |
---|---|---|
committer | horchi <vdr@jwendel.de> | 2017-03-05 14:51:57 +0100 |
commit | 5eacf5bf36ddbac082a9e40a2bcdfd0f04fd3f9f (patch) | |
tree | 392875cb707b94aaba9d8941113eae35efaf2ec2 /menu.c | |
download | vdr-plugin-epg2vdr-5eacf5bf36ddbac082a9e40a2bcdfd0f04fd3f9f.tar.gz vdr-plugin-epg2vdr-5eacf5bf36ddbac082a9e40a2bcdfd0f04fd3f9f.tar.bz2 |
Diffstat (limited to 'menu.c')
-rw-r--r-- | menu.c | 823 |
1 files changed, 823 insertions, 0 deletions
@@ -0,0 +1,823 @@ +/* + * menu.c: EPG2VDR plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#include "svdrpclient.h" +#include "plgconfig.h" +#include "menu.h" + +#include "update.h" + +//*************************************************************************** +// Object +//*************************************************************************** + +cMenuDb::cMenuDb() +{ + vdrList = 0; + vdrCount = 0; + vdrUuidList = 0; + + timersCacheMaxUpdsp = 0; + dbInitialized = no; + connection = 0; + + timerDb = 0; + vdrDb = 0; + timerDoneDb = 0; + userDb = 0; + searchtimerDb = 0; + recordingListDb = 0; + useeventsDb = 0; + + selectTimers = 0; + selectMaxUpdSp = 0; + selectTimerById = 0; + selectActiveVdrs = 0; + selectAllVdrs = 0; + selectAllUser = 0; + selectSearchTimers = 0; + selectSearchTimerByName = 0; + + selectDoneTimerByStateTitleOrder = 0; + selectDoneTimerByStateTimeOrder = 0; + selectRecordingForEvent = 0; + selectRecordingForEventByLv = 0; + + webLoginEnabled = no; + user = "@"; + startWithSched = no; + + search = new cSearchTimer(); + + userTimes = new cUserTimes; + initDb(); +} + +cMenuDb::~cMenuDb() +{ + exitDb(); + delete userTimes; +} + +cDbFieldDef startTimeDef("starttime", "starttime", cDBS::ffInt, 0, cDBS::ftData); +cDbFieldDef timerStateDef("state", "state", cDBS::ffAscii, 100, cDBS::ftData); +cDbFieldDef timerActionDef("action", "action", cDBS::ffAscii, 100, cDBS::ftData); + +//*************************************************************************** +// initDb / exitDb +//*************************************************************************** + +int cMenuDb::initDb() +{ + int status = success; + + exitDb(); + + connection = new cDbConnection(); + + timerDb = new cDbTable(connection, "timers"); + if (timerDb->open() != success) return fail; + + vdrDb = new cDbTable(connection, "vdrs"); + if (vdrDb->open() != success) return fail; + + timerDoneDb = new cDbTable(connection, "timersdone"); + if (timerDoneDb->open() != success) return fail; + + userDb = new cDbTable(connection, "users"); + if (userDb->open() != success) return fail; + + searchtimerDb = new cDbTable(connection, "searchtimers"); + if (searchtimerDb->open() != success) return fail; + + recordingListDb = new cDbTable(connection, "recordinglist"); + if (recordingListDb->open() != success) return fail; + + useeventsDb = new cDbTable(connection, "useevents"); + if ((status = useeventsDb->open() != success)) return status; + + if ((status = cParameters::initDb(connection)) != success) + return status; + + valueStartTime.setField(&startTimeDef); + timerState.setField(&timerStateDef); + timerAction.setField(&timerActionDef); + + //----------- + // select + // max(updsp) + // from timers + + selectMaxUpdSp = new cDbStatement(timerDb); + + selectMaxUpdSp->build("select "); + selectMaxUpdSp->bind("UPDSP", cDBS::bndOut, "max("); + selectMaxUpdSp->build(") from %s", timerDb->TableName()); + + status += selectMaxUpdSp->prepare(); + + // ---------- + // select + // t.*, + // t.day + t.starttime div 100 * 60 * 60 + t.starttime % 100 * 60, + // v.name, v.state + // from timers t, vdrs v + // where + // t.vdruuid = v.uuid + // and (t.state in ('P','R') or t.state is null) + // order by t.day, t.starttime + + selectTimers = new cDbStatement(timerDb); + + selectTimers->build("select "); + selectTimers->setBindPrefix("t."); + selectTimers->bindAllOut(); + selectTimers->bindTextFree(", t.day + t.starttime div 100 * 60 * 60 + t.starttime % 100 * 60", + &valueStartTime, cDBS::bndOut); + selectTimers->setBindPrefix("v."); + selectTimers->bind(vdrDb, "NAME", cDBS::bndOut, ", "); + selectTimers->bind(vdrDb, "UUID", cDBS::bndOut, ", "); + selectTimers->bind(vdrDb, "STATE", cDBS::bndOut, ", "); + selectTimers->clrBindPrefix(); + selectTimers->build(" from %s t, %s v where ", + timerDb->TableName(), vdrDb->TableName()); + selectTimers->build("t.%s = v.%s", + timerDb->getField("VDRUUID")->getDbName(), + vdrDb->getField("UUID")->getDbName()); + + selectTimers->bindInChar("t", timerDb->getField("STATE")->getDbName(), &timerState, " and ("); + selectTimers->build(" or t.%s is null)", timerDb->getField("STATE")->getDbName()); + + selectTimers->bindInChar("t", timerDb->getField("ACTION")->getDbName(), &timerAction, " and ("); + selectTimers->build(" or t.%s is null)", timerDb->getField("ACTION")->getDbName()); + + // selectTimers->build(" and (t.%s in ('P','R') or t.%s is null)", + // timerDb->getField("STATE")->getDbName(), + // timerDb->getField("STATE")->getDbName()); + + selectTimers->build(" order by t.%s, t.%s", + timerDb->getField("DAY")->getDbName(), + timerDb->getField("STARTTIME")->getDbName()); + + status += selectTimers->prepare(); + + // select + // t.*, + // t.day + t.starttime div 100 * 60 * 60 + t.starttime % 100 * 60, + // v.name, v.state + // from timers t, vdrs v + // where + // t.id = ? + // and t.vdruuid = v.uuid + + selectTimerById = new cDbStatement(timerDb); + + selectTimerById->build("select "); + selectTimerById->setBindPrefix("t."); + selectTimerById->bindAllOut(); + selectTimerById->bindTextFree(", t.day + t.starttime div 100 * 60 * 60 + t.starttime % 100 * 60", + &valueStartTime, cDBS::bndOut); + selectTimerById->setBindPrefix("v."); + selectTimerById->bind(vdrDb, "NAME", cDBS::bndOut, ", "); + selectTimerById->bind(vdrDb, "UUID", cDBS::bndOut, ", "); + selectTimerById->bind(vdrDb, "STATE", cDBS::bndOut, ", "); + selectTimerById->clrBindPrefix(); + selectTimerById->build(" from %s t, %s v where ", timerDb->TableName(), vdrDb->TableName()); + selectTimerById->setBindPrefix("t."); + selectTimerById->bind("ID", cDBS::bndIn | cDBS::bndSet); + selectTimerById->clrBindPrefix(); + selectTimerById->build(" and t.%s = v.%s", + timerDb->getField("VDRUUID")->getDbName(), + vdrDb->getField("UUID")->getDbName()); + + status += selectTimerById->prepare(); + + // ---------- + // select ip, svdrp from vdrs + // where state = 'attached' + + selectActiveVdrs = new cDbStatement(vdrDb); + + selectActiveVdrs->build("select "); + selectActiveVdrs->bind("IP", cDBS::bndOut); + selectActiveVdrs->bind("SVDRP", cDBS::bndOut, ", "); + selectActiveVdrs->bind("UUID", cDBS::bndOut, ", "); + selectActiveVdrs->build(" from %s where %s = 'attached' and %s > 0", + vdrDb->TableName(), + vdrDb->getField("STATE")->getDbName(), + vdrDb->getField("SVDRP")->getDbName()); + + status += selectActiveVdrs->prepare(); + + // ---------- + // select ip, name, state, uuid from vdrs + + selectAllVdrs = new cDbStatement(vdrDb); + + selectAllVdrs->build("select "); + selectAllVdrs->bind("IP", cDBS::bndOut); + selectAllVdrs->bind("NAME", cDBS::bndOut, ", "); + selectAllVdrs->bind("STATE", cDBS::bndOut, ", "); + selectAllVdrs->bind("UUID", cDBS::bndOut, ", "); + selectAllVdrs->build(" from %s where svdrp > 0", vdrDb->TableName()); + + status += selectAllVdrs->prepare(); + + // ---------- + // select * from users + + selectAllUser = new cDbStatement(userDb); + + selectAllUser->build("select "); + selectAllUser->bindAllOut(); + selectAllUser->build(" from %s", userDb->TableName()); + + status += selectAllUser->prepare(); + + // ---------- + // select * from searchtimers + // where state != 'D' + + selectSearchTimers = new cDbStatement(searchtimerDb); + + selectSearchTimers->build("select "); + selectSearchTimers->bindAllOut(); + selectSearchTimers->build(" from %s where %s != 'D'", + searchtimerDb->TableName(), + searchtimerDb->getField("STATE")->getDbName()); + + status += selectSearchTimers->prepare(); + + // ---------- + // select * from searchtimers + // where state != 'D' + // and name = ? + + selectSearchTimerByName = new cDbStatement(searchtimerDb); + + selectSearchTimerByName->build("select "); + selectSearchTimerByName->bindAllOut(); + selectSearchTimerByName->build(" from %s where %s != 'D'", + searchtimerDb->TableName(), + searchtimerDb->getField("STATE")->getDbName()); + selectSearchTimerByName->bind("NAME", cDBS::bndIn | cDBS::bndSet, " and "); + + status += selectSearchTimerByName->prepare(); + + // ---------- + // select updsp, id, state, title, shorttext, + // from timersdone where state like ? order by title + + selectDoneTimerByStateTitleOrder = new cDbStatement(timerDoneDb); + + selectDoneTimerByStateTitleOrder->build("select "); + selectDoneTimerByStateTitleOrder->bind("ID", cDBS::bndOut); + selectDoneTimerByStateTitleOrder->bind("STATE", cDBS::bndOut, ", "); + selectDoneTimerByStateTitleOrder->bind("STARTTIME", cDBS::bndOut, ", "); + selectDoneTimerByStateTitleOrder->bind("UPDSP", cDBS::bndOut, ", "); + selectDoneTimerByStateTitleOrder->bind("TITLE", cDBS::bndOut, ", "); + selectDoneTimerByStateTitleOrder->bind("SHORTTEXT", cDBS::bndOut, ", "); + selectDoneTimerByStateTitleOrder->clrBindPrefix(); + selectDoneTimerByStateTitleOrder->build(" from %s where ", timerDoneDb->TableName()); + selectDoneTimerByStateTitleOrder->bindCmp(0, "STATE", 0, "like"); + selectDoneTimerByStateTitleOrder->build(" order by %s", timerDoneDb->getField("TITLE")->getDbName()); + + status += selectDoneTimerByStateTitleOrder->prepare(); + + // same statement with + // 'order by starttimer' + + selectDoneTimerByStateTimeOrder = new cDbStatement(timerDoneDb); + selectDoneTimerByStateTimeOrder->build("select "); + selectDoneTimerByStateTimeOrder->bind("ID", cDBS::bndOut); + selectDoneTimerByStateTimeOrder->bind("STATE", cDBS::bndOut, ", "); + selectDoneTimerByStateTimeOrder->bind("STARTTIME", cDBS::bndOut, ", "); + selectDoneTimerByStateTimeOrder->bind("UPDSP", cDBS::bndOut, ", "); + selectDoneTimerByStateTimeOrder->bind("TITLE", cDBS::bndOut, ", "); + selectDoneTimerByStateTimeOrder->bind("SHORTTEXT", cDBS::bndOut, ", "); + selectDoneTimerByStateTimeOrder->clrBindPrefix(); + selectDoneTimerByStateTimeOrder->build(" from %s where ", timerDoneDb->TableName()); + selectDoneTimerByStateTimeOrder->bindCmp(0, "STATE", 0, "like"); + selectDoneTimerByStateTimeOrder->build(" order by %s", timerDoneDb->getField("STARTTIME")->getDbName()); + + status += selectDoneTimerByStateTimeOrder->prepare(); + + // select * + // from recordinglist where + // (state <> 'D' or state is null) + // and title like ? + // and shorttext like ? + + selectRecordingForEvent = new cDbStatement(recordingListDb); + + selectRecordingForEvent->build("select "); + selectRecordingForEvent->bindAllOut(); + selectRecordingForEvent->build(" from %s where ", recordingListDb->TableName()); + selectRecordingForEvent->build(" (%s <> 'D' or %s is null)", + recordingListDb->getField("STATE")->getDbName(), + recordingListDb->getField("STATE")->getDbName()); + selectRecordingForEvent->bindCmp(0, "TITLE", 0, "like", " and "); + selectRecordingForEvent->bindCmp(0, "SHORTTEXT", 0, "like", " and "); + + status += selectRecordingForEvent->prepare(); + + // select * + // from recordinglist where + // (state <> 'D' or state is null) + // and epglvr(title, ?) < 50 +// // order by lv + + selectRecordingForEventByLv = new cDbStatement(recordingListDb); + + selectRecordingForEventByLv->build("select "); + selectRecordingForEventByLv->bindAllOut(); + selectRecordingForEventByLv->build(" from %s where ", recordingListDb->TableName()); + selectRecordingForEventByLv->build(" (%s <> 'D' or %s is null)", + recordingListDb->getField("STATE")->getDbName(), + recordingListDb->getField("STATE")->getDbName()); + selectRecordingForEventByLv->bindTextFree("and epglvr(title, ?) < 50", recordingListDb->getValue("TITLE"), cDBS::bndIn); + + status += selectRecordingForEventByLv->prepare(); + + // search timer stuff + + if (!status) + { + if ((status = search->initDb()) != success) + return status; + } + + // --------------------------------- + // prepare vdr-list for EditStraItem + + int i = 0; + + vdrDb->countWhere("svdrp > 0", vdrCount); + vdrList = new char*[vdrCount]; + vdrUuidList = new char*[vdrCount];; + + vdrDb->clear(); + + for (int f = selectAllVdrs->find(); f; f = selectAllVdrs->fetch()) + { + asprintf(&vdrList[i], "%s%c", vdrDb->getStrValue("NAME"), vdrDb->hasValue("STATE", "attached") ? '*' : ' '); + vdrUuidList[i] = strdup(vdrDb->getStrValue("UUID")); + i++; + } + + selectAllVdrs->freeResult(); + + // some parameters + + user = "@"; + getParameter("webif", "needLogin", webLoginEnabled); + + if (webLoginEnabled) + user += Epg2VdrConfig.user; + + getParameter(user.c_str(), "startWithSched", startWithSched); + + // prepare User Times (quickTimes) + + initUserTimes(); + + // ------ + + dbInitialized = yes; + + return status; +} + +int cMenuDb::exitDb() +{ + dbInitialized = no; + + search->exitDb(); + + if (connection) + { + cParameters::exitDb(); + + delete timerDb; timerDb = 0; + delete vdrDb; vdrDb = 0; + delete timerDoneDb; timerDoneDb = 0; + delete userDb; userDb = 0; + delete searchtimerDb; searchtimerDb = 0; + delete recordingListDb; recordingListDb = 0; + delete useeventsDb; useeventsDb = 0; + + delete selectTimers; selectTimers = 0; + delete selectMaxUpdSp; selectMaxUpdSp = 0; + delete selectTimerById; selectTimerById = 0; + delete selectActiveVdrs; selectActiveVdrs = 0; + delete selectAllVdrs; selectAllVdrs = 0; + delete selectAllUser; selectAllUser = 0; + delete selectSearchTimers; selectSearchTimers = 0; + delete selectSearchTimerByName; selectSearchTimerByName = 0; + + delete selectDoneTimerByStateTitleOrder; selectDoneTimerByStateTitleOrder = 0; + delete selectDoneTimerByStateTimeOrder; selectDoneTimerByStateTimeOrder = 0; + delete selectRecordingForEvent; selectRecordingForEvent = 0; + delete selectRecordingForEventByLv; selectRecordingForEventByLv = 0; + + delete connection; connection = 0; + + for (int i = 0; i < vdrCount; i++) + { + free(vdrList[i]); + free(vdrUuidList[i]); + } + + delete vdrList; + delete vdrUuidList; + } + + return done; +} + +//*************************************************************************** +// Init Users List +//*************************************************************************** + +int cMenuDb::initUserList(char**& userList, int& count, long int& loginEnabled) +{ + int i = 0; + count = 0; + + if (!dbConnected()) + return fail; + + getParameter("webif", "needLogin", loginEnabled); + + userDb->countWhere("1 = 1", count); + userList = new char*[count]; + memset(userList, 0, count*sizeof(char*)); + + userDb->clear(); + + for (int f = selectAllUser->find(); f; f = selectAllUser->fetch()) + { + if (userDb->getIntValue("ACTIVE") > 0) + asprintf(&userList[i++], "%s", userDb->getStrValue("USER")); + } + + return success; +} + +//*************************************************************************** +// Init Times +//*************************************************************************** + +int cMenuDb::initUserTimes() +{ + char* p; + char times[500+TB] = ""; + + userTimes->clear(); + getParameter(user.c_str(), "quickTimes", times); + + tell(3, "DEBUG: got quickTimes [%s] for user '%s'", times, user.c_str()); + + // parse string like: + // PrimeTime=20:15~EarlyNight=22:20~MidNight=00:00~LateNight=02:00 + + p = strtok(times, "~"); + + while (p) + { + char* time; + + if (time = strchr(p, '=')) + *time++ = 0; + + if (!isEmpty(time)) + userTimes->add(time, p); + else + tell(0, "Error: Ignoring invalid quickTime '%s'", p); + + p = strtok(0, "~"); + } + + return done; +} + +//*************************************************************************** +// Lookup Timer +//*************************************************************************** + +int cMenuDb::lookupTimer(const cEvent* event, int& timerMatch, int& remote, int force) +{ + int maxSp = 0; + + timerMatch = tmNone; + remote = no; + + if (!event) + return 0; + + // on change create lookup cache + + timerDb->clear(); + selectMaxUpdSp->execute(); + maxSp = timerDb->getIntValue("UPDSP"); + selectMaxUpdSp->freeResult(); + + if (maxSp != timersCacheMaxUpdsp) + { + tell(1, "DEBUG: Update timer lookup cache %s", force ? "(forced)": ""); + + timersCacheMaxUpdsp = maxSp; + timers.Clear(); + timerDb->clear(); + timerState.setValue("P,R,u"); + timerAction.setValue("C,M,A,F,a"); + + for (int f = selectTimers->find(); f && dbConnected(); f = selectTimers->fetch()) + { + cTimerInfo* info = new cTimerInfo; + + info->timerid = timerDb->getValue("ID")->getIntValue(); + info->state = timerDb->getValue("STATE")->getCharValue(); + info->starttime = valueStartTime.getIntValue(); + info->eventid = timerDb->getIntValue("EVENTID"); + strcpy(info->channelid, timerDb->getStrValue("CHANNELID")); + strcpy(info->uuid, timerDb->getStrValue("VDRUUID")); + + timers.Add(info); + } + + selectTimers->freeResult(); + } + + // lookup timer in cache + + for (const cTimerInfo* ifo = timers.First(); ifo; ifo = timers.Next(ifo)) + { + if (ifo->eventid == event->EventID()) + { + remote = strcmp(ifo->uuid, Epg2VdrConfig.uuid) != 0; + timerMatch = tmFull; + return ifo->timerid; + } + + else if (strcmp(ifo->channelid, event->ChannelID().ToString()) == 0 + && ifo->starttime == event->StartTime()) // #TODO around + { + remote = strcmp(ifo->uuid, Epg2VdrConfig.uuid) != 0; + timerMatch = tmFull; + return ifo->timerid; + } + } + + return 0; +} + +//*************************************************************************** +// Modify Timer +// +// - timerRow contain the actual vdrUuid +// - for move destUuid is set +//*************************************************************************** + +int cMenuDb::modifyTimer(cDbRow* timerRow, const char* destUuid) +{ + int knownTimer = !timerRow->hasValue("ID", (long)na); + int move = knownTimer && destUuid && !timerRow->hasValue("VDRUUID", destUuid); + int timerid = timerDb->getIntValue("ID"); + + // lookup known (existing) timer + + connection->startTransaction(); + + if (knownTimer) + { + timerDb->clear(); + timerDb->copyValues(timerRow, cDBS::ftPrimary); + + if (!timerDb->find()) + { + connection->commit(); + + tell(0, "Timer (%d) at vdr '%s' not found, aborting modify request!", + timerid, timerDb->getStrValue("VDRUUID")); + + return fail; + } + + // found and all values are loaded! + } + + if (move) + { + // request 'D'elete of 'old' timer + + timerDb->setValue("ACTION", "D"); // = taDelete + timerDb->setValue("SOURCE", Epg2VdrConfig.uuid); + timerDb->update(); + + // create new on other vdr + + timerDb->copyValues(timerRow, cDBS::ftData); // takeover all data (can be modified by user) + timerDb->setValue("ID", 0); // don't care on insert! + timerDb->setValue("VDRUUID", destUuid); + timerDb->setValue("ACTION", "C"); // = taCreate + timerDb->setValue("SOURCE", Epg2VdrConfig.uuid); + timerDb->insert(); + + tell(0, "Created 'move' request for timer (%d) at vdr '%s'", + timerid, timerDb->getStrValue("VDRUUID")); + } + else + { + // create 'C'reate oder 'M'odify request ... + + timerDb->copyValues(timerRow, cDBS::ftData); + + timerDb->setCharValue("ACTION", knownTimer ? taModify : taCreate); + timerDb->getValue("STATE")->setNull(); + timerDb->setValue("SOURCE", Epg2VdrConfig.uuid); + + if (!knownTimer) + timerDb->setValue("NAMINGMODE", tnmAuto); + + if (knownTimer) + timerDb->update(); + else + timerDb->insert(); + + tell(0, "Created '%s' request for timer (%d) at vdr '%s'", + knownTimer ? "modify" : "create", + timerid, timerDb->getStrValue("VDRUUID")); + } + + connection->commit(); + triggerVdrs("TIMERJOB"); // trigger all! + + return success; +} + +//*************************************************************************** +// Create Timer +//*************************************************************************** + +int cMenuDb::createTimer(cDbRow* timerRow, const char* destUuid) +{ + // Timer 'C'reate request ... + + timerDb->clear(); + timerDb->copyValues(timerRow, cDBS::ftData); + + timerDb->setValue("VDRUUID", destUuid); + timerDb->setValue("ACTION", "C"); // taCreate + timerDb->setValue("SOURCE", Epg2VdrConfig.uuid); + timerDb->setValue("NAMINGMODE", tnmAuto); + + timerDb->insert(); + triggerVdrs("TIMERJOB", destUuid); + + tell(0, "Created 'create' request for event '%ld' at vdr '%s'", + timerDb->getIntValue("EVENTID"), timerDb->getStrValue("VDRUUID")); + + return done; +} + +//*************************************************************************** +// Delete Timer +//*************************************************************************** + +int cMenuDb::deleteTimer(long timerid) +{ + timerDb->clear(); + timerDb->setValue("ID", timerid); + + if (!selectTimerById->find()) + { + selectTimerById->freeResult(); + tell(0, "Timer (%ld) not found, maybe deleted from other user, aborting", timerid); + Skins.Message(mtInfo, tr("Timer not found, maybe deleted from other user")); + + return fail; + } + + selectTimerById->freeResult(); + + timerDb->setValue("ACTION", "D"); // = taDelete + timerDb->setValue("SOURCE", Epg2VdrConfig.uuid); + timerDb->update(); + + tell(0, "Created delete request for timer (%ld)", timerid); + + triggerVdrs("TIMERJOB", timerDb->getStrValue("VDRUUID")); + + return success; +} + +//*************************************************************************** +// Trigger VDRs +//*************************************************************************** + +int cMenuDb::triggerVdrs(const char* trg, const char* uuid, const char* options) +{ + int count = 0; + + if (!dbConnected()) + return 0; + + if (!isEmpty(uuid)) + { + if (triggerVdr(uuid, trg, options) == success) + count++; + + return count; + } + + vdrDb->clear(); + + for (int f = selectActiveVdrs->find(); f; f = selectActiveVdrs->fetch()) + { + char* uuid = strdup(vdrDb->getStrValue("UUID")); + tell(1, "Trigger VDR '%s' with '%s'", uuid, trg); + + if (triggerVdr(uuid, trg, options) == success) + count++; + + free(uuid); + } + + selectActiveVdrs->freeResult(); + + return count; +} + +int cMenuDb::triggerVdr(const char* uuid, const char* trg, const char* options) +{ + const char* plgs[] = { "epg2vdr", 0 }; // "scraper2vdr" + + // myself - SVDR to myself will lock vdr!! + + if (strcmp(uuid, Epg2VdrConfig.uuid) == 0) + { + if (strcasecmp(trg, "TIMERJOB") == 0) + { + tell(2, "Trigger myself to update timer-jobs"); + oUpdate->triggerTimerJobs(); + } + + return success; + } + + if (!dbConnected()) + { + tell(0, "Error: Lost database connection, aborting trigger"); + return fail; + } + + vdrDb->clear(); + vdrDb->setValue("UUID", uuid); + + if (!vdrDb->find()) + { + tell(0, "Error: Can't lookup VDR with uuid '%s', skipping trigger", uuid); + return fail; + } + + const char* ip = vdrDb->getStrValue("IP"); + unsigned int port = vdrDb->getIntValue("SVDRP"); + + vdrDb->reset(); + + // svdrp connection + + cSvdrpClient cl(ip, port); + + // open tcp connection + + if (cl.open() == success) + { + for (int i = 0; plgs[i]; i++) + { + char* command = 0; + cList<cLine> result; + + asprintf(&command, "PLUG %s %s %s", plgs[i], trg, !isEmpty(options) ? options : ""); + + tell(0, "Send '%s' to '%s' at '%s:%d'", command, plgs[i], ip, port); + + if (!cl.send(command)) + tell(0, "Error: Send '%s' to '%s' at '%s:%d' failed!", + command, plgs[i], ip, port); + else + cl.receive(&result, 2); + + free(command); + } + + cl.close(no); + } + + return success; +} |