Add mpd command "playlistid"; add dummy implementation for mpd command
"idle"
This commit is contained in:
parent
ad23c0ff30
commit
aa0abc1664
185
src/mpd.c
185
src/mpd.c
|
@ -349,6 +349,33 @@ mpd_add_mediainfo(struct evbuffer *evbuf, struct media_file_info *mfi, int pos_p
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mpd_add_mediainfo_byid(struct evbuffer *evbuf, int id, int pos_pl)
|
||||||
|
{
|
||||||
|
struct media_file_info *mfi;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
mfi = db_file_fetch_byid(id);
|
||||||
|
if (!mfi)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_MPD, "Error fetching file by id: %d\n", id);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = mpd_add_mediainfo(evbuf, mfi, pos_pl);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_MPD, "Error adding media info for file with id: %d\n", id);
|
||||||
|
|
||||||
|
free_mfi(mfi, 0);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
free_mfi(mfi, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Adds the informations (path, id, tags, etc.) for the given song to the given buffer.
|
* Adds the informations (path, id, tags, etc.) for the given song to the given buffer.
|
||||||
*
|
*
|
||||||
|
@ -413,7 +440,6 @@ mpd_command_currentsong(struct evbuffer *evbuf, int argc, char **argv, char **er
|
||||||
{
|
{
|
||||||
|
|
||||||
struct player_status status;
|
struct player_status status;
|
||||||
struct media_file_info *mfi;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
player_get_status(&status);
|
player_get_status(&status);
|
||||||
|
@ -424,17 +450,7 @@ mpd_command_currentsong(struct evbuffer *evbuf, int argc, char **argv, char **er
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
mfi = db_file_fetch_byid(status.id);
|
ret = mpd_add_mediainfo_byid(evbuf, status.id, status.pos_pl);
|
||||||
if (!mfi)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_MPD, "Error fetching file by id: %d\n", status.id);
|
|
||||||
ret = asprintf(errmsg, "Error fetching file by id: %d", status.id);
|
|
||||||
if (ret < 0)
|
|
||||||
DPRINTF(E_LOG, L_MPD, "Out of memory\n");
|
|
||||||
return ACK_ERROR_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = mpd_add_mediainfo(evbuf, mfi, status.pos_pl);
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_MPD, "Error adding media info for file with id: %d\n", status.id);
|
DPRINTF(E_LOG, L_MPD, "Error adding media info for file with id: %d\n", status.id);
|
||||||
|
@ -442,11 +458,27 @@ mpd_command_currentsong(struct evbuffer *evbuf, int argc, char **argv, char **er
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
DPRINTF(E_LOG, L_MPD, "Out of memory\n");
|
DPRINTF(E_LOG, L_MPD, "Out of memory\n");
|
||||||
|
|
||||||
free_mfi(mfi, 0);
|
|
||||||
return ACK_ERROR_UNKNOWN;
|
return ACK_ERROR_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
free_mfi(mfi, 0);
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Example input:
|
||||||
|
* idle "database" "mixer" "options" "output" "player" "playlist" "sticker" "update"
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
mpd_command_idle(struct evbuffer *evbuf, int argc, char **argv, char **errmsg)
|
||||||
|
{
|
||||||
|
DPRINTF(E_WARN, L_MPD, "Idle command is not supported by forked-daapd, there will be no notifications about changes\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mpd_command_noidle(struct evbuffer *evbuf, int argc, char **argv, char **errmsg)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1447,6 +1479,67 @@ mpd_command_deleteid(struct evbuffer *evbuf, int argc, char **argv, char **errms
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mpd_command_playlistid(struct evbuffer *evbuf, int argc, char **argv, char **errmsg)
|
||||||
|
{
|
||||||
|
struct player_queue *queue;
|
||||||
|
uint32_t songid;
|
||||||
|
int pos_pl;
|
||||||
|
int i;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
songid = 0;
|
||||||
|
|
||||||
|
if (argc > 1)
|
||||||
|
{
|
||||||
|
ret = safe_atou32(argv[1], &songid);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_MPD, "Argument doesn't convert to integer: '%s'\n", argv[1]);
|
||||||
|
ret = asprintf(errmsg, "Argument doesn't convert to integer: '%s'", argv[1]);
|
||||||
|
if (ret < 0)
|
||||||
|
DPRINTF(E_LOG, L_MPD, "Out of memory\n");
|
||||||
|
return ACK_ERROR_ARG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the whole queue (start_pos = 0, end_pos = -1)
|
||||||
|
queue = player_queue_get(0, -1, 0);
|
||||||
|
|
||||||
|
if (!queue)
|
||||||
|
{
|
||||||
|
// Queue is emtpy
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos_pl = queue->start_pos;
|
||||||
|
for (i = 0; i < queue->count; i++)
|
||||||
|
{
|
||||||
|
if (songid == 0 || songid == queue->queue[i])
|
||||||
|
{
|
||||||
|
ret = mpd_add_mediainfo_byid(evbuf, queue->queue[i], pos_pl);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_MPD, "Error adding media info for file with id: %d\n", queue->queue[i]);
|
||||||
|
ret = asprintf(errmsg, "Error adding media info for file with id: %d\n", queue->queue[i]);
|
||||||
|
|
||||||
|
queue_free(queue);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
DPRINTF(E_LOG, L_MPD, "Out of memory\n");
|
||||||
|
return ACK_ERROR_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pos_pl++;
|
||||||
|
}
|
||||||
|
|
||||||
|
queue_free(queue);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Command handler function for 'playlistinfo'
|
* Command handler function for 'playlistinfo'
|
||||||
* Displays a list of all songs in the queue, or if the optional argument is given, displays information
|
* Displays a list of all songs in the queue, or if the optional argument is given, displays information
|
||||||
|
@ -1458,7 +1551,6 @@ static int
|
||||||
mpd_command_playlistinfo(struct evbuffer *evbuf, int argc, char **argv, char **errmsg)
|
mpd_command_playlistinfo(struct evbuffer *evbuf, int argc, char **argv, char **errmsg)
|
||||||
{
|
{
|
||||||
struct player_queue *queue;
|
struct player_queue *queue;
|
||||||
struct media_file_info *mfi;
|
|
||||||
int start_pos;
|
int start_pos;
|
||||||
int end_pos;
|
int end_pos;
|
||||||
int pos_pl;
|
int pos_pl;
|
||||||
|
@ -1492,34 +1584,19 @@ mpd_command_playlistinfo(struct evbuffer *evbuf, int argc, char **argv, char **e
|
||||||
pos_pl = queue->start_pos;
|
pos_pl = queue->start_pos;
|
||||||
for (i = 0; i < queue->count; i++)
|
for (i = 0; i < queue->count; i++)
|
||||||
{
|
{
|
||||||
mfi = db_file_fetch_byid(queue->queue[i]);
|
ret = mpd_add_mediainfo_byid(evbuf, queue->queue[i], pos_pl);
|
||||||
if (!mfi)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_MPD, "Error fetching file by id: %d\n", queue->queue[i]);
|
|
||||||
ret = asprintf(errmsg, "Error fetching file by id: %d", queue->queue[i]);
|
|
||||||
|
|
||||||
queue_free(queue);
|
|
||||||
|
|
||||||
if (ret < 0)
|
|
||||||
DPRINTF(E_LOG, L_MPD, "Out of memory\n");
|
|
||||||
return ACK_ERROR_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = mpd_add_mediainfo(evbuf, mfi, pos_pl);
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_MPD, "Error adding media info for file with id: %d\n", queue->queue[i]);
|
DPRINTF(E_LOG, L_MPD, "Error adding media info for file with id: %d\n", queue->queue[i]);
|
||||||
ret = asprintf(errmsg, "Error adding media info for file with id: %d\n", queue->queue[i]);
|
ret = asprintf(errmsg, "Error adding media info for file with id: %d\n", queue->queue[i]);
|
||||||
|
|
||||||
queue_free(queue);
|
queue_free(queue);
|
||||||
free_mfi(mfi, 0);
|
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
DPRINTF(E_LOG, L_MPD, "Out of memory\n");
|
DPRINTF(E_LOG, L_MPD, "Out of memory\n");
|
||||||
return ACK_ERROR_UNKNOWN;
|
return ACK_ERROR_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
free_mfi(mfi, 0);
|
|
||||||
pos_pl++;
|
pos_pl++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1608,7 +1685,11 @@ mpd_command_lsinfo(struct evbuffer *evbuf, int argc, char **argv, char **errmsg)
|
||||||
struct media_file_info *mfi;
|
struct media_file_info *mfi;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (strncmp(argv[1], "/", 1) == 0)
|
if (argc < 2)
|
||||||
|
{
|
||||||
|
ret = snprintf(parent, sizeof(parent), "/");
|
||||||
|
}
|
||||||
|
else if (strncmp(argv[1], "/", 1) == 0)
|
||||||
{
|
{
|
||||||
ret = snprintf(parent, sizeof(parent), "%s", argv[1]);
|
ret = snprintf(parent, sizeof(parent), "%s", argv[1]);
|
||||||
}
|
}
|
||||||
|
@ -1766,6 +1847,9 @@ mpd_command_outputs(struct evbuffer *evbuf, int argc, char **argv, char **errmsg
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
mpd_command_commands(struct evbuffer *evbuf, int argc, char **argv, char **errmsg);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Dummy function to handle commands that are not supported by forked-daapd and should
|
* Dummy function to handle commands that are not supported by forked-daapd and should
|
||||||
* not raise an error.
|
* not raise an error.
|
||||||
|
@ -1808,12 +1892,14 @@ static struct command mpd_handlers[] =
|
||||||
.mpdcommand = "currentsong",
|
.mpdcommand = "currentsong",
|
||||||
.handler = mpd_command_currentsong
|
.handler = mpd_command_currentsong
|
||||||
},
|
},
|
||||||
/*
|
|
||||||
{
|
{
|
||||||
.mpdcommand = "idle",
|
.mpdcommand = "idle",
|
||||||
.handler = mpd_command_idle
|
.handler = mpd_command_idle
|
||||||
},
|
},
|
||||||
*/
|
{
|
||||||
|
.mpdcommand = "idle",
|
||||||
|
.handler = mpd_command_noidle
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.mpdcommand = "status",
|
.mpdcommand = "status",
|
||||||
.handler = mpd_command_status
|
.handler = mpd_command_status
|
||||||
|
@ -1954,11 +2040,11 @@ static struct command mpd_handlers[] =
|
||||||
.mpdcommand = "playlistfind",
|
.mpdcommand = "playlistfind",
|
||||||
.handler = mpd_command_playlistfind
|
.handler = mpd_command_playlistfind
|
||||||
},
|
},
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
.mpdcommand = "playlistid",
|
.mpdcommand = "playlistid",
|
||||||
.handler = mpd_command_playlistid
|
.handler = mpd_command_playlistid
|
||||||
},
|
},
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
.mpdcommand = "playlistinfo",
|
.mpdcommand = "playlistinfo",
|
||||||
.handler = mpd_command_playlistinfo
|
.handler = mpd_command_playlistinfo
|
||||||
|
@ -2212,10 +2298,12 @@ static struct command mpd_handlers[] =
|
||||||
.mpdcommand = "config",
|
.mpdcommand = "config",
|
||||||
.handler = mpd_command_config
|
.handler = mpd_command_config
|
||||||
},
|
},
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
.mpdcommand = "commands",
|
.mpdcommand = "commands",
|
||||||
.handler = mpd_command_commands
|
.handler = mpd_command_commands
|
||||||
},
|
},
|
||||||
|
/*
|
||||||
{
|
{
|
||||||
.mpdcommand = "notcommands",
|
.mpdcommand = "notcommands",
|
||||||
.handler = mpd_command_notcommands
|
.handler = mpd_command_notcommands
|
||||||
|
@ -2291,6 +2379,22 @@ mpd_find_command(const char *name)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mpd_command_commands(struct evbuffer *evbuf, int argc, char **argv, char **errmsg)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; mpd_handlers[i].handler; i++)
|
||||||
|
{
|
||||||
|
evbuffer_add_printf(evbuf,
|
||||||
|
"command: %s\n",
|
||||||
|
mpd_handlers[i].mpdcommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The read callback function is invoked if a complete command sequence was received from the client
|
* The read callback function is invoked if a complete command sequence was received from the client
|
||||||
* (see mpd_input_filter function).
|
* (see mpd_input_filter function).
|
||||||
|
@ -2309,6 +2413,7 @@ mpd_read_cb(struct bufferevent *bev, void *ctx)
|
||||||
char *errmsg;
|
char *errmsg;
|
||||||
struct command *command;
|
struct command *command;
|
||||||
enum command_list_type listtype;
|
enum command_list_type listtype;
|
||||||
|
int idle_cmd;
|
||||||
char *argv[COMMAND_ARGV_MAX];
|
char *argv[COMMAND_ARGV_MAX];
|
||||||
int argc;
|
int argc;
|
||||||
|
|
||||||
|
@ -2319,12 +2424,14 @@ mpd_read_cb(struct bufferevent *bev, void *ctx)
|
||||||
|
|
||||||
DPRINTF(E_SPAM, L_MPD, "Received MPD command sequence\n");
|
DPRINTF(E_SPAM, L_MPD, "Received MPD command sequence\n");
|
||||||
|
|
||||||
|
idle_cmd = 0;
|
||||||
|
|
||||||
listtype = COMMAND_LIST_NONE;
|
listtype = COMMAND_LIST_NONE;
|
||||||
ncmd = 0;
|
ncmd = 0;
|
||||||
|
|
||||||
while ((line = evbuffer_readln(input, NULL, EVBUFFER_EOL_ANY)))
|
while ((line = evbuffer_readln(input, NULL, EVBUFFER_EOL_ANY)))
|
||||||
{
|
{
|
||||||
DPRINTF(E_SPAM, L_MPD, "MPD message: %s\n", line);
|
DPRINTF(E_DBG, L_MPD, "MPD message: %s\n", line);
|
||||||
|
|
||||||
// Split the read line into command name and arguments
|
// Split the read line into command name and arguments
|
||||||
ret = mpd_parse_args(line, &argc, argv);
|
ret = mpd_parse_args(line, &argc, argv);
|
||||||
|
@ -2362,6 +2469,10 @@ mpd_read_cb(struct bufferevent *bev, void *ctx)
|
||||||
free(line);
|
free(line);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else if (0 == strcmp(argv[0], "idle"))
|
||||||
|
idle_cmd = 1;
|
||||||
|
else if (0 == strcmp(argv[0], "noidle"))
|
||||||
|
idle_cmd = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the command handler and execute the command function
|
* Find the command handler and execute the command function
|
||||||
|
@ -2409,7 +2520,7 @@ mpd_read_cb(struct bufferevent *bev, void *ctx)
|
||||||
* If everything was successful add OK line to signal clients end of message.
|
* If everything was successful add OK line to signal clients end of message.
|
||||||
* If an error occured the necessary ACK line should already be added to the response buffer.
|
* If an error occured the necessary ACK line should already be added to the response buffer.
|
||||||
*/
|
*/
|
||||||
if (ret == 0)
|
if (ret == 0 && idle_cmd == 0)
|
||||||
{
|
{
|
||||||
evbuffer_add(output, "OK\n", 3);
|
evbuffer_add(output, "OK\n", 3);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue