mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-11 23:13:24 -05:00
(basic) support for mpd commands 'find' and 'list'
This commit is contained in:
parent
911b982815
commit
7024f2f3e7
217
src/mpd.c
217
src/mpd.c
@ -1680,8 +1680,213 @@ mpd_command_load(struct evbuffer *evbuf, int argc, char **argv, char **errmsg)
|
||||
}
|
||||
|
||||
static int
|
||||
mpd_command_list()
|
||||
mpd_get_query_params_find(int argc, char **argv, struct query_params *qp)
|
||||
{
|
||||
char *c1;
|
||||
char *c2;
|
||||
int start_pos;
|
||||
int end_pos;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
c1 = NULL;
|
||||
c2 = NULL;
|
||||
|
||||
for (i = 0; i < argc; i += 2)
|
||||
{
|
||||
if (0 == strcasecmp(argv[i], "any"))
|
||||
{
|
||||
c1 = sqlite3_mprintf("(f.artist LIKE '%%%q%%' OR f.album LIKE '%%%q%%' OR f.title LIKE '%%%q%%')", argv[i + 1], argv[i + 1], argv[i + 1]);
|
||||
}
|
||||
else if (0 == strcasecmp(argv[i], "file"))
|
||||
{
|
||||
c1 = sqlite3_mprintf("(f.virtual_path = '/%q')", argv[i + 1]);
|
||||
}
|
||||
else if (0 == strcasecmp(argv[i], "base"))
|
||||
{
|
||||
c1 = sqlite3_mprintf("(f.virtual_path LIKE '/%q%%')", argv[i + 1]);
|
||||
}
|
||||
else if (0 == strcasecmp(argv[i], "modified-since"))
|
||||
{
|
||||
DPRINTF(E_WARN, L_MPD, "Special parameter 'modified-since' is not supported by forked-daapd and will be ignored\n");
|
||||
}
|
||||
else if (0 == strcasecmp(argv[i], "window"))
|
||||
{
|
||||
ret = mpd_pars_range_arg(argv[i + 1], &start_pos, &end_pos);
|
||||
if (ret == 0)
|
||||
{
|
||||
qp->idx_type = I_SUB;
|
||||
qp->limit = end_pos - start_pos;
|
||||
qp->offset = start_pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINTF(E_LOG, L_MPD, "Window argument doesn't convert to integer or range: '%s'\n", argv[i + 1]);
|
||||
}
|
||||
}
|
||||
else if (0 == strcasecmp(argv[i], "artist"))
|
||||
{
|
||||
c1 = sqlite3_mprintf("(f.artist = '%q')", argv[i + 1]);
|
||||
}
|
||||
else if (0 == strcasecmp(argv[i], "albumartist"))
|
||||
{
|
||||
c1 = sqlite3_mprintf("(f.album_artist = '%q')", argv[i + 1]);
|
||||
}
|
||||
else if (0 == strcasecmp(argv[i], "album"))
|
||||
{
|
||||
c1 = sqlite3_mprintf("(f.album = '%q')", argv[i + 1]);
|
||||
}
|
||||
else if (0 == strcasecmp(argv[i], "title"))
|
||||
{
|
||||
c1 = sqlite3_mprintf("(f.title = '%q')", argv[i + 1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINTF(E_WARN, L_MPD, "Parameter '%s' is not supported by forked-daapd and will be ignored\n", argv[i]);
|
||||
}
|
||||
|
||||
if (c1)
|
||||
{
|
||||
if (qp->filter)
|
||||
c2 = sqlite3_mprintf("%s AND %s", qp->filter, c1);
|
||||
else
|
||||
c2 = sqlite3_mprintf("%s", c1);
|
||||
|
||||
if (qp->filter)
|
||||
sqlite3_free(qp->filter);
|
||||
|
||||
qp->filter = c2;
|
||||
c2 = NULL;
|
||||
sqlite3_free(c1);
|
||||
c1 = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mpd_command_find(struct evbuffer *evbuf, int argc, char **argv, char **errmsg)
|
||||
{
|
||||
struct query_params qp;
|
||||
struct db_media_file_info dbmfi;
|
||||
int ret;
|
||||
|
||||
if (argc < 3 || ((argc - 1) % 2) != 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_MPD, "Missing argument(s) for command 'find'\n");
|
||||
ret = asprintf(errmsg, "Missing argument(s) for command 'find'");
|
||||
if (ret < 0)
|
||||
DPRINTF(E_LOG, L_MPD, "Out of memory\n");
|
||||
return ACK_ERROR_ARG;
|
||||
}
|
||||
|
||||
memset(&qp, 0, sizeof(struct query_params));
|
||||
|
||||
qp.type = Q_ITEMS;
|
||||
qp.sort = S_NAME;
|
||||
qp.idx_type = I_NONE;
|
||||
|
||||
mpd_get_query_params_find(argc - 1, argv + 1, &qp);
|
||||
|
||||
ret = db_query_start(&qp);
|
||||
if (ret < 0)
|
||||
{
|
||||
db_query_end(&qp);
|
||||
|
||||
DPRINTF(E_LOG, L_MPD, "Could not start query\n");
|
||||
ret = asprintf(errmsg, "Could not start query");
|
||||
if (ret < 0)
|
||||
DPRINTF(E_LOG, L_MPD, "Out of memory\n");
|
||||
return ACK_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
while (((ret = db_query_fetch_file(&qp, &dbmfi)) == 0) && (dbmfi.id))
|
||||
{
|
||||
ret = mpd_add_db_media_file_info(evbuf, &dbmfi);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_MPD, "Error adding song to the evbuffer, song id: %s\n", dbmfi.id);
|
||||
}
|
||||
}
|
||||
|
||||
db_query_end(&qp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mpd_command_findadd(struct evbuffer *evbuf, int argc, char **argv, char **errmsg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mpd_command_list(struct evbuffer *evbuf, int argc, char **argv, char **errmsg)
|
||||
{
|
||||
struct query_params qp;
|
||||
struct db_group_info dbgri;
|
||||
char *type;
|
||||
int ret;
|
||||
|
||||
if (argc < 2 || (argc % 2) != 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_MPD, "Missing argument(s) for command 'list'\n");
|
||||
ret = asprintf(errmsg, "Missing argument(s) for command 'list'");
|
||||
if (ret < 0)
|
||||
DPRINTF(E_LOG, L_MPD, "Out of memory\n");
|
||||
return ACK_ERROR_ARG;
|
||||
}
|
||||
|
||||
memset(&qp, 0, sizeof(struct query_params));
|
||||
|
||||
if (0 == strcasecmp(argv[1], "artist")
|
||||
|| 0 == strcasecmp(argv[1], "albumartist"))
|
||||
{
|
||||
qp.type = Q_GROUP_ARTISTS;
|
||||
qp.sort = S_ARTIST;
|
||||
type = "Artist: ";
|
||||
}
|
||||
else if (0 == strcasecmp(argv[1], "album"))
|
||||
{
|
||||
qp.type = Q_GROUP_ALBUMS;
|
||||
qp.sort = S_ALBUM;
|
||||
type = "Album: ";
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINTF(E_WARN, L_MPD, "Unsupported type argument for command 'list': %s\n", argv[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
qp.idx_type = I_NONE;
|
||||
|
||||
if (argc > 2)
|
||||
{
|
||||
mpd_get_query_params_find(argc - 2, argv + 2, &qp);
|
||||
}
|
||||
|
||||
ret = db_query_start(&qp);
|
||||
if (ret < 0)
|
||||
{
|
||||
db_query_end(&qp);
|
||||
|
||||
DPRINTF(E_LOG, L_MPD, "Could not start query\n");
|
||||
ret = asprintf(errmsg, "Could not start query");
|
||||
if (ret < 0)
|
||||
DPRINTF(E_LOG, L_MPD, "Out of memory\n");
|
||||
return ACK_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
while ((ret = db_query_fetch_group(&qp, &dbgri)) == 0)
|
||||
{
|
||||
evbuffer_add_printf(evbuf,
|
||||
"%s%s\n",
|
||||
type,
|
||||
dbgri.itemname);
|
||||
}
|
||||
|
||||
db_query_end(&qp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1781,7 +1986,7 @@ mpd_command_lsinfo(struct evbuffer *evbuf, int argc, char **argv, char **errmsg)
|
||||
}
|
||||
|
||||
static int
|
||||
mpd_get_query_params(int argc, char **argv, struct query_params *qp)
|
||||
mpd_get_query_params_search(int argc, char **argv, struct query_params *qp)
|
||||
{
|
||||
char *c1;
|
||||
char *c2;
|
||||
@ -1889,8 +2094,8 @@ mpd_command_search(struct evbuffer *evbuf, int argc, char **argv, char **errmsg)
|
||||
|
||||
if (argc < 3 || ((argc - 1) % 2) != 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_MPD, "Missing argument(s) for command 'update'\n");
|
||||
ret = asprintf(errmsg, "Missing argument(s) for command 'update'");
|
||||
DPRINTF(E_LOG, L_MPD, "Missing argument(s) for command 'search'\n");
|
||||
ret = asprintf(errmsg, "Missing argument(s) for command 'search'");
|
||||
if (ret < 0)
|
||||
DPRINTF(E_LOG, L_MPD, "Out of memory\n");
|
||||
return ACK_ERROR_ARG;
|
||||
@ -1902,7 +2107,7 @@ mpd_command_search(struct evbuffer *evbuf, int argc, char **argv, char **errmsg)
|
||||
qp.sort = S_NAME;
|
||||
qp.idx_type = I_NONE;
|
||||
|
||||
mpd_get_query_params(argc - 1, argv + 1, &qp);
|
||||
mpd_get_query_params_search(argc - 1, argv + 1, &qp);
|
||||
|
||||
ret = db_query_start(&qp);
|
||||
if (ret < 0)
|
||||
@ -2321,6 +2526,7 @@ static struct command mpd_handlers[] =
|
||||
.mpdcommand = "count",
|
||||
.handler = mpd_command_count
|
||||
},
|
||||
*/
|
||||
{
|
||||
.mpdcommand = "find",
|
||||
.handler = mpd_command_find
|
||||
@ -2329,7 +2535,6 @@ static struct command mpd_handlers[] =
|
||||
.mpdcommand = "findadd",
|
||||
.handler = mpd_command_findadd
|
||||
},
|
||||
*/
|
||||
{
|
||||
.mpdcommand = "list",
|
||||
.handler = mpd_command_list
|
||||
|
Loading…
Reference in New Issue
Block a user