bool CPVRChannelGroup::AddToGroup(const CPVRChannelPtr &channel, int iChannelNumber /* = 0 */) { CSingleLock lock(m_critSection); bool bReturn(false); if (!CPVRChannelGroup::IsGroupMember(channel)) { if (iChannelNumber <= 0 || iChannelNumber > (int) m_members.size() + 1) iChannelNumber = m_members.size() + 1; CPVRChannelPtr realChannel = (IsInternalGroup()) ? GetByClient(channel->UniqueID(), channel->ClientID()) : g_PVRChannelGroups->GetGroupAll(m_bRadio)->GetByClient(channel->UniqueID(), channel->ClientID()); if (realChannel) { PVRChannelGroupMember newMember = { realChannel, (unsigned int)iChannelNumber }; m_members.push_back(newMember); m_bChanged = true; SortAndRenumber(); // TODO notify observers bReturn = true; } } return bReturn; }
bool CPVRChannelGroup::RemoveDeletedChannels(const CPVRChannelGroup &channels) { bool bReturn(false); CSingleLock lock(m_critSection); /* check for deleted channels */ for (int iChannelPtr = m_members.size() - 1; iChannelPtr >= 0; iChannelPtr--) { CPVRChannelPtr channel = m_members.at(iChannelPtr).channel; if (!channel) continue; if (channels.GetByClient(channel->UniqueID(), channel->ClientID()) == NULL) { /* channel was not found */ CLog::Log(LOGINFO,"PVRChannelGroup - %s - deleted %s channel '%s' from group '%s'", __FUNCTION__, m_bRadio ? "radio" : "TV", channel->ChannelName().c_str(), GroupName().c_str()); /* remove this channel from all non-system groups if this is the internal group */ if (IsInternalGroup()) { g_PVRChannelGroups->Get(m_bRadio)->RemoveFromAllGroups(*channel); /* since it was not found in the internal group, it was deleted from the backend */ channel->Delete(); } m_members.erase(m_members.begin() + iChannelPtr); m_bChanged = true; bReturn = true; } } return bReturn; }
CPVRTimerInfoTag::CPVRTimerInfoTag(const PVR_TIMER &timer, const CPVRChannelPtr &channel, unsigned int iClientId) : m_strTitle(timer.strTitle), m_strDirectory(timer.strDirectory) { m_iClientId = iClientId; m_iClientIndex = timer.iClientIndex; m_iClientChannelUid = channel ? channel->UniqueID() : timer.iClientChannelUid; m_iChannelNumber = channel ? g_PVRChannelGroups->GetGroupAll(channel->IsRadio())->GetChannelNumber(channel) : 0; m_StartTime = timer.startTime + g_advancedSettings.m_iPVRTimeCorrection; m_StopTime = timer.endTime + g_advancedSettings.m_iPVRTimeCorrection; m_bIsRepeating = timer.bIsRepeating; m_FirstDay = timer.firstDay + g_advancedSettings.m_iPVRTimeCorrection; m_iWeekdays = timer.iWeekdays; m_iPriority = timer.iPriority; m_iLifetime = timer.iLifetime; m_iMarginStart = timer.iMarginStart; m_iMarginEnd = timer.iMarginEnd; m_genre = StringUtils::Split(CEpg::ConvertGenreIdToString(timer.iGenreType, timer.iGenreSubType), g_advancedSettings.m_videoItemSeparator); m_iGenreType = timer.iGenreType; m_iGenreSubType = timer.iGenreSubType; CEpgInfoTagPtr emptyTag; m_epgTag = emptyTag; m_channel = channel; m_bIsRadio = channel && channel->IsRadio(); m_state = timer.state; m_strFileNameAndPath = StringUtils::Format("pvr://client%i/timers/%i", m_iClientId, m_iClientIndex); m_iTimerId = 0; UpdateSummary(); }
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; }
CPVRTimerInfoTagPtr CPVRTimerInfoTag::CreateInstantTimerTag(const CPVRChannelPtr &channel) { if (!channel) { CLog::Log(LOGERROR, "%s - no channel set", __FUNCTION__); return CPVRTimerInfoTagPtr(); } CEpgInfoTagPtr epgTag(channel->GetEPGNow()); CPVRTimerInfoTagPtr newTimer; if (epgTag) newTimer = CreateFromEpg(epgTag); if (!newTimer) { newTimer.reset(new CPVRTimerInfoTag); newTimer->m_iClientIndex = PVR_TIMER_NO_CLIENT_INDEX; newTimer->m_iParentClientIndex = PVR_TIMER_NO_PARENT; newTimer->m_channel = channel; newTimer->m_strTitle = channel->ChannelName(); newTimer->m_iChannelNumber = channel->ChannelNumber(); newTimer->m_iClientChannelUid = channel->UniqueID(); newTimer->m_iClientId = channel->ClientID(); newTimer->m_bIsRadio = channel->IsRadio(); // timertype: manual one-shot timer for given client CPVRTimerTypePtr timerType(CPVRTimerType::CreateFromAttributes( PVR_TIMER_TYPE_IS_MANUAL, PVR_TIMER_TYPE_IS_REPEATING | PVR_TIMER_TYPE_FORBIDS_NEW_INSTANCES, channel->ClientID())); if (!timerType) { CLog::Log(LOGERROR, "%s - unable to create one shot manual timer type", __FUNCTION__); return CPVRTimerInfoTagPtr(); } newTimer->SetTimerType(timerType); } // no matter the timer was created from an epg tag, set special instant timer start and end times. CDateTime startTime(0); newTimer->SetStartFromUTC(startTime); newTimer->m_iMarginStart = 0; /* set the start margin to 0 for instant timers */ int iDuration = CSettings::GetInstance().GetInt(CSettings::SETTING_PVRRECORD_INSTANTRECORDTIME); CDateTime endTime = CDateTime::GetUTCDateTime() + CDateTimeSpan(0, 0, iDuration ? iDuration : 120, 0); newTimer->SetEndFromUTC(endTime); /* update summary string according to changed start/end time */ newTimer->UpdateSummary(); /* set epg tag at timer & timer at epg tag */ newTimer->UpdateEpgInfoTag(); /* unused only for reference */ newTimer->m_strFileNameAndPath = CPVRTimersPath::PATH_NEW; return newTimer; }
bool CPVRTimers::InstantTimer(const CPVRChannelPtr &channel) { assert(channel.get()); if (!g_PVRManager.CheckParentalLock(channel)) return false; CEpgInfoTagPtr epgTag(channel->GetEPGNow()); CPVRTimerInfoTagPtr newTimer; if (epgTag) newTimer = CPVRTimerInfoTag::CreateFromEpg(epgTag); if (!newTimer) { newTimer.reset(new CPVRTimerInfoTag); /* set the timer data */ newTimer->m_iClientIndex = -1; newTimer->m_strTitle = channel->ChannelName(); newTimer->m_strSummary = g_localizeStrings.Get(19056); newTimer->m_iChannelNumber = channel->ChannelNumber(); newTimer->m_iClientChannelUid = channel->UniqueID(); newTimer->m_iClientId = channel->ClientID(); newTimer->m_bIsRadio = channel->IsRadio(); /* generate summary string */ newTimer->m_strSummary = StringUtils::Format("%s %s %s %s %s", newTimer->StartAsLocalTime().GetAsLocalizedDate().c_str(), g_localizeStrings.Get(19159).c_str(), newTimer->StartAsLocalTime().GetAsLocalizedTime("", false).c_str(), g_localizeStrings.Get(19160).c_str(), newTimer->EndAsLocalTime().GetAsLocalizedTime("", false).c_str()); } CDateTime startTime(0); newTimer->SetStartFromUTC(startTime); newTimer->m_iMarginStart = 0; /* set the start margin to 0 for instant timers */ int iDuration = CSettings::GetInstance().GetInt(CSettings::SETTING_PVRRECORD_INSTANTRECORDTIME); CDateTime endTime = CDateTime::GetUTCDateTime() + CDateTimeSpan(0, 0, iDuration ? iDuration : 120, 0); newTimer->SetEndFromUTC(endTime); /* unused only for reference */ newTimer->m_strFileNameAndPath = CPVRTimersPath::PATH_NEW; bool bReturn = newTimer->AddToClient(); if (!bReturn) CLog::Log(LOGERROR, "PVRTimers - %s - unable to add an instant timer on the client", __FUNCTION__); return bReturn; }
bool CPVRClient::OpenStream(const CPVRChannelPtr &channel, bool bIsSwitchingChannel) { bool bReturn(false); CloseStream(); if(!CanPlayChannel(channel)) { CLog::Log(LOGDEBUG, "add-on '%s' can not play channel '%s'", GetFriendlyName().c_str(), channel->ChannelName().c_str()); } else if (!channel->StreamURL().empty()) { CLog::Log(LOGDEBUG, "opening live stream on url '%s'", channel->StreamURL().c_str()); bReturn = true; // the Njoy N7 sometimes doesn't switch channels, but opens a stream to the previous channel // when not waiting for a short period. // added in 1.1.0 AddonVersion checkVersion("1.1.0"); if (m_apiVersion >= checkVersion) { unsigned int iWaitTimeMs = m_pStruct->GetChannelSwitchDelay(); if (iWaitTimeMs > 0) XbmcThreads::ThreadSleep(iWaitTimeMs); } } else { CLog::Log(LOGDEBUG, "opening live stream for channel '%s'", channel->ChannelName().c_str()); PVR_CHANNEL tag; WriteClientChannelInfo(channel, tag); try { bReturn = m_pStruct->OpenLiveStream(tag); } catch (std::exception &e) { LogException(e, __FUNCTION__); } } if (bReturn) { CPVRChannelPtr currentChannel(g_PVRChannelGroups->GetByUniqueID(channel->UniqueID(), channel->ClientID())); CSingleLock lock(m_critSection); m_playingChannel = currentChannel; m_bIsPlayingTV = true; m_bIsPlayingRecording = false; } return bReturn; }
void CGUIEPGGridContainerModel::FindChannelAndBlockIndex(int channelUid, unsigned int broadcastUid, int eventOffset, int &newChannelIndex, int &newBlockIndex) const { const CDateTimeSpan blockDuration(0, 0, MINSPERBLOCK, 0); bool bFoundPrevChannel = false; for (size_t channel = 0; channel < m_channelItems.size(); ++channel) { CDateTime gridCursor(m_gridStart); //reset cursor for new channel unsigned long progIdx = m_epgItemsPtr[channel].start; unsigned long lastIdx = m_epgItemsPtr[channel].stop; int iEpgId = m_programmeItems[progIdx]->GetEPGInfoTag()->EpgID(); CEpgInfoTagPtr tag; CPVRChannelPtr chan; for (int block = 0; block < m_blocks; ++block) { while (progIdx <= lastIdx) { tag = m_programmeItems[progIdx]->GetEPGInfoTag(); if (tag->EpgID() != iEpgId || gridCursor < tag->StartAsUTC() || m_gridEnd <= tag->StartAsUTC()) break; // next block if (gridCursor < tag->EndAsUTC()) { if (broadcastUid > 0 && tag->UniqueBroadcastID() == broadcastUid) { newChannelIndex = channel; newBlockIndex = block + eventOffset; return; // both found. done. } if (!bFoundPrevChannel && channelUid > -1) { chan = tag->ChannelTag(); if (chan && chan->UniqueID() == channelUid) { newChannelIndex = channel; bFoundPrevChannel = true; } } break; // next block } progIdx++; } gridCursor += blockDuration; } } }
CPVRTimerInfoTagPtr CPVRTimers::GetActiveTimerForChannel(const CPVRChannelPtr &channel) const { CSingleLock lock(m_critSection); for (const auto &tagsEntry : m_tags) { for (const auto &timersEntry : *tagsEntry.second) { if (timersEntry->IsRecording() && timersEntry->m_iClientChannelUid == channel->UniqueID() && timersEntry->m_iClientId == channel->ClientID()) return timersEntry; } } return CPVRTimerInfoTagPtr(); }
/*! * @brief Copy over channel info from xbmcChannel to addonClient. * @param xbmcChannel The channel on XBMC's side. * @param addonChannel The channel on the addon's side. */ void CPVRClient::WriteClientChannelInfo(const CPVRChannelPtr &xbmcChannel, PVR_CHANNEL &addonChannel) { assert(xbmcChannel.get()); memset(&addonChannel, 0, sizeof(addonChannel)); addonChannel.iUniqueId = xbmcChannel->UniqueID(); addonChannel.iChannelNumber = xbmcChannel->ClientChannelNumber(); addonChannel.iSubChannelNumber = xbmcChannel->ClientSubChannelNumber(); strncpy(addonChannel.strChannelName, xbmcChannel->ClientChannelName().c_str(), sizeof(addonChannel.strChannelName) - 1); strncpy(addonChannel.strIconPath, xbmcChannel->IconPath().c_str(), sizeof(addonChannel.strIconPath) - 1); addonChannel.iEncryptionSystem = xbmcChannel->EncryptionSystem(); addonChannel.bIsRadio = xbmcChannel->IsRadio(); addonChannel.bIsHidden = xbmcChannel->IsHidden(); strncpy(addonChannel.strInputFormat, xbmcChannel->InputFormat().c_str(), sizeof(addonChannel.strInputFormat) - 1); strncpy(addonChannel.strStreamURL, xbmcChannel->StreamURL().c_str(), sizeof(addonChannel.strStreamURL) - 1); }
void CPVRChannelGroup::RemoveInvalidChannels(void) { CPVRChannelPtr channel; CSingleLock lock(m_critSection); for (PVR_CHANNEL_GROUP_SORTED_MEMBERS::iterator it = m_sortedMembers.begin(); it != m_sortedMembers.end();) { bool bDelete = false; channel = (*it).channel; if (channel->ClientChannelNumber() <= 0) { CLog::Log(LOGERROR, "PVRChannelGroup - %s - removing invalid channel '%s' from client '%i': no valid client channel number", __FUNCTION__, channel->ChannelName().c_str(), channel->ClientID()); bDelete = true; } if (!bDelete && channel->UniqueID() <= 0) { CLog::Log(LOGERROR, "PVRChannelGroup - %s - removing invalid channel '%s' from client '%i': no valid unique ID", __FUNCTION__, channel->ChannelName().c_str(), channel->ClientID()); bDelete = true; } /* remove this channel from all non-system groups if this is the internal group */ if (bDelete) { if (IsInternalGroup()) { g_PVRChannelGroups->Get(m_bRadio)->RemoveFromAllGroups(channel); channel->Delete(); } else { m_members.erase(channel->StorageId()); it = m_sortedMembers.erase(it); } m_bChanged = true; } else { ++it; } } }
bool CPVRClient::SwitchChannel(const CPVRChannelPtr &channel) { bool bSwitched(false); if (IsPlayingLiveStream() && CanPlayChannel(channel)) { PVR_CHANNEL tag; WriteClientChannelInfo(channel, tag); bSwitched = m_struct.SwitchChannel(tag); } if (bSwitched) { CPVRChannelPtr currentChannel(g_PVRChannelGroups->GetByUniqueID(channel->UniqueID(), channel->ClientID())); CSingleLock lock(m_critSection); m_playingChannel = currentChannel; } return bSwitched; }
void CPVRChannelGroup::RemoveInvalidChannels(void) { bool bDelete(false); CSingleLock lock(m_critSection); for (unsigned int ptr = 0; ptr < m_members.size(); ptr--) { bDelete = false; CPVRChannelPtr channel = m_members.at(ptr).channel; if (channel->IsVirtual()) continue; if (m_members.at(ptr).channel->ClientChannelNumber() <= 0) { CLog::Log(LOGERROR, "PVRChannelGroup - %s - removing invalid channel '%s' from client '%i': no valid client channel number", __FUNCTION__, channel->ChannelName().c_str(), channel->ClientID()); bDelete = true; } if (!bDelete && channel->UniqueID() <= 0) { CLog::Log(LOGERROR, "PVRChannelGroup - %s - removing invalid channel '%s' from client '%i': no valid unique ID", __FUNCTION__, channel->ChannelName().c_str(), channel->ClientID()); bDelete = true; } /* remove this channel from all non-system groups if this is the internal group */ if (bDelete) { if (IsInternalGroup()) { g_PVRChannelGroups->Get(m_bRadio)->RemoveFromAllGroups(*channel); channel->Delete(); } else { m_members.erase(m_members.begin() + ptr); } m_bChanged = true; } } }
void CGUIDialogPVRTimerSettings::InitializeChannelsList() { m_channelEntries.clear(); CFileItemList channelsList; g_PVRChannelGroups->GetGroupAll(m_bIsRadio)->GetMembers(channelsList); for (int i = 0; i < channelsList.Size(); ++i) { const CPVRChannelPtr channel(channelsList[i]->GetPVRChannelInfoTag()); std::string channelDescription( StringUtils::Format("%i %s", channel->ChannelNumber(), channel->ChannelName().c_str())); m_channelEntries.insert( std::make_pair(i, ChannelDescriptor(channel->UniqueID(), channel->ClientID(), channelDescription))); } // Add special "any channel" entry (used for epg-based repeating timers). m_channelEntries.insert( std::make_pair( ENTRY_ANY_CHANNEL, ChannelDescriptor(PVR_CHANNEL_INVALID_UID, 0, g_localizeStrings.Get(809)))); }
CPVRTimerInfoTagPtr CPVRTimers::GetTimerForEpgTag(const CEpgInfoTagPtr &epgTag) const { if (epgTag) { // already a timer assigned to tag? CPVRTimerInfoTagPtr timer(epgTag->Timer()); if (timer) return timer; // try to find a matching timer for the tag. if (epgTag->ChannelTag()) { 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) { timer = *timerIt; if (!timer->IsRepeating() && (timer->GetEpgInfoTag(false) == epgTag || (timer->m_iEpgUid != EPG_TAG_INVALID_UID && timer->m_iEpgUid == epgTag->UniqueBroadcastID()) || (timer->m_iClientChannelUid == channel->UniqueID() && timer->m_bIsRadio == channel->IsRadio() && timer->StartAsUTC() <= epgTag->StartAsUTC() && timer->EndAsUTC() >= epgTag->EndAsUTC()))) { return timer; } } } } } return CPVRTimerInfoTagPtr(); }
bool CPVRClient::SwitchChannel(const CPVRChannelPtr &channel) { bool bSwitched(false); if (IsPlayingLiveStream() && CanPlayChannel(channel)) { PVR_CHANNEL tag; WriteClientChannelInfo(channel, tag); try { bSwitched = m_pStruct->SwitchChannel(tag); } catch (std::exception &e) { LogException(e, __FUNCTION__); } } if (bSwitched) { CPVRChannelPtr currentChannel(g_PVRChannelGroups->GetByUniqueID(channel->UniqueID(), channel->ClientID())); CSingleLock lock(m_critSection); m_playingChannel = currentChannel; } return bSwitched; }
bool CPVRDatabase::PersistChannels(CPVRChannelGroup &group) { bool bReturn(true); CPVRChannelPtr channel; for (const auto& groupMember : group.m_members) { channel = groupMember.second.channel; if (channel->IsChanged() || channel->IsNew()) { if (Persist(*channel, false)) { groupMember.second.channel->Persisted(); bReturn = true; } } } bReturn &= CommitInsertQueries(); if (bReturn) { std::string strQuery; std::string strValue; for (const auto& groupMember : group.m_members) { channel = groupMember.second.channel; strQuery = PrepareSQL("iUniqueId = %u AND iClientId = %u", channel->UniqueID(), channel->ClientID()); strValue = GetSingleValue("channels", "idChannel", strQuery); if (!strValue.empty() && StringUtils::IsInteger(strValue)) channel->SetChannelID(atoi(strValue.c_str())); } } return bReturn; }
CPVRTimerInfoTagPtr CPVRTimerInfoTag::CreateFromEpg(const CEpgInfoTagPtr &tag, bool bCreateRule /* = false */) { /* create a new timer */ CPVRTimerInfoTagPtr newTag(new CPVRTimerInfoTag()); /* check if a valid channel is set */ CPVRChannelPtr channel = tag->ChannelTag(); if (!channel) { CLog::Log(LOGERROR, "%s - no channel set", __FUNCTION__); return CPVRTimerInfoTagPtr(); } /* check if the epg end date is in the future */ if (tag->EndAsLocalTime() < CDateTime::GetCurrentDateTime() && !bCreateRule) { CLog::Log(LOGERROR, "%s - end time is in the past", __FUNCTION__); return CPVRTimerInfoTagPtr(); } /* set the timer data */ CDateTime newStart = tag->StartAsUTC(); CDateTime newEnd = tag->EndAsUTC(); newTag->m_iClientIndex = PVR_TIMER_NO_CLIENT_INDEX; newTag->m_iParentClientIndex = PVR_TIMER_NO_PARENT; newTag->m_strTitle = tag->Title().empty() ? channel->ChannelName() : tag->Title(); newTag->m_iChannelNumber = channel->ChannelNumber(); newTag->m_iClientChannelUid = channel->UniqueID(); newTag->m_iClientId = channel->ClientID(); newTag->m_bIsRadio = channel->IsRadio(); newTag->m_channel = channel; newTag->m_iEpgUid = tag->UniqueBroadcastID(); newTag->SetStartFromUTC(newStart); newTag->SetEndFromUTC(newEnd); CPVRTimerTypePtr timerType; if (bCreateRule) { // create epg-based timer rule timerType = CPVRTimerType::CreateFromAttributes( PVR_TIMER_TYPE_IS_REPEATING, PVR_TIMER_TYPE_IS_MANUAL | PVR_TIMER_TYPE_FORBIDS_NEW_INSTANCES, channel->ClientID()); if (timerType) { if (timerType->SupportsEpgTitleMatch()) newTag->m_strEpgSearchString = newTag->m_strTitle; if (timerType->SupportsWeekdays()) newTag->m_iWeekdays = PVR_WEEKDAY_ALLDAYS; if (timerType->SupportsStartAnyTime()) newTag->m_bStartAnyTime = true; if (timerType->SupportsEndAnyTime()) newTag->m_bEndAnyTime = true; } } else { // create one-shot epg-based timer timerType = CPVRTimerType::CreateFromAttributes( PVR_TIMER_TYPE_ATTRIBUTE_NONE, PVR_TIMER_TYPE_IS_REPEATING | PVR_TIMER_TYPE_IS_MANUAL | PVR_TIMER_TYPE_FORBIDS_NEW_INSTANCES, channel->ClientID()); } if (!timerType) { CLog::Log(LOGERROR, "%s - unable to create any epg-based timer type", __FUNCTION__); return CPVRTimerInfoTagPtr(); } newTag->SetTimerType(timerType); newTag->UpdateSummary(); newTag->UpdateEpgInfoTag(); /* unused only for reference */ newTag->m_strFileNameAndPath = CPVRTimersPath::PATH_NEW; return newTag; }
void CGUIDialogPVRTimerSettings::OnSettingChanged(const CSetting *setting) { if (setting == NULL) return; CGUIDialogSettingsManualBase::OnSettingChanged(setting); CPVRTimerInfoTag* tag = m_timerItem->GetPVRTimerInfoTag(); if (tag == NULL) return; const std::string &settingId = setting->GetId(); if (settingId == SETTING_TMR_ACTIVE) m_bTimerActive = static_cast<const CSettingBool*>(setting)->GetValue(); if (settingId == SETTING_TMR_RADIO || settingId == SETTING_TMR_CHNAME_TV || settingId == SETTING_TMR_CHNAME_RADIO) { if (settingId == SETTING_TMR_RADIO) { tag->m_bIsRadio = static_cast<const CSettingBool*>(setting)->GetValue(); m_selectedChannelEntry = 0; } else m_selectedChannelEntry = static_cast<const CSettingInt*>(setting)->GetValue(); std::map<std::pair<bool, int>, int>::iterator itc = m_channelEntries.find(std::make_pair(tag->m_bIsRadio, m_selectedChannelEntry)); if (itc != m_channelEntries.end()) { CPVRChannelPtr channel = g_PVRChannelGroups->GetChannelById(itc->second); if (channel) { tag->m_iClientChannelUid = channel->UniqueID(); tag->m_iClientId = channel->ClientID(); tag->m_bIsRadio = channel->IsRadio(); tag->m_iChannelNumber = channel->ChannelNumber(); } else { tag->m_iClientChannelUid = PVR_VIRTUAL_CHANNEL_UID; tag->m_iClientId = PVR_VIRTUAL_CLIENT_ID; tag->m_iChannelNumber = 0; } // Update channel pointer from above values tag->UpdateChannel(); } } else if (settingId == SETTING_TMR_DAY) { m_tmp_day = static_cast<const CSettingInt*>(setting)->GetValue(); if (m_tmp_day <= 10) SetTimerFromWeekdaySetting(*tag); else { CDateTime time = CDateTime::GetCurrentDateTime(); CDateTime timestart = m_timerStartTime; CDateTime timestop = m_timerEndTime; int m_tmp_diff; // get diffence of timer in days between today and timer start date tm time_cur; time.GetAsTm(time_cur); tm time_tmr; timestart.GetAsTm(time_tmr); m_tmp_diff = time_tmr.tm_yday - time_cur.tm_yday; if (time_tmr.tm_yday - time_cur.tm_yday < 0) m_tmp_diff = 365; CDateTime newStart = timestart + CDateTimeSpan(m_tmp_day - 11 - m_tmp_diff, 0, 0, 0); CDateTime newEnd = timestop + CDateTimeSpan(m_tmp_day - 11 - m_tmp_diff, 0, 0, 0); // add a day to end time if end time is before start time // TODO: this should be removed after separate end date control was added if (newEnd < newStart) newEnd += CDateTimeSpan(1, 0, 0, 0); tag->SetStartFromLocalTime(newStart); tag->SetEndFromLocalTime(newEnd); tag->m_bIsRepeating = false; tag->m_iWeekdays = 0; } } else if (settingId == SETTING_TMR_PRIORITY) tag->m_iPriority = static_cast<const CSettingInt*>(setting)->GetValue(); else if (settingId == SETTING_TMR_LIFETIME) tag->m_iLifetime = static_cast<const CSettingInt*>(setting)->GetValue(); else if (settingId == SETTING_TMR_FIRST_DAY) { m_tmp_iFirstDay = static_cast<const CSettingInt*>(setting)->GetValue(); CDateTime newFirstDay; if (m_tmp_iFirstDay > 0) newFirstDay = CDateTime::GetCurrentDateTime() + CDateTimeSpan(m_tmp_iFirstDay - 1, 0, 0, 0); tag->SetFirstDayFromLocalTime(newFirstDay); } else if (settingId == SETTING_TMR_NAME) tag->m_strTitle = static_cast<const CSettingString*>(setting)->GetValue(); else if (settingId == SETTING_TMR_DIR) tag->m_strDirectory = static_cast<const CSettingString*>(setting)->GetValue(); tag->UpdateSummary(); }
CPVRTimerInfoTagPtr CPVRTimerInfoTag::CreateFromEpg(const CEpgInfoTagPtr &tag) { /* create a new timer */ CPVRTimerInfoTagPtr newTag(new CPVRTimerInfoTag()); if (!newTag) { CLog::Log(LOGERROR, "%s - couldn't create new timer", __FUNCTION__); return CPVRTimerInfoTagPtr(); } /* check if a valid channel is set */ CPVRChannelPtr channel = tag->ChannelTag(); if (!channel) { CLog::Log(LOGERROR, "%s - no channel set", __FUNCTION__); return CPVRTimerInfoTagPtr(); } /* check if the epg end date is in the future */ if (tag->EndAsLocalTime() < CDateTime::GetCurrentDateTime()) { CLog::Log(LOGERROR, "%s - end time is in the past", __FUNCTION__); return CPVRTimerInfoTagPtr(); } /* set the timer data */ CDateTime newStart = tag->StartAsUTC(); CDateTime newEnd = tag->EndAsUTC(); newTag->m_iClientIndex = -1; newTag->m_strTitle = tag->Title().empty() ? channel->ChannelName() : tag->Title(); newTag->m_iChannelNumber = channel->ChannelNumber(); newTag->m_iClientChannelUid = channel->UniqueID(); newTag->m_iClientId = channel->ClientID(); newTag->m_bIsRadio = channel->IsRadio(); newTag->m_iGenreType = tag->GenreType(); newTag->m_iGenreSubType = tag->GenreSubType(); newTag->m_channel = channel; newTag->SetStartFromUTC(newStart); newTag->SetEndFromUTC(newEnd); if (tag->Plot().empty()) { newTag->m_strSummary= StringUtils::Format("%s %s %s %s %s", newTag->StartAsLocalTime().GetAsLocalizedDate().c_str(), g_localizeStrings.Get(19159).c_str(), newTag->StartAsLocalTime().GetAsLocalizedTime("", false).c_str(), g_localizeStrings.Get(19160).c_str(), newTag->EndAsLocalTime().GetAsLocalizedTime("", false).c_str()); } else { newTag->m_strSummary = tag->Plot(); } newTag->m_epgTag = g_EpgContainer.GetById(tag->EpgID())->GetTag(tag->StartAsUTC()); /* unused only for reference */ newTag->m_strFileNameAndPath = "pvr://timers/new"; return newTag; }
void CPVRChannelGroup::SearchAndSetChannelIcons(bool bUpdateDb /* = false */) { std::string iconPath = CServiceBroker::GetSettings().GetString(CSettings::SETTING_PVRMENU_ICONPATH); if (iconPath.empty()) return; /* fetch files in icon path for fast lookup */ CFileItemList fileItemList; XFILE::CDirectory::GetDirectory(iconPath, fileItemList, ".jpg|.png|.tbn"); if (fileItemList.IsEmpty()) return; CGUIDialogProgressBarHandle* dlgProgressHandle = g_PVRManager.ShowProgressDialog(g_localizeStrings.Get(19286)); // Searching for channel icons CSingleLock lock(m_critSection); /* create a map for fast lookup of normalized file base name */ std::map<std::string, std::string> fileItemMap; const VECFILEITEMS &items = fileItemList.GetList(); for(VECFILEITEMS::const_iterator it = items.begin(); it != items.end(); ++it) { std::string baseName = URIUtils::GetFileName((*it)->GetPath()); URIUtils::RemoveExtension(baseName); StringUtils::ToLower(baseName); fileItemMap.insert(std::make_pair(baseName, (*it)->GetPath())); } int channelIndex = 0; CPVRChannelPtr channel; for(PVR_CHANNEL_GROUP_MEMBERS::const_iterator it = m_members.begin(); it != m_members.end(); ++it) { channel = it->second.channel; /* update progress dialog */ if (dlgProgressHandle) { dlgProgressHandle->SetProgress(channelIndex++, m_members.size()); dlgProgressHandle->SetText(channel->ChannelName()); } /* skip if an icon is already set and exists */ if (channel->IsIconExists()) continue; /* reset icon before searching for a new one */ channel->SetIconPath(""); std::string strChannelUid = StringUtils::Format("%08d", channel->UniqueID()); std::string strLegalClientChannelName = CUtil::MakeLegalFileName(channel->ClientChannelName()); StringUtils::ToLower(strLegalClientChannelName); std::string strLegalChannelName = CUtil::MakeLegalFileName(channel->ChannelName()); StringUtils::ToLower(strLegalChannelName); std::map<std::string, std::string>::iterator itItem; if ((itItem = fileItemMap.find(strLegalClientChannelName)) != fileItemMap.end() || (itItem = fileItemMap.find(strLegalChannelName)) != fileItemMap.end() || (itItem = fileItemMap.find(strChannelUid)) != fileItemMap.end()) { channel->SetIconPath(itItem->second, g_advancedSettings.m_bPVRAutoScanIconsUserSet); } if (bUpdateDb) channel->Persist(); //! @todo start channel icon scraper here if nothing was found } if (dlgProgressHandle) dlgProgressHandle->MarkFinished(); }
CPVRTimerInfoTagPtr CPVRTimerInfoTag::CreateFromEpg(const CEpgInfoTagPtr &tag, bool bRepeating /* = false */) { /* create a new timer */ CPVRTimerInfoTagPtr newTag(new CPVRTimerInfoTag()); /* check if a valid channel is set */ CPVRChannelPtr channel = tag->ChannelTag(); if (!channel) { CLog::Log(LOGERROR, "%s - no channel set", __FUNCTION__); return CPVRTimerInfoTagPtr(); } /* check if the epg end date is in the future */ if (tag->EndAsLocalTime() < CDateTime::GetCurrentDateTime()) { CLog::Log(LOGERROR, "%s - end time is in the past", __FUNCTION__); return CPVRTimerInfoTagPtr(); } /* set the timer data */ CDateTime newStart = tag->StartAsUTC(); CDateTime newEnd = tag->EndAsUTC(); newTag->m_iClientIndex = -1; newTag->m_iParentClientIndex = PVR_TIMER_NO_PARENT; newTag->m_strTitle = tag->Title().empty() ? channel->ChannelName() : tag->Title(); newTag->m_iChannelNumber = channel->ChannelNumber(); newTag->m_iClientChannelUid = channel->UniqueID(); newTag->m_iClientId = channel->ClientID(); newTag->m_bIsRadio = channel->IsRadio(); newTag->m_iGenreType = tag->GenreType(); newTag->m_iGenreSubType = tag->GenreSubType(); newTag->m_channel = channel; newTag->SetStartFromUTC(newStart); newTag->SetEndFromUTC(newEnd); CPVRTimerTypePtr timerType; if (bRepeating) { // create repeating epg-based timer timerType = CPVRTimerType::CreateFromAttributes( PVR_TIMER_TYPE_IS_REPEATING, PVR_TIMER_TYPE_IS_MANUAL | PVR_TIMER_TYPE_FORBIDS_NEW_INSTANCES, channel->ClientID()); } if (!timerType) { // create one-shot epg-based timer timerType = CPVRTimerType::CreateFromAttributes( PVR_TIMER_TYPE_ATTRIBUTE_NONE, PVR_TIMER_TYPE_IS_REPEATING | PVR_TIMER_TYPE_IS_MANUAL | PVR_TIMER_TYPE_FORBIDS_NEW_INSTANCES, channel->ClientID()); } if (!timerType) { CLog::Log(LOGERROR, "%s - unable to create any epg-based timer type", __FUNCTION__); return CPVRTimerInfoTagPtr(); } newTag->SetTimerType(timerType); newTag->UpdateSummary(); newTag->m_epgTag = g_EpgContainer.GetById(tag->EpgID())->GetTag(tag->StartAsUTC()); /* unused only for reference */ newTag->m_strFileNameAndPath = CPVRTimersPath::PATH_NEW; return newTag; }
void CPVRChannelGroup::SearchAndSetChannelIcons(bool bUpdateDb /* = false */) { std::string iconPath = CSettings::Get().GetString("pvrmenu.iconpath"); if (iconPath.empty()) return; CPVRDatabase *database = GetPVRDatabase(); if (!database) return; /* fetch files in icon path for fast lookup */ CFileItemList fileItemList; XFILE::CDirectory::GetDirectory(iconPath, fileItemList, ".jpg|.png|.tbn"); if (fileItemList.IsEmpty()) return; CGUIDialogExtendedProgressBar* dlgProgress = (CGUIDialogExtendedProgressBar*)g_windowManager.GetWindow(WINDOW_DIALOG_EXT_PROGRESS); CGUIDialogProgressBarHandle* dlgProgressHandle = dlgProgress ? dlgProgress->GetHandle(g_localizeStrings.Get(19287)) : NULL; CSingleLock lock(m_critSection); /* create a map for fast lookup of normalized file base name */ std::map<std::string, std::string> fileItemMap; const VECFILEITEMS &items = fileItemList.GetList(); for(VECFILEITEMS::const_iterator it = items.begin(); it != items.end(); ++it) { std::string baseName = URIUtils::GetFileName((*it)->GetPath()); URIUtils::RemoveExtension(baseName); StringUtils::ToLower(baseName); fileItemMap.insert(std::make_pair(baseName, (*it)->GetPath())); } int channelIndex = 0; for(std::vector<PVRChannelGroupMember>::const_iterator it = m_members.begin(); it != m_members.end(); ++it) { CPVRChannelPtr channel = (*it).channel; /* update progress dialog */ if (dlgProgressHandle) { dlgProgressHandle->SetProgress(channelIndex++, m_members.size()); dlgProgressHandle->SetText(channel->ChannelName()); } /* skip if an icon is already set and exists */ if (channel->IsIconExists()) continue; /* reset icon before searching for a new one */ channel->SetIconPath(""); std::string strChannelUid = StringUtils::Format("%08d", channel->UniqueID()); std::string strLegalClientChannelName = CUtil::MakeLegalFileName(channel->ClientChannelName()); StringUtils::ToLower(strLegalClientChannelName); std::string strLegalChannelName = CUtil::MakeLegalFileName(channel->ChannelName()); StringUtils::ToLower(strLegalChannelName); std::map<std::string, std::string>::iterator itItem; if ((itItem = fileItemMap.find(strLegalClientChannelName)) != fileItemMap.end() || (itItem = fileItemMap.find(strLegalChannelName)) != fileItemMap.end() || (itItem = fileItemMap.find(strChannelUid)) != fileItemMap.end()) { channel->SetIconPath(itItem->second, g_advancedSettings.m_bPVRAutoScanIconsUserSet); } if (bUpdateDb) channel->Persist(); /* TODO: start channel icon scraper here if nothing was found */ } if (dlgProgressHandle) dlgProgressHandle->MarkFinished(); }
CPVRTimerInfoTag::CPVRTimerInfoTag(const PVR_TIMER &timer, const CPVRChannelPtr &channel, unsigned int iClientId) : m_strTitle(timer.strTitle), m_strEpgSearchString(timer.strEpgSearchString), m_bFullTextEpgSearch(timer.bFullTextEpgSearch), m_strDirectory(timer.strDirectory), m_state(timer.state), m_iClientId(iClientId), m_iClientIndex(timer.iClientIndex), m_iParentClientIndex(timer.iParentClientIndex), m_iClientChannelUid(channel ? channel->UniqueID() : (timer.iClientChannelUid > 0) ? timer.iClientChannelUid : PVR_CHANNEL_INVALID_UID), m_bStartAnyTime(timer.bStartAnyTime), m_bEndAnyTime(timer.bEndAnyTime), m_iPriority(timer.iPriority), m_iLifetime(timer.iLifetime), m_iMaxRecordings(timer.iMaxRecordings), m_iWeekdays(timer.iWeekdays), m_iPreventDupEpisodes(timer.iPreventDuplicateEpisodes), m_iRecordingGroup(timer.iRecordingGroup), m_strFileNameAndPath(StringUtils::Format("pvr://client%i/timers/%i", m_iClientId, m_iClientIndex)), m_iChannelNumber(channel ? g_PVRChannelGroups->GetGroupAll(channel->IsRadio())->GetChannelNumber(channel) : 0), m_bIsRadio(channel && channel->IsRadio()), m_iTimerId(0), m_channel(channel), m_iMarginStart(timer.iMarginStart), m_iMarginEnd(timer.iMarginEnd), m_StartTime(timer.startTime + g_advancedSettings.m_iPVRTimeCorrection), m_StopTime(timer.endTime + g_advancedSettings.m_iPVRTimeCorrection), m_FirstDay(timer.firstDay + g_advancedSettings.m_iPVRTimeCorrection), m_iEpgUid(timer.iEpgUid) { if (m_iClientIndex == PVR_TIMER_NO_CLIENT_INDEX) CLog::Log(LOGERROR, "%s: invalid client index supplied by client %d (must be > 0)!", __FUNCTION__, m_iClientId); if (g_PVRClients->SupportsTimers(m_iClientId)) { // begin compat section // Create timer type according to certain timer values already available in Isengard. // This is for migration only and does not make changes to the addons obsolete. Addons should // work and benefit from some UI changes (e.g. some of the timer settings dialog enhancements), // but all old problems/bugs due to static attributes and values will remain the same as in // Isengard. Also, new features (like epg search) are not available to addons automatically. // This code can be removed once all addons actually support the respective PVR Addon API version. if (timer.iTimerType == PVR_TIMER_TYPE_NONE) { // Create type according to certain timer values. unsigned int iMustHave = PVR_TIMER_TYPE_ATTRIBUTE_NONE; unsigned int iMustNotHave = PVR_TIMER_TYPE_FORBIDS_NEW_INSTANCES; if (timer.iEpgUid == PVR_TIMER_NO_EPG_UID && timer.iWeekdays != PVR_WEEKDAY_NONE) iMustHave |= PVR_TIMER_TYPE_IS_REPEATING; else iMustNotHave |= PVR_TIMER_TYPE_IS_REPEATING; if (timer.iEpgUid == PVR_TIMER_NO_EPG_UID) iMustHave |= PVR_TIMER_TYPE_IS_MANUAL; else iMustNotHave |= PVR_TIMER_TYPE_IS_MANUAL; CPVRTimerTypePtr type(CPVRTimerType::CreateFromAttributes(iMustHave, iMustNotHave, m_iClientId)); if (type) SetTimerType(type); } // end compat section else { SetTimerType(CPVRTimerType::CreateFromIds(timer.iTimerType, m_iClientId)); } if (!m_timerType) CLog::Log(LOGERROR, "%s: no timer type, although timers are supported by client %d!", __FUNCTION__, m_iClientId); else if (m_iEpgUid == EPG_TAG_INVALID_UID && m_timerType->IsEpgBasedOnetime()) CLog::Log(LOGERROR, "%s: no epg tag given for epg based timer type (%d)!", __FUNCTION__, m_timerType->GetTypeId()); } ResetChildState(); UpdateSummary(); UpdateEpgInfoTag(); }
CPVRTimerInfoTag::CPVRTimerInfoTag(const PVR_TIMER &timer, const CPVRChannelPtr &channel, unsigned int iClientId) : m_strTitle(timer.strTitle), m_strEpgSearchString(timer.strEpgSearchString), m_bFullTextEpgSearch(timer.bFullTextEpgSearch), m_strDirectory(timer.strDirectory) { m_iClientId = iClientId; m_iClientIndex = timer.iClientIndex; m_iParentClientIndex = timer.iParentClientIndex; m_iClientChannelUid = channel ? channel->UniqueID() : (timer.iClientChannelUid > 0) ? timer.iClientChannelUid : PVR_INVALID_CHANNEL_UID; m_iChannelNumber = channel ? g_PVRChannelGroups->GetGroupAll(channel->IsRadio())->GetChannelNumber(channel) : 0; m_StartTime = timer.startTime + g_advancedSettings.m_iPVRTimeCorrection; m_StopTime = timer.endTime + g_advancedSettings.m_iPVRTimeCorrection; m_iPreventDupEpisodes = timer.iPreventDuplicateEpisodes; m_iRecordingGroup = timer.iRecordingGroup; m_FirstDay = timer.firstDay + g_advancedSettings.m_iPVRTimeCorrection; m_iWeekdays = timer.iWeekdays; m_iPriority = timer.iPriority; m_iLifetime = timer.iLifetime; m_iMarginStart = timer.iMarginStart; m_iMarginEnd = timer.iMarginEnd; m_genre = StringUtils::Split(CEpg::ConvertGenreIdToString(timer.iGenreType, timer.iGenreSubType), g_advancedSettings.m_videoItemSeparator); m_iGenreType = timer.iGenreType; m_iGenreSubType = timer.iGenreSubType; m_channel = channel; m_bIsRadio = channel && channel->IsRadio(); m_state = timer.state; m_strFileNameAndPath = StringUtils::Format("pvr://client%i/timers/%i", m_iClientId, m_iClientIndex); m_iTimerId = 0; if (g_PVRClients->SupportsTimers(m_iClientId)) { // begin compat section // Create timer type according to certain timer values already available in Isengard. // This is for migration only and does not make changes to the addons obsolete. Addons should // work and benefit from some UI changes (e.g. some of the timer settings dialog enhancements), // but all old problems/bugs due to static attributes and values will remain the same as in // Isengard. Also, new features (like epg search) are not available to addons automatically. // This code can be removed once all addons actually support the respective PVR Addon API version. if (timer.iTimerType == PVR_TIMER_TYPE_NONE) { // Create type according to certain timer values. unsigned int iMustHave = PVR_TIMER_TYPE_ATTRIBUTE_NONE; unsigned int iMustNotHave = PVR_TIMER_TYPE_FORBIDS_NEW_INSTANCES; if (timer.iWeekdays != PVR_WEEKDAY_NONE) iMustHave |= PVR_TIMER_TYPE_IS_REPEATING; else iMustNotHave |= PVR_TIMER_TYPE_IS_REPEATING; if (timer.iEpgUid == 0) iMustHave |= PVR_TIMER_TYPE_IS_MANUAL; else iMustNotHave |= PVR_TIMER_TYPE_IS_MANUAL; CPVRTimerTypePtr type(CPVRTimerType::CreateFromAttributes(iMustHave, iMustNotHave, m_iClientId)); if (type) SetTimerType(type); } // end compat section else { SetTimerType(CPVRTimerType::CreateFromIds(timer.iTimerType, m_iClientId)); } if (!m_timerType) CLog::Log(LOGERROR, "%s: no timer type, although timers are supported by client %d!", __FUNCTION__, m_iClientId); } UpdateSummary(); }