Commit | Line | Data |
---|---|---|
200adb00 RK |
1 | #! /usr/bin/perl -w |
2 | # | |
3 | # This file is part of DisOrder. | |
4 | # Copyright (C) 2010 Richard Kettlewell | |
5 | # | |
6 | # This program is free software: you can redistribute it and/or modify | |
7 | # it under the terms of the GNU General Public License as published by | |
8 | # the Free Software Foundation, either version 3 of the License, or | |
9 | # (at your option) any later version. | |
10 | # | |
11 | # This program is distributed in the hope that it will be useful, | |
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | # GNU General Public License for more details. | |
15 | # | |
16 | # You should have received a copy of the GNU General Public License | |
17 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
18 | # | |
19 | use strict; | |
20 | ||
21 | # Variables and utilities ----------------------------------------------------- | |
22 | ||
23 | our @h = (); | |
24 | our @c = (); | |
25 | ||
26 | sub Write { | |
27 | my $path = shift; | |
28 | my $lines = shift; | |
29 | ||
30 | (open(F, ">$path") | |
31 | and print F @$lines | |
32 | and close F) | |
7788b7c7 | 33 | or die "$0: $path: $!\n"; |
200adb00 RK |
34 | } |
35 | ||
36 | # Command classes ------------------------------------------------------------- | |
37 | ||
96b1cf08 | 38 | # simple(CMD, SUMMARY, DETAIL, [[NAME,DESCR], [NAME,DESCR], ...],) |
200adb00 RK |
39 | # |
40 | # Response is simply success/failure | |
96b1cf08 | 41 | sub simple { |
200adb00 RK |
42 | my $cmd = shift; |
43 | my $summary = shift; | |
44 | my $detail = shift; | |
45 | my $args = shift; | |
46 | ||
47 | my $cmdc = $cmd; | |
48 | $cmdc =~ s/-/_/g; | |
49 | # Synchronous C API | |
50 | push(@h, "/** \@brief $summary\n", | |
7788b7c7 RK |
51 | " *\n", |
52 | " * $detail\n", | |
53 | " *\n", | |
54 | map(" * \@param $_->[0] $_->[1]\n", @$args), | |
55 | " * \@return 0 on success, non-0 on error\n", | |
56 | " */\n", | |
57 | "int disorder_$cmdc(disorder_client *c", | |
58 | map(", const char *$_->[0]", @$args), ");\n", | |
59 | "\n"); | |
200adb00 | 60 | push(@c, "int disorder_$cmdc(disorder_client *c", |
7788b7c7 RK |
61 | map(", const char *$_->[0]", @$args), ") {\n", |
62 | " return disorder_simple(c, 0, \"$cmd\"", | |
63 | map(", $_->[0]", @$args), | |
64 | ", (char *)0);\n", | |
65 | "}\n\n"); | |
66 | ||
67 | # Asynchronous C API | |
68 | # TODO | |
69 | ||
70 | # Python API | |
71 | # TODO | |
72 | ||
73 | # Java API | |
74 | # TODO | |
75 | } | |
76 | ||
77 | # string(CMD, SUMMARY, DETAIL, [[NAME,DESCR], [NAME,DESCR], ...], [RETURN, DESCR]) | |
78 | # | |
3680ef53 | 79 | # Response is a string, or failure, or 555 for "none". |
7788b7c7 RK |
80 | sub string { |
81 | my $cmd = shift; | |
82 | my $summary = shift; | |
83 | my $detail = shift; | |
84 | my $args = shift; | |
85 | my $return = shift; | |
86 | ||
87 | my $cmdc = $cmd; | |
88 | $cmdc =~ s/-/_/g; | |
89 | # Synchronous C API | |
90 | push(@h, "/** \@brief $summary\n", | |
91 | " *\n", | |
92 | " * $detail\n", | |
93 | " *\n", | |
94 | map(" * \@param $_->[0] $_->[1]\n", @$args), | |
95 | " * \@param $return->[0]p $return->[1]\n", | |
96 | " * \@return 0 on success, non-0 on error\n", | |
97 | " */\n", | |
98 | "int disorder_$cmdc(disorder_client *c", | |
99 | map(", const char *$_->[0]", @$args), | |
100 | ", char **$return->[0]p);\n", | |
101 | "\n"); | |
102 | push(@c, "int disorder_$cmdc(disorder_client *c", | |
103 | map(", const char *$_->[0]", @$args), | |
104 | ", char **$return->[0]p) {\n", | |
105 | " return dequote(disorder_simple(c, $return->[0]p, \"$cmd\"", | |
106 | map(", $_->[0]", @$args), | |
107 | ", (char *)0), $return->[0]p);\n", | |
108 | "}\n\n"); | |
109 | ||
110 | # Asynchronous C API | |
111 | # TODO | |
112 | ||
113 | # Python API | |
114 | # TODO | |
115 | ||
116 | # Java API | |
117 | # TODO | |
118 | } | |
119 | ||
3680ef53 | 120 | # string_login(CMD, SUMMARY, DETAIL, [[NAME,DESCR], [NAME,DESCR], ...]) |
7788b7c7 | 121 | # |
3680ef53 RK |
122 | # Like string(), but the server returns a username, which we squirrel |
123 | # away rather than returning to the caller. | |
7788b7c7 RK |
124 | sub string_login { |
125 | my $cmd = shift; | |
126 | my $summary = shift; | |
127 | my $detail = shift; | |
128 | my $args = shift; | |
129 | my $return = shift; | |
130 | ||
131 | my $cmdc = $cmd; | |
132 | $cmdc =~ s/-/_/g; | |
133 | # Synchronous C API | |
134 | push(@h, "/** \@brief $summary\n", | |
135 | " *\n", | |
136 | " * $detail\n", | |
137 | " *\n", | |
138 | map(" * \@param $_->[0] $_->[1]\n", @$args), | |
139 | " * \@return 0 on success, non-0 on error\n", | |
140 | " */\n", | |
141 | "int disorder_$cmdc(disorder_client *c", | |
142 | map(", const char *$_->[0]", @$args), | |
143 | ");\n"); | |
144 | push(@c, "int disorder_$cmdc(disorder_client *c", | |
145 | map(", const char *$_->[0]", @$args), | |
146 | ") {\n", | |
147 | " char *u;\n", | |
148 | " int rc;\n", | |
149 | " if((rc = disorder_simple(c, &u, \"$cmd\"", | |
150 | map(", $_->[0]", @$args), | |
151 | " )))\n", | |
152 | " return rc;\n", | |
153 | " c->user = u;\n", | |
154 | " return 0;\n", | |
155 | "}\n\n"); | |
200adb00 RK |
156 | |
157 | # Asynchronous C API | |
158 | # TODO | |
159 | ||
160 | # Python API | |
161 | # TODO | |
162 | ||
163 | # Java API | |
164 | # TODO | |
165 | } | |
166 | ||
96b1cf08 RK |
167 | # boolean(CMD, SUMMARY, DETAIL, [[NAME,DESCR], [NAME,DESCR], ...], [RETURN, DESCR]) |
168 | # | |
169 | # Response is yes/no or failure | |
170 | sub boolean { | |
171 | my $cmd = shift; | |
172 | my $summary = shift; | |
173 | my $detail = shift; | |
174 | my $args = shift; | |
175 | my $return = shift; | |
176 | ||
177 | my $cmdc = $cmd; | |
178 | $cmdc =~ s/-/_/g; | |
179 | # Synchronous C API | |
180 | push(@h, "/** \@brief $summary\n", | |
7788b7c7 RK |
181 | " *\n", |
182 | " * $detail\n", | |
183 | " *\n", | |
184 | map(" * \@param $_->[0] $_->[1]\n", @$args), | |
185 | " * \@param $return->[0]p $return->[1]\n", | |
186 | " * \@return 0 on success, non-0 on error\n", | |
187 | " */\n", | |
188 | "int disorder_$cmdc(disorder_client *c", | |
189 | map(", const char *$_->[0]", @$args), | |
190 | ", int *$return->[0]p);\n", | |
191 | "\n"); | |
96b1cf08 | 192 | push(@c, "int disorder_$cmdc(disorder_client *c", |
7788b7c7 RK |
193 | map(", const char *$_->[0]", @$args), |
194 | ", int *$return->[0]p) {\n", | |
195 | " char *v;\n", | |
196 | " int rc;\n", | |
197 | " if((rc = disorder_simple(c, &v, \"$cmd\"", | |
198 | map(", $_->[0]", @$args), | |
199 | ", (char *)0)))\n", | |
200 | " return rc;\n", | |
201 | " return boolean(\"$cmd\", v, $return->[0]p);\n", | |
202 | "}\n\n"); | |
96b1cf08 RK |
203 | |
204 | # Asynchronous C API | |
205 | # TODO | |
206 | ||
207 | # Python API | |
208 | # TODO | |
209 | ||
210 | # Java API | |
211 | # TODO | |
212 | } | |
213 | ||
3680ef53 RK |
214 | # list(CMD, SUMMARY, DETAIL, [[NAME,DESCR], [NAME,DESCR], ...], [RETURN, DESCR]) |
215 | # | |
216 | # Response is a a list of strings in a dot-stuffed body | |
217 | sub list { | |
218 | my $cmd = shift; | |
219 | my $summary = shift; | |
220 | my $detail = shift; | |
221 | my $args = shift; | |
222 | my $return = shift; | |
223 | ||
224 | my $cmdc = $cmd; | |
225 | $cmdc =~ s/-/_/g; | |
226 | # Synchronous C API | |
227 | push(@h, "/** \@brief $summary\n", | |
228 | " *\n", | |
229 | " * $detail\n", | |
230 | " *\n", | |
231 | map(" * \@param $_->[0] $_->[1]\n", @$args), | |
232 | " * \@param $return->[0]p $return->[1]\n", | |
233 | " * \@param n$return->[0]p Number of elements in $return->[0]p\n", | |
234 | " * \@return 0 on success, non-0 on error\n", | |
235 | " */\n", | |
236 | "int disorder_$cmdc(disorder_client *c", | |
237 | map(", const char *$_->[0]", @$args), | |
238 | ", char ***$return->[0]p, int *n$return->[0]p);\n", | |
239 | "\n"); | |
240 | push(@c, "int disorder_$cmdc(disorder_client *c", | |
241 | map(", const char *$_->[0]", @$args), | |
242 | ", char ***$return->[0]p, int *n$return->[0]p) {\n", | |
243 | " return disorder_simple_list(c, $return->[0]p, n$return->[0]p, \"$cmd\"", | |
244 | map(", $_->[0]", @$args), | |
245 | ", (char *)0);\n", | |
246 | "}\n\n"); | |
247 | ||
248 | # Asynchronous C API | |
249 | # TODO | |
250 | ||
251 | # Python API | |
252 | # TODO | |
253 | ||
254 | # Java API | |
255 | # TODO | |
256 | } | |
257 | ||
200adb00 RK |
258 | # TODO other command classes |
259 | ||
260 | # Front matter ---------------------------------------------------------------- | |
261 | ||
262 | our @gpl = ("/*\n", | |
7788b7c7 RK |
263 | " * This file is part of DisOrder.\n", |
264 | " * Copyright (C) 2010 Richard Kettlewell\n", | |
265 | " *\n", | |
266 | " * This program is free software: you can redistribute it and/or modify\n", | |
267 | " * it under the terms of the GNU General Public License as published by\n", | |
268 | " * the Free Software Foundation, either version 3 of the License, or\n", | |
269 | " * (at your option) any later version.\n", | |
270 | " *\n", | |
271 | " * This program is distributed in the hope that it will be useful,\n", | |
272 | " * but WITHOUT ANY WARRANTY; without even the implied warranty of\n", | |
273 | " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n", | |
274 | " * GNU General Public License for more details.\n", | |
275 | " *\n", | |
276 | " * You should have received a copy of the GNU General Public License\n", | |
277 | " * along with this program. If not, see <http://www.gnu.org/licenses/>.\n", | |
278 | " */\n"); | |
200adb00 RK |
279 | |
280 | ||
281 | push(@h, @gpl, | |
282 | "#ifndef CLIENT_STUBS_H\n", | |
283 | "#define CLIENT_STUBS_H\n", | |
284 | "\n"); | |
285 | ||
286 | push(@c, @gpl, | |
287 | "\n"); | |
288 | ||
289 | # The protocol ---------------------------------------------------------------- | |
290 | ||
96b1cf08 RK |
291 | simple("adopt", |
292 | "Adopt a track", | |
293 | "Makes the calling user owner of a randomly picked track.", | |
294 | [["id", "Track ID"]]); | |
200adb00 | 295 | |
96b1cf08 RK |
296 | simple("adduser", |
297 | "Create a user", | |
298 | "Create a new user. Requires the 'admin' right. Email addresses etc must be filled in in separate commands.", | |
299 | [["user", "New username"], | |
7788b7c7 RK |
300 | ["password", "Initial password"], |
301 | ["rights", "Initial rights (optional)"]]); | |
200adb00 | 302 | |
3680ef53 RK |
303 | list("allfiles", |
304 | "List files and directories in a directory", | |
305 | "See 'files' and 'dirs' for more specific lists.", | |
306 | [["dir", "Directory to list (optional)"], | |
307 | ["re", "Regexp that results must match (optional)"]], | |
308 | ["files", "List of matching files and directories"]); | |
200adb00 | 309 | |
7788b7c7 RK |
310 | string_login("confirm", |
311 | "Confirm registration", | |
312 | "The confirmation string must have been created with 'register'. The username is returned so the caller knows who they are.", | |
313 | [["confirmation", "Confirmation string"]]); | |
200adb00 | 314 | |
7788b7c7 RK |
315 | string_login("cookie", |
316 | "Log in with a cookie", | |
317 | "The cookie must have been created with 'make-cookie'. The username is returned so the caller knows who they are.", | |
318 | [["cookie", "Cookie string"]]); | |
200adb00 | 319 | |
96b1cf08 RK |
320 | simple("deluser", |
321 | "Delete user", | |
322 | "Requires the 'admin' right.", | |
323 | [["user", "User to delete"]]); | |
200adb00 | 324 | |
3680ef53 RK |
325 | list("dirs", |
326 | "List directories in a directory", | |
327 | "", | |
328 | [["dir", "Directory to list (optional)"], | |
329 | ["re", "Regexp that results must match (optional)"]], | |
330 | ["files", "List of matching directories"]); | |
200adb00 | 331 | |
96b1cf08 RK |
332 | simple("disable", |
333 | "Disable play", | |
334 | "Play will stop at the end of the current track, if one is playing. Requires the 'global prefs' right.", | |
335 | []); | |
336 | ||
337 | simple("edituser", | |
338 | "Set a user property", | |
339 | "With the 'admin' right you can do anything. Otherwise you need the 'userinfo' right and can only set 'email' and 'password'.", | |
340 | [["username", "User to modify"], | |
7788b7c7 | 341 | ["property", "Property name"], |
96b1cf08 RK |
342 | ["value", "New property value"]]); |
343 | ||
344 | simple("enable", | |
345 | "Enable play", | |
346 | "Requires the 'global prefs' right.", | |
347 | []); | |
348 | ||
349 | boolean("enabled", | |
7788b7c7 RK |
350 | "Detect whether play is enabled", |
351 | "", | |
352 | [], | |
353 | ["enabled", "1 if play is enabled and 0 otherwise"]); | |
96b1cf08 RK |
354 | |
355 | boolean("exists", | |
7788b7c7 RK |
356 | "Test whether a track exists", |
357 | "", | |
358 | [["track", "Track name"]], | |
359 | ["exists", "1 if the track exists and 0 otherwise"]); | |
200adb00 | 360 | |
3680ef53 RK |
361 | list("files", |
362 | "List files in a directory", | |
363 | "", | |
364 | [["dir", "Directory to list (optional)"], | |
365 | ["re", "Regexp that results must match (optional)"]], | |
366 | ["files", "List of matching files"]); | |
200adb00 | 367 | |
7788b7c7 RK |
368 | string("get", |
369 | "Get a track preference", | |
370 | "If the track does not exist that is an error. If the track exists but the preference does not then a null value is returned.", | |
371 | [["track", "Track name"], | |
372 | ["pref", "Preference name"]], | |
373 | ["value", "Preference value"]); | |
200adb00 | 374 | |
7788b7c7 RK |
375 | string("get-global", |
376 | "Get a global preference", | |
377 | "If the preference does exist not then a null value is returned.", | |
378 | [["pref", "Global preference name"]], | |
379 | ["value", "Preference value"]); | |
200adb00 RK |
380 | |
381 | # TODO length | |
382 | ||
383 | # TODO log | |
384 | ||
7788b7c7 RK |
385 | string("make-cookie", |
386 | "Create a login cookie for this user", | |
387 | "The cookie may be redeemed via the 'cookie' command", | |
388 | [], | |
389 | ["cookie", "Newly created cookie"]); | |
200adb00 RK |
390 | |
391 | # TODO move | |
392 | ||
393 | # TODO moveafter | |
394 | ||
395 | # TODO new | |
396 | ||
96b1cf08 RK |
397 | simple("nop", |
398 | "Do nothing", | |
399 | "Used as a keepalive. No authentication required.", | |
400 | []); | |
200adb00 | 401 | |
7788b7c7 RK |
402 | string("part", |
403 | "Get a track name part", | |
404 | "If the name part cannot be constructed an empty string is returned.", | |
405 | [["track", "Track name"], | |
406 | ["context", "Context (\"sort\" or \"display\")"], | |
407 | ["part", "Name part (\"artist\", \"album\" or \"title\")"]], | |
408 | ["part", "Value of name part"]); | |
200adb00 | 409 | |
96b1cf08 RK |
410 | simple("pause", |
411 | "Pause the currently playing track", | |
412 | "Requires the 'pause' right.", | |
413 | []); | |
200adb00 RK |
414 | |
415 | # TODO playafter | |
416 | ||
417 | # TODO playing | |
418 | ||
96b1cf08 RK |
419 | simple("playlist-delete", |
420 | "Delete a playlist", | |
421 | "Requires the 'play' right and permission to modify the playlist.", | |
422 | [["playlist", "Playlist to delete"]]); | |
200adb00 | 423 | |
3680ef53 RK |
424 | list("playlist-get", |
425 | "List the contents of a playlist", | |
426 | "Requires the 'read' right and oermission to read the playlist.", | |
427 | [["playlist", "Playlist name"]], | |
428 | ["tracks", "List of tracks in playlist"]); | |
200adb00 | 429 | |
7788b7c7 RK |
430 | string("playlist-get-share", |
431 | "Get a playlist's sharing status", | |
432 | "Requires the 'read' right and permission to read the playlist.", | |
433 | [["playlist", "Playlist to read"]], | |
434 | ["share", "Sharing status (\"public\", \"private\" or \"shared\")"]); | |
200adb00 | 435 | |
3680ef53 RK |
436 | simple("playlist-lock", |
437 | "Lock a playlist", | |
438 | "Requires the 'play' right and permission to modify the playlist. A given connection may lock at most one playlist.", | |
439 | [["playlist", "Playlist to delete"]]); | |
440 | ||
96b1cf08 RK |
441 | simple("playlist-set-share", |
442 | "Set a playlist's sharing status", | |
7788b7c7 | 443 | "Requires the 'play' right and permission to modify the playlist.", |
96b1cf08 | 444 | [["playlist", "Playlist to modify"], |
7788b7c7 | 445 | ["share", "New sharing status (\"public\", \"private\" or \"shared\")"]]); |
200adb00 | 446 | |
96b1cf08 RK |
447 | simple("playlist-unlock", |
448 | "Unlock the locked playlist playlist", | |
449 | "The playlist to unlock is implicit in the connection.", | |
450 | []); | |
200adb00 | 451 | |
3680ef53 RK |
452 | list("playlists", |
453 | "List playlists", | |
454 | "Requires the 'read' right. Only playlists that you have permission to read are returned.", | |
455 | [], | |
456 | ["playlists", "Playlist names"]); | |
200adb00 RK |
457 | |
458 | # TODO prefs | |
459 | ||
460 | # TODO queue | |
461 | ||
96b1cf08 RK |
462 | simple("random-disable", |
463 | "Disable random play", | |
464 | "Requires the 'global prefs' right.", | |
465 | []); | |
466 | ||
467 | simple("random-enable", | |
468 | "Enable random play", | |
469 | "Requires the 'global prefs' right.", | |
470 | []); | |
200adb00 | 471 | |
96b1cf08 | 472 | boolean("random-enabled", |
7788b7c7 RK |
473 | "Detect whether random play is enabled", |
474 | "Random play counts as enabled even if play is disabled.", | |
475 | [], | |
476 | ["enabled", "1 if random play is enabled and 0 otherwise"]); | |
200adb00 RK |
477 | |
478 | # TODO recent | |
479 | ||
96b1cf08 RK |
480 | simple("reconfigure", |
481 | "Re-read configuraiton file.", | |
482 | "Requires the 'admin' right.", | |
483 | []); | |
200adb00 | 484 | |
7788b7c7 RK |
485 | string("register", |
486 | "Register a new user", | |
487 | "Requires the 'register' right which is usually only available to the 'guest' user. Redeem the confirmation string via 'confirm' to complete registration.", | |
488 | [["username", "Requested new username"], | |
489 | ["password", "Requested initial password"], | |
490 | ["email", "New user's email address"]], | |
491 | ["confirmation", "Confirmation string"]); | |
200adb00 | 492 | |
96b1cf08 RK |
493 | simple("reminder", |
494 | "Send a password reminder.", | |
495 | "If the user has no valid email address, or no password, or a reminder has been sent too recently, then no reminder will be sent.", | |
496 | [["username", "User to remind"]]); | |
200adb00 | 497 | |
96b1cf08 RK |
498 | simple("remove", |
499 | "Remove a track form the queue.", | |
500 | "Requires one of the 'remove mine', 'remove random' or 'remove any' rights depending on how the track came to be added to the queue.", | |
501 | [["id", "Track ID"]]); | |
200adb00 | 502 | |
96b1cf08 RK |
503 | simple("rescan", |
504 | "Rescan all collections for new or obsolete tracks.", | |
505 | "Requires the 'rescan' right.", | |
7788b7c7 | 506 | []); # TODO wait/fresh flags |
200adb00 | 507 | |
7788b7c7 RK |
508 | string("resolve", |
509 | "Resolve a track name", | |
510 | "Converts aliases to non-alias track names", | |
511 | [["track", "Track name (might be an alias)"]], | |
512 | ["resolved", "Resolve track name (definitely not an alias)"]); | |
200adb00 | 513 | |
96b1cf08 RK |
514 | simple("resume", |
515 | "Resume the currently playing track", | |
516 | "Requires the 'pause' right.", | |
517 | []); | |
200adb00 | 518 | |
96b1cf08 RK |
519 | simple("revoke", |
520 | "Revoke a cookie.", | |
521 | "It will not subsequently be possible to log in with the cookie.", | |
7788b7c7 | 522 | []); # TODO fix docs! |
200adb00 RK |
523 | |
524 | # TODO rtp-address | |
525 | ||
96b1cf08 RK |
526 | simple("scratch", |
527 | "Terminate the playing track.", | |
528 | "Requires one of the 'scratch mine', 'scratch random' or 'scratch any' rights depending on how the track came to be added to the queue.", | |
529 | [["id", "Track ID (optional)"]]); | |
200adb00 RK |
530 | |
531 | # TODO schedule-add | |
532 | ||
96b1cf08 RK |
533 | simple("schedule-del", |
534 | "Delete a scheduled event.", | |
535 | "Users can always delete their own scheduled events; with the admin right you can delete any event.", | |
536 | [["event", "ID of event to delete"]]); | |
200adb00 RK |
537 | |
538 | # TODO schedule-get | |
539 | ||
3680ef53 RK |
540 | list("schedule-list", |
541 | "List scheduled events", | |
542 | "This just lists IDs. Use 'schedule-get' to retrieve more detail", | |
543 | [], | |
544 | ["ids", "List of event IDs"]); | |
200adb00 | 545 | |
3680ef53 RK |
546 | list("search", |
547 | "Search for tracks", | |
548 | "Terms are either keywords or tags formatted as 'tag:TAG-NAME'.", | |
549 | [["terms", "List of search terms"]], | |
550 | ["tracks", "List of matching tracks"]); | |
200adb00 | 551 | |
96b1cf08 RK |
552 | simple("set", |
553 | "Set a track preference", | |
554 | "Requires the 'prefs' right.", | |
555 | [["track", "Track name"], | |
7788b7c7 | 556 | ["pref", "Preference name"], |
96b1cf08 | 557 | ["value", "New value"]]); |
200adb00 | 558 | |
96b1cf08 RK |
559 | simple("set-global", |
560 | "Set a global preference", | |
561 | "Requires the 'global prefs' right.", | |
562 | [["pref", "Preference name"], | |
563 | ["value", "New value"]]); | |
200adb00 | 564 | |
eea34c08 RK |
565 | simple("shutdown", |
566 | "Request server shutdown", | |
567 | "Requires the 'admin' right.", | |
568 | []); | |
7788b7c7 | 569 | |
3680ef53 RK |
570 | list("stats", |
571 | "Get server statistics", | |
572 | "The details of what the server reports are not really defined. The returned strings are intended to be printed out one to a line..", | |
573 | [], | |
574 | ["stats", "List of server information strings."]); | |
200adb00 | 575 | |
3680ef53 RK |
576 | list("tags", |
577 | "Get a list of known tags", | |
578 | "Only tags which apply to at least one track are returned.", | |
579 | [], | |
580 | ["tags", "List of tags"]); | |
200adb00 | 581 | |
96b1cf08 RK |
582 | simple("unset", |
583 | "Unset a track preference", | |
584 | "Requires the 'prefs' right.", | |
585 | [["track", "Track name"], | |
7788b7c7 | 586 | ["pref", "Preference name"]]); |
200adb00 | 587 | |
96b1cf08 RK |
588 | simple("unset-global", |
589 | "Set a global preference", | |
590 | "Requires the 'global prefs' right.", | |
591 | [["pref", "Preference name"]]); | |
200adb00 | 592 | |
7788b7c7 | 593 | # TODO user? |
200adb00 | 594 | |
7788b7c7 RK |
595 | string("userinfo", |
596 | "Get a user property.", | |
597 | "If the user does not exist an error is returned, if the user exists but the property does not then a null value is returned.", | |
598 | [["username", "User to read"], | |
599 | ["property", "Property to read"]], | |
600 | ["value", "Value of property"]); | |
200adb00 | 601 | |
3680ef53 RK |
602 | list("users", |
603 | "Get a list of users", | |
604 | "", | |
605 | [], | |
606 | ["users", "List of users"]); | |
200adb00 | 607 | |
7788b7c7 RK |
608 | string("version", |
609 | "Get the server version", | |
610 | "", | |
611 | [], | |
612 | ["version", "Server version string"]); | |
200adb00 RK |
613 | |
614 | # TODO volume | |
615 | ||
616 | # End matter ------------------------------------------------------------------ | |
617 | ||
618 | push(@h, "#endif\n"); | |
619 | ||
620 | # Write it all out ------------------------------------------------------------ | |
621 | ||
7788b7c7 RK |
622 | Write("lib/client-stubs.h", \@h); |
623 | Write("lib/client-stubs.c", \@c); |