mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-27 06:33:21 -05:00
[mpd] add support for commands 'listall' and 'listallinfo'
This commit is contained in:
parent
7703a997c4
commit
2611d06ab7
293
src/mpd.c
293
src/mpd.c
@ -2685,6 +2685,210 @@ mpd_command_list(struct evbuffer *evbuf, int argc, char **argv, char **errmsg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mpd_add_directory(struct evbuffer *evbuf, int directory_id, int listall, int listinfo, char **errmsg)
|
||||
{
|
||||
struct directory_info subdir;
|
||||
struct query_params qp;
|
||||
struct directory_enum dir_enum;
|
||||
struct db_playlist_info dbpli;
|
||||
char modified[32];
|
||||
uint32_t time_modified;
|
||||
struct db_media_file_info dbmfi;
|
||||
int ret;
|
||||
|
||||
// Load playlists for dir-id
|
||||
memset(&qp, 0, sizeof(struct query_params));
|
||||
qp.type = Q_PL;
|
||||
qp.sort = S_PLAYLIST;
|
||||
qp.idx_type = I_NONE;
|
||||
qp.filter = sqlite3_mprintf("(directory_id = %d AND (f.type = %d OR f.type = %d))", directory_id, PL_PLAIN, PL_SMART);
|
||||
ret = db_query_start(&qp);
|
||||
if (ret < 0)
|
||||
{
|
||||
db_query_end(&qp);
|
||||
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_pl(&qp, &dbpli)) == 0) && (dbpli.id))
|
||||
{
|
||||
if (safe_atou32(dbpli.db_timestamp, &time_modified) != 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_MPD, "Error converting time modified to uint32_t: %s\n", dbpli.db_timestamp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (listinfo)
|
||||
{
|
||||
mpd_time(modified, sizeof(modified), time_modified);
|
||||
evbuffer_add_printf(evbuf,
|
||||
"playlist: %s\n"
|
||||
"Last-Modified: %s\n",
|
||||
(dbpli.virtual_path + 1),
|
||||
modified);
|
||||
}
|
||||
else
|
||||
{
|
||||
evbuffer_add_printf(evbuf,
|
||||
"playlist: %s\n",
|
||||
(dbpli.virtual_path + 1));
|
||||
}
|
||||
}
|
||||
db_query_end(&qp);
|
||||
sqlite3_free(qp.filter);
|
||||
|
||||
// Load sub directories for dir-id
|
||||
memset(&dir_enum, 0, sizeof(struct directory_enum));
|
||||
dir_enum.parent_id = directory_id;
|
||||
ret = db_directory_enum_start(&dir_enum);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_MPD, "Failed to start directory enum for parent_id %d\n", directory_id);
|
||||
return -1;
|
||||
}
|
||||
while ((ret = db_directory_enum_fetch(&dir_enum, &subdir)) == 0 && subdir.id > 0)
|
||||
{
|
||||
if (listinfo)
|
||||
{
|
||||
evbuffer_add_printf(evbuf,
|
||||
"directory: %s\n"
|
||||
"Last-Modified: %s\n",
|
||||
(subdir.virtual_path + 1),
|
||||
"2015-12-01 00:00");
|
||||
}
|
||||
else
|
||||
{
|
||||
evbuffer_add_printf(evbuf,
|
||||
"directory: %s\n",
|
||||
(subdir.virtual_path + 1));
|
||||
}
|
||||
|
||||
if (listall)
|
||||
{
|
||||
mpd_add_directory(evbuf, subdir.id, listall, listinfo, errmsg);
|
||||
}
|
||||
}
|
||||
db_directory_enum_end(&dir_enum);
|
||||
|
||||
// Load files for dir-id
|
||||
memset(&qp, 0, sizeof(struct query_params));
|
||||
qp.type = Q_ITEMS;
|
||||
qp.sort = S_ARTIST;
|
||||
qp.idx_type = I_NONE;
|
||||
qp.filter = sqlite3_mprintf("(directory_id = %d)", directory_id);
|
||||
ret = db_query_start(&qp);
|
||||
if (ret < 0)
|
||||
{
|
||||
db_query_end(&qp);
|
||||
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))
|
||||
{
|
||||
if (listinfo)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
evbuffer_add_printf(evbuf,
|
||||
"file: %s\n",
|
||||
(dbmfi.virtual_path + 1));
|
||||
}
|
||||
}
|
||||
db_query_end(&qp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mpd_command_listall(struct evbuffer *evbuf, int argc, char **argv, char **errmsg)
|
||||
{
|
||||
int dir_id;
|
||||
char parent[PATH_MAX];
|
||||
int ret;
|
||||
|
||||
if (argc < 2 || strlen(argv[1]) == 0
|
||||
|| (strncmp(argv[1], "/", 1) == 0 && strlen(argv[1]) == 1))
|
||||
{
|
||||
ret = snprintf(parent, sizeof(parent), "/");
|
||||
}
|
||||
else if (strncmp(argv[1], "/", 1) == 0)
|
||||
{
|
||||
ret = snprintf(parent, sizeof(parent), "%s/", argv[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = snprintf(parent, sizeof(parent), "/%s", argv[1]);
|
||||
}
|
||||
|
||||
if ((ret < 0) || (ret >= sizeof(parent)))
|
||||
{
|
||||
DPRINTF(E_INFO, L_MPD, "Parent path exceeds PATH_MAX\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Load dir-id from db for parent-path
|
||||
dir_id = db_directory_id_byvirtualpath(parent);
|
||||
if (dir_id == 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_MPD, "Directory info not found for virtual-path '%s'\n", parent);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = mpd_add_directory(evbuf, dir_id, 1, 0, errmsg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
mpd_command_listallinfo(struct evbuffer *evbuf, int argc, char **argv, char **errmsg)
|
||||
{
|
||||
int dir_id;
|
||||
char parent[PATH_MAX];
|
||||
int ret;
|
||||
|
||||
if (argc < 2 || strlen(argv[1]) == 0
|
||||
|| (strncmp(argv[1], "/", 1) == 0 && strlen(argv[1]) == 1))
|
||||
{
|
||||
ret = snprintf(parent, sizeof(parent), "/");
|
||||
}
|
||||
else if (strncmp(argv[1], "/", 1) == 0)
|
||||
{
|
||||
ret = snprintf(parent, sizeof(parent), "%s/", argv[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = snprintf(parent, sizeof(parent), "/%s", argv[1]);
|
||||
}
|
||||
|
||||
if ((ret < 0) || (ret >= sizeof(parent)))
|
||||
{
|
||||
DPRINTF(E_INFO, L_MPD, "Parent path exceeds PATH_MAX\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Load dir-id from db for parent-path
|
||||
dir_id = db_directory_id_byvirtualpath(parent);
|
||||
if (dir_id == 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_MPD, "Directory info not found for virtual-path '%s'\n", parent);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = mpd_add_directory(evbuf, dir_id, 1, 1, errmsg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Command handler function for 'lsinfo'
|
||||
* Lists the contents of the directory given in argv[1].
|
||||
@ -2693,15 +2897,8 @@ static int
|
||||
mpd_command_lsinfo(struct evbuffer *evbuf, int argc, char **argv, char **errmsg)
|
||||
{
|
||||
int dir_id;
|
||||
struct directory_info subdir;
|
||||
struct query_params qp;
|
||||
struct directory_enum dir_enum;
|
||||
char parent[PATH_MAX];
|
||||
int print_playlists;
|
||||
struct db_playlist_info dbpli;
|
||||
char modified[32];
|
||||
uint32_t time_modified;
|
||||
struct db_media_file_info dbmfi;
|
||||
int ret;
|
||||
|
||||
if (argc < 2 || strlen(argv[1]) == 0
|
||||
@ -2744,89 +2941,15 @@ mpd_command_lsinfo(struct evbuffer *evbuf, int argc, char **argv, char **errmsg)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Load playlists for dir-id
|
||||
memset(&qp, 0, sizeof(struct query_params));
|
||||
qp.type = Q_PL;
|
||||
qp.sort = S_PLAYLIST;
|
||||
qp.idx_type = I_NONE;
|
||||
qp.filter = sqlite3_mprintf("(directory_id = %d AND (f.type = %d OR f.type = %d))", dir_id, PL_PLAIN, PL_SMART);
|
||||
ret = db_query_start(&qp);
|
||||
if (ret < 0)
|
||||
{
|
||||
db_query_end(&qp);
|
||||
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_pl(&qp, &dbpli)) == 0) && (dbpli.id))
|
||||
{
|
||||
if (safe_atou32(dbpli.db_timestamp, &time_modified) != 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_MPD, "Error converting time modified to uint32_t: %s\n", dbpli.db_timestamp);
|
||||
return -1;
|
||||
}
|
||||
mpd_time(modified, sizeof(modified), time_modified);
|
||||
evbuffer_add_printf(evbuf,
|
||||
"playlist: %s\n"
|
||||
"Last-Modified: %s\n",
|
||||
(dbpli.virtual_path + 1),
|
||||
modified);
|
||||
}
|
||||
db_query_end(&qp);
|
||||
sqlite3_free(qp.filter);
|
||||
|
||||
// Load sub directories for dir-id
|
||||
memset(&dir_enum, 0, sizeof(struct directory_enum));
|
||||
dir_enum.parent_id = dir_id;
|
||||
ret = db_directory_enum_start(&dir_enum);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_MPD, "Failed to start directory enum for parent_id %d\n", dir_id);
|
||||
return -1;
|
||||
}
|
||||
while ((ret = db_directory_enum_fetch(&dir_enum, &subdir)) == 0 && subdir.id > 0)
|
||||
{
|
||||
evbuffer_add_printf(evbuf,
|
||||
"directory: %s\n"
|
||||
"Last-Modified: %s\n",
|
||||
(subdir.virtual_path + 1),
|
||||
"2015-12-01 00:00");
|
||||
}
|
||||
db_directory_enum_end(&dir_enum);
|
||||
|
||||
// Load files for dir-id
|
||||
memset(&qp, 0, sizeof(struct query_params));
|
||||
qp.type = Q_ITEMS;
|
||||
qp.sort = S_ARTIST;
|
||||
qp.idx_type = I_NONE;
|
||||
qp.filter = sqlite3_mprintf("(directory_id = %d)", dir_id);
|
||||
ret = db_query_start(&qp);
|
||||
if (ret < 0)
|
||||
{
|
||||
db_query_end(&qp);
|
||||
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);
|
||||
ret = mpd_add_directory(evbuf, dir_id, 0, 1, errmsg);
|
||||
|
||||
// If the root directory was passed as argument add the stored playlists to the response
|
||||
if (print_playlists)
|
||||
if (ret == 0 && print_playlists)
|
||||
{
|
||||
return mpd_command_listplaylists(evbuf, argc, argv, errmsg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -3808,7 +3931,6 @@ static struct command mpd_handlers[] =
|
||||
.mpdcommand = "list",
|
||||
.handler = mpd_command_list
|
||||
},
|
||||
/*
|
||||
{
|
||||
.mpdcommand = "listall",
|
||||
.handler = mpd_command_listall
|
||||
@ -3817,6 +3939,7 @@ static struct command mpd_handlers[] =
|
||||
.mpdcommand = "listallinfo",
|
||||
.handler = mpd_command_listallinfo
|
||||
},
|
||||
/*
|
||||
{
|
||||
.mpdcommand = "listfiles",
|
||||
.handler = mpd_command_listfiles
|
||||
|
Loading…
x
Reference in New Issue
Block a user