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.
This commit is contained in:
Max Kellermann 2009-01-19 19:09:49 +01:00
parent 2934585d5a
commit f9c693e602
2 changed files with 139 additions and 0 deletions

View File

@ -1155,6 +1155,73 @@ OK
</variablelist> </variablelist>
</section> </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> <section>
<title>Connection settings</title> <title>Connection settings</title>

View File

@ -40,6 +40,11 @@
#include "idle.h" #include "idle.h"
#include "config.h" #include "config.h"
#ifdef ENABLE_SQLITE
#include "sticker.h"
#include "song_sticker.h"
#endif
#include <assert.h> #include <assert.h>
#include <time.h> #include <time.h>
#include <stdlib.h> #include <stdlib.h>
@ -1403,6 +1408,70 @@ handle_idle(struct client *client,
return 1; 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. * The command registry.
* *
@ -1467,6 +1536,9 @@ static const struct command commands[] = {
{ "shuffle", PERMISSION_CONTROL, 0, 0, handle_shuffle }, { "shuffle", PERMISSION_CONTROL, 0, 0, handle_shuffle },
{ "stats", PERMISSION_READ, 0, 0, handle_stats }, { "stats", PERMISSION_READ, 0, 0, handle_stats },
{ "status", PERMISSION_READ, 0, 0, handle_status }, { "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 }, { "stop", PERMISSION_CONTROL, 0, 0, handle_stop },
{ "swap", PERMISSION_CONTROL, 2, 2, handle_swap }, { "swap", PERMISSION_CONTROL, 2, 2, handle_swap },
{ "swapid", PERMISSION_CONTROL, 2, 2, handle_swapid }, { "swapid", PERMISSION_CONTROL, 2, 2, handle_swapid },