From 6f595e9abba405d086d58576eba43342bcf1a2b0 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sat, 23 Oct 2021 13:00:34 +0200 Subject: [PATCH] command/queue: add optional position parameter to "add" Closes https://github.com/MusicPlayerDaemon/MPD/issues/1285 --- NEWS | 2 ++ doc/protocol.rst | 5 ++++- meson.build | 2 +- src/command/AllCommands.cxx | 2 +- src/command/QueueCommands.cxx | 24 ++++++++++++++++++++---- 5 files changed, 28 insertions(+), 7 deletions(-) diff --git a/NEWS b/NEWS index fdc2a9b92..410b41abe 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,6 @@ ver 0.23.3 (not yet released) +* protocol + - add optional position parameter to "add" * output - alsa: add option "stop_dsd_silence" to work around DSD DAC noise * macOS: fix libfmt related build failure diff --git a/doc/protocol.rst b/doc/protocol.rst index 5c9dd5a1f..7e73ddb5c 100644 --- a/doc/protocol.rst +++ b/doc/protocol.rst @@ -689,11 +689,14 @@ Whenever possible, ids should be used. .. _command_add: -:command:`add {URI}` +:command:`add {URI} [POSITION]` Adds the file ``URI`` to the playlist (directories add recursively). ``URI`` can also be a single file. + The position parameter is the same as in :ref:`addid + `. + Clients that are connected via local socket may add arbitrary local files (URI is an absolute path). Example:: diff --git a/meson.build b/meson.build index 98fa5c037..b4ce17823 100644 --- a/meson.build +++ b/meson.build @@ -44,7 +44,7 @@ version_conf = configuration_data() version_conf.set_quoted('PACKAGE', meson.project_name()) version_conf.set_quoted('PACKAGE_NAME', meson.project_name()) version_conf.set_quoted('VERSION', meson.project_version()) -version_conf.set_quoted('PROTOCOL_VERSION', '0.23.1') +version_conf.set_quoted('PROTOCOL_VERSION', '0.23.3') configure_file(output: 'Version.h', configuration: version_conf) conf = configuration_data() diff --git a/src/command/AllCommands.cxx b/src/command/AllCommands.cxx index 2a4a2208d..36b9987fa 100644 --- a/src/command/AllCommands.cxx +++ b/src/command/AllCommands.cxx @@ -85,7 +85,7 @@ handle_not_commands(Client &client, Request request, Response &response); * This array must be sorted! */ static constexpr struct command commands[] = { - { "add", PERMISSION_ADD, 1, 1, handle_add }, + { "add", PERMISSION_ADD, 1, 2, handle_add }, { "addid", PERMISSION_ADD, 1, 2, handle_addid }, { "addtagid", PERMISSION_ADD, 3, 3, handle_addtagid }, { "albumart", PERMISSION_READ, 2, 2, handle_album_art }, diff --git a/src/command/QueueCommands.cxx b/src/command/QueueCommands.cxx index d132dd021..2d70e208e 100644 --- a/src/command/QueueCommands.cxx +++ b/src/command/QueueCommands.cxx @@ -79,6 +79,11 @@ handle_add(Client &client, Request args, [[maybe_unused]] Response &r) here */ uri = ""; + const auto old_size = partition.playlist.GetLength(); + const unsigned position = args.size > 1 + ? ParseInsertPosition(args[1], partition.playlist) + : old_size; + const auto located_uri = LocateUri(UriPluginKind::INPUT, uri, &client #ifdef ENABLE_DATABASE @@ -89,23 +94,34 @@ handle_add(Client &client, Request args, [[maybe_unused]] Response &r) case LocatedUri::Type::ABSOLUTE: AddUri(client, located_uri); client.GetInstance().LookupRemoteTag(located_uri.canonical_uri); - return CommandResult::OK; + break; case LocatedUri::Type::PATH: AddUri(client, located_uri); - return CommandResult::OK; + break; case LocatedUri::Type::RELATIVE: #ifdef ENABLE_DATABASE AddDatabaseSelection(partition, located_uri.canonical_uri); - return CommandResult::OK; + break; #else r.Error(ACK_ERROR_NO_EXIST, "No database"); return CommandResult::ERROR; #endif } - gcc_unreachable(); + if (position < old_size) { + const unsigned new_size = partition.playlist.GetLength(); + const RangeArg move_range{old_size, new_size}; + + try { + partition.MoveRange(move_range, position); + } catch (...) { + /* ignore - shall we handle it? */ + } + } + + return CommandResult::OK; } CommandResult