summaryrefslogtreecommitdiff
path: root/epgsearchext.c
diff options
context:
space:
mode:
Diffstat (limited to 'epgsearchext.c')
-rw-r--r--epgsearchext.c2846
1 files changed, 1382 insertions, 1464 deletions
diff --git a/epgsearchext.c b/epgsearchext.c
index f8d1f90..4c69c43 100644
--- a/epgsearchext.c
+++ b/epgsearchext.c
@@ -43,7 +43,7 @@ cSearchExts SearchExts;
cSearchExts SearchTemplates;
#ifndef MAX_SUBTITLE_LENGTH
- #define MAX_SUBTITLE_LENGTH 40
+#define MAX_SUBTITLE_LENGTH 40
#endif
// -- cSearchExt -----------------------------------------------------------------
@@ -51,1641 +51,1559 @@ char *cSearchExt::buffer = NULL;
cSearchExt::cSearchExt(void)
{
- ID = -1;
- *search = 0;
- options = 1;
- useTime = false;
- startTime = 0000;
- stopTime = 2359;
- useChannel = false;
- {
- LOCK_CHANNELS_READ;
- channelMin = Channels->GetByNumber(cDevice::CurrentChannel());
- channelMax = Channels->GetByNumber(cDevice::CurrentChannel());
- }
- channelGroup = NULL;
- useCase = false;
- mode = 0;
- useTitle = true;
- useSubtitle = true;
- useDescription = true;
- useDuration = false;
- minDuration = 0;
- maxDuration = 2359;
- useAsSearchTimer = false;
- useDayOfWeek = false;
- DayOfWeek = 0;
- buffer = NULL;
- *directory = 0;
- useEpisode = 0;
- Priority = EPGSearchConfig.DefPriority;
- Lifetime = EPGSearchConfig.DefLifetime;
- MarginStart = EPGSearchConfig.DefMarginStart;
- MarginStop = EPGSearchConfig.DefMarginStop;
- useVPS = false;
- action = searchTimerActionRecord;
- useExtEPGInfo = false;
- contentsFilter = "";
- catvalues = (char**) malloc(SearchExtCats.Count() * sizeof(char*));
- cSearchExtCat *SearchExtCat = SearchExtCats.First();
- int index = 0;
- while (SearchExtCat)
- {
- catvalues[index] = (char*)malloc(MaxFileName);
- *catvalues[index] = 0;
- SearchExtCat = SearchExtCats.Next(SearchExtCat);
- index++;
- }
- avoidRepeats = 0;
- compareTitle = 1;
- compareSubtitle = 1;
- compareSummary = 1;
- compareSummaryMatchInPercent = 90;
- compareDate = 0;
- allowedRepeats = 0;
- catvaluesAvoidRepeat = 0;
- repeatsWithinDays = 0;
- delAfterDays = 0;
- recordingsKeep = 0;
- switchMinsBefore = 1;
- pauseOnNrRecordings = 0;
- blacklistMode = blacklistsOnlyGlobal; // no blacklists
- blacklists.Clear();
- fuzzyTolerance = 1;
- useInFavorites = 0;
- menuTemplate = 0;
- delMode = 0;
- delAfterCountRecs = 0;
- delAfterDaysOfFirstRec = 0;
- useAsSearchTimerFrom = 0;
- useAsSearchTimerTil = 0;
- ignoreMissingEPGCats = 0;
- unmuteSoundOnSwitch = 0;
- skipRunningEvents = false;
+ ID = -1;
+ *search = 0;
+ options = 1;
+ useTime = false;
+ startTime = 0000;
+ stopTime = 2359;
+ useChannel = false;
+ {
+ LOCK_CHANNELS_READ;
+ channelMin = Channels->GetByNumber(cDevice::CurrentChannel());
+ channelMax = Channels->GetByNumber(cDevice::CurrentChannel());
+ }
+ channelGroup = NULL;
+ useCase = false;
+ mode = 0;
+ useTitle = true;
+ useSubtitle = true;
+ useDescription = true;
+ useDuration = false;
+ minDuration = 0;
+ maxDuration = 2359;
+ useAsSearchTimer = false;
+ useDayOfWeek = false;
+ DayOfWeek = 0;
+ buffer = NULL;
+ *directory = 0;
+ useEpisode = 0;
+ Priority = EPGSearchConfig.DefPriority;
+ Lifetime = EPGSearchConfig.DefLifetime;
+ MarginStart = EPGSearchConfig.DefMarginStart;
+ MarginStop = EPGSearchConfig.DefMarginStop;
+ useVPS = false;
+ action = searchTimerActionRecord;
+ useExtEPGInfo = false;
+ contentsFilter = "";
+ catvalues = (char**) malloc(SearchExtCats.Count() * sizeof(char*));
+ cSearchExtCat *SearchExtCat = SearchExtCats.First();
+ int index = 0;
+ while (SearchExtCat) {
+ catvalues[index] = (char*)malloc(MaxFileName);
+ *catvalues[index] = 0;
+ SearchExtCat = SearchExtCats.Next(SearchExtCat);
+ index++;
+ }
+ avoidRepeats = 0;
+ compareTitle = 1;
+ compareSubtitle = 1;
+ compareSummary = 1;
+ compareSummaryMatchInPercent = 90;
+ compareDate = 0;
+ allowedRepeats = 0;
+ catvaluesAvoidRepeat = 0;
+ repeatsWithinDays = 0;
+ delAfterDays = 0;
+ recordingsKeep = 0;
+ switchMinsBefore = 1;
+ pauseOnNrRecordings = 0;
+ blacklistMode = blacklistsOnlyGlobal; // no blacklists
+ blacklists.Clear();
+ fuzzyTolerance = 1;
+ useInFavorites = 0;
+ menuTemplate = 0;
+ delMode = 0;
+ delAfterCountRecs = 0;
+ delAfterDaysOfFirstRec = 0;
+ useAsSearchTimerFrom = 0;
+ useAsSearchTimerTil = 0;
+ ignoreMissingEPGCats = 0;
+ unmuteSoundOnSwitch = 0;
+ skipRunningEvents = false;
}
cSearchExt::~cSearchExt(void)
{
- if (buffer) {
- free(buffer);
- buffer = NULL;
- }
-
- if (catvalues)
- {
- cSearchExtCat *SearchExtCat = SearchExtCats.First();
- int index = 0;
- while (SearchExtCat)
- {
- free(catvalues[index]);
- SearchExtCat = SearchExtCats.Next(SearchExtCat);
- index++;
- }
- free(catvalues);
- catvalues = NULL;
- }
+ if (buffer) {
+ free(buffer);
+ buffer = NULL;
+ }
+
+ if (catvalues) {
+ cSearchExtCat *SearchExtCat = SearchExtCats.First();
+ int index = 0;
+ while (SearchExtCat) {
+ free(catvalues[index]);
+ SearchExtCat = SearchExtCats.Next(SearchExtCat);
+ index++;
+ }
+ free(catvalues);
+ catvalues = NULL;
+ }
}
cSearchExt& cSearchExt::operator= (const cSearchExt &SearchExt)
{
- CopyFromTemplate(&SearchExt);
- ID = SearchExt.ID;
- strcpy(search, SearchExt.search);
-
- cSearchExtCat *SearchExtCat = SearchExtCats.First();
- int index = 0;
- while (SearchExtCat)
- {
- *catvalues[index] = 0;
- strcpy(catvalues[index], SearchExt.catvalues[index]);
- SearchExtCat = SearchExtCats.Next(SearchExtCat);
- index++;
- }
-
- return *this;
+ CopyFromTemplate(&SearchExt);
+ ID = SearchExt.ID;
+ strcpy(search, SearchExt.search);
+
+ cSearchExtCat *SearchExtCat = SearchExtCats.First();
+ int index = 0;
+ while (SearchExtCat) {
+ *catvalues[index] = 0;
+ strcpy(catvalues[index], SearchExt.catvalues[index]);
+ SearchExtCat = SearchExtCats.Next(SearchExtCat);
+ index++;
+ }
+
+ return *this;
}
- void cSearchExt::CopyFromTemplate(const cSearchExt* templ, bool ignoreChannelSettings)
+void cSearchExt::CopyFromTemplate(const cSearchExt* templ, bool ignoreChannelSettings)
{
- options = templ->options;
- useTime = templ->useTime;
- startTime = templ->startTime;
- stopTime = templ->stopTime;
- if (!ignoreChannelSettings)
- useChannel = templ->useChannel;
- useCase = templ->useCase;
- mode = templ->mode;
- useTitle = templ->useTitle;
- useSubtitle = templ->useSubtitle;
- useDescription = templ->useDescription;
- useDuration = templ->useDuration;
- minDuration = templ->minDuration;
- maxDuration = templ->maxDuration;
- useAsSearchTimer = templ->useAsSearchTimer;
- useDayOfWeek = templ->useDayOfWeek;
- DayOfWeek = templ->DayOfWeek;
- useEpisode = templ->useEpisode;
- strcpy(directory, templ->directory);
- Priority = templ->Priority;
- Lifetime = templ->Lifetime;
- MarginStart = templ->MarginStart;
- MarginStop = templ->MarginStop;
- useVPS = templ->useVPS;
- action = templ->action;
- useExtEPGInfo = templ->useExtEPGInfo;
- contentsFilter = templ->contentsFilter;
- switchMinsBefore = templ->switchMinsBefore;
- pauseOnNrRecordings = templ->pauseOnNrRecordings;
-
- cSearchExtCat *SearchExtCat = SearchExtCats.First();
- int index = 0;
- while (SearchExtCat)
- {
- strcpy(catvalues[index], templ->catvalues[index]);
- SearchExtCat = SearchExtCats.Next(SearchExtCat);
- index++;
- }
-
- if (!ignoreChannelSettings)
- {
- channelMin = templ->channelMin;
- channelMax = templ->channelMax;
- if (channelGroup)
- {
- free(channelGroup);
- channelGroup = NULL;
- }
- if (templ->channelGroup)
- channelGroup = strdup(templ->channelGroup);
- }
- avoidRepeats = templ->avoidRepeats;
- compareTitle = templ->compareTitle;
- compareSubtitle = templ->compareSubtitle;
- compareSummary = templ->compareSummary;
- compareSummaryMatchInPercent = templ->compareSummaryMatchInPercent;
- compareDate = templ->compareDate;
- allowedRepeats = templ->allowedRepeats;
- catvaluesAvoidRepeat = templ->catvaluesAvoidRepeat;
- repeatsWithinDays = templ->repeatsWithinDays;
- delAfterDays = templ->delAfterDays;
- recordingsKeep = templ->recordingsKeep;
- blacklistMode = templ->blacklistMode;
- blacklists.Clear();
- const cBlacklistObject* blacklistObj = templ->blacklists.First();
- while(blacklistObj)
- {
- blacklists.Add(new cBlacklistObject(blacklistObj->blacklist));
- blacklistObj = templ->blacklists.Next(blacklistObj);
- }
- fuzzyTolerance = templ->fuzzyTolerance;
- useInFavorites = templ->useInFavorites;
- menuTemplate = templ->menuTemplate;
- delMode = templ->delMode;
- delAfterCountRecs = templ->delAfterCountRecs;
- delAfterDaysOfFirstRec = templ->delAfterDaysOfFirstRec;
- useAsSearchTimerFrom = templ->useAsSearchTimerFrom;
- useAsSearchTimerTil = templ->useAsSearchTimerTil;
- ignoreMissingEPGCats = templ->ignoreMissingEPGCats;
- unmuteSoundOnSwitch = templ->unmuteSoundOnSwitch;
+ options = templ->options;
+ useTime = templ->useTime;
+ startTime = templ->startTime;
+ stopTime = templ->stopTime;
+ if (!ignoreChannelSettings)
+ useChannel = templ->useChannel;
+ useCase = templ->useCase;
+ mode = templ->mode;
+ useTitle = templ->useTitle;
+ useSubtitle = templ->useSubtitle;
+ useDescription = templ->useDescription;
+ useDuration = templ->useDuration;
+ minDuration = templ->minDuration;
+ maxDuration = templ->maxDuration;
+ useAsSearchTimer = templ->useAsSearchTimer;
+ useDayOfWeek = templ->useDayOfWeek;
+ DayOfWeek = templ->DayOfWeek;
+ useEpisode = templ->useEpisode;
+ strcpy(directory, templ->directory);
+ Priority = templ->Priority;
+ Lifetime = templ->Lifetime;
+ MarginStart = templ->MarginStart;
+ MarginStop = templ->MarginStop;
+ useVPS = templ->useVPS;
+ action = templ->action;
+ useExtEPGInfo = templ->useExtEPGInfo;
+ contentsFilter = templ->contentsFilter;
+ switchMinsBefore = templ->switchMinsBefore;
+ pauseOnNrRecordings = templ->pauseOnNrRecordings;
+
+ cSearchExtCat *SearchExtCat = SearchExtCats.First();
+ int index = 0;
+ while (SearchExtCat) {
+ strcpy(catvalues[index], templ->catvalues[index]);
+ SearchExtCat = SearchExtCats.Next(SearchExtCat);
+ index++;
+ }
+
+ if (!ignoreChannelSettings) {
+ channelMin = templ->channelMin;
+ channelMax = templ->channelMax;
+ if (channelGroup) {
+ free(channelGroup);
+ channelGroup = NULL;
+ }
+ if (templ->channelGroup)
+ channelGroup = strdup(templ->channelGroup);
+ }
+ avoidRepeats = templ->avoidRepeats;
+ compareTitle = templ->compareTitle;
+ compareSubtitle = templ->compareSubtitle;
+ compareSummary = templ->compareSummary;
+ compareSummaryMatchInPercent = templ->compareSummaryMatchInPercent;
+ compareDate = templ->compareDate;
+ allowedRepeats = templ->allowedRepeats;
+ catvaluesAvoidRepeat = templ->catvaluesAvoidRepeat;
+ repeatsWithinDays = templ->repeatsWithinDays;
+ delAfterDays = templ->delAfterDays;
+ recordingsKeep = templ->recordingsKeep;
+ blacklistMode = templ->blacklistMode;
+ blacklists.Clear();
+ const cBlacklistObject* blacklistObj = templ->blacklists.First();
+ while (blacklistObj) {
+ blacklists.Add(new cBlacklistObject(blacklistObj->blacklist));
+ blacklistObj = templ->blacklists.Next(blacklistObj);
+ }
+ fuzzyTolerance = templ->fuzzyTolerance;
+ useInFavorites = templ->useInFavorites;
+ menuTemplate = templ->menuTemplate;
+ delMode = templ->delMode;
+ delAfterCountRecs = templ->delAfterCountRecs;
+ delAfterDaysOfFirstRec = templ->delAfterDaysOfFirstRec;
+ useAsSearchTimerFrom = templ->useAsSearchTimerFrom;
+ useAsSearchTimerTil = templ->useAsSearchTimerTil;
+ ignoreMissingEPGCats = templ->ignoreMissingEPGCats;
+ unmuteSoundOnSwitch = templ->unmuteSoundOnSwitch;
}
bool cSearchExt::operator< (const cListObject &ListObject)
{
- cSearchExt *SE = (cSearchExt *)&ListObject;
- return strcasecmp(search, SE->search) < 0;
+ cSearchExt *SE = (cSearchExt *)&ListObject;
+ return strcasecmp(search, SE->search) < 0;
}
char* replaceSpecialChars(const char* in)
{
- char* tmp_in = strdup(in);
- while(strstr(tmp_in, "|"))
- tmp_in = strreplace(tmp_in, "|", "!^pipe^!"); // ugly: replace a pipe with something,
- strreplace(tmp_in, ':', '|');
- return tmp_in;
+ char* tmp_in = strdup(in);
+ while (strstr(tmp_in, "|"))
+ tmp_in = strreplace(tmp_in, "|", "!^pipe^!"); // ugly: replace a pipe with something,
+ strreplace(tmp_in, ':', '|');
+ return tmp_in;
}
const char *cSearchExt::ToText()
{
- char tmp_Start[5] = "";
- char tmp_Stop[5] = "";
- char tmp_minDuration[5] = "";
- char tmp_maxDuration[5] = "";
- cString tmp_chanSel;
- char* tmp_catvalues = NULL;
- char* tmp_blacklists = NULL;
-
- free(buffer);
- char* tmp_search = replaceSpecialChars(search);
- char* tmp_directory = replaceSpecialChars(directory);
- char* tmp_contentsFilter = replaceSpecialChars(contentsFilter.c_str());
-
- if (useTime)
- {
- sprintf(tmp_Start, "%04d", startTime);
- sprintf(tmp_Stop, "%04d", stopTime);
- }
- if (useDuration)
- {
- sprintf(tmp_minDuration, "%04d", minDuration);
- sprintf(tmp_maxDuration, "%04d", maxDuration);
- }
-
- if (useChannel==1)
- {
- if (channelMin->Number() < channelMax->Number())
- tmp_chanSel = cString::sprintf("%s|%s", CHANNELSTRING(channelMin), CHANNELSTRING(channelMax));
- else
- tmp_chanSel = cString(CHANNELSTRING(channelMin));
- }
- if (useChannel==2)
- {
- int channelGroupNr = ChannelGroups.GetIndex(channelGroup);
- if (channelGroupNr == -1)
- {
- LogFile.eSysLog("channel group '%s' does not exist!", channelGroup);
- useChannel = 0;
- }
- else
- tmp_chanSel = cString(channelGroup);
- }
-
- if (useExtEPGInfo)
- {
- cSearchExtCat *SearchExtCat = SearchExtCats.First();
- int index = 0;
- while (SearchExtCat)
- {
- char* catvalue = NULL;
- if (msprintf(&catvalue, "%s", catvalues[index])==-1) break;
- while(strstr(catvalue, ":"))
- catvalue = strreplace(catvalue, ":", "!^colon^!"); // ugly: replace with something, that should not happen to be part ofa category value
- while(strstr(catvalue, "|"))
- catvalue = strreplace(catvalue, "|", "!^pipe^!"); // ugly: replace with something, that should not happen to be part of a regular expression
-
- if (index == 0)
- msprintf(&tmp_catvalues, "%d#%s", SearchExtCat->id, catvalue);
- else
- {
- char* temp = tmp_catvalues;
- msprintf(&tmp_catvalues, "%s|%d#%s", tmp_catvalues, SearchExtCat->id, catvalue);
- free(temp);
- }
- SearchExtCat = SearchExtCats.Next(SearchExtCat);
- index++;
- free(catvalue);
- }
- }
-
- if (blacklistMode == blacklistsSelection && blacklists.Count() > 0)
- {
- cBlacklistObject *blacklistObj = blacklists.First();
- int index = 0;
- while (blacklistObj)
- {
- if (index == 0)
- msprintf(&tmp_blacklists, "%d", blacklistObj->blacklist->ID);
- else
- {
- char* temp = tmp_blacklists;
- msprintf(&tmp_blacklists, "%s|%d", tmp_blacklists, blacklistObj->blacklist->ID);
- free(temp);
- }
- blacklistObj = blacklists.Next(blacklistObj);
- index++;
- }
- }
-
- msprintf(&buffer, "%d:%s:%d:%s:%s:%d:%s:%d:%d:%d:%d:%d:%d:%s:%s:%d:%d:%d:%d:%s:%d:%d:%d:%d:%d:%d:%d:%s:%d:%d:%d:%d:%d:%ld:%d:%d:%d:%d:%d:%d:%s:%d:%d:%d:%d:%d:%d:%ld:%ld:%d:%d:%d:%s:%d",
- ID,
- tmp_search,
- useTime,
- tmp_Start,
- tmp_Stop,
- useChannel,
- (useChannel>0 && useChannel<3)?*tmp_chanSel:"0",
- useCase,
- mode,
- useTitle,
- useSubtitle,
- useDescription,
- useDuration,
- tmp_minDuration,
- tmp_maxDuration,
- useAsSearchTimer,
- useDayOfWeek,
- DayOfWeek,
- useEpisode,
- tmp_directory,
- Priority,
- Lifetime,
- MarginStart,
- MarginStop,
- useVPS,
- action,
- useExtEPGInfo,
- useExtEPGInfo?tmp_catvalues:"",
- avoidRepeats,
- allowedRepeats,
- compareTitle,
- compareSubtitle,
- compareSummary,
- catvaluesAvoidRepeat,
- repeatsWithinDays,
- delAfterDays,
- recordingsKeep,
- switchMinsBefore,
- pauseOnNrRecordings,
- blacklistMode,
- blacklists.Count()>0?tmp_blacklists:"",
- fuzzyTolerance,
- useInFavorites,
- menuTemplate,
- delMode,
- delAfterCountRecs,
- delAfterDaysOfFirstRec,
- useAsSearchTimerFrom,
- useAsSearchTimerTil,
- ignoreMissingEPGCats,
- unmuteSoundOnSwitch,
- compareSummaryMatchInPercent,
- contentsFilter.c_str(),
- compareDate);
-
- if (tmp_search) free(tmp_search);
- if (tmp_directory) free(tmp_directory);
- if (tmp_catvalues) free(tmp_catvalues);
- if (tmp_blacklists) free(tmp_blacklists);
- if (tmp_contentsFilter) free(tmp_contentsFilter);
-
- return buffer;
+ char tmp_Start[5] = "";
+ char tmp_Stop[5] = "";
+ char tmp_minDuration[5] = "";
+ char tmp_maxDuration[5] = "";
+ cString tmp_chanSel;
+ char* tmp_catvalues = NULL;
+ char* tmp_blacklists = NULL;
+
+ free(buffer);
+ char* tmp_search = replaceSpecialChars(search);
+ char* tmp_directory = replaceSpecialChars(directory);
+ char* tmp_contentsFilter = replaceSpecialChars(contentsFilter.c_str());
+
+ if (useTime) {
+ sprintf(tmp_Start, "%04d", startTime);
+ sprintf(tmp_Stop, "%04d", stopTime);
+ }
+ if (useDuration) {
+ sprintf(tmp_minDuration, "%04d", minDuration);
+ sprintf(tmp_maxDuration, "%04d", maxDuration);
+ }
+
+ if (useChannel == 1) {
+ if (channelMin->Number() < channelMax->Number())
+ tmp_chanSel = cString::sprintf("%s|%s", CHANNELSTRING(channelMin), CHANNELSTRING(channelMax));
+ else
+ tmp_chanSel = cString(CHANNELSTRING(channelMin));
+ }
+ if (useChannel == 2) {
+ int channelGroupNr = ChannelGroups.GetIndex(channelGroup);
+ if (channelGroupNr == -1) {
+ LogFile.eSysLog("channel group '%s' does not exist!", channelGroup);
+ useChannel = 0;
+ } else
+ tmp_chanSel = cString(channelGroup);
+ }
+
+ if (useExtEPGInfo) {
+ cSearchExtCat *SearchExtCat = SearchExtCats.First();
+ int index = 0;
+ while (SearchExtCat) {
+ char* catvalue = NULL;
+ if (msprintf(&catvalue, "%s", catvalues[index]) == -1) break;
+ while (strstr(catvalue, ":"))
+ catvalue = strreplace(catvalue, ":", "!^colon^!"); // ugly: replace with something, that should not happen to be part ofa category value
+ while (strstr(catvalue, "|"))
+ catvalue = strreplace(catvalue, "|", "!^pipe^!"); // ugly: replace with something, that should not happen to be part of a regular expression
+
+ if (index == 0)
+ msprintf(&tmp_catvalues, "%d#%s", SearchExtCat->id, catvalue);
+ else {
+ char* temp = tmp_catvalues;
+ msprintf(&tmp_catvalues, "%s|%d#%s", tmp_catvalues, SearchExtCat->id, catvalue);
+ free(temp);
+ }
+ SearchExtCat = SearchExtCats.Next(SearchExtCat);
+ index++;
+ free(catvalue);
+ }
+ }
+
+ if (blacklistMode == blacklistsSelection && blacklists.Count() > 0) {
+ cBlacklistObject *blacklistObj = blacklists.First();
+ int index = 0;
+ while (blacklistObj) {
+ if (index == 0)
+ msprintf(&tmp_blacklists, "%d", blacklistObj->blacklist->ID);
+ else {
+ char* temp = tmp_blacklists;
+ msprintf(&tmp_blacklists, "%s|%d", tmp_blacklists, blacklistObj->blacklist->ID);
+ free(temp);
+ }
+ blacklistObj = blacklists.Next(blacklistObj);
+ index++;
+ }
+ }
+
+ msprintf(&buffer, "%d:%s:%d:%s:%s:%d:%s:%d:%d:%d:%d:%d:%d:%s:%s:%d:%d:%d:%d:%s:%d:%d:%d:%d:%d:%d:%d:%s:%d:%d:%d:%d:%d:%ld:%d:%d:%d:%d:%d:%d:%s:%d:%d:%d:%d:%d:%d:%ld:%ld:%d:%d:%d:%s:%d",
+ ID,
+ tmp_search,
+ useTime,
+ tmp_Start,
+ tmp_Stop,
+ useChannel,
+ (useChannel > 0 && useChannel < 3) ? *tmp_chanSel : "0",
+ useCase,
+ mode,
+ useTitle,
+ useSubtitle,
+ useDescription,
+ useDuration,
+ tmp_minDuration,
+ tmp_maxDuration,
+ useAsSearchTimer,
+ useDayOfWeek,
+ DayOfWeek,
+ useEpisode,
+ tmp_directory,
+ Priority,
+ Lifetime,
+ MarginStart,
+ MarginStop,
+ useVPS,
+ action,
+ useExtEPGInfo,
+ useExtEPGInfo ? tmp_catvalues : "",
+ avoidRepeats,
+ allowedRepeats,
+ compareTitle,
+ compareSubtitle,
+ compareSummary,
+ catvaluesAvoidRepeat,
+ repeatsWithinDays,
+ delAfterDays,
+ recordingsKeep,
+ switchMinsBefore,
+ pauseOnNrRecordings,
+ blacklistMode,
+ blacklists.Count() > 0 ? tmp_blacklists : "",
+ fuzzyTolerance,
+ useInFavorites,
+ menuTemplate,
+ delMode,
+ delAfterCountRecs,
+ delAfterDaysOfFirstRec,
+ useAsSearchTimerFrom,
+ useAsSearchTimerTil,
+ ignoreMissingEPGCats,
+ unmuteSoundOnSwitch,
+ compareSummaryMatchInPercent,
+ contentsFilter.c_str(),
+ compareDate);
+
+ if (tmp_search) free(tmp_search);
+ if (tmp_directory) free(tmp_directory);
+ if (tmp_catvalues) free(tmp_catvalues);
+ if (tmp_blacklists) free(tmp_blacklists);
+ if (tmp_contentsFilter) free(tmp_contentsFilter);
+
+ return buffer;
}
bool cSearchExt::Parse(const char *s)
{
- char *line;
- char *pos;
- char *pos_next;
- int parameter = 1;
- int valuelen;
- char value[MaxFileName];
- bool disableSearchtimer = false;
-
- *directory = 0;
- *search = 0;
-
- pos = line = strdup(s);
- pos_next = pos + strlen(pos);
- if (*pos_next == '\n') *pos_next = 0;
- while (*pos) {
- while (*pos == ' ') pos++;
- if (*pos) {
- if (*pos != ':') {
- pos_next = strchr(pos, ':');
- if (!pos_next)
- pos_next = pos + strlen(pos);
- valuelen = pos_next - pos + 1;
- if (valuelen > MaxFileName) valuelen = MaxFileName;
- strn0cpy(value, pos, valuelen);
- pos = pos_next;
- switch (parameter) {
- case 1:
- if (!isnumber(value)) return false;
- ID = atoi(value);
- break;
- case 2: strcpy(search, value);
- break;
- case 3: useTime = atoi(value);
- break;
- case 4: startTime = atoi(value);
- break;
- case 5: stopTime = atoi(value);
- break;
- case 6: useChannel = atoi(value);
- break;
- case 7:
- if (useChannel == 0)
- {
- channelMin = NULL;
- channelMax = NULL;
- }
- else if (useChannel == 1)
- {
- int minNum=0, maxNum=0;
- int fields = sscanf(value, "%d-%d", &minNum, &maxNum);
- if (fields == 0) // stored with ID
- {
+ char *line;
+ char *pos;
+ char *pos_next;
+ int parameter = 1;
+ int valuelen;
+ char value[MaxFileName];
+ bool disableSearchtimer = false;
+
+ *directory = 0;
+ *search = 0;
+
+ pos = line = strdup(s);
+ pos_next = pos + strlen(pos);
+ if (*pos_next == '\n') *pos_next = 0;
+ while (*pos) {
+ while (*pos == ' ') pos++;
+ if (*pos) {
+ if (*pos != ':') {
+ pos_next = strchr(pos, ':');
+ if (!pos_next)
+ pos_next = pos + strlen(pos);
+ valuelen = pos_next - pos + 1;
+ if (valuelen > MaxFileName) valuelen = MaxFileName;
+ strn0cpy(value, pos, valuelen);
+ pos = pos_next;
+ switch (parameter) {
+ case 1:
+ if (!isnumber(value)) return false;
+ ID = atoi(value);
+ break;
+ case 2:
+ strcpy(search, value);
+ break;
+ case 3:
+ useTime = atoi(value);
+ break;
+ case 4:
+ startTime = atoi(value);
+ break;
+ case 5:
+ stopTime = atoi(value);
+ break;
+ case 6:
+ useChannel = atoi(value);
+ break;
+ case 7:
+ if (useChannel == 0) {
+ channelMin = NULL;
+ channelMax = NULL;
+ } else if (useChannel == 1) {
+ int minNum = 0, maxNum = 0;
+ int fields = sscanf(value, "%d-%d", &minNum, &maxNum);
+ if (fields == 0) { // stored with ID
#ifdef __FreeBSD__
- char *channelMinbuffer = MALLOC(char, 32);
- char *channelMaxbuffer = MALLOC(char, 32);
- int channels = sscanf(value, "%31[^|]|%31[^|]", channelMinbuffer, channelMaxbuffer);
+ char *channelMinbuffer = MALLOC(char, 32);
+ char *channelMaxbuffer = MALLOC(char, 32);
+ int channels = sscanf(value, "%31[^|]|%31[^|]", channelMinbuffer, channelMaxbuffer);
#else
- char *channelMinbuffer = NULL;
- char *channelMaxbuffer = NULL;
- int channels = sscanf(value, "%m[^|]|%m[^|]", &channelMinbuffer, &channelMaxbuffer);
+ char *channelMinbuffer = NULL;
+ char *channelMaxbuffer = NULL;
+ int channels = sscanf(value, "%m[^|]|%m[^|]", &channelMinbuffer, &channelMaxbuffer);
#endif
- LOCK_CHANNELS_READ;
- channelMin = Channels->GetByChannelID(tChannelID::FromString(channelMinbuffer), true, true);
- if (!channelMin)
- {
- LogFile.eSysLog("ERROR: channel '%s' not defined", channelMinbuffer);
- channelMin = channelMax = NULL;
- disableSearchtimer = true;
- useChannel = 0;
- }
- if (channels == 1)
- channelMax = channelMin;
- else
- {
- channelMax = Channels->GetByChannelID(tChannelID::FromString(channelMaxbuffer), true, true);
- if (!channelMax)
- {
- LogFile.eSysLog("ERROR: channel '%s' not defined", channelMaxbuffer);
- channelMin = channelMax = NULL;
- disableSearchtimer = true;
- useChannel = 0;
- }
+ LOCK_CHANNELS_READ;
+ channelMin = Channels->GetByChannelID(tChannelID::FromString(channelMinbuffer), true, true);
+ if (!channelMin) {
+ LogFile.eSysLog("ERROR: channel '%s' not defined", channelMinbuffer);
+ channelMin = channelMax = NULL;
+ disableSearchtimer = true;
+ useChannel = 0;
+ }
+ if (channels == 1)
+ channelMax = channelMin;
+ else {
+ channelMax = Channels->GetByChannelID(tChannelID::FromString(channelMaxbuffer), true, true);
+ if (!channelMax) {
+ LogFile.eSysLog("ERROR: channel '%s' not defined", channelMaxbuffer);
+ channelMin = channelMax = NULL;
+ disableSearchtimer = true;
+ useChannel = 0;
+ }
+ }
+ free(channelMinbuffer);
+ free(channelMaxbuffer);
}
- free(channelMinbuffer);
- free(channelMaxbuffer);
- }
- }
- else if (useChannel == 2)
- channelGroup = strdup(value);
- break;
- case 8: useCase = atoi(value);
- break;
- case 9: mode = atoi(value);
- break;
- case 10: useTitle = atoi(value);
- break;
- case 11: useSubtitle = atoi(value);
- break;
- case 12: useDescription = atoi(value);
- break;
- case 13: useDuration = atoi(value);
- break;
- case 14: minDuration = atoi(value);
- break;
- case 15: maxDuration = atoi(value);
- break;
- case 16: useAsSearchTimer = atoi(value);
- break;
- case 17: useDayOfWeek = atoi(value);
- break;
- case 18: DayOfWeek = atoi(value);
- break;
- case 19: useEpisode = atoi(value);
- break;
- case 20: strcpy(directory, value);
- break;
- case 21: Priority = atoi(value);
- break;
- case 22: Lifetime = atoi(value);
- break;
- case 23: MarginStart = atoi(value);
- break;
- case 24: MarginStop = atoi(value);
- break;
- case 25: useVPS = atoi(value);
- break;
- case 26: action = atoi(value);
- break;
- case 27: useExtEPGInfo = atoi(value);
- break;
- case 28:
- if (!ParseExtEPGValues(value))
- {
- LogFile.eSysLog("ERROR reading ext. EPG values - 1");
- free(line);
- return false;
- }
- break;
- case 29: avoidRepeats = atoi(value);
- break;
- case 30: allowedRepeats = atoi(value);
- break;
- case 31: compareTitle = atoi(value);
- break;
- case 32: compareSubtitle = atoi(value)>0?1:0;
- break;
- case 33: compareSummary = atoi(value);
- break;
- case 34: catvaluesAvoidRepeat = atol(value);
- break;
- case 35: repeatsWithinDays = atoi(value);
- break;
- case 36: delAfterDays = atoi(value);
- break;
- case 37: recordingsKeep = atoi(value);
- break;
- case 38: switchMinsBefore = atoi(value);
- break;
- case 39: pauseOnNrRecordings = atoi(value);
- break;
- case 40: blacklistMode = atoi(value);
- break;
- case 41:
- if (blacklistMode == blacklistsSelection && !ParseBlacklistIDs(value))
- {
- LogFile.eSysLog("ERROR parsing blacklist IDs");
- free(line);
- return false;
- }
- break;
- case 42: fuzzyTolerance = atoi(value);
- break;
- case 43: useInFavorites = atoi(value);
- break;
- case 44: menuTemplate = atoi(value);
- break;
- case 45: delMode = atoi(value);
- break;
- case 46: delAfterCountRecs = atoi(value);
- break;
- case 47: delAfterDaysOfFirstRec = atoi(value);
- break;
- case 48:
- useAsSearchTimerFrom = atol(value);
- break;
- case 49:
- useAsSearchTimerTil = atol(value);
- break;
- case 50:
- ignoreMissingEPGCats = atoi(value);
- break;
- case 51:
- unmuteSoundOnSwitch = atoi(value);
- break;
- case 52:
- compareSummaryMatchInPercent = atoi(value);
- break;
- case 53:
- contentsFilter = value;
- break;
- case 54:
- compareDate = atoi(value);
- break;
- default:
- break;
- } //switch
- }
- parameter++;
- }
- if (*pos) pos++;
- } //while
-
- strreplace(directory, '|', ':');
- strreplace(search, '|', ':');
- strreplace(contentsFilter, "|", ":");
-
- while(strstr(search, "!^pipe^!"))
- strreplace(search, "!^pipe^!", "|");
- while(strstr(directory, "!^pipe^!"))
- strreplace(directory, "!^pipe^!", "|");
- strreplace(contentsFilter, "!^pipe^!", "|");
-
- if (disableSearchtimer && useAsSearchTimer)
- {
- useAsSearchTimer = false;
- LogFile.Log(1, "search timer '%s' disabled", search);
- }
-
- free(line);
- return (parameter >= 11) ? true : false;
+ } else if (useChannel == 2)
+ channelGroup = strdup(value);
+ break;
+ case 8:
+ useCase = atoi(value);
+ break;
+ case 9:
+ mode = atoi(value);
+ break;
+ case 10:
+ useTitle = atoi(value);
+ break;
+ case 11:
+ useSubtitle = atoi(value);
+ break;
+ case 12:
+ useDescription = atoi(value);
+ break;
+ case 13:
+ useDuration = atoi(value);
+ break;
+ case 14:
+ minDuration = atoi(value);
+ break;
+ case 15:
+ maxDuration = atoi(value);
+ break;
+ case 16:
+ useAsSearchTimer = atoi(value);
+ break;
+ case 17:
+ useDayOfWeek = atoi(value);
+ break;
+ case 18:
+ DayOfWeek = atoi(value);
+ break;
+ case 19:
+ useEpisode = atoi(value);
+ break;
+ case 20:
+ strcpy(directory, value);
+ break;
+ case 21:
+ Priority = atoi(value);
+ break;
+ case 22:
+ Lifetime = atoi(value);
+ break;
+ case 23:
+ MarginStart = atoi(value);
+ break;
+ case 24:
+ MarginStop = atoi(value);
+ break;
+ case 25:
+ useVPS = atoi(value);
+ break;
+ case 26:
+ action = atoi(value);
+ break;
+ case 27:
+ useExtEPGInfo = atoi(value);
+ break;
+ case 28:
+ if (!ParseExtEPGValues(value)) {
+ LogFile.eSysLog("ERROR reading ext. EPG values - 1");
+ free(line);
+ return false;
+ }
+ break;
+ case 29:
+ avoidRepeats = atoi(value);
+ break;
+ case 30:
+ allowedRepeats = atoi(value);
+ break;
+ case 31:
+ compareTitle = atoi(value);
+ break;
+ case 32:
+ compareSubtitle = atoi(value) > 0 ? 1 : 0;
+ break;
+ case 33:
+ compareSummary = atoi(value);
+ break;
+ case 34:
+ catvaluesAvoidRepeat = atol(value);
+ break;
+ case 35:
+ repeatsWithinDays = atoi(value);
+ break;
+ case 36:
+ delAfterDays = atoi(value);
+ break;
+ case 37:
+ recordingsKeep = atoi(value);
+ break;
+ case 38:
+ switchMinsBefore = atoi(value);
+ break;
+ case 39:
+ pauseOnNrRecordings = atoi(value);
+ break;
+ case 40:
+ blacklistMode = atoi(value);
+ break;
+ case 41:
+ if (blacklistMode == blacklistsSelection && !ParseBlacklistIDs(value)) {
+ LogFile.eSysLog("ERROR parsing blacklist IDs");
+ free(line);
+ return false;
+ }
+ break;
+ case 42:
+ fuzzyTolerance = atoi(value);
+ break;
+ case 43:
+ useInFavorites = atoi(value);
+ break;
+ case 44:
+ menuTemplate = atoi(value);
+ break;
+ case 45:
+ delMode = atoi(value);
+ break;
+ case 46:
+ delAfterCountRecs = atoi(value);
+ break;
+ case 47:
+ delAfterDaysOfFirstRec = atoi(value);
+ break;
+ case 48:
+ useAsSearchTimerFrom = atol(value);
+ break;
+ case 49:
+ useAsSearchTimerTil = atol(value);
+ break;
+ case 50:
+ ignoreMissingEPGCats = atoi(value);
+ break;
+ case 51:
+ unmuteSoundOnSwitch = atoi(value);
+ break;
+ case 52:
+ compareSummaryMatchInPercent = atoi(value);
+ break;
+ case 53:
+ contentsFilter = value;
+ break;
+ case 54:
+ compareDate = atoi(value);
+ break;
+ default:
+ break;
+ } //switch
+ }
+ parameter++;
+ }
+ if (*pos) pos++;
+ } //while
+
+ strreplace(directory, '|', ':');
+ strreplace(search, '|', ':');
+ strreplace(contentsFilter, "|", ":");
+
+ while (strstr(search, "!^pipe^!"))
+ strreplace(search, "!^pipe^!", "|");
+ while (strstr(directory, "!^pipe^!"))
+ strreplace(directory, "!^pipe^!", "|");
+ strreplace(contentsFilter, "!^pipe^!", "|");
+
+ if (disableSearchtimer && useAsSearchTimer) {
+ useAsSearchTimer = false;
+ LogFile.Log(1, "search timer '%s' disabled", search);
+ }
+
+ free(line);
+ return (parameter >= 11) ? true : false;
}
char* cSearchExt::BuildFile(const cEvent* pEvent) const
{
- char* file = NULL;
-
- if (!pEvent)
- return file;
-
- const char *Subtitle = pEvent ? pEvent->ShortText() : NULL;
- char SubtitleBuffer[Utf8BufSize(MAX_SUBTITLE_LENGTH)];
- if (isempty(Subtitle))
- {
- time_t Start = pEvent->StartTime();
- struct tm tm_r;
- strftime(SubtitleBuffer, sizeof(SubtitleBuffer), "%Y.%m.%d-%R-%a", localtime_r(&Start, &tm_r));
- Subtitle = SubtitleBuffer;
- }
- else if (Utf8StrLen(Subtitle) > MAX_SUBTITLE_LENGTH)
- {
- Utf8Strn0Cpy(SubtitleBuffer, Subtitle, sizeof(SubtitleBuffer));
- SubtitleBuffer[Utf8SymChars(SubtitleBuffer, MAX_SUBTITLE_LENGTH)] = 0;
- Subtitle = SubtitleBuffer;
- }
-
- if (useEpisode)
- {
- cString pFile = cString::sprintf("%s~%s", pEvent->Title(), Subtitle);
- if (file) free(file);
- file = strdup(pFile);
- }
- else if (pEvent->Title())
- file = strdup(pEvent->Title());
-
- if (!isempty(directory))
- {
- char* pFile = NULL;
-
- cVarExpr varExprDir(directory);
- if (!varExprDir.DependsOnVar("%title%", pEvent) && !varExprDir.DependsOnVar("%subtitle%", pEvent))
- msprintf(&pFile, "%s~%s", directory, file?file:"");
- else
- // ignore existing title and subtitle in file if already used as variables in directory
- msprintf(&pFile, "%s", directory);
-
- // parse the epxression and evaluate it
- cVarExpr varExprFile(pFile);
- if (pFile) free(pFile);
- pFile = strdup(varExprFile.Evaluate(pEvent).c_str());
-
- cVarExpr varExprSearchFile(pFile);
- if (pFile) free(pFile);
- pFile = strdup(varExprSearchFile.Evaluate(this).c_str());
-
- if (file) free(file);
- file = strdup(pFile);
- free(pFile);
- }
+ char* file = NULL;
+
+ if (!pEvent)
+ return file;
+
+ const char *Subtitle = pEvent ? pEvent->ShortText() : NULL;
+ char SubtitleBuffer[Utf8BufSize(MAX_SUBTITLE_LENGTH)];
+ if (isempty(Subtitle)) {
+ time_t Start = pEvent->StartTime();
+ struct tm tm_r;
+ strftime(SubtitleBuffer, sizeof(SubtitleBuffer), "%Y.%m.%d-%R-%a", localtime_r(&Start, &tm_r));
+ Subtitle = SubtitleBuffer;
+ } else if (Utf8StrLen(Subtitle) > MAX_SUBTITLE_LENGTH) {
+ Utf8Strn0Cpy(SubtitleBuffer, Subtitle, sizeof(SubtitleBuffer));
+ SubtitleBuffer[Utf8SymChars(SubtitleBuffer, MAX_SUBTITLE_LENGTH)] = 0;
+ Subtitle = SubtitleBuffer;
+ }
+
+ if (useEpisode) {
+ cString pFile = cString::sprintf("%s~%s", pEvent->Title(), Subtitle);
+ if (file) free(file);
+ file = strdup(pFile);
+ } else if (pEvent->Title())
+ file = strdup(pEvent->Title());
+
+ if (!isempty(directory)) {
+ char* pFile = NULL;
+
+ cVarExpr varExprDir(directory);
+ if (!varExprDir.DependsOnVar("%title%", pEvent) && !varExprDir.DependsOnVar("%subtitle%", pEvent))
+ msprintf(&pFile, "%s~%s", directory, file ? file : "");
+ else
+ // ignore existing title and subtitle in file if already used as variables in directory
+ msprintf(&pFile, "%s", directory);
+
+ // parse the epxression and evaluate it
+ cVarExpr varExprFile(pFile);
+ if (pFile) free(pFile);
+ pFile = strdup(varExprFile.Evaluate(pEvent).c_str());
+
+ cVarExpr varExprSearchFile(pFile);
+ if (pFile) free(pFile);
+ pFile = strdup(varExprSearchFile.Evaluate(this).c_str());
+
+ if (file) free(file);
+ file = strdup(pFile);
+ free(pFile);
+ }
// replace some special chars
- if (file)
- {
- while(strstr(file, "|")) file = strreplace(file, "|", "!^pipe^!");
- while(strstr(file, ":")) file = strreplace(file, ':', '|');
- while(strstr(file, " ~")) file = strreplace(file, " ~", "~");
- while(strstr(file, "~ ")) file = strreplace(file, "~ ", "~");
- }
- return file;
+ if (file) {
+ while (strstr(file, "|")) file = strreplace(file, "|", "!^pipe^!");
+ while (strstr(file, ":")) file = strreplace(file, ':', '|');
+ while (strstr(file, " ~")) file = strreplace(file, " ~", "~");
+ while (strstr(file, "~ ")) file = strreplace(file, "~ ", "~");
+ }
+ return file;
}
bool cSearchExt::ParseBlacklistIDs(const char *s)
{
- char *line;
- char *pos;
- char *pos_next;
- int valuelen;
- char value[MaxFileName];
-
- cMutexLock BlacklistLock(&Blacklists);
- blacklists.Clear();
-
- pos = line = strdup(s);
- pos_next = pos + strlen(pos);
- if (*pos_next == '\n') *pos_next = 0;
- while (*pos) {
- while (*pos == ' ') pos++;
- if (*pos) {
- if (*pos != '|') {
- pos_next = strchr(pos, '|');
- if (!pos_next)
- pos_next = pos + strlen(pos);
- valuelen = pos_next - pos + 1;
- if (valuelen > MaxFileName) valuelen = MaxFileName;
- strn0cpy(value, pos, valuelen);
- pos = pos_next;
- cBlacklist* blacklist = Blacklists.GetBlacklistFromID(atoi(value));
- if (!blacklist)
- LogFile.eSysLog("blacklist ID %s missing, will be skipped", value);
- else
- blacklists.Add(new cBlacklistObject(blacklist));
- }
- }
- if (*pos) pos++;
- } //while
-
- free(line);
- return true;
+ char *line;
+ char *pos;
+ char *pos_next;
+ int valuelen;
+ char value[MaxFileName];
+
+ cMutexLock BlacklistLock(&Blacklists);
+ blacklists.Clear();
+
+ pos = line = strdup(s);
+ pos_next = pos + strlen(pos);
+ if (*pos_next == '\n') *pos_next = 0;
+ while (*pos) {
+ while (*pos == ' ') pos++;
+ if (*pos) {
+ if (*pos != '|') {
+ pos_next = strchr(pos, '|');
+ if (!pos_next)
+ pos_next = pos + strlen(pos);
+ valuelen = pos_next - pos + 1;
+ if (valuelen > MaxFileName) valuelen = MaxFileName;
+ strn0cpy(value, pos, valuelen);
+ pos = pos_next;
+ cBlacklist* blacklist = Blacklists.GetBlacklistFromID(atoi(value));
+ if (!blacklist)
+ LogFile.eSysLog("blacklist ID %s missing, will be skipped", value);
+ else
+ blacklists.Add(new cBlacklistObject(blacklist));
+ }
+ }
+ if (*pos) pos++;
+ } //while
+
+ free(line);
+ return true;
}
bool cSearchExt::ParseExtEPGValues(const char *s)
{
- char *line;
- char *pos;
- char *pos_next;
- int valuelen;
- char value[MaxFileName];
-
- pos = line = strdup(s);
- pos_next = pos + strlen(pos);
- if (*pos_next == '\n') *pos_next = 0;
- while (*pos) {
- while (*pos == ' ') pos++;
- if (*pos) {
- if (*pos != '|') {
- pos_next = strchr(pos, '|');
- if (!pos_next)
- pos_next = pos + strlen(pos);
- valuelen = pos_next - pos + 1;
- if (valuelen > MaxFileName) valuelen = MaxFileName;
- strn0cpy(value, pos, valuelen);
- pos = pos_next;
- if (!ParseExtEPGEntry(value))
- {
- LogFile.eSysLog("ERROR reading ext. EPG value: %s", value);
- free(line);
- return false;
+ char *line;
+ char *pos;
+ char *pos_next;
+ int valuelen;
+ char value[MaxFileName];
+
+ pos = line = strdup(s);
+ pos_next = pos + strlen(pos);
+ if (*pos_next == '\n') *pos_next = 0;
+ while (*pos) {
+ while (*pos == ' ') pos++;
+ if (*pos) {
+ if (*pos != '|') {
+ pos_next = strchr(pos, '|');
+ if (!pos_next)
+ pos_next = pos + strlen(pos);
+ valuelen = pos_next - pos + 1;
+ if (valuelen > MaxFileName) valuelen = MaxFileName;
+ strn0cpy(value, pos, valuelen);
+ pos = pos_next;
+ if (!ParseExtEPGEntry(value)) {
+ LogFile.eSysLog("ERROR reading ext. EPG value: %s", value);
+ free(line);
+ return false;
+ }
}
- }
- }
- if (*pos) pos++;
- } //while
+ }
+ if (*pos) pos++;
+ } //while
- free(line);
- return true;
+ free(line);
+ return true;
}
bool cSearchExt::ParseExtEPGEntry(const char *s)
{
- char *line;
- char *pos;
- char *pos_next;
- int parameter = 1;
- int valuelen;
- char value[MaxFileName];
- int currentid = -1;
-
- pos = line = strdup(s);
- pos_next = pos + strlen(pos);
- if (*pos_next == '\n') *pos_next = 0;
- while (*pos) {
- while (*pos == ' ') pos++;
- if (*pos) {
- if (*pos != '#') {
- pos_next = strchr(pos, '#');
- if (!pos_next)
- pos_next = pos + strlen(pos);
- valuelen = pos_next - pos + 1;
- if (valuelen > MaxFileName) valuelen = MaxFileName;
- strn0cpy(value, pos, valuelen);
- pos = pos_next;
- switch (parameter) {
- case 1:
- {
- currentid = atoi(value);
- int index = SearchExtCats.GetIndexFromID(currentid);
- if (index > -1 && index < SearchExtCats.Count())
- strcpy(catvalues[index], "");
- }
- break;
- case 2:
- if (currentid > -1)
- {
- int index = SearchExtCats.GetIndexFromID(currentid);
- if (index > -1 && index < SearchExtCats.Count())
- {
- while(strstr(value, "!^colon^!"))
- strreplace(value, "!^colon^!", ":");
- while(strstr(value, "!^pipe^!"))
- strreplace(value, "!^pipe^!", "|");
- strcpy(catvalues[index], value);
- }
- }
- break;
- default:
- break;
- } //switch
- }
- parameter++;
- }
- if (*pos) pos++;
- } //while
-
- free(line);
- return (parameter >= 2) ? true : false;
+ char *line;
+ char *pos;
+ char *pos_next;
+ int parameter = 1;
+ int valuelen;
+ char value[MaxFileName];
+ int currentid = -1;
+
+ pos = line = strdup(s);
+ pos_next = pos + strlen(pos);
+ if (*pos_next == '\n') *pos_next = 0;
+ while (*pos) {
+ while (*pos == ' ') pos++;
+ if (*pos) {
+ if (*pos != '#') {
+ pos_next = strchr(pos, '#');
+ if (!pos_next)
+ pos_next = pos + strlen(pos);
+ valuelen = pos_next - pos + 1;
+ if (valuelen > MaxFileName) valuelen = MaxFileName;
+ strn0cpy(value, pos, valuelen);
+ pos = pos_next;
+ switch (parameter) {
+ case 1: {
+ currentid = atoi(value);
+ int index = SearchExtCats.GetIndexFromID(currentid);
+ if (index > -1 && index < SearchExtCats.Count())
+ strcpy(catvalues[index], "");
+ }
+ break;
+ case 2:
+ if (currentid > -1) {
+ int index = SearchExtCats.GetIndexFromID(currentid);
+ if (index > -1 && index < SearchExtCats.Count()) {
+ while (strstr(value, "!^colon^!"))
+ strreplace(value, "!^colon^!", ":");
+ while (strstr(value, "!^pipe^!"))
+ strreplace(value, "!^pipe^!", "|");
+ strcpy(catvalues[index], value);
+ }
+ }
+ break;
+ default:
+ break;
+ } //switch
+ }
+ parameter++;
+ }
+ if (*pos) pos++;
+ } //while
+
+ free(line);
+ return (parameter >= 2) ? true : false;
}
bool cSearchExt::Save(FILE *f)
{
- return fprintf(f, "%s\n", ToText()) > 0;
+ return fprintf(f, "%s\n", ToText()) > 0;
}
const cEvent * cSearchExt::GetEventBySearchExt(const cSchedule *schedules, const cEvent *Start, bool inspectTimerMargin)
{
- if (!schedules) return NULL;
-
- const cEvent *pe = NULL;
- const cEvent *p1 = NULL;
-
- const cList<cEvent>* Events = schedules->Events();
- if (Start)
- p1 = Events->Next(Start);
- else
- p1 = Events->First();
-
- time_t tNow=time(NULL);
- char* searchText = strdup(search);
-
- int searchStart = 0, searchStop = 0;
- if (useTime)
- {
- searchStart = startTime;
- searchStop = stopTime;
- if (searchStop < searchStart)
- searchStop += 2400;
- }
- int minSearchDuration = 0;
- int maxSearchDuration = 0;
- if (useDuration)
- {
- minSearchDuration = minDuration/100*60 + minDuration%100;
- maxSearchDuration = maxDuration/100*60 + maxDuration%100;
- }
-
- if (!useCase)
- ToLower(searchText);
-
- for (const cEvent *p = p1; p; p = Events->Next(p))
- {
- if(!p)
- {
- break;
- }
-
- if (skipRunningEvents && tNow > p->StartTime())
- continue;
-
- // ignore events without title
- if (!p->Title() || !*p->Title())
- continue;
-
- if (tNow < p->EndTime() + (inspectTimerMargin?(MarginStop * 60):0))
- {
- if (useTime)
- {
- time_t tEvent = p->StartTime();
- struct tm tmEvent;
- localtime_r(&tEvent, &tmEvent);
-
- int eventStart = tmEvent.tm_hour*100 + tmEvent.tm_min;
- int eventStart2 = eventStart + 2400;
- if ((eventStart < searchStart || eventStart > searchStop) &&
- (eventStart2 < searchStart || eventStart2 > searchStop))
- continue;
-
- if (useDayOfWeek)
- {
- if (DayOfWeek >= 0)
- {
- if (( DayOfWeek != tmEvent.tm_wday || (DayOfWeek == tmEvent.tm_wday && eventStart < searchStart)) &&
- (!((DayOfWeek+1)%7 == tmEvent.tm_wday && eventStart2 < searchStop)))
- continue;
- }
- else
- {
- int iFound = 0;
- for(int i=0; i<7; i++)
- {
- if ((abs(DayOfWeek) & (int)pow(2,i)) && ((i == tmEvent.tm_wday && eventStart >= searchStart) ||
- ((i+1)%7 == tmEvent.tm_wday && eventStart2 < searchStop)))
- {
- iFound = 1;
- break;
- }
- }
- if (!iFound)
- continue;
- }
+ if (!schedules) return NULL;
+
+ const cEvent *pe = NULL;
+ const cEvent *p1 = NULL;
+
+ const cList<cEvent>* Events = schedules->Events();
+ if (Start)
+ p1 = Events->Next(Start);
+ else
+ p1 = Events->First();
+
+ time_t tNow = time(NULL);
+ char* searchText = strdup(search);
+
+ int searchStart = 0, searchStop = 0;
+ if (useTime) {
+ searchStart = startTime;
+ searchStop = stopTime;
+ if (searchStop < searchStart)
+ searchStop += 2400;
+ }
+ int minSearchDuration = 0;
+ int maxSearchDuration = 0;
+ if (useDuration) {
+ minSearchDuration = minDuration / 100 * 60 + minDuration % 100;
+ maxSearchDuration = maxDuration / 100 * 60 + maxDuration % 100;
+ }
+
+ if (!useCase)
+ ToLower(searchText);
+
+ for (const cEvent *p = p1; p; p = Events->Next(p)) {
+ if (!p) {
+ break;
+ }
+
+ if (skipRunningEvents && tNow > p->StartTime())
+ continue;
+
+ // ignore events without title
+ if (!p->Title() || !*p->Title())
+ continue;
+
+ if (tNow < p->EndTime() + (inspectTimerMargin ? (MarginStop * 60) : 0)) {
+ if (useTime) {
+ time_t tEvent = p->StartTime();
+ struct tm tmEvent;
+ localtime_r(&tEvent, &tmEvent);
+
+ int eventStart = tmEvent.tm_hour * 100 + tmEvent.tm_min;
+ int eventStart2 = eventStart + 2400;
+ if ((eventStart < searchStart || eventStart > searchStop) &&
+ (eventStart2 < searchStart || eventStart2 > searchStop))
+ continue;
+
+ if (useDayOfWeek) {
+ if (DayOfWeek >= 0) {
+ if ((DayOfWeek != tmEvent.tm_wday || (DayOfWeek == tmEvent.tm_wday && eventStart < searchStart)) &&
+ (!((DayOfWeek + 1) % 7 == tmEvent.tm_wday && eventStart2 < searchStop)))
+ continue;
+ } else {
+ int iFound = 0;
+ for (int i = 0; i < 7; i++) {
+ if ((abs(DayOfWeek) & (int)pow(2, i)) && ((i == tmEvent.tm_wday && eventStart >= searchStart) ||
+ ((i + 1) % 7 == tmEvent.tm_wday && eventStart2 < searchStop))) {
+ iFound = 1;
+ break;
+ }
+ }
+ if (!iFound)
+ continue;
+ }
+ }
}
- }
- if (useDuration)
- {
- int duration = p->Duration()/60;
- if (minSearchDuration > duration || maxSearchDuration < duration)
- continue;
- }
-
- if (!useTime && useDayOfWeek)
- {
- time_t tEvent = p->StartTime();
- struct tm tmEvent;
- localtime_r(&tEvent, &tmEvent);
- if (DayOfWeek >= 0 && DayOfWeek != tmEvent.tm_wday)
- continue;
- if (DayOfWeek < 0)
- {
- int iFound = 0;
- for(int i=0; i<7; i++)
- if (abs(DayOfWeek) & (int)pow(2,i) && i == tmEvent.tm_wday)
- {
- iFound = 1;
- break;
- }
- if (!iFound)
- continue;
+ if (useDuration) {
+ int duration = p->Duration() / 60;
+ if (minSearchDuration > duration || maxSearchDuration < duration)
+ continue;
}
- }
-
- char* szTest = NULL;
- msprintf(&szTest, "%s%s%s%s%s", (useTitle?(p->Title()?p->Title():""):""), (useSubtitle||useDescription)?"~":"",
- (useSubtitle?(p->ShortText()?p->ShortText():""):""),useDescription?"~":"",
- (useDescription?(p->Description()?p->Description():""):""));
-
- if (!useCase)
- ToLower(szTest);
-
- if (szTest && *szTest)
- {
- if (!MatchesSearchMode(szTest, searchText, mode," ,;|~", fuzzyTolerance))
- {
- free(szTest);
- continue;
- }
- }
- if (szTest)
- free(szTest);
-
- if (contentsFilter.size() > 0 && !MatchesContentsFilter(p))
- continue;
-
- if (useExtEPGInfo && !MatchesExtEPGInfo(p))
- continue;
- pe=p;
- break;
- }
- }
- free(searchText);
- return pe;
+
+ if (!useTime && useDayOfWeek) {
+ time_t tEvent = p->StartTime();
+ struct tm tmEvent;
+ localtime_r(&tEvent, &tmEvent);
+ if (DayOfWeek >= 0 && DayOfWeek != tmEvent.tm_wday)
+ continue;
+ if (DayOfWeek < 0) {
+ int iFound = 0;
+ for (int i = 0; i < 7; i++)
+ if (abs(DayOfWeek) & (int)pow(2, i) && i == tmEvent.tm_wday) {
+ iFound = 1;
+ break;
+ }
+ if (!iFound)
+ continue;
+ }
+ }
+
+ char* szTest = NULL;
+ msprintf(&szTest, "%s%s%s%s%s", (useTitle ? (p->Title() ? p->Title() : "") : ""), (useSubtitle || useDescription) ? "~" : "",
+ (useSubtitle ? (p->ShortText() ? p->ShortText() : "") : ""), useDescription ? "~" : "",
+ (useDescription ? (p->Description() ? p->Description() : "") : ""));
+
+ if (!useCase)
+ ToLower(szTest);
+
+ if (szTest && *szTest) {
+ if (!MatchesSearchMode(szTest, searchText, mode, " ,;|~", fuzzyTolerance)) {
+ free(szTest);
+ continue;
+ }
+ }
+ if (szTest)
+ free(szTest);
+
+ if (contentsFilter.size() > 0 && !MatchesContentsFilter(p))
+ continue;
+
+ if (useExtEPGInfo && !MatchesExtEPGInfo(p))
+ continue;
+ pe = p;
+ break;
+ }
+ }
+ free(searchText);
+ return pe;
}
// returns a pointer array to the matching search results
cSearchResults* cSearchExt::Run(int PayTVMode, bool inspectTimerMargin, int evalLimitMins, cSearchResults* pPrevResults, bool suppressRepeatCheck)
{
- LogFile.Log(3,"start search for search timer '%s'", search);
-
- bool noPayTV = false;
- if (PayTVMode == -1) // use search's setting
- noPayTV = (useChannel == 3);
- else
- noPayTV = (PayTVMode == 1);
-
- time_t tNow=time(NULL);
- cSearchResults* pSearchResults = pPrevResults;
- cSearchResults* pBlacklistResults = GetBlacklistEvents(inspectTimerMargin?MarginStop:0);
-
- {
- LOCK_CHANNELS_READ;
- LOCK_SCHEDULES_READ;
-
- int counter = 0;
- const cSchedule *Schedule = Schedules->First();
- while (Schedule) {
- const cChannel* channel = Channels->GetByChannelID(Schedule->ChannelID(),true,true);
- if (!channel)
- {
- Schedule = Schedules->Next(Schedule);
- continue;
- }
-
- if (useChannel == 1 && channelMin && channelMax)
- {
- if (channelMin->Number() > channel->Number() || channelMax->Number() < channel->Number())
- {
- Schedule = Schedules->Next(Schedule);
- continue;
- }
- }
- if (useChannel == 2 && channelGroup)
- {
- cChannelGroup* group = ChannelGroups.GetGroupByName(channelGroup);
- if (!group || !group->ChannelInGroup(channel))
- {
- Schedule = Schedules->Next(Schedule);
- continue;
- }
- }
+ LogFile.Log(3, "start search for search timer '%s'", search);
- if (useChannel == 3 && noPayTV)
- {
- if (channel->Ca() >= CA_ENCRYPTED_MIN)
- {
- Schedule = Schedules->Next(Schedule);
- continue;
- }
- }
+ bool noPayTV = false;
+ if (PayTVMode == -1) // use search's setting
+ noPayTV = (useChannel == 3);
+ else
+ noPayTV = (PayTVMode == 1);
- if (noPayTV) // no paytv
- {
- if (channel->Ca() >= CA_ENCRYPTED_MIN)
- {
- Schedule = Schedules->Next(Schedule);
- continue;
- }
- }
-
- const cEvent *pPrevEvent = NULL;
- do {
- const cEvent* event = GetEventBySearchExt(Schedule, pPrevEvent,inspectTimerMargin);
- pPrevEvent = event;
- if (evalLimitMins && event) // limit evaluation to now + limit
- {
- if (tNow + evalLimitMins*60 <= event->EndTime())
- break;
- }
- if (event && Channels->GetByChannelID(event->ChannelID(),true,true))
- {
- if (pBlacklistResults && pBlacklistResults->Lookup(event))
- {
- LogFile.Log(3,"skip '%s~%s' (%s - %s, channel %d): matches blacklist", event->Title()?event->Title():"no title", event->ShortText()?event->ShortText():"no subtitle", GETDATESTRING(event), GETTIMESTRING(event), ChannelNrFromEvent(event));
- continue;
+ time_t tNow = time(NULL);
+ cSearchResults* pSearchResults = pPrevResults;
+ cSearchResults* pBlacklistResults = GetBlacklistEvents(inspectTimerMargin ? MarginStop : 0);
+
+ {
+ LOCK_CHANNELS_READ;
+ LOCK_SCHEDULES_READ;
+
+ int counter = 0;
+ const cSchedule *Schedule = Schedules->First();
+ while (Schedule) {
+ const cChannel* channel = Channels->GetByChannelID(Schedule->ChannelID(), true, true);
+ if (!channel) {
+ Schedule = Schedules->Next(Schedule);
+ continue;
+ }
+
+ if (useChannel == 1 && channelMin && channelMax) {
+ if (channelMin->Number() > channel->Number() || channelMax->Number() < channel->Number()) {
+ Schedule = Schedules->Next(Schedule);
+ continue;
+ }
+ }
+ if (useChannel == 2 && channelGroup) {
+ cChannelGroup* group = ChannelGroups.GetGroupByName(channelGroup);
+ if (!group || !group->ChannelInGroup(channel)) {
+ Schedule = Schedules->Next(Schedule);
+ continue;
+ }
}
- if (!pSearchResults) pSearchResults = new cSearchResults;
- pSearchResults->Add(new cSearchResult(event, this));
- counter++;
- }
- } while(pPrevEvent);
- Schedule = Schedules->Next(Schedule);
- }
- LogFile.Log(3,"found %d event(s) for search timer '%s'", counter, search);
- } // Give up locks
-
- if (pBlacklistResults) delete pBlacklistResults;
-
- if (useAsSearchTimer && avoidRepeats && pSearchResults && !suppressRepeatCheck)
- {
- pSearchResults->SortBy(CompareEventTime); // sort before checking repeats to make sure the first event is selected
- CheckRepeatTimers(pSearchResults);
- }
-
- skipRunningEvents = false;
- return pSearchResults;
+
+ if (useChannel == 3 && noPayTV) {
+ if (channel->Ca() >= CA_ENCRYPTED_MIN) {
+ Schedule = Schedules->Next(Schedule);
+ continue;
+ }
+ }
+
+ if (noPayTV) { // no paytv
+ if (channel->Ca() >= CA_ENCRYPTED_MIN) {
+ Schedule = Schedules->Next(Schedule);
+ continue;
+ }
+ }
+
+ const cEvent *pPrevEvent = NULL;
+ do {
+ const cEvent* event = GetEventBySearchExt(Schedule, pPrevEvent, inspectTimerMargin);
+ pPrevEvent = event;
+ if (evalLimitMins && event) { // limit evaluation to now + limit
+ if (tNow + evalLimitMins * 60 <= event->EndTime())
+ break;
+ }
+ if (event && Channels->GetByChannelID(event->ChannelID(), true, true)) {
+ if (pBlacklistResults && pBlacklistResults->Lookup(event)) {
+ LogFile.Log(3, "skip '%s~%s' (%s - %s, channel %d): matches blacklist", event->Title() ? event->Title() : "no title", event->ShortText() ? event->ShortText() : "no subtitle", GETDATESTRING(event), GETTIMESTRING(event), ChannelNrFromEvent(event));
+ continue;
+ }
+ if (!pSearchResults) pSearchResults = new cSearchResults;
+ pSearchResults->Add(new cSearchResult(event, this));
+ counter++;
+ }
+ } while (pPrevEvent);
+ Schedule = Schedules->Next(Schedule);
+ }
+ LogFile.Log(3, "found %d event(s) for search timer '%s'", counter, search);
+ } // Give up locks
+
+ if (pBlacklistResults) delete pBlacklistResults;
+
+ if (useAsSearchTimer && avoidRepeats && pSearchResults && !suppressRepeatCheck) {
+ pSearchResults->SortBy(CompareEventTime); // sort before checking repeats to make sure the first event is selected
+ CheckRepeatTimers(pSearchResults);
+ }
+
+ skipRunningEvents = false;
+ return pSearchResults;
}
cSearchResults* cSearchExt::GetBlacklistEvents(int MarginStop)
{
- if (blacklistMode == blacklistsNone) return NULL;
-
- cMutexLock BlacklistLock(&Blacklists);
- cSearchResults* blacklistEvents = NULL;
- if (blacklistMode == blacklistsOnlyGlobal)
- {
- cBlacklist* tmpblacklist = Blacklists.First();
- while(tmpblacklist)
- {
- if (tmpblacklist->isGlobal)
- blacklistEvents = tmpblacklist->Run(blacklistEvents, MarginStop);
- tmpblacklist = Blacklists.Next(tmpblacklist);
- }
- }
- if (blacklistMode == blacklistsAll)
- {
- cBlacklist* tmpblacklist = Blacklists.First();
- while(tmpblacklist)
- {
- blacklistEvents = tmpblacklist->Run(blacklistEvents, MarginStop);
- tmpblacklist = Blacklists.Next(tmpblacklist);
- }
- }
- if (blacklistMode == blacklistsSelection)
- {
- cBlacklistObject* tmpblacklistObj = blacklists.First();
- while(tmpblacklistObj)
- {
- blacklistEvents = tmpblacklistObj->blacklist->Run(blacklistEvents, MarginStop);
- tmpblacklistObj = blacklists.Next(tmpblacklistObj);
- }
- }
- return blacklistEvents;
+ if (blacklistMode == blacklistsNone) return NULL;
+
+ cMutexLock BlacklistLock(&Blacklists);
+ cSearchResults* blacklistEvents = NULL;
+ if (blacklistMode == blacklistsOnlyGlobal) {
+ cBlacklist* tmpblacklist = Blacklists.First();
+ while (tmpblacklist) {
+ if (tmpblacklist->isGlobal)
+ blacklistEvents = tmpblacklist->Run(blacklistEvents, MarginStop);
+ tmpblacklist = Blacklists.Next(tmpblacklist);
+ }
+ }
+ if (blacklistMode == blacklistsAll) {
+ cBlacklist* tmpblacklist = Blacklists.First();
+ while (tmpblacklist) {
+ blacklistEvents = tmpblacklist->Run(blacklistEvents, MarginStop);
+ tmpblacklist = Blacklists.Next(tmpblacklist);
+ }
+ }
+ if (blacklistMode == blacklistsSelection) {
+ cBlacklistObject* tmpblacklistObj = blacklists.First();
+ while (tmpblacklistObj) {
+ blacklistEvents = tmpblacklistObj->blacklist->Run(blacklistEvents, MarginStop);
+ tmpblacklistObj = blacklists.Next(tmpblacklistObj);
+ }
+ }
+ return blacklistEvents;
}
void cSearchExt::CheckRepeatTimers(cSearchResults* pResults)
{
- if (!pResults)
- return;
- if (avoidRepeats == 0)
- return;
-
- LogFile.Log(2,"analysing repeats for search timer '%s'...", search);
- if ((action != searchTimerActionRecord) && (action != searchTimerActionInactiveRecord))
- {
- LogFile.Log(3,"search timer not set to 'record', so skip all");
- return;
- }
-
- cSearchResult* pResultObj = NULL;
- for (pResultObj = pResults->First(); pResultObj; pResultObj = pResults->Next(pResultObj))
- {
- if ((action != searchTimerActionRecord) && (action != searchTimerActionInactiveRecord)) // only announce if there is no timer for the event
- {
- pResultObj->needsTimer = false;
- continue;
- }
-
- const cEvent* pEvent = pResultObj->event;
- // check if this event was already recorded
- int records = 0;
- cRecDone* firstRec = NULL;
- LogFile.Log(3,"get count recordings with %d%% match", compareSummaryMatchInPercent);
- records = RecsDone.GetCountRecordings(pEvent, this, &firstRec, compareSummaryMatchInPercent);
- LogFile.Log(3,"recordings: %d", records);
-
- if (records > allowedRepeats) // already recorded
- {
- LogFile.Log(3,"skip '%s~%s' (%s - %s, channel %d): already recorded %d equal event(s)", pEvent->Title()?pEvent->Title():"no title", pEvent->ShortText()?pEvent->ShortText():"no subtitle", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), ChannelNrFromEvent(pEvent), records);
- pResultObj->needsTimer = false; // first assume we need no timer
- continue;
- }
-
- int plannedTimers = 0;
- LogFile.Log(3,"get planned recordings");
- cSearchResult* pFirstResultMatching = NULL;
- // check other results, if they are already planned for equal events
- for (cSearchResult* pResultObjP = pResults->First(); pResultObjP; pResultObjP = pResults->Next(pResultObjP))
- {
- if (pResultObj == pResultObjP) break;
-
- const cEvent* pEventP = pResultObjP->event;
- if (!pEventP) continue;
-
- if (!pResultObjP->needsTimer) continue;
-
- if (EventsMatch(pEvent, pEventP, compareTitle, compareSubtitle, compareSummary, compareDate, catvaluesAvoidRepeat, compareSummaryMatchInPercent))
- {
- if (!pFirstResultMatching) pFirstResultMatching = pResultObjP;
- plannedTimers++;
- }
- }
- LogFile.Log(3,"planned: %d", plannedTimers);
-
- if (plannedTimers + records > allowedRepeats)
- {
- LogFile.Log(3,"skip '%s~%s' (%s - %s, channel %d): events planned(%d), recorded(%d), allowed(%d)", pEvent->Title()?pEvent->Title():"no title", pEvent->ShortText()?pEvent->ShortText():"no subtitle", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), ChannelNrFromEvent(pEvent), plannedTimers, records, allowedRepeats);
- pResultObj->needsTimer = false;
- continue;
- }
- else if (allowedRepeats > 0 && repeatsWithinDays > 0) // if we only allow repeats with in a given range
- {
- if (firstRec) // already recorded, check for allowed repeat within days
- {
- if (firstRec->startTime > pEvent->StartTime() - pEvent->Duration()) // no repeat
- {
- LogFile.Log(3,"skip '%s~%s' (%s - %s, channel %d); no repeat for event already recorded at %s, channel %d", pEvent->Title()?pEvent->Title():"no title", pEvent->ShortText()?pEvent->ShortText():"no subtitle", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), ChannelNrFromEvent(pEvent), DAYDATETIME(firstRec->startTime), firstRec->ChannelNr());
- pResultObj->needsTimer = false;
- continue;
+ if (!pResults)
+ return;
+ if (avoidRepeats == 0)
+ return;
+
+ LogFile.Log(2, "analysing repeats for search timer '%s'...", search);
+ if ((action != searchTimerActionRecord) && (action != searchTimerActionInactiveRecord)) {
+ LogFile.Log(3, "search timer not set to 'record', so skip all");
+ return;
+ }
+
+ cSearchResult* pResultObj = NULL;
+ for (pResultObj = pResults->First(); pResultObj; pResultObj = pResults->Next(pResultObj)) {
+ if ((action != searchTimerActionRecord) && (action != searchTimerActionInactiveRecord)) { // only announce if there is no timer for the event
+ pResultObj->needsTimer = false;
+ continue;
+ }
+
+ const cEvent* pEvent = pResultObj->event;
+ // check if this event was already recorded
+ int records = 0;
+ cRecDone* firstRec = NULL;
+ LogFile.Log(3, "get count recordings with %d%% match", compareSummaryMatchInPercent);
+ records = RecsDone.GetCountRecordings(pEvent, this, &firstRec, compareSummaryMatchInPercent);
+ LogFile.Log(3, "recordings: %d", records);
+
+ if (records > allowedRepeats) { // already recorded
+ LogFile.Log(3, "skip '%s~%s' (%s - %s, channel %d): already recorded %d equal event(s)", pEvent->Title() ? pEvent->Title() : "no title", pEvent->ShortText() ? pEvent->ShortText() : "no subtitle", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), ChannelNrFromEvent(pEvent), records);
+ pResultObj->needsTimer = false; // first assume we need no timer
+ continue;
+ }
+
+ int plannedTimers = 0;
+ LogFile.Log(3, "get planned recordings");
+ cSearchResult* pFirstResultMatching = NULL;
+ // check other results, if they are already planned for equal events
+ for (cSearchResult* pResultObjP = pResults->First(); pResultObjP; pResultObjP = pResults->Next(pResultObjP)) {
+ if (pResultObj == pResultObjP) break;
+
+ const cEvent* pEventP = pResultObjP->event;
+ if (!pEventP) continue;
+
+ if (!pResultObjP->needsTimer) continue;
+
+ if (EventsMatch(pEvent, pEventP, compareTitle, compareSubtitle, compareSummary, compareDate, catvaluesAvoidRepeat, compareSummaryMatchInPercent)) {
+ if (!pFirstResultMatching) pFirstResultMatching = pResultObjP;
+ plannedTimers++;
}
- int daysFromFirstRec = int(double((pEvent->StartTime() - firstRec->startTime)) / (60*60*24) + 0.5);
- if (daysFromFirstRec > repeatsWithinDays)
- {
- LogFile.Log(3,"skip '%s~%s' (%s - %s, channel %d); first recording at %s is %d days before, limit is %d days", pEvent->Title()?pEvent->Title():"no title", pEvent->ShortText()?pEvent->ShortText():"no subtitle", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), ChannelNrFromEvent(pEvent), DAYDATETIME(firstRec->startTime),daysFromFirstRec, repeatsWithinDays);
- pResultObj->needsTimer = false;
- continue;
+ }
+ LogFile.Log(3, "planned: %d", plannedTimers);
+
+ if (plannedTimers + records > allowedRepeats) {
+ LogFile.Log(3, "skip '%s~%s' (%s - %s, channel %d): events planned(%d), recorded(%d), allowed(%d)", pEvent->Title() ? pEvent->Title() : "no title", pEvent->ShortText() ? pEvent->ShortText() : "no subtitle", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), ChannelNrFromEvent(pEvent), plannedTimers, records, allowedRepeats);
+ pResultObj->needsTimer = false;
+ continue;
+ } else if (allowedRepeats > 0 && repeatsWithinDays > 0) { // if we only allow repeats with in a given range
+ if (firstRec) { // already recorded, check for allowed repeat within days
+ if (firstRec->startTime > pEvent->StartTime() - pEvent->Duration()) { // no repeat
+ LogFile.Log(3, "skip '%s~%s' (%s - %s, channel %d); no repeat for event already recorded at %s, channel %d", pEvent->Title() ? pEvent->Title() : "no title", pEvent->ShortText() ? pEvent->ShortText() : "no subtitle", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), ChannelNrFromEvent(pEvent), DAYDATETIME(firstRec->startTime), firstRec->ChannelNr());
+ pResultObj->needsTimer = false;
+ continue;
+ }
+ int daysFromFirstRec = int(double((pEvent->StartTime() - firstRec->startTime)) / (60 * 60 * 24) + 0.5);
+ if (daysFromFirstRec > repeatsWithinDays) {
+ LogFile.Log(3, "skip '%s~%s' (%s - %s, channel %d); first recording at %s is %d days before, limit is %d days", pEvent->Title() ? pEvent->Title() : "no title", pEvent->ShortText() ? pEvent->ShortText() : "no subtitle", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), ChannelNrFromEvent(pEvent), DAYDATETIME(firstRec->startTime), daysFromFirstRec, repeatsWithinDays);
+ pResultObj->needsTimer = false;
+ continue;
+ }
}
- }
- if (plannedTimers > 0 && pFirstResultMatching)
- {
- const cEvent* pFirst = pFirstResultMatching->event;
- if (pFirst->StartTime() > pEvent->StartTime() - pEvent->Duration()) // no repeat
- {
- LogFile.Log(3,"skip '%s~%s' (%s - %s, channel %d); no repeat for event already recorded at %s - %s, channel %d", pEvent->Title()?pEvent->Title():"no title", pEvent->ShortText()?pEvent->ShortText():"no subtitle", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), ChannelNrFromEvent(pEvent), GETDATESTRING(pFirst), GETTIMESTRING(pFirst), ChannelNrFromEvent(pFirst));
- pResultObj->needsTimer = false;
- continue;
+ if (plannedTimers > 0 && pFirstResultMatching) {
+ const cEvent* pFirst = pFirstResultMatching->event;
+ if (pFirst->StartTime() > pEvent->StartTime() - pEvent->Duration()) { // no repeat
+ LogFile.Log(3, "skip '%s~%s' (%s - %s, channel %d); no repeat for event already recorded at %s - %s, channel %d", pEvent->Title() ? pEvent->Title() : "no title", pEvent->ShortText() ? pEvent->ShortText() : "no subtitle", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), ChannelNrFromEvent(pEvent), GETDATESTRING(pFirst), GETTIMESTRING(pFirst), ChannelNrFromEvent(pFirst));
+ pResultObj->needsTimer = false;
+ continue;
+ }
+
+ int daysBetween = int(double((pEvent->StartTime() - pFirst->StartTime())) / (60 * 60 * 24) + 0.5);
+ if (daysBetween > repeatsWithinDays) {
+ LogFile.Log(3, "skip '%s~%s' (%s - %s, channel %d); first event '%s~%s' (%s - %s) is %d days before, limit is %d days", pEvent->Title() ? pEvent->Title() : "no title", pEvent->ShortText() ? pEvent->ShortText() : "no subtitle", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), ChannelNrFromEvent(pEvent), GETDATESTRING(pFirst), GETTIMESTRING(pFirst), daysBetween, repeatsWithinDays);
+ pResultObj->needsTimer = false;
+ continue;
+ }
}
+ }
+ bool dummy;
+ const cTimer* timer = cSearchTimerThread::GetTimer(this, pEvent, dummy);
+ if (timer && !timer->HasFlags(tfActive)) {
+ LogFile.Log(3, "skip '%s~%s' (%s - %s, channel %d), existing timer disabled", pEvent->Title() ? pEvent->Title() : "no title", pEvent->ShortText() ? pEvent->ShortText() : "no subtitle", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), ChannelNrFromEvent(pEvent));
+ pResultObj->needsTimer = false;
+ continue;
+ } else
+ LogFile.Log(3, "*** planning event '%s~%s' (%s - %s, channel %d) for recording", pEvent->Title() ? pEvent->Title() : "no title", pEvent->ShortText() ? pEvent->ShortText() : "no subtitle", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), ChannelNrFromEvent(pEvent));
+ }
+ int needsTimer = 0;
+ for (pResultObj = pResults->First(); pResultObj; pResultObj = pResults->Next(pResultObj))
+ if (pResultObj->needsTimer) needsTimer++;
- int daysBetween = int(double((pEvent->StartTime() - pFirst->StartTime())) / (60*60*24) + 0.5);
- if (daysBetween > repeatsWithinDays)
- {
- LogFile.Log(3,"skip '%s~%s' (%s - %s, channel %d); first event '%s~%s' (%s - %s) is %d days before, limit is %d days", pEvent->Title()?pEvent->Title():"no title", pEvent->ShortText()?pEvent->ShortText():"no subtitle", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), ChannelNrFromEvent(pEvent), GETDATESTRING(pFirst), GETTIMESTRING(pFirst),daysBetween, repeatsWithinDays);
- pResultObj->needsTimer = false;
- continue;
- }
- }
- }
- bool dummy;
- const cTimer* timer = cSearchTimerThread::GetTimer(this, pEvent, dummy);
- if (timer && !timer->HasFlags(tfActive))
- {
- LogFile.Log(3,"skip '%s~%s' (%s - %s, channel %d), existing timer disabled", pEvent->Title()?pEvent->Title():"no title", pEvent->ShortText()?pEvent->ShortText():"no subtitle", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), ChannelNrFromEvent(pEvent));
- pResultObj->needsTimer = false;
- continue;
- }
- else
- LogFile.Log(3,"*** planning event '%s~%s' (%s - %s, channel %d) for recording", pEvent->Title()?pEvent->Title():"no title", pEvent->ShortText()?pEvent->ShortText():"no subtitle", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), ChannelNrFromEvent(pEvent));
- }
- int needsTimer = 0;
- for (pResultObj = pResults->First(); pResultObj; pResultObj = pResults->Next(pResultObj))
- if (pResultObj->needsTimer) needsTimer++;
-
- LogFile.Log(2,"%d/%d events need a timer for search timer '%s'", needsTimer, pResults->Count(), search);
+ LogFile.Log(2, "%d/%d events need a timer for search timer '%s'", needsTimer, pResults->Count(), search);
}
void cSearchExt::CheckExistingRecordings(cSearchResults* pResults)
{
- if (!pResults)
- return;
-
- LogFile.Log(3,"analysing existing recordings for search timer '%s'...", search);
-
- // how many recordings do we already have?
- int num = GetCountRecordings();
-
- cSearchResult* pResultObj = NULL;
- int remain = pauseOnNrRecordings - num;
- for (pResultObj = pResults->First(); pResultObj; pResultObj = pResults->Next(pResultObj), remain--)
- {
- if (!pResultObj->needsTimer)
- {
- remain++;
- continue; // maybe already disabled because of done feature
- }
- pResultObj->needsTimer = (remain > 0);
- if (remain <= 0)
- {
- const cEvent* pEvent = pResultObj->event;
- LogFile.Log(3,"skip '%s~%s' (%s - %s, channel %d): only %d recordings are allowed", pEvent->Title()?pEvent->Title():"no title", pEvent->ShortText()?pEvent->ShortText():"no subtitle", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), ChannelNrFromEvent(pEvent), pauseOnNrRecordings);
- }
- }
+ if (!pResults)
+ return;
+
+ LogFile.Log(3, "analysing existing recordings for search timer '%s'...", search);
+
+ // how many recordings do we already have?
+ int num = GetCountRecordings();
+
+ cSearchResult* pResultObj = NULL;
+ int remain = pauseOnNrRecordings - num;
+ for (pResultObj = pResults->First(); pResultObj; pResultObj = pResults->Next(pResultObj), remain--) {
+ if (!pResultObj->needsTimer) {
+ remain++;
+ continue; // maybe already disabled because of done feature
+ }
+ pResultObj->needsTimer = (remain > 0);
+ if (remain <= 0) {
+ const cEvent* pEvent = pResultObj->event;
+ LogFile.Log(3, "skip '%s~%s' (%s - %s, channel %d): only %d recordings are allowed", pEvent->Title() ? pEvent->Title() : "no title", pEvent->ShortText() ? pEvent->ShortText() : "no subtitle", GETDATESTRING(pEvent), GETTIMESTRING(pEvent), ChannelNrFromEvent(pEvent), pauseOnNrRecordings);
+ }
+ }
}
bool cSearchExt::MatchesExtEPGInfo(const cEvent* e)
{
- if (!e || !e->Description())
- return false;
- cSearchExtCat* SearchExtCat = SearchExtCats.First();
- while (SearchExtCat)
- {
- char* value = NULL;
- int index = SearchExtCats.GetIndexFromID(SearchExtCat->id);
- if (index > -1)
- value = catvalues[index];
- if (value && SearchExtCat->searchmode >= 10 && atol(value) == 0) // numerical value != 0 ?
- value = NULL;
- if (value && *value)
- {
- char* testvalue = GetExtEPGValue(e, SearchExtCat);
- if (!testvalue)
- return (ignoreMissingEPGCats?true:false);
-
- // compare not case sensitive
- char* valueLower = strdup(value);
- ToLower(valueLower);
- ToLower(testvalue);
- if (!MatchesSearchMode(testvalue, valueLower, SearchExtCat->searchmode, ",;|~", fuzzyTolerance))
- {
+ if (!e || !e->Description())
+ return false;
+ cSearchExtCat* SearchExtCat = SearchExtCats.First();
+ while (SearchExtCat) {
+ char* value = NULL;
+ int index = SearchExtCats.GetIndexFromID(SearchExtCat->id);
+ if (index > -1)
+ value = catvalues[index];
+ if (value && SearchExtCat->searchmode >= 10 && atol(value) == 0) // numerical value != 0 ?
+ value = NULL;
+ if (value && *value) {
+ char* testvalue = GetExtEPGValue(e, SearchExtCat);
+ if (!testvalue)
+ return (ignoreMissingEPGCats ? true : false);
+
+ // compare not case sensitive
+ char* valueLower = strdup(value);
+ ToLower(valueLower);
+ ToLower(testvalue);
+ if (!MatchesSearchMode(testvalue, valueLower, SearchExtCat->searchmode, ",;|~", fuzzyTolerance)) {
+ free(testvalue);
+ free(valueLower);
+ return false;
+ }
free(testvalue);
free(valueLower);
- return false;
- }
- free(testvalue);
- free(valueLower);
- }
- SearchExtCat = SearchExtCats.Next(SearchExtCat);
- }
- return true;
+ }
+ SearchExtCat = SearchExtCats.Next(SearchExtCat);
+ }
+ return true;
}
void cSearchExt::OnOffTimers(bool bOn)
{
- LOCK_TIMERS_WRITE;
- for (cTimer *ti = Timers->First(); ti; ti = Timers->Next(ti))
- {
- if (((!bOn && ti->HasFlags(tfActive)) || (bOn && !ti->HasFlags(tfActive))) && TriggeredFromSearchTimerID(ti) == ID)
- ti->OnOff();
- }
+ LOCK_TIMERS_WRITE;
+ for (cTimer *ti = Timers->First(); ti; ti = Timers->Next(ti)) {
+ if (((!bOn && ti->HasFlags(tfActive)) || (bOn && !ti->HasFlags(tfActive))) && TriggeredFromSearchTimerID(ti) == ID)
+ ti->OnOff();
+ }
}
void cSearchExt::DeleteAllTimers()
{
- cList<cTimerObj> DelTimers;
- LOCK_TIMERS_WRITE;
- Timers->SetExplicitModify();
- cTimer *ti = Timers->First();
- while(ti)
- {
- if (!ti->Recording() && TriggeredFromSearchTimerID(ti) == ID)
- {
- cTimer* tiNext = Timers->Next(ti);
- LogFile.iSysLog("deleting timer %s", *ti->ToDescr());
- Timers->Del(ti);
- Timers->SetModified();
- ti = tiNext;
- }
- else
- ti = Timers->Next(ti);
- };
+ cList<cTimerObj> DelTimers;
+ LOCK_TIMERS_WRITE;
+ Timers->SetExplicitModify();
+ cTimer *ti = Timers->First();
+ while (ti) {
+ if (!ti->Recording() && TriggeredFromSearchTimerID(ti) == ID) {
+ cTimer* tiNext = Timers->Next(ti);
+ LogFile.iSysLog("deleting timer %s", *ti->ToDescr());
+ Timers->Del(ti);
+ Timers->SetModified();
+ ti = tiNext;
+ } else
+ ti = Timers->Next(ti);
+ };
}
cTimerObjList* cSearchExt::GetTimerList(cTimerObjList* timerList)
{
- if (!timerList)
- timerList = new cTimerObjList;
-
- LOCK_TIMERS_READ;
- for (const cTimer *ti = Timers->First(); ti; ti = Timers->Next(ti))
- {
- if (TriggeredFromSearchTimerID(ti) == ID)
- {
- // check if already in list
- bool found = false;
- for (cTimerObj *tObj = timerList->First(); tObj; tObj = timerList->Next(tObj))
- {
- if (tObj->timer == ti)
- {
- found = true;
- break;
+ if (!timerList)
+ timerList = new cTimerObjList;
+
+ LOCK_TIMERS_READ;
+ for (const cTimer *ti = Timers->First(); ti; ti = Timers->Next(ti)) {
+ if (TriggeredFromSearchTimerID(ti) == ID) {
+ // check if already in list
+ bool found = false;
+ for (cTimerObj *tObj = timerList->First(); tObj; tObj = timerList->Next(tObj)) {
+ if (tObj->timer == ti) {
+ found = true;
+ break;
+ }
}
- }
- if (!found)
- timerList->Add(new cTimerObj(ti));
- }
- }
- return timerList;
+ if (!found)
+ timerList->Add(new cTimerObj(ti));
+ }
+ }
+ return timerList;
}
// counts the currently existent recordings triggered by this search timer
int cSearchExt::GetCountRecordings()
{
- int countRecs = 0;
-
- LOCK_RECORDINGS_READ;
- for (const cRecording *recording = Recordings->First(); recording; recording = Recordings->Next(recording))
- {
- if (recording->IsEdited()) continue; // ignore recordings edited
- if (!recording->Info()) continue;
- char* searchID = GetAuxValue(recording, "s-id");
-
- if (!searchID) continue;
- if (ID == atoi(searchID))
- countRecs++;
- free(searchID);
- }
- LogFile.Log(3, "found %d recordings for search '%s'", countRecs, search);
- return countRecs;
+ int countRecs = 0;
+
+ LOCK_RECORDINGS_READ;
+ for (const cRecording *recording = Recordings->First(); recording; recording = Recordings->Next(recording)) {
+ if (recording->IsEdited()) continue; // ignore recordings edited
+ if (!recording->Info()) continue;
+ char* searchID = GetAuxValue(recording, "s-id");
+
+ if (!searchID) continue;
+ if (ID == atoi(searchID))
+ countRecs++;
+ free(searchID);
+ }
+ LogFile.Log(3, "found %d recordings for search '%s'", countRecs, search);
+ return countRecs;
}
bool cSearchExt::IsActiveAt(time_t t)
{
- if (useAsSearchTimer == 0) return false;
- if (useAsSearchTimer == 2)
- {
- if (useAsSearchTimerFrom > 0 && t < useAsSearchTimerFrom) return false;
- if (useAsSearchTimerTil > 0 && t > useAsSearchTimerTil) return false;
+ if (useAsSearchTimer == 0) return false;
+ if (useAsSearchTimer == 2) {
+ if (useAsSearchTimerFrom > 0 && t < useAsSearchTimerFrom) return false;
+ if (useAsSearchTimerTil > 0 && t > useAsSearchTimerTil) return false;
}
- return true;
+ return true;
}
bool cSearchExt::HasContent(int contentID)
{
- for(unsigned int i=0; i<contentsFilter.size();i+=2)
- {
- std::string hexContentID = contentsFilter.substr(i,2);
- if(hexContentID.size()!=2) return false;
- std::istringstream iss(hexContentID);
- int tmpContentID =0;
- if(!(iss>>std::noshowbase>>std::hex>>tmpContentID)) return false;
- if (contentID == tmpContentID) return true;
- }
- return false;
+ for (unsigned int i = 0; i < contentsFilter.size(); i += 2) {
+ std::string hexContentID = contentsFilter.substr(i, 2);
+ if (hexContentID.size() != 2) return false;
+ std::istringstream iss(hexContentID);
+ int tmpContentID = 0;
+ if (!(iss >> std::noshowbase >> std::hex >> tmpContentID)) return false;
+ if (contentID == tmpContentID) return true;
+ }
+ return false;
}
void cSearchExt::SetContentFilter(int* contentStringsFlags)
{
- // create the hex array of content descriptor IDs
- string tmp;
- contentsFilter = "";
- for(unsigned int i=0; contentStringsFlags && i<=CONTENT_DESCRIPTOR_MAX; i++)
- {
- if (contentStringsFlags[i])
- {
- std::ostringstream oss;
- oss<<std::hex<<std::noshowbase<<i;
- contentsFilter += oss.str();
- }
+ // create the hex array of content descriptor IDs
+ string tmp;
+ contentsFilter = "";
+ for (unsigned int i = 0; contentStringsFlags && i <= CONTENT_DESCRIPTOR_MAX; i++) {
+ if (contentStringsFlags[i]) {
+ std::ostringstream oss;
+ oss << std::hex << std::noshowbase << i;
+ contentsFilter += oss.str();
+ }
}
}
bool cSearchExt::MatchesContentsFilter(const cEvent* e)
{
- if (!e) return false;
- // check if each content filter ID is contained in the events descriptors
- for(unsigned int i=0; i<contentsFilter.size();i+=2)
- {
- std::string hexContentID = contentsFilter.substr(i,2);
- if(hexContentID.size()!=2) return false;
- std::istringstream iss(hexContentID);
- int searchContentID =0;
- if(!(iss>>std::hex>>searchContentID)) return false;
- int c=0, eventContentID=0;
- bool found = false;
- while((eventContentID=e->Contents(c++)) > 0)
- if (eventContentID == searchContentID)
- {
- found = true;
- break;
- }
- if (!found) return false;
- }
- return true;
+ if (!e) return false;
+ // check if each content filter ID is contained in the events descriptors
+ for (unsigned int i = 0; i < contentsFilter.size(); i += 2) {
+ std::string hexContentID = contentsFilter.substr(i, 2);
+ if (hexContentID.size() != 2) return false;
+ std::istringstream iss(hexContentID);
+ int searchContentID = 0;
+ if (!(iss >> std::hex >> searchContentID)) return false;
+ int c = 0, eventContentID = 0;
+ bool found = false;
+ while ((eventContentID = e->Contents(c++)) > 0)
+ if (eventContentID == searchContentID) {
+ found = true;
+ break;
+ }
+ if (!found) return false;
+ }
+ return true;
}
// -- cSearchExts ----------------------------------------------------------------
bool cSearchExts::Load(const char *FileName)
{
- cMutexLock SearchExtsLock(this);
- Clear();
- if (FileName) {
- free(fileName);
- fileName = strdup(FileName);
- }
-
- bool result = true;
- if (fileName && access(fileName, F_OK) == 0) {
- LogFile.iSysLog("loading %s", fileName);
- FILE *f = fopen(fileName, "r");
- if (f) {
- int line = 0;
- char buffer[MAXPARSEBUFFER];
- result = true;
- while (fgets(buffer, sizeof(buffer), f) > 0) {
- line++;
- char *p = strchr(buffer, '#');
- if (p == buffer) *p = 0;
-
- stripspace(buffer);
- if (!isempty(buffer)) {
- cSearchExt* search = new cSearchExt;
- if (search->Parse(buffer))
- Add(search);
- else {
- LogFile.eSysLog("error in '%s', line %d\n", fileName, line);
- delete search;
- result = false;
- break;
- }
+ cMutexLock SearchExtsLock(this);
+ Clear();
+ if (FileName) {
+ free(fileName);
+ fileName = strdup(FileName);
+ }
+
+ bool result = true;
+ if (fileName && access(fileName, F_OK) == 0) {
+ LogFile.iSysLog("loading %s", fileName);
+ FILE *f = fopen(fileName, "r");
+ if (f) {
+ int line = 0;
+ char buffer[MAXPARSEBUFFER];
+ result = true;
+ while (fgets(buffer, sizeof(buffer), f) > 0) {
+ line++;
+ char *p = strchr(buffer, '#');
+ if (p == buffer) *p = 0;
+
+ stripspace(buffer);
+ if (!isempty(buffer)) {
+ cSearchExt* search = new cSearchExt;
+ if (search->Parse(buffer))
+ Add(search);
+ else {
+ LogFile.eSysLog("error in '%s', line %d\n", fileName, line);
+ delete search;
+ result = false;
+ break;
+ }
+ }
}
- }
- fclose(f);
- }
- else {
- LOG_ERROR_STR(fileName);
- result = false;
- }
- }
-
- if (!result)
- fprintf(stderr, "vdr: error while reading '%s'\n", fileName);
- LogFile.Log(2,"loaded searches from %s (count: %d)", fileName, Count());
- return result;
+ fclose(f);
+ } else {
+ LOG_ERROR_STR(fileName);
+ result = false;
+ }
+ }
+
+ if (!result)
+ fprintf(stderr, "vdr: error while reading '%s'\n", fileName);
+ LogFile.Log(2, "loaded searches from %s (count: %d)", fileName, Count());
+ return result;
}
int cSearchExts::GetNewID()
{
- cMutexLock SearchExtsLock(this);
- int newID = -1;
- cSearchExt *l = (cSearchExt *)First();
- while (l) {
- newID = std::max(newID, l->ID);
- l = (cSearchExt *)l->Next();
- }
- return newID+1;
+ cMutexLock SearchExtsLock(this);
+ int newID = -1;
+ cSearchExt *l = (cSearchExt *)First();
+ while (l) {
+ newID = std::max(newID, l->ID);
+ l = (cSearchExt *)l->Next();
+ }
+ return newID + 1;
}
void cSearchExts::Update(void)
{
- cMutexLock SearchExtsLock(this);
- cSearchExt *l = (cSearchExt *)First();
- while (l) {
- // check if ID is set
- if (l->ID == -1)
- l->ID = GetNewID();
- l = (cSearchExt *)l->Next();
- }
+ cMutexLock SearchExtsLock(this);
+ cSearchExt *l = (cSearchExt *)First();
+ while (l) {
+ // check if ID is set
+ if (l->ID == -1)
+ l->ID = GetNewID();
+ l = (cSearchExt *)l->Next();
+ }
}
bool cSearchExts::Save(void)
{
- cMutexLock SearchExtsLock(this);
- bool result = true;
- cSearchExt *l = (cSearchExt *)this->First();
- cSafeFile f(fileName);
- if (f.Open()) {
- while (l) {
- if (!l->Save(f)) {
+ cMutexLock SearchExtsLock(this);
+ bool result = true;
+ cSearchExt *l = (cSearchExt *)this->First();
+ cSafeFile f(fileName);
+ if (f.Open()) {
+ while (l) {
+ if (!l->Save(f)) {
+ result = false;
+ break;
+ }
+ l = (cSearchExt *)l->Next();
+ }
+ if (!f.Close())
result = false;
- break;
- }
- l = (cSearchExt *)l->Next();
- }
- if (!f.Close())
- result = false;
- }
- else
- result = false;
- return result;
+ } else
+ result = false;
+ return result;
}
cSearchExt* cSearchExts::GetSearchFromID(int ID)
{
- if (ID == -1)
- return NULL;
- cMutexLock SearchExtsLock(this);
- cSearchExt *l = (cSearchExt *)First();
- while (l) {
- if (l->ID == ID)
- return l;
- l = (cSearchExt *)l->Next();
- }
- return NULL;
+ if (ID == -1)
+ return NULL;
+ cMutexLock SearchExtsLock(this);
+ cSearchExt *l = (cSearchExt *)First();
+ while (l) {
+ if (l->ID == ID)
+ return l;
+ l = (cSearchExt *)l->Next();
+ }
+ return NULL;
}
void cSearchExts::RemoveBlacklistID(int ID)
{
- bool changed = false;
- cMutexLock SearchExtsLock(this);
- cSearchExt *l = (cSearchExt *)First();
- while (l)
- {
- cBlacklistObject* blacklistObj = l->blacklists.First();
- while(blacklistObj)
- {
- cBlacklistObject* blacklistObjNext = l->blacklists.Next(blacklistObj);
- if (blacklistObj->blacklist->ID == ID)
- {
- l->blacklists.Del(blacklistObj);
- changed = true;
- }
- blacklistObj = blacklistObjNext;
- }
- l = (cSearchExt *)l->Next();
- }
- if (changed)
- Save();
+ bool changed = false;
+ cMutexLock SearchExtsLock(this);
+ cSearchExt *l = (cSearchExt *)First();
+ while (l) {
+ cBlacklistObject* blacklistObj = l->blacklists.First();
+ while (blacklistObj) {
+ cBlacklistObject* blacklistObjNext = l->blacklists.Next(blacklistObj);
+ if (blacklistObj->blacklist->ID == ID) {
+ l->blacklists.Del(blacklistObj);
+ changed = true;
+ }
+ blacklistObj = blacklistObjNext;
+ }
+ l = (cSearchExt *)l->Next();
+ }
+ if (changed)
+ Save();
}
bool cSearchExts::Exists(const cSearchExt* SearchExt)
{
- cMutexLock SearchExtsLock(this);
- cSearchExt *l = (cSearchExt *)First();
- while (l)
- {
- if (l == SearchExt)
- return true;
- l = (cSearchExt *)l->Next();
- }
- return false;
+ cMutexLock SearchExtsLock(this);
+ cSearchExt *l = (cSearchExt *)First();
+ while (l) {
+ if (l == SearchExt)
+ return true;
+ l = (cSearchExt *)l->Next();
+ }
+ return false;
}
cSearchExts* cSearchExts::Clone()
{
- cSearchExts* clonedList = new cSearchExts();
-
- cMutexLock SearchExtsLock(this);
- cSearchExt *l = (cSearchExt *)First();
- while (l)
- {
- cSearchExt* clone = new cSearchExt();
- *clone = *l;
- clonedList->Add(clone);
- l = (cSearchExt *)l->Next();
- }
- return clonedList;
+ cSearchExts* clonedList = new cSearchExts();
+
+ cMutexLock SearchExtsLock(this);
+ cSearchExt *l = (cSearchExt *)First();
+ while (l) {
+ cSearchExt* clone = new cSearchExt();
+ *clone = *l;
+ clonedList->Add(clone);
+ l = (cSearchExt *)l->Next();
+ }
+ return clonedList;
}
bool cSearchExts::CheckForAutoDelete(cSearchExt* SearchExt)
{
- if (!SearchExt || SearchExt->delMode == 0) return false;
-
- cRecDone* firstRec = NULL;
- bool delSearch = false;
- int recs = RecsDone.GetTotalCountRecordings(SearchExt, &firstRec);
- if (SearchExt->delMode == 1 && SearchExt->delAfterCountRecs > 0)
- delSearch = recs >= SearchExt->delAfterCountRecs;
- if (SearchExt->delMode == 2 && SearchExt->delAfterDaysOfFirstRec && firstRec)
- delSearch = (time(NULL) - firstRec->startTime) > SearchExt->delAfterDaysOfFirstRec * 24 * 60 * 60;
- if (delSearch)
- {
- int DelID = SearchExt->ID;
- LogFile.Log(1,"auto deleting search '%s' (ID: %d)", SearchExt->search, DelID);
- cMutexLock SearchExtsLock(&SearchExts);
- SearchExts.Del(SearchExt);
- SearchExts.Save();
- RecsDone.RemoveSearchID(DelID);
- }
- return delSearch;
+ if (!SearchExt || SearchExt->delMode == 0) return false;
+
+ cRecDone* firstRec = NULL;
+ bool delSearch = false;
+ int recs = RecsDone.GetTotalCountRecordings(SearchExt, &firstRec);
+ if (SearchExt->delMode == 1 && SearchExt->delAfterCountRecs > 0)
+ delSearch = recs >= SearchExt->delAfterCountRecs;
+ if (SearchExt->delMode == 2 && SearchExt->delAfterDaysOfFirstRec && firstRec)
+ delSearch = (time(NULL) - firstRec->startTime) > SearchExt->delAfterDaysOfFirstRec * 24 * 60 * 60;
+ if (delSearch) {
+ int DelID = SearchExt->ID;
+ LogFile.Log(1, "auto deleting search '%s' (ID: %d)", SearchExt->search, DelID);
+ cMutexLock SearchExtsLock(&SearchExts);
+ SearchExts.Del(SearchExt);
+ SearchExts.Save();
+ RecsDone.RemoveSearchID(DelID);
+ }
+ return delSearch;
}
void cSearchExts::SortBy(int(*compar)(const void *, const void *))
{
- int n = Count();
- cListObject *a[n];
- cListObject *object = objects;
- int i = 0;
- while (object && i < n) {
- a[i++] = object;
- object = object->Next();
- }
- qsort(a, n, sizeof(cListObject *), compar);
- objects = lastObject = NULL;
- for (i = 0; i < n; i++) {
- a[i]->Unlink();
- count--;
- Add(a[i]);
- }
+ int n = Count();
+ cListObject *a[n];
+ cListObject *object = objects;
+ int i = 0;
+ while (object && i < n) {
+ a[i++] = object;
+ object = object->Next();
+ }
+ qsort(a, n, sizeof(cListObject *), compar);
+ objects = lastObject = NULL;
+ for (i = 0; i < n; i++) {
+ a[i]->Unlink();
+ count--;
+ Add(a[i]);
+ }
}
cSearchResult::cSearchResult(const cEvent* Event, int searchID) : event(Event), blacklist(NULL), needsTimer(true)
{
- search = SearchExts.GetSearchFromID(searchID);
+ search = SearchExts.GetSearchFromID(searchID);
}