added support for the playqueueedit move command

This commit is contained in:
chme 2014-04-19 08:09:32 +02:00
parent 365c5a3bc9
commit c3c2c421d2
3 changed files with 144 additions and 1 deletions

View File

@ -1336,7 +1336,12 @@ dacp_reply_playqueueedit_add(struct evhttp_request *req, struct evbuffer *evbuf,
return;
}
}
//?command=add&query='dmap.itemid:156'&sort=album&mode=3&session-id=100
// -> mode=3: add to playqueue position 0 (play next)
//?command=add&query='dmap.itemid:158'&sort=album&mode=0&session-id=100
// -> mode=0: add to end of playqueue
//?command=add&query='dmap.itemid:306'&queuefilter=album:6525753023700533274&sort=album&mode=1&session-id=100
// -> mode 1: stop playblack, clear playqueue, add songs to playqueue
if ((mode == 1) || (mode == 2))
{
player_playback_stop();
@ -1412,6 +1417,51 @@ dacp_reply_playqueueedit_add(struct evhttp_request *req, struct evbuffer *evbuf,
evhttp_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf);
}
static void
dacp_reply_playqueueedit_move(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query)
{
/*
* Handles the move command.
* Exampe request:
* playqueue-edit?command=move&edit-params='edit-param.move-pair:3,0'&session-id=100
*
* The 'edit-param.move-pair' param contains the index of the song in the playqueue to be moved (index 3 in the example)
* and the index of the song after which it should be inserted (index 0 in the exampe, the now playing song).
*/
int ret;
const char *editparams;
int src;
int dst;
editparams = evhttp_find_header(query, "edit-params");
if (editparams)
{
ret = safe_atoi32(strchr(editparams, ':') + 1, &src);
if (ret < 0)
{
DPRINTF(E_LOG, L_DACP, "Invalid edit-params move-from value in playqueue-edit request\n");
dmap_send_error(req, "cacr", "Invalid request");
return;
}
ret = safe_atoi32(strchr(editparams, ',') + 1, &dst);
if (ret < 0)
{
DPRINTF(E_LOG, L_DACP, "Invalid edit-params move-to value in playqueue-edit request\n");
dmap_send_error(req, "cacr", "Invalid request");
return;
}
player_queue_move(src, dst);
}
/* 204 No Content is the canonical reply */
evhttp_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf);
}
static void
dacp_reply_playqueueedit(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query)
{
@ -1454,6 +1504,9 @@ dacp_reply_playqueueedit(struct evhttp_request *req, struct evbuffer *evbuf, cha
User selected track (Audiobooks):
?command=add&query='dmap.itemid:...'&mode=1&session-id=...
-> clear queue, play itemid and the rest of album tracks
?command=move&edit-params='edit-param.move-pair:3,0'&session-id=100
-> move song from playqueue position 3 to be played after song at position 0
*/
s = daap_session_find(req, query, evbuf);
@ -1475,6 +1528,8 @@ dacp_reply_playqueueedit(struct evhttp_request *req, struct evbuffer *evbuf, cha
dacp_reply_cue_play(req, evbuf, uri, query);
else if (strcmp(param, "add") == 0)
dacp_reply_playqueueedit_add(req, evbuf, uri, query);
else if (strcmp(param, "move") == 0)
dacp_reply_playqueueedit_move(req, evbuf, uri, query);
else
{
DPRINTF(E_LOG, L_DACP, "Unknown playqueue-edit command %s\n", param);

View File

@ -116,6 +116,7 @@ struct player_command
enum repeat_mode mode;
uint32_t id;
int intval;
int ps_pos[2];
} arg;
int ret;
@ -3356,6 +3357,70 @@ queue_add(struct player_command *cmd)
return 0;
}
static int queue_move(struct player_command *cmd)
{
struct player_source *ps_src = NULL;
struct player_source *ps_dst = NULL;
int pos_max = MAX(cmd->arg.ps_pos[0], cmd->arg.ps_pos[1]);
DPRINTF(E_LOG, L_PLAYER, "Move song from position %d to be next song after %d\n", cmd->arg.ps_pos[0],
cmd->arg.ps_pos[1]);
struct player_source *ps_tmp = cur_playing ? cur_playing : cur_streaming;
if (!ps_tmp)
{
DPRINTF(E_DBG, L_PLAYER, "Current playing/streaming song not found\n");
return 0;
}
int i = 0;
for (i = 0; i <= pos_max; ++i)
{
if (i == cmd->arg.ps_pos[0])
ps_src = ps_tmp;
if (i == cmd->arg.ps_pos[1])
ps_dst = ps_tmp;
ps_tmp = shuffle ? ps_tmp->shuffle_next : ps_tmp->pl_next;
}
if (ps_src && ps_dst)
{
struct player_source *ps_src_prev;
struct player_source *ps_src_next;
struct player_source *ps_dst_next;
if (shuffle)
{
ps_src_prev = ps_src->shuffle_prev;
ps_src_next = ps_src->shuffle_next;
ps_src_prev->shuffle_next = ps_src_next;
ps_src_next->shuffle_prev = ps_src_prev;
ps_dst_next = ps_dst->shuffle_next;
ps_dst->shuffle_next = ps_src;
ps_src->shuffle_prev = ps_dst;
ps_dst_next->shuffle_prev = ps_src;
ps_src->shuffle_next = ps_dst_next;
}
else
{
ps_src_prev = ps_src->pl_prev;
ps_src_next = ps_src->pl_next;
ps_src_prev->pl_next = ps_src_next;
ps_src_next->pl_prev = ps_src_prev;
ps_dst_next = ps_dst->pl_next;
ps_dst->pl_next = ps_src;
ps_src->pl_prev = ps_dst;
ps_dst_next->pl_prev = ps_src;
ps_src->pl_next = ps_dst_next;
}
}
return 0;
}
static int
queue_clear(struct player_command *cmd)
{
@ -3829,6 +3894,26 @@ player_queue_add(struct player_source *ps)
return ret;
}
int
player_queue_move(int ps_pos_from, int ps_pos_to)
{
struct player_command cmd;
int ret;
command_init(&cmd);
cmd.func = queue_move;
cmd.func_bh = NULL;
cmd.arg.ps_pos[0] = ps_pos_from;
cmd.arg.ps_pos[1] = ps_pos_to;
ret = sync_command(&cmd);
command_deinit(&cmd);
return ret;
}
void
player_queue_clear(void)
{

View File

@ -145,6 +145,9 @@ player_queue_get(void);
int
player_queue_add(struct player_source *ps);
int
player_queue_move(int ps_pos_from, int ps_pos_to);
void
player_queue_clear(void);