diff options
author | Max Kellermann <max@duempel.org> | 2009-01-19 19:09:49 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2009-01-19 19:09:49 +0100 |
commit | f9c693e602231e77eee94580addf60eff095b2de (patch) | |
tree | a7179381c68640f730f82b410f96a6ac54e1009b | |
parent | 2934585d5ae3d7b74e4bec099711d6e75271cc35 (diff) | |
download | mpd-f9c693e602231e77eee94580addf60eff095b2de.tar.gz mpd-f9c693e602231e77eee94580addf60eff095b2de.tar.xz mpd-f9c693e602231e77eee94580addf60eff095b2de.zip |
command: added "sticker" command
The "sticker" command allows clients to query or manipulate the
sticker database. This patch implements the sub-commands "get" and
"set"; more will follow soon (enumeration), as well as extended
"lsinfo" / "playlistinfo" versions.
-rw-r--r-- | doc/protocol.xml | 67 | ||||
-rw-r--r-- | src/command.c | 72 |
2 files changed, 139 insertions, 0 deletions
diff --git a/doc/protocol.xml b/doc/protocol.xml index ff5d4838f..36ee3c35d 100644 --- a/doc/protocol.xml +++ b/doc/protocol.xml @@ -1156,6 +1156,73 @@ OK </section> <section> + <title>Stickers</title> + + <para> + "Stickers" are pieces of information attached to existing MPD + objects (e.g. song files, directories, albums). Clients can + create arbitrary name/value pairs. MPD itself does not assume + any special meaning in them. + </para> + + <para> + The goal is to allow clients to share additional (possibly + dynamic) information about songs, which is neither stored on + the client (not available to other clients), nor stored in the + song files (MPD has no write access). + </para> + + <para> + Client developers should create a standard for common sticker + names, to ensure interoperability. + </para> + + <para> + Objects which may have stickers are addressed by their object + type ("song" for song objects) and their URI (the path within + the database for songs). + </para> + + <variablelist> + <varlistentry id="command_sticker_get"> + <term> + <cmdsynopsis> + <command>sticker</command> + <arg choice="plain">get</arg> + <arg choice="req"><replaceable>TYPE</replaceable></arg> + <arg choice="req"><replaceable>URI</replaceable></arg> + <arg choice="req"><replaceable>NAME</replaceable></arg> + </cmdsynopsis> + </term> + <listitem> + <para> + Reads a sticker value for the specified object. + </para> + </listitem> + </varlistentry> + <varlistentry id="command_sticker_set"> + <term> + <cmdsynopsis> + <command>sticker</command> + <arg choice="plain">set</arg> + <arg choice="req"><replaceable>TYPE</replaceable></arg> + <arg choice="req"><replaceable>URI</replaceable></arg> + <arg choice="req"><replaceable>NAME</replaceable></arg> + <arg choice="req"><replaceable>VALUE</replaceable></arg> + </cmdsynopsis> + </term> + <listitem> + <para> + Adds a sticker value to the specified object. If a + sticker item with that name already exists, it is + replaced. + </para> + </listitem> + </varlistentry> + </variablelist> + </section> + + <section> <title>Connection settings</title> <variablelist> diff --git a/src/command.c b/src/command.c index dbc7bdb99..6e8dc9fc0 100644 --- a/src/command.c +++ b/src/command.c @@ -40,6 +40,11 @@ #include "idle.h" #include "config.h" +#ifdef ENABLE_SQLITE +#include "sticker.h" +#include "song_sticker.h" +#endif + #include <assert.h> #include <time.h> #include <stdlib.h> @@ -1403,6 +1408,70 @@ handle_idle(struct client *client, return 1; } +#ifdef ENABLE_SQLITE +static enum command_return +handle_sticker_song(struct client *client, int argc, char *argv[]) +{ + struct song *song = db_get_song(argv[3]); + + if (song == NULL) { + command_error(client, ACK_ERROR_NO_EXIST, + "no such song"); + return COMMAND_RETURN_ERROR; + } + + if (argc == 5 && strcmp(argv[1], "get") == 0) { + char *value; + + value = sticker_song_get_value(song, argv[4]); + if (value == NULL) { + command_error(client, ACK_ERROR_NO_EXIST, + "no such sticker"); + return COMMAND_RETURN_ERROR; + } + + client_printf(client, "sticker:%s=%s\n", argv[4], value); + g_free(value); + + return COMMAND_RETURN_OK; + } else if (argc == 6 && strcmp(argv[1], "set") == 0) { + bool ret; + + ret = sticker_song_set_value(song, argv[4], argv[5]); + if (!ret) { + command_error(client, ACK_ERROR_SYSTEM, + "failed to set sticker vqalue"); + return COMMAND_RETURN_ERROR; + } + + return COMMAND_RETURN_OK; + } else { + command_error(client, ACK_ERROR_ARG, "bad request"); + return COMMAND_RETURN_ERROR; + } +} + +static enum command_return +handle_sticker(struct client *client, int argc, char *argv[]) +{ + assert(argc >= 4); + + if (!sticker_enabled()) { + command_error(client, ACK_ERROR_UNKNOWN, + "sticker database is disabled"); + return COMMAND_RETURN_ERROR; + } + + if (strcmp(argv[2], "song") == 0) + return handle_sticker_song(client, argc, argv); + else { + command_error(client, ACK_ERROR_ARG, + "unknown sticker domain"); + return COMMAND_RETURN_ERROR; + } +} +#endif + /** * The command registry. * @@ -1467,6 +1536,9 @@ static const struct command commands[] = { { "shuffle", PERMISSION_CONTROL, 0, 0, handle_shuffle }, { "stats", PERMISSION_READ, 0, 0, handle_stats }, { "status", PERMISSION_READ, 0, 0, handle_status }, +#ifdef ENABLE_SQLITE + { "sticker", PERMISSION_ADMIN, 3, -1, handle_sticker }, +#endif { "stop", PERMISSION_CONTROL, 0, 0, handle_stop }, { "swap", PERMISSION_CONTROL, 2, 2, handle_swap }, { "swapid", PERMISSION_CONTROL, 2, 2, handle_swapid }, |