aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorksooo <3226626+ksooo@users.noreply.github.com>2023-09-02 23:52:03 +0200
committerksooo <3226626+ksooo@users.noreply.github.com>2024-08-15 00:38:33 +0200
commit18b9791a57b70b0f66f352b748e3af9b2164b684 (patch)
tree8f18314f57cb0b853335208a4050431eb97b3262
parentb2abd741c583132645bd769712012bff4c7c803b (diff)
[PVR] CPVRGUIDirectory: Add support for saved search results.
-rw-r--r--xbmc/pvr/epg/CMakeLists.txt2
-rw-r--r--xbmc/pvr/epg/EpgContainer.cpp6
-rw-r--r--xbmc/pvr/epg/EpgContainer.h4
-rw-r--r--xbmc/pvr/epg/EpgSearch.cpp51
-rw-r--r--xbmc/pvr/epg/EpgSearch.h48
-rw-r--r--xbmc/pvr/filesystem/PVRGUIDirectory.cpp21
-rw-r--r--xbmc/pvr/filesystem/PVRGUIDirectory.h1
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRSearch.cpp26
8 files changed, 134 insertions, 25 deletions
diff --git a/xbmc/pvr/epg/CMakeLists.txt b/xbmc/pvr/epg/CMakeLists.txt
index 0ea75b702a..ee5e7f4015 100644
--- a/xbmc/pvr/epg/CMakeLists.txt
+++ b/xbmc/pvr/epg/CMakeLists.txt
@@ -2,6 +2,7 @@ set(SOURCES EpgContainer.cpp
Epg.cpp
EpgDatabase.cpp
EpgInfoTag.cpp
+ EpgSearch.cpp
EpgSearchFilter.cpp
EpgSearchPath.cpp
EpgChannelData.cpp
@@ -12,6 +13,7 @@ set(HEADERS Epg.h
EpgContainer.h
EpgDatabase.h
EpgInfoTag.h
+ EpgSearch.h
EpgSearchData.h
EpgSearchFilter.h
EpgSearchPath.h
diff --git a/xbmc/pvr/epg/EpgContainer.cpp b/xbmc/pvr/epg/EpgContainer.cpp
index 4e20f790b1..72521d1593 100644
--- a/xbmc/pvr/epg/EpgContainer.cpp
+++ b/xbmc/pvr/epg/EpgContainer.cpp
@@ -953,7 +953,8 @@ int CPVREpgContainer::CleanupCachedImages()
});
}
-std::vector<std::shared_ptr<CPVREpgSearchFilter>> CPVREpgContainer::GetSavedSearches(bool bRadio)
+std::vector<std::shared_ptr<CPVREpgSearchFilter>> CPVREpgContainer::GetSavedSearches(
+ bool bRadio) const
{
const std::shared_ptr<const CPVREpgDatabase> database = GetEpgDatabase();
if (!database)
@@ -965,7 +966,8 @@ std::vector<std::shared_ptr<CPVREpgSearchFilter>> CPVREpgContainer::GetSavedSear
return database->GetSavedSearches(bRadio);
}
-std::shared_ptr<CPVREpgSearchFilter> CPVREpgContainer::GetSavedSearchById(bool bRadio, int iId)
+std::shared_ptr<CPVREpgSearchFilter> CPVREpgContainer::GetSavedSearchById(bool bRadio,
+ int iId) const
{
const std::shared_ptr<const CPVREpgDatabase> database = GetEpgDatabase();
if (!database)
diff --git a/xbmc/pvr/epg/EpgContainer.h b/xbmc/pvr/epg/EpgContainer.h
index 0b6c426b61..dbfb5acf6b 100644
--- a/xbmc/pvr/epg/EpgContainer.h
+++ b/xbmc/pvr/epg/EpgContainer.h
@@ -224,7 +224,7 @@ namespace PVR
* @param bRadio Whether to fetch saved searches for radio or TV.
* @return The searches.
*/
- std::vector<std::shared_ptr<CPVREpgSearchFilter>> GetSavedSearches(bool bRadio);
+ std::vector<std::shared_ptr<CPVREpgSearchFilter>> GetSavedSearches(bool bRadio) const;
/*!
* @brief Get the saved search matching the given id.
@@ -232,7 +232,7 @@ namespace PVR
* @param iId The id.
* @return The saved search or nullptr if not found.
*/
- std::shared_ptr<CPVREpgSearchFilter> GetSavedSearchById(bool bRadio, int iId);
+ std::shared_ptr<CPVREpgSearchFilter> GetSavedSearchById(bool bRadio, int iId) const;
/*!
* @brief Persist a saved search in the database.
diff --git a/xbmc/pvr/epg/EpgSearch.cpp b/xbmc/pvr/epg/EpgSearch.cpp
new file mode 100644
index 0000000000..5981b87a47
--- /dev/null
+++ b/xbmc/pvr/epg/EpgSearch.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2023 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 "EpgSearch.h"
+
+#include "ServiceBroker.h"
+#include "pvr/PVRManager.h"
+#include "pvr/epg/EpgContainer.h"
+#include "pvr/epg/EpgSearchFilter.h"
+
+#include <algorithm>
+#include <mutex>
+
+using namespace PVR;
+
+void CPVREpgSearch::Execute()
+{
+ std::unique_lock<CCriticalSection> lock(m_critSection);
+
+ std::vector<std::shared_ptr<CPVREpgInfoTag>> tags{
+ CServiceBroker::GetPVRManager().EpgContainer().GetTags(m_filter.GetEpgSearchData())};
+ m_filter.SetEpgSearchDataFiltered();
+
+ // Tags can still contain false positives, for search criteria that cannot be handled via
+ // database. So, run extended search filters on what we got from the database.
+ for (auto it = tags.cbegin(); it != tags.cend();)
+ {
+ it = tags.erase(std::remove_if(tags.begin(), tags.end(),
+ [this](const std::shared_ptr<const CPVREpgInfoTag>& entry)
+ { return !m_filter.FilterEntry(entry); }),
+ tags.cend());
+ }
+
+ if (m_filter.ShouldRemoveDuplicates())
+ m_filter.RemoveDuplicates(tags);
+
+ m_filter.SetLastExecutedDateTime(CDateTime::GetUTCDateTime());
+
+ m_results = tags;
+}
+
+const std::vector<std::shared_ptr<CPVREpgInfoTag>>& CPVREpgSearch::GetResults() const
+{
+ std::unique_lock<CCriticalSection> lock(m_critSection);
+ return m_results;
+}
diff --git a/xbmc/pvr/epg/EpgSearch.h b/xbmc/pvr/epg/EpgSearch.h
new file mode 100644
index 0000000000..6dbbf89b29
--- /dev/null
+++ b/xbmc/pvr/epg/EpgSearch.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#pragma once
+
+#include "threads/CriticalSection.h"
+
+#include <memory>
+#include <vector>
+
+namespace PVR
+{
+class CPVREpgInfoTag;
+class CPVREpgSearchFilter;
+
+class CPVREpgSearch
+{
+public:
+ CPVREpgSearch() = delete;
+
+ /*!
+ * @brief ctor.
+ * @param filter The filter defining the search criteria.
+ */
+ explicit CPVREpgSearch(CPVREpgSearchFilter& filter) : m_filter(filter) {}
+
+ /*!
+ * @brief Execute the search.
+ */
+ void Execute();
+
+ /*!
+ * @brief Get the last search results.
+ * @return the results.
+ */
+ const std::vector<std::shared_ptr<CPVREpgInfoTag>>& GetResults() const;
+
+private:
+ mutable CCriticalSection m_critSection;
+ CPVREpgSearchFilter& m_filter;
+ std::vector<std::shared_ptr<CPVREpgInfoTag>> m_results;
+};
+} // namespace PVR
diff --git a/xbmc/pvr/filesystem/PVRGUIDirectory.cpp b/xbmc/pvr/filesystem/PVRGUIDirectory.cpp
index 63341bd707..290b2b8bce 100644
--- a/xbmc/pvr/filesystem/PVRGUIDirectory.cpp
+++ b/xbmc/pvr/filesystem/PVRGUIDirectory.cpp
@@ -23,6 +23,7 @@
#include "pvr/channels/PVRChannelGroupsContainer.h"
#include "pvr/channels/PVRChannelsPath.h"
#include "pvr/epg/EpgContainer.h"
+#include "pvr/epg/EpgSearch.h"
#include "pvr/epg/EpgSearchFilter.h"
#include "pvr/epg/EpgSearchPath.h"
#include "pvr/recordings/PVRRecording.h"
@@ -224,6 +225,8 @@ bool CPVRGUIDirectory::GetDirectory(CFileItemList& results) const
{
if (path.IsSavedSearchesRoot())
return GetSavedSearchesDirectory(path.IsRadio(), results);
+ else if (path.IsSavedSearch())
+ return GetSavedSearchResults(path.IsRadio(), path.GetId(), results);
}
return true;
}
@@ -435,6 +438,24 @@ bool CPVRGUIDirectory::GetSavedSearchesDirectory(bool bRadio, CFileItemList& res
return true;
}
+bool CPVRGUIDirectory::GetSavedSearchResults(bool isRadio, int id, CFileItemList& results) const
+{
+ auto& epgContainer{CServiceBroker::GetPVRManager().EpgContainer()};
+ const std::shared_ptr<CPVREpgSearchFilter> filter{epgContainer.GetSavedSearchById(isRadio, id)};
+ if (filter)
+ {
+ CPVREpgSearch search(*filter);
+ search.Execute();
+ const auto tags{search.GetResults()};
+ for (const auto& tag : tags)
+ {
+ results.Add(std::make_shared<CFileItem>(tag));
+ }
+ return true;
+ }
+ return false;
+}
+
bool CPVRGUIDirectory::GetChannelGroupsDirectory(bool bRadio,
bool bExcludeHidden,
CFileItemList& results)
diff --git a/xbmc/pvr/filesystem/PVRGUIDirectory.h b/xbmc/pvr/filesystem/PVRGUIDirectory.h
index 462c55360c..31375ade32 100644
--- a/xbmc/pvr/filesystem/PVRGUIDirectory.h
+++ b/xbmc/pvr/filesystem/PVRGUIDirectory.h
@@ -100,6 +100,7 @@ private:
bool GetTimersDirectory(CFileItemList& results) const;
bool GetRecordingsDirectory(CFileItemList& results) const;
bool GetSavedSearchesDirectory(bool bRadio, CFileItemList& results) const;
+ bool GetSavedSearchResults(bool isRadio, int id, CFileItemList& results) const;
const CURL m_url;
};
diff --git a/xbmc/pvr/windows/GUIWindowPVRSearch.cpp b/xbmc/pvr/windows/GUIWindowPVRSearch.cpp
index 4a9ad6b10e..356e65dcc0 100644
--- a/xbmc/pvr/windows/GUIWindowPVRSearch.cpp
+++ b/xbmc/pvr/windows/GUIWindowPVRSearch.cpp
@@ -26,6 +26,7 @@
#include "pvr/epg/Epg.h"
#include "pvr/epg/EpgContainer.h"
#include "pvr/epg/EpgInfoTag.h"
+#include "pvr/epg/EpgSearch.h"
#include "pvr/epg/EpgSearchFilter.h"
#include "pvr/epg/EpgSearchPath.h"
#include "pvr/guilib/PVRGUIActionsEPG.h"
@@ -71,27 +72,10 @@ bool AsyncSearchAction::Execute()
void AsyncSearchAction::Run()
{
- std::vector<std::shared_ptr<CPVREpgInfoTag>> results =
- CServiceBroker::GetPVRManager().EpgContainer().GetTags(m_filter->GetEpgSearchData());
- m_filter->SetEpgSearchDataFiltered();
-
- // Tags can still contain false positives, for search criteria that cannot be handled via
- // database. So, run extended search filters on what we got from the database.
- for (auto it = results.begin(); it != results.end();)
- {
- it = results.erase(std::remove_if(results.begin(), results.end(),
- [this](const std::shared_ptr<CPVREpgInfoTag>& entry) {
- return !m_filter->FilterEntry(entry);
- }),
- results.end());
- }
-
- if (m_filter->ShouldRemoveDuplicates())
- m_filter->RemoveDuplicates(results);
-
- m_filter->SetLastExecutedDateTime(CDateTime::GetUTCDateTime());
-
- for (const auto& tag : results)
+ CPVREpgSearch search(*m_filter);
+ search.Execute();
+ const auto tags{search.GetResults()};
+ for (const auto& tag : tags)
{
m_items->Add(std::make_shared<CFileItem>(tag));
}