aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArne Morten Kvarving <spiff@kodi.tv>2024-09-26 21:20:11 +0200
committerArne Morten Kvarving <spiff@kodi.tv>2024-10-02 19:00:23 +0200
commit14d2545bac5aff765e322065dd105474b3c12997 (patch)
tree0d28dca53dfdc76259e0e0e4ffabf59c47e20af1
parent777b96257d609454a4b4716a2b9106d5a73f7fcd (diff)
move CFileItem::FindTrailer to VideoUtils
-rw-r--r--xbmc/FileItem.cpp83
-rw-r--r--xbmc/FileItem.h3
-rw-r--r--xbmc/video/VideoInfoScanner.cpp5
-rw-r--r--xbmc/video/VideoUtils.cpp85
-rw-r--r--xbmc/video/VideoUtils.h7
-rw-r--r--xbmc/video/dialogs/GUIDialogVideoInfo.cpp3
-rw-r--r--xbmc/video/test/TestVideoUtils.cpp62
7 files changed, 159 insertions, 89 deletions
diff --git a/xbmc/FileItem.cpp b/xbmc/FileItem.cpp
index dcc28288e4..a3fa357232 100644
--- a/xbmc/FileItem.cpp
+++ b/xbmc/FileItem.cpp
@@ -2354,89 +2354,6 @@ const std::shared_ptr<PVR::CPVRChannel> CFileItem::GetPVRChannelInfoTag() const
: std::shared_ptr<CPVRChannel>();
}
-std::string CFileItem::FindTrailer() const
-{
- std::string strFile2;
- std::string strFile = m_strPath;
- if (IsStack())
- {
- std::string strPath;
- URIUtils::GetParentPath(m_strPath,strPath);
- CStackDirectory dir;
- std::string strPath2;
- strPath2 = dir.GetStackedTitlePath(strFile);
- strFile = URIUtils::AddFileToFolder(strPath,URIUtils::GetFileName(strPath2));
- CFileItem item(dir.GetFirstStackedFile(m_strPath),false);
- std::string strTBNFile(URIUtils::ReplaceExtension(ART::GetTBNFile(item), "-trailer"));
- strFile2 = URIUtils::AddFileToFolder(strPath,URIUtils::GetFileName(strTBNFile));
- }
- if (URIUtils::IsInRAR(strFile) || URIUtils::IsInZIP(strFile))
- {
- std::string strPath = URIUtils::GetDirectory(strFile);
- std::string strParent;
- URIUtils::GetParentPath(strPath,strParent);
- strFile = URIUtils::AddFileToFolder(strParent,URIUtils::GetFileName(m_strPath));
- }
-
- // no local trailer available for these
- if (NETWORK::IsInternetStream(*this) || URIUtils::IsUPnP(strFile) ||
- URIUtils::IsBluray(strFile) || IsLiveTV() || IsPlugin() || IsDVD())
- return "";
-
- std::string strDir = URIUtils::GetDirectory(strFile);
- CFileItemList items;
- CDirectory::GetDirectory(strDir, items, CServiceBroker::GetFileExtensionProvider().GetVideoExtensions(), DIR_FLAG_READ_CACHE | DIR_FLAG_NO_FILE_INFO | DIR_FLAG_NO_FILE_DIRS);
- URIUtils::RemoveExtension(strFile);
- strFile += "-trailer";
- std::string strFile3 = URIUtils::AddFileToFolder(strDir, "movie-trailer");
-
- // Precompile our REs
- VECCREGEXP matchRegExps;
- CRegExp tmpRegExp(true, CRegExp::autoUtf8);
- const std::vector<std::string>& strMatchRegExps = CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_trailerMatchRegExps;
-
- std::vector<std::string>::const_iterator strRegExp = strMatchRegExps.begin();
- while (strRegExp != strMatchRegExps.end())
- {
- if (tmpRegExp.RegComp(*strRegExp))
- {
- matchRegExps.push_back(tmpRegExp);
- }
- ++strRegExp;
- }
-
- std::string strTrailer;
- for (int i = 0; i < items.Size(); i++)
- {
- std::string strCandidate = items[i]->m_strPath;
- URIUtils::RemoveExtension(strCandidate);
- if (StringUtils::EqualsNoCase(strCandidate, strFile) ||
- StringUtils::EqualsNoCase(strCandidate, strFile2) ||
- StringUtils::EqualsNoCase(strCandidate, strFile3))
- {
- strTrailer = items[i]->m_strPath;
- break;
- }
- else
- {
- VECCREGEXP::iterator expr = matchRegExps.begin();
-
- while (expr != matchRegExps.end())
- {
- if (expr->RegFind(strCandidate) != -1)
- {
- strTrailer = items[i]->m_strPath;
- i = items.Size();
- break;
- }
- ++expr;
- }
- }
- }
-
- return strTrailer;
-}
-
VideoDbContentType CFileItem::GetVideoContentType() const
{
VideoDbContentType type = VideoDbContentType::MOVIES;
diff --git a/xbmc/FileItem.h b/xbmc/FileItem.h
index 635c964d8d..ffdac95d49 100644
--- a/xbmc/FileItem.h
+++ b/xbmc/FileItem.h
@@ -448,9 +448,6 @@ public:
*/
std::string GetLocalMetadataPath() const;
- // finds a matching local trailer file
- std::string FindTrailer() const;
-
bool LoadMusicTag();
bool LoadGameTag();
diff --git a/xbmc/video/VideoInfoScanner.cpp b/xbmc/video/VideoInfoScanner.cpp
index c02ee60282..10cc30a6c9 100644
--- a/xbmc/video/VideoInfoScanner.cpp
+++ b/xbmc/video/VideoInfoScanner.cpp
@@ -49,6 +49,7 @@
#include "video/VideoFileItemClassify.h"
#include "video/VideoManagerTypes.h"
#include "video/VideoThumbLoader.h"
+#include "video/VideoUtils.h"
#include "video/dialogs/GUIDialogVideoManagerExtras.h"
#include "video/dialogs/GUIDialogVideoManagerVersions.h"
@@ -59,7 +60,7 @@
using namespace XFILE;
using namespace ADDON;
using namespace KODI::MESSAGING;
-using namespace KODI::VIDEO;
+using namespace KODI;
using KODI::MESSAGING::HELPERS::DialogResponse;
using KODI::UTILITY::CDigest;
@@ -1527,7 +1528,7 @@ namespace KODI::VIDEO
if (content == CONTENT_MOVIES)
{
// find local trailer first
- std::string strTrailer = pItem->FindTrailer();
+ std::string strTrailer = UTILS::FindTrailer(*pItem);
if (!strTrailer.empty())
movieDetails.m_strTrailer = strTrailer;
diff --git a/xbmc/video/VideoUtils.cpp b/xbmc/video/VideoUtils.cpp
index 16f6c0cd38..73f38e4ead 100644
--- a/xbmc/video/VideoUtils.cpp
+++ b/xbmc/video/VideoUtils.cpp
@@ -13,13 +13,18 @@
#include "ServiceBroker.h"
#include "Util.h"
#include "filesystem/Directory.h"
+#include "filesystem/StackDirectory.h"
#include "filesystem/VideoDatabaseDirectory/QueryParams.h"
+#include "network/NetworkFileItemClassify.h"
#include "playlists/PlayListFileItemClassify.h"
#include "pvr/filesystem/PVRGUIDirectory.h"
+#include "settings/AdvancedSettings.h"
#include "settings/SettingUtils.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
#include "settings/lib/Setting.h"
+#include "utils/ArtUtils.h"
+#include "utils/FileExtensionProvider.h"
#include "utils/FileUtils.h"
#include "utils/URIUtils.h"
#include "utils/log.h"
@@ -187,6 +192,86 @@ KODI::VIDEO::UTILS::ResumeInformation GetNonFolderItemResumeInformation(const CF
namespace KODI::VIDEO::UTILS
{
+
+std::string FindTrailer(const CFileItem& item)
+{
+ std::string strFile2;
+ std::string strFile = item.GetPath();
+ if (item.IsStack())
+ {
+ std::string strPath;
+ URIUtils::GetParentPath(item.GetPath(), strPath);
+ XFILE::CStackDirectory dir;
+ std::string strPath2;
+ strPath2 = dir.GetStackedTitlePath(strFile);
+ strFile = URIUtils::AddFileToFolder(strPath, URIUtils::GetFileName(strPath2));
+ CFileItem sitem(dir.GetFirstStackedFile(item.GetPath()), false);
+ std::string strTBNFile(URIUtils::ReplaceExtension(ART::GetTBNFile(sitem), "-trailer"));
+ strFile2 = URIUtils::AddFileToFolder(strPath, URIUtils::GetFileName(strTBNFile));
+ }
+ if (URIUtils::IsInRAR(strFile) || URIUtils::IsInZIP(strFile))
+ {
+ std::string strPath = URIUtils::GetDirectory(strFile);
+ std::string strParent;
+ URIUtils::GetParentPath(strPath, strParent);
+ strFile = URIUtils::AddFileToFolder(strParent, URIUtils::GetFileName(item.GetPath()));
+ }
+
+ // no local trailer available for these
+ if (NETWORK::IsInternetStream(item) || URIUtils::IsUPnP(strFile) || URIUtils::IsBluray(strFile) ||
+ item.IsLiveTV() || item.IsPlugin() || item.IsDVD())
+ return "";
+
+ std::string strDir = URIUtils::GetDirectory(strFile);
+ CFileItemList items;
+ XFILE::CDirectory::GetDirectory(
+ strDir, items, CServiceBroker::GetFileExtensionProvider().GetVideoExtensions(),
+ XFILE::DIR_FLAG_READ_CACHE | XFILE::DIR_FLAG_NO_FILE_INFO | XFILE::DIR_FLAG_NO_FILE_DIRS);
+ URIUtils::RemoveExtension(strFile);
+ strFile += "-trailer";
+ std::string strFile3 = URIUtils::AddFileToFolder(strDir, "movie-trailer");
+
+ // Precompile our REs
+ VECCREGEXP matchRegExps;
+ CRegExp tmpRegExp(true, CRegExp::autoUtf8);
+ const std::vector<std::string>& strMatchRegExps =
+ CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_trailerMatchRegExps;
+
+ for (const auto& strRegExp : strMatchRegExps)
+ {
+ if (tmpRegExp.RegComp(strRegExp))
+ matchRegExps.push_back(tmpRegExp);
+ }
+
+ std::string strTrailer;
+ for (int i = 0; i < items.Size(); i++)
+ {
+ std::string strCandidate = items[i]->GetPath();
+ URIUtils::RemoveExtension(strCandidate);
+ if (StringUtils::EqualsNoCase(strCandidate, strFile) ||
+ StringUtils::EqualsNoCase(strCandidate, strFile2) ||
+ StringUtils::EqualsNoCase(strCandidate, strFile3))
+ {
+ strTrailer = items[i]->GetPath();
+ break;
+ }
+ else
+ {
+ for (auto& expr : matchRegExps)
+ {
+ if (expr.RegFind(strCandidate) != -1)
+ {
+ strTrailer = items[i]->GetPath();
+ i = items.Size();
+ break;
+ }
+ }
+ }
+ }
+
+ return strTrailer;
+}
+
std::string GetOpticalMediaPath(const CFileItem& item)
{
auto exists = [&item](const std::string& file)
diff --git a/xbmc/video/VideoUtils.h b/xbmc/video/VideoUtils.h
index c344072ffe..2ee611c4e8 100644
--- a/xbmc/video/VideoUtils.h
+++ b/xbmc/video/VideoUtils.h
@@ -14,6 +14,13 @@ class CFileItem;
namespace KODI::VIDEO::UTILS
{
+
+/*! \brief
+ * Find a local trailer file for a given file item
+ * \return non-empty string with path of trailer if found
+ */
+std::string FindTrailer(const CFileItem& item);
+
/*!
\brief Check whether an item is an optical media folder or its parent.
This will return the non-empty path to the playable entry point of the media
diff --git a/xbmc/video/dialogs/GUIDialogVideoInfo.cpp b/xbmc/video/dialogs/GUIDialogVideoInfo.cpp
index 7d93996ba5..f7c931e4b0 100644
--- a/xbmc/video/dialogs/GUIDialogVideoInfo.cpp
+++ b/xbmc/video/dialogs/GUIDialogVideoInfo.cpp
@@ -59,6 +59,7 @@
#include "video/VideoItemArtworkHandler.h"
#include "video/VideoLibraryQueue.h"
#include "video/VideoThumbLoader.h"
+#include "video/VideoUtils.h"
#include "video/dialogs/GUIDialogVideoManagerExtras.h"
#include "video/dialogs/GUIDialogVideoManagerVersions.h"
#include "video/guilib/VideoGUIUtils.h"
@@ -453,7 +454,7 @@ void CGUIDialogVideoInfo::SetMovie(const CFileItem *item)
if (m_movieItem->GetVideoInfoTag()->m_strTrailer.empty() ||
URIUtils::IsInternetStream(m_movieItem->GetVideoInfoTag()->m_strTrailer))
{
- std::string localTrailer = m_movieItem->FindTrailer();
+ std::string localTrailer = VIDEO::UTILS::FindTrailer(*m_movieItem);
if (!localTrailer.empty())
{
m_movieItem->GetVideoInfoTag()->m_strTrailer = localTrailer;
diff --git a/xbmc/video/test/TestVideoUtils.cpp b/xbmc/video/test/TestVideoUtils.cpp
index 579fff0180..9feb832e5b 100644
--- a/xbmc/video/test/TestVideoUtils.cpp
+++ b/xbmc/video/test/TestVideoUtils.cpp
@@ -7,6 +7,7 @@
*/
#include "FileItem.h"
+#include "URL.h"
#include "Util.h"
#include "filesystem/Directory.h"
#include "platform/Filesystem.h"
@@ -22,12 +23,23 @@
using namespace KODI;
namespace fs = KODI::PLATFORM::FILESYSTEM;
+namespace
+{
+
using OptDef = std::pair<std::string, bool>;
class OpticalMediaPathTest : public testing::WithParamInterface<OptDef>, public testing::Test
{
};
+using TrailerDef = std::pair<std::string, std::string>;
+
+class TrailerTest : public testing::WithParamInterface<TrailerDef>, public testing::Test
+{
+};
+
+} // namespace
+
TEST_P(OpticalMediaPathTest, GetOpticalMediaPath)
{
std::error_code ec;
@@ -57,3 +69,53 @@ const auto mediapath_tests = std::array{
};
INSTANTIATE_TEST_SUITE_P(TestVideoUtils, OpticalMediaPathTest, testing::ValuesIn(mediapath_tests));
+
+TEST_P(TrailerTest, FindTrailer)
+{
+ std::string temp_path;
+ if (!GetParam().second.empty())
+ {
+ std::error_code ec;
+ temp_path = fs::create_temp_directory(ec);
+ EXPECT_FALSE(ec);
+ XFILE::CDirectory::Create(temp_path);
+ const std::string file_path = URIUtils::AddFileToFolder(temp_path, GetParam().second);
+ {
+ std::ofstream of(file_path);
+ }
+ URIUtils::AddSlashAtEnd(temp_path);
+ }
+
+ std::string input_path = GetParam().first;
+ if (!temp_path.empty())
+ {
+ StringUtils::Replace(input_path, "#DIRECTORY#", temp_path);
+ StringUtils::Replace(input_path, "#URLENCODED_DIRECTORY#", CURL::Encode(temp_path));
+ }
+
+ CFileItem item(input_path, false);
+ EXPECT_EQ(VIDEO::UTILS::FindTrailer(item),
+ GetParam().second.empty() ? ""
+ : URIUtils::AddFileToFolder(temp_path, GetParam().second));
+
+ if (!temp_path.empty())
+ XFILE::CDirectory::RemoveRecursive(temp_path);
+}
+
+const auto trailer_tests = std::array{
+ TrailerDef{"https://some.where/foo", ""},
+ TrailerDef{"upnp://1/2/3", ""},
+ TrailerDef{"bluray://1", ""},
+ TrailerDef{"pvr://foobar.pvr", ""},
+ TrailerDef{"plugin://plugin.video.foo/foo?param=1", ""},
+ TrailerDef{"dvd://1", ""},
+ TrailerDef{"stack://#DIRECTORY#foo-cd1.avi , #DIRECTORY#foo-cd2.avi", "foo-trailer.mkv"},
+ TrailerDef{"stack://#DIRECTORY#foo-cd1.avi , #DIRECTORY#foo-cd2.avi", "foo-cd1-trailer.avi"},
+ TrailerDef{"stack://#DIRECTORY#foo-cd1.avi , #DIRECTORY#foo-cd2.avi", "movie-trailer.mp4"},
+ TrailerDef{"zip://#URLENCODED_DIRECTORY#bar.zip/bar.avi", "bar-trailer.mov"},
+ TrailerDef{"zip://#URLENCODED_DIRECTORY#bar.zip/bar.mkv", "movie-trailer.ogm"},
+ TrailerDef{"#DIRECTORY#bar.mkv", "bar-trailer.mkv"},
+ TrailerDef{"#DIRECTORY#bar.mkv", "movie-trailer.avi"},
+};
+
+INSTANTIATE_TEST_SUITE_P(TestVideoUtils, TrailerTest, testing::ValuesIn(trailer_tests));