StickerCommands.cxx 4.62 KB
Newer Older
1
/*
Max Kellermann's avatar
Max Kellermann committed
2
 * Copyright (C) 2003-2014 The Music Player Daemon Project
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
 * 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 "StickerCommands.hxx"
Max Kellermann's avatar
Max Kellermann committed
22
#include "SongPrint.hxx"
23
#include "db/Interface.hxx"
Max Kellermann's avatar
Max Kellermann committed
24
#include "db/DatabaseGlue.hxx"
25 26 27
#include "sticker/SongSticker.hxx"
#include "sticker/StickerPrint.hxx"
#include "sticker/StickerDatabase.hxx"
28
#include "CommandError.hxx"
Max Kellermann's avatar
Max Kellermann committed
29
#include "protocol/Result.hxx"
30 31 32
#include "client/Client.hxx"
#include "Partition.hxx"
#include "Instance.hxx"
33 34
#include "util/Error.hxx"

35 36 37
#include <string.h>

struct sticker_song_find_data {
38
	Client &client;
39 40 41 42
	const char *name;
};

static void
43
sticker_song_find_print_cb(const LightSong &song, const char *value,
44
			   void *user_data)
45 46 47 48 49 50 51 52
{
	struct sticker_song_find_data *data =
		(struct sticker_song_find_data *)user_data;

	song_print_uri(data->client, song);
	sticker_print_value(data->client, data->name, value);
}

53
static CommandResult
54
handle_sticker_song(Client &client, int argc, char *argv[])
55
{
56
	Error error;
57
	const Database *db = client.GetDatabase(error);
58 59 60
	if (db == nullptr)
		return print_error(client, error);

61 62
	/* get song song_id key */
	if (argc == 5 && strcmp(argv[1], "get") == 0) {
63
		const LightSong *song = db->GetSong(argv[3], error);
64 65
		if (song == nullptr)
			return print_error(client, error);
66

67
		const auto value = sticker_song_get_value(*song, argv[4]);
68
		db->ReturnSong(song);
69
		if (value.empty()) {
70 71
			command_error(client, ACK_ERROR_NO_EXIST,
				      "no such sticker");
72
			return CommandResult::ERROR;
73 74
		}

75
		sticker_print_value(client, argv[4], value.c_str());
76

77
		return CommandResult::OK;
78 79
	/* list song song_id */
	} else if (argc == 4 && strcmp(argv[1], "list") == 0) {
80
		const LightSong *song = db->GetSong(argv[3], error);
81 82
		if (song == nullptr)
			return print_error(client, error);
83

84
		sticker *sticker = sticker_song_get(*song);
85
		db->ReturnSong(song);
86
		if (sticker) {
87
			sticker_print(client, *sticker);
88 89 90
			sticker_free(sticker);
		}

91
		return CommandResult::OK;
92 93
	/* set song song_id id key */
	} else if (argc == 6 && strcmp(argv[1], "set") == 0) {
94
		const LightSong *song = db->GetSong(argv[3], error);
95 96
		if (song == nullptr)
			return print_error(client, error);
97

98
		bool ret = sticker_song_set_value(*song, argv[4], argv[5]);
99
		db->ReturnSong(song);
100 101 102
		if (!ret) {
			command_error(client, ACK_ERROR_SYSTEM,
				      "failed to set sticker value");
103
			return CommandResult::ERROR;
104 105
		}

106
		return CommandResult::OK;
107 108 109
	/* delete song song_id [key] */
	} else if ((argc == 4 || argc == 5) &&
		   strcmp(argv[1], "delete") == 0) {
110
		const LightSong *song = db->GetSong(argv[3], error);
111 112
		if (song == nullptr)
			return print_error(client, error);
113

114
		bool ret = argc == 4
115 116
			? sticker_song_delete(*song)
			: sticker_song_delete_value(*song, argv[4]);
117
		db->ReturnSong(song);
118 119 120
		if (!ret) {
			command_error(client, ACK_ERROR_SYSTEM,
				      "no such sticker");
121
			return CommandResult::ERROR;
122 123
		}

124
		return CommandResult::OK;
125 126 127
	/* find song dir key */
	} else if (argc == 5 && strcmp(argv[1], "find") == 0) {
		/* "sticker find song a/directory name" */
128 129 130

		const char *const base_uri = argv[3];

131 132 133 134 135 136
		bool success;
		struct sticker_song_find_data data = {
			client,
			argv[4],
		};

137
		success = sticker_song_find(*db, base_uri, data.name,
138 139 140 141
					    sticker_song_find_print_cb, &data);
		if (!success) {
			command_error(client, ACK_ERROR_SYSTEM,
				      "failed to set search sticker database");
142
			return CommandResult::ERROR;
143 144
		}

145
		return CommandResult::OK;
146 147
	} else {
		command_error(client, ACK_ERROR_ARG, "bad request");
148
		return CommandResult::ERROR;
149 150 151
	}
}

152
CommandResult
153
handle_sticker(Client &client, int argc, char *argv[])
154 155 156 157 158 159
{
	assert(argc >= 4);

	if (!sticker_enabled()) {
		command_error(client, ACK_ERROR_UNKNOWN,
			      "sticker database is disabled");
160
		return CommandResult::ERROR;
161 162 163 164 165 166 167
	}

	if (strcmp(argv[2], "song") == 0)
		return handle_sticker_song(client, argc, argv);
	else {
		command_error(client, ACK_ERROR_ARG,
			      "unknown sticker domain");
168
		return CommandResult::ERROR;
169 170
	}
}