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) | |
33 | or die "$0: $path: $!\n"; | |
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", | |
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"); | |
60 | push(@c, "int disorder_$cmdc(disorder_client *c", | |
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 | ||
96b1cf08 RK |
77 | # boolean(CMD, SUMMARY, DETAIL, [[NAME,DESCR], [NAME,DESCR], ...], [RETURN, DESCR]) |
78 | # | |
79 | # Response is yes/no or failure | |
80 | sub boolean { | |
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] $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 | ", int *$return->[0]);\n", | |
101 | "\n"); | |
102 | push(@c, "int disorder_$cmdc(disorder_client *c", | |
103 | map(", const char *$_->[0]", @$args), | |
104 | ", int *$return->[0]) {\n", | |
105 | " char *v;\n", | |
106 | " int rc = disorder_simple(c, &v, \"$cmd\"", | |
107 | map(", $_->[0]", @$args), | |
108 | ", (char *)0);\n", | |
109 | " if(rc) return rc;\n", | |
110 | " if(!strcmp(v, \"yes\")) *$return->[0] = 1;\n", | |
111 | " if(!strcmp(v, \"no\")) *$return->[0] = 0;\n", | |
112 | " else {\n", | |
113 | " disorder_error(0, \"malformed response to '$cmd' command\");\n", | |
114 | " rc = -1;\n", | |
115 | " }\n", | |
116 | " xfree(v);\n", | |
117 | " return 0;\n", | |
118 | "}\n\n"); | |
119 | ||
120 | # Asynchronous C API | |
121 | # TODO | |
122 | ||
123 | # Python API | |
124 | # TODO | |
125 | ||
126 | # Java API | |
127 | # TODO | |
128 | } | |
129 | ||
200adb00 RK |
130 | # TODO other command classes |
131 | ||
132 | # Front matter ---------------------------------------------------------------- | |
133 | ||
134 | our @gpl = ("/*\n", | |
135 | " * This file is part of DisOrder.\n", | |
136 | " * Copyright (C) 2010 Richard Kettlewell\n", | |
137 | " *\n", | |
138 | " * This program is free software: you can redistribute it and/or modify\n", | |
139 | " * it under the terms of the GNU General Public License as published by\n", | |
140 | " * the Free Software Foundation, either version 3 of the License, or\n", | |
141 | " * (at your option) any later version.\n", | |
142 | " *\n", | |
143 | " * This program is distributed in the hope that it will be useful,\n", | |
144 | " * but WITHOUT ANY WARRANTY; without even the implied warranty of\n", | |
145 | " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n", | |
146 | " * GNU General Public License for more details.\n", | |
147 | " *\n", | |
148 | " * You should have received a copy of the GNU General Public License\n", | |
149 | " * along with this program. If not, see <http://www.gnu.org/licenses/>.\n", | |
150 | " */\n"); | |
151 | ||
152 | ||
153 | push(@h, @gpl, | |
154 | "#ifndef CLIENT_STUBS_H\n", | |
155 | "#define CLIENT_STUBS_H\n", | |
156 | "\n"); | |
157 | ||
158 | push(@c, @gpl, | |
159 | "\n"); | |
160 | ||
161 | # The protocol ---------------------------------------------------------------- | |
162 | ||
96b1cf08 RK |
163 | simple("adopt", |
164 | "Adopt a track", | |
165 | "Makes the calling user owner of a randomly picked track.", | |
166 | [["id", "Track ID"]]); | |
200adb00 | 167 | |
96b1cf08 RK |
168 | simple("adduser", |
169 | "Create a user", | |
170 | "Create a new user. Requires the 'admin' right. Email addresses etc must be filled in in separate commands.", | |
171 | [["user", "New username"], | |
172 | ["password", "Initial password"], | |
173 | ["rights", "Initial rights (optional)"]]); | |
200adb00 RK |
174 | |
175 | # TODO allfiles | |
176 | ||
96b1cf08 RK |
177 | simple("confirm", |
178 | "Confirm user registration", | |
179 | "The confirmation string is as returned by the register command.", | |
180 | [["confirmation", "Confirmnation string"]]); | |
200adb00 RK |
181 | |
182 | # TODO cookie | |
183 | ||
96b1cf08 RK |
184 | simple("deluser", |
185 | "Delete user", | |
186 | "Requires the 'admin' right.", | |
187 | [["user", "User to delete"]]); | |
200adb00 RK |
188 | |
189 | # TODO dirs | |
190 | ||
96b1cf08 RK |
191 | simple("disable", |
192 | "Disable play", | |
193 | "Play will stop at the end of the current track, if one is playing. Requires the 'global prefs' right.", | |
194 | []); | |
195 | ||
196 | simple("edituser", | |
197 | "Set a user property", | |
198 | "With the 'admin' right you can do anything. Otherwise you need the 'userinfo' right and can only set 'email' and 'password'.", | |
199 | [["username", "User to modify"], | |
200 | ["property", "Property name"], | |
201 | ["value", "New property value"]]); | |
202 | ||
203 | simple("enable", | |
204 | "Enable play", | |
205 | "Requires the 'global prefs' right.", | |
206 | []); | |
207 | ||
208 | boolean("enabled", | |
209 | "Detect whether play is enabled", | |
210 | "", | |
211 | [], | |
212 | ["enabled", "1 if play is enabled and 0 otherwise"]); | |
213 | ||
214 | boolean("exists", | |
215 | "Test whether a track exists", | |
216 | "", | |
217 | [["track", "Track name"]], | |
218 | ["exists", "1 if the track exists and 0 otherwise"]); | |
200adb00 RK |
219 | |
220 | # TODO files | |
221 | ||
222 | # TODO get | |
223 | ||
224 | # TODO get-global | |
225 | ||
226 | # TODO length | |
227 | ||
228 | # TODO log | |
229 | ||
230 | # TODO make-cookie | |
231 | ||
232 | # TODO move | |
233 | ||
234 | # TODO moveafter | |
235 | ||
236 | # TODO new | |
237 | ||
96b1cf08 RK |
238 | simple("nop", |
239 | "Do nothing", | |
240 | "Used as a keepalive. No authentication required.", | |
241 | []); | |
200adb00 RK |
242 | |
243 | # TODO part | |
244 | ||
96b1cf08 RK |
245 | simple("pause", |
246 | "Pause the currently playing track", | |
247 | "Requires the 'pause' right.", | |
248 | []); | |
200adb00 RK |
249 | |
250 | # TODO playafter | |
251 | ||
252 | # TODO playing | |
253 | ||
96b1cf08 RK |
254 | simple("playlist-delete", |
255 | "Delete a playlist", | |
256 | "Requires the 'play' right and permission to modify the playlist.", | |
257 | [["playlist", "Playlist to delete"]]); | |
200adb00 RK |
258 | |
259 | # TODO playlist-get | |
260 | ||
261 | # TODO playlist-get-share | |
262 | ||
96b1cf08 RK |
263 | simple("playlist-lock", |
264 | "Lock a playlist", | |
265 | "Requires the 'play' right and permission to modify the playlist. A given connection may lock at most one playlist.", | |
266 | [["playlist", "Playlist to delete"]]); | |
200adb00 RK |
267 | |
268 | # TODO playlist-set | |
269 | ||
96b1cf08 RK |
270 | simple("playlist-set-share", |
271 | "Set a playlist's sharing status", | |
272 | "Requires the 'play' right and permission to modify the playlist. ", | |
273 | [["playlist", "Playlist to modify"], | |
274 | ["share", "New sharing status ('public', 'private' or 'shared')"]]); | |
200adb00 | 275 | |
96b1cf08 RK |
276 | simple("playlist-unlock", |
277 | "Unlock the locked playlist playlist", | |
278 | "The playlist to unlock is implicit in the connection.", | |
279 | []); | |
200adb00 RK |
280 | |
281 | # TODO playlists | |
282 | ||
283 | # TODO prefs | |
284 | ||
285 | # TODO queue | |
286 | ||
96b1cf08 RK |
287 | simple("random-disable", |
288 | "Disable random play", | |
289 | "Requires the 'global prefs' right.", | |
290 | []); | |
291 | ||
292 | simple("random-enable", | |
293 | "Enable random play", | |
294 | "Requires the 'global prefs' right.", | |
295 | []); | |
200adb00 | 296 | |
96b1cf08 RK |
297 | boolean("random-enabled", |
298 | "Detect whether random play is enabled", | |
299 | "Random play counts as enabled even if play is disabled.", | |
300 | [], | |
301 | ["enabled", "1 if random play is enabled and 0 otherwise"]); | |
200adb00 RK |
302 | |
303 | # TODO random-enabled | |
304 | ||
305 | # TODO recent | |
306 | ||
96b1cf08 RK |
307 | simple("reconfigure", |
308 | "Re-read configuraiton file.", | |
309 | "Requires the 'admin' right.", | |
310 | []); | |
200adb00 RK |
311 | |
312 | # TODO register | |
313 | ||
96b1cf08 RK |
314 | simple("reminder", |
315 | "Send a password reminder.", | |
316 | "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.", | |
317 | [["username", "User to remind"]]); | |
200adb00 | 318 | |
96b1cf08 RK |
319 | simple("remove", |
320 | "Remove a track form the queue.", | |
321 | "Requires one of the 'remove mine', 'remove random' or 'remove any' rights depending on how the track came to be added to the queue.", | |
322 | [["id", "Track ID"]]); | |
200adb00 | 323 | |
96b1cf08 RK |
324 | simple("rescan", |
325 | "Rescan all collections for new or obsolete tracks.", | |
326 | "Requires the 'rescan' right.", | |
327 | []); # TODO wait/fresh flags | |
200adb00 RK |
328 | |
329 | # TODO resolve | |
330 | ||
96b1cf08 RK |
331 | simple("resume", |
332 | "Resume the currently playing track", | |
333 | "Requires the 'pause' right.", | |
334 | []); | |
200adb00 | 335 | |
96b1cf08 RK |
336 | simple("revoke", |
337 | "Revoke a cookie.", | |
338 | "It will not subsequently be possible to log in with the cookie.", | |
339 | [["cookie", "Cookie to revoke"]]); | |
200adb00 RK |
340 | |
341 | # TODO rtp-address | |
342 | ||
96b1cf08 RK |
343 | simple("scratch", |
344 | "Terminate the playing track.", | |
345 | "Requires one of the 'scratch mine', 'scratch random' or 'scratch any' rights depending on how the track came to be added to the queue.", | |
346 | [["id", "Track ID (optional)"]]); | |
200adb00 RK |
347 | |
348 | # TODO schedule-add | |
349 | ||
96b1cf08 RK |
350 | simple("schedule-del", |
351 | "Delete a scheduled event.", | |
352 | "Users can always delete their own scheduled events; with the admin right you can delete any event.", | |
353 | [["event", "ID of event to delete"]]); | |
200adb00 RK |
354 | |
355 | # TODO schedule-get | |
356 | ||
357 | # TODO schedule-list | |
358 | ||
359 | # TODO search | |
360 | ||
96b1cf08 RK |
361 | simple("set", |
362 | "Set a track preference", | |
363 | "Requires the 'prefs' right.", | |
364 | [["track", "Track name"], | |
365 | ["pref", "Preference name"], | |
366 | ["value", "New value"]]); | |
200adb00 | 367 | |
96b1cf08 RK |
368 | simple("set-global", |
369 | "Set a global preference", | |
370 | "Requires the 'global prefs' right.", | |
371 | [["pref", "Preference name"], | |
372 | ["value", "New value"]]); | |
200adb00 RK |
373 | |
374 | # TODO stats | |
375 | ||
376 | # TODO tags | |
377 | ||
96b1cf08 RK |
378 | simple("unset", |
379 | "Unset a track preference", | |
380 | "Requires the 'prefs' right.", | |
381 | [["track", "Track name"], | |
382 | ["pref", "Preference name"]]); | |
200adb00 | 383 | |
96b1cf08 RK |
384 | simple("unset-global", |
385 | "Set a global preference", | |
386 | "Requires the 'global prefs' right.", | |
387 | [["pref", "Preference name"]]); | |
200adb00 RK |
388 | |
389 | # user is only used by connect functions | |
390 | ||
391 | # TODO userinfo | |
392 | ||
393 | # TODO users | |
394 | ||
395 | # TODO version | |
396 | ||
397 | # TODO volume | |
398 | ||
399 | # End matter ------------------------------------------------------------------ | |
400 | ||
401 | push(@h, "#endif\n"); | |
402 | ||
403 | # Write it all out ------------------------------------------------------------ | |
404 | ||
405 | Write("client-stubs.h", \@h); | |
406 | Write("client-stubs.c", \@c); |