Merge branch 'queue_save_with_append' of https://github.com/geneticdrift/MPD

This commit is contained in:
Max Kellermann 2022-10-02 11:40:45 +02:00
commit 209e4e940e
6 changed files with 54 additions and 15 deletions

1
NEWS
View File

@ -1,6 +1,7 @@
ver 0.24 (not yet released) ver 0.24 (not yet released)
* protocol * protocol
- "playlistfind"/"playlistsearch" have "sort" and "window" parameters - "playlistfind"/"playlistsearch" have "sort" and "window" parameters
- "save" can append to or replace an existing playlist
- filter "prio" (for "playlistfind"/"playlistsearch") - filter "prio" (for "playlistfind"/"playlistsearch")
- limit "player" idle events to the current partition - limit "player" idle events to the current partition
- operator "starts_with" - operator "starts_with"

View File

@ -1008,10 +1008,21 @@ remote playlists (absolute URI with a supported scheme).
.. _command_save: .. _command_save:
:command:`save {NAME}` :command:`save {NAME} [MODE]`
Saves the queue to Saves the queue to
`NAME.m3u` in the playlist directory. `NAME.m3u` in the playlist directory.
``MODE`` [#since_0_24]_
Optional argument. One of `create`, `append`, or `replace`.
`create`
The default. Create a new playlist.
Fail if a playlist with name ``NAME`` already exists.
`append`, `replace`
Append or replace an existing playlist.
Fail if a playlist with name ``NAME`` doesn\'t already exist.
The music database The music database
================== ==================

View File

@ -84,16 +84,25 @@ playlist_print_uri(BufferedOutputStream &os, const char *uri)
} }
void void
spl_save_queue(const char *name_utf8, const Queue &queue) spl_save_queue(const char *name_utf8, PlaylistSaveMode save_mode, const Queue &queue)
{ {
const auto path_fs = spl_map_to_fs(name_utf8); const auto path_fs = spl_map_to_fs(name_utf8);
assert(!path_fs.IsNull()); assert(!path_fs.IsNull());
if (FileExists(path_fs)) if (save_mode == PlaylistSaveMode::CREATE) {
throw PlaylistError(PlaylistResult::LIST_EXISTS, if (FileExists(path_fs)) {
"Playlist already exists"); throw PlaylistError(PlaylistResult::LIST_EXISTS, "Playlist already exists");
}
}
else if (!FileExists(path_fs)) {
throw PlaylistError(PlaylistResult::NO_SUCH_LIST, "No such playlist");
}
FileOutputStream fos(path_fs,
save_mode == PlaylistSaveMode::APPEND
? FileOutputStream::Mode::APPEND_EXISTING
: FileOutputStream::Mode::CREATE);
FileOutputStream fos(path_fs);
BufferedOutputStream bos(fos); BufferedOutputStream bos(fos);
for (unsigned i = 0; i < queue.GetLength(); i++) for (unsigned i = 0; i < queue.GetLength(); i++)
@ -106,7 +115,7 @@ spl_save_queue(const char *name_utf8, const Queue &queue)
} }
void void
spl_save_playlist(const char *name_utf8, const playlist &playlist) spl_save_playlist(const char *name_utf8, PlaylistSaveMode save_mode, const playlist &playlist)
{ {
spl_save_queue(name_utf8, playlist.queue); spl_save_queue(name_utf8, save_mode, playlist.queue);
} }

View File

@ -31,16 +31,19 @@ playlist_print_song(BufferedOutputStream &os, const DetachedSong &song);
void void
playlist_print_uri(BufferedOutputStream &os, const char *uri); playlist_print_uri(BufferedOutputStream &os, const char *uri);
/** enum class PlaylistSaveMode {
* Saves a queue object into a stored playlist file. CREATE,
*/ APPEND,
REPLACE
};
void void
spl_save_queue(const char *name_utf8, const Queue &queue); spl_save_queue(const char *name_utf8, PlaylistSaveMode save_mode, const Queue &queue);
/** /**
* Saves a playlist object into a stored playlist file. * Saves a playlist object into a stored playlist file.
*/ */
void void
spl_save_playlist(const char *name_utf8, const playlist &playlist); spl_save_playlist(const char *name_utf8, PlaylistSaveMode save_mode, const playlist &playlist);
#endif #endif

View File

@ -184,7 +184,7 @@ static constexpr struct command commands[] = {
handle_replay_gain_status }, handle_replay_gain_status },
{ "rescan", PERMISSION_CONTROL, 0, 1, handle_rescan }, { "rescan", PERMISSION_CONTROL, 0, 1, handle_rescan },
{ "rm", PERMISSION_CONTROL, 1, 1, handle_rm }, { "rm", PERMISSION_CONTROL, 1, 1, handle_rm },
{ "save", PERMISSION_CONTROL, 1, 1, handle_save }, { "save", PERMISSION_CONTROL, 1, 2, handle_save },
#ifdef ENABLE_DATABASE #ifdef ENABLE_DATABASE
{ "search", PERMISSION_READ, 1, -1, handle_search }, { "search", PERMISSION_READ, 1, -1, handle_search },
{ "searchadd", PERMISSION_ADD, 1, -1, handle_searchadd }, { "searchadd", PERMISSION_ADD, 1, -1, handle_searchadd },

View File

@ -66,7 +66,22 @@ print_spl_list(Response &r, const PlaylistVector &list)
CommandResult CommandResult
handle_save(Client &client, Request args, [[maybe_unused]] Response &r) handle_save(Client &client, Request args, [[maybe_unused]] Response &r)
{ {
spl_save_playlist(args.front(), client.GetPlaylist()); PlaylistSaveMode mode = PlaylistSaveMode::CREATE;
const char *mode_arg = args.GetOptional(1);
if (mode_arg != nullptr) {
if (StringIsEqual(mode_arg, "create"))
mode = PlaylistSaveMode::CREATE;
else if (StringIsEqual(mode_arg, "append"))
mode = PlaylistSaveMode::APPEND;
else if (StringIsEqual(mode_arg, "replace"))
mode = PlaylistSaveMode::REPLACE;
else
throw std::invalid_argument("Unrecognized save mode, expected one of 'create', 'append', 'replace'");
}
spl_save_playlist(args.front(), mode, client.GetPlaylist());
return CommandResult::OK; return CommandResult::OK;
} }