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 | ||
711a4497 RK |
214 | # integer(CMD, SUMMARY, DETAIL, [[NAME,DESCR], [NAME,DESCR], ...], [RETURN, DESCR]) |
215 | # | |
216 | # Response is an integer, or failure | |
217 | sub integer { | |
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 | " * \@return 0 on success, non-0 on error\n", | |
234 | " */\n", | |
235 | "int disorder_$cmdc(disorder_client *c", | |
236 | map(", const char *$_->[0]", @$args), | |
237 | ", long *$return->[0]p);\n", | |
238 | "\n"); | |
239 | push(@c, "int disorder_$cmdc(disorder_client *c", | |
240 | map(", const char *$_->[0]", @$args), | |
241 | ", long *$return->[0]p) {\n", | |
242 | " char *v;\n", | |
243 | " int rc;\n", | |
244 | "\n", | |
245 | " if((rc = disorder_simple(c, &v, \"$cmd\"", | |
246 | map(", $_->[0]", @$args), | |
247 | ", (char *)0)))\n", | |
248 | " return rc;\n", | |
249 | " *$return->[0]p = atol(v);\n", | |
250 | " xfree(v);\n", | |
251 | " return 0;\n", | |
252 | "}\n\n"); | |
253 | ||
254 | # Asynchronous C API | |
255 | # TODO | |
256 | ||
257 | # Python API | |
258 | # TODO | |
259 | ||
260 | # Java API | |
261 | # TODO | |
262 | } | |
263 | ||
3680ef53 RK |
264 | # list(CMD, SUMMARY, DETAIL, [[NAME,DESCR], [NAME,DESCR], ...], [RETURN, DESCR]) |
265 | # | |
266 | # Response is a a list of strings in a dot-stuffed body | |
267 | sub list { | |
268 | my $cmd = shift; | |
269 | my $summary = shift; | |
270 | my $detail = shift; | |
271 | my $args = shift; | |
272 | my $return = shift; | |
273 | ||
274 | my $cmdc = $cmd; | |
275 | $cmdc =~ s/-/_/g; | |
276 | # Synchronous C API | |
277 | push(@h, "/** \@brief $summary\n", | |
278 | " *\n", | |
279 | " * $detail\n", | |
280 | " *\n", | |
281 | map(" * \@param $_->[0] $_->[1]\n", @$args), | |
282 | " * \@param $return->[0]p $return->[1]\n", | |
283 | " * \@param n$return->[0]p Number of elements in $return->[0]p\n", | |
284 | " * \@return 0 on success, non-0 on error\n", | |
285 | " */\n", | |
286 | "int disorder_$cmdc(disorder_client *c", | |
287 | map(", const char *$_->[0]", @$args), | |
288 | ", char ***$return->[0]p, int *n$return->[0]p);\n", | |
289 | "\n"); | |
290 | push(@c, "int disorder_$cmdc(disorder_client *c", | |
291 | map(", const char *$_->[0]", @$args), | |
292 | ", char ***$return->[0]p, int *n$return->[0]p) {\n", | |
293 | " return disorder_simple_list(c, $return->[0]p, n$return->[0]p, \"$cmd\"", | |
294 | map(", $_->[0]", @$args), | |
295 | ", (char *)0);\n", | |
296 | "}\n\n"); | |
297 | ||
298 | # Asynchronous C API | |
299 | # TODO | |
300 | ||
301 | # Python API | |
302 | # TODO | |
303 | ||
304 | # Java API | |
305 | # TODO | |
306 | } | |
307 | ||
200adb00 RK |
308 | # TODO other command classes |
309 | ||
310 | # Front matter ---------------------------------------------------------------- | |
311 | ||
312 | our @gpl = ("/*\n", | |
7788b7c7 RK |
313 | " * This file is part of DisOrder.\n", |
314 | " * Copyright (C) 2010 Richard Kettlewell\n", | |
315 | " *\n", | |
316 | " * This program is free software: you can redistribute it and/or modify\n", | |
317 | " * it under the terms of the GNU General Public License as published by\n", | |
318 | " * the Free Software Foundation, either version 3 of the License, or\n", | |
319 | " * (at your option) any later version.\n", | |
320 | " *\n", | |
321 | " * This program is distributed in the hope that it will be useful,\n", | |
322 | " * but WITHOUT ANY WARRANTY; without even the implied warranty of\n", | |
323 | " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n", | |
324 | " * GNU General Public License for more details.\n", | |
325 | " *\n", | |
326 | " * You should have received a copy of the GNU General Public License\n", | |
327 | " * along with this program. If not, see <http://www.gnu.org/licenses/>.\n", | |
328 | " */\n"); | |
200adb00 RK |
329 | |
330 | ||
331 | push(@h, @gpl, | |
332 | "#ifndef CLIENT_STUBS_H\n", | |
333 | "#define CLIENT_STUBS_H\n", | |
334 | "\n"); | |
335 | ||
336 | push(@c, @gpl, | |
337 | "\n"); | |
338 | ||
339 | # The protocol ---------------------------------------------------------------- | |
340 | ||
96b1cf08 RK |
341 | simple("adopt", |
342 | "Adopt a track", | |
343 | "Makes the calling user owner of a randomly picked track.", | |
344 | [["id", "Track ID"]]); | |
200adb00 | 345 | |
96b1cf08 RK |
346 | simple("adduser", |
347 | "Create a user", | |
348 | "Create a new user. Requires the 'admin' right. Email addresses etc must be filled in in separate commands.", | |
349 | [["user", "New username"], | |
7788b7c7 RK |
350 | ["password", "Initial password"], |
351 | ["rights", "Initial rights (optional)"]]); | |
200adb00 | 352 | |
3680ef53 RK |
353 | list("allfiles", |
354 | "List files and directories in a directory", | |
355 | "See 'files' and 'dirs' for more specific lists.", | |
356 | [["dir", "Directory to list (optional)"], | |
357 | ["re", "Regexp that results must match (optional)"]], | |
358 | ["files", "List of matching files and directories"]); | |
200adb00 | 359 | |
7788b7c7 RK |
360 | string_login("confirm", |
361 | "Confirm registration", | |
362 | "The confirmation string must have been created with 'register'. The username is returned so the caller knows who they are.", | |
363 | [["confirmation", "Confirmation string"]]); | |
200adb00 | 364 | |
7788b7c7 RK |
365 | string_login("cookie", |
366 | "Log in with a cookie", | |
367 | "The cookie must have been created with 'make-cookie'. The username is returned so the caller knows who they are.", | |
368 | [["cookie", "Cookie string"]]); | |
200adb00 | 369 | |
96b1cf08 RK |
370 | simple("deluser", |
371 | "Delete user", | |
372 | "Requires the 'admin' right.", | |
373 | [["user", "User to delete"]]); | |
200adb00 | 374 | |
3680ef53 RK |
375 | list("dirs", |
376 | "List directories in a directory", | |
377 | "", | |
378 | [["dir", "Directory to list (optional)"], | |
379 | ["re", "Regexp that results must match (optional)"]], | |
380 | ["files", "List of matching directories"]); | |
200adb00 | 381 | |
96b1cf08 RK |
382 | simple("disable", |
383 | "Disable play", | |
384 | "Play will stop at the end of the current track, if one is playing. Requires the 'global prefs' right.", | |
385 | []); | |
386 | ||
387 | simple("edituser", | |
388 | "Set a user property", | |
389 | "With the 'admin' right you can do anything. Otherwise you need the 'userinfo' right and can only set 'email' and 'password'.", | |
390 | [["username", "User to modify"], | |
7788b7c7 | 391 | ["property", "Property name"], |
96b1cf08 RK |
392 | ["value", "New property value"]]); |
393 | ||
394 | simple("enable", | |
395 | "Enable play", | |
396 | "Requires the 'global prefs' right.", | |
397 | []); | |
398 | ||
399 | boolean("enabled", | |
7788b7c7 RK |
400 | "Detect whether play is enabled", |
401 | "", | |
402 | [], | |
403 | ["enabled", "1 if play is enabled and 0 otherwise"]); | |
96b1cf08 RK |
404 | |
405 | boolean("exists", | |
7788b7c7 RK |
406 | "Test whether a track exists", |
407 | "", | |
408 | [["track", "Track name"]], | |
409 | ["exists", "1 if the track exists and 0 otherwise"]); | |
200adb00 | 410 | |
3680ef53 RK |
411 | list("files", |
412 | "List files in a directory", | |
413 | "", | |
414 | [["dir", "Directory to list (optional)"], | |
415 | ["re", "Regexp that results must match (optional)"]], | |
416 | ["files", "List of matching files"]); | |
200adb00 | 417 | |
7788b7c7 RK |
418 | string("get", |
419 | "Get a track preference", | |
420 | "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.", | |
421 | [["track", "Track name"], | |
422 | ["pref", "Preference name"]], | |
423 | ["value", "Preference value"]); | |
200adb00 | 424 | |
7788b7c7 RK |
425 | string("get-global", |
426 | "Get a global preference", | |
427 | "If the preference does exist not then a null value is returned.", | |
428 | [["pref", "Global preference name"]], | |
429 | ["value", "Preference value"]); | |
200adb00 | 430 | |
711a4497 RK |
431 | integer("length", |
432 | "Get a track's length", | |
433 | "If the track does not exist an error is returned.", | |
434 | [["track", "Track name"]], | |
435 | ["length", "Track length in seconds"]); | |
200adb00 RK |
436 | |
437 | # TODO log | |
438 | ||
7788b7c7 RK |
439 | string("make-cookie", |
440 | "Create a login cookie for this user", | |
441 | "The cookie may be redeemed via the 'cookie' command", | |
442 | [], | |
443 | ["cookie", "Newly created cookie"]); | |
200adb00 RK |
444 | |
445 | # TODO move | |
446 | ||
447 | # TODO moveafter | |
448 | ||
449 | # TODO new | |
450 | ||
96b1cf08 RK |
451 | simple("nop", |
452 | "Do nothing", | |
453 | "Used as a keepalive. No authentication required.", | |
454 | []); | |
200adb00 | 455 | |
7788b7c7 RK |
456 | string("part", |
457 | "Get a track name part", | |
458 | "If the name part cannot be constructed an empty string is returned.", | |
459 | [["track", "Track name"], | |
460 | ["context", "Context (\"sort\" or \"display\")"], | |
461 | ["part", "Name part (\"artist\", \"album\" or \"title\")"]], | |
462 | ["part", "Value of name part"]); | |
200adb00 | 463 | |
96b1cf08 RK |
464 | simple("pause", |
465 | "Pause the currently playing track", | |
466 | "Requires the 'pause' right.", | |
467 | []); | |
200adb00 | 468 | |
00861dcb RK |
469 | string("play", |
470 | "Play a track", | |
471 | "Requires the 'play' right.", | |
472 | [["track", "Track to play"]], | |
473 | ["id", "Queue ID of new track"]); | |
474 | ||
200adb00 RK |
475 | # TODO playafter |
476 | ||
477 | # TODO playing | |
478 | ||
96b1cf08 RK |
479 | simple("playlist-delete", |
480 | "Delete a playlist", | |
481 | "Requires the 'play' right and permission to modify the playlist.", | |
482 | [["playlist", "Playlist to delete"]]); | |
200adb00 | 483 | |
3680ef53 RK |
484 | list("playlist-get", |
485 | "List the contents of a playlist", | |
486 | "Requires the 'read' right and oermission to read the playlist.", | |
487 | [["playlist", "Playlist name"]], | |
488 | ["tracks", "List of tracks in playlist"]); | |
200adb00 | 489 | |
7788b7c7 RK |
490 | string("playlist-get-share", |
491 | "Get a playlist's sharing status", | |
492 | "Requires the 'read' right and permission to read the playlist.", | |
493 | [["playlist", "Playlist to read"]], | |
494 | ["share", "Sharing status (\"public\", \"private\" or \"shared\")"]); | |
200adb00 | 495 | |
3680ef53 RK |
496 | simple("playlist-lock", |
497 | "Lock a playlist", | |
498 | "Requires the 'play' right and permission to modify the playlist. A given connection may lock at most one playlist.", | |
499 | [["playlist", "Playlist to delete"]]); | |
500 | ||
96b1cf08 RK |
501 | simple("playlist-set-share", |
502 | "Set a playlist's sharing status", | |
7788b7c7 | 503 | "Requires the 'play' right and permission to modify the playlist.", |
96b1cf08 | 504 | [["playlist", "Playlist to modify"], |
7788b7c7 | 505 | ["share", "New sharing status (\"public\", \"private\" or \"shared\")"]]); |
200adb00 | 506 | |
96b1cf08 RK |
507 | simple("playlist-unlock", |
508 | "Unlock the locked playlist playlist", | |
509 | "The playlist to unlock is implicit in the connection.", | |
510 | []); | |
200adb00 | 511 | |
3680ef53 RK |
512 | list("playlists", |
513 | "List playlists", | |
514 | "Requires the 'read' right. Only playlists that you have permission to read are returned.", | |
515 | [], | |
516 | ["playlists", "Playlist names"]); | |
200adb00 RK |
517 | |
518 | # TODO prefs | |
519 | ||
520 | # TODO queue | |
521 | ||
96b1cf08 RK |
522 | simple("random-disable", |
523 | "Disable random play", | |
524 | "Requires the 'global prefs' right.", | |
525 | []); | |
526 | ||
527 | simple("random-enable", | |
528 | "Enable random play", | |
529 | "Requires the 'global prefs' right.", | |
530 | []); | |
200adb00 | 531 | |
96b1cf08 | 532 | boolean("random-enabled", |
7788b7c7 RK |
533 | "Detect whether random play is enabled", |
534 | "Random play counts as enabled even if play is disabled.", | |
535 | [], | |
536 | ["enabled", "1 if random play is enabled and 0 otherwise"]); | |
200adb00 RK |
537 | |
538 | # TODO recent | |
539 | ||
96b1cf08 RK |
540 | simple("reconfigure", |
541 | "Re-read configuraiton file.", | |
542 | "Requires the 'admin' right.", | |
543 | []); | |
200adb00 | 544 | |
7788b7c7 RK |
545 | string("register", |
546 | "Register a new user", | |
547 | "Requires the 'register' right which is usually only available to the 'guest' user. Redeem the confirmation string via 'confirm' to complete registration.", | |
548 | [["username", "Requested new username"], | |
549 | ["password", "Requested initial password"], | |
550 | ["email", "New user's email address"]], | |
551 | ["confirmation", "Confirmation string"]); | |
200adb00 | 552 | |
96b1cf08 RK |
553 | simple("reminder", |
554 | "Send a password reminder.", | |
555 | "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.", | |
556 | [["username", "User to remind"]]); | |
200adb00 | 557 | |
96b1cf08 RK |
558 | simple("remove", |
559 | "Remove a track form the queue.", | |
560 | "Requires one of the 'remove mine', 'remove random' or 'remove any' rights depending on how the track came to be added to the queue.", | |
561 | [["id", "Track ID"]]); | |
200adb00 | 562 | |
96b1cf08 RK |
563 | simple("rescan", |
564 | "Rescan all collections for new or obsolete tracks.", | |
565 | "Requires the 'rescan' right.", | |
7788b7c7 | 566 | []); # TODO wait/fresh flags |
200adb00 | 567 | |
7788b7c7 RK |
568 | string("resolve", |
569 | "Resolve a track name", | |
570 | "Converts aliases to non-alias track names", | |
571 | [["track", "Track name (might be an alias)"]], | |
572 | ["resolved", "Resolve track name (definitely not an alias)"]); | |
200adb00 | 573 | |
96b1cf08 RK |
574 | simple("resume", |
575 | "Resume the currently playing track", | |
576 | "Requires the 'pause' right.", | |
577 | []); | |
200adb00 | 578 | |
96b1cf08 RK |
579 | simple("revoke", |
580 | "Revoke a cookie.", | |
581 | "It will not subsequently be possible to log in with the cookie.", | |
7788b7c7 | 582 | []); # TODO fix docs! |
200adb00 RK |
583 | |
584 | # TODO rtp-address | |
585 | ||
96b1cf08 RK |
586 | simple("scratch", |
587 | "Terminate the playing track.", | |
588 | "Requires one of the 'scratch mine', 'scratch random' or 'scratch any' rights depending on how the track came to be added to the queue.", | |
589 | [["id", "Track ID (optional)"]]); | |
200adb00 RK |
590 | |
591 | # TODO schedule-add | |
592 | ||
96b1cf08 RK |
593 | simple("schedule-del", |
594 | "Delete a scheduled event.", | |
595 | "Users can always delete their own scheduled events; with the admin right you can delete any event.", | |
596 | [["event", "ID of event to delete"]]); | |
200adb00 RK |
597 | |
598 | # TODO schedule-get | |
599 | ||
3680ef53 RK |
600 | list("schedule-list", |
601 | "List scheduled events", | |
602 | "This just lists IDs. Use 'schedule-get' to retrieve more detail", | |
603 | [], | |
604 | ["ids", "List of event IDs"]); | |
200adb00 | 605 | |
3680ef53 RK |
606 | list("search", |
607 | "Search for tracks", | |
608 | "Terms are either keywords or tags formatted as 'tag:TAG-NAME'.", | |
609 | [["terms", "List of search terms"]], | |
610 | ["tracks", "List of matching tracks"]); | |
200adb00 | 611 | |
96b1cf08 RK |
612 | simple("set", |
613 | "Set a track preference", | |
614 | "Requires the 'prefs' right.", | |
615 | [["track", "Track name"], | |
7788b7c7 | 616 | ["pref", "Preference name"], |
96b1cf08 | 617 | ["value", "New value"]]); |
200adb00 | 618 | |
96b1cf08 RK |
619 | simple("set-global", |
620 | "Set a global preference", | |
621 | "Requires the 'global prefs' right.", | |
622 | [["pref", "Preference name"], | |
623 | ["value", "New value"]]); | |
200adb00 | 624 | |
eea34c08 RK |
625 | simple("shutdown", |
626 | "Request server shutdown", | |
627 | "Requires the 'admin' right.", | |
628 | []); | |
7788b7c7 | 629 | |
3680ef53 RK |
630 | list("stats", |
631 | "Get server statistics", | |
632 | "The details of what the server reports are not really defined. The returned strings are intended to be printed out one to a line..", | |
633 | [], | |
634 | ["stats", "List of server information strings."]); | |
200adb00 | 635 | |
3680ef53 RK |
636 | list("tags", |
637 | "Get a list of known tags", | |
638 | "Only tags which apply to at least one track are returned.", | |
639 | [], | |
640 | ["tags", "List of tags"]); | |
200adb00 | 641 | |
96b1cf08 RK |
642 | simple("unset", |
643 | "Unset a track preference", | |
644 | "Requires the 'prefs' right.", | |
645 | [["track", "Track name"], | |
7788b7c7 | 646 | ["pref", "Preference name"]]); |
200adb00 | 647 | |
96b1cf08 RK |
648 | simple("unset-global", |
649 | "Set a global preference", | |
650 | "Requires the 'global prefs' right.", | |
651 | [["pref", "Preference name"]]); | |
200adb00 | 652 | |
7788b7c7 | 653 | # TODO user? |
200adb00 | 654 | |
7788b7c7 RK |
655 | string("userinfo", |
656 | "Get a user property.", | |
657 | "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.", | |
658 | [["username", "User to read"], | |
659 | ["property", "Property to read"]], | |
660 | ["value", "Value of property"]); | |
200adb00 | 661 | |
3680ef53 RK |
662 | list("users", |
663 | "Get a list of users", | |
664 | "", | |
665 | [], | |
666 | ["users", "List of users"]); | |
200adb00 | 667 | |
7788b7c7 RK |
668 | string("version", |
669 | "Get the server version", | |
670 | "", | |
671 | [], | |
672 | ["version", "Server version string"]); | |
200adb00 RK |
673 | |
674 | # TODO volume | |
675 | ||
676 | # End matter ------------------------------------------------------------------ | |
677 | ||
678 | push(@h, "#endif\n"); | |
679 | ||
680 | # Write it all out ------------------------------------------------------------ | |
681 | ||
7788b7c7 RK |
682 | Write("lib/client-stubs.h", \@h); |
683 | Write("lib/client-stubs.c", \@c); |