aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Rector <rmrector@gmail.com>2021-02-08 19:01:58 -0700
committerGitHub <noreply@github.com>2021-02-08 19:01:58 -0700
commit38127dd2853a4512e092f215214b87e3f526dd9e (patch)
treec67828517a4a301f8aa732a58627d30e502f8c36
parent66b20d929bd2388762b021d82b0ea028fbbc6929 (diff)
parentb1e41546c7f32062edfb1cdb8a83887f60cff80e (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.cpp72
-rw-r--r--xbmc/interfaces/json-rpc/AudioLibrary.h2
-rw-r--r--xbmc/interfaces/json-rpc/JSONServiceDescription.cpp4
-rw-r--r--xbmc/interfaces/json-rpc/VideoLibrary.cpp80
-rw-r--r--xbmc/interfaces/json-rpc/VideoLibrary.h2
-rw-r--r--xbmc/interfaces/json-rpc/schema/methods.json116
-rw-r--r--xbmc/interfaces/json-rpc/schema/version.txt2
-rw-r--r--xbmc/music/MusicDatabase.cpp60
-rw-r--r--xbmc/music/MusicDatabase.h10
-rw-r--r--xbmc/utils/ScraperUrl.cpp2
-rw-r--r--xbmc/utils/ScraperUrl.h1
-rw-r--r--xbmc/video/VideoDatabase.cpp116
-rw-r--r--xbmc/video/VideoDatabase.h10
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 &parameterObject, 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 &parameterObject, CVariant &result);
static JSONRPC_STATUS GetRoles(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
static JSONRPC_STATUS GetSources(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, 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 &parameterObject, CVariant &result);
static JSONRPC_STATUS GetRecentlyAddedSongs(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, 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 &parameterObject, 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 &parameterObject, CVariant &result);
static JSONRPC_STATUS GetTags(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, 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 &parameterObject, CVariant &result);
static JSONRPC_STATUS SetMovieSetDetails(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, 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);