mirror of
https://github.com/owntone/owntone-server.git
synced 2025-10-29 07:45:04 -04:00
[artwork] Add function to get artwork for non-library queue items
Adds artwork_get_by_queue_item_id() and a source handler for getting artwork from queue_item->artwork_url.
This commit is contained in:
parent
bf598153f3
commit
921d4446d6
182
src/artwork.c
182
src/artwork.c
@ -113,6 +113,8 @@ struct artwork_ctx {
|
||||
uint32_t media_kind;
|
||||
// Input data for group handlers
|
||||
int64_t persistentid;
|
||||
// Input data for queue item handlers
|
||||
struct db_queue_item *queue_item;
|
||||
|
||||
// Not to be used by handler - query for item or group
|
||||
struct query_params qp;
|
||||
@ -210,6 +212,8 @@ static int source_item_ownpl_get(struct artwork_ctx *ctx);
|
||||
static int source_item_spotifywebapi_search_get(struct artwork_ctx *ctx);
|
||||
static int source_item_discogs_get(struct artwork_ctx *ctx);
|
||||
static int source_item_coverartarchive_get(struct artwork_ctx *ctx);
|
||||
/* Forward - queue item handlers */
|
||||
static int source_queue_item_artwork_url_get(struct artwork_ctx *ctx);
|
||||
|
||||
/* List of sources that can provide artwork for a group (i.e. usually an album
|
||||
* identified by a persistentid). The source handlers will be called in the
|
||||
@ -353,6 +357,24 @@ static struct artwork_source artwork_item_source[] =
|
||||
}
|
||||
};
|
||||
|
||||
/* List of sources that can provide artwork for a queue item. The source
|
||||
* handlers will be called in the order of this list. Must be terminated by a
|
||||
* NULL struct.
|
||||
*/
|
||||
static struct artwork_source artwork_queue_item_source[] =
|
||||
{
|
||||
{
|
||||
.name = "artwork url",
|
||||
.handler = source_queue_item_artwork_url_get,
|
||||
.cache = NEVER,
|
||||
},
|
||||
{
|
||||
.name = NULL,
|
||||
.handler = NULL,
|
||||
.cache = 0,
|
||||
}
|
||||
};
|
||||
|
||||
/* Forward - parsers of online source responses */
|
||||
static enum parse_result response_jparse_spotify(char **artwork_url, json_object *response, int max_w, int max_h);
|
||||
static enum parse_result response_jparse_discogs(char **artwork_url, json_object *response, int max_w, int max_h);
|
||||
@ -1607,41 +1629,25 @@ source_item_own_get(struct artwork_ctx *ctx)
|
||||
return artwork_get(ctx->evbuf, path, NULL, false, ctx->data_kind, ctx->req_params);
|
||||
}
|
||||
|
||||
/*
|
||||
* Downloads the artwork from the location pointed to by queue_item->artwork_url
|
||||
*/
|
||||
static int
|
||||
source_item_artwork_url_get(struct artwork_ctx *ctx)
|
||||
{
|
||||
struct db_queue_item *queue_item;
|
||||
const char *proto_http = "http:";
|
||||
const char *proto_https = "https:";
|
||||
bool is_http;
|
||||
bool is_https;
|
||||
int ret;
|
||||
|
||||
DPRINTF(E_SPAM, L_ART, "Trying artwork url for %s\n", ctx->dbmfi->path);
|
||||
|
||||
queue_item = db_queue_fetch_byfileid(ctx->id);
|
||||
if (!queue_item || !queue_item->artwork_url)
|
||||
goto notfound;
|
||||
|
||||
is_http = (strncmp(queue_item->artwork_url, proto_http, strlen(proto_http)) == 0);
|
||||
is_https = (strncmp(queue_item->artwork_url, proto_https, strlen(proto_https)) == 0);
|
||||
if (!is_http && !is_https)
|
||||
goto notfound;
|
||||
|
||||
ret = artwork_get_byurl(ctx->evbuf, queue_item->artwork_url, ctx->req_params);
|
||||
|
||||
snprintf(ctx->path, sizeof(ctx->path), "%s", queue_item->artwork_url);
|
||||
|
||||
free_queue_item(queue_item, 0);
|
||||
if (ctx->queue_item)
|
||||
{
|
||||
ret = source_queue_item_artwork_url_get(ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx->queue_item = db_queue_fetch_byfileid(ctx->id);
|
||||
ret = source_queue_item_artwork_url_get(ctx);
|
||||
free_queue_item(ctx->queue_item, 0);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
notfound:
|
||||
free_queue_item(queue_item, 0);
|
||||
return ART_E_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1852,6 +1858,41 @@ source_item_ownpl_get(struct artwork_ctx *ctx)
|
||||
return format;
|
||||
}
|
||||
|
||||
/*
|
||||
* Downloads artwork from ctx->queue_item->artwork_url
|
||||
*/
|
||||
static int
|
||||
source_queue_item_artwork_url_get(struct artwork_ctx *ctx)
|
||||
{
|
||||
const char *proto_http = "http:";
|
||||
const char *proto_https = "https:";
|
||||
const char *artwork_url;
|
||||
bool is_http;
|
||||
bool is_https;
|
||||
int ret;
|
||||
|
||||
if (!ctx->queue_item || !ctx->queue_item->artwork_url)
|
||||
goto notfound;
|
||||
|
||||
DPRINTF(E_SPAM, L_ART, "Trying artwork url for %s\n", ctx->queue_item->path);
|
||||
|
||||
artwork_url = ctx->queue_item->artwork_url;
|
||||
|
||||
is_http = (strncmp(artwork_url, proto_http, strlen(proto_http)) == 0);
|
||||
is_https = (strncmp(artwork_url, proto_https, strlen(proto_https)) == 0);
|
||||
if (!is_http && !is_https)
|
||||
goto notfound;
|
||||
|
||||
ret = artwork_get_byurl(ctx->evbuf, artwork_url, ctx->req_params);
|
||||
|
||||
snprintf(ctx->path, sizeof(ctx->path), "%s", artwork_url);
|
||||
|
||||
return ret;
|
||||
|
||||
notfound:
|
||||
return ART_E_NONE;
|
||||
}
|
||||
|
||||
|
||||
/* --------------------------- SOURCE PROCESSING --------------------------- */
|
||||
|
||||
@ -2003,13 +2044,52 @@ process_group(struct artwork_ctx *ctx)
|
||||
return process_items(ctx, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
process_queue_item(struct artwork_ctx *ctx)
|
||||
{
|
||||
const char *source_name;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
for (i = 0; artwork_queue_item_source[i].handler; i++)
|
||||
{
|
||||
// If just one handler says we should not cache a negative result then we obey that
|
||||
if ((artwork_queue_item_source[i].cache & ON_FAILURE) == 0)
|
||||
ctx->cache = NEVER;
|
||||
|
||||
source_name = artwork_queue_item_source[i].name;
|
||||
|
||||
DPRINTF(E_SPAM, L_ART, "Checking queue item source '%s'\n", source_name);
|
||||
|
||||
ret = artwork_queue_item_source[i].handler(ctx);
|
||||
if (ret > 0)
|
||||
{
|
||||
DPRINTF(E_DBG, L_ART, "Artwork for queue item '%s' found in source '%s'\n", ctx->queue_item->title, source_name);
|
||||
ctx->cache = artwork_queue_item_source[i].cache;
|
||||
return ret;
|
||||
}
|
||||
else if (ret == ART_E_ABORT)
|
||||
{
|
||||
DPRINTF(E_DBG, L_ART, "Source '%s' stopped search for artwork for queue item '%s'\n", source_name, ctx->queue_item->title);
|
||||
ctx->cache = NEVER;
|
||||
}
|
||||
else if (ret == ART_E_ERROR)
|
||||
{
|
||||
DPRINTF(E_LOG, L_ART, "Source '%s' returned an error for queue item '%s'\n", source_name, ctx->queue_item->title);
|
||||
ctx->cache = NEVER;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------ ARTWORK API ------------------------------ */
|
||||
|
||||
int
|
||||
artwork_get_item(struct evbuffer *evbuf, int id, int max_w, int max_h, int format)
|
||||
{
|
||||
struct artwork_ctx ctx;
|
||||
struct artwork_ctx ctx = { 0 };
|
||||
char filter[32];
|
||||
int ret;
|
||||
|
||||
@ -2018,8 +2098,6 @@ artwork_get_item(struct evbuffer *evbuf, int id, int max_w, int max_h, int forma
|
||||
if (id == DB_MEDIA_FILE_NON_PERSISTENT_ID)
|
||||
return -1;
|
||||
|
||||
memset(&ctx, 0, sizeof(struct artwork_ctx));
|
||||
|
||||
ctx.qp.type = Q_ITEMS;
|
||||
ctx.qp.filter = filter;
|
||||
ctx.evbuf = evbuf;
|
||||
@ -2070,13 +2148,11 @@ artwork_get_item(struct evbuffer *evbuf, int id, int max_w, int max_h, int forma
|
||||
int
|
||||
artwork_get_group(struct evbuffer *evbuf, int id, int max_w, int max_h, int format)
|
||||
{
|
||||
struct artwork_ctx ctx;
|
||||
struct artwork_ctx ctx = { 0 };
|
||||
int ret;
|
||||
|
||||
DPRINTF(E_DBG, L_ART, "Artwork request for group %d (max_w=%d, max_h=%d)\n", id, max_w, max_h);
|
||||
|
||||
memset(&ctx, 0, sizeof(struct artwork_ctx));
|
||||
|
||||
/* Get the persistent id for the given group id */
|
||||
ret = db_group_persistentid_byid(id, &ctx.persistentid);
|
||||
if (ret < 0)
|
||||
@ -2111,6 +2187,48 @@ artwork_get_group(struct evbuffer *evbuf, int id, int max_w, int max_h, int form
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
artwork_get_by_queue_item_id(struct evbuffer *evbuf, int item_id, int max_w, int max_h, int format)
|
||||
{
|
||||
struct artwork_ctx ctx = { 0 };
|
||||
struct db_queue_item *queue_item;
|
||||
int ret;
|
||||
|
||||
DPRINTF(E_DBG, L_ART, "Artwork request for queue item %d (max_w=%d, max_h=%d)\n", item_id, max_w, max_h);
|
||||
|
||||
queue_item = db_queue_fetch_byitemid(item_id);
|
||||
if (!queue_item)
|
||||
return -1;
|
||||
|
||||
if (queue_item->file_id != DB_MEDIA_FILE_NON_PERSISTENT_ID)
|
||||
{
|
||||
ret = artwork_get_item(evbuf, queue_item->file_id, max_w, max_h, format);
|
||||
free_queue_item(queue_item, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ctx.queue_item = queue_item;
|
||||
ctx.evbuf = evbuf;
|
||||
ctx.req_params.max_w = max_w;
|
||||
ctx.req_params.max_h = max_h;
|
||||
ctx.req_params.format = format;
|
||||
ctx.cache = ON_FAILURE;
|
||||
|
||||
ret = process_queue_item(&ctx);
|
||||
if (ret > 0)
|
||||
{
|
||||
// No caching of queue item artwork implemented as of yet
|
||||
free_queue_item(queue_item, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
DPRINTF(E_DBG, L_ART, "No artwork found for queue item %d\n", item_id);
|
||||
|
||||
free_queue_item(queue_item, 0);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Checks if the file is an artwork file */
|
||||
bool
|
||||
artwork_file_is_artwork(const char *filename)
|
||||
|
||||
@ -38,6 +38,20 @@ artwork_get_item(struct evbuffer *evbuf, int id, int max_w, int max_h, int forma
|
||||
int
|
||||
artwork_get_group(struct evbuffer *evbuf, int id, int max_w, int max_h, int format);
|
||||
|
||||
/*
|
||||
* Get the artwork image for a queue item. If the queue item is in the library,
|
||||
* this will return the same as artwork_get_by_file_id
|
||||
*
|
||||
* @out evbuf Event buffer that will contain the (scaled) image
|
||||
* @in item_id The queue item id
|
||||
* @in max_w Requested maximum image width (may not be obeyed)
|
||||
* @in max_h Requested maximum image height (may not be obeyed)
|
||||
* @in format Requested format (may not be obeyed), 0 for default
|
||||
* @return ART_FMT_* on success, -1 on error or no artwork found
|
||||
*/
|
||||
int
|
||||
artwork_get_by_queue_item_id(struct evbuffer *evbuf, int item_id, int max_w, int max_h, int format);
|
||||
|
||||
/*
|
||||
* Checks if the file is an artwork file (based on user config)
|
||||
*
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user