diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:22 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:22 +0000 |
commit | c04dcc2e7d834218ef2d4194331e383402495ae1 (patch) | |
tree | 7333e38d10d75386e60f336b80c2443c1166031d /xbmc/pvr/timers/PVRTimerRuleMatcher.cpp | |
parent | Initial commit. (diff) | |
download | kodi-c04dcc2e7d834218ef2d4194331e383402495ae1.tar.xz kodi-c04dcc2e7d834218ef2d4194331e383402495ae1.zip |
Adding upstream version 2:20.4+dfsg.upstream/2%20.4+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'xbmc/pvr/timers/PVRTimerRuleMatcher.cpp')
-rw-r--r-- | xbmc/pvr/timers/PVRTimerRuleMatcher.cpp | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/xbmc/pvr/timers/PVRTimerRuleMatcher.cpp b/xbmc/pvr/timers/PVRTimerRuleMatcher.cpp new file mode 100644 index 0000000..9178e85 --- /dev/null +++ b/xbmc/pvr/timers/PVRTimerRuleMatcher.cpp @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2012-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "PVRTimerRuleMatcher.h" + +#include "XBDateTime.h" +#include "addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_channels.h" // PVR_CHANNEL_INVALID_UID +#include "pvr/epg/EpgInfoTag.h" +#include "pvr/timers/PVRTimerInfoTag.h" +#include "utils/RegExp.h" + +using namespace PVR; + +CPVRTimerRuleMatcher::CPVRTimerRuleMatcher(const std::shared_ptr<CPVRTimerInfoTag>& timerRule, + const CDateTime& start) + : m_timerRule(timerRule), m_start(CPVRTimerInfoTag::ConvertUTCToLocalTime(start)) +{ +} + +CPVRTimerRuleMatcher::~CPVRTimerRuleMatcher() = default; + +std::shared_ptr<CPVRChannel> CPVRTimerRuleMatcher::GetChannel() const +{ + if (m_timerRule->GetTimerType()->SupportsChannels()) + return m_timerRule->Channel(); + + return {}; +} + +CDateTime CPVRTimerRuleMatcher::GetNextTimerStart() const +{ + if (!m_timerRule->GetTimerType()->SupportsStartTime()) + return CDateTime(); // invalid datetime + + const CDateTime startDateLocal = m_timerRule->GetTimerType()->SupportsFirstDay() + ? m_timerRule->FirstDayAsLocalTime() + : m_start; + const CDateTime startTimeLocal = m_timerRule->StartAsLocalTime(); + CDateTime nextStart(startDateLocal.GetYear(), startDateLocal.GetMonth(), startDateLocal.GetDay(), + startTimeLocal.GetHour(), startTimeLocal.GetMinute(), 0); + + const CDateTimeSpan oneDay(1, 0, 0, 0); + while (nextStart < m_start) + { + nextStart += oneDay; + } + + if (m_timerRule->GetTimerType()->SupportsWeekdays() && + m_timerRule->WeekDays() != PVR_WEEKDAY_ALLDAYS) + { + bool bMatch = false; + while (!bMatch) + { + int startWeekday = nextStart.GetDayOfWeek(); + if (startWeekday == 0) + startWeekday = 7; + + bMatch = ((1 << (startWeekday - 1)) & m_timerRule->WeekDays()); + if (!bMatch) + nextStart += oneDay; + } + } + + return nextStart.GetAsUTCDateTime(); +} + +bool CPVRTimerRuleMatcher::Matches(const std::shared_ptr<CPVREpgInfoTag>& epgTag) const +{ + return epgTag && CPVRTimerInfoTag::ConvertUTCToLocalTime(epgTag->EndAsUTC()) > m_start && + MatchSeriesLink(epgTag) && MatchChannel(epgTag) && MatchStart(epgTag) && + MatchEnd(epgTag) && MatchDayOfWeek(epgTag) && MatchSearchText(epgTag); +} + +bool CPVRTimerRuleMatcher::MatchSeriesLink(const std::shared_ptr<CPVREpgInfoTag>& epgTag) const +{ + if (m_timerRule->GetTimerType()->RequiresEpgSeriesLinkOnCreate()) + return epgTag->SeriesLink() == m_timerRule->SeriesLink(); + else + return true; +} + +bool CPVRTimerRuleMatcher::MatchChannel(const std::shared_ptr<CPVREpgInfoTag>& epgTag) const +{ + if (m_timerRule->GetTimerType()->SupportsAnyChannel() && + m_timerRule->ClientChannelUID() == PVR_CHANNEL_INVALID_UID) + return true; // matches any channel + + if (m_timerRule->GetTimerType()->SupportsChannels()) + return m_timerRule->ClientChannelUID() != PVR_CHANNEL_INVALID_UID && + epgTag->ClientID() == m_timerRule->ClientID() && + epgTag->UniqueChannelID() == m_timerRule->ClientChannelUID(); + else + return true; +} + +bool CPVRTimerRuleMatcher::MatchStart(const std::shared_ptr<CPVREpgInfoTag>& epgTag) const +{ + if (m_timerRule->GetTimerType()->SupportsFirstDay()) + { + // only year, month and day do matter here... + const CDateTime startEpgLocal = CPVRTimerInfoTag::ConvertUTCToLocalTime(epgTag->StartAsUTC()); + const CDateTime startEpg(startEpgLocal.GetYear(), startEpgLocal.GetMonth(), + startEpgLocal.GetDay(), 0, 0, 0); + const CDateTime firstDayLocal = m_timerRule->FirstDayAsLocalTime(); + const CDateTime startTimer(firstDayLocal.GetYear(), firstDayLocal.GetMonth(), + firstDayLocal.GetDay(), 0, 0, 0); + if (startEpg < startTimer) + return false; + } + + if (m_timerRule->GetTimerType()->SupportsStartAnyTime() && m_timerRule->IsStartAnyTime()) + return true; // matches any start time + + if (m_timerRule->GetTimerType()->SupportsStartTime()) + { + // only hours and minutes do matter here... + const CDateTime startEpgLocal = CPVRTimerInfoTag::ConvertUTCToLocalTime(epgTag->StartAsUTC()); + const CDateTime startEpg(2000, 1, 1, startEpgLocal.GetHour(), startEpgLocal.GetMinute(), 0); + const CDateTime startTimerLocal = m_timerRule->StartAsLocalTime(); + const CDateTime startTimer(2000, 1, 1, startTimerLocal.GetHour(), startTimerLocal.GetMinute(), + 0); + return startEpg >= startTimer; + } + else + return true; +} + +bool CPVRTimerRuleMatcher::MatchEnd(const std::shared_ptr<CPVREpgInfoTag>& epgTag) const +{ + if (m_timerRule->GetTimerType()->SupportsEndAnyTime() && m_timerRule->IsEndAnyTime()) + return true; // matches any end time + + if (m_timerRule->GetTimerType()->SupportsEndTime()) + { + // only hours and minutes do matter here... + const CDateTime endEpgLocal = CPVRTimerInfoTag::ConvertUTCToLocalTime(epgTag->EndAsUTC()); + const CDateTime endEpg(2000, 1, 1, endEpgLocal.GetHour(), endEpgLocal.GetMinute(), 0); + const CDateTime endTimerLocal = m_timerRule->EndAsLocalTime(); + const CDateTime endTimer(2000, 1, 1, endTimerLocal.GetHour(), endTimerLocal.GetMinute(), 0); + return endEpg <= endTimer; + } + else + return true; +} + +bool CPVRTimerRuleMatcher::MatchDayOfWeek(const std::shared_ptr<CPVREpgInfoTag>& epgTag) const +{ + if (m_timerRule->GetTimerType()->SupportsWeekdays()) + { + if (m_timerRule->WeekDays() != PVR_WEEKDAY_ALLDAYS) + { + const CDateTime startEpgLocal = CPVRTimerInfoTag::ConvertUTCToLocalTime(epgTag->StartAsUTC()); + int startWeekday = startEpgLocal.GetDayOfWeek(); + if (startWeekday == 0) + startWeekday = 7; + + return ((1 << (startWeekday - 1)) & m_timerRule->WeekDays()); + } + } + return true; +} + +bool CPVRTimerRuleMatcher::MatchSearchText(const std::shared_ptr<CPVREpgInfoTag>& epgTag) const +{ + if (m_timerRule->GetTimerType()->SupportsEpgFulltextMatch() && m_timerRule->IsFullTextEpgSearch()) + { + if (!m_textSearch) + { + m_textSearch.reset(new CRegExp(true /* case insensitive */)); + m_textSearch->RegComp(m_timerRule->EpgSearchString()); + } + return m_textSearch->RegFind(epgTag->Title()) >= 0 || + m_textSearch->RegFind(epgTag->EpisodeName()) >= 0 || + m_textSearch->RegFind(epgTag->PlotOutline()) >= 0 || + m_textSearch->RegFind(epgTag->Plot()) >= 0; + } + else if (m_timerRule->GetTimerType()->SupportsEpgTitleMatch()) + { + if (!m_textSearch) + { + m_textSearch.reset(new CRegExp(true /* case insensitive */)); + m_textSearch->RegComp(m_timerRule->EpgSearchString()); + } + return m_textSearch->RegFind(epgTag->Title()) >= 0; + } + else + return true; +} |