CFileItemPtr CPVRTimers::GetTimerForEpgTag(const CFileItem *item) const { if (item && item->HasEPGInfoTag() && item->GetEPGInfoTag()->ChannelTag()) { const CEpgInfoTagPtr epgTag(item->GetEPGInfoTag()); const CPVRChannelPtr channel(epgTag->ChannelTag()); CSingleLock lock(m_critSection); for (MapTags::const_iterator it = m_tags.begin(); it != m_tags.end(); ++it) { for (VecTimerInfoTag::const_iterator timerIt = it->second->begin(); timerIt != it->second->end(); ++timerIt) { CPVRTimerInfoTagPtr timer = *timerIt; if (timer->GetEpgInfoTag() == epgTag || (timer->m_iClientChannelUid == channel->UniqueID() && timer->m_bIsRadio == channel->IsRadio() && timer->StartAsUTC() <= epgTag->StartAsUTC() && timer->EndAsUTC() >= epgTag->EndAsUTC())) { 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; std::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; CPVRTimerInfoTagPtr 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; }
std::vector<CEpgInfoTagPtr> CEpgContainer::GetEpgTagsForTimer(const CPVRTimerInfoTagPtr &timer) const { CPVRChannelPtr channel(timer->ChannelTag()); if (!channel) channel = timer->UpdateChannel(); if (channel) { const CEpgPtr epg(channel->GetEPG()); if (epg) return epg->GetTagsBetween(timer->StartAsUTC(), timer->EndAsUTC()); } return std::vector<CEpgInfoTagPtr>(); }
void CPVRTimers::UpdateEpgEvent(CPVRTimerInfoTagPtr timer) { CSingleLock lock(timer->m_critSection); /* repeating timers have no epg event */ if (timer->IsRepeating()) return; /* already got an epg event set */ if (timer->m_epgTag) return; /* try to get the channel */ CPVRChannelPtr channel = g_PVRChannelGroups->GetByUniqueID(timer->m_iClientChannelUid, timer->m_iClientId); if (!channel) return; /* try to get the EPG table */ CEpgPtr epg = channel->GetEPG(); if (!epg) return; /* try to set the timer on the epg tag that matches with a 2 minute margin */ CEpgInfoTagPtr epgTag = epg->GetTagBetween(timer->StartAsUTC() - CDateTimeSpan(0, 0, 2, 0), timer->EndAsUTC() + CDateTimeSpan(0, 0, 2, 0)); if (!epgTag) epgTag = epg->GetTagAround(timer->StartAsUTC()); if (epgTag) { timer->m_epgTag = epgTag; timer->m_genre = epgTag->Genre(); timer->m_iGenreType = epgTag->GenreType(); timer->m_iGenreSubType = epgTag->GenreSubType(); epgTag->SetTimer(timer); } }
bool CPVRTimers::UpdateEntries(const 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<CPVRTimerInfoTagPtr>* >::const_iterator it = timers.m_tags.begin(); it != timers.m_tags.end(); it++) { for (vector<CPVRTimerInfoTagPtr>::const_iterator timerIt = it->second->begin(); timerIt != it->second->end(); timerIt++) { /* check if this timer is present in this container */ CPVRTimerInfoTagPtr existingTimer = GetByClient((*timerIt)->m_iClientId, (*timerIt)->m_iClientIndex); if (existingTimer) { /* if it's present, update the current tag */ bool bStateChanged(existingTimer->m_state != (*timerIt)->m_state); if (existingTimer->UpdateEntry(*(*timerIt))) { bChanged = true; UpdateEpgEvent(existingTimer); 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__, (*timerIt)->m_iClientIndex, (*timerIt)->m_iClientId); } } else { /* new timer */ CPVRTimerInfoTagPtr newTimer = CPVRTimerInfoTagPtr(new CPVRTimerInfoTag); newTimer->UpdateEntry(*(*timerIt)); UpdateEpgEvent(newTimer); vector<CPVRTimerInfoTagPtr>* addEntry = NULL; map<CDateTime, vector<CPVRTimerInfoTagPtr>* >::iterator itr = m_tags.find(newTimer->StartAsUTC()); if (itr == m_tags.end()) { addEntry = new vector<CPVRTimerInfoTagPtr>; m_tags.insert(make_pair(newTimer->StartAsUTC(), addEntry)); } else { addEntry = itr->second; } addEntry->push_back(newTimer); UpdateEpgEvent(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__, (*timerIt)->m_iClientIndex, (*timerIt)->m_iClientId); } } } /* to collect timer with changed starting time */ vector<CPVRTimerInfoTagPtr> timersToMove; /* check for deleted timers */ for (map<CDateTime, vector<CPVRTimerInfoTagPtr>* >::iterator it = m_tags.begin(); it != m_tags.end();) { for (int iTimerPtr = it->second->size() - 1; iTimerPtr >= 0; iTimerPtr--) { CPVRTimerInfoTagPtr timer = it->second->at(iTimerPtr); if (!timers.GetByClient(timer->m_iClientId, timer->m_iClientIndex)) { /* 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); } it->second->erase(it->second->begin() + iTimerPtr); 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); timer->ClearEpgTag(); /* remember timer */ timersToMove.push_back(timer); /* remove timer for now, reinsert later */ it->second->erase(it->second->begin() + iTimerPtr); bChanged = true; bAddedOrDeleted = true; } } if (it->second->size() == 0) m_tags.erase(it++); else ++it; } /* reinsert timers with changed timer start */ for (vector<CPVRTimerInfoTagPtr>::const_iterator timerIt = timersToMove.begin(); timerIt != timersToMove.end(); timerIt++) { vector<CPVRTimerInfoTagPtr>* addEntry = NULL; map<CDateTime, vector<CPVRTimerInfoTagPtr>* >::const_iterator itr = m_tags.find((*timerIt)->StartAsUTC()); if (itr == m_tags.end()) { addEntry = new vector<CPVRTimerInfoTagPtr>; m_tags.insert(make_pair((*timerIt)->StartAsUTC(), addEntry)); } else { addEntry = itr->second; } addEntry->push_back(*timerIt); UpdateEpgEvent(*timerIt); } m_bIsUpdating = false; if (bChanged) { UpdateChannels(); SetChanged(); lock.Leave(); NotifyObservers(bAddedOrDeleted ? ObservableMessageTimersReset : ObservableMessageTimers); 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; }