mirror of
https://github.com/owntone/owntone-server.git
synced 2025-02-05 10:48:09 -05:00
Merge pull request #193 from chme/mpd
[mpd] Add support for moveid and close command
This commit is contained in:
commit
316af87189
63
src/mpd.c
63
src/mpd.c
@ -1748,6 +1748,57 @@ mpd_command_deleteid(struct evbuffer *evbuf, int argc, char **argv, char **errms
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mpd_command_move(struct evbuffer *evbuf, int argc, char **argv, char **errmsg)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mpd_command_moveid(struct evbuffer *evbuf, int argc, char **argv, char **errmsg)
|
||||||
|
{
|
||||||
|
uint32_t songid;
|
||||||
|
uint32_t to_pos;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (argc < 3)
|
||||||
|
{
|
||||||
|
ret = asprintf(errmsg, "Missing argument for command 'moveid'");
|
||||||
|
if (ret < 0)
|
||||||
|
DPRINTF(E_LOG, L_MPD, "Out of memory\n");
|
||||||
|
return ACK_ERROR_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = safe_atou32(argv[1], &songid);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = safe_atou32(argv[2], &to_pos);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
ret = asprintf(errmsg, "Argument doesn't convert to integer: '%s'", argv[2]);
|
||||||
|
if (ret < 0)
|
||||||
|
DPRINTF(E_LOG, L_MPD, "Out of memory\n");
|
||||||
|
return ACK_ERROR_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = player_queue_move_byitemid(songid, to_pos);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
ret = asprintf(errmsg, "Failed to move song with id '%s' to index '%s'", argv[1], argv[2]);
|
||||||
|
if (ret < 0)
|
||||||
|
DPRINTF(E_LOG, L_MPD, "Out of memory\n");
|
||||||
|
return ACK_ERROR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Command handler function for 'playlistid'
|
* Command handler function for 'playlistid'
|
||||||
* 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
|
||||||
@ -3561,7 +3612,6 @@ static struct command mpd_handlers[] =
|
|||||||
.mpdcommand = "deleteid",
|
.mpdcommand = "deleteid",
|
||||||
.handler = mpd_command_deleteid
|
.handler = mpd_command_deleteid
|
||||||
},
|
},
|
||||||
/*
|
|
||||||
{
|
{
|
||||||
.mpdcommand = "move",
|
.mpdcommand = "move",
|
||||||
.handler = mpd_command_move
|
.handler = mpd_command_move
|
||||||
@ -3570,7 +3620,6 @@ static struct command mpd_handlers[] =
|
|||||||
.mpdcommand = "moveid",
|
.mpdcommand = "moveid",
|
||||||
.handler = mpd_command_moveid
|
.handler = mpd_command_moveid
|
||||||
},
|
},
|
||||||
*/
|
|
||||||
// According to the mpd protocol the use of "playlist" is deprecated
|
// According to the mpd protocol the use of "playlist" is deprecated
|
||||||
{
|
{
|
||||||
.mpdcommand = "playlist",
|
.mpdcommand = "playlist",
|
||||||
@ -3790,11 +3839,11 @@ static struct command mpd_handlers[] =
|
|||||||
/*
|
/*
|
||||||
* Connection settings
|
* Connection settings
|
||||||
*/
|
*/
|
||||||
/*
|
|
||||||
{
|
{
|
||||||
.mpdcommand = "close",
|
.mpdcommand = "close",
|
||||||
.handler = mpd_command_close
|
.handler = mpd_command_ignore
|
||||||
},
|
},
|
||||||
|
/*
|
||||||
{
|
{
|
||||||
.mpdcommand = "kill",
|
.mpdcommand = "kill",
|
||||||
.handler = mpd_command_kill
|
.handler = mpd_command_kill
|
||||||
@ -3949,6 +3998,7 @@ mpd_read_cb(struct bufferevent *bev, void *ctx)
|
|||||||
struct command *command;
|
struct command *command;
|
||||||
enum command_list_type listtype;
|
enum command_list_type listtype;
|
||||||
int idle_cmd;
|
int idle_cmd;
|
||||||
|
int close_cmd;
|
||||||
char *argv[COMMAND_ARGV_MAX];
|
char *argv[COMMAND_ARGV_MAX];
|
||||||
int argc;
|
int argc;
|
||||||
|
|
||||||
@ -3960,6 +4010,7 @@ 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;
|
idle_cmd = 0;
|
||||||
|
close_cmd = 0;
|
||||||
|
|
||||||
listtype = COMMAND_LIST_NONE;
|
listtype = COMMAND_LIST_NONE;
|
||||||
ncmd = 0;
|
ncmd = 0;
|
||||||
@ -4008,6 +4059,8 @@ mpd_read_cb(struct bufferevent *bev, void *ctx)
|
|||||||
idle_cmd = 1;
|
idle_cmd = 1;
|
||||||
else if (0 == strcmp(argv[0], "noidle"))
|
else if (0 == strcmp(argv[0], "noidle"))
|
||||||
idle_cmd = 0;
|
idle_cmd = 0;
|
||||||
|
else if (0 == strcmp(argv[0], "close"))
|
||||||
|
close_cmd = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the command handler and execute the command function
|
* Find the command handler and execute the command function
|
||||||
@ -4055,7 +4108,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 && idle_cmd == 0)
|
if (ret == 0 && idle_cmd == 0 && close_cmd == 0)
|
||||||
{
|
{
|
||||||
evbuffer_add(output, "OK\n", 3);
|
evbuffer_add(output, "OK\n", 3);
|
||||||
}
|
}
|
||||||
|
55
src/player.c
55
src/player.c
@ -159,6 +159,14 @@ struct playerqueue_add_param
|
|||||||
int pos;
|
int pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct playerqueue_move_param
|
||||||
|
{
|
||||||
|
uint32_t item_id;
|
||||||
|
int from_pos;
|
||||||
|
int to_pos;
|
||||||
|
int count;
|
||||||
|
};
|
||||||
|
|
||||||
struct icy_artwork
|
struct icy_artwork
|
||||||
{
|
{
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
@ -198,11 +206,11 @@ struct player_command
|
|||||||
enum repeat_mode mode;
|
enum repeat_mode mode;
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
int intval;
|
int intval;
|
||||||
int ps_pos[2];
|
|
||||||
struct icy_artwork icy;
|
struct icy_artwork icy;
|
||||||
struct playback_start_param playback_start_param;
|
struct playback_start_param playback_start_param;
|
||||||
struct playerqueue_get_param queue_get_param;
|
struct playerqueue_get_param queue_get_param;
|
||||||
struct playerqueue_add_param queue_add_param;
|
struct playerqueue_add_param queue_add_param;
|
||||||
|
struct playerqueue_move_param queue_move_param;
|
||||||
} arg;
|
} arg;
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
@ -3416,8 +3424,8 @@ playerqueue_move_bypos(struct player_command *cmd)
|
|||||||
{
|
{
|
||||||
struct player_source *ps_playing;
|
struct player_source *ps_playing;
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_PLAYER, "Moving song from position %d to be the next song after %d\n", cmd->arg.ps_pos[0],
|
DPRINTF(E_DBG, L_PLAYER, "Moving song from position %d to be the next song after %d\n",
|
||||||
cmd->arg.ps_pos[1]);
|
cmd->arg.queue_move_param.from_pos, cmd->arg.queue_move_param.to_pos);
|
||||||
|
|
||||||
ps_playing = source_now_playing();
|
ps_playing = source_now_playing();
|
||||||
|
|
||||||
@ -3427,7 +3435,22 @@ playerqueue_move_bypos(struct player_command *cmd)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
queue_move_bypos(queue, ps_playing->item_id, cmd->arg.ps_pos[0], cmd->arg.ps_pos[1], shuffle);
|
queue_move_bypos(queue, ps_playing->item_id, cmd->arg.queue_move_param.from_pos, cmd->arg.queue_move_param.to_pos, shuffle);
|
||||||
|
|
||||||
|
cur_plversion++;
|
||||||
|
|
||||||
|
listener_notify(LISTENER_PLAYLIST);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
playerqueue_move_byitemid(struct player_command *cmd)
|
||||||
|
{
|
||||||
|
DPRINTF(E_DBG, L_PLAYER, "Moving song with item-id %d to be the next song after index %d\n",
|
||||||
|
cmd->arg.queue_move_param.item_id, cmd->arg.queue_move_param.to_pos);
|
||||||
|
|
||||||
|
queue_move_byitemid(queue, cmd->arg.queue_move_param.item_id, cmd->arg.queue_move_param.to_pos, 0);
|
||||||
|
|
||||||
cur_plversion++;
|
cur_plversion++;
|
||||||
|
|
||||||
@ -4198,8 +4221,28 @@ player_queue_move_bypos(int pos_from, int pos_to)
|
|||||||
|
|
||||||
cmd.func = playerqueue_move_bypos;
|
cmd.func = playerqueue_move_bypos;
|
||||||
cmd.func_bh = NULL;
|
cmd.func_bh = NULL;
|
||||||
cmd.arg.ps_pos[0] = pos_from;
|
cmd.arg.queue_move_param.from_pos = pos_from;
|
||||||
cmd.arg.ps_pos[1] = pos_to;
|
cmd.arg.queue_move_param.to_pos = pos_to;
|
||||||
|
|
||||||
|
ret = sync_command(&cmd);
|
||||||
|
|
||||||
|
command_deinit(&cmd);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
player_queue_move_byitemid(uint32_t item_id, int pos_to)
|
||||||
|
{
|
||||||
|
struct player_command cmd;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
command_init(&cmd);
|
||||||
|
|
||||||
|
cmd.func = playerqueue_move_byitemid;
|
||||||
|
cmd.func_bh = NULL;
|
||||||
|
cmd.arg.queue_move_param.item_id = item_id;
|
||||||
|
cmd.arg.queue_move_param.to_pos = pos_to;
|
||||||
|
|
||||||
ret = sync_command(&cmd);
|
ret = sync_command(&cmd);
|
||||||
|
|
||||||
|
@ -169,6 +169,9 @@ player_queue_add_next(struct queue_item *items);
|
|||||||
int
|
int
|
||||||
player_queue_move_bypos(int ps_pos_from, int ps_pos_to);
|
player_queue_move_bypos(int ps_pos_from, int ps_pos_to);
|
||||||
|
|
||||||
|
int
|
||||||
|
player_queue_move_byitemid(uint32_t item_id, int pos_to);
|
||||||
|
|
||||||
int
|
int
|
||||||
player_queue_remove_bypos(int pos);
|
player_queue_remove_bypos(int pos);
|
||||||
|
|
||||||
|
82
src/queue.c
82
src/queue.c
@ -725,7 +725,7 @@ queue_move_bypos(struct queue *queue, unsigned int item_id, unsigned int from_po
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the item at the target position
|
// Get the item at the target position
|
||||||
item_next = queueitem_get_bypos(queue, item_id, to_offset, shuffle);
|
item_next = queueitem_get_bypos(queue, item_id, (to_offset + 1), shuffle);
|
||||||
if (!item_next)
|
if (!item_next)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_PLAYER, "Invalid position given to move items\n");
|
DPRINTF(E_LOG, L_PLAYER, "Invalid position given to move items\n");
|
||||||
@ -744,7 +744,7 @@ queue_move_bypos(struct queue *queue, unsigned int item_id, unsigned int from_po
|
|||||||
item->next->prev = item->prev;
|
item->next->prev = item->prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert item into the queue befor the item at the target postion
|
// Insert item into the queue before the item at the target postion
|
||||||
if (shuffle)
|
if (shuffle)
|
||||||
{
|
{
|
||||||
item_next->shuffle_prev->shuffle_next = item;
|
item_next->shuffle_prev->shuffle_next = item;
|
||||||
@ -755,11 +755,81 @@ queue_move_bypos(struct queue *queue, unsigned int item_id, unsigned int from_po
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
item_next->next->prev = item;
|
item_next->prev->next = item;
|
||||||
item->next = item_next->next;
|
item->prev = item_next->prev;
|
||||||
|
|
||||||
item_next->next = item;
|
item_next->prev = item;
|
||||||
item->prev = item_next;
|
item->next = item_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Moves the item with the given item-id to the index to_pos in the play-queue (shuffle = 0)
|
||||||
|
* or shuffle-queue (shuffle = 1)
|
||||||
|
*
|
||||||
|
* @param queue The queue to move item
|
||||||
|
* @param item_id The item-id of the to be moved
|
||||||
|
* @param to_pos The index to move the item
|
||||||
|
* @param shuffle If 0 the position in the play-queue, 1 the position in the shuffle-queue
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
queue_move_byitemid(struct queue *queue, unsigned int item_id, unsigned int to_pos, char shuffle)
|
||||||
|
{
|
||||||
|
struct queue_item *item;
|
||||||
|
struct queue_item *item_next;
|
||||||
|
int index;
|
||||||
|
|
||||||
|
// Get the item to be moved
|
||||||
|
item = queueitem_get_byitemid(queue, item_id);
|
||||||
|
if (!item)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_PLAYER, "Item with item-id %d does not exist in the queue\n", item_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the index of the item to move is lower than the target index
|
||||||
|
// If that is the case, increment the target position, because the given to_pos
|
||||||
|
// is based on the queue without the moved item.
|
||||||
|
index = queue_index_byitemid(queue, item_id, shuffle);
|
||||||
|
if (index < to_pos)
|
||||||
|
to_pos++;
|
||||||
|
|
||||||
|
// Get the item at the target position
|
||||||
|
item_next = queueitem_get_byindex(queue, to_pos, shuffle);
|
||||||
|
if (!item_next)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_PLAYER, "Invalid position given to move items\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove item from the queue
|
||||||
|
if (shuffle)
|
||||||
|
{
|
||||||
|
item->shuffle_prev->shuffle_next = item->shuffle_next;
|
||||||
|
item->shuffle_next->shuffle_prev = item->shuffle_prev;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item->prev->next = item->next;
|
||||||
|
item->next->prev = item->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert item into the queue before the item at the target postion
|
||||||
|
if (shuffle)
|
||||||
|
{
|
||||||
|
item_next->shuffle_prev->shuffle_next = item;
|
||||||
|
item->shuffle_prev = item_next->shuffle_prev;
|
||||||
|
|
||||||
|
item_next->shuffle_prev = item;
|
||||||
|
item->shuffle_next = item_next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item_next->prev->next = item;
|
||||||
|
item->prev = item_next->prev;
|
||||||
|
|
||||||
|
item_next->prev = item;
|
||||||
|
item->next = item_next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,6 +83,9 @@ queue_add_after(struct queue *queue, struct queue_item *item, unsigned int item_
|
|||||||
void
|
void
|
||||||
queue_move_bypos(struct queue *queue, unsigned int item_id, unsigned int from_pos, unsigned int to_offset, char shuffle);
|
queue_move_bypos(struct queue *queue, unsigned int item_id, unsigned int from_pos, unsigned int to_offset, char shuffle);
|
||||||
|
|
||||||
|
void
|
||||||
|
queue_move_byitemid(struct queue *queue, unsigned int item_id, unsigned int to_pos, char shuffle);
|
||||||
|
|
||||||
void
|
void
|
||||||
queue_remove_byitemid(struct queue *queue, unsigned int item_id);
|
queue_remove_byitemid(struct queue *queue, unsigned int item_id);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user