mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-26 22:23:17 -05:00
Add support for artist group request (experimental)
The purpose of this is mainly to support Hyperfine Remote for Android
This commit is contained in:
parent
799fe9e684
commit
95fc525beb
@ -41,7 +41,7 @@ QUOTE : '\'';
|
|||||||
LPAR : '(';
|
LPAR : '(';
|
||||||
RPAR : ')';
|
RPAR : ')';
|
||||||
|
|
||||||
OPAND : '+';
|
OPAND : '+' | ' ';
|
||||||
OPOR : ',';
|
OPOR : ',';
|
||||||
|
|
||||||
NEWLINE : '\r'? '\n';
|
NEWLINE : '\r'? '\n';
|
||||||
|
@ -879,13 +879,13 @@ artwork_get_group(int id, int max_w, int max_h, int format, struct evbuffer *evb
|
|||||||
files_art:
|
files_art:
|
||||||
memset(&qp, 0, sizeof(struct query_params));
|
memset(&qp, 0, sizeof(struct query_params));
|
||||||
|
|
||||||
qp.type = Q_GROUPITEMS;
|
qp.type = Q_GROUP_ITEMS;
|
||||||
qp.id = id;
|
qp.id = id;
|
||||||
|
|
||||||
ret = db_query_start(&qp);
|
ret = db_query_start(&qp);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_ART, "Could not start Q_GROUPITEMS query\n");
|
DPRINTF(E_LOG, L_ART, "Could not start Q_GROUP_ITEMS query\n");
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -899,7 +899,7 @@ artwork_get_group(int id, int max_w, int max_h, int format, struct evbuffer *evb
|
|||||||
db_query_end(&qp);
|
db_query_end(&qp);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
DPRINTF(E_LOG, L_ART, "Error fetching Q_GROUPITEMS results\n");
|
DPRINTF(E_LOG, L_ART, "Error fetching Q_GROUP_ITEMS results\n");
|
||||||
else if (got_art > 0)
|
else if (got_art > 0)
|
||||||
return got_art;
|
return got_art;
|
||||||
|
|
||||||
|
67
src/db.c
67
src/db.c
@ -232,12 +232,13 @@ static const ssize_t dbpli_cols_map[] =
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* This list must be kept in sync with
|
/* This list must be kept in sync with
|
||||||
* - the order of fields in the Q_GROUPS query
|
* - the order of fields in the Q_GROUP_ALBUMS and Q_GROUP_ARTISTS query
|
||||||
* - the name of the fields in struct group_info
|
* - the name of the fields in struct group_info
|
||||||
*/
|
*/
|
||||||
static const ssize_t dbgri_cols_map[] =
|
static const ssize_t dbgri_cols_map[] =
|
||||||
{
|
{
|
||||||
dbgri_offsetof(itemcount),
|
dbgri_offsetof(itemcount),
|
||||||
|
dbgri_offsetof(groupalbumcount),
|
||||||
dbgri_offsetof(id),
|
dbgri_offsetof(id),
|
||||||
dbgri_offsetof(persistentid),
|
dbgri_offsetof(persistentid),
|
||||||
dbgri_offsetof(songalbumartist),
|
dbgri_offsetof(songalbumartist),
|
||||||
@ -967,7 +968,7 @@ db_build_query_plitems(struct query_params *qp, char **q)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
db_build_query_groups(struct query_params *qp, char **q)
|
db_build_query_group_albums(struct query_params *qp, char **q)
|
||||||
{
|
{
|
||||||
char *query;
|
char *query;
|
||||||
char *idx;
|
char *idx;
|
||||||
@ -983,13 +984,13 @@ db_build_query_groups(struct query_params *qp, char **q)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (idx && qp->filter)
|
if (idx && qp->filter)
|
||||||
query = sqlite3_mprintf("SELECT COUNT(*), g.id, g.persistentid, f.album_artist, g.name FROM files f, groups g WHERE f.songalbumid = g.persistentid AND g.type = %d AND f.disabled = 0 AND %s GROUP BY f.album, g.name %s;", G_ALBUMS, qp->filter, idx);
|
query = sqlite3_mprintf("SELECT COUNT(*), 1, g.id, g.persistentid, f.album_artist, g.name FROM files f, groups g WHERE f.songalbumid = g.persistentid AND g.type = %d AND f.disabled = 0 AND %s GROUP BY f.album, g.name %s;", G_ALBUMS, qp->filter, idx);
|
||||||
else if (idx)
|
else if (idx)
|
||||||
query = sqlite3_mprintf("SELECT COUNT(*), g.id, g.persistentid, f.album_artist, g.name FROM files f, groups g WHERE f.songalbumid = g.persistentid AND g.type = %d AND f.disabled = 0 GROUP BY f.album, g.name %s;", G_ALBUMS, idx);
|
query = sqlite3_mprintf("SELECT COUNT(*), 1, g.id, g.persistentid, f.album_artist, g.name FROM files f, groups g WHERE f.songalbumid = g.persistentid AND g.type = %d AND f.disabled = 0 GROUP BY f.album, g.name %s;", G_ALBUMS, idx);
|
||||||
else if (qp->filter)
|
else if (qp->filter)
|
||||||
query = sqlite3_mprintf("SELECT COUNT(*), g.id, g.persistentid, f.album_artist, g.name FROM files f, groups g WHERE f.songalbumid = g.persistentid AND g.type = %d AND f.disabled = 0 AND %s GROUP BY f.album, g.name;", G_ALBUMS, qp->filter);
|
query = sqlite3_mprintf("SELECT COUNT(*), 1, g.id, g.persistentid, f.album_artist, g.name FROM files f, groups g WHERE f.songalbumid = g.persistentid AND g.type = %d AND f.disabled = 0 AND %s GROUP BY f.album, g.name;", G_ALBUMS, qp->filter);
|
||||||
else
|
else
|
||||||
query = sqlite3_mprintf("SELECT COUNT(*), g.id, g.persistentid, f.album_artist, g.name FROM files f, groups g WHERE f.songalbumid = g.persistentid AND g.type = %d AND f.disabled = 0 GROUP BY f.album, g.name;", G_ALBUMS);
|
query = sqlite3_mprintf("SELECT COUNT(*), 1, g.id, g.persistentid, f.album_artist, g.name FROM files f, groups g WHERE f.songalbumid = g.persistentid AND g.type = %d AND f.disabled = 0 GROUP BY f.album, g.name;", G_ALBUMS);
|
||||||
|
|
||||||
if (!query)
|
if (!query)
|
||||||
{
|
{
|
||||||
@ -1003,7 +1004,43 @@ db_build_query_groups(struct query_params *qp, char **q)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
db_build_query_groupitems(struct query_params *qp, char **q)
|
db_build_query_group_artists(struct query_params *qp, char **q)
|
||||||
|
{
|
||||||
|
char *query;
|
||||||
|
char *idx;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
qp->results = db_get_count("SELECT COUNT(DISTINCT f.album_artist) FROM files f WHERE f.disabled = 0;");
|
||||||
|
if (qp->results < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Get index clause */
|
||||||
|
ret = db_build_query_index_clause(qp, &idx);
|
||||||
|
if (ret < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (idx && qp->filter)
|
||||||
|
query = sqlite3_mprintf("SELECT COUNT(*), COUNT(DISTINCT f.album), 1, 1, f.album_artist, f.album_artist FROM files f WHERE f.disabled = 0 AND %s GROUP BY f.album_artist %s;", qp->filter, idx);
|
||||||
|
else if (idx)
|
||||||
|
query = sqlite3_mprintf("SELECT COUNT(*), COUNT(DISTINCT f.album), 1, 1, f.album_artist, f.album_artist FROM files f WHERE f.disabled = 0 GROUP BY f.album_artist %s;", idx);
|
||||||
|
else if (qp->filter)
|
||||||
|
query = sqlite3_mprintf("SELECT COUNT(*), COUNT(DISTINCT f.album), 1, 1, f.album_artist, f.album_artist FROM files f WHERE f.disabled = 0 AND %s GROUP BY f.album_artist;", qp->filter);
|
||||||
|
else
|
||||||
|
query = sqlite3_mprintf("SELECT COUNT(*), COUNT(DISTINCT f.album), 1, 1, f.album_artist, f.album_artist FROM files f WHERE f.disabled = 0 GROUP BY f.album_artist;");
|
||||||
|
|
||||||
|
if (!query)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_DB, "Out of memory for query string\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*q = query;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
db_build_query_group_items(struct query_params *qp, char **q)
|
||||||
{
|
{
|
||||||
char *query;
|
char *query;
|
||||||
char *count;
|
char *count;
|
||||||
@ -1189,12 +1226,16 @@ db_query_start(struct query_params *qp)
|
|||||||
ret = db_build_query_plitems(qp, &query);
|
ret = db_build_query_plitems(qp, &query);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Q_GROUPS:
|
case Q_GROUP_ALBUMS:
|
||||||
ret = db_build_query_groups(qp, &query);
|
ret = db_build_query_group_albums(qp, &query);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Q_GROUPITEMS:
|
case Q_GROUP_ARTISTS:
|
||||||
ret = db_build_query_groupitems(qp, &query);
|
ret = db_build_query_group_artists(qp, &query);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Q_GROUP_ITEMS:
|
||||||
|
ret = db_build_query_group_items(qp, &query);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Q_GROUP_DIRS:
|
case Q_GROUP_DIRS:
|
||||||
@ -1269,7 +1310,7 @@ db_query_fetch_file(struct query_params *qp, struct db_media_file_info *dbmfi)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((qp->type != Q_ITEMS) && (qp->type != Q_PLITEMS) && (qp->type != Q_GROUPITEMS))
|
if ((qp->type != Q_ITEMS) && (qp->type != Q_PLITEMS) && (qp->type != Q_GROUP_ITEMS))
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_DB, "Not an items, playlist or group items query!\n");
|
DPRINTF(E_LOG, L_DB, "Not an items, playlist or group items query!\n");
|
||||||
return -1;
|
return -1;
|
||||||
@ -1405,7 +1446,7 @@ db_query_fetch_group(struct query_params *qp, struct db_group_info *dbgri)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qp->type != Q_GROUPS)
|
if ((qp->type != Q_GROUP_ALBUMS) && (qp->type != Q_GROUP_ARTISTS))
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_DB, "Not a groups query!\n");
|
DPRINTF(E_LOG, L_DB, "Not a groups query!\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
8
src/db.h
8
src/db.h
@ -33,9 +33,10 @@ enum query_type {
|
|||||||
Q_BROWSE_ALBUMS = Q_F_BROWSE | (1 << 4),
|
Q_BROWSE_ALBUMS = Q_F_BROWSE | (1 << 4),
|
||||||
Q_BROWSE_GENRES = Q_F_BROWSE | (1 << 5),
|
Q_BROWSE_GENRES = Q_F_BROWSE | (1 << 5),
|
||||||
Q_BROWSE_COMPOSERS = Q_F_BROWSE | (1 << 6),
|
Q_BROWSE_COMPOSERS = Q_F_BROWSE | (1 << 6),
|
||||||
Q_GROUPS = (1 << 7),
|
Q_GROUP_ALBUMS = (1 << 7),
|
||||||
Q_GROUPITEMS = (1 << 8),
|
Q_GROUP_ARTISTS = (1 << 8),
|
||||||
Q_GROUP_DIRS = Q_F_BROWSE | (1 << 9),
|
Q_GROUP_ITEMS = (1 << 9),
|
||||||
|
Q_GROUP_DIRS = Q_F_BROWSE | (1 << 10),
|
||||||
};
|
};
|
||||||
|
|
||||||
struct query_params {
|
struct query_params {
|
||||||
@ -190,6 +191,7 @@ struct db_group_info {
|
|||||||
char *persistentid;
|
char *persistentid;
|
||||||
char *itemname;
|
char *itemname;
|
||||||
char *itemcount;
|
char *itemcount;
|
||||||
|
char *groupalbumcount;
|
||||||
char *songalbumartist;
|
char *songalbumartist;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -101,6 +101,7 @@ const struct dmap_field_map dfm_dmap_aeSP = { -1,
|
|||||||
static const struct dmap_field_map dfm_dmap_aePS = { -1, -1, -1 };
|
static const struct dmap_field_map dfm_dmap_aePS = { -1, -1, -1 };
|
||||||
static const struct dmap_field_map dfm_dmap_ascd = { dbmfi_offsetof(codectype), -1, -1 };
|
static const struct dmap_field_map dfm_dmap_ascd = { dbmfi_offsetof(codectype), -1, -1 };
|
||||||
static const struct dmap_field_map dfm_dmap_ascs = { -1, -1, -1 };
|
static const struct dmap_field_map dfm_dmap_ascs = { -1, -1, -1 };
|
||||||
|
static const struct dmap_field_map dfm_dmap_agac = { -1, -1, dbgri_offsetof(groupalbumcount) };
|
||||||
static const struct dmap_field_map dfm_dmap_agrp = { dbmfi_offsetof(grouping), -1, -1 };
|
static const struct dmap_field_map dfm_dmap_agrp = { dbmfi_offsetof(grouping), -1, -1 };
|
||||||
static const struct dmap_field_map dfm_dmap_aeSV = { -1, -1, -1 };
|
static const struct dmap_field_map dfm_dmap_aeSV = { -1, -1, -1 };
|
||||||
static const struct dmap_field_map dfm_dmap_aePI = { -1, -1, -1 };
|
static const struct dmap_field_map dfm_dmap_aePI = { -1, -1, -1 };
|
||||||
@ -162,6 +163,7 @@ struct dmap_field;
|
|||||||
"com.apple.itunes.smart-playlist", "aeSP", &dfm_dmap_aeSP, DMAP_TYPE_UBYTE
|
"com.apple.itunes.smart-playlist", "aeSP", &dfm_dmap_aeSP, DMAP_TYPE_UBYTE
|
||||||
"com.apple.itunes.season-num", "aeSU", &dfm_dmap_aeSU, DMAP_TYPE_UINT
|
"com.apple.itunes.season-num", "aeSU", &dfm_dmap_aeSU, DMAP_TYPE_UINT
|
||||||
"com.apple.itunes.music-sharing-version", "aeSV", &dfm_dmap_aeSV, DMAP_TYPE_UINT
|
"com.apple.itunes.music-sharing-version", "aeSV", &dfm_dmap_aeSV, DMAP_TYPE_UINT
|
||||||
|
"daap.groupalbumcount", "agac", &dfm_dmap_agac, DMAP_TYPE_UINT
|
||||||
"daap.songgrouping", "agrp", &dfm_dmap_agrp, DMAP_TYPE_STRING
|
"daap.songgrouping", "agrp", &dfm_dmap_agrp, DMAP_TYPE_STRING
|
||||||
"daap.databaseplaylists", "aply", &dfm_dmap_aply, DMAP_TYPE_LIST
|
"daap.databaseplaylists", "aply", &dfm_dmap_aply, DMAP_TYPE_LIST
|
||||||
"daap.playlistrepeatmode", "aprm", &dfm_dmap_aprm, DMAP_TYPE_UBYTE
|
"daap.playlistrepeatmode", "aprm", &dfm_dmap_aprm, DMAP_TYPE_UBYTE
|
||||||
|
@ -1515,6 +1515,7 @@ daap_reply_groups(struct evhttp_request *req, struct evbuffer *evbuf, char **uri
|
|||||||
struct sort_ctx *sctx;
|
struct sort_ctx *sctx;
|
||||||
const char *param;
|
const char *param;
|
||||||
char **strval;
|
char **strval;
|
||||||
|
int group_type;
|
||||||
int nmeta;
|
int nmeta;
|
||||||
int sort_headers;
|
int sort_headers;
|
||||||
int ngrp;
|
int ngrp;
|
||||||
@ -1527,8 +1528,17 @@ daap_reply_groups(struct evhttp_request *req, struct evbuffer *evbuf, char **uri
|
|||||||
if (!s)
|
if (!s)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* For now we only support album groups */
|
param = evhttp_find_header(query, "group-type");
|
||||||
tag = "agal";
|
if (strcmp(param, "artists") == 0)
|
||||||
|
{
|
||||||
|
tag = "agar";
|
||||||
|
group_type = Q_GROUP_ARTISTS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tag = "agal";
|
||||||
|
group_type = Q_GROUP_ALBUMS;
|
||||||
|
}
|
||||||
|
|
||||||
ret = evbuffer_expand(evbuf, 61);
|
ret = evbuffer_expand(evbuf, 61);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -1595,7 +1605,7 @@ daap_reply_groups(struct evhttp_request *req, struct evbuffer *evbuf, char **uri
|
|||||||
|
|
||||||
memset(&qp, 0, sizeof(struct query_params));
|
memset(&qp, 0, sizeof(struct query_params));
|
||||||
get_query_params(query, &sort_headers, &qp);
|
get_query_params(query, &sort_headers, &qp);
|
||||||
qp.type = Q_GROUPS;
|
qp.type = group_type;
|
||||||
|
|
||||||
sctx = NULL;
|
sctx = NULL;
|
||||||
if (sort_headers)
|
if (sort_headers)
|
||||||
@ -1669,8 +1679,9 @@ daap_reply_groups(struct evhttp_request *req, struct evbuffer *evbuf, char **uri
|
|||||||
if ((ret == 0) && (val > 0))
|
if ((ret == 0) && (val > 0))
|
||||||
dmap_add_int(group, "mimc", val);
|
dmap_add_int(group, "mimc", val);
|
||||||
|
|
||||||
/* Song album artist, always added (asaa) */
|
/* Song album artist (asaa), always added if group-type is albums */
|
||||||
dmap_add_string(group, "asaa", dbgri.songalbumartist);
|
if (group_type == Q_GROUP_ALBUMS)
|
||||||
|
dmap_add_string(group, "asaa", dbgri.songalbumartist);
|
||||||
|
|
||||||
/* Item id (miid) */
|
/* Item id (miid) */
|
||||||
val = 0;
|
val = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user