2 * Copyright (C) 2012-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
21 #include "guilib/LocalizeStrings.h"
22 #include "utils/TextSearch.h"
23 #include "utils/log.h"
25 #include "../addons/include/xbmc_pvr_types.h"
27 #include "EpgSearchFilter.h"
28 #include "EpgContainer.h"
30 #include "pvr/PVRManager.h"
31 #include "pvr/channels/PVRChannelGroupsContainer.h"
32 #include "pvr/recordings/PVRRecordings.h"
33 #include "pvr/timers/PVRTimers.h"
39 void EpgSearchFilter::Reset()
42 m_bIsCaseSensitive = false;
43 m_bSearchInDescription = false;
44 m_iGenreType = EPG_SEARCH_UNSET;
45 m_iGenreSubType = EPG_SEARCH_UNSET;
46 m_iMinimumDuration = EPG_SEARCH_UNSET;
47 m_iMaximumDuration = EPG_SEARCH_UNSET;
48 m_startDateTime.SetFromUTCDateTime(g_EpgContainer.GetFirstEPGDate());
49 m_endDateTime.SetFromUTCDateTime(g_EpgContainer.GetLastEPGDate());
50 m_bIncludeUnknownGenres = false;
51 m_bPreventRepeats = false;
53 /* pvr specific filters */
54 m_iChannelNumber = EPG_SEARCH_UNSET;
56 m_iChannelGroup = EPG_SEARCH_UNSET;
57 m_bIgnorePresentTimers = true;
58 m_bIgnorePresentRecordings = true;
59 m_iUniqueBroadcastId = EPG_SEARCH_UNSET;
62 bool EpgSearchFilter::MatchGenre(const CEpgInfoTag &tag) const
66 if (m_iGenreType != EPG_SEARCH_UNSET)
68 bool bIsUnknownGenre(tag.GenreType() > EPG_EVENT_CONTENTMASK_USERDEFINED ||
69 tag.GenreType() < EPG_EVENT_CONTENTMASK_MOVIEDRAMA);
70 bReturn = ((m_bIncludeUnknownGenres && bIsUnknownGenre) || tag.GenreType() == m_iGenreType);
76 bool EpgSearchFilter::MatchDuration(const CEpgInfoTag &tag) const
80 if (m_iMinimumDuration != EPG_SEARCH_UNSET)
81 bReturn = (tag.GetDuration() > m_iMinimumDuration * 60);
83 if (bReturn && m_iMaximumDuration != EPG_SEARCH_UNSET)
84 bReturn = (tag.GetDuration() < m_iMaximumDuration * 60);
89 bool EpgSearchFilter::MatchStartAndEndTimes(const CEpgInfoTag &tag) const
91 return (tag.StartAsLocalTime() >= m_startDateTime && tag.EndAsLocalTime() <= m_endDateTime);
94 bool EpgSearchFilter::MatchSearchTerm(const CEpgInfoTag &tag) const
98 if (!m_strSearchTerm.empty())
100 CTextSearch search(m_strSearchTerm, m_bIsCaseSensitive, SEARCH_DEFAULT_OR);
101 bReturn = search.Search(tag.Title()) ||
102 search.Search(tag.PlotOutline());
108 bool EpgSearchFilter::MatchBroadcastId(const CEpgInfoTag &tag) const
110 if (m_iUniqueBroadcastId != EPG_SEARCH_UNSET)
111 return (tag.UniqueBroadcastID() == m_iUniqueBroadcastId);
116 bool EpgSearchFilter::FilterEntry(const CEpgInfoTag &tag) const
118 return (MatchGenre(tag) &&
119 MatchBroadcastId(tag) &&
120 MatchDuration(tag) &&
121 MatchStartAndEndTimes(tag) &&
122 MatchSearchTerm(tag)) &&
123 (!tag.HasPVRChannel() ||
124 (MatchChannelNumber(tag) &&
125 MatchChannelGroup(tag) &&
126 (!m_bFTAOnly || !tag.ChannelTag()->IsEncrypted())));
129 int EpgSearchFilter::RemoveDuplicates(CFileItemList &results)
131 unsigned int iSize = results.Size();
133 for (unsigned int iResultPtr = 0; iResultPtr < iSize; iResultPtr++)
135 const CEpgInfoTag *epgentry_1 = results.Get(iResultPtr)->GetEPGInfoTag();
136 for (unsigned int iTagPtr = 0; iTagPtr < iSize; iTagPtr++)
138 const CEpgInfoTag *epgentry_2 = results.Get(iTagPtr)->GetEPGInfoTag();
139 if (iResultPtr == iTagPtr)
142 if (epgentry_1->Title() != epgentry_2->Title() ||
143 epgentry_1->Plot() != epgentry_2->Plot() ||
144 epgentry_1->PlotOutline() != epgentry_2->PlotOutline())
147 results.Remove(iTagPtr);
158 bool EpgSearchFilter::MatchChannelNumber(const CEpgInfoTag &tag) const
162 if (m_iChannelNumber != EPG_SEARCH_UNSET && g_PVRManager.IsStarted())
164 CPVRChannelGroupPtr group = (m_iChannelGroup != EPG_SEARCH_UNSET) ? g_PVRChannelGroups->GetByIdFromAll(m_iChannelGroup) : g_PVRChannelGroups->GetGroupAllTV();
166 group = CPVRManager::Get().ChannelGroups()->GetGroupAllTV();
168 bReturn = (m_iChannelNumber == (int) group->GetChannelNumber(*tag.ChannelTag()));
174 bool EpgSearchFilter::MatchChannelGroup(const CEpgInfoTag &tag) const
178 if (m_iChannelGroup != EPG_SEARCH_UNSET && g_PVRManager.IsStarted())
180 CPVRChannelGroupPtr group = g_PVRChannelGroups->GetByIdFromAll(m_iChannelGroup);
181 bReturn = (group && group->IsGroupMember(*tag.ChannelTag()));
187 int EpgSearchFilter::FilterRecordings(CFileItemList &results)
190 if (!g_PVRManager.IsStarted())
193 CFileItemList recordings;
194 g_PVRRecordings->GetAll(recordings);
197 for (int iRecordingPtr = 0; iRecordingPtr < recordings.Size(); iRecordingPtr++)
199 CPVRRecording *recording = recordings.Get(iRecordingPtr)->GetPVRRecordingInfoTag();
203 for (int iResultPtr = 0; iResultPtr < results.Size(); iResultPtr++)
205 const CEpgInfoTag *epgentry = results.Get(iResultPtr)->GetEPGInfoTag();
209 epgentry->Title() != recording->m_strTitle ||
210 epgentry->Plot() != recording->m_strPlot)
213 results.Remove(iResultPtr);
222 int EpgSearchFilter::FilterTimers(CFileItemList &results)
225 if (!g_PVRManager.IsStarted())
228 vector<CFileItemPtr> timers = g_PVRTimers->GetActiveTimers();
230 for (unsigned int iTimerPtr = 0; iTimerPtr < timers.size(); iTimerPtr++)
232 CFileItemPtr fileItem = timers.at(iTimerPtr);
233 if (!fileItem || !fileItem->HasPVRTimerInfoTag())
236 CPVRTimerInfoTag *timer = fileItem->GetPVRTimerInfoTag();
240 for (int iResultPtr = 0; iResultPtr < results.Size(); iResultPtr++)
242 const CEpgInfoTag *epgentry = results.Get(iResultPtr)->GetEPGInfoTag();
244 *epgentry->ChannelTag() != *timer->ChannelTag() ||
245 epgentry->StartAsUTC() < timer->StartAsUTC() ||
246 epgentry->EndAsUTC() > timer->EndAsUTC())
249 results.Remove(iResultPtr);