Skip to content

Commit

Permalink
Feat: MYMPD_API_PLAYLIST_COPY accepts multiple sources #1001
Browse files Browse the repository at this point in the history
  • Loading branch information
jcorporation committed May 23, 2023
1 parent 6af1579 commit 9b1d4ec
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 36 deletions.
10 changes: 5 additions & 5 deletions htdocs/js/apidoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -538,12 +538,12 @@ const APImethods = {
}
},
"MYMPD_API_PLAYLIST_COPY": {
"desc": "Copies or moves a source playlist to a destination playlist.",
"desc": "Copies or moves source playlists to a destination playlist.",
"params": {
"srcPlist": {
"type": APItypes.string,
"example": "test_plist",
"desc": "Source MPD playlist to rename"
"srcPlists": {
"type": APItypes.array,
"example": "[\"test_plist\"]",
"desc": "Source MPD playlists to copy"
},
"dstPlist": {
"type": APItypes.string,
Expand Down
12 changes: 8 additions & 4 deletions src/mympd_api/mympd_api_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -1310,14 +1310,18 @@ void mympd_api_handler(struct t_partition_state *partition_state, struct t_work_
}
}
break;
case MYMPD_API_PLAYLIST_COPY:
if (json_get_string(request->data, "$.params.srcPlist", 1, FILENAME_LEN_MAX, &sds_buf1, vcb_isfilename, &error) == true &&
json_get_string(request->data, "$.params.dstPlist", 1, FILENAME_LEN_MAX, &sds_buf2, vcb_isfilename, &error) == true &&
case MYMPD_API_PLAYLIST_COPY: {
struct t_list src_plists;
list_init(&src_plists);
if (json_get_array_string(request->data, "$.params.srcPlists", &src_plists, vcb_isfilename, JSONRPC_ARRAY_MAX, &error) == true &&
json_get_string(request->data, "$.params.dstPlist", 1, FILENAME_LEN_MAX, &sds_buf1, vcb_isfilename, &error) == true &&
json_get_uint(request->data, "$.params.mode", 0, 4, &uint_buf1, &error))
{
response->data = mympd_api_playlist_copy(partition_state, response->data, request->id, sds_buf1, sds_buf2, uint_buf1);
response->data = mympd_api_playlist_copy(partition_state, response->data, request->id, &src_plists, sds_buf1, uint_buf1);
}
list_clear(&src_plists);
break;
}
case MYMPD_API_DATABASE_FILESYSTEM_LIST: {
struct t_tags tagcols;
reset_t_tags(&tagcols);
Expand Down
55 changes: 29 additions & 26 deletions src/mympd_api/playlists.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,46 +52,53 @@ static void free_t_pl_data(void *data) {
}

/**
* Copies or moves a playlist to a new playlist or insert/append/replace to an existing playlist.
* Copies or moves source playlists to a destination playlist.
* @param partition_state pointer to partition state
* @param buffer already allocated sds string to append the response
* @param request_id jsonrpc request id
* @param src_plist playlist to copy
* @param src_plists playlists to copy
* @param dst_plist destination playlist
* @return true on success, else false
* @param mode copy mode enum
* @return jsonrpc response
*/
sds mympd_api_playlist_copy(struct t_partition_state *partition_state, sds buffer,
long request_id, sds src_plist, sds dst_plist, enum plist_copy_modes mode)
long request_id, struct t_list *src_plists, sds dst_plist, enum plist_copy_modes mode)
{
enum mympd_cmd_ids cmd_id = MYMPD_API_PLAYLIST_COPY;
bool rc = mpd_send_list_playlist(partition_state->conn, src_plist);
if (mympd_check_rc_error_and_recover_respond(partition_state, &buffer, cmd_id, request_id, rc, "mpd_send_list_playlist") == false) {
return buffer;
}
struct mpd_song *song;
//copy sources in temporary list
struct t_list src;
list_init(&src);
while ((song = mpd_recv_song(partition_state->conn)) != NULL) {
list_push(&src, mpd_song_get_uri(song), 0, NULL, NULL);
}
mpd_response_finish(partition_state->conn);
if (mympd_check_error_and_recover_respond(partition_state, &buffer, cmd_id, request_id) == false) {
list_clear(&src);
return buffer;
struct t_list_node *current = src_plists->head;
while (current != NULL) {
bool rc = mpd_send_list_playlist(partition_state->conn, current->key);
if (mympd_check_rc_error_and_recover_respond(partition_state, &buffer, cmd_id, request_id, rc, "mpd_send_list_playlist") == false) {
return buffer;
}
struct mpd_song *song;
while ((song = mpd_recv_song(partition_state->conn)) != NULL) {
list_push(&src, mpd_song_get_uri(song), 0, NULL, NULL);
}
mpd_response_finish(partition_state->conn);
if (mympd_check_error_and_recover_respond(partition_state, &buffer, cmd_id, request_id) == false) {
list_clear(&src);
return buffer;
}
current = current->next;
}

if (mode == PLAYLIST_COPY_REPLACE) {
//clear dst playlist
rc = mpd_run_playlist_clear(partition_state->conn, dst_plist);
bool rc = mpd_run_playlist_clear(partition_state->conn, dst_plist);
if (mympd_check_rc_error_and_recover_respond(partition_state, &buffer, cmd_id, request_id, rc, "mpd_run_playlist_clear") == false) {
list_clear(&src);
return buffer;
}
}
struct t_list_node *current;

//insert or append to dst playlist
unsigned i = 0;
unsigned j = 0;
while ((current = list_shift_first(&src)) != NULL) {
//insert or append to dst playlist
if (i == 0 &&
mpd_command_list_begin(partition_state->conn, false) == false)
{
Expand All @@ -110,7 +117,7 @@ sds mympd_api_playlist_copy(struct t_partition_state *partition_state, sds buffe
if (i == MPD_COMMANDS_MAX ||
src.head == NULL)
{
rc = mpd_command_list_end(partition_state->conn) && mpd_response_finish(partition_state->conn);
bool rc = mpd_command_list_end(partition_state->conn) && mpd_response_finish(partition_state->conn);
if (mympd_check_rc_error_and_recover_respond(partition_state, &buffer, cmd_id, request_id, rc, "mpd_run_playlist_clear") == false) {
list_clear(&src);
return buffer;
Expand All @@ -130,13 +137,9 @@ sds mympd_api_playlist_copy(struct t_partition_state *partition_state, sds buffe
JSONRPC_FACILITY_PLAYLIST, JSONRPC_SEVERITY_INFO, "Playlist successfully replaced");
case PLAYLIST_MOVE_APPEND:
case PLAYLIST_MOVE_INSERT: {
//delete src playlist
struct t_list plist;
list_init(&plist);
list_push(&plist, src_plist, 0, NULL, NULL);
//delete src playlists
bool result;
buffer = mympd_api_playlist_delete(partition_state, buffer, request_id, &plist, false, &result);
list_clear(&plist);
buffer = mympd_api_playlist_delete(partition_state, buffer, request_id, src_plists, false, &result);
if (result == false) {
return buffer;
}
Expand Down
2 changes: 1 addition & 1 deletion src/mympd_api/playlists.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,5 @@ bool mympd_api_playlist_content_append(struct t_partition_state *partition_state
bool mympd_api_playlist_content_insert(struct t_partition_state *partition_state, sds plist, struct t_list *uris, unsigned to);
bool mympd_api_playlist_content_replace(struct t_partition_state *partition_state, sds plist, struct t_list *uris);
sds mympd_api_playlist_copy(struct t_partition_state *partition_state, sds buffer,
long request_id, sds src_plist, sds dst_plist, enum plist_copy_modes mode);
long request_id, struct t_list *src_plists, sds dst_plist, enum plist_copy_modes mode);
#endif

0 comments on commit 9b1d4ec

Please sign in to comment.