[vdr-plugin-epgsearch] 12/16: New upstream version 2.2.0+git20170817
Tobias Grimm
tiber-guest at moszumanska.debian.org
Wed Dec 27 13:51:28 UTC 2017
This is an automated email from the git hooks/post-receive script.
tiber-guest pushed a commit to branch master
in repository vdr-plugin-epgsearch.
commit d50d69f641ade1ddf2eec23ffaf51c63f80df241
Author: Tobias Grimm <etobi at debian.org>
Date: Fri Aug 18 00:17:46 2017 +0200
New upstream version 2.2.0+git20170817
---
.gitignore | 2 +
Makefile | 2 +-
conflictcheck.c | 168 ++++++++++++++++++++++++++++++++++++++++---
conflictcheck.h | 4 ++
doc-src/de/epgsearch.1.txt | 9 +++
doc-src/en/epgsearch.1.txt | 9 +++
epgsearch.c | 11 +--
epgsearchcfg.c | 1 +
epgsearchcfg.h | 1 +
epgsearchsetup.c | 4 ++
epgsearchsvdrp.c | 4 +-
epgsearchtools.c | 4 +-
epgsearchtools.h | 2 +
menu_conflictcheck.c | 13 +++-
menu_searchresults.c | 11 +--
menu_searchresults.h | 1 +
menu_whatson.c | 24 +++++--
menu_whatson.h | 2 +
po/ca_ES.po | 8 ++-
po/cs_CZ.po | 8 ++-
po/da_DK.po | 8 ++-
po/de_DE.po | 8 ++-
po/el_GR.po | 8 ++-
po/es_ES.po | 8 ++-
po/et_EE.po | 8 ++-
po/fi_FI.po | 8 ++-
po/fr_FR.po | 8 ++-
po/hr_HR.po | 8 ++-
po/hu_HU.po | 8 ++-
po/it_IT.po | 8 ++-
po/lt_LT.po | 8 ++-
po/nl_NL.po | 8 ++-
po/nn_NO.po | 8 ++-
po/pl_PL.po | 8 ++-
po/pt_PT.po | 8 ++-
po/ro_RO.po | 8 ++-
po/ru_RU.po | 8 ++-
po/sk_SK.po | 8 ++-
po/sl_SI.po | 8 ++-
po/sv_SE.po | 8 ++-
po/tr_TR.po | 8 ++-
recdone_thread.c | 174 +++++++++++++++++++++++++++++++++++++++++++++
recdone_thread.h | 40 +++++++++++
recstatus.c | 138 +++--------------------------------
recstatus.h | 14 ++--
searchtimer_thread.c | 8 +--
svdrpclient.h | 4 ++
timer_thread.c | 2 +-
48 files changed, 641 insertions(+), 195 deletions(-)
diff --git a/.gitignore b/.gitignore
index d8fc760..f2c4ff9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,7 @@
/createcats
/.dependencies
+/.dependencies_doc
+/.doc_stmp
/MANUAL
/README.DE
/doc/
diff --git a/Makefile b/Makefile
index 857fbd7..a6837b9 100644
--- a/Makefile
+++ b/Makefile
@@ -132,7 +132,7 @@ ifeq ($(WITHOUT_QUICKSEARCH), 0)
ALL += libvdr-$(PLUGIN4).so
endif
-OBJS = afuzzy.o blacklist.o changrp.o confdloader.o conflictcheck.o conflictcheck_thread.o distance.o $(PLUGIN).o epgsearchcats.o epgsearchcfg.o epgsearchext.o epgsearchsetup.o epgsearchsvdrp.o epgsearchtools.o mail.o md5.o menu_announcelist.o menu_blacklistedit.o menu_blacklists.o menu_commands.o menu_conflictcheck.o menu_deftimercheckmethod.o menu_dirselect.o menu_event.o menu_favorites.o menu_main.o menu_myedittimer.o menu_quicksearch.o menu_recsdone.o menu_search.o menu_searchaction [...]
+OBJS = afuzzy.o blacklist.o changrp.o confdloader.o conflictcheck.o conflictcheck_thread.o distance.o $(PLUGIN).o epgsearchcats.o epgsearchcfg.o epgsearchext.o epgsearchsetup.o epgsearchsvdrp.o epgsearchtools.o mail.o md5.o menu_announcelist.o menu_blacklistedit.o menu_blacklists.o menu_commands.o menu_conflictcheck.o menu_deftimercheckmethod.o menu_dirselect.o menu_event.o menu_favorites.o menu_main.o menu_myedittimer.o menu_quicksearch.o menu_recsdone.o menu_search.o menu_searchaction [...]
ifeq ($(REGEXLIB), pcre)
LIBS += $(shell pcre-config --libs-posix)
diff --git a/conflictcheck.c b/conflictcheck.c
index 7b30ccd..8e6bd53 100644
--- a/conflictcheck.c
+++ b/conflictcheck.c
@@ -30,6 +30,7 @@ The project's page is at http://winni.vdr-developer.org/epgsearch
#include "recstatus.h"
#include "timerstatus.h"
#include "uservars.h"
+#include <vdr/svdrp.h>
#define FULLMATCH 1000
#define EPGLIMITBEFORE (1 * 3600) // Time in seconds before a timer's start time and
@@ -166,6 +167,7 @@ cConflictCheck::cConflictCheck()
relevantConflicts = 0;
numConflicts = 0;
devices = NULL;
+ localConflicts = !(EPGSearchConfig.RemoteConflictCheck && Setup.SVDRPPeering);
InitDevicesInfo();
}
@@ -232,18 +234,23 @@ void cConflictCheck::Check()
if (timerList)
DELETENULL(timerList);
+ LogFile.Log(3, "check only local conflicts = %s",GetLocal()?"yes":"no");
timerList = CreateCurrentTimerList();
if (timerList) evaltimeList = CreateEvaluationTimeList(timerList);
if (evaltimeList) failedList = CreateConflictList(evaltimeList, timerList);
+ if ((!localConflicts) && timerList) CreateRemoteConflictList(timerList,failedList);
if (failedList)
- {
for(cConflictCheckTime* checkTime = failedList->First(); checkTime; checkTime = failedList->Next(checkTime))
{
LogFile.Log(2,"result of conflict check for %s:", DAYDATETIME(checkTime->evaltime));
std::set<cConflictCheckTimerObj*,TimerObjSort>::iterator it;
for (it = checkTime->failedTimers.begin(); it != checkTime->failedTimers.end(); ++it)
- LogFile.Log(2,"timer '%s' (%s, channel %s) failed", (*it)->timer->File(), DAYDATETIME((*it)->timer->StartTime()), CHANNELNAME((*it)->timer->Channel()));
- }
+ {
+ if (!localConflicts)
+ LogFile.Log(2,"timer '%s' (%s, channel %s) %s%s failed", (*it)->timer->File(), DAYDATETIME((*it)->timer->StartTime()), CHANNELNAME((*it)->timer->Channel()), (*it)->timer->Remote()?"@":"",(*it)->timer->Remote()?(*it)->timer->Remote():"");
+ else
+ LogFile.Log(2,"timer '%s' (%s, channel %s) failed", (*it)->timer->File(), DAYDATETIME((*it)->timer->StartTime()), CHANNELNAME((*it)->timer->Channel()));
+ }
}
if (numConflicts > 0 && gl_timerStatusMonitor)
gl_timerStatusMonitor->SetConflictCheckAdvised();
@@ -261,14 +268,16 @@ cList<cConflictCheckTimerObj>* cConflictCheck::CreateCurrentTimerList()
for (ti = Timers->First(); ti; ti = Timers->Next(ti))
{
tMax = std::max(tMax, ti->StartTime());
- if (ti->Remote()) continue; // TO BE DONE: remote service request CC
+ if (localConflicts && ti->Remote()) continue;
if (!ti->IsSingleEvent()) continue;
// already recording?
- int deviceNr = gl_recStatusMonitor->TimerRecDevice(ti)-1;
+ int deviceNr = -1;
+ if (ti->Local()) // we check devices only for local timers
+ deviceNr = gl_recStatusMonitor->TimerRecDevice(ti)-1;
- // create a copy of this timer
- cTimer* clone = new cTimer(*ti);
- clone->SetEvent(ti->Event());
+ // create a copy of this timer
+ cTimer* clone = new cTimer(*ti);
+ clone->SetEvent(ti->Event());
cConflictCheckTimerObj* timerObj = new cConflictCheckTimerObj(clone, ti->StartTime(), ti->StopTime(), deviceNr, ti->Id());
if (deviceNr >= 0)
@@ -290,6 +299,7 @@ cList<cConflictCheckTimerObj>* cConflictCheck::CreateCurrentTimerList()
for (ti = Timers->First(); ti; ti = Timers->Next(ti))
{
if (ti->IsSingleEvent()) continue;
+ if (localConflicts && ti->Remote()) continue; //JF???
time_t day = time(NULL);
while(day < tMax)
{
@@ -300,7 +310,7 @@ cList<cConflictCheckTimerObj>* cConflictCheck::CreateCurrentTimerList()
if (Start < time(NULL))
{
#ifndef DEBUG_CONFL
- if (ti->Recording())
+ if (ti->Local() && ti->Recording())
deviceNr = gl_recStatusMonitor->TimerRecDevice(ti)-1;
#else
if (Start + ti->StopTime() - ti->StartTime() > time(NULL))
@@ -335,7 +345,7 @@ cList<cConflictCheckTimerObj>* cConflictCheck::CreateCurrentTimerList()
}
day += SECSINDAY;
}
- }
+ }
if (CurrentTimerList) CurrentTimerList->Sort();
LogFile.Log(3,"current timer list created");
@@ -351,6 +361,8 @@ cList<cConflictCheckTime>* cConflictCheck::CreateEvaluationTimeList(cList<cConfl
{
if (!TimerObj->timer->HasFlags(tfActive)) continue;
+ if (TimerObj->timer->Remote()) continue; // here we check local timers only
+
if (!EvalTimeList) EvalTimeList = new cList<cConflictCheckTime>;
cConflictCheckTime* checkTime = NULL;
@@ -462,6 +474,140 @@ cList<cConflictCheckTime>* cConflictCheck::CreateConflictList(cList<cConflictChe
return EvalTimeList;
}
+void cConflictCheck::CreateRemoteConflictList(cList<cConflictCheckTimerObj>* TimerList, cList<cConflictCheckTime>* failedList)
+{
+ LogFile.Log(3,"add remote conflicts to list");
+ bool foundRemote = false;
+ cStringList RemoteHosts;
+ // check if we have any Remote timers
+ RemoteHosts.Clear();
+ for(cConflictCheckTimerObj* TimerObj= TimerList->First(); TimerObj; TimerObj = TimerList->Next(TimerObj))
+ {
+ if (!TimerObj->timer->HasFlags(tfActive)) continue;
+
+ if (TimerObj->timer->Remote())
+ {
+ if (RemoteHosts.Find(TimerObj->timer->Remote()) < 0)
+ {
+ foundRemote = true;
+ RemoteHosts.Append(strdup(TimerObj->timer->Remote()));
+ }
+ }
+ }
+
+ if (!foundRemote)
+ {
+ LogFile.Log(3,"no remote timers to add");
+ return;
+ }
+
+ RemoteHosts.Sort();
+
+ cStringList Response;
+ // for all RemoteHosts
+ for (int i=0; i< RemoteHosts.Size(); i++)
+ {
+ Response.Clear();
+ if (ExecSVDRPCommand(RemoteHosts[i], "PLUG epgsearch LSCC REL", &Response))
+ {
+ for (int j = 0; j < Response.Size(); j++)
+ {
+ const char *s = Response[j];
+ int Code = SVDRPCode(s);
+ if (Code == 901)
+ {
+ LogFile.Log(3,"conflictcheck %s no remote conflicts found",RemoteHosts[i]);
+ continue;
+ } else if (Code != 900)
+ {
+ LogFile.Log(2,"Invalid remote response %d %s", Code,
+ SVDRPValue(s));
+ break;
+ } else if (const char* line = SVDRPValue(s))
+ {
+ LogFile.Log(2,"remote conflictcheck line %s",line);
+ int Id,recPart;
+ char rest[256];
+ time_t evaltime;
+ sscanf(line,"%ld:%d|%s",&evaltime,&Id,rest);
+ cConflictCheckTime* checkTime = new cConflictCheckTime(evaltime);
+ if (!failedList)
+ failedList = new cList<cConflictCheckTime>;
+ LogFile.Log(2,"added remote checkTime %s to failedList",DAYDATETIME(evaltime));
+ failedList->Add(checkTime);
+ numConflicts++;
+ // find TimerObj with id Id in timerList
+ cConflictCheckTimerObj* failedTimer = NULL;
+ bool foundfT = false;
+ for(failedTimer = TimerList->First(); failedTimer; failedTimer = TimerList->Next(failedTimer))
+ {
+ if (failedTimer->timer->Id() == Id)
+ {
+ foundfT = true;
+ break;
+ }
+ }
+ if (!foundfT)
+ {
+ LogFile.Log(2,"remote failed Timer disappeared");
+ continue;
+ }
+ LogFile.Log(2,"create remote failedTimer with Id %d",Id);
+ failedTimer->conflCheckTime = checkTime;
+ failedTimer->origIndex = Id;
+ sscanf(rest,"%d|%s",&recPart,rest);
+ failedTimer->recDuration=((failedTimer->stop-failedTimer->start)* recPart / 100);
+ cConflictCheckTimerObj* concurrentTimer = NULL;
+ while (strlen(rest) > 0)
+ {
+ int n = sscanf(rest,"%d#%s",&Id,rest);
+ if (n < 2)
+ {
+ if (sscanf(rest,"%d",&Id) <= 0)
+ {
+ LogFile.Log(2,"error scanning rest of line %s",rest);
+ break;
+ }
+ *rest = 0; // TODO :<more timers> possible ??
+ }
+ // find TimerObj itcc for with Id in timerList
+ bool foundcT = false;
+ for(concurrentTimer = TimerList->First(); concurrentTimer; concurrentTimer = TimerList->Next(concurrentTimer))
+ {
+ if (concurrentTimer->timer->Id() == Id)
+ {
+ foundcT = true;
+ break;
+ }
+ }
+ if (!foundcT)
+ {
+ LogFile.Log(2,"remote concurrent Timer disappeared");
+ continue;
+ }
+ if (!failedTimer->concurrentTimers)
+ failedTimer->concurrentTimers = new std::set<cConflictCheckTimerObj*,TimerObjSort>;
+ LogFile.Log(2,"insert remote Id %d into concurrentTimers",concurrentTimer->timer->Id());
+ failedTimer->concurrentTimers->insert(concurrentTimer);
+ } // while concurrent Timers
+ LogFile.Log(2,"insert Id %d into checkTime->failedTimers",failedTimer->timer->Id());
+ checkTime->failedTimers.insert(failedTimer);
+ relevantConflicts++;
+ }
+ else
+ LogFile.Log(2,"got Code %d, but no Value from %s",Code,RemoteHosts[i]);
+ } // received response
+ }
+ else
+ {
+ LogFile.Log(2,"ExecSVDRPCommand failed for %s",RemoteHosts[i]);
+ }
+ } // for all RemoteHosts
+ cConflictCheckThread::m_cacheTotalConflicts = numConflicts;
+ cConflictCheckThread::m_cacheRelevantConflicts = relevantConflicts;
+ LogFile.Log(3,"add remote conflicts done");
+}
+
// checks for conflicts at one special time
int cConflictCheck::ProcessCheckTime(cConflictCheckTime* checkTime)
{
@@ -667,6 +813,8 @@ void cConflictCheck::AddConflict(cConflictCheckTimerObj* TimerObj, cConflictChec
bool cConflictCheck::TimerInConflict(const cTimer* timer)
{
+ if (!failedList)
+ return false;
for(cConflictCheckTime* checkTime = failedList->First(); checkTime; checkTime = failedList->Next(checkTime))
{
std::set<cConflictCheckTimerObj*,TimerObjSort>::iterator it;
diff --git a/conflictcheck.h b/conflictcheck.h
index 049243c..44a08d1 100644
--- a/conflictcheck.h
+++ b/conflictcheck.h
@@ -262,6 +262,7 @@ class cConflictCheck
public:
int relevantConflicts;
int numConflicts;
+ bool localConflicts;
time_t nextRelevantConflictDate;
cConflictCheck();
@@ -269,9 +270,12 @@ class cConflictCheck
void InitDevicesInfo();
void Check();
void BondDevices(const char* bondings);
+ void SetLocal() { localConflicts = true; }
+ bool GetLocal() { return localConflicts; }
cList<cConflictCheckTimerObj>* CreateCurrentTimerList();
cList<cConflictCheckTime>* CreateEvaluationTimeList(cList<cConflictCheckTimerObj>*);
cList<cConflictCheckTime>* CreateConflictList(cList<cConflictCheckTime>*, cList<cConflictCheckTimerObj>* timerList);
+ void CreateRemoteConflictList(cList<cConflictCheckTimerObj>* timerList, cList<cConflictCheckTime>* failedList);
int GetDevice(cConflictCheckTimerObj* TimerObj, bool *NeedsDetachReceivers);
cList<cConflictCheckTime>* GetFailed() { return failedList; }
cList<cConflictCheckTimerObj>* GetTimers() { return timerList; }
diff --git a/doc-src/de/epgsearch.1.txt b/doc-src/de/epgsearch.1.txt
index 57e2301..e6cce39 100644
--- a/doc-src/de/epgsearch.1.txt
+++ b/doc-src/de/epgsearch.1.txt
@@ -626,6 +626,9 @@ erzeugt Timer, falls passende Eintr
betrifft nur Sucheintr�ge, die mit 'Als Suchtimer verwenden'
markiert sind.
+Suchtimer werden immer lokal erzeugt, auch wenn ein anderer Defaulthost
+f�r Aufnahmen definiert ist.
+
=item - B<Aktualisierungsintervall:>
Das Intervall in Minuten, in dem die Hintergrundsuche vorgenommen
@@ -735,6 +738,12 @@ wird darauf nicht per OSD-Nachricht hingewiesen und der Konflikt wird als
Hier kann der Zeitraum der Pr�fung angegeben werden.
+=item - B<Konflikte auch f�r Remote-Timer pr�fen:>
+
+Falls SVDRPPeering aktiv ist, werden auch Konflikte bei entfernten Timern
+�berp�ft. Dazu muss am entsprechenden Remote-Rechner das epgsearch-Plugin
+ebenfalls aktiviert sein. Default ist nein.
+
=item - B<Nach jeder Timer-Programmierung:>
Das bewirkt eine Konfliktpr�fung nach jeder manuellen Timer-Programmierung
diff --git a/doc-src/en/epgsearch.1.txt b/doc-src/en/epgsearch.1.txt
index 659f4b9..e44f0e4 100644
--- a/doc-src/en/epgsearch.1.txt
+++ b/doc-src/en/epgsearch.1.txt
@@ -603,6 +603,9 @@ If yes, the plugin makes a background scan of the EPG and adds timers
if it finds matching entries. This applies only to searches that are
marked with 'use as search timer'.
+Search timers will always be created local, even if SVDRPDefaulthost
+is set to a different host.
+
=item - B<Update interval:>
The update interval of the background scan for search timers in minutes.
@@ -714,6 +717,12 @@ in the conflicts overview.
Here you can specify the day range that should be used for the conflict
check.
+=item - B<Check also remote conflicts:>
+
+If SVDRPPeering is active, conflicts for remote timers will be checked, if
+set to "yes". For this to work epgseach-plugin has to be active on the
+remote host too. Default is "no".
+
=item - B<After each timer programming:>
This performs a conflict check after each manual timer programming and - if
diff --git a/epgsearch.c b/epgsearch.c
index 7f368c3..2e01d0e 100644
--- a/epgsearch.c
+++ b/epgsearch.c
@@ -89,7 +89,7 @@ int cLogFile::loglevellimit = 0;
bool cPluginEpgsearch::VDR_readyafterStartup = false;
// external SVDRPCommand
-const char *cSVDRPClient::SVDRPSendCmd = "svdrpsend";
+const char *epgsSVDRP::cSVDRPClient::SVDRPSendCmd = "svdrpsend";
cPluginEpgsearch::cPluginEpgsearch(void)
{
@@ -189,7 +189,7 @@ bool cPluginEpgsearch::ProcessArgs(int argc, char *argv[])
switch (c) {
case 'f':
- cSVDRPClient::SVDRPSendCmd = optarg;
+ epgsSVDRP::cSVDRPClient::SVDRPSendCmd = optarg;
EPGSearchConfig.useExternalSVDRP = 1;
break;
case 'c':
@@ -211,10 +211,10 @@ bool cPluginEpgsearch::ProcessArgs(int argc, char *argv[])
}
}
- if (EPGSearchConfig.useExternalSVDRP && access(cSVDRPClient::SVDRPSendCmd, F_OK) != 0)
+ if (EPGSearchConfig.useExternalSVDRP && access(epgsSVDRP::cSVDRPClient::SVDRPSendCmd, F_OK) != 0)
{
- LogFile.eSysLog("ERROR - can't find svdrpsend script: '%s'", cSVDRPClient::SVDRPSendCmd);
- cSVDRPClient::SVDRPSendCmd = NULL;
+ LogFile.eSysLog("ERROR - can't find svdrpsend script: '%s'", epgsSVDRP::cSVDRPClient::SVDRPSendCmd);
+ epgsSVDRP::cSVDRPClient::SVDRPSendCmd = NULL;
}
return true;
@@ -652,6 +652,7 @@ bool cPluginEpgsearch::SetupParse(const char *Name, const char *Value)
if (!strcasecmp(Name, "CheckTimerConflicts")) EPGSearchConfig.checkTimerConflictsAfterUpdate = atoi(Value);
if (!strcasecmp(Name, "CheckTimerConflictsPriority")) EPGSearchConfig.checkMinPriority = atoi(Value);
if (!strcasecmp(Name, "CheckTimerConflictsDays")) EPGSearchConfig.checkMaxDays = atoi(Value);
+ if (!strcasecmp(Name, "RemoteConflictCheck")) EPGSearchConfig.RemoteConflictCheck = atoi(Value);
if (!strcasecmp(Name, "CheckConflictsIntervall")) EPGSearchConfig.conflictCheckIntervall = atoi(Value);
if (!strcasecmp(Name, "CheckConflictsWithinLimit")) EPGSearchConfig.conflictCheckWithinLimit = atoi(Value);
if (!strcasecmp(Name, "CheckConflictsIntervall2")) EPGSearchConfig.conflictCheckIntervall2 = atoi(Value);
diff --git a/epgsearchcfg.c b/epgsearchcfg.c
index 7124271..c48889e 100644
--- a/epgsearchcfg.c
+++ b/epgsearchcfg.c
@@ -92,6 +92,7 @@ cEPGSearchConfig::cEPGSearchConfig(void)
ReplaceOrgSchedule = 0;
sendMailOnSearchtimers = 0;
sendMailOnConflicts = 0;
+ RemoteConflictCheck = 0;
}
cShowMode& cShowMode::operator= (const cShowMode &ShowMode)
diff --git a/epgsearchcfg.h b/epgsearchcfg.h
index e51dee8..d8da05b 100644
--- a/epgsearchcfg.h
+++ b/epgsearchcfg.h
@@ -129,6 +129,7 @@ cEPGSearchConfig(void);
int useOkForSwitch;
int sendMailOnSearchtimers;
int sendMailOnConflicts;
+ int RemoteConflictCheck;
char MailAddressTo[MaxFileName];
char MailAddress[MaxFileName];
char MailServer[MaxFileName];
diff --git a/epgsearchsetup.c b/epgsearchsetup.c
index 851c115..642d011 100644
--- a/epgsearchsetup.c
+++ b/epgsearchsetup.c
@@ -223,6 +223,7 @@ void cMenuEPGSearchSetup::Store(void)
SetupStore("CheckConflictsAfterTimerProg", EPGSearchConfig.checkTimerConflAfterTimerProg);
SetupStore("CheckConflictsOnRecording", EPGSearchConfig.checkTimerConflOnRecording);
SetupStore("NoConflMsgWhileReplay", EPGSearchConfig.noConflMsgWhileReplay);
+ SetupStore("RemoteConflictCheck", EPGSearchConfig.RemoteConflictCheck);
SetupStore("CheckEPGHours", EPGSearchConfig.checkEPGHours);
SetupStore("CheckEPGWarnByOSD", EPGSearchConfig.checkEPGWarnByOSD);
SetupStore("CheckEPGWarnByMail", EPGSearchConfig.checkEPGWarnByMail);
@@ -790,6 +791,9 @@ void cMenuSetupTimerConflicts::Set()
Add(new cMenuEditIntItem(tr("Only check within next ... days"), &data->checkMaxDays, 1, 14));
AddHelp(tr("Help$This value reduces the conflict check to the given range of days. All other conflicts are classified as 'not yet important'."));
+ Add(new cMenuEditBoolItem(tr("Check also remote conflicts"), &data->RemoteConflictCheck, trVDR("no"), trVDR("yes")));
+ AddHelp(tr("Help$Set this to 'yes' if the conflict check should be done for timers set on remote hosts. This needs SVDRPPeering to be set in vdr and Plugin epgsearch running on the remote host."));
+
cOsdItem* sep = new cOsdItem(tr("--- Automatic checking ---"));
sep->SetSelectable(false);
Add(sep);
diff --git a/epgsearchsvdrp.c b/epgsearchsvdrp.c
index 591201c..beeeaa5 100644
--- a/epgsearchsvdrp.c
+++ b/epgsearchsvdrp.c
@@ -128,7 +128,7 @@ const char **cPluginEpgsearch::SVDRPHelpPages(void)
" Returns the ID of the default search template\n"
" or activates a search template with ID as default",
"LSCC [ REL ]\n"
- " Returns the current timer conflicts. With the option\n"
+ " Returns the current (local) timer conflicts. With the option\n"
" 'REL' only relevant conflicts are listed",
"MENU [ NOW|PRG|SUM ]\n"
" Calls one of the main menus of epgsearch or the summary\n"
@@ -1255,7 +1255,9 @@ cString cPluginEpgsearch::SVDRPCommand(const char *Command, const char *Option,
if (*Option && strcasecmp(Option, "REL") == 0)
relOnly = true;
+ LogFile.Log(3,"svdrp LSCC");
cConflictCheck conflictCheck;
+ conflictCheck.SetLocal(); // including remote timers results in an infinite loop
conflictCheck.Check();
if ((relOnly && conflictCheck.numConflicts > 0) ||
diff --git a/epgsearchtools.c b/epgsearchtools.c
index b8a8c6c..76b1b9a 100644
--- a/epgsearchtools.c
+++ b/epgsearchtools.c
@@ -409,7 +409,7 @@ bool SendViaSVDRP(cString SVDRPcmd)
if (EPGSearchConfig.useExternalSVDRP)
{
cmdbuf = cString::sprintf("%s -p %d \"%s\"",
- cSVDRPClient::SVDRPSendCmd,
+ epgsSVDRP::cSVDRPClient::SVDRPSendCmd,
EPGSearchConfig.SVDRPPort,
*SVDRPcmd);
@@ -425,7 +425,7 @@ bool SendViaSVDRP(cString SVDRPcmd)
else
{
cmdbuf = SVDRPcmd;
- cSVDRPClient client;
+ epgsSVDRP::cSVDRPClient client;
if (!client.SendCmd(*cmdbuf))
{
LogFile.eSysLog("command '%s' failed", *cmdbuf);
diff --git a/epgsearchtools.h b/epgsearchtools.h
index 9b80473..7ad67f7 100644
--- a/epgsearchtools.h
+++ b/epgsearchtools.h
@@ -91,6 +91,7 @@ using std::string;
#define ICON_BAR_EMPTY 0x89
#define ICON_BAR_CLOSE 0x8A
#define ICON_VPS 0x93
+#define ICON_TIMER_INACT 0x95
// UTF-8 Icons
#define ICON_BAR_OPEN_UTF8 "\uE007"
@@ -102,6 +103,7 @@ using std::string;
#define ICON_CLOCK_HALF_UTF8 "\uE014"
#define ICON_RUNNING_UTF8 "\uE012"
#define ICON_VPS_UTF8 "\uE013"
+#define ICON_TIMER_INACT_UTF8 "\uE015"
#define CONTENT_DESCRIPTOR_MAX 255
diff --git a/menu_conflictcheck.c b/menu_conflictcheck.c
index 4450f25..88d1a0e 100644
--- a/menu_conflictcheck.c
+++ b/menu_conflictcheck.c
@@ -182,9 +182,15 @@ bool cMenuConflictCheckDetailsItem::Update(bool Force)
if (!timerObj->conflCheckTime && timerObj->device > -1)
sprintf(device, "%d", timerObj->device+1);
else
- strcpy(device, tr("C"));
+ {
+ if (timer->Local())
+ strcpy(device, tr("C"));
+ else
+ strcpy(device, "R"); //Remote Timer
+ }
}
+// cString buffer = cString::sprintf("%s\t%s\t%d\t%s - %s\t%d\t%s\t%s", hasTimer?">":"", timer->Remote()?timer->Remote():"", timer->Channel()->Number(), TIMESTRING(timerObj->start), TIMESTRING(timerObj->stop), timer->Priority(), device, timer->File());
cString buffer = cString::sprintf("%s\t%d\t%s - %s\t%d\t%s\t%s", hasTimer?">":"", timer->Channel()->Number(), TIMESTRING(timerObj->start), TIMESTRING(timerObj->stop), timer->Priority(), device, timer->File());
SetText(buffer);
@@ -300,6 +306,11 @@ eOSState cMenuConflictCheckDetails::DeleteTimer(cConflictCheckTimerObj* TimerObj
else
return osContinue;
}
+ if (!HandleRemoteTimerModifications(NULL,timer))
+ {
+ LogFile.Log(2,"HandleRemoteTimerModifications failed");
+ return osContinue;
+ }
LogFile.iSysLog("deleting timer %s", *timer->ToDescr());
Timers->Del(timer);
cOsdMenu::Del(Current());
diff --git a/menu_searchresults.c b/menu_searchresults.c
index 99c11bf..023cf8d 100644
--- a/menu_searchresults.c
+++ b/menu_searchresults.c
@@ -63,6 +63,7 @@ cMenuSearchResultsItem::cMenuSearchResultsItem(const cEvent *EventInfo, bool Epi
menuTemplate = MenuTemplate?MenuTemplate:cTemplFile::GetTemplateByName("MenuSearchResults");
search = Search;
inSwitchList = false;
+ timerActive = false;
Update(true);
}
@@ -75,14 +76,16 @@ bool cMenuSearchResultsItem::Update(bool Force)
eTimerMatch OldTimerMatch = timerMatch;
bool OldInSwitchList = inSwitchList;
+ bool OldtimerActive = timerActive;
bool hasMatch = false;
const cTimer* timer = NULL;
LOCK_TIMERS_READ;
if (event) timer = Timers->GetMatch(event, &timerMatch);
if (event) inSwitchList = (SwitchTimers.InSwitchList(event)!=NULL);
if (timer) hasMatch = true;
+ if (timer) timerActive = timer->HasFlags(tfActive);
- if (Force || timerMatch != OldTimerMatch || inSwitchList != OldInSwitchList)
+ if (Force || timerMatch != OldTimerMatch || inSwitchList != OldInSwitchList || timerActive != OldtimerActive)
{
char t[Utf8BufSize(2)]="",v[Utf8BufSize(2)]="",r[Utf8BufSize(2)]="";
char szStatus[Utf8BufSize(4)] = "";
@@ -90,7 +93,7 @@ bool cMenuSearchResultsItem::Update(bool Force)
{
if (!isUTF8)
{
- t[0] = event && hasMatch ? (timerMatch == tmFull) ? ((timer && timer->Recording())?ICON_REC:ICON_CLOCK) : ICON_CLOCK_HALF : ' ';
+ t[0] = event && hasMatch ? (timerMatch == tmFull) ? ((timer && timer->Recording()) ? ICON_REC : (timerActive ? ICON_CLOCK : ICON_TIMER_INACT)) : (timerActive ? ICON_CLOCK_HALF : ' ') : ' ';
t[1] = '\0';
v[0] = event && event->Vps() && (event->Vps() - event->StartTime()) ? ICON_VPS : ' ';
v[1] = '\0';
@@ -102,7 +105,7 @@ bool cMenuSearchResultsItem::Update(bool Force)
{
#if defined(__GNUC__) && __GNUC__ < 3 && __GNUC_MINOR__ < 96
#else
- sprintf(t, "%s", (event && hasMatch ? (timerMatch == tmFull) ? ((timer && timer->Recording())?ICON_REC_UTF8:ICON_CLOCK_UTF8) : ICON_CLOCK_HALF_UTF8 : " "));
+ sprintf(t, "%s", (event && hasMatch ? (timerMatch == tmFull) ? ((timer && timer->Recording()) ? ICON_REC_UTF8 : (timerActive ? ICON_CLOCK_UTF8 : ICON_TIMER_INACT_UTF8)) : (timerActive ? ICON_CLOCK_HALF_UTF8: " ") : " "));
sprintf(v, "%s", event && event->Vps() && (event->Vps() - event->StartTime()) ? ICON_VPS_UTF8 : " ");
sprintf(r, "%s", (event && event->IsRunning() ? ICON_RUNNING_UTF8 : " "));
#endif
@@ -110,7 +113,7 @@ bool cMenuSearchResultsItem::Update(bool Force)
}
else
{
- t[0] = event && hasMatch ? (timerMatch == tmFull) ? ((timer && timer->Recording())?'R':'T') : 't' : ' ';
+ t[0] = event && hasMatch ? (timerMatch == tmFull) ? ((timer && timer->Recording()) ? 'R' : (timerActive ? 'T' : 'i')) : (timerActive ? 't' :' ') : ' ';
t[1] = '\0';
v[0] = event && event->Vps() && (event->Vps() - event->StartTime()) ? 'V' : ' ';
v[1] = '\0';
diff --git a/menu_searchresults.h b/menu_searchresults.h
index 36b8665..6bb7f62 100644
--- a/menu_searchresults.h
+++ b/menu_searchresults.h
@@ -52,6 +52,7 @@ class cMenuSearchResultsItem : public cOsdItem {
public:
eTimerMatch timerMatch;
bool inSwitchList;
+ bool timerActive;
const cEvent *event;
const cSearchExt* search;
const char *FileName(void) { return fileName; }
diff --git a/menu_whatson.c b/menu_whatson.c
index e84bb95..7f7dab3 100644
--- a/menu_whatson.c
+++ b/menu_whatson.c
@@ -61,7 +61,9 @@ cMenuMyScheduleItem::cMenuMyScheduleItem(const cTimers *Timers, const cEvent *Ev
channel = Channel;
mode = Mode;
timerMatch = tmNone;
+ isRemote = false;
inSwitchList = false;
+ timerActive = false;
menuTemplate = MenuTemplate;
Update(Timers, true);
}
@@ -78,14 +80,19 @@ bool cMenuMyScheduleItem::Update(const cTimers* Timers, bool Force)
bool result = false;
eTimerMatch OldTimerMatch = timerMatch;
+ bool OldIsRemote = isRemote;
bool OldInSwitchList = inSwitchList;
+ bool OldtimerActive = timerActive;
bool hasMatch = false;
const cTimer* timer = NULL;
if (event) timer = Timers->GetMatch(event, &timerMatch);
if (event) inSwitchList = (SwitchTimers.InSwitchList(event)!=NULL);
if (timer) hasMatch = true;
+ if (timer) timerActive = timer->HasFlags(tfActive);
+ if (timer) isRemote = timer->Remote();
- if (Force || timerMatch != OldTimerMatch || inSwitchList != OldInSwitchList)
+ if (Force || timerMatch != OldTimerMatch || inSwitchList != OldInSwitchList
+ || isRemote != OldIsRemote || timerActive != OldtimerActive)
{
char szProgressPart[Utf8BufSize(12)] = "";
char szProgressPartT2S[12] = "";
@@ -155,7 +162,7 @@ bool cMenuMyScheduleItem::Update(const cTimers* Timers, bool Force)
{
if (!isUTF8)
{
- t[0] = event && hasMatch ? (timerMatch == tmFull) ? ((timer && timer->Recording())?ICON_REC:ICON_CLOCK) : ICON_CLOCK_HALF : ' ';
+ t[0] = event && hasMatch ? (timerMatch == tmFull) ? ((timer && timer->Recording()) ? ICON_REC : (timerActive ? ICON_CLOCK : ICON_TIMER_INACT)) : (timerActive ? ICON_CLOCK_HALF : ' ' ): ' ';
v[0] = event && event->Vps() && (event->Vps() - event->StartTime()) ? ICON_VPS : ' ';
r[0] = event && event->IsRunning() ? ICON_RUNNING : ' ';
}
@@ -163,7 +170,7 @@ bool cMenuMyScheduleItem::Update(const cTimers* Timers, bool Force)
{
#if defined(__GNUC__) && __GNUC__ < 3 && __GNUC_MINOR__ < 96
#else
- sprintf(t, "%s", (event && hasMatch ? (timerMatch == tmFull) ? ((timer && timer->Recording())?ICON_REC_UTF8:ICON_CLOCK_UTF8) : ICON_CLOCK_HALF_UTF8 : " "));
+ sprintf(t, "%s", (event && hasMatch ? (timerMatch == tmFull) ? ((timer && timer->Recording()) ? ICON_REC_UTF8 : (timerActive ? ICON_CLOCK_UTF8 : ICON_TIMER_INACT_UTF8)) : (timerActive ? ICON_CLOCK_HALF_UTF8 : " ") : " "));
sprintf(v, "%s", event && event->Vps() && (event->Vps() - event->StartTime()) ? ICON_VPS_UTF8 : " ");
sprintf(r, "%s", (event && event->IsRunning() ? ICON_RUNNING_UTF8 : " "));
#endif
@@ -171,7 +178,7 @@ bool cMenuMyScheduleItem::Update(const cTimers* Timers, bool Force)
}
else
{
- t[0] = event && hasMatch ? (timerMatch == tmFull) ? ((timer && timer->Recording())?'R':'T') : 't' : ' ';
+ t[0] = event && hasMatch ? (timerMatch == tmFull) ? ((timer && timer->Recording()) ? 'R' : (timerActive ? 'T' : 'i')) : (timerActive ? 't' : ' ') : ' ';
v[0] = event && event->Vps() && (event->Vps() - event->StartTime()) ? 'V' : ' ';
r[0] = event && event->IsRunning() ? '*' : ' ';
}
@@ -235,7 +242,7 @@ bool cMenuMyScheduleItem::Update(const cTimers* Timers, bool Force)
SetText(buffer, false);
- if (gl_InfoConflict == 0 && EPGSearchConfig.checkTimerConflAfterTimerProg && !Force && timer && timerMatch && timerMatch != OldTimerMatch && !(timer->Remote()))
+ if (gl_InfoConflict == 0 && EPGSearchConfig.checkTimerConflAfterTimerProg && !Force && timer && ((timerMatch && timerMatch != OldTimerMatch) || (isRemote != OldIsRemote)))
{
cConflictCheck C;
C.Check();
@@ -752,8 +759,11 @@ eOSState cMenuWhatsOnSearch::ShowSummary()
const cEvent *ei = ((cMenuMyScheduleItem *)Get(Current()))->event;
if (ei)
{
- LOCK_CHANNELS_READ;
- const cChannel *channel = Channels->GetByChannelID(ei->ChannelID(), true, true);
+ const cChannel *channel;
+ {
+ LOCK_CHANNELS_READ;
+ channel = Channels->GetByChannelID(ei->ChannelID(), true, true);
+ }
if (channel)
return AddSubMenu(new cMenuEventSearch(ei, eventObjects, SurfModeChannel));
}
diff --git a/menu_whatson.h b/menu_whatson.h
index 65a2b73..803b4bb 100644
--- a/menu_whatson.h
+++ b/menu_whatson.h
@@ -36,7 +36,9 @@ public:
const cChannel *channel;
showMode mode;
eTimerMatch timerMatch;
+ bool isRemote;
bool inSwitchList;
+ bool timerActive;
cMenuTemplate* menuTemplate;
cMenuMyScheduleItem(const cTimers *Timers, const cEvent *Event, const cChannel *Channel = NULL, showMode ShowMode = showNow, cMenuTemplate* menuTemplate = NULL);
diff --git a/po/ca_ES.po b/po/ca_ES.po
index 3aef54b..30005c6 100644
--- a/po/ca_ES.po
+++ b/po/ca_ES.po
@@ -9,7 +9,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.5.7\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2017-05-12 12:04+0200\n"
+"POT-Creation-Date: 2017-06-15 11:15+0200\n"
"PO-Revision-Date: 2007-08-14 20:21+0200\n"
"Last-Translator: Jordi Vilà <jvila at tinet.org>\n"
"Language-Team: Catalan <vdr at linuxtv.org>\n"
@@ -434,6 +434,12 @@ msgstr ""
msgid "Help$This value reduces the conflict check to the given range of days. All other conflicts are classified as 'not yet important'."
msgstr ""
+msgid "Check also remote conflicts"
+msgstr ""
+
+msgid "Help$Set this to 'yes' if the conflict check should be done for timers set on remote hosts. This needs SVDRPPeering to be set in vdr and Plugin epgsearch running on the remote host."
+msgstr ""
+
msgid "--- Automatic checking ---"
msgstr ""
diff --git a/po/cs_CZ.po b/po/cs_CZ.po
index 242884e..8289bc7 100644
--- a/po/cs_CZ.po
+++ b/po/cs_CZ.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.7.21\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2017-05-12 12:04+0200\n"
+"POT-Creation-Date: 2017-06-15 11:15+0200\n"
"PO-Revision-Date: 2011-10-31 20:21+0200\n"
"Last-Translator: Radek Stastny <dedkus at gmail.com>\n"
"Language-Team: Czech <vdr at linuxtv.org>\n"
@@ -431,6 +431,12 @@ msgstr "Kontrolovat pouze během dalších . dní"
msgid "Help$This value reduces the conflict check to the given range of days. All other conflicts are classified as 'not yet important'."
msgstr ""
+msgid "Check also remote conflicts"
+msgstr ""
+
+msgid "Help$Set this to 'yes' if the conflict check should be done for timers set on remote hosts. This needs SVDRPPeering to be set in vdr and Plugin epgsearch running on the remote host."
+msgstr ""
+
msgid "--- Automatic checking ---"
msgstr "--- Automatická kontrola ---"
diff --git a/po/da_DK.po b/po/da_DK.po
index f2237ae..e84abd5 100644
--- a/po/da_DK.po
+++ b/po/da_DK.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.5.7\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2017-05-12 12:04+0200\n"
+"POT-Creation-Date: 2017-06-15 11:15+0200\n"
"PO-Revision-Date: 2007-08-14 20:21+0200\n"
"Last-Translator: Mogens Elneff <mogens at elneff.dk>\n"
"Language-Team: Danish <vdr at linuxtv.org>\n"
@@ -432,6 +432,12 @@ msgstr ""
msgid "Help$This value reduces the conflict check to the given range of days. All other conflicts are classified as 'not yet important'."
msgstr ""
+msgid "Check also remote conflicts"
+msgstr ""
+
+msgid "Help$Set this to 'yes' if the conflict check should be done for timers set on remote hosts. This needs SVDRPPeering to be set in vdr and Plugin epgsearch running on the remote host."
+msgstr ""
+
msgid "--- Automatic checking ---"
msgstr ""
diff --git a/po/de_DE.po b/po/de_DE.po
index 703f665..79f795c 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: <see README>\n"
-"POT-Creation-Date: 2017-05-12 12:04+0200\n"
+"POT-Creation-Date: 2017-06-15 11:33+0200\n"
"PO-Revision-Date: 2007-08-14 20:21+0200\n"
"Last-Translator: Klaus Schmidinger <kls at cadsoft.de>\n"
"Language-Team: German <vdr at linuxtv.org>\n"
@@ -461,6 +461,12 @@ msgstr "Prüfe nur die nächsten ... Tage"
msgid "Help$This value reduces the conflict check to the given range of days. All other conflicts are classified as 'not yet important'."
msgstr "Mit diesem Wert kann der Zeitbereich der Konfliktprüfung eingestellt werden. Alle Konflikte ausserhalb des Bereichs werden als 'noch nicht wichtig' eingestuft."
+msgid "Check also remote conflicts"
+msgstr "Konflikte auch für Remote-Timer prüfen"
+
+msgid "Help$Set this to 'yes' if the conflict check should be done for timers set on remote hosts. This needs SVDRPPeering to be set in vdr and Plugin epgsearch running on the remote host."
+msgstr "Mit 'ja' wird der Konfliktcheck auf für Timer auf entfernten Rechnern gemacht. Dazu muss SVDRPPeering gesetzt sein und das Plugin epgsearch am entfernten Rechner laufen"
+
msgid "--- Automatic checking ---"
msgstr "--- Automatische Prüfung ---"
diff --git a/po/el_GR.po b/po/el_GR.po
index 2befab5..3c9ccf8 100644
--- a/po/el_GR.po
+++ b/po/el_GR.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.5.7\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2017-05-12 12:04+0200\n"
+"POT-Creation-Date: 2017-06-15 11:15+0200\n"
"PO-Revision-Date: 2007-08-14 20:21+0200\n"
"Last-Translator: Dimitrios Dimitrakos <mail at dimitrios.de>\n"
"Language-Team: Greek <vdr at linuxtv.org>\n"
@@ -432,6 +432,12 @@ msgstr ""
msgid "Help$This value reduces the conflict check to the given range of days. All other conflicts are classified as 'not yet important'."
msgstr ""
+msgid "Check also remote conflicts"
+msgstr ""
+
+msgid "Help$Set this to 'yes' if the conflict check should be done for timers set on remote hosts. This needs SVDRPPeering to be set in vdr and Plugin epgsearch running on the remote host."
+msgstr ""
+
msgid "--- Automatic checking ---"
msgstr ""
diff --git a/po/es_ES.po b/po/es_ES.po
index e77a5eb..c288ddb 100644
--- a/po/es_ES.po
+++ b/po/es_ES.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.5.7\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2017-05-12 12:04+0200\n"
+"POT-Creation-Date: 2017-06-15 11:15+0200\n"
"PO-Revision-Date: 2007-11-18 20:09+0200\n"
"Last-Translator: bittor from open7x0.org <bittor7x0 _at_ gmail.com>\n"
"Language-Team: Spanish <vdr at linuxtv.org>\n"
@@ -467,6 +467,12 @@ msgstr "Sólo comprobar los próximos ... días"
msgid "Help$This value reduces the conflict check to the given range of days. All other conflicts are classified as 'not yet important'."
msgstr "Este valor reduce la comprobación de conflictos al rango de días dados. El resto de conflictos son clasificados como 'no importantes'."
+msgid "Check also remote conflicts"
+msgstr ""
+
+msgid "Help$Set this to 'yes' if the conflict check should be done for timers set on remote hosts. This needs SVDRPPeering to be set in vdr and Plugin epgsearch running on the remote host."
+msgstr ""
+
msgid "--- Automatic checking ---"
msgstr "--- Comprobación automática ---"
diff --git a/po/et_EE.po b/po/et_EE.po
index c5f5e7e..ade1339 100644
--- a/po/et_EE.po
+++ b/po/et_EE.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.5.7\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2017-05-12 12:04+0200\n"
+"POT-Creation-Date: 2017-06-15 11:15+0200\n"
"PO-Revision-Date: 2007-08-14 20:21+0200\n"
"Last-Translator: Arthur Konovalov <kasjas at hot.ee>\n"
"Language-Team: Estonian <vdr at linuxtv.org>\n"
@@ -432,6 +432,12 @@ msgstr ""
msgid "Help$This value reduces the conflict check to the given range of days. All other conflicts are classified as 'not yet important'."
msgstr ""
+msgid "Check also remote conflicts"
+msgstr ""
+
+msgid "Help$Set this to 'yes' if the conflict check should be done for timers set on remote hosts. This needs SVDRPPeering to be set in vdr and Plugin epgsearch running on the remote host."
+msgstr ""
+
msgid "--- Automatic checking ---"
msgstr ""
diff --git a/po/fi_FI.po b/po/fi_FI.po
index 24c7e59..51d9fc8 100644
--- a/po/fi_FI.po
+++ b/po/fi_FI.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: EPGSearch 0.9.25\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2017-05-12 12:04+0200\n"
+"POT-Creation-Date: 2017-06-15 11:15+0200\n"
"PO-Revision-Date: 2011-01-04 21:07+0200\n"
"Last-Translator: Ville Skyttä <ville.skytta at iki.fi>\n"
"Language-Team: Finnish <vdr at linuxtv.org>\n"
@@ -464,6 +464,12 @@ msgstr "Tarkista vain seuraavat ... päivää"
msgid "Help$This value reduces the conflict check to the given range of days. All other conflicts are classified as 'not yet important'."
msgstr "Asettaa ajanjakson päivinä päällekkäisyyksien tarkistukselle. Muita päällekkäisyyksiä ei pidetä vielä merkitsevinä."
+msgid "Check also remote conflicts"
+msgstr ""
+
+msgid "Help$Set this to 'yes' if the conflict check should be done for timers set on remote hosts. This needs SVDRPPeering to be set in vdr and Plugin epgsearch running on the remote host."
+msgstr ""
+
msgid "--- Automatic checking ---"
msgstr "--- Automaattinen tarkistus ---"
diff --git a/po/fr_FR.po b/po/fr_FR.po
index 8928dbc..be10c25 100644
--- a/po/fr_FR.po
+++ b/po/fr_FR.po
@@ -10,7 +10,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.5.7\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2017-05-12 12:04+0200\n"
+"POT-Creation-Date: 2017-06-15 11:15+0200\n"
"PO-Revision-Date: 2008-04-30 08:36+0200\n"
"Last-Translator: Patrice Staudt <patrice.staudt at laposte.net>\n"
"Language-Team: French <vdr at linuxtv.org>\n"
@@ -471,6 +471,12 @@ msgstr "Ne vérifier que les prochains ... jours"
msgid "Help$This value reduces the conflict check to the given range of days. All other conflicts are classified as 'not yet important'."
msgstr "Avec cette valeur vous définissez l'interval de temps de la vérification de conflits. Tous ces conflits en dehors de cet interval sont qualifés comme 'pas encore importants."
+msgid "Check also remote conflicts"
+msgstr ""
+
+msgid "Help$Set this to 'yes' if the conflict check should be done for timers set on remote hosts. This needs SVDRPPeering to be set in vdr and Plugin epgsearch running on the remote host."
+msgstr ""
+
msgid "--- Automatic checking ---"
msgstr "--- Vérifications automatiques ---"
diff --git a/po/hr_HR.po b/po/hr_HR.po
index fed7b39..6ffd2f5 100644
--- a/po/hr_HR.po
+++ b/po/hr_HR.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.5.7\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2017-05-12 12:04+0200\n"
+"POT-Creation-Date: 2017-06-15 11:15+0200\n"
"PO-Revision-Date: 2007-08-14 20:21+0200\n"
"Last-Translator: Drazen Dupor <drazen.dupor at dupor.com>\n"
"Language-Team: Croatian <vdr at linuxtv.org>\n"
@@ -433,6 +433,12 @@ msgstr ""
msgid "Help$This value reduces the conflict check to the given range of days. All other conflicts are classified as 'not yet important'."
msgstr ""
+msgid "Check also remote conflicts"
+msgstr ""
+
+msgid "Help$Set this to 'yes' if the conflict check should be done for timers set on remote hosts. This needs SVDRPPeering to be set in vdr and Plugin epgsearch running on the remote host."
+msgstr ""
+
msgid "--- Automatic checking ---"
msgstr ""
diff --git a/po/hu_HU.po b/po/hu_HU.po
index b3bac82..673f83b 100644
--- a/po/hu_HU.po
+++ b/po/hu_HU.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.5.7\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2017-05-12 12:04+0200\n"
+"POT-Creation-Date: 2017-06-15 11:15+0200\n"
"PO-Revision-Date: 2007-08-14 20:21+0200\n"
"Last-Translator: Istvan Koenigsberger <istvnko at hotmail.com>, Guido Josten <guido.josten at t-online.de>\n"
"Language-Team: Hungarian <vdr at linuxtv.org>\n"
@@ -432,6 +432,12 @@ msgstr ""
msgid "Help$This value reduces the conflict check to the given range of days. All other conflicts are classified as 'not yet important'."
msgstr ""
+msgid "Check also remote conflicts"
+msgstr ""
+
+msgid "Help$Set this to 'yes' if the conflict check should be done for timers set on remote hosts. This needs SVDRPPeering to be set in vdr and Plugin epgsearch running on the remote host."
+msgstr ""
+
msgid "--- Automatic checking ---"
msgstr ""
diff --git a/po/it_IT.po b/po/it_IT.po
index ebfb1b8..e91de4a 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: <see README>\n"
-"POT-Creation-Date: 2017-05-12 12:04+0200\n"
+"POT-Creation-Date: 2017-06-15 11:15+0200\n"
"PO-Revision-Date: 2011-07-17 17:46+0100\n"
"Last-Translator: Diego Pierotto <vdr-italian at tiscali.it>\n"
"Language-Team: Italian <vdr at linuxtv.org>\n"
@@ -465,6 +465,12 @@ msgstr "Verifica solo entro i prossimi ... giorni"
msgid "Help$This value reduces the conflict check to the given range of days. All other conflicts are classified as 'not yet important'."
msgstr "Questo valore riduce la verifica del conflitto ad un dato range di giorni. Tutti gli altri conflitti sono classificati come 'non ancora importanti'."
+msgid "Check also remote conflicts"
+msgstr ""
+
+msgid "Help$Set this to 'yes' if the conflict check should be done for timers set on remote hosts. This needs SVDRPPeering to be set in vdr and Plugin epgsearch running on the remote host."
+msgstr ""
+
msgid "--- Automatic checking ---"
msgstr "--- Verifica automatica ---"
diff --git a/po/lt_LT.po b/po/lt_LT.po
index 4ce7a98..6354955 100644
--- a/po/lt_LT.po
+++ b/po/lt_LT.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.7.10\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2017-05-12 12:04+0200\n"
+"POT-Creation-Date: 2017-06-15 11:15+0200\n"
"PO-Revision-Date: 2007-08-14 20:21+0200\n"
"Last-Translator: Valdemaras Pipiras <varas at ambernet.lt>\n"
"Language-Team: Lithuanian <vdr at linuxtv.org>\n"
@@ -469,6 +469,12 @@ msgstr "Tikrinti tik kas ... dienas"
msgid "Help$This value reduces the conflict check to the given range of days. All other conflicts are classified as 'not yet important'."
msgstr "pagal šį parametrą Nustatomas konflikto paieškos periodiškumas dienomis. Visi kiti konfliktai laikomi kaip 'dar ne svarbūs'."
+msgid "Check also remote conflicts"
+msgstr ""
+
+msgid "Help$Set this to 'yes' if the conflict check should be done for timers set on remote hosts. This needs SVDRPPeering to be set in vdr and Plugin epgsearch running on the remote host."
+msgstr ""
+
msgid "--- Automatic checking ---"
msgstr "--- Automatinė paieška ---"
diff --git a/po/nl_NL.po b/po/nl_NL.po
index 142c6ba..9fa0a5c 100644
--- a/po/nl_NL.po
+++ b/po/nl_NL.po
@@ -9,7 +9,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.5.7\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2017-05-12 12:04+0200\n"
+"POT-Creation-Date: 2017-06-15 11:15+0200\n"
"PO-Revision-Date: 2007-08-14 20:21+0200\n"
"Last-Translator: Maarten Wisse <Maarten.Wisse at urz.uni-hd.de>\n"
"Language-Team: Dutch <vdr at linuxtv.org>\n"
@@ -471,6 +471,12 @@ msgstr "Controleer alleen vóór de volgende ... dagen"
msgid "Help$This value reduces the conflict check to the given range of days. All other conflicts are classified as 'not yet important'."
msgstr "Deze waarde beperkt de conflict controle tot het gegeven aantal dagen. Alle andere conflicten worden als 'nog niet belangrijk' bestempeld."
+msgid "Check also remote conflicts"
+msgstr ""
+
+msgid "Help$Set this to 'yes' if the conflict check should be done for timers set on remote hosts. This needs SVDRPPeering to be set in vdr and Plugin epgsearch running on the remote host."
+msgstr ""
+
msgid "--- Automatic checking ---"
msgstr "--- Automatische controle ---"
diff --git a/po/nn_NO.po b/po/nn_NO.po
index 286e41f..2a55b8e 100644
--- a/po/nn_NO.po
+++ b/po/nn_NO.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.5.7\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2017-05-04 17:01+0200\n"
+"POT-Creation-Date: 2017-06-15 11:15+0200\n"
"PO-Revision-Date: 2007-08-14 20:21+0200\n"
"Last-Translator: Truls Slevigen <truls at slevigen.no>\n"
"Language-Team: Norwegian Nynorsk <vdr at linuxtv.org>\n"
@@ -432,6 +432,12 @@ msgstr ""
msgid "Help$This value reduces the conflict check to the given range of days. All other conflicts are classified as 'not yet important'."
msgstr ""
+msgid "Check also remote conflicts"
+msgstr ""
+
+msgid "Help$Set this to 'yes' if the conflict check should be done for timers set on remote hosts. This needs SVDRPPeering to be set in vdr and Plugin epgsearch running on the remote host."
+msgstr ""
+
msgid "--- Automatic checking ---"
msgstr ""
diff --git a/po/pl_PL.po b/po/pl_PL.po
index b91d576..7bd42a9 100644
--- a/po/pl_PL.po
+++ b/po/pl_PL.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.5.7\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2017-05-04 17:01+0200\n"
+"POT-Creation-Date: 2017-06-15 11:15+0200\n"
"PO-Revision-Date: 2007-08-14 20:21+0200\n"
"Last-Translator: Michael Rakowski <mrak at gmx.de>\n"
"Language-Team: Polish <vdr at linuxtv.org>\n"
@@ -432,6 +432,12 @@ msgstr ""
msgid "Help$This value reduces the conflict check to the given range of days. All other conflicts are classified as 'not yet important'."
msgstr ""
+msgid "Check also remote conflicts"
+msgstr ""
+
+msgid "Help$Set this to 'yes' if the conflict check should be done for timers set on remote hosts. This needs SVDRPPeering to be set in vdr and Plugin epgsearch running on the remote host."
+msgstr ""
+
msgid "--- Automatic checking ---"
msgstr ""
diff --git a/po/pt_PT.po b/po/pt_PT.po
index 47bc02a..8fc5fd0 100644
--- a/po/pt_PT.po
+++ b/po/pt_PT.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.5.7\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2017-05-04 17:01+0200\n"
+"POT-Creation-Date: 2017-06-15 11:15+0200\n"
"PO-Revision-Date: 2007-08-14 20:21+0200\n"
"Last-Translator: Paulo Lopes <pmml at netvita.pt>\n"
"Language-Team: Portuguese <vdr at linuxtv.org>\n"
@@ -431,6 +431,12 @@ msgstr ""
msgid "Help$This value reduces the conflict check to the given range of days. All other conflicts are classified as 'not yet important'."
msgstr ""
+msgid "Check also remote conflicts"
+msgstr ""
+
+msgid "Help$Set this to 'yes' if the conflict check should be done for timers set on remote hosts. This needs SVDRPPeering to be set in vdr and Plugin epgsearch running on the remote host."
+msgstr ""
+
msgid "--- Automatic checking ---"
msgstr ""
diff --git a/po/ro_RO.po b/po/ro_RO.po
index 20683e6..0048be8 100644
--- a/po/ro_RO.po
+++ b/po/ro_RO.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.5.7\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2017-05-04 17:01+0200\n"
+"POT-Creation-Date: 2017-06-15 11:15+0200\n"
"PO-Revision-Date: 2007-08-14 20:21+0200\n"
"Last-Translator: Lucian Muresan <lucianm at users.sourceforge.net>\n"
"Language-Team: Romanian <vdr at linuxtv.org>\n"
@@ -432,6 +432,12 @@ msgstr ""
msgid "Help$This value reduces the conflict check to the given range of days. All other conflicts are classified as 'not yet important'."
msgstr ""
+msgid "Check also remote conflicts"
+msgstr ""
+
+msgid "Help$Set this to 'yes' if the conflict check should be done for timers set on remote hosts. This needs SVDRPPeering to be set in vdr and Plugin epgsearch running on the remote host."
+msgstr ""
+
msgid "--- Automatic checking ---"
msgstr ""
diff --git a/po/ru_RU.po b/po/ru_RU.po
index 188430d..4282eb1 100644
--- a/po/ru_RU.po
+++ b/po/ru_RU.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.5.7\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2017-05-04 17:01+0200\n"
+"POT-Creation-Date: 2017-06-15 11:15+0200\n"
"PO-Revision-Date: 2007-08-14 20:21+0200\n"
"Last-Translator: Vyacheslav Dikonov <sdiconov at mail.ru>\n"
"Language-Team: Russian <vdr at linuxtv.org>\n"
@@ -431,6 +431,12 @@ msgstr ""
msgid "Help$This value reduces the conflict check to the given range of days. All other conflicts are classified as 'not yet important'."
msgstr ""
+msgid "Check also remote conflicts"
+msgstr ""
+
+msgid "Help$Set this to 'yes' if the conflict check should be done for timers set on remote hosts. This needs SVDRPPeering to be set in vdr and Plugin epgsearch running on the remote host."
+msgstr ""
+
msgid "--- Automatic checking ---"
msgstr ""
diff --git a/po/sk_SK.po b/po/sk_SK.po
index 10e771e..f39b6d4 100644
--- a/po/sk_SK.po
+++ b/po/sk_SK.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: epgsearch\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2017-05-04 17:01+0200\n"
+"POT-Creation-Date: 2017-06-15 11:15+0200\n"
"PO-Revision-Date: 2009-11-02 09:40+0100\n"
"Last-Translator: Milan Hrala <hrala.milan at gmail.com>\n"
"Language-Team: Slovak <hrala.milan at gmail.com>\n"
@@ -468,6 +468,12 @@ msgstr "Skontrolovať iba do budúcich ... dní"
msgid "Help$This value reduces the conflict check to the given range of days. All other conflicts are classified as 'not yet important'."
msgstr "Táto hodnota znižuje konflikty podľa daného rozsahu dní. Všetky ostatné konflikty sú klasifikované ako 'ešte dôležité'."
+msgid "Check also remote conflicts"
+msgstr ""
+
+msgid "Help$Set this to 'yes' if the conflict check should be done for timers set on remote hosts. This needs SVDRPPeering to be set in vdr and Plugin epgsearch running on the remote host."
+msgstr ""
+
msgid "--- Automatic checking ---"
msgstr "--- Automatická kontrola ---"
diff --git a/po/sl_SI.po b/po/sl_SI.po
index 631d5ba..24d68be 100644
--- a/po/sl_SI.po
+++ b/po/sl_SI.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.5.7\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2017-05-04 17:01+0200\n"
+"POT-Creation-Date: 2017-06-15 11:15+0200\n"
"PO-Revision-Date: 2007-08-14 20:21+0200\n"
"Last-Translator: Matjaz Thaler <matjaz.thaler at guest.arnes.si>\n"
"Language-Team: Slovenian <vdr at linuxtv.org>\n"
@@ -432,6 +432,12 @@ msgstr ""
msgid "Help$This value reduces the conflict check to the given range of days. All other conflicts are classified as 'not yet important'."
msgstr ""
+msgid "Check also remote conflicts"
+msgstr ""
+
+msgid "Help$Set this to 'yes' if the conflict check should be done for timers set on remote hosts. This needs SVDRPPeering to be set in vdr and Plugin epgsearch running on the remote host."
+msgstr ""
+
msgid "--- Automatic checking ---"
msgstr ""
diff --git a/po/sv_SE.po b/po/sv_SE.po
index dfcd6f8..94db34a 100644
--- a/po/sv_SE.po
+++ b/po/sv_SE.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.5.7\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2017-05-04 17:01+0200\n"
+"POT-Creation-Date: 2017-06-15 11:15+0200\n"
"PO-Revision-Date: 2007-08-14 20:21+0200\n"
"Last-Translator: Tomas Prybil <tomas at prybil.se>\n"
"Language-Team: Swedish <vdr at linuxtv.org>\n"
@@ -432,6 +432,12 @@ msgstr ""
msgid "Help$This value reduces the conflict check to the given range of days. All other conflicts are classified as 'not yet important'."
msgstr ""
+msgid "Check also remote conflicts"
+msgstr ""
+
+msgid "Help$Set this to 'yes' if the conflict check should be done for timers set on remote hosts. This needs SVDRPPeering to be set in vdr and Plugin epgsearch running on the remote host."
+msgstr ""
+
msgid "--- Automatic checking ---"
msgstr ""
diff --git a/po/tr_TR.po b/po/tr_TR.po
index 3e8305c..535c3a2 100644
--- a/po/tr_TR.po
+++ b/po/tr_TR.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 1.5.7\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2017-05-04 17:01+0200\n"
+"POT-Creation-Date: 2017-06-15 11:15+0200\n"
"PO-Revision-Date: 2007-08-14 20:21+0200\n"
"Last-Translator: Oktay Yolgeçen <oktay_73 at yahoo.de>\n"
"Language-Team: Turkish <vdr at linuxtv.org>\n"
@@ -431,6 +431,12 @@ msgstr ""
msgid "Help$This value reduces the conflict check to the given range of days. All other conflicts are classified as 'not yet important'."
msgstr ""
+msgid "Check also remote conflicts"
+msgstr ""
+
+msgid "Help$Set this to 'yes' if the conflict check should be done for timers set on remote hosts. This needs SVDRPPeering to be set in vdr and Plugin epgsearch running on the remote host."
+msgstr ""
+
msgid "--- Automatic checking ---"
msgstr ""
diff --git a/recdone_thread.c b/recdone_thread.c
new file mode 100644
index 0000000..7029849
--- /dev/null
+++ b/recdone_thread.c
@@ -0,0 +1,174 @@
+/* -*- c++ -*-
+Copyright (C) 2004-2013 Christian Wieninger 2017 Johann Friedrichs
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+*/
+
+#include <string>
+#include <list>
+#ifdef __FreeBSD__
+#include <netinet/in.h>
+#endif
+#include "recdone_thread.h"
+#include "recdone.h"
+
+#include <vdr/tools.h>
+#include <vdr/plugin.h>
+#define ALLOWED_BREAK_INSECS 2
+
+extern int updateForced;
+
+cRecdoneThread::cRecdoneThread()
+: cThread("EPGSearch: recdone")
+{
+}
+
+cRecdoneThread::~cRecdoneThread() {
+}
+
+bool cRecdoneThread::IsPesRecording(const cRecording *pRecording)
+{
+ return pRecording && pRecording->IsPesRecording();
+}
+
+#define LOC_INDEXFILESUFFIX "/index"
+
+struct tIndexTs {
+ uint64_t offset:40; // up to 1TB per file (not using off_t here - must definitely be exactly 64 bit!)
+ int reserved:7; // reserved for future use
+ int independent:1; // marks frames that can be displayed by themselves (for trick modes)
+ uint16_t number:16; // up to 64K files per recording
+ tIndexTs(off_t Offset, bool Independent, uint16_t Number)
+ {
+ offset = Offset;
+ reserved = 0;
+ independent = Independent;
+ number = Number;
+ }
+};
+
+int cRecdoneThread::RecLengthInSecs(const cRecording *pRecording)
+{
+ struct stat buf;
+ cString fullname = cString::sprintf("%s%s", pRecording->FileName(), IsPesRecording(pRecording) ? LOC_INDEXFILESUFFIX ".vdr" : LOC_INDEXFILESUFFIX);
+ if (pRecording->FileName() && *fullname && access(fullname, R_OK) == 0 && stat(fullname, &buf) == 0)
+ {
+ double frames = buf.st_size ? (buf.st_size - 1) / sizeof(tIndexTs) + 1 : 0;
+ double Seconds = 0;
+ modf((frames + 0.5) / pRecording->FramesPerSecond(), &Seconds);
+ return Seconds;
+ }
+ return -1;
+}
+
+void cRecdoneThread::Action(void)
+{
+ LogFile.Log(1,"started recdone_thread with %s",m_filename);
+ cMutexLock RecsDoneLock(&RecsDone);
+ time_t now = time(NULL);
+ // remove timers that finished recording from TimersRecording
+ // incomplete recordings are kept for a while, perhaps they will be resumed
+ LOCK_TIMERS_READ;
+ cMutexLock TimersRecordingLock(&TimersRecording);
+ cRecDoneTimerObj *tiR = TimersRecording.First();
+ while(tiR)
+ {
+ // check if timer still exists
+ bool found = false;
+
+ for (const cTimer *ti = Timers->First(); ti; ti = Timers->Next(ti))
+ if (ti == tiR->timer)
+ {
+ found = true;
+ break;
+ }
+
+ if (found && !tiR->timer->Recording())
+ {
+ if (tiR->recDone)
+ {
+ cSearchExt* search = SearchExts.GetSearchFromID(tiR->recDone->searchID);
+ if (!search) return;
+ // check if recording has ended before timer end
+
+ bool complete = true;
+ const cRecording *pRecording;
+ {
+ LOCK_RECORDINGS_READ;
+ pRecording = Recordings->GetByName(m_filename);
+ }
+ long timerLengthSecs = tiR->timer->StopTime()-tiR->timer->StartTime();
+ int recFraction = 100;
+ if (pRecording && timerLengthSecs)
+ {
+ int recLen = RecLengthInSecs(pRecording);
+ recFraction = double(recLen) * 100 / timerLengthSecs;
+ }
+ bool vpsUsed = tiR->timer->HasFlags(tfVps) && tiR->timer->Event() && tiR->timer->Event()->Vps();
+ if ((!vpsUsed && now < tiR->timer->StopTime()) || recFraction < (vpsUsed ? 90: 98)) // assure timer has reached its end or at least 98% were recorded
+ {
+ complete = false;
+ LogFile.Log(1,"finished: '%s' (not complete! - recorded only %d%%); search timer: '%s'; VPS used: %s", tiR->timer->File(), recFraction, search->search, vpsUsed ? "Yes": "No");
+ }
+ else
+ {
+ LogFile.Log(1,"finished: '%s'; search timer: '%s'; VPS used: %s", tiR->timer->File(), search->search, vpsUsed ? "Yes": "No");
+ if (recFraction < 100)
+ LogFile.Log(2,"recorded %d%%'", recFraction);
+ }
+ if (complete)
+ {
+ RecsDone.Add(tiR->recDone);
+ LogFile.Log(1,"added rec done for '%s~%s';%s", tiR->recDone->title?tiR->recDone->title:"unknown title",
+ tiR->recDone->shortText?tiR->recDone->shortText:"unknown subtitle",
+ search->search);
+ RecsDone.Save();
+ tiR->recDone = NULL; // prevent deletion
+ tiR->lastBreak = 0;
+
+ // check for search timers to delete automatically
+ SearchExts.CheckForAutoDelete(search);
+
+ // trigger a search timer update (skip running events)
+ search->skipRunningEvents = true;
+ updateForced = 1;
+ }
+ else if (tiR->lastBreak == 0) // store first break
+ tiR->lastBreak = now;
+ }
+ if (tiR->lastBreak == 0 || (now - tiR->lastBreak) > ALLOWED_BREAK_INSECS)
+ { // remove finished recordings or those with an unallowed break
+ if (tiR->recDone) delete tiR->recDone; // clean up
+ cRecDoneTimerObj *tiRNext = TimersRecording.Next(tiR);
+ TimersRecording.Del(tiR);
+ tiR = tiRNext;
+ continue;
+ }
+ break;
+ }
+ if (!found)
+ {
+ if (tiR->recDone) delete tiR->recDone; // clean up
+ cRecDoneTimerObj *tiRNext = TimersRecording.Next(tiR);
+ TimersRecording.Del(tiR);
+ tiR = tiRNext;
+ continue;
+ }
+ tiR = TimersRecording.Next(tiR);
+ }
+ if (m_filename) free(m_filename);
+ LogFile.Log(1,"recdone_thread ended");
+}
diff --git a/recdone_thread.h b/recdone_thread.h
new file mode 100644
index 0000000..adb65f9
--- /dev/null
+++ b/recdone_thread.h
@@ -0,0 +1,40 @@
+/* -*- c++ -*-
+Copyright (C) 2004-2013 Christian Wieninger 2017 Johann Friedrichs
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+
+*/
+
+#ifndef VDR_RECDONE_THREAD_H
+#define VDR_RECDONE_THREAD_H
+
+#include <vdr/thread.h>
+#include "recstatus.h"
+
+class cRecdoneThread: public cThread {
+private:
+ char * m_filename;
+public:
+ virtual void Action(void);
+ cRecdoneThread(void);
+ virtual ~cRecdoneThread();
+ void SetFilename(const char *FileName) {
+ m_filename = strdup(FileName); };
+ int RecLengthInSecs(const cRecording *pRecording);
+ bool IsPesRecording(const cRecording *pRecording);
+};
+
+#endif
diff --git a/recstatus.c b/recstatus.c
index 794ba27..0b382fd 100644
--- a/recstatus.c
+++ b/recstatus.c
@@ -23,15 +23,15 @@ The project's page is at http://winni.vdr-developer.org/epgsearch
#include "epgsearchtools.h"
#include "recstatus.h"
-#include "recdone.h"
+#include "recdone_thread.h"
#include "conflictcheck_thread.h"
#include "epgsearchcfg.h"
#include <math.h>
#define ALLOWED_BREAK_INSECS 2
-extern int updateForced;
extern int gl_InfoConflict;
-
+cTimersRecording TimersRecording;
+cRecdoneThread RecdoneThread;
cRecStatusMonitor* gl_recStatusMonitor = NULL;
@@ -54,6 +54,7 @@ void cRecStatusMonitor::Recording(const cDevice *Device, const char *Name, const
{
// check if this is a new entry
cRecDoneTimerObj *tiRFound = NULL;
+ cMutexLock TimersRecordingLock(&TimersRecording);
for (cRecDoneTimerObj *tiR = TimersRecording.First(); tiR; tiR = TimersRecording.Next(tiR))
if (tiR->timer == ti)
{
@@ -105,139 +106,18 @@ void cRecStatusMonitor::Recording(const cDevice *Device, const char *Name, const
if (!On)
{
- cMutexLock RecsDoneLock(&RecsDone);
- // remove timers that finished recording from TimersRecording
- // incomplete recordings are kept for a while, perhaps they will be resumed
- cRecDoneTimerObj *tiR = TimersRecording.First();
- while(tiR)
- {
- // check if timer still exists
- bool found = false;
-
- LOCK_TIMERS_READ;
- for (const cTimer *ti = Timers->First(); ti; ti = Timers->Next(ti))
- if (ti == tiR->timer)
- {
- found = true;
- break;
- }
-
- if (found && !tiR->timer->Recording())
- {
- if (tiR->recDone)
- {
- cSearchExt* search = SearchExts.GetSearchFromID(tiR->recDone->searchID);
- if (!search) return;
-
- // check if recording has ended before timer end
-
- bool complete = true;
- const cRecording *pRecording;
- {
- LOCK_RECORDINGS_READ;
- pRecording = Recordings->GetByName(Filename);
- }
- long timerLengthSecs = tiR->timer->StopTime()-tiR->timer->StartTime();
- int recFraction = 100;
- if (pRecording && timerLengthSecs)
- {
- int recLen = RecLengthInSecs(pRecording);
- recFraction = double(recLen) * 100 / timerLengthSecs;
- }
- bool vpsUsed = tiR->timer->HasFlags(tfVps) && tiR->timer->Event() && tiR->timer->Event()->Vps();
- if ((!vpsUsed && now < tiR->timer->StopTime()) || recFraction < (vpsUsed ? 90: 98)) // assure timer has reached its end or at least 98% were recorded
- {
- complete = false;
- LogFile.Log(1,"finished: '%s' (not complete! - recorded only %d%%); search timer: '%s'; VPS used: %s", tiR->timer->File(), recFraction, search->search, vpsUsed ? "Yes": "No");
- }
- else
- {
- LogFile.Log(1,"finished: '%s'; search timer: '%s'; VPS used: %s", tiR->timer->File(), search->search, vpsUsed ? "Yes": "No");
- if (recFraction < 100)
- LogFile.Log(2,"recorded %d%%'", recFraction);
- }
- if (complete)
- {
- RecsDone.Add(tiR->recDone);
- LogFile.Log(1,"added rec done for '%s~%s';%s", tiR->recDone->title?tiR->recDone->title:"unknown title",
- tiR->recDone->shortText?tiR->recDone->shortText:"unknown subtitle",
- search->search);
- RecsDone.Save();
- tiR->recDone = NULL; // prevent deletion
- tiR->lastBreak = 0;
-
- // check for search timers to delete automatically
- SearchExts.CheckForAutoDelete(search);
-
- // trigger a search timer update (skip running events)
- search->skipRunningEvents = true;
- updateForced = 1;
- }
- else if (tiR->lastBreak == 0) // store first break
- tiR->lastBreak = now;
- }
- if (tiR->lastBreak == 0 || (now - tiR->lastBreak) > ALLOWED_BREAK_INSECS)
- { // remove finished recordings or those with an unallowed break
- if (tiR->recDone) delete tiR->recDone; // clean up
- cRecDoneTimerObj *tiRNext = TimersRecording.Next(tiR);
- TimersRecording.Del(tiR);
- tiR = tiRNext;
- continue;
- }
- break;
- }
- if (!found)
- {
- if (tiR->recDone) delete tiR->recDone; // clean up
- cRecDoneTimerObj *tiRNext = TimersRecording.Next(tiR);
- TimersRecording.Del(tiR);
- tiR = tiRNext;
- continue;
- }
- tiR = TimersRecording.Next(tiR);
- }
+ // must be done in a different thread because we hold timer and scheduling lock here
+ while (RecdoneThread.Active()) cCondWait::SleepMs(100); // wait before changing filename
+ RecdoneThread.SetFilename(Filename);
+ RecdoneThread.Start();
}
}
int cRecStatusMonitor::TimerRecDevice(const cTimer* timer)
{
if (!timer) return 0;
+ cMutexLock TimersRecordingLock(&TimersRecording);
for (cRecDoneTimerObj *tiR = TimersRecording.First(); tiR; tiR = TimersRecording.Next(tiR))
if (tiR->timer == timer && timer->Recording()) return tiR->deviceNr+1;
return 0;
}
-
-bool cRecStatusMonitor::IsPesRecording(const cRecording *pRecording)
-{
- return pRecording && pRecording->IsPesRecording();
-}
-
-#define LOC_INDEXFILESUFFIX "/index"
-
-struct tIndexTs {
- uint64_t offset:40; // up to 1TB per file (not using off_t here - must definitely be exactly 64 bit!)
- int reserved:7; // reserved for future use
- int independent:1; // marks frames that can be displayed by themselves (for trick modes)
- uint16_t number:16; // up to 64K files per recording
- tIndexTs(off_t Offset, bool Independent, uint16_t Number)
- {
- offset = Offset;
- reserved = 0;
- independent = Independent;
- number = Number;
- }
- };
-
-int cRecStatusMonitor::RecLengthInSecs(const cRecording *pRecording)
-{
- struct stat buf;
- cString fullname = cString::sprintf("%s%s", pRecording->FileName(), IsPesRecording(pRecording) ? LOC_INDEXFILESUFFIX ".vdr" : LOC_INDEXFILESUFFIX);
- if (pRecording->FileName() && *fullname && access(fullname, R_OK) == 0 && stat(fullname, &buf) == 0)
- {
- double frames = buf.st_size ? (buf.st_size - 1) / sizeof(tIndexTs) + 1 : 0;
- double Seconds = 0;
- modf((frames + 0.5) / pRecording->FramesPerSecond(), &Seconds);
- return Seconds;
- }
- return -1;
-}
diff --git a/recstatus.h b/recstatus.h
index c0104f9..dcc6fec 100644
--- a/recstatus.h
+++ b/recstatus.h
@@ -21,6 +21,9 @@ The author can be reached at cwieninger at gmx.de
The project's page is at http://winni.vdr-developer.org/epgsearch
*/
+#ifndef __RECSTATUS_H
+#define __RECSTATUS_H
+
#include <vdr/status.h>
#include "recdone.h"
#include "epgsearchtools.h"
@@ -36,17 +39,20 @@ public:
~cRecDoneTimerObj() { timer = NULL; recDone = NULL; } // do not delete anything!
};
+class cTimersRecording: public cList<cRecDoneTimerObj>, public cMutex {
+};
+
+extern cTimersRecording TimersRecording;
+
class cRecStatusMonitor : public cStatus
{
-public:
- cList<cRecDoneTimerObj> TimersRecording;
protected:
virtual void Recording(const cDevice *Device, const char *Name, const char*, bool On);
public:
cRecStatusMonitor();
int TimerRecDevice(const cTimer*);
- bool IsPesRecording(const cRecording *pRecording);
- int RecLengthInSecs(const cRecording *pRecording);
};
extern cRecStatusMonitor* gl_recStatusMonitor;
+
+#endif
diff --git a/searchtimer_thread.c b/searchtimer_thread.c
index 930ba99..ba54566 100644
--- a/searchtimer_thread.c
+++ b/searchtimer_thread.c
@@ -198,7 +198,7 @@ bool cSearchTimerThread::TimerWasModified(const cTimer* t)
void cSearchTimerThread::Action(void)
{
- if (EPGSearchConfig.useExternalSVDRP && !cSVDRPClient::SVDRPSendCmd)
+ if (EPGSearchConfig.useExternalSVDRP && !epgsSVDRP::cSVDRPClient::SVDRPSendCmd)
{
LogFile.eSysLog("ERROR - SVDRPSend script not specified or does not exist (use -f option)");
return;
@@ -703,9 +703,6 @@ bool cSearchTimerThread::AddModTimer(cTimer* Timer, int index, cSearchExt* searc
}
else
tmpSummary = SummaryExtended(searchExt, Timer, pEvent);
- if (Setup.SVDRPPeering && *Setup.SVDRPDefaultHost)
- Timer->SetRemote(Setup.SVDRPDefaultHost);
- else {
if (index==0)
msprintf(&cmdbuf, "NEWT %d:%d:%s:%s:%s:%d:%d:%s:%s",
Flags,
@@ -732,9 +729,6 @@ bool cSearchTimerThread::AddModTimer(cTimer* Timer, int index, cSearchExt* searc
if (!SendViaSVDRP(cmdbuf))
return false;
- }
- if (!HandleRemoteTimerModifications(Timer))
- return false;
if (gl_timerStatusMonitor) gl_timerStatusMonitor->SetConflictCheckAdvised();
diff --git a/svdrpclient.h b/svdrpclient.h
index d76a1f6..e9533fe 100644
--- a/svdrpclient.h
+++ b/svdrpclient.h
@@ -31,6 +31,8 @@ The project's page is at http://winni.vdr-developer.org/epgsearch
#define SVDRPDISCONNECT 221
#define CMDSUCCESS 250
+namespace epgsSVDRP {
+
class cSVDRPClient {
private:
int sock;
@@ -142,4 +144,6 @@ public:
static const char *SVDRPSendCmd;
};
+};
+
#endif
diff --git a/timer_thread.c b/timer_thread.c
index feef7b3..ba82c41 100644
--- a/timer_thread.c
+++ b/timer_thread.c
@@ -76,7 +76,7 @@ void cTimerThread::Stop(void) {
void cTimerThread::Action(void)
{
m_Active = true;
- if (EPGSearchConfig.useExternalSVDRP && !cSVDRPClient::SVDRPSendCmd)
+ if (EPGSearchConfig.useExternalSVDRP && !epgsSVDRP::cSVDRPClient::SVDRPSendCmd)
{
LogFile.eSysLog("ERROR - SVDRPSend script not specified or does not exist (use -f option)");
m_Active = false;
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-vdr-dvb/vdr-plugin-epgsearch.git
More information about the pkg-vdr-dvb-changes
mailing list