diff options
author | Ryan Rector <rmrector@gmail.com> | 2021-02-08 19:01:58 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-08 19:01:58 -0700 |
commit | 38127dd2853a4512e092f215214b87e3f526dd9e (patch) | |
tree | c67828517a4a301f8aa732a58627d30e502f8c36 | |
parent | 66b20d929bd2388762b021d82b0ea028fbbc6929 (diff) | |
parent | b1e41546c7f32062edfb1cdb8a83887f60cff80e (diff) |
Merge pull request #19185 from rmrector/available-art-get-api
[jsonrpc] get available-but-not-assigned artwork
-rw-r--r-- | xbmc/interfaces/json-rpc/AudioLibrary.cpp | 72 | ||||
-rw-r--r-- | xbmc/interfaces/json-rpc/AudioLibrary.h | 2 | ||||
-rw-r--r-- | xbmc/interfaces/json-rpc/JSONServiceDescription.cpp | 4 | ||||
-rw-r--r-- | xbmc/interfaces/json-rpc/VideoLibrary.cpp | 80 | ||||
-rw-r--r-- | xbmc/interfaces/json-rpc/VideoLibrary.h | 2 | ||||
-rw-r--r-- | xbmc/interfaces/json-rpc/schema/methods.json | 116 | ||||
-rw-r--r-- | xbmc/interfaces/json-rpc/schema/version.txt | 2 | ||||
-rw-r--r-- | xbmc/music/MusicDatabase.cpp | 60 | ||||
-rw-r--r-- | xbmc/music/MusicDatabase.h | 10 | ||||
-rw-r--r-- | xbmc/utils/ScraperUrl.cpp | 2 | ||||
-rw-r--r-- | xbmc/utils/ScraperUrl.h | 1 | ||||
-rw-r--r-- | xbmc/video/VideoDatabase.cpp | 116 | ||||
-rw-r--r-- | xbmc/video/VideoDatabase.h | 10 |
13 files changed, 453 insertions, 24 deletions
diff --git a/xbmc/interfaces/json-rpc/AudioLibrary.cpp b/xbmc/interfaces/json-rpc/AudioLibrary.cpp index 77ee116f86..258e266aa2 100644 --- a/xbmc/interfaces/json-rpc/AudioLibrary.cpp +++ b/xbmc/interfaces/json-rpc/AudioLibrary.cpp @@ -663,6 +663,78 @@ JSONRPC_STATUS JSONRPC::CAudioLibrary::GetSources(const std::string& method, ITr return OK; } +JSONRPC_STATUS CAudioLibrary::GetAvailableArtTypes(const std::string& method, ITransportLayer* transport, IClient* client, const CVariant& parameterObject, CVariant& result) +{ + std::string mediaType; + int mediaID = -1; + if (parameterObject["item"].isMember("albumid")) + { + mediaType = MediaTypeAlbum; + mediaID = parameterObject["item"]["albumid"].asInteger32(); + } + if (parameterObject["item"].isMember("artistid")) + { + mediaType = MediaTypeArtist; + mediaID = parameterObject["item"]["artistid"].asInteger32(); + } + if (mediaID == -1) + return InternalError; + + CMusicDatabase musicdatabase; + if (!musicdatabase.Open()) + return InternalError; + + CVariant availablearttypes = CVariant(CVariant::VariantTypeArray); + for (const auto& artType : musicdatabase.GetAvailableArtTypesForItem(mediaID, mediaType)) + { + availablearttypes.append(artType); + } + result = CVariant(CVariant::VariantTypeObject); + result["availablearttypes"] = availablearttypes; + + return OK; +} + +JSONRPC_STATUS CAudioLibrary::GetAvailableArt(const std::string& method, ITransportLayer* transport, IClient* client, const CVariant& parameterObject, CVariant& result) +{ + std::string mediaType; + int mediaID = -1; + if (parameterObject["item"].isMember("albumid")) + { + mediaType = MediaTypeAlbum; + mediaID = parameterObject["item"]["albumid"].asInteger32(); + } + if (parameterObject["item"].isMember("artistid")) + { + mediaType = MediaTypeArtist; + mediaID = parameterObject["item"]["artistid"].asInteger32(); + } + if (mediaID == -1) + return InternalError; + + std::string artType = parameterObject["arttype"].asString(); + StringUtils::ToLower(artType); + + CMusicDatabase musicdatabase; + if (!musicdatabase.Open()) + return InternalError; + + CVariant availableart = CVariant(CVariant::VariantTypeArray); + for (const auto& artentry : musicdatabase.GetAvailableArtForItem(mediaID, mediaType, artType)) + { + CVariant item = CVariant(CVariant::VariantTypeObject); + item["url"] = CTextureUtils::GetWrappedImageURL(artentry.m_url); + item["arttype"] = artentry.m_aspect; + if (!artentry.m_preview.empty()) + item["previewurl"] = CTextureUtils::GetWrappedImageURL(artentry.m_preview); + availableart.append(item); + } + result = CVariant(CVariant::VariantTypeObject); + result["availableart"] = availableart; + + return OK; +} + JSONRPC_STATUS CAudioLibrary::SetArtistDetails(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { int id = (int)parameterObject["artistid"].asInteger(); diff --git a/xbmc/interfaces/json-rpc/AudioLibrary.h b/xbmc/interfaces/json-rpc/AudioLibrary.h index 39a722f02f..1d5f02ff83 100644 --- a/xbmc/interfaces/json-rpc/AudioLibrary.h +++ b/xbmc/interfaces/json-rpc/AudioLibrary.h @@ -33,6 +33,8 @@ namespace JSONRPC static JSONRPC_STATUS GetGenres(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result); static JSONRPC_STATUS GetRoles(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result); static JSONRPC_STATUS GetSources(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result); + static JSONRPC_STATUS GetAvailableArtTypes(const std::string& method, ITransportLayer* transport, IClient* client, const CVariant& parameterObject, CVariant& result); + static JSONRPC_STATUS GetAvailableArt(const std::string& method, ITransportLayer* transport, IClient* client, const CVariant& parameterObject, CVariant& result); static JSONRPC_STATUS GetRecentlyAddedAlbums(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result); static JSONRPC_STATUS GetRecentlyAddedSongs(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result); diff --git a/xbmc/interfaces/json-rpc/JSONServiceDescription.cpp b/xbmc/interfaces/json-rpc/JSONServiceDescription.cpp index 2848bfe1d9..39faf635d2 100644 --- a/xbmc/interfaces/json-rpc/JSONServiceDescription.cpp +++ b/xbmc/interfaces/json-rpc/JSONServiceDescription.cpp @@ -107,6 +107,8 @@ JsonRpcMethodMap CJSONServiceDescription::m_methodMaps[] = { { "AudioLibrary.GetGenres", CAudioLibrary::GetGenres }, { "AudioLibrary.GetRoles", CAudioLibrary::GetRoles }, { "AudioLibrary.GetSources", CAudioLibrary::GetSources }, + { "AudioLibrary.GetAvailableArtTypes", CAudioLibrary::GetAvailableArtTypes }, + { "AudioLibrary.GetAvailableArt", CAudioLibrary::GetAvailableArt }, { "AudioLibrary.SetArtistDetails", CAudioLibrary::SetArtistDetails }, { "AudioLibrary.SetAlbumDetails", CAudioLibrary::SetAlbumDetails }, { "AudioLibrary.SetSongDetails", CAudioLibrary::SetSongDetails }, @@ -117,6 +119,8 @@ JsonRpcMethodMap CJSONServiceDescription::m_methodMaps[] = { // Video Library { "VideoLibrary.GetGenres", CVideoLibrary::GetGenres }, { "VideoLibrary.GetTags", CVideoLibrary::GetTags }, + { "VideoLibrary.GetAvailableArtTypes", CVideoLibrary::GetAvailableArtTypes }, + { "VideoLibrary.GetAvailableArt", CVideoLibrary::GetAvailableArt }, { "VideoLibrary.GetMovies", CVideoLibrary::GetMovies }, { "VideoLibrary.GetMovieDetails", CVideoLibrary::GetMovieDetails }, { "VideoLibrary.GetMovieSets", CVideoLibrary::GetMovieSets }, diff --git a/xbmc/interfaces/json-rpc/VideoLibrary.cpp b/xbmc/interfaces/json-rpc/VideoLibrary.cpp index 83b05762b6..08dc3824c6 100644 --- a/xbmc/interfaces/json-rpc/VideoLibrary.cpp +++ b/xbmc/interfaces/json-rpc/VideoLibrary.cpp @@ -508,6 +508,86 @@ JSONRPC_STATUS CVideoLibrary::GetTags(const std::string &method, ITransportLayer return OK; } +namespace +{ + const std::map<std::string, std::string> mediaIDTypes = { + {"episodeid", MediaTypeEpisode}, + {"tvshowid", MediaTypeTvShow}, + {"seasonid", MediaTypeSeason}, + {"movieid", MediaTypeMovie}, + {"setid", MediaTypeVideoCollection}, + {"musicvideoid", MediaTypeMusicVideo}, + }; +} + +JSONRPC_STATUS CVideoLibrary::GetAvailableArtTypes(const std::string& method, ITransportLayer* transport, IClient* client, const CVariant& parameterObject, CVariant& result) +{ + std::string mediaType; + int mediaID = -1; + for (const auto& mediaIDType : mediaIDTypes) { + if (parameterObject["item"].isMember(mediaIDType.first)) + { + mediaType = mediaIDType.second; + mediaID = parameterObject["item"][mediaIDType.first].asInteger32(); + break; + } + } + if (mediaID == -1) + return InternalError; + + CVideoDatabase videodatabase; + if (!videodatabase.Open()) + return InternalError; + + CVariant availablearttypes = CVariant(CVariant::VariantTypeArray); + for (const auto& artType : videodatabase.GetAvailableArtTypesForItem(mediaID, mediaType)) + { + availablearttypes.append(artType); + } + result = CVariant(CVariant::VariantTypeObject); + result["availablearttypes"] = availablearttypes; + + return OK; +} + +JSONRPC_STATUS CVideoLibrary::GetAvailableArt(const std::string& method, ITransportLayer* transport, IClient* client, const CVariant& parameterObject, CVariant& result) +{ + std::string mediaType; + int mediaID = -1; + for (const auto& mediaIDType : mediaIDTypes) { + if (parameterObject["item"].isMember(mediaIDType.first)) + { + mediaType = mediaIDType.second; + mediaID = parameterObject["item"][mediaIDType.first].asInteger32(); + break; + } + } + if (mediaID == -1) + return InternalError; + + std::string artType = parameterObject["arttype"].asString(); + StringUtils::ToLower(artType); + + CVideoDatabase videodatabase; + if (!videodatabase.Open()) + return InternalError; + + CVariant availableart = CVariant(CVariant::VariantTypeArray); + for (const auto& artentry : videodatabase.GetAvailableArtForItem(mediaID, mediaType, artType)) + { + CVariant item = CVariant(CVariant::VariantTypeObject); + item["url"] = CTextureUtils::GetWrappedImageURL(artentry.m_url); + item["arttype"] = artentry.m_aspect; + if (!artentry.m_preview.empty()) + item["previewurl"] = CTextureUtils::GetWrappedImageURL(artentry.m_preview); + availableart.append(item); + } + result = CVariant(CVariant::VariantTypeObject); + result["availableart"] = availableart; + + return OK; +} + JSONRPC_STATUS CVideoLibrary::SetMovieDetails(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { int id = (int)parameterObject["movieid"].asInteger(); diff --git a/xbmc/interfaces/json-rpc/VideoLibrary.h b/xbmc/interfaces/json-rpc/VideoLibrary.h index f6e68853f5..d933fa3e22 100644 --- a/xbmc/interfaces/json-rpc/VideoLibrary.h +++ b/xbmc/interfaces/json-rpc/VideoLibrary.h @@ -45,6 +45,8 @@ namespace JSONRPC static JSONRPC_STATUS GetGenres(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result); static JSONRPC_STATUS GetTags(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result); + static JSONRPC_STATUS GetAvailableArtTypes(const std::string& method, ITransportLayer* transport, IClient* client, const CVariant& parameterObject, CVariant& result); + static JSONRPC_STATUS GetAvailableArt(const std::string& method, ITransportLayer* transport, IClient* client, const CVariant& parameterObject, CVariant& result); static JSONRPC_STATUS SetMovieDetails(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result); static JSONRPC_STATUS SetMovieSetDetails(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result); diff --git a/xbmc/interfaces/json-rpc/schema/methods.json b/xbmc/interfaces/json-rpc/schema/methods.json index a330eaae6a..361de44f31 100644 --- a/xbmc/interfaces/json-rpc/schema/methods.json +++ b/xbmc/interfaces/json-rpc/schema/methods.json @@ -1023,6 +1023,60 @@ } } }, + "AudioLibrary.GetAvailableArtTypes": { + "type": "method", + "description": "Retrieve a list of potential art types for a media item", + "transport": "Response", + "permission": "ReadData", + "params": [ + { + "name": "item", "required": true, + "type": [ + { "type": "object", "properties": { "albumid": { "$ref": "Library.Id", "required": true } }, "additionalProperties": false }, + { "type": "object", "properties": { "artistid": { "$ref": "Library.Id", "required": true } }, "additionalProperties": false } + ] + } + ], + "returns": { + "type": "object", + "properties": { + "availablearttypes": { "type": "array", "required": true, + "items": { "type": "string" } + } + } + } + }, + "AudioLibrary.GetAvailableArt": { + "type": "method", + "description": "Retrieve all potential art URLs for a media item by art type", + "transport": "Response", + "permission": "ReadData", + "params": [ + { + "name": "item", "required": true, + "type": [ + { "type": "object", "properties": { "albumid": { "$ref": "Library.Id", "required": true } }, "additionalProperties": false }, + { "type": "object", "properties": { "artistid": { "$ref": "Library.Id", "required": true } }, "additionalProperties": false } + ] + }, + { "name": "arttype", "type": "string" } + ], + "returns": { + "type": "object", + "properties": { + "availableart": { "type": "array", "required": true, + "items": { + "type": "object", + "properties": { + "url": { "type": "string", "description": "URL to the original image", "required": true }, + "arttype": { "type": "string", "required": true }, + "previewurl": { "type": "string", "description": "URL to a preview thumbnail of the image" } + } + } + } + } + } + }, "AudioLibrary.SetArtistDetails": { "type": "method", "description": "Update the given artist with the given details", @@ -1540,6 +1594,68 @@ } } }, + "VideoLibrary.GetAvailableArtTypes": { + "type": "method", + "description": "Retrieve a list of potential art types for a media item", + "transport": "Response", + "permission": "ReadData", + "params": [ + { + "name": "item", "required": true, + "type": [ + { "type": "object", "properties": { "episodeid": { "$ref": "Library.Id", "required": true } }, "additionalProperties": false }, + { "type": "object", "properties": { "tvshowid": { "$ref": "Library.Id", "required": true } }, "additionalProperties": false }, + { "type": "object", "properties": { "seasonid": { "$ref": "Library.Id", "required": true } }, "additionalProperties": false }, + { "type": "object", "properties": { "movieid": { "$ref": "Library.Id", "required": true } }, "additionalProperties": false }, + { "type": "object", "properties": { "setid": { "$ref": "Library.Id", "required": true } }, "additionalProperties": false }, + { "type": "object", "properties": { "musicvideoid": { "$ref": "Library.Id", "required": true } }, "additionalProperties": false } + ] + } + ], + "returns": { + "type": "object", + "properties": { + "availablearttypes": { "type": "array", "required": true, + "items": { "type": "string" } + } + } + } + }, + "VideoLibrary.GetAvailableArt": { + "type": "method", + "description": "Retrieve all potential art URLs for a media item by art type", + "transport": "Response", + "permission": "ReadData", + "params": [ + { + "name": "item", "required": true, + "type": [ + { "type": "object", "properties": { "episodeid": { "$ref": "Library.Id", "required": true } }, "additionalProperties": false }, + { "type": "object", "properties": { "tvshowid": { "$ref": "Library.Id", "required": true } }, "additionalProperties": false }, + { "type": "object", "properties": { "seasonid": { "$ref": "Library.Id", "required": true } }, "additionalProperties": false }, + { "type": "object", "properties": { "movieid": { "$ref": "Library.Id", "required": true } }, "additionalProperties": false }, + { "type": "object", "properties": { "setid": { "$ref": "Library.Id", "required": true } }, "additionalProperties": false }, + { "type": "object", "properties": { "musicvideoid": { "$ref": "Library.Id", "required": true } }, "additionalProperties": false } + ] + }, + { "name": "arttype", "type": "string" } + ], + "returns": { + "type": "object", + "properties": { + "availableart": { "type": "array", "required": true, + "items": { + "type": "object", + "properties": { + "url": { "type": "string", "description": "URL to the original image", "required": true }, + "arttype": { "type": "string", "required": true }, + "previewurl": { "type": "string", "description": "URL to a preview thumbnail of the image" } + } + } + } + } + } + }, "VideoLibrary.SetMovieDetails": { "type": "method", "description": "Update the given movie with the given details", diff --git a/xbmc/interfaces/json-rpc/schema/version.txt b/xbmc/interfaces/json-rpc/schema/version.txt index 7258e02770..0df0e570bd 100644 --- a/xbmc/interfaces/json-rpc/schema/version.txt +++ b/xbmc/interfaces/json-rpc/schema/version.txt @@ -1 +1 @@ -JSONRPC_VERSION 12.1.0 +JSONRPC_VERSION 12.2.0 diff --git a/xbmc/music/MusicDatabase.cpp b/xbmc/music/MusicDatabase.cpp index ddea303cdc..b6e78f3f28 100644 --- a/xbmc/music/MusicDatabase.cpp +++ b/xbmc/music/MusicDatabase.cpp @@ -12228,36 +12228,56 @@ bool CMusicDatabase::GetArtTypes(const MediaType &mediaType, std::vector<std::st std::vector<std::string> CMusicDatabase::GetAvailableArtTypesForItem(int mediaId, const MediaType& mediaType) { + CScraperUrl thumbURL; + if (mediaType == MediaTypeArtist) + { + CArtist artist; + if (GetArtist(mediaId, artist)) + thumbURL = artist.thumbURL; + } + else if (mediaType == MediaTypeAlbum) + { + CAlbum album; + if (GetAlbum(mediaId, album)) + thumbURL = album.thumbURL; + } + std::vector<std::string> result; + for (const auto& urlEntry : thumbURL.GetUrls()) + { + std::string artType = urlEntry.m_aspect; + if (artType.empty()) + artType = "thumb"; + if (std::find(result.begin(), result.end(), artType) == result.end()) + result.push_back(artType); + } + return result; +} + +std::vector<CScraperUrl::SUrlEntry> CMusicDatabase::GetAvailableArtForItem( + int mediaId, const MediaType& mediaType, const std::string& artType) +{ + CScraperUrl thumbURL; if (mediaType == MediaTypeArtist) { CArtist artist; if (GetArtist(mediaId, artist)) - { - for (const auto& urlEntry : artist.thumbURL.GetUrls()) - { - std::string artType = urlEntry.m_aspect; - if (artType.empty()) - artType = "thumb"; - if (std::find(result.begin(), result.end(), artType) == result.end()) - result.push_back(artType); - } - } + thumbURL = artist.thumbURL; } else if (mediaType == MediaTypeAlbum) { CAlbum album; if (GetAlbum(mediaId, album)) - { - for (const auto& urlEntry : album.thumbURL.GetUrls()) - { - std::string artType = urlEntry.m_aspect; - if (artType.empty()) - artType = "thumb"; - if (std::find(result.begin(), result.end(), artType) == result.end()) - result.push_back(artType); - } - } + thumbURL = album.thumbURL; + } + + std::vector<CScraperUrl::SUrlEntry> result; + for (auto urlEntry : thumbURL.GetUrls()) + { + if (urlEntry.m_aspect.empty()) + urlEntry.m_aspect = "thumb"; + if (artType.empty() || urlEntry.m_aspect == artType) + result.push_back(urlEntry); } return result; } diff --git a/xbmc/music/MusicDatabase.h b/xbmc/music/MusicDatabase.h index 697c475da1..578cb87239 100644 --- a/xbmc/music/MusicDatabase.h +++ b/xbmc/music/MusicDatabase.h @@ -670,6 +670,16 @@ public: */ std::vector<std::string> GetAvailableArtTypesForItem(int mediaId, const MediaType& mediaType); + /*! \brief Fetch the list of available-but-unassigned art URLs held in the + database for a specific media item and art type. + \param mediaId the id in the media (artist/album) table. + \param mediaType corresponds to the table the item resides in (artist/album). + \param artType e.g. "thumb", "fanart", etc. + \return list of URLs + */ + std::vector<CScraperUrl::SUrlEntry> GetAvailableArtForItem( + int mediaId, const MediaType& mediaType, const std::string& artType); + ///////////////////////////////////////////////// // Tag Scan Version ///////////////////////////////////////////////// diff --git a/xbmc/utils/ScraperUrl.cpp b/xbmc/utils/ScraperUrl.cpp index 43df6dd6eb..f801e1adda 100644 --- a/xbmc/utils/ScraperUrl.cpp +++ b/xbmc/utils/ScraperUrl.cpp @@ -198,6 +198,7 @@ bool CScraperUrl::ParseAndAppendUrl(const TiXmlElement* element) } url.m_aspect = XMLUtils::GetAttribute(element, "aspect"); + url.m_preview = XMLUtils::GetAttribute(element, "preview"); m_urls.push_back(url); @@ -274,6 +275,7 @@ void CScraperUrl::AddParsedUrl(const std::string& url, nUrl.m_post = post; nUrl.m_isgz = isgz; nUrl.m_cache = cache; + nUrl.m_preview = preview; if (season >= 0) { nUrl.m_type = UrlType::Season; diff --git a/xbmc/utils/ScraperUrl.h b/xbmc/utils/ScraperUrl.h index c68aa3b076..9ff416a5dc 100644 --- a/xbmc/utils/ScraperUrl.h +++ b/xbmc/utils/ScraperUrl.h @@ -38,6 +38,7 @@ public: std::string m_url; std::string m_cache; std::string m_aspect; + std::string m_preview; UrlType m_type; bool m_post; bool m_isgz; diff --git a/xbmc/video/VideoDatabase.cpp b/xbmc/video/VideoDatabase.cpp index 6166db275c..2b5e9efe88 100644 --- a/xbmc/video/VideoDatabase.cpp +++ b/xbmc/video/VideoDatabase.cpp @@ -62,6 +62,7 @@ #include <memory> #include <string> #include <vector> +#include <unordered_set> using namespace dbiplus; using namespace XFILE; @@ -4794,6 +4795,7 @@ std::vector<std::string> GetBasicItemAvailableArtTypes(int mediaId, CVideoInfoTag tag = db.GetDetailsByTypeAndId(dbType, mediaId); //! @todo artwork: fanart stored separately, doesn't need to be + tag.m_fanart.Unpack(); if (tag.m_fanart.GetNumFanarts() && std::find(result.cbegin(), result.cend(), "fanart") == result.cend()) result.emplace_back("fanart"); @@ -4863,12 +4865,97 @@ std::vector<std::string> GetMovieSetAvailableArtTypes(int mediaId, CVideoDatabas } return result; } + +std::vector<CScraperUrl::SUrlEntry> GetBasicItemAvailableArt( + int mediaId, VIDEODB_CONTENT_TYPE dbType, const std::string& artType, CVideoDatabase& db) +{ + std::vector<CScraperUrl::SUrlEntry> result; + CVideoInfoTag tag = db.GetDetailsByTypeAndId(dbType, mediaId); + + if (artType.empty() || artType == "fanart") + { + tag.m_fanart.Unpack(); + for (unsigned int i = 1; i < tag.m_fanart.GetNumFanarts(); i++) + { + CScraperUrl::SUrlEntry url(tag.m_fanart.GetImageURL(i)); + url.m_preview = tag.m_fanart.GetPreviewURL(i); + url.m_aspect = "fanart"; + result.push_back(url); + } + } + tag.m_strPictureURL.Parse(); + for (auto urlEntry : tag.m_strPictureURL.GetUrls()) + { + if (urlEntry.m_aspect.empty()) + urlEntry.m_aspect = tag.m_type == MediaTypeEpisode ? "thumb" : "poster"; + if ((urlEntry.m_aspect == artType || + artType.empty() && !StringUtils::StartsWith(urlEntry.m_aspect, "set.")) && + urlEntry.m_type == CScraperUrl::UrlType::General) + { + result.push_back(urlEntry); + } + } + + return result; } -std::vector<std::string> CVideoDatabase::GetAvailableArtTypesForItem(int mediaId, - const MediaType& mediaType) +std::vector<CScraperUrl::SUrlEntry> GetSeasonAvailableArt( + int mediaId, const std::string& artType, CVideoDatabase& db) { - VIDEODB_CONTENT_TYPE dbType{VIDEODB_CONTENT_UNKNOWN}; + CVideoInfoTag tag; + db.GetSeasonInfo(mediaId, tag); + + std::vector<CScraperUrl::SUrlEntry> result; + + CVideoInfoTag sourceShow; + db.GetTvShowInfo("", sourceShow, tag.m_iIdShow); + sourceShow.m_strPictureURL.Parse(); + for (auto urlEntry : sourceShow.m_strPictureURL.GetUrls()) + { + if (urlEntry.m_aspect.empty()) + urlEntry.m_aspect = "poster"; + if ((artType.empty() || urlEntry.m_aspect == artType) && + urlEntry.m_type == CScraperUrl::UrlType::Season && + urlEntry.m_season == tag.m_iSeason) + { + result.push_back(urlEntry); + } + } + return result; +} + +std::vector<CScraperUrl::SUrlEntry> GetMovieSetAvailableArt( + int mediaId, const std::string& artType, CVideoDatabase& db) +{ + std::vector<CScraperUrl::SUrlEntry> result; + CFileItemList items; + std::string baseDir = StringUtils::Format("videodb://movies/sets/%d", mediaId); + std::unordered_set<std::string> addedURLs; + if (db.GetMoviesNav(baseDir, items)) + { + for (const auto& item : items) + { + CVideoInfoTag* pTag = item->GetVideoInfoTag(); + pTag->m_strPictureURL.Parse(); + + for (auto urlEntry : pTag->m_strPictureURL.GetUrls()) + { + bool isSetArt = !artType.empty() ? urlEntry.m_aspect == "set." + artType : + StringUtils::StartsWith(urlEntry.m_aspect, "set."); + if (isSetArt && addedURLs.insert(urlEntry.m_url).second) + { + urlEntry.m_aspect = urlEntry.m_aspect.substr(4); + result.push_back(urlEntry); + } + } + } + } + return result; +} + +VIDEODB_CONTENT_TYPE CovertMediaTypeToContentType(const MediaType& mediaType) +{ + VIDEODB_CONTENT_TYPE dbType{ VIDEODB_CONTENT_UNKNOWN }; if (mediaType == MediaTypeTvShow) dbType = VIDEODB_CONTENT_TVSHOWS; else if (mediaType == MediaTypeMovie) @@ -4878,6 +4965,29 @@ std::vector<std::string> CVideoDatabase::GetAvailableArtTypesForItem(int mediaId else if (mediaType == MediaTypeMusicVideo) dbType = VIDEODB_CONTENT_MUSICVIDEOS; + return dbType; +} +} // namespace + +std::vector<CScraperUrl::SUrlEntry> CVideoDatabase::GetAvailableArtForItem( + int mediaId, const MediaType& mediaType, const std::string& artType) +{ + VIDEODB_CONTENT_TYPE dbType = CovertMediaTypeToContentType(mediaType); + + if (dbType != VIDEODB_CONTENT_UNKNOWN) + return GetBasicItemAvailableArt(mediaId, dbType, artType, *this); + if (mediaType == MediaTypeSeason) + return GetSeasonAvailableArt(mediaId, artType, *this); + if (mediaType == MediaTypeVideoCollection) + return GetMovieSetAvailableArt(mediaId, artType, *this); + return {}; +} + +std::vector<std::string> CVideoDatabase::GetAvailableArtTypesForItem(int mediaId, + const MediaType& mediaType) +{ + VIDEODB_CONTENT_TYPE dbType = CovertMediaTypeToContentType(mediaType); + if (dbType != VIDEODB_CONTENT_UNKNOWN) return GetBasicItemAvailableArtTypes(mediaId, dbType, *this); if (mediaType == MediaTypeSeason) diff --git a/xbmc/video/VideoDatabase.h b/xbmc/video/VideoDatabase.h index f22155d922..48aa06d3e8 100644 --- a/xbmc/video/VideoDatabase.h +++ b/xbmc/video/VideoDatabase.h @@ -858,6 +858,16 @@ public: */ std::vector<std::string> GetAvailableArtTypesForItem(int mediaId, const MediaType& mediaType); + /*! \brief Fetch the list of available-but-unassigned art URLs held in the + database for a specific media item and art type. + \param mediaId the id in the media table. + \param mediaType corresponds to the table the item resides in. + \param artType e.g. "thumb", "fanart", etc. + \return list of URLs + */ + std::vector<CScraperUrl::SUrlEntry> GetAvailableArtForItem( + int mediaId, const MediaType& mediaType, const std::string& artType); + int AddTag(const std::string &tag); void AddTagToItem(int idItem, int idTag, const std::string &type); void RemoveTagFromItem(int idItem, int idTag, const std::string &type); |