diff options
Diffstat (limited to 'src/command')
29 files changed, 506 insertions, 231 deletions
diff --git a/src/command/AllCommands.cxx b/src/command/AllCommands.cxx index 74802ced4..2ac55e715 100644 --- a/src/command/AllCommands.cxx +++ b/src/command/AllCommands.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -20,23 +20,26 @@ #include "config.h" #include "AllCommands.hxx" #include "QueueCommands.hxx" +#include "TagCommands.hxx" #include "PlayerCommands.hxx" #include "PlaylistCommands.hxx" #include "DatabaseCommands.hxx" #include "FileCommands.hxx" #include "OutputCommands.hxx" #include "MessageCommands.hxx" +#include "NeighborCommands.hxx" #include "OtherCommands.hxx" #include "Permission.hxx" #include "tag/TagType.h" #include "protocol/Result.hxx" -#include "Client.hxx" +#include "Partition.hxx" +#include "client/Client.hxx" #include "util/Tokenizer.hxx" #include "util/Error.hxx" #ifdef ENABLE_SQLITE #include "StickerCommands.hxx" -#include "StickerDatabase.hxx" +#include "sticker/StickerDatabase.hxx" #endif #include <assert.h> @@ -74,14 +77,18 @@ handle_not_commands(Client &client, int argc, char *argv[]); static const struct command commands[] = { { "add", PERMISSION_ADD, 1, 1, handle_add }, { "addid", PERMISSION_ADD, 1, 2, handle_addid }, + { "addtagid", PERMISSION_ADD, 3, 3, handle_addtagid }, { "channels", PERMISSION_READ, 0, 0, handle_channels }, { "clear", PERMISSION_CONTROL, 0, 0, handle_clear }, { "clearerror", PERMISSION_CONTROL, 0, 0, handle_clearerror }, + { "cleartagid", PERMISSION_ADD, 1, 2, handle_cleartagid }, { "close", PERMISSION_NONE, -1, -1, handle_close }, { "commands", PERMISSION_NONE, 0, 0, handle_commands }, { "config", PERMISSION_ADMIN, 0, 0, handle_config }, { "consume", PERMISSION_CONTROL, 1, 1, handle_consume }, +#ifdef ENABLE_DATABASE { "count", PERMISSION_READ, 2, -1, handle_count }, +#endif { "crossfade", PERMISSION_CONTROL, 1, 1, handle_crossfade }, { "currentsong", PERMISSION_READ, 0, 0, handle_currentsong }, { "decoders", PERMISSION_READ, 0, 0, handle_decoders }, @@ -89,13 +96,20 @@ static const struct command commands[] = { { "deleteid", PERMISSION_CONTROL, 1, 1, handle_deleteid }, { "disableoutput", PERMISSION_ADMIN, 1, 1, handle_disableoutput }, { "enableoutput", PERMISSION_ADMIN, 1, 1, handle_enableoutput }, +#ifdef ENABLE_DATABASE { "find", PERMISSION_READ, 2, -1, handle_find }, { "findadd", PERMISSION_READ, 2, -1, handle_findadd}, +#endif { "idle", PERMISSION_READ, 0, -1, handle_idle }, { "kill", PERMISSION_ADMIN, -1, -1, handle_kill }, +#ifdef ENABLE_DATABASE { "list", PERMISSION_READ, 1, -1, handle_list }, { "listall", PERMISSION_READ, 0, 1, handle_listall }, { "listallinfo", PERMISSION_READ, 0, 1, handle_listallinfo }, +#endif +#ifdef ENABLE_NEIGHBOR_PLUGINS + { "listneighbors", PERMISSION_READ, 0, 0, handle_listneighbors }, +#endif { "listplaylist", PERMISSION_READ, 1, 1, handle_listplaylist }, { "listplaylistinfo", PERMISSION_READ, 1, 1, handle_listplaylistinfo }, { "listplaylists", PERMISSION_READ, 0, 0, handle_listplaylists }, @@ -139,9 +153,11 @@ static const struct command commands[] = { { "rescan", PERMISSION_CONTROL, 0, 1, handle_rescan }, { "rm", PERMISSION_CONTROL, 1, 1, handle_rm }, { "save", PERMISSION_CONTROL, 1, 1, handle_save }, +#ifdef ENABLE_DATABASE { "search", PERMISSION_READ, 2, -1, handle_search }, { "searchadd", PERMISSION_ADD, 2, -1, handle_searchadd }, { "searchaddpl", PERMISSION_CONTROL, 3, -1, handle_searchaddpl }, +#endif { "seek", PERMISSION_CONTROL, 2, 2, handle_seek }, { "seekcur", PERMISSION_CONTROL, 1, 1, handle_seekcur }, { "seekid", PERMISSION_CONTROL, 2, 2, handle_seekid }, @@ -169,13 +185,19 @@ static const struct command commands[] = { static const unsigned num_commands = sizeof(commands) / sizeof(commands[0]); static bool -command_available(gcc_unused const struct command *cmd) +command_available(gcc_unused const Partition &partition, + gcc_unused const struct command *cmd) { #ifdef ENABLE_SQLITE if (strcmp(cmd->cmd, "sticker") == 0) return sticker_enabled(); #endif +#ifdef ENABLE_NEIGHBOR_PLUGINS + if (strcmp(cmd->cmd, "listneighbors") == 0) + return neighbor_commands_available(partition.instance); +#endif + return true; } @@ -191,7 +213,7 @@ handle_commands(Client &client, cmd = &commands[i]; if (cmd->permission == (permission & cmd->permission) && - command_available(cmd)) + command_available(client.partition, cmd)) client_printf(client, "command: %s\n", cmd->cmd); } diff --git a/src/command/AllCommands.hxx b/src/command/AllCommands.hxx index 2be94c136..b7834a8de 100644 --- a/src/command/AllCommands.hxx +++ b/src/command/AllCommands.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/command/CommandError.cxx b/src/command/CommandError.cxx index fc14d4a5d..c94ffea63 100644 --- a/src/command/CommandError.cxx +++ b/src/command/CommandError.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -19,14 +19,13 @@ #include "config.h" #include "CommandError.hxx" -#include "DatabaseError.hxx" +#include "db/DatabaseError.hxx" #include "protocol/Result.hxx" #include "util/Error.hxx" #include "Log.hxx" -#include <glib.h> - #include <assert.h> +#include <string.h> #include <errno.h> CommandResult @@ -38,7 +37,7 @@ print_playlist_result(Client &client, PlaylistResult result) case PlaylistResult::ERRNO: command_error(client, ACK_ERROR_SYSTEM, "%s", - g_strerror(errno)); + strerror(errno)); return CommandResult::ERROR; case PlaylistResult::DENIED: @@ -102,6 +101,7 @@ print_error(Client &client, const Error &error) command_error(client, (ack)error.GetCode(), "%s", error.GetMessage()); return CommandResult::ERROR; +#ifdef ENABLE_DATABASE } else if (error.IsDomain(db_domain)) { switch ((enum db_error)error.GetCode()) { case DB_DISABLED: @@ -113,9 +113,10 @@ print_error(Client &client, const Error &error) command_error(client, ACK_ERROR_NO_EXIST, "Not found"); return CommandResult::ERROR; } +#endif } else if (error.IsDomain(errno_domain)) { command_error(client, ACK_ERROR_SYSTEM, "%s", - g_strerror(error.GetCode())); + strerror(error.GetCode())); return CommandResult::ERROR; } diff --git a/src/command/CommandError.hxx b/src/command/CommandError.hxx index c7d3fff76..b48baa5bf 100644 --- a/src/command/CommandError.hxx +++ b/src/command/CommandError.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/command/CommandListBuilder.cxx b/src/command/CommandListBuilder.cxx index cc10f7205..1dcbf2946 100644 --- a/src/command/CommandListBuilder.cxx +++ b/src/command/CommandListBuilder.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -19,7 +19,7 @@ #include "config.h" #include "CommandListBuilder.hxx" -#include "ClientInternal.hxx" +#include "client/ClientInternal.hxx" #include <string.h> diff --git a/src/command/CommandListBuilder.hxx b/src/command/CommandListBuilder.hxx index a112ac33b..0747c4697 100644 --- a/src/command/CommandListBuilder.hxx +++ b/src/command/CommandListBuilder.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/command/CommandResult.hxx b/src/command/CommandResult.hxx index 9916b70cb..a2e968fb6 100644 --- a/src/command/CommandResult.hxx +++ b/src/command/CommandResult.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/command/DatabaseCommands.cxx b/src/command/DatabaseCommands.cxx index b86cbdae7..ef6fb922e 100644 --- a/src/command/DatabaseCommands.cxx +++ b/src/command/DatabaseCommands.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -19,21 +19,18 @@ #include "config.h" #include "DatabaseCommands.hxx" -#include "DatabaseQueue.hxx" -#include "DatabasePlaylist.hxx" -#include "DatabasePrint.hxx" -#include "DatabaseSelection.hxx" +#include "db/DatabaseGlue.hxx" +#include "db/DatabaseQueue.hxx" +#include "db/DatabasePlaylist.hxx" +#include "db/DatabasePrint.hxx" +#include "db/Selection.hxx" #include "CommandError.hxx" -#include "Client.hxx" +#include "client/Client.hxx" #include "tag/Tag.hxx" -#include "util/UriUtil.hxx" #include "util/Error.hxx" #include "SongFilter.hxx" #include "protocol/Result.hxx" -#include <assert.h> -#include <string.h> - CommandResult handle_lsinfo2(Client &client, int argc, char *argv[]) { @@ -123,7 +120,11 @@ handle_searchaddpl(Client &client, int argc, char *argv[]) } Error error; - return search_add_to_playlist("", playlist, &filter, error) + const Database *db = client.GetDatabase(error); + if (db == nullptr) + return print_error(client, error); + + return search_add_to_playlist(*db, "", playlist, &filter, error) ? CommandResult::OK : print_error(client, error); } diff --git a/src/command/DatabaseCommands.hxx b/src/command/DatabaseCommands.hxx index 76b2ba817..8678f19c8 100644 --- a/src/command/DatabaseCommands.hxx +++ b/src/command/DatabaseCommands.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/command/FileCommands.cxx b/src/command/FileCommands.cxx index eecc3102f..cfd5e3926 100644 --- a/src/command/FileCommands.cxx +++ b/src/command/FileCommands.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -22,16 +22,18 @@ #include "CommandError.hxx" #include "protocol/Ack.hxx" #include "protocol/Result.hxx" -#include "ClientFile.hxx" -#include "Client.hxx" +#include "client/Client.hxx" #include "util/CharUtil.hxx" +#include "util/UriUtil.hxx" #include "util/Error.hxx" #include "tag/TagHandler.hxx" #include "tag/ApeTag.hxx" #include "tag/TagId3.hxx" +#include "TagStream.hxx" #include "TagFile.hxx" #include "Mapper.hxx" #include "fs/AllocatedPath.hxx" +#include "ls.hxx" #include <assert.h> @@ -80,6 +82,25 @@ static constexpr tag_handler print_comment_handler = { print_pair, }; +static CommandResult +read_stream_comments(Client &client, const char *uri) +{ + if (!uri_supported_scheme(uri)) { + command_error(client, ACK_ERROR_NO_EXIST, + "unsupported URI scheme"); + return CommandResult::ERROR; + } + + if (!tag_stream_scan(uri, print_comment_handler, &client)) { + command_error(client, ACK_ERROR_NO_EXIST, + "Failed to load file"); + return CommandResult::ERROR; + } + + return CommandResult::OK; + +} + CommandResult handle_read_comments(Client &client, gcc_unused int argc, char *argv[]) { @@ -100,21 +121,28 @@ handle_read_comments(Client &client, gcc_unused int argc, char *argv[]) } Error error; - if (!client_allow_file(client, path_fs, error)) + if (!client.AllowFile(path_fs, error)) return print_error(client, error); - } else if (*uri != '/') { + } else if (uri_has_scheme(uri)) { + return read_stream_comments(client, uri); + } else if (!PathTraitsUTF8::IsAbsolute(uri)) { +#ifdef ENABLE_DATABASE path_fs = map_uri_fs(uri); if (path_fs.IsNull()) { command_error(client, ACK_ERROR_NO_EXIST, "No such file"); return CommandResult::ERROR; } +#else + command_error(client, ACK_ERROR_NO_EXIST, "No database"); + return CommandResult::ERROR; +#endif } else { command_error(client, ACK_ERROR_NO_EXIST, "No such file"); return CommandResult::ERROR; } - if (!tag_file_scan(path_fs, &print_comment_handler, &client)) { + if (!tag_file_scan(path_fs, print_comment_handler, &client)) { command_error(client, ACK_ERROR_NO_EXIST, "Failed to load file"); return CommandResult::ERROR; diff --git a/src/command/FileCommands.hxx b/src/command/FileCommands.hxx index e184d6e30..8858b62c9 100644 --- a/src/command/FileCommands.hxx +++ b/src/command/FileCommands.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/command/MessageCommands.cxx b/src/command/MessageCommands.cxx index 7d9893e70..fe7500aaf 100644 --- a/src/command/MessageCommands.cxx +++ b/src/command/MessageCommands.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -19,12 +19,11 @@ #include "config.h" #include "MessageCommands.hxx" -#include "Client.hxx" -#include "ClientList.hxx" +#include "client/Client.hxx" +#include "client/ClientList.hxx" #include "Instance.hxx" -#include "Main.hxx" +#include "Partition.hxx" #include "protocol/Result.hxx" -#include "protocol/ArgParser.hxx" #include <set> #include <string> @@ -82,7 +81,7 @@ handle_channels(Client &client, assert(argc == 1); std::set<std::string> channels; - for (const auto &c : *instance->client_list) + for (const auto &c : *client.partition.instance.client_list) channels.insert(c->subscriptions.begin(), c->subscriptions.end()); @@ -123,7 +122,7 @@ handle_send_message(Client &client, bool sent = false; const ClientMessage msg(argv[1], argv[2]); - for (const auto &c : *instance->client_list) + for (const auto &c : *client.partition.instance.client_list) if (c->PushMessage(msg)) sent = true; diff --git a/src/command/MessageCommands.hxx b/src/command/MessageCommands.hxx index 6a107f69d..2edc9e816 100644 --- a/src/command/MessageCommands.hxx +++ b/src/command/MessageCommands.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/command/NeighborCommands.cxx b/src/command/NeighborCommands.cxx new file mode 100644 index 000000000..1171f6424 --- /dev/null +++ b/src/command/NeighborCommands.cxx @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include "NeighborCommands.hxx" +#include "client/Client.hxx" +#include "Instance.hxx" +#include "Partition.hxx" +#include "protocol/Result.hxx" +#include "neighbor/Glue.hxx" +#include "neighbor/Info.hxx" + +#include <set> +#include <string> + +#include <assert.h> + +bool +neighbor_commands_available(const Instance &instance) +{ + return instance.neighbors != nullptr; +} + +CommandResult +handle_listneighbors(Client &client, + gcc_unused int argc, gcc_unused char *argv[]) +{ + const NeighborGlue *const neighbors = + client.partition.instance.neighbors; + if (neighbors == nullptr) { + command_error(client, ACK_ERROR_UNKNOWN, + "No neighbor plugin configured"); + return CommandResult::ERROR; + } + + for (const auto &i : neighbors->GetList()) + client_printf(client, + "neighbor: %s\n" + "name: %s\n", + i.uri.c_str(), + i.display_name.c_str()); + return CommandResult::OK; +} diff --git a/src/command/NeighborCommands.hxx b/src/command/NeighborCommands.hxx new file mode 100644 index 000000000..64a7fe120 --- /dev/null +++ b/src/command/NeighborCommands.hxx @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_NEIGHBOR_COMMANDS_HXX +#define MPD_NEIGHBOR_COMMANDS_HXX + +#include "CommandResult.hxx" +#include "Compiler.h" + +struct Instance; +class Client; + +gcc_pure +bool +neighbor_commands_available(const Instance &instance); + +CommandResult +handle_listneighbors(Client &client, int argc, char *argv[]); + +#endif diff --git a/src/command/OtherCommands.cxx b/src/command/OtherCommands.cxx index 7b2cb1331..9455971e8 100644 --- a/src/command/OtherCommands.cxx +++ b/src/command/OtherCommands.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -19,20 +19,20 @@ #include "config.h" #include "OtherCommands.hxx" -#include "DatabaseCommands.hxx" #include "CommandError.hxx" -#include "UpdateGlue.hxx" -#include "Directory.hxx" -#include "Song.hxx" +#include "db/Uri.hxx" +#include "DetachedSong.hxx" #include "SongPrint.hxx" #include "TagPrint.hxx" +#include "TagStream.hxx" +#include "tag/TagHandler.hxx" #include "TimePrint.hxx" #include "Mapper.hxx" -#include "DecoderPrint.hxx" +#include "decoder/DecoderPrint.hxx" #include "protocol/ArgParser.hxx" #include "protocol/Result.hxx" #include "ls.hxx" -#include "Volume.hxx" +#include "mixer/Volume.hxx" #include "util/ASCII.hxx" #include "util/UriUtil.hxx" #include "util/Error.hxx" @@ -40,12 +40,15 @@ #include "Stats.hxx" #include "Permission.hxx" #include "PlaylistFile.hxx" -#include "ClientFile.hxx" -#include "Client.hxx" +#include "db/PlaylistVector.hxx" +#include "client/Client.hxx" +#include "Partition.hxx" +#include "Instance.hxx" #include "Idle.hxx" -#ifdef ENABLE_SQLITE -#include "StickerDatabase.hxx" +#ifdef ENABLE_DATABASE +#include "DatabaseCommands.hxx" +#include "db/update/Service.hxx" #endif #include <assert.h> @@ -102,6 +105,20 @@ handle_close(gcc_unused Client &client, return CommandResult::FINISH; } +static void +print_tag(TagType type, const char *value, void *ctx) +{ + Client &client = *(Client *)ctx; + + tag_print(client, type, value); +} + +static constexpr tag_handler print_tag_handler = { + nullptr, + print_tag, + nullptr, +}; + CommandResult handle_lsinfo(Client &client, int argc, char *argv[]) { @@ -125,39 +142,61 @@ handle_lsinfo(Client &client, int argc, char *argv[]) } Error error; - if (!client_allow_file(client, path_fs, error)) + if (!client.AllowFile(path_fs, error)) return print_error(client, error); - Song *song = Song::LoadFile(path_utf8, nullptr); - if (song == nullptr) { + DetachedSong song(path_utf8); + if (!song.Update()) { + command_error(client, ACK_ERROR_NO_EXIST, + "No such file"); + return CommandResult::ERROR; + } + + song_print_info(client, song); + return CommandResult::OK; + } + + if (uri_has_scheme(uri)) { + if (!uri_supported_scheme(uri)) { + command_error(client, ACK_ERROR_NO_EXIST, + "unsupported URI scheme"); + return CommandResult::ERROR; + } + + if (!tag_stream_scan(uri, print_tag_handler, &client)) { command_error(client, ACK_ERROR_NO_EXIST, "No such file"); return CommandResult::ERROR; } - song_print_info(client, *song); - song->Free(); return CommandResult::OK; } +#ifdef ENABLE_DATABASE CommandResult result = handle_lsinfo2(client, argc, argv); if (result != CommandResult::OK) return result; +#endif if (isRootDirectory(uri)) { Error error; const auto &list = ListPlaylistFiles(error); print_spl_list(client, list); + } else { +#ifndef ENABLE_DATABASE + command_error(client, ACK_ERROR_NO_EXIST, "No database"); + return CommandResult::ERROR; +#endif } return CommandResult::OK; } -CommandResult -handle_update(Client &client, gcc_unused int argc, char *argv[]) +static CommandResult +handle_update(Client &client, int argc, char *argv[], bool discard) { +#ifdef ENABLE_DATABASE const char *path = ""; - unsigned ret; assert(argc <= 2); if (argc == 2) { @@ -173,7 +212,13 @@ handle_update(Client &client, gcc_unused int argc, char *argv[]) } } - ret = update_enqueue(path, false); + UpdateService *update = client.partition.instance.update; + if (update == nullptr) { + command_error(client, ACK_ERROR_NO_EXIST, "No database"); + return CommandResult::ERROR; + } + + unsigned ret = update->Enqueue(path, discard); if (ret > 0) { client_printf(client, "updating_db: %i\n", ret); return CommandResult::OK; @@ -182,34 +227,27 @@ handle_update(Client &client, gcc_unused int argc, char *argv[]) "already updating"); return CommandResult::ERROR; } +#else + (void)client; + (void)argc; + (void)argv; + (void)discard; + + command_error(client, ACK_ERROR_NO_EXIST, "No database"); + return CommandResult::ERROR; +#endif } CommandResult -handle_rescan(Client &client, gcc_unused int argc, char *argv[]) +handle_update(Client &client, gcc_unused int argc, char *argv[]) { - const char *path = ""; - unsigned ret; - - assert(argc <= 2); - if (argc == 2) { - path = argv[1]; - - if (!uri_safe_local(path)) { - command_error(client, ACK_ERROR_ARG, - "Malformed path"); - return CommandResult::ERROR; - } - } + return handle_update(client, argc, argv, false); +} - ret = update_enqueue(path, true); - if (ret > 0) { - client_printf(client, "updating_db: %i\n", ret); - return CommandResult::OK; - } else { - command_error(client, ACK_ERROR_UPDATE_ALREADY, - "already updating"); - return CommandResult::ERROR; - } +CommandResult +handle_rescan(Client &client, gcc_unused int argc, char *argv[]) +{ + return handle_update(client, argc, argv, true); } CommandResult @@ -226,7 +264,7 @@ handle_setvol(Client &client, gcc_unused int argc, char *argv[]) return CommandResult::ERROR; } - success = volume_level_change(level); + success = volume_level_change(client.partition.outputs, level); if (!success) { command_error(client, ACK_ERROR_SYSTEM, "problems setting volume"); @@ -248,7 +286,7 @@ handle_volume(Client &client, gcc_unused int argc, char *argv[]) return CommandResult::ERROR; } - const int old_volume = volume_level_get(); + const int old_volume = volume_level_get(client.partition.outputs); if (old_volume < 0) { command_error(client, ACK_ERROR_SYSTEM, "No mixer"); return CommandResult::ERROR; @@ -260,7 +298,8 @@ handle_volume(Client &client, gcc_unused int argc, char *argv[]) else if (new_volume > 100) new_volume = 100; - if (new_volume != old_volume && !volume_level_change(new_volume)) { + if (new_volume != old_volume && + !volume_level_change(client.partition.outputs, new_volume)) { command_error(client, ACK_ERROR_SYSTEM, "problems setting volume"); return CommandResult::ERROR; @@ -309,9 +348,11 @@ handle_config(Client &client, return CommandResult::ERROR; } +#ifdef ENABLE_DATABASE const char *path = mapper_get_music_directory_utf8(); if (path != nullptr) client_printf(client, "music_directory: %s\n", path); +#endif return CommandResult::OK; } diff --git a/src/command/OtherCommands.hxx b/src/command/OtherCommands.hxx index 1a0b16ed1..4f54303bd 100644 --- a/src/command/OtherCommands.hxx +++ b/src/command/OtherCommands.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/command/OutputCommands.cxx b/src/command/OutputCommands.cxx index e949448af..03058d7ed 100644 --- a/src/command/OutputCommands.cxx +++ b/src/command/OutputCommands.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -19,24 +19,21 @@ #include "config.h" #include "OutputCommands.hxx" -#include "OutputPrint.hxx" -#include "OutputCommand.hxx" +#include "output/OutputPrint.hxx" +#include "output/OutputCommand.hxx" #include "protocol/Result.hxx" #include "protocol/ArgParser.hxx" - -#include <string.h> +#include "client/Client.hxx" +#include "Partition.hxx" CommandResult handle_enableoutput(Client &client, gcc_unused int argc, char *argv[]) { unsigned device; - bool ret; - if (!check_unsigned(client, &device, argv[1])) return CommandResult::ERROR; - ret = audio_output_enable_index(device); - if (!ret) { + if (!audio_output_enable_index(client.partition.outputs, device)) { command_error(client, ACK_ERROR_NO_EXIST, "No such audio output"); return CommandResult::ERROR; @@ -49,13 +46,10 @@ CommandResult handle_disableoutput(Client &client, gcc_unused int argc, char *argv[]) { unsigned device; - bool ret; - if (!check_unsigned(client, &device, argv[1])) return CommandResult::ERROR; - ret = audio_output_disable_index(device); - if (!ret) { + if (!audio_output_disable_index(client.partition.outputs, device)) { command_error(client, ACK_ERROR_NO_EXIST, "No such audio output"); return CommandResult::ERROR; @@ -71,7 +65,7 @@ handle_toggleoutput(Client &client, gcc_unused int argc, char *argv[]) if (!check_unsigned(client, &device, argv[1])) return CommandResult::ERROR; - if (!audio_output_toggle_index(device)) { + if (!audio_output_toggle_index(client.partition.outputs, device)) { command_error(client, ACK_ERROR_NO_EXIST, "No such audio output"); return CommandResult::ERROR; @@ -84,7 +78,7 @@ CommandResult handle_devices(Client &client, gcc_unused int argc, gcc_unused char *argv[]) { - printAudioDevices(client); + printAudioDevices(client, client.partition.outputs); return CommandResult::OK; } diff --git a/src/command/OutputCommands.hxx b/src/command/OutputCommands.hxx index a5edc22e2..c12c14049 100644 --- a/src/command/OutputCommands.hxx +++ b/src/command/OutputCommands.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/command/PlayerCommands.cxx b/src/command/PlayerCommands.cxx index 12c71dfd4..a4e0ec0a7 100644 --- a/src/command/PlayerCommands.cxx +++ b/src/command/PlayerCommands.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -22,16 +22,19 @@ #include "CommandError.hxx" #include "Playlist.hxx" #include "PlaylistPrint.hxx" -#include "UpdateGlue.hxx" -#include "Client.hxx" -#include "Volume.hxx" -#include "OutputAll.hxx" +#include "client/Client.hxx" +#include "mixer/Volume.hxx" #include "Partition.hxx" +#include "Instance.hxx" #include "protocol/Result.hxx" #include "protocol/ArgParser.hxx" #include "AudioFormat.hxx" #include "ReplayGainConfig.hxx" +#ifdef ENABLE_DATABASE +#include "db/update/Service.hxx" +#endif + #define COMMAND_STATUS_STATE "state" #define COMMAND_STATUS_REPEAT "repeat" #define COMMAND_STATUS_SINGLE "single" @@ -112,7 +115,6 @@ handle_status(Client &client, gcc_unused int argc, gcc_unused char *argv[]) { const char *state = nullptr; - int updateJobId; int song; const auto player_status = client.player_control.GetStatus(); @@ -140,7 +142,7 @@ handle_status(Client &client, COMMAND_STATUS_PLAYLIST_LENGTH ": %i\n" COMMAND_STATUS_MIXRAMPDB ": %f\n" COMMAND_STATUS_STATE ": %s\n", - volume_level_get(), + volume_level_get(client.partition.outputs), playlist.GetRepeat(), playlist.GetRandom(), playlist.GetSingle(), @@ -188,11 +190,17 @@ handle_status(Client &client, } } - if ((updateJobId = isUpdatingDB())) { +#ifdef ENABLE_DATABASE + const UpdateService *update_service = client.partition.instance.update; + unsigned updateJobId = update_service != nullptr + ? update_service->GetId() + : 0; + if (updateJobId != 0) { client_printf(client, COMMAND_STATUS_UPDATING_DB ": %i\n", updateJobId); } +#endif Error error = client.player_control.LockGetError(); if (error.IsDefined()) @@ -277,7 +285,7 @@ handle_random(Client &client, gcc_unused int argc, char *argv[]) return CommandResult::ERROR; client.partition.SetRandom(status); - audio_output_all_set_replay_gain_mode(replay_gain_get_real_mode(client.partition.GetRandom())); + client.partition.outputs.SetReplayGainMode(replay_gain_get_real_mode(client.partition.GetRandom())); return CommandResult::OK; } @@ -379,8 +387,7 @@ handle_replay_gain_mode(Client &client, return CommandResult::ERROR; } - audio_output_all_set_replay_gain_mode(replay_gain_get_real_mode(client.playlist.queue.random)); - + client.partition.outputs.SetReplayGainMode(replay_gain_get_real_mode(client.playlist.queue.random)); return CommandResult::OK; } diff --git a/src/command/PlayerCommands.hxx b/src/command/PlayerCommands.hxx index 8dad0855b..c90fa4548 100644 --- a/src/command/PlayerCommands.hxx +++ b/src/command/PlayerCommands.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/command/PlaylistCommands.cxx b/src/command/PlaylistCommands.cxx index d178fa097..0997cc68d 100644 --- a/src/command/PlaylistCommands.cxx +++ b/src/command/PlaylistCommands.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -19,15 +19,17 @@ #include "config.h" #include "PlaylistCommands.hxx" -#include "DatabasePlaylist.hxx" +#include "db/DatabasePlaylist.hxx" #include "CommandError.hxx" #include "PlaylistPrint.hxx" #include "PlaylistSave.hxx" #include "PlaylistFile.hxx" -#include "PlaylistVector.hxx" -#include "PlaylistQueue.hxx" +#include "db/PlaylistVector.hxx" +#include "SongLoader.hxx" +#include "playlist/PlaylistQueue.hxx" +#include "playlist/Print.hxx" #include "TimePrint.hxx" -#include "Client.hxx" +#include "client/Client.hxx" #include "protocol/ArgParser.hxx" #include "protocol/Result.hxx" #include "ls.hxx" @@ -35,9 +37,6 @@ #include "util/UriUtil.hxx" #include "util/Error.hxx" -#include <assert.h> -#include <stdlib.h> - static void print_spl_list(Client &client, const PlaylistVector &list) { @@ -67,11 +66,12 @@ handle_load(Client &client, int argc, char *argv[]) } else if (!check_range(client, &start_index, &end_index, argv[2])) return CommandResult::ERROR; + const SongLoader loader(client); const PlaylistResult result = playlist_open_into_queue(argv[1], start_index, end_index, client.playlist, - client.player_control, true); + client.player_control, loader); if (result != PlaylistResult::NO_SUCH_LIST) return print_playlist_result(client, result); @@ -188,16 +188,20 @@ handle_playlistadd(Client &client, gcc_unused int argc, char *argv[]) bool success; Error error; if (uri_has_scheme(uri)) { - if (!uri_supported_scheme(uri)) { - command_error(client, ACK_ERROR_NO_EXIST, - "unsupported URI scheme"); - return CommandResult::ERROR; - } - - success = spl_append_uri(uri, playlist, error); - } else - success = search_add_to_playlist(uri, playlist, nullptr, + const SongLoader loader(client); + success = spl_append_uri(playlist, loader, uri, error); + } else { +#ifdef ENABLE_DATABASE + const Database *db = client.GetDatabase(error); + if (db == nullptr) + return print_error(client, error); + + success = search_add_to_playlist(*db, uri, playlist, nullptr, error); +#else + success = false; +#endif + } if (!success && !error.IsDefined()) { command_error(client, ACK_ERROR_NO_EXIST, diff --git a/src/command/PlaylistCommands.hxx b/src/command/PlaylistCommands.hxx index 802d6ff2f..c737c54eb 100644 --- a/src/command/PlaylistCommands.hxx +++ b/src/command/PlaylistCommands.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/command/QueueCommands.cxx b/src/command/QueueCommands.cxx index a21eb75f0..f14beb872 100644 --- a/src/command/QueueCommands.cxx +++ b/src/command/QueueCommands.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -20,13 +20,13 @@ #include "config.h" #include "QueueCommands.hxx" #include "CommandError.hxx" -#include "DatabaseQueue.hxx" +#include "db/DatabaseQueue.hxx" +#include "db/Selection.hxx" #include "SongFilter.hxx" -#include "DatabaseSelection.hxx" +#include "SongLoader.hxx" #include "Playlist.hxx" #include "PlaylistPrint.hxx" -#include "ClientFile.hxx" -#include "Client.hxx" +#include "client/Client.hxx" #include "Partition.hxx" #include "protocol/ArgParser.hxx" #include "protocol/Result.hxx" @@ -39,79 +39,58 @@ #include <string.h> -CommandResult -handle_add(Client &client, gcc_unused int argc, char *argv[]) +static const char * +translate_uri(Client &client, const char *uri) { - char *uri = argv[1]; - PlaylistResult result; - - if (memcmp(uri, "file:///", 8) == 0) { - const char *path_utf8 = uri + 7; - const auto path_fs = AllocatedPath::FromUTF8(path_utf8); - - if (path_fs.IsNull()) { - command_error(client, ACK_ERROR_NO_EXIST, - "unsupported file name"); - return CommandResult::ERROR; - } - - Error error; - if (!client_allow_file(client, path_fs, error)) - return print_error(client, error); - - result = client.partition.AppendFile(path_utf8); - return print_playlist_result(client, result); + if (memcmp(uri, "file:///", 8) == 0) + /* drop the "file://", leave only an absolute path + (starting with a slash) */ + return uri + 7; + + if (PathTraitsUTF8::IsAbsolute(uri)) { + command_error(client, ACK_ERROR_NO_EXIST, "Malformed URI"); + return nullptr; } - if (uri_has_scheme(uri)) { - if (!uri_supported_scheme(uri)) { - command_error(client, ACK_ERROR_NO_EXIST, - "unsupported URI scheme"); - return CommandResult::ERROR; - } + return uri; +} - result = client.partition.AppendURI(uri); +CommandResult +handle_add(Client &client, gcc_unused int argc, char *argv[]) +{ + const char *const uri = translate_uri(client, argv[1]); + if (uri == nullptr) + return CommandResult::ERROR; + + if (uri_has_scheme(uri) || PathTraitsUTF8::IsAbsolute(uri)) { + const SongLoader loader(client); + auto result = client.partition.AppendURI(loader, uri); return print_playlist_result(client, result); } +#ifdef ENABLE_DATABASE const DatabaseSelection selection(uri, true); Error error; return AddFromDatabase(client.partition, selection, error) ? CommandResult::OK : print_error(client, error); +#else + command_error(client, ACK_ERROR_NO_EXIST, "No database"); + return CommandResult::ERROR; +#endif } CommandResult handle_addid(Client &client, int argc, char *argv[]) { - char *uri = argv[1]; - unsigned added_id; - PlaylistResult result; - - if (memcmp(uri, "file:///", 8) == 0) { - const char *path_utf8 = uri + 7; - const auto path_fs = AllocatedPath::FromUTF8(path_utf8); - - if (path_fs.IsNull()) { - command_error(client, ACK_ERROR_NO_EXIST, - "unsupported file name"); - return CommandResult::ERROR; - } + const char *const uri = translate_uri(client, argv[1]); + if (uri == nullptr) + return CommandResult::ERROR; - Error error; - if (!client_allow_file(client, path_fs, error)) - return print_error(client, error); + const SongLoader loader(client); - result = client.partition.AppendFile(path_utf8, &added_id); - } else { - if (uri_has_scheme(uri) && !uri_supported_scheme(uri)) { - command_error(client, ACK_ERROR_NO_EXIST, - "unsupported URI scheme"); - return CommandResult::ERROR; - } - - result = client.partition.AppendURI(uri, &added_id); - } + unsigned added_id; + auto result = client.partition.AppendURI(loader, uri, &added_id); if (result != PlaylistResult::SUCCESS) return print_playlist_result(client, result); diff --git a/src/command/QueueCommands.hxx b/src/command/QueueCommands.hxx index 90d744447..af5413d8c 100644 --- a/src/command/QueueCommands.hxx +++ b/src/command/QueueCommands.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/command/StickerCommands.cxx b/src/command/StickerCommands.cxx index b65e6f607..bf3660b85 100644 --- a/src/command/StickerCommands.cxx +++ b/src/command/StickerCommands.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -20,19 +20,19 @@ #include "config.h" #include "StickerCommands.hxx" #include "SongPrint.hxx" -#include "DatabaseLock.hxx" -#include "DatabasePlugin.hxx" -#include "DatabaseGlue.hxx" -#include "DatabaseSimple.hxx" -#include "SongSticker.hxx" -#include "StickerPrint.hxx" -#include "StickerDatabase.hxx" +#include "db/DatabaseLock.hxx" +#include "db/DatabasePlugin.hxx" +#include "db/DatabaseGlue.hxx" +#include "sticker/SongSticker.hxx" +#include "sticker/StickerPrint.hxx" +#include "sticker/StickerDatabase.hxx" #include "CommandError.hxx" #include "protocol/Result.hxx" +#include "client/Client.hxx" +#include "Partition.hxx" +#include "Instance.hxx" #include "util/Error.hxx" -#include <glib.h> - #include <string.h> struct sticker_song_find_data { @@ -41,7 +41,7 @@ struct sticker_song_find_data { }; static void -sticker_song_find_print_cb(Song &song, const char *value, +sticker_song_find_print_cb(const LightSong &song, const char *value, void *user_data) { struct sticker_song_find_data *data = @@ -55,17 +55,17 @@ static CommandResult handle_sticker_song(Client &client, int argc, char *argv[]) { Error error; - const Database *db = GetDatabase(error); + const Database *db = client.GetDatabase(error); if (db == nullptr) return print_error(client, error); /* get song song_id key */ if (argc == 5 && strcmp(argv[1], "get") == 0) { - Song *song = db->GetSong(argv[3], error); + const LightSong *song = db->GetSong(argv[3], error); if (song == nullptr) return print_error(client, error); - const auto value = sticker_song_get_value(song, argv[4]); + const auto value = sticker_song_get_value(*song, argv[4]); db->ReturnSong(song); if (value.empty()) { command_error(client, ACK_ERROR_NO_EXIST, @@ -78,11 +78,11 @@ handle_sticker_song(Client &client, int argc, char *argv[]) return CommandResult::OK; /* list song song_id */ } else if (argc == 4 && strcmp(argv[1], "list") == 0) { - Song *song = db->GetSong(argv[3], error); + const LightSong *song = db->GetSong(argv[3], error); if (song == nullptr) return print_error(client, error); - sticker *sticker = sticker_song_get(song); + sticker *sticker = sticker_song_get(*song); db->ReturnSong(song); if (sticker) { sticker_print(client, *sticker); @@ -92,11 +92,11 @@ handle_sticker_song(Client &client, int argc, char *argv[]) return CommandResult::OK; /* set song song_id id key */ } else if (argc == 6 && strcmp(argv[1], "set") == 0) { - Song *song = db->GetSong(argv[3], error); + const LightSong *song = db->GetSong(argv[3], error); if (song == nullptr) return print_error(client, error); - bool ret = sticker_song_set_value(song, argv[4], argv[5]); + bool ret = sticker_song_set_value(*song, argv[4], argv[5]); db->ReturnSong(song); if (!ret) { command_error(client, ACK_ERROR_SYSTEM, @@ -108,13 +108,13 @@ handle_sticker_song(Client &client, int argc, char *argv[]) /* delete song song_id [key] */ } else if ((argc == 4 || argc == 5) && strcmp(argv[1], "delete") == 0) { - Song *song = db->GetSong(argv[3], error); + const LightSong *song = db->GetSong(argv[3], error); if (song == nullptr) return print_error(client, error); bool ret = argc == 4 - ? sticker_song_delete(song) - : sticker_song_delete_value(song, argv[4]); + ? sticker_song_delete(*song) + : sticker_song_delete_value(*song, argv[4]); db->ReturnSong(song); if (!ret) { command_error(client, ACK_ERROR_SYSTEM, @@ -126,24 +126,17 @@ handle_sticker_song(Client &client, int argc, char *argv[]) /* find song dir key */ } else if (argc == 5 && strcmp(argv[1], "find") == 0) { /* "sticker find song a/directory name" */ + + const char *const base_uri = argv[3]; + bool success; struct sticker_song_find_data data = { client, argv[4], }; - db_lock(); - Directory *directory = db_get_directory(argv[3]); - if (directory == nullptr) { - db_unlock(); - command_error(client, ACK_ERROR_NO_EXIST, - "no such directory"); - return CommandResult::ERROR; - } - - success = sticker_song_find(*directory, data.name, + success = sticker_song_find(*db, base_uri, data.name, sticker_song_find_print_cb, &data); - db_unlock(); if (!success) { command_error(client, ACK_ERROR_SYSTEM, "failed to set search sticker database"); diff --git a/src/command/StickerCommands.hxx b/src/command/StickerCommands.hxx index 9e4380f37..ab8ac0db1 100644 --- a/src/command/StickerCommands.hxx +++ b/src/command/StickerCommands.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/command/TagCommands.cxx b/src/command/TagCommands.cxx new file mode 100644 index 000000000..02e95af71 --- /dev/null +++ b/src/command/TagCommands.cxx @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include "TagCommands.hxx" +#include "CommandError.hxx" +#include "client/Client.hxx" +#include "protocol/ArgParser.hxx" +#include "protocol/Result.hxx" +#include "tag/Tag.hxx" +#include "Partition.hxx" + +CommandResult +handle_addtagid(Client &client, gcc_unused int argc, char *argv[]) +{ + unsigned song_id; + if (!check_unsigned(client, &song_id, argv[1])) + return CommandResult::ERROR; + + const char *const tag_name = argv[2]; + const TagType tag_type = tag_name_parse_i(tag_name); + if (tag_type == TAG_NUM_OF_ITEM_TYPES) { + command_error(client, ACK_ERROR_ARG, + "Unknown tag type: %s", tag_name); + return CommandResult::ERROR; + } + + const char *const value = argv[3]; + + Error error; + if (!client.partition.playlist.AddSongIdTag(song_id, tag_type, value, + error)) + return print_error(client, error); + + return CommandResult::OK; +} + +CommandResult +handle_cleartagid(Client &client, int argc, char *argv[]) +{ + unsigned song_id; + if (!check_unsigned(client, &song_id, argv[1])) + return CommandResult::ERROR; + + TagType tag_type = TAG_NUM_OF_ITEM_TYPES; + if (argc >= 3) { + const char *const tag_name = argv[2]; + tag_type = tag_name_parse_i(tag_name); + if (tag_type == TAG_NUM_OF_ITEM_TYPES) { + command_error(client, ACK_ERROR_ARG, + "Unknown tag type: %s", tag_name); + return CommandResult::ERROR; + } + } + + Error error; + if (!client.partition.playlist.ClearSongIdTag(song_id, tag_type, + error)) + return print_error(client, error); + + return CommandResult::OK; +} diff --git a/src/command/TagCommands.hxx b/src/command/TagCommands.hxx new file mode 100644 index 000000000..b54ddb178 --- /dev/null +++ b/src/command/TagCommands.hxx @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_TAG_COMMANDS_HXX +#define MPD_TAG_COMMANDS_HXX + +#include "CommandResult.hxx" + +class Client; + +CommandResult +handle_addtagid(Client &client, int argc, char *argv[]); + +CommandResult +handle_cleartagid(Client &client, int argc, char *argv[]); + +#endif |