diff options
author | Arne Morten Kvarving <spiff@kodi.tv> | 2024-09-26 21:20:11 +0200 |
---|---|---|
committer | Arne Morten Kvarving <spiff@kodi.tv> | 2024-10-02 19:00:23 +0200 |
commit | 14d2545bac5aff765e322065dd105474b3c12997 (patch) | |
tree | 0d28dca53dfdc76259e0e0e4ffabf59c47e20af1 | |
parent | 777b96257d609454a4b4716a2b9106d5a73f7fcd (diff) |
move CFileItem::FindTrailer to VideoUtils
-rw-r--r-- | xbmc/FileItem.cpp | 83 | ||||
-rw-r--r-- | xbmc/FileItem.h | 3 | ||||
-rw-r--r-- | xbmc/video/VideoInfoScanner.cpp | 5 | ||||
-rw-r--r-- | xbmc/video/VideoUtils.cpp | 85 | ||||
-rw-r--r-- | xbmc/video/VideoUtils.h | 7 | ||||
-rw-r--r-- | xbmc/video/dialogs/GUIDialogVideoInfo.cpp | 3 | ||||
-rw-r--r-- | xbmc/video/test/TestVideoUtils.cpp | 62 |
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)); |