int EpgSearchFilter::FilterTimers(CFileItemList &results) { int iRemoved(0); if (!g_PVRManager.IsStarted()) return iRemoved; vector<CPVRTimerInfoTag *> timers; g_PVRTimers->GetActiveTimers(&timers); // TODO not thread safe and inefficient! for (unsigned int iTimerPtr = 0; iTimerPtr < timers.size(); iTimerPtr++) { CPVRTimerInfoTag *timer = timers.at(iTimerPtr); if (!timer) continue; for (int iResultPtr = 0; iResultPtr < results.Size(); iResultPtr++) { const CEpgInfoTag *epgentry = results.Get(iResultPtr)->GetEPGInfoTag(); if (!epgentry || *epgentry->ChannelTag() != *timer->m_channel || epgentry->StartAsUTC() < timer->StartAsUTC() || epgentry->EndAsUTC() > timer->EndAsUTC()) continue; results.Remove(iResultPtr); iResultPtr--; ++iRemoved; } } return iRemoved; }
/*! * @brief Copy over timer info from xbmcTimer to addonTimer. * @param xbmcTimer The timer on XBMC's side. * @param addonTimer The timer on the addon's side. */ void CPVRClient::WriteClientTimerInfo(const CPVRTimerInfoTag &xbmcTimer, PVR_TIMER &addonTimer) { time_t start, end, firstDay; xbmcTimer.StartAsUTC().GetAsTime(start); xbmcTimer.EndAsUTC().GetAsTime(end); xbmcTimer.FirstDayAsUTC().GetAsTime(firstDay); CEpgInfoTagPtr epgTag = xbmcTimer.GetEpgInfoTag(); memset(&addonTimer, 0, sizeof(addonTimer)); addonTimer.iClientIndex = xbmcTimer.m_iClientIndex; addonTimer.state = xbmcTimer.m_state; addonTimer.iClientIndex = xbmcTimer.m_iClientIndex; addonTimer.iClientChannelUid = xbmcTimer.m_iClientChannelUid; strncpy(addonTimer.strTitle, xbmcTimer.m_strTitle.c_str(), sizeof(addonTimer.strTitle) - 1); strncpy(addonTimer.strDirectory, xbmcTimer.m_strDirectory.c_str(), sizeof(addonTimer.strDirectory) - 1); addonTimer.iPriority = xbmcTimer.m_iPriority; addonTimer.iLifetime = xbmcTimer.m_iLifetime; addonTimer.bIsRepeating = xbmcTimer.m_bIsRepeating; addonTimer.iWeekdays = xbmcTimer.m_iWeekdays; addonTimer.startTime = start - g_advancedSettings.m_iPVRTimeCorrection; addonTimer.endTime = end - g_advancedSettings.m_iPVRTimeCorrection; addonTimer.firstDay = firstDay - g_advancedSettings.m_iPVRTimeCorrection; addonTimer.iEpgUid = epgTag ? epgTag->UniqueBroadcastID() : -1; strncpy(addonTimer.strSummary, xbmcTimer.m_strSummary.c_str(), sizeof(addonTimer.strSummary) - 1); addonTimer.iMarginStart = xbmcTimer.m_iMarginStart; addonTimer.iMarginEnd = xbmcTimer.m_iMarginEnd; addonTimer.iGenreType = xbmcTimer.m_iGenreType; addonTimer.iGenreSubType = xbmcTimer.m_iGenreSubType; }
CPVRTimerInfoTag *CPVRTimers::GetMatch(const CEpgInfoTag *Epg) { CPVRTimerInfoTag *returnTag = NULL; CSingleLock lock(m_critSection); for (unsigned int ptr = 0; ptr < size(); ptr++) { CPVRTimerInfoTag *timer = at(ptr); if (!Epg || !Epg->GetTable() || !Epg->GetTable()->Channel()) continue; const CPVRChannel *channel = Epg->GetTable()->Channel(); if (timer->ChannelNumber() != channel->ChannelNumber() || timer->m_bIsRadio != channel->IsRadio()) continue; if (timer->StartAsUTC() > Epg->StartAsUTC() || timer->EndAsUTC() < Epg->EndAsUTC()) continue; returnTag = timer; break; } return returnTag; }
void CPVRClient::WriteClientTimerInfo(const CPVRTimerInfoTag &xbmcTimer, PVR_TIMER &addonTimer) { time_t start, end, firstDay; xbmcTimer.StartAsUTC().GetAsTime(start); xbmcTimer.EndAsUTC().GetAsTime(end); xbmcTimer.FirstDayAsUTC().GetAsTime(firstDay); addonTimer.iClientIndex = xbmcTimer.m_iClientIndex; addonTimer.bIsActive = xbmcTimer.m_bIsActive; addonTimer.iClientIndex = xbmcTimer.m_iClientIndex; addonTimer.iClientChannelUid = xbmcTimer.m_iClientChannelUid; addonTimer.bIsRecording = xbmcTimer.m_bIsRecording; addonTimer.strTitle = xbmcTimer.m_strTitle; addonTimer.strDirectory = xbmcTimer.m_strDirectory; addonTimer.iPriority = xbmcTimer.m_iPriority; addonTimer.iLifetime = xbmcTimer.m_iLifetime; addonTimer.bIsRepeating = xbmcTimer.m_bIsRepeating; addonTimer.iWeekdays = xbmcTimer.m_iWeekdays; addonTimer.startTime = start - g_advancedSettings.m_iPVRTimeCorrection; addonTimer.endTime = end - g_advancedSettings.m_iPVRTimeCorrection; addonTimer.firstDay = firstDay - g_advancedSettings.m_iPVRTimeCorrection; addonTimer.iEpgUid = xbmcTimer.m_epgInfo ? xbmcTimer.m_epgInfo->UniqueBroadcastID() : -1; addonTimer.strSummary = xbmcTimer.m_strSummary.c_str(); addonTimer.iMarginStart = xbmcTimer.m_iMarginStart; addonTimer.iMarginEnd = xbmcTimer.m_iMarginEnd; }
CFileItemPtr CPVRTimers::GetMatch(const CEpgInfoTag *Epg) { CSingleLock lock(m_critSection); for (map<CDateTime, vector<CPVRTimerInfoTag *>* >::iterator it = m_tags.begin(); it != m_tags.end(); it++) { for (unsigned int iTimerPtr = 0; iTimerPtr < it->second->size(); iTimerPtr++) { CPVRTimerInfoTag *timer = it->second->at(iTimerPtr); CPVRChannelPtr channel; if (Epg) channel = Epg->ChannelTag(); if (!channel) continue; if (timer->ChannelNumber() != channel->ChannelNumber() || timer->m_bIsRadio != channel->IsRadio()) continue; if (timer->StartAsUTC() > Epg->StartAsUTC() || timer->EndAsUTC() < Epg->EndAsUTC()) continue; CFileItemPtr fileItem(new CFileItem(*timer)); return fileItem; } } CFileItemPtr fileItem; return fileItem; }
int EpgSearchFilter::FilterTimers(CFileItemList &results) { int iRemoved(0); if (!g_PVRManager.IsStarted()) return iRemoved; vector<CFileItemPtr> timers = g_PVRTimers->GetActiveTimers(); // TODO inefficient! for (unsigned int iTimerPtr = 0; iTimerPtr < timers.size(); iTimerPtr++) { CFileItemPtr fileItem = timers.at(iTimerPtr); if (!fileItem || !fileItem->HasPVRTimerInfoTag()) continue; CPVRTimerInfoTag *timer = fileItem->GetPVRTimerInfoTag(); if (!timer) continue; for (int iResultPtr = 0; iResultPtr < results.Size(); iResultPtr++) { const CEpgInfoTagPtr epgentry(results.Get(iResultPtr)->GetEPGInfoTag()); if (!epgentry || *epgentry->ChannelTag() != *timer->ChannelTag() || epgentry->StartAsUTC() < timer->StartAsUTC() || epgentry->EndAsUTC() > timer->EndAsUTC()) continue; results.Remove(iResultPtr); iResultPtr--; ++iRemoved; } } return iRemoved; }
/*! * @brief Copy over timer info from xbmcTimer to addonTimer. * @param xbmcTimer The timer on XBMC's side. * @param addonTimer The timer on the addon's side. */ void CPVRClient::WriteClientTimerInfo(const CPVRTimerInfoTag &xbmcTimer, PVR_TIMER &addonTimer) { time_t start, end, firstDay; xbmcTimer.StartAsUTC().GetAsTime(start); xbmcTimer.EndAsUTC().GetAsTime(end); xbmcTimer.FirstDayAsUTC().GetAsTime(firstDay); CPVREpgInfoTagPtr epgTag = xbmcTimer.GetEpgInfoTag(); memset(&addonTimer, 0, sizeof(addonTimer)); addonTimer.iClientIndex = xbmcTimer.m_iClientIndex; addonTimer.iParentClientIndex = xbmcTimer.m_iParentClientIndex; addonTimer.state = xbmcTimer.m_state; addonTimer.iTimerType = xbmcTimer.GetTimerType() ? xbmcTimer.GetTimerType()->GetTypeId() : PVR_TIMER_TYPE_NONE; addonTimer.iClientChannelUid = xbmcTimer.m_iClientChannelUid; strncpy(addonTimer.strTitle, xbmcTimer.m_strTitle.c_str(), sizeof(addonTimer.strTitle) - 1); strncpy(addonTimer.strEpgSearchString, xbmcTimer.m_strEpgSearchString.c_str(), sizeof(addonTimer.strEpgSearchString) - 1); addonTimer.bFullTextEpgSearch = xbmcTimer.m_bFullTextEpgSearch; strncpy(addonTimer.strDirectory, xbmcTimer.m_strDirectory.c_str(), sizeof(addonTimer.strDirectory) - 1); addonTimer.iPriority = xbmcTimer.m_iPriority; addonTimer.iLifetime = xbmcTimer.m_iLifetime; addonTimer.iMaxRecordings = xbmcTimer.m_iMaxRecordings; addonTimer.iPreventDuplicateEpisodes = xbmcTimer.m_iPreventDupEpisodes; addonTimer.iRecordingGroup = xbmcTimer.m_iRecordingGroup; addonTimer.iWeekdays = xbmcTimer.m_iWeekdays; addonTimer.startTime = start - g_advancedSettings.m_iPVRTimeCorrection; addonTimer.endTime = end - g_advancedSettings.m_iPVRTimeCorrection; addonTimer.bStartAnyTime = xbmcTimer.m_bStartAnyTime; addonTimer.bEndAnyTime = xbmcTimer.m_bEndAnyTime; addonTimer.firstDay = firstDay - g_advancedSettings.m_iPVRTimeCorrection; addonTimer.iEpgUid = epgTag ? epgTag->UniqueBroadcastID() : PVR_TIMER_NO_EPG_UID; strncpy(addonTimer.strSummary, xbmcTimer.m_strSummary.c_str(), sizeof(addonTimer.strSummary) - 1); addonTimer.iMarginStart = xbmcTimer.m_iMarginStart; addonTimer.iMarginEnd = xbmcTimer.m_iMarginEnd; addonTimer.iGenreType = epgTag ? epgTag->GenreType() : 0; addonTimer.iGenreSubType = epgTag ? epgTag->GenreSubType() : 0; }
bool CPVRTimers::UpdateEntries(CPVRTimers *timers) { bool bChanged(false); bool bAddedOrDeleted(false); vector<CStdString> timerNotifications; CSingleLock lock(m_critSection); /* go through the timer list and check for updated or new timers */ for (map<CDateTime, vector<CPVRTimerInfoTag *>* >::iterator it = timers->m_tags.begin(); it != timers->m_tags.end(); it++) { vector<CPVRTimerInfoTag*> *entry = it->second; for (unsigned int iTagPtr = 0; iTagPtr < entry->size(); iTagPtr++) { const CPVRTimerInfoTag *timer = entry->at(iTagPtr); /* check if this timer is present in this container */ CPVRTimerInfoTag *existingTimer = (CPVRTimerInfoTag *) GetByClient(timer->m_iClientId, timer->m_iClientIndex); if (existingTimer) { /* if it's present, update the current tag */ bool bStateChanged(existingTimer->m_state != timer->m_state); if (existingTimer->UpdateEntry(*timer)) { bChanged = true; if (bStateChanged && g_PVRManager.IsStarted()) { CStdString strMessage; existingTimer->GetNotificationText(strMessage); timerNotifications.push_back(strMessage); } CLog::Log(LOGDEBUG,"PVRTimers - %s - updated timer %d on client %d", __FUNCTION__, timer->m_iClientIndex, timer->m_iClientId); } } else { /* new timer */ CPVRTimerInfoTag *newTimer = new CPVRTimerInfoTag; newTimer->UpdateEntry(*timer); vector<CPVRTimerInfoTag *>* addEntry = NULL; map<CDateTime, vector<CPVRTimerInfoTag *>* >::iterator itr = m_tags.find(newTimer->StartAsUTC()); if (itr == m_tags.end()) { addEntry = new vector<CPVRTimerInfoTag *>; m_tags.insert(make_pair(newTimer->StartAsUTC(), addEntry)); } else { addEntry = itr->second; } addEntry->push_back(newTimer); bChanged = true; bAddedOrDeleted = true; if (g_PVRManager.IsStarted()) { CStdString strMessage; newTimer->GetNotificationText(strMessage); timerNotifications.push_back(strMessage); } CLog::Log(LOGDEBUG,"PVRTimers - %s - added timer %d on client %d", __FUNCTION__, timer->m_iClientIndex, timer->m_iClientId); } } } /* to collect timer with changed starting time */ vector<CPVRTimerInfoTag *> timersToMove; /* check for deleted timers */ for (map<CDateTime, vector<CPVRTimerInfoTag *>* >::iterator it = m_tags.begin(); it != m_tags.end();) { vector<CPVRTimerInfoTag*> *entry = it->second; for (int iTagPtr = entry->size() - 1; iTagPtr >= 0; iTagPtr--) { CPVRTimerInfoTag *timer = entry->at(iTagPtr); if (!timer) continue; if (timers->GetByClient(timer->m_iClientId, timer->m_iClientIndex) == NULL) { /* timer was not found */ CLog::Log(LOGDEBUG,"PVRTimers - %s - deleted timer %d on client %d", __FUNCTION__, timer->m_iClientIndex, timer->m_iClientId); if (g_PVRManager.IsStarted()) { CStdString strMessage; strMessage.Format("%s: '%s'", (timer->EndAsUTC() <= CDateTime::GetCurrentDateTime().GetAsUTCDateTime()) ? g_localizeStrings.Get(19227) : g_localizeStrings.Get(19228), timer->m_strTitle.c_str()); timerNotifications.push_back(strMessage); } delete entry->at(iTagPtr); entry->erase(entry->begin() + iTagPtr); bChanged = true; bAddedOrDeleted = true; } else if (timer->StartAsUTC() != it->first) { /* timer start has changed */ CLog::Log(LOGDEBUG,"PVRTimers - %s - changed start time timer %d on client %d", __FUNCTION__, timer->m_iClientIndex, timer->m_iClientId); /* remember timer */ timersToMove.push_back(entry->at(iTagPtr)); /* remove timer for now, reinsert later */ entry->erase(entry->begin() + iTagPtr); bChanged = true; bAddedOrDeleted = true; } } if (entry->size() == 0) m_tags.erase(it++); else ++it; } /* reinsert timers with changed timer start */ for (unsigned int iTagPtr = 0; iTagPtr < timersToMove.size(); iTagPtr++) { CPVRTimerInfoTag *timer = timersToMove.at(iTagPtr); vector<CPVRTimerInfoTag *>* addEntry = NULL; map<CDateTime, vector<CPVRTimerInfoTag *>* >::iterator itr = m_tags.find(timer->StartAsUTC()); if (itr == m_tags.end()) { addEntry = new vector<CPVRTimerInfoTag *>; m_tags.insert(make_pair(timer->StartAsUTC(), addEntry)); } else { addEntry = itr->second; } addEntry->push_back(timer); } m_bIsUpdating = false; if (bChanged) { SetChanged(); lock.Leave(); NotifyObservers(bAddedOrDeleted ? "timers-reset" : "timers", false); if (g_guiSettings.GetBool("pvrrecord.timernotifications")) { /* queue notifications */ for (unsigned int iNotificationPtr = 0; iNotificationPtr < timerNotifications.size(); iNotificationPtr++) { CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, g_localizeStrings.Get(19166), timerNotifications.at(iNotificationPtr)); } } } return bChanged; }
bool CPVRTimers::UpdateEntries(CPVRTimers *timers) { bool bChanged(false); bool bAddedOrDeleted(false); vector<CStdString> timerNotifications; CSingleLock lock(m_critSection); /* go through the timer list and check for updated or new timers */ for (unsigned int iTimerPtr = 0; iTimerPtr < timers->size(); iTimerPtr++) { const CPVRTimerInfoTag *timer = timers->at(iTimerPtr); /* check if this timer is present in this container */ CPVRTimerInfoTag *existingTimer = (CPVRTimerInfoTag *) GetByClient(timer->m_iClientId, timer->m_iClientIndex); if (existingTimer) { /* if it's present, update the current tag */ bool bStateChanged(existingTimer->m_state != timer->m_state); if (existingTimer->UpdateEntry(*timer)) { bChanged = true; if (bStateChanged && g_PVRManager.IsStarted()) { CStdString strMessage; existingTimer->GetNotificationText(strMessage); timerNotifications.push_back(strMessage); } CLog::Log(LOGDEBUG,"PVRTimers - %s - updated timer %d on client %d", __FUNCTION__, timer->m_iClientIndex, timer->m_iClientId); } } else { /* new timer */ CPVRTimerInfoTag *newTimer = new CPVRTimerInfoTag; newTimer->UpdateEntry(*timer); push_back(newTimer); bChanged = true; bAddedOrDeleted = true; if (g_PVRManager.IsStarted()) { CStdString strMessage; newTimer->GetNotificationText(strMessage); timerNotifications.push_back(strMessage); } CLog::Log(LOGDEBUG,"PVRTimers - %s - added timer %d on client %d", __FUNCTION__, timer->m_iClientIndex, timer->m_iClientId); } } /* check for deleted timers */ unsigned int iSize = size(); for (unsigned int iTimerPtr = 0; iTimerPtr < iSize; iTimerPtr++) { CPVRTimerInfoTag *timer = (CPVRTimerInfoTag *) at(iTimerPtr); if (!timer) continue; if (timers->GetByClient(timer->m_iClientId, timer->m_iClientIndex) == NULL) { /* timer was not found */ CLog::Log(LOGDEBUG,"PVRTimers - %s - deleted timer %d on client %d", __FUNCTION__, timer->m_iClientIndex, timer->m_iClientId); if (g_PVRManager.IsStarted()) { CStdString strMessage; strMessage.Format("%s: '%s'", (timer->EndAsUTC() <= CDateTime::GetCurrentDateTime().GetAsUTCDateTime()) ? g_localizeStrings.Get(19227) : g_localizeStrings.Get(19228), timer->m_strTitle.c_str()); timerNotifications.push_back(strMessage); } CEpgInfoTag *epgTag = at(iTimerPtr)->GetEpgInfoTag(); if (epgTag) epgTag->SetTimer(NULL); delete at(iTimerPtr); erase(begin() + iTimerPtr); iTimerPtr--; iSize--; bChanged = true; bAddedOrDeleted = true; } } m_bIsUpdating = false; if (bChanged) { Sort(); SetChanged(); lock.Leave(); NotifyObservers(bAddedOrDeleted ? "timers-reset" : "timers", false); if (g_guiSettings.GetBool("pvrrecord.timernotifications")) { /* queue notifications */ for (unsigned int iNotificationPtr = 0; iNotificationPtr < timerNotifications.size(); iNotificationPtr++) { CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, g_localizeStrings.Get(19166), timerNotifications.at(iNotificationPtr)); } } } return bChanged; }