Added new optional argument MODE to command 'save' to be able to append or replace an existing playlist

This commit is contained in:
gd 2022-10-02 11:19:26 +03:00
parent b0d6c0e7cb
commit cd093a6014
5 changed files with 53 additions and 15 deletions

View File

@ -1008,10 +1008,21 @@ remote playlists (absolute URI with a supported scheme).
.. _command_save:
:command:`save {NAME}`
:command:`save {NAME} [MODE]`
Saves the queue to
`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
==================

View File

@ -84,16 +84,25 @@ playlist_print_uri(BufferedOutputStream &os, const char *uri)
}
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);
assert(!path_fs.IsNull());
if (FileExists(path_fs))
throw PlaylistError(PlaylistResult::LIST_EXISTS,
"Playlist already exists");
if (save_mode == PlaylistSaveMode::CREATE) {
if (FileExists(path_fs)) {
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);
for (unsigned i = 0; i < queue.GetLength(); i++)
@ -106,7 +115,7 @@ spl_save_queue(const char *name_utf8, const Queue &queue)
}
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
playlist_print_uri(BufferedOutputStream &os, const char *uri);
/**
* Saves a queue object into a stored playlist file.
*/
enum class PlaylistSaveMode {
CREATE,
APPEND,
REPLACE
};
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.
*/
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

View File

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

View File

@ -66,7 +66,22 @@ print_spl_list(Response &r, const PlaylistVector &list)
CommandResult
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;
}