summaryrefslogtreecommitdiff
path: root/recmanager.c
diff options
context:
space:
mode:
Diffstat (limited to 'recmanager.c')
-rw-r--r--recmanager.c710
1 files changed, 710 insertions, 0 deletions
diff --git a/recmanager.c b/recmanager.c
new file mode 100644
index 0000000..fbbf890
--- /dev/null
+++ b/recmanager.c
@@ -0,0 +1,710 @@
+#define __STL_CONFIG_H
+
+#include <string>
+#include <sstream>
+#include <vector>
+#include <algorithm>
+
+#include <vdr/menu.h>
+#include "recmanager.h"
+
+static int CompareRecording(const void *p1, const void *p2) {
+ return (int)((*(cRecording **)p1)->Start() - (*(cRecording **)p2)->Start());
+}
+
+cRecManager::cRecManager(void) {
+ epgSearchPlugin = NULL;
+ epgSearchAvailable = false;
+}
+
+cRecManager::~cRecManager(void) {
+}
+
+void cRecManager::SetEPGSearchPlugin(void) {
+ epgSearchPlugin = cPluginManager::GetPlugin("epgsearch");
+ if (epgSearchPlugin) {
+ epgSearchAvailable = true;
+ }
+}
+
+bool cRecManager::RefreshRemoteTimers(void) {
+ cString errorMsg;
+ if (!pRemoteTimers->Service("RemoteTimers::RefreshTimers-v1.0", &errorMsg)) {
+ esyslog("tvguide: %s", *errorMsg);
+ return false;
+ }
+ return true;
+}
+
+bool cRecManager::CheckEventForTimer(const cEvent *event) {
+ bool hasTimer = false;
+
+ if (config.useRemoteTimers && pRemoteTimers) {
+ RemoteTimers_GetMatch_v1_0 rtMatch;
+ rtMatch.event = event;
+ pRemoteTimers->Service("RemoteTimers::GetMatch-v1.0", &rtMatch);
+ if (rtMatch.timerMatch == tmFull)
+ hasTimer = true;
+ } else
+ hasTimer = event->HasTimer();
+
+ return hasTimer;
+}
+
+cTimer *cRecManager::GetTimerForEvent(const cEvent *event) {
+ cTimer *timer = NULL;
+ if (config.useRemoteTimers && pRemoteTimers) {
+ RemoteTimers_GetMatch_v1_0 rtMatch;
+ rtMatch.event = event;
+ pRemoteTimers->Service("RemoteTimers::GetMatch-v1.0", &rtMatch);
+ timer = rtMatch.timer;
+ } else
+ timer = Timers.GetMatch(event);
+ return timer;
+}
+
+cTimer *cRecManager::createTimer(const cEvent *event, std::string path) {
+ cTimer *timer = NULL;
+ if (config.useRemoteTimers && pRemoteTimers) {
+ timer = createRemoteTimer(event, path);
+ } else {
+ timer = createLocalTimer(event, path);
+ }
+ return timer;
+}
+
+cTimer *cRecManager::createLocalTimer(const cEvent *event, std::string path) {
+ cTimer *timer = new cTimer(event);
+ cTimer *t = Timers.GetTimer(timer);
+ if (t) {
+ t->OnOff();
+ t->SetEventFromSchedule();
+ delete timer;
+ timer = t;
+ isyslog("timer %s reactivated", *t->ToDescr());
+ } else {
+ Timers.Add(timer);
+ isyslog("timer %s added (active)", *timer->ToDescr());
+ }
+ SetTimerPath(timer, event, path);
+ Timers.SetModified();
+ return timer;
+}
+
+cTimer *cRecManager::createRemoteTimer(const cEvent *event, std::string path) {
+ cTimer *t = new cTimer(event);
+ SetTimerPath(t, event, path);
+ RemoteTimers_Timer_v1_0 rt;
+ rt.timer = t;
+ pRemoteTimers->Service("RemoteTimers::GetTimer-v1.0", &rt.timer);
+ if (rt.timer) {
+ rt.timer->OnOff();
+ if (!pRemoteTimers->Service("RemoteTimers::ModTimer-v1.0", &rt))
+ rt.timer = NULL;
+ } else {
+ rt.timer = t;
+ if (!pRemoteTimers->Service("RemoteTimers::NewTimer-v1.0", &rt))
+ isyslog("%s", *rt.errorMsg);
+ }
+ RefreshRemoteTimers();
+ return rt.timer;
+}
+
+void cRecManager::SetTimerPath(cTimer *timer, const cEvent *event, std::string path) {
+ if (config.instRecFolderMode == eFolderFixed) {
+ Epgsearch_services_v1_2 *epgSearch = new Epgsearch_services_v1_2;
+ std::string recDir = config.instRecFixedFolder;
+ std::replace(recDir.begin(), recDir.end(), '/', '~');
+ if (strchr(recDir.c_str(), '%') != NULL) {
+ if (epgSearchPlugin->Service("Epgsearch-services-v1.1", epgSearch)) {
+ std::string newFileName = epgSearch->handler->Evaluate(recDir, event);
+ if (strchr(newFileName.c_str(), '%') == NULL) // only set directory to new value if all categories could have been replaced
+ timer->SetFile(newFileName.c_str());
+ else
+ esyslog("tvguide: timer path not set because replacing variable was not successfull: %s", newFileName.c_str());
+ }
+ } else {
+ cString newFileName;
+ if (recDir.size() > 0) {
+ newFileName = cString::sprintf("%s~%s", recDir.c_str(), timer->File());
+ timer->SetFile(*newFileName);
+ }
+ }
+ return;
+ }
+ //Set choosen path
+ cString newFileName;
+ if (path.size() > 0) {
+ std::replace(path.begin(), path.end(), '/', '~');
+ newFileName = cString::sprintf("%s~%s", path.c_str(), timer->File());
+ } else {
+ newFileName = event->Title();
+ }
+ timer->SetFile(*newFileName);
+}
+
+void cRecManager::DeleteTimer(int timerID) {
+ cTimer *t = Timers.Get(timerID);
+ if (!t)
+ return;
+ DeleteTimer(t);
+}
+
+void cRecManager::DeleteTimer(const cEvent *event) {
+ if (!event)
+ return;
+ if (config.useRemoteTimers && pRemoteTimers) {
+ DeleteRemoteTimer(event);
+ } else {
+ DeleteLocalTimer(event);
+ }
+}
+
+void cRecManager::DeleteLocalTimer(const cEvent *event) {
+ cTimer *t = Timers.GetMatch(event);
+ if (!t)
+ return;
+ DeleteTimer(t);
+}
+
+
+void cRecManager::DeleteTimer(cTimer *timer) {
+ if (timer->Recording()) {
+ timer->Skip();
+ cRecordControls::Process(time(NULL));
+ }
+ isyslog("timer %s deleted", *timer->ToDescr());
+ Timers.Del(timer, true);
+ Timers.SetModified();
+}
+
+void cRecManager::DeleteRemoteTimer(const cEvent *event) {
+ RemoteTimers_GetMatch_v1_0 rtMatch;
+ rtMatch.event = event;
+ pRemoteTimers->Service("RemoteTimers::GetMatch-v1.0", &rtMatch);
+ if (rtMatch.timer) {
+ RemoteTimers_Timer_v1_0 rt;
+ rt.timer = rtMatch.timer;
+ isyslog("remotetimer %s deleted", *rt.timer->ToDescr());
+ if (!pRemoteTimers->Service("RemoteTimers::DelTimer-v1.0", &rt))
+ isyslog("remotetimer error");
+ RefreshRemoteTimers();
+ }
+}
+
+void cRecManager::SaveTimer(cTimer *timer, cTimer newTimerSettings) {
+ if (!timer)
+ return;
+
+ bool active = newTimerSettings.HasFlags(tfActive);
+ int prio = newTimerSettings.Priority();
+ int lifetime = newTimerSettings.Lifetime();
+ time_t day = newTimerSettings.Day();
+ int start = newTimerSettings.Start();
+ int stop = newTimerSettings.Stop();
+ std::string fileName = newTimerSettings.File();
+
+ timer->SetDay(day);
+ timer->SetStart(start);
+ timer->SetStop(stop);
+ timer->SetPriority(prio);
+ timer->SetLifetime(lifetime);
+ timer->SetFile(fileName.c_str());
+
+ if (timer->HasFlags(tfActive) && !active)
+ timer->ClrFlags(tfActive);
+ else if (!timer->HasFlags(tfActive) && active)
+ timer->SetFlags(tfActive);
+
+ timer->SetEventFromSchedule();
+ if (config.useRemoteTimers && pRemoteTimers) {
+ RemoteTimers_Timer_v1_0 rt;
+ rt.timer = timer;
+ if (!pRemoteTimers->Service("RemoteTimers::ModTimer-v1.0", &rt))
+ rt.timer = NULL;
+ RefreshRemoteTimers();
+ } else {
+ Timers.SetModified();
+ }
+}
+
+
+bool cRecManager::IsRecorded(const cEvent *event) {
+ cTimer *timer = Timers.GetMatch(event);
+ if (!timer)
+ return false;
+ return timer->Recording();
+}
+
+cTVGuideTimerConflicts *cRecManager::CheckTimerConflict(void) {
+ cTVGuideTimerConflicts *conflictList = new cTVGuideTimerConflicts();
+ if (!epgSearchAvailable)
+ return conflictList;
+ Epgsearch_services_v1_1 *epgSearch = new Epgsearch_services_v1_1;
+ if (epgSearchPlugin->Service("Epgsearch-services-v1.1", epgSearch)) {
+ std::list<std::string> conflicts = epgSearch->handler->TimerConflictList();
+ int numConflicts = conflicts.size();
+ if (numConflicts == 0)
+ return conflictList;
+ for (std::list<std::string>::iterator it=conflicts.begin(); it != conflicts.end(); ++it) {
+ conflictList->AddConflict(*it);
+ }
+ }
+ delete epgSearch;
+ conflictList->CalculateConflicts();
+ return conflictList;
+}
+
+void cRecManager::CreateSeriesTimer(cTimer *seriesTimer) {
+ seriesTimer->SetEventFromSchedule();
+ if (config.useRemoteTimers && pRemoteTimers) {
+ RemoteTimers_Timer_v1_0 rt;
+ rt.timer = seriesTimer;
+ if (!pRemoteTimers->Service("RemoteTimers::NewTimer-v1.0", &rt))
+ isyslog("%s", *rt.errorMsg);
+ RefreshRemoteTimers();
+ } else {
+ Timers.Add(seriesTimer);
+ Timers.SetModified();
+ }
+}
+
+
+void cRecManager::ReadEPGSearchTemplates(std::vector<TVGuideEPGSearchTemplate> *epgTemplates) {
+ cString ConfigDir = cPlugin::ConfigDirectory("epgsearch");
+ cString epgsearchConf = "epgsearchtemplates.conf";
+ cString fileName = AddDirectory(*ConfigDir, *epgsearchConf);
+ if (access(fileName, F_OK) == 0) {
+ FILE *f = fopen(fileName, "r");
+ if (f) {
+ char *s;
+ cReadLine ReadLine;
+ while ((s = ReadLine.Read(f)) != NULL) {
+ char *p = strchr(s, '#');
+ if (p)
+ *p = 0;
+ stripspace(s);
+ try {
+ if (!isempty(s)) {
+ std::string templ = s;
+ int posID = templ.find_first_of(":");
+ int posName = templ.find_first_of(":", posID+1);
+ std::string name = templ.substr(posID+1, posName - posID - 1);
+ std::string templValue = templ.substr(posName);
+ TVGuideEPGSearchTemplate tmp;
+ tmp.name = name;
+ tmp.templValue = templValue;
+ epgTemplates->push_back(tmp);
+ }
+ } catch (...){}
+ }
+ }
+ }
+}
+
+const cEvent **cRecManager::PerformSearchTimerSearch(std::string epgSearchString, int &numResults) {
+ if (!epgSearchAvailable)
+ return NULL;
+ const cEvent **searchResults = NULL;
+ Epgsearch_services_v1_1 *epgSearch = new Epgsearch_services_v1_1;
+ if (epgSearchPlugin->Service("Epgsearch-services-v1.1", epgSearch)) {
+ std::list<std::string> results = epgSearch->handler->QuerySearch(epgSearchString);
+ numResults = results.size();
+ if (numResults > 0) {
+ searchResults = new const cEvent *[numResults];
+ cSchedulesLock schedulesLock;
+ const cSchedules *schedules;
+ schedules = cSchedules::Schedules(schedulesLock);
+ const cEvent *event = NULL;
+ int index=0;
+ for (std::list<std::string>::iterator it=results.begin(); it != results.end(); ++it) {
+ try {
+ splitstring s(it->c_str());
+ std::vector<std::string> flds = s.split(':', 1);
+ int eventID = atoi(flds[1].c_str());
+ std::string channelID = flds[7];
+ tChannelID chanID = tChannelID::FromString(channelID.c_str());
+ cChannel *channel = Channels.GetByChannelID(chanID);
+ if (channel) {
+ const cSchedule *Schedule = NULL;
+ Schedule = schedules->GetSchedule(channel);
+ event = Schedule->GetEvent(eventID);
+ if (event) {
+ searchResults[index] = event;
+ } else
+ return NULL;
+ } else
+ return NULL;
+ index++;
+ } catch (...){}
+ }
+ }
+ }
+ return searchResults;
+}
+
+const cEvent **cRecManager::PerformSearch(Epgsearch_searchresults_v1_0 data, int &numResults) {
+ if (epgSearchAvailable) {
+ if (epgSearchPlugin->Service("Epgsearch-searchresults-v1.0", &data)) {
+ cList<Epgsearch_searchresults_v1_0::cServiceSearchResult> *list = data.pResultList;
+ if (!list)
+ return NULL;
+ int numElements = list->Count();
+ const cEvent **searchResults = NULL;
+ if (numElements > 0) {
+ searchResults = new const cEvent *[numElements];
+ numResults = numElements;
+ int index = 0;
+ for (Epgsearch_searchresults_v1_0::cServiceSearchResult *r = list->First(); r ; r = list->Next(r)) {
+ searchResults[index] = r->event;
+ index++;
+ }
+ }
+ delete list;
+ return searchResults;
+ }
+ }
+ return NULL;
+}
+
+void cRecManager::GetSearchTimers(std::vector<cTVGuideSearchTimer> *searchTimer) {
+ if (!epgSearchAvailable) {
+ return;
+ }
+ Epgsearch_services_v1_1 *epgSearch = new Epgsearch_services_v1_1;
+ if (epgSearchPlugin->Service("Epgsearch-services-v1.1", epgSearch)) {
+ std::list<std::string> searchTimerList;
+ searchTimerList = epgSearch->handler->SearchTimerList();
+ for(std::list<std::string>::iterator it = searchTimerList.begin(); it != searchTimerList.end(); it++) {
+ cTVGuideSearchTimer timer;
+ timer.SetEPGSearchString(it->c_str());
+ if (timer.Parse())
+ searchTimer->push_back(timer);
+ }
+ }
+ std::sort(searchTimer->begin(), searchTimer->end());
+}
+
+int cRecManager::CreateSearchTimer(std::string epgSearchString) {
+ int timerID = -1;
+ if (!epgSearchAvailable)
+ return timerID;
+ Epgsearch_services_v1_1 *epgSearch = new Epgsearch_services_v1_1;
+ if (epgSearchPlugin->Service("Epgsearch-services-v1.1", epgSearch)) {
+ timerID = epgSearch->handler->AddSearchTimer(epgSearchString);
+ }
+ return timerID;
+}
+
+bool cRecManager::SaveSearchTimer(cTVGuideSearchTimer *searchTimer) {
+ if (!epgSearchAvailable)
+ return false;
+ Epgsearch_services_v1_1 *epgSearch = new Epgsearch_services_v1_1;
+ if (searchTimer->GetID() > -1) {
+ if (epgSearchPlugin->Service("Epgsearch-services-v1.1", epgSearch)) {
+ bool success = epgSearch->handler->ModSearchTimer(searchTimer->BuildSearchString());
+ if (success) {
+ esyslog("tvguide: search timer with id %d sucessfully modified", searchTimer->GetID());
+ return true;
+ } else {
+ esyslog("tvguide: error modifying search timer with id %d, build string %s", searchTimer->GetID(), searchTimer->BuildSearchString().c_str());
+ return false;
+ }
+ }
+ } else {
+ if (epgSearchPlugin->Service("Epgsearch-services-v1.1", epgSearch)) {
+ int timerID = epgSearch->handler->AddSearchTimer(searchTimer->BuildSearchString());
+ if (timerID >=0) {
+ esyslog("tvguide: search timer with id %d sucessfully created", timerID);
+ return true;
+ } else {
+ esyslog("tvguide: error creating search timer, build string %s", searchTimer->BuildSearchString().c_str());
+ return false;
+ }
+ }
+ }
+ return false;
+}
+
+void cRecManager::DeleteSearchTimer(cTVGuideSearchTimer *searchTimer, bool delTimers) {
+ if (!epgSearchAvailable)
+ return;
+ int searchTimerID = searchTimer->GetID();
+ if (delTimers) {
+ cTimer *timer = Timers.First();
+ while(timer) {
+ if (!timer->Recording()) {
+ char* searchID = GetAuxValue(timer, "s-id");
+ if (searchID) {
+ if (searchTimerID == atoi(searchID)) {
+ cTimer* timerNext = Timers.Next(timer);
+ DeleteTimer(timer);
+ timer = timerNext;
+ } else {
+ timer = Timers.Next(timer);
+ }
+ free(searchID);
+ } else {
+ timer = Timers.Next(timer);
+ }
+ } else {
+ timer = Timers.Next(timer);
+ }
+ }
+ }
+ Epgsearch_services_v1_1 *epgSearch = new Epgsearch_services_v1_1;
+ if (epgSearchPlugin->Service("Epgsearch-services-v1.1", epgSearch)) {
+ bool success = epgSearch->handler->DelSearchTimer(searchTimerID);
+ if (success) {
+ esyslog("tvguide: search timer \"%s\" sucessfully deleted", searchTimer->SearchString().c_str());
+ } else {
+ esyslog("tvguide: error deleting search timer \"%s\"", searchTimer->SearchString().c_str());
+ }
+ }
+}
+
+void cRecManager::UpdateSearchTimers(void) {
+ if (epgSearchAvailable) {
+ Epgsearch_updatesearchtimers_v1_0 data;
+ data.showMessage = false;
+ epgSearchPlugin->Service("Epgsearch-updatesearchtimers-v1.0", &data);
+ }
+}
+
+// announceOnly: 0 = switch, 1 = announce only, 2 = ask for switch
+bool cRecManager::CreateSwitchTimer(const cEvent *event, cSwitchTimer switchTimer) {
+ if (epgSearchAvailable && event) {
+ Epgsearch_switchtimer_v1_0 data;
+ data.event = event;
+ data.mode = 1;
+ data.switchMinsBefore = switchTimer.switchMinsBefore;
+ data.announceOnly = switchTimer.announceOnly;
+ data.success = false;
+ epgSearchPlugin->Service("Epgsearch-switchtimer-v1.0", &data);
+ cSwitchTimer *t = new cSwitchTimer(event);
+ SwitchTimers.Add(t);
+ return data.success;
+ }
+ return false;
+}
+
+void cRecManager::DeleteSwitchTimer(const cEvent *event) {
+ SwitchTimers.DeleteSwitchTimer(event);
+ if (epgSearchAvailable) {
+ Epgsearch_switchtimer_v1_0 data;
+ data.event = event;
+ data.mode = 2;
+ data.switchMinsBefore = 0;
+ data.announceOnly = 0;
+ data.success = false;
+ epgSearchPlugin->Service("Epgsearch-switchtimer-v1.0", &data);
+ }
+}
+
+cRecording **cRecManager::SearchForRecordings(std::string searchString, int &numResults) {
+
+ cRecording **matchingRecordings = NULL;
+ int num = 0;
+ numResults = 0;
+
+ for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) {
+ std::string s1 = recording->Name();
+ std::string s2 = searchString;
+ if (s1.empty() || s2.empty()) continue;
+
+ // tolerance for fuzzy searching: 90% of the shorter text length, but at least 1
+ int tolerance = std::max(1, (int)std::min(s1.size(), s2.size()) / 10);
+
+ bool match = FindIgnoreCase(s1, s2) >= 0 || FindIgnoreCase(s2, s1) >= 0;
+
+ if (!match) {
+ AFUZZY af = { NULL, NULL, NULL, NULL, NULL, NULL, { 0 }, { 0 }, 0, 0, 0, 0, 0, 0 };
+ if (s1.size() > 32) s1 = s1.substr(0, 32);
+ afuzzy_init(s1.c_str(), tolerance, 0, &af);
+ /* Checking substring */
+ int res = afuzzy_checkSUB(s2.c_str(), &af);
+ afuzzy_free(&af);
+ match = (res > 0);
+ }
+
+ if (!match) {
+ AFUZZY af = { NULL, NULL, NULL, NULL, NULL, NULL, { 0 }, { 0 }, 0, 0, 0, 0, 0, 0 };
+ if (s2.size() > 32) s2 = s2.substr(0, 32);
+ afuzzy_init(s2.c_str(), tolerance, 0, &af);
+ /* Checking substring */
+ int res = afuzzy_checkSUB(s1.c_str(), &af);
+ afuzzy_free(&af);
+ match = (res > 0);
+ }
+
+ if (match) {
+ matchingRecordings = (cRecording **)realloc(matchingRecordings, (num + 1) * sizeof(cRecording *));
+ matchingRecordings[num++] = recording;
+ }
+ }
+ if (num > 0) {
+ qsort(matchingRecordings, num, sizeof(cRecording *), CompareRecording);
+ numResults = num;
+ return matchingRecordings;
+ }
+ return NULL;
+}
+
+const cEvent **cRecManager::LoadReruns(const cEvent *event, int &numResults) {
+ if (epgSearchAvailable && !isempty(event->Title())) {
+ Epgsearch_searchresults_v1_0 data;
+ std::string strQuery = event->Title();
+ if (config.useSubtitleRerun > 0) {
+ if (config.useSubtitleRerun == 2 || !isempty(event->ShortText()))
+ strQuery += "~";
+ if (!isempty(event->ShortText()))
+ strQuery += event->ShortText();
+ data.useSubTitle = true;
+ } else {
+ data.useSubTitle = false;
+ }
+ data.query = (char *)strQuery.c_str();
+ data.mode = 0;
+ data.channelNr = 0;
+ data.useTitle = true;
+ data.useDescription = false;
+
+ if (epgSearchPlugin->Service("Epgsearch-searchresults-v1.0", &data)) {
+ cList<Epgsearch_searchresults_v1_0::cServiceSearchResult>* list = data.pResultList;
+ if (!list)
+ return NULL;
+ const cEvent **searchResults = NULL;
+ int numElements = list->Count();
+ if (numElements > 0) {
+ searchResults = new const cEvent *[numElements];
+ int index = 0;
+ for (Epgsearch_searchresults_v1_0::cServiceSearchResult *r = list->First(); r; r = list->Next(r)) {
+ if ((event->ChannelID() == r->event->ChannelID()) && (event->StartTime() == r->event->StartTime()))
+ continue;
+ searchResults[index] = r->event;
+ index++;
+ }
+ delete list;
+ numResults = index;
+ return searchResults;
+ }
+ }
+ }
+ return NULL;
+}
+
+void cRecManager::GetFavorites(std::vector<cTVGuideSearchTimer> *favorites) {
+ if (!epgSearchAvailable) {
+ return;
+ }
+ Epgsearch_services_v1_1 *epgSearch = new Epgsearch_services_v1_1;
+ if (epgSearchPlugin->Service("Epgsearch-services-v1.1", epgSearch)) {
+ std::list<std::string> searchTimerList;
+ searchTimerList = epgSearch->handler->SearchTimerList();
+ for(std::list<std::string>::iterator it = searchTimerList.begin(); it != searchTimerList.end(); it++) {
+ cTVGuideSearchTimer timer;
+ timer.SetEPGSearchString(it->c_str());
+ if (timer.Parse()) {
+ if (timer.UseInFavorites())
+ favorites->push_back(timer);
+ }
+ }
+ }
+
+}
+
+const cEvent **cRecManager::WhatsOnNow(bool nowOrNext, int &numResults) {
+ std::vector<const cEvent*> tmpResults;
+ cSchedulesLock schedulesLock;
+ const cSchedules *schedules = cSchedules::Schedules(schedulesLock);
+ const cChannel *startChannel = NULL, *stopChannel = NULL;
+ if (config.favLimitChannels) {
+ startChannel = Channels.GetByNumber(config.favStartChannel);
+ stopChannel = Channels.GetByNumber(config.favStopChannel);
+ }
+ if (!startChannel)
+ startChannel = Channels.First();
+
+ for (const cChannel *channel = startChannel; channel; channel = Channels.Next(channel)) {
+ if (channel->GroupSep()) continue;
+ const cSchedule *Schedule = schedules->GetSchedule(channel);
+ if (!Schedule) continue;
+
+ const cEvent *event = NULL;
+ if (nowOrNext)
+ event = Schedule->GetPresentEvent();
+ else
+ event = Schedule->GetFollowingEvent();
+ if (event) {
+ tmpResults.push_back(event);
+ }
+ if (stopChannel && (stopChannel->Number() <= channel->Number()))
+ break;
+ }
+ numResults = tmpResults.size();
+ const cEvent **results = new const cEvent *[numResults];
+ for (int i=0; i<numResults; i++) {
+ results[i] = tmpResults[i];
+ }
+
+ return results;
+}
+
+const cEvent **cRecManager::UserDefinedTime(int userTime, int &numResults) {
+ std::vector<const cEvent*> tmpResults;
+ int favTime = 0;
+ if (userTime == 1) {
+ favTime = config.favTime1;
+ } else if (userTime == 2) {
+ favTime = config.favTime2;
+ } else if (userTime == 3) {
+ favTime = config.favTime3;
+ } else if (userTime == 4) {
+ favTime = config.favTime4;
+ }
+
+ time_t now = time(0);
+ tm *midn = localtime(&now);
+ midn->tm_sec = 0;
+ midn->tm_min = 0;
+ midn->tm_hour = 0;
+ time_t midnight = mktime(midn);
+ int hours = favTime/100;
+ int mins = favTime - hours * 100;
+ time_t searchTime = midnight + hours*60*60 + mins*60;
+ if (searchTime < now)
+ searchTime += 24*60*60;
+
+ cSchedulesLock schedulesLock;
+ const cSchedules *schedules = cSchedules::Schedules(schedulesLock);
+ const cChannel *startChannel = NULL, *stopChannel = NULL;
+ if (config.favLimitChannels) {
+ startChannel = Channels.GetByNumber(config.favStartChannel);
+ stopChannel = Channels.GetByNumber(config.favStopChannel);
+ }
+ if (!startChannel)
+ startChannel = Channels.First();
+
+ for (const cChannel *channel = startChannel; channel; channel = Channels.Next(channel)) {
+ if (channel->GroupSep()) continue;
+ const cSchedule *Schedule = schedules->GetSchedule(channel);
+ if (!Schedule) continue;
+ const cEvent *event = Schedule->GetEventAround(searchTime);
+ if (!event) continue;
+ //if event is more or less over (only 15mns left), take next
+ if ((event->EndTime() - searchTime) < 15*60) {
+ event = Schedule->Events()->Next(event);
+ }
+ if (event)
+ tmpResults.push_back(event);
+ if (stopChannel && (stopChannel->Number() <= channel->Number()))
+ break;
+ }
+
+ numResults = tmpResults.size();
+ const cEvent **results = new const cEvent *[numResults];
+ for (int i=0; i<numResults; i++) {
+ results[i] = tmpResults[i];
+ }
+ return results;
+}