From: Richard Kettlewell Date: Sat, 5 Jun 2010 11:21:32 +0000 (+0100) Subject: Further commands. X-Git-Tag: branchpoint-5.1~22^2~31 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/disorder/commitdiff_plain/3680ef53ec6a3d5769c8703caed4a58e18a91bc6 Further commands. --- diff --git a/cgi/macros-disorder.c b/cgi/macros-disorder.c index 7c369e1..dc96c73 100644 --- a/cgi/macros-disorder.c +++ b/cgi/macros-disorder.c @@ -931,7 +931,7 @@ static int exp_dirs(int nargs, const struct mx_node **args, struct sink *output, void *u) { - return exp__files_dirs(nargs, args, output, u, "dir", disorder_directories); + return exp__files_dirs(nargs, args, output, u, "dir", disorder_dirs); } static int exp__search_shim(disorder_client *c, const char *terms, diff --git a/clients/disorder.c b/clients/disorder.c index a55a6e8..48745b6 100644 --- a/clients/disorder.c +++ b/clients/disorder.c @@ -244,7 +244,7 @@ static int isarg_regexp(const char *s) { } static void cf_dirs(char **argv) { - cf_somelist(argv, disorder_directories); + cf_somelist(argv, disorder_dirs); } static void cf_files(char **argv) { diff --git a/lib/client-stubs.c b/lib/client-stubs.c index 03047ad..427805f 100644 --- a/lib/client-stubs.c +++ b/lib/client-stubs.c @@ -24,6 +24,10 @@ int disorder_adduser(disorder_client *c, const char *user, const char *password, return disorder_simple(c, 0, "adduser", user, password, rights, (char *)0); } +int disorder_allfiles(disorder_client *c, const char *dir, const char *re, char ***filesp, int *nfilesp) { + return disorder_simple_list(c, filesp, nfilesp, "allfiles", dir, re, (char *)0); +} + int disorder_confirm(disorder_client *c, const char *confirmation) { char *u; int rc; @@ -46,6 +50,10 @@ int disorder_deluser(disorder_client *c, const char *user) { return disorder_simple(c, 0, "deluser", user, (char *)0); } +int disorder_dirs(disorder_client *c, const char *dir, const char *re, char ***filesp, int *nfilesp) { + return disorder_simple_list(c, filesp, nfilesp, "dirs", dir, re, (char *)0); +} + int disorder_disable(disorder_client *c) { return disorder_simple(c, 0, "disable", (char *)0); } @@ -74,6 +82,10 @@ int disorder_exists(disorder_client *c, const char *track, int *existsp) { return boolean("exists", v, existsp); } +int disorder_files(disorder_client *c, const char *dir, const char *re, char ***filesp, int *nfilesp) { + return disorder_simple_list(c, filesp, nfilesp, "files", dir, re, (char *)0); +} + int disorder_get(disorder_client *c, const char *track, const char *pref, char **valuep) { return dequote(disorder_simple(c, valuep, "get", track, pref, (char *)0), valuep); } @@ -102,14 +114,18 @@ int disorder_playlist_delete(disorder_client *c, const char *playlist) { return disorder_simple(c, 0, "playlist-delete", playlist, (char *)0); } -int disorder_playlist_lock(disorder_client *c, const char *playlist) { - return disorder_simple(c, 0, "playlist-lock", playlist, (char *)0); +int disorder_playlist_get(disorder_client *c, const char *playlist, char ***tracksp, int *ntracksp) { + return disorder_simple_list(c, tracksp, ntracksp, "playlist-get", playlist, (char *)0); } int disorder_playlist_get_share(disorder_client *c, const char *playlist, char **sharep) { return dequote(disorder_simple(c, sharep, "playlist-get-share", playlist, (char *)0), sharep); } +int disorder_playlist_lock(disorder_client *c, const char *playlist) { + return disorder_simple(c, 0, "playlist-lock", playlist, (char *)0); +} + int disorder_playlist_set_share(disorder_client *c, const char *playlist, const char *share) { return disorder_simple(c, 0, "playlist-set-share", playlist, share, (char *)0); } @@ -118,6 +134,10 @@ int disorder_playlist_unlock(disorder_client *c) { return disorder_simple(c, 0, "playlist-unlock", (char *)0); } +int disorder_playlists(disorder_client *c, char ***playlistsp, int *nplaylistsp) { + return disorder_simple_list(c, playlistsp, nplaylistsp, "playlists", (char *)0); +} + int disorder_random_disable(disorder_client *c) { return disorder_simple(c, 0, "random-disable", (char *)0); } @@ -174,6 +194,14 @@ int disorder_schedule_del(disorder_client *c, const char *event) { return disorder_simple(c, 0, "schedule-del", event, (char *)0); } +int disorder_schedule_list(disorder_client *c, char ***idsp, int *nidsp) { + return disorder_simple_list(c, idsp, nidsp, "schedule-list", (char *)0); +} + +int disorder_search(disorder_client *c, const char *terms, char ***tracksp, int *ntracksp) { + return disorder_simple_list(c, tracksp, ntracksp, "search", terms, (char *)0); +} + int disorder_set(disorder_client *c, const char *track, const char *pref, const char *value) { return disorder_simple(c, 0, "set", track, pref, value, (char *)0); } @@ -182,6 +210,14 @@ int disorder_set_global(disorder_client *c, const char *pref, const char *value) return disorder_simple(c, 0, "set-global", pref, value, (char *)0); } +int disorder_stats(disorder_client *c, char ***statsp, int *nstatsp) { + return disorder_simple_list(c, statsp, nstatsp, "stats", (char *)0); +} + +int disorder_tags(disorder_client *c, char ***tagsp, int *ntagsp) { + return disorder_simple_list(c, tagsp, ntagsp, "tags", (char *)0); +} + int disorder_unset(disorder_client *c, const char *track, const char *pref) { return disorder_simple(c, 0, "unset", track, pref, (char *)0); } @@ -194,6 +230,10 @@ int disorder_userinfo(disorder_client *c, const char *username, const char *prop return dequote(disorder_simple(c, valuep, "userinfo", username, property, (char *)0), valuep); } +int disorder_users(disorder_client *c, char ***usersp, int *nusersp) { + return disorder_simple_list(c, usersp, nusersp, "users", (char *)0); +} + int disorder_version(disorder_client *c, char **versionp) { return dequote(disorder_simple(c, versionp, "version", (char *)0), versionp); } diff --git a/lib/client-stubs.h b/lib/client-stubs.h index 4e67b01..d487772 100644 --- a/lib/client-stubs.h +++ b/lib/client-stubs.h @@ -38,6 +38,18 @@ int disorder_adopt(disorder_client *c, const char *id); */ int disorder_adduser(disorder_client *c, const char *user, const char *password, const char *rights); +/** @brief List files and directories in a directory + * + * See 'files' and 'dirs' for more specific lists. + * + * @param dir Directory to list (optional) + * @param re Regexp that results must match (optional) + * @param filesp List of matching files and directories + * @param nfilesp Number of elements in filesp + * @return 0 on success, non-0 on error + */ +int disorder_allfiles(disorder_client *c, const char *dir, const char *re, char ***filesp, int *nfilesp); + /** @brief Confirm registration * * The confirmation string must have been created with 'register'. The username is returned so the caller knows who they are. @@ -63,6 +75,18 @@ int disorder_cookie(disorder_client *c, const char *cookie); */ int disorder_deluser(disorder_client *c, const char *user); +/** @brief List directories in a directory + * + * + * + * @param dir Directory to list (optional) + * @param re Regexp that results must match (optional) + * @param filesp List of matching directories + * @param nfilesp Number of elements in filesp + * @return 0 on success, non-0 on error + */ +int disorder_dirs(disorder_client *c, const char *dir, const char *re, char ***filesp, int *nfilesp); + /** @brief Disable play * * Play will stop at the end of the current track, if one is playing. Requires the 'global prefs' right. @@ -109,6 +133,18 @@ int disorder_enabled(disorder_client *c, int *enabledp); */ int disorder_exists(disorder_client *c, const char *track, int *existsp); +/** @brief List files in a directory + * + * + * + * @param dir Directory to list (optional) + * @param re Regexp that results must match (optional) + * @param filesp List of matching files + * @param nfilesp Number of elements in filesp + * @return 0 on success, non-0 on error + */ +int disorder_files(disorder_client *c, const char *dir, const char *re, char ***filesp, int *nfilesp); + /** @brief Get a track preference * * 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. @@ -176,14 +212,16 @@ int disorder_pause(disorder_client *c); */ int disorder_playlist_delete(disorder_client *c, const char *playlist); -/** @brief Lock a playlist +/** @brief List the contents of a playlist * - * Requires the 'play' right and permission to modify the playlist. A given connection may lock at most one playlist. + * Requires the 'read' right and oermission to read the playlist. * - * @param playlist Playlist to delete + * @param playlist Playlist name + * @param tracksp List of tracks in playlist + * @param ntracksp Number of elements in tracksp * @return 0 on success, non-0 on error */ -int disorder_playlist_lock(disorder_client *c, const char *playlist); +int disorder_playlist_get(disorder_client *c, const char *playlist, char ***tracksp, int *ntracksp); /** @brief Get a playlist's sharing status * @@ -195,6 +233,15 @@ int disorder_playlist_lock(disorder_client *c, const char *playlist); */ int disorder_playlist_get_share(disorder_client *c, const char *playlist, char **sharep); +/** @brief Lock a playlist + * + * Requires the 'play' right and permission to modify the playlist. A given connection may lock at most one playlist. + * + * @param playlist Playlist to delete + * @return 0 on success, non-0 on error + */ +int disorder_playlist_lock(disorder_client *c, const char *playlist); + /** @brief Set a playlist's sharing status * * Requires the 'play' right and permission to modify the playlist. @@ -213,6 +260,16 @@ int disorder_playlist_set_share(disorder_client *c, const char *playlist, const */ int disorder_playlist_unlock(disorder_client *c); +/** @brief List playlists + * + * Requires the 'read' right. Only playlists that you have permission to read are returned. + * + * @param playlistsp Playlist names + * @param nplaylistsp Number of elements in playlistsp + * @return 0 on success, non-0 on error + */ +int disorder_playlists(disorder_client *c, char ***playlistsp, int *nplaylistsp); + /** @brief Disable random play * * Requires the 'global prefs' right. @@ -328,6 +385,27 @@ int disorder_scratch(disorder_client *c, const char *id); */ int disorder_schedule_del(disorder_client *c, const char *event); +/** @brief List scheduled events + * + * This just lists IDs. Use 'schedule-get' to retrieve more detail + * + * @param idsp List of event IDs + * @param nidsp Number of elements in idsp + * @return 0 on success, non-0 on error + */ +int disorder_schedule_list(disorder_client *c, char ***idsp, int *nidsp); + +/** @brief Search for tracks + * + * Terms are either keywords or tags formatted as 'tag:TAG-NAME'. + * + * @param terms List of search terms + * @param tracksp List of matching tracks + * @param ntracksp Number of elements in tracksp + * @return 0 on success, non-0 on error + */ +int disorder_search(disorder_client *c, const char *terms, char ***tracksp, int *ntracksp); + /** @brief Set a track preference * * Requires the 'prefs' right. @@ -349,6 +427,26 @@ int disorder_set(disorder_client *c, const char *track, const char *pref, const */ int disorder_set_global(disorder_client *c, const char *pref, const char *value); +/** @brief Get server statistics + * + * The details of what the server reports are not really defined. The returned strings are intended to be printed out one to a line.. + * + * @param statsp List of server information strings. + * @param nstatsp Number of elements in statsp + * @return 0 on success, non-0 on error + */ +int disorder_stats(disorder_client *c, char ***statsp, int *nstatsp); + +/** @brief Get a list of known tags + * + * Only tags which apply to at least one track are returned. + * + * @param tagsp List of tags + * @param ntagsp Number of elements in tagsp + * @return 0 on success, non-0 on error + */ +int disorder_tags(disorder_client *c, char ***tagsp, int *ntagsp); + /** @brief Unset a track preference * * Requires the 'prefs' right. @@ -379,6 +477,16 @@ int disorder_unset_global(disorder_client *c, const char *pref); */ int disorder_userinfo(disorder_client *c, const char *username, const char *property, char **valuep); +/** @brief Get a list of users + * + * + * + * @param usersp List of users + * @param nusersp Number of elements in usersp + * @return 0 on success, non-0 on error + */ +int disorder_users(disorder_client *c, char ***usersp, int *nusersp); + /** @brief Get the server version * * diff --git a/lib/client.c b/lib/client.c index 415823a..cb65114 100644 --- a/lib/client.c +++ b/lib/client.c @@ -698,45 +698,6 @@ static int disorder_simple_list(disorder_client *c, return readlist(c, vecp, nvecp); } -/** @brief List directories below @p dir - * @param c Client - * @param dir Directory to list, or NULL for root (UTF-8) - * @param re Regexp that results must match, or NULL (UTF-8) - * @param vecp Where to store list (UTF-8) - * @param nvecp Where to store number of items, or NULL - * @return 0 on success, non-0 on error - */ -int disorder_directories(disorder_client *c, const char *dir, const char *re, - char ***vecp, int *nvecp) { - return disorder_simple_list(c, vecp, nvecp, "dirs", dir, re, (char *)0); -} - -/** @brief List files below @p dir - * @param c Client - * @param dir Directory to list, or NULL for root (UTF-8) - * @param re Regexp that results must match, or NULL (UTF-8) - * @param vecp Where to store list (UTF-8) - * @param nvecp Where to store number of items, or NULL - * @return 0 on success, non-0 on error - */ -int disorder_files(disorder_client *c, const char *dir, const char *re, - char ***vecp, int *nvecp) { - return disorder_simple_list(c, vecp, nvecp, "files", dir, re, (char *)0); -} - -/** @brief List files and directories below @p dir - * @param c Client - * @param dir Directory to list, or NULL for root (UTF-8) - * @param re Regexp that results must match, or NULL (UTF-8) - * @param vecp Where to store list (UTF-8) - * @param nvecp Where to store number of items, or NULL - * @return 0 on success, non-0 on error - */ -int disorder_allfiles(disorder_client *c, const char *dir, const char *re, - char ***vecp, int *nvecp) { - return disorder_simple_list(c, vecp, nvecp, "allfiles", dir, re, (char *)0); -} - /** @brief Return the user we logged in with * @param c Client * @return User name (owned by @p c, don't modify) @@ -817,29 +778,6 @@ int disorder_length(disorder_client *c, const char *track, return 0; } -/** @brief Search for tracks - * @param c Client - * @param terms Search terms (UTF-8) - * @param vecp Where to store list (UTF-8) - * @param nvecp Where to store number of items, or NULL - * @return 0 on success, non-0 on error - */ -int disorder_search(disorder_client *c, const char *terms, - char ***vecp, int *nvecp) { - return disorder_simple_list(c, vecp, nvecp, "search", terms, (char *)0); -} - -/** @brief Get server stats - * @param c Client - * @param vecp Where to store list (UTF-8) - * @param nvecp Where to store number of items, or NULL - * @return 0 on success, non-0 on error - */ -int disorder_stats(disorder_client *c, - char ***vecp, int *nvecp) { - return disorder_simple_list(c, vecp, nvecp, "stats", (char *)0); -} - /** @brief Set volume * @param c Client * @param left New left channel value @@ -896,28 +834,6 @@ int disorder_log(disorder_client *c, struct sink *s) { return 0; } -/** @brief List all known tags - * @param c Client - * @param vecp Where to store list (UTF-8) - * @param nvecp Where to store number of items, or NULL - * @return 0 on success, non-0 on error - */ -int disorder_tags(disorder_client *c, - char ***vecp, int *nvecp) { - return disorder_simple_list(c, vecp, nvecp, "tags", (char *)0); -} - -/** @brief List all known users - * @param c Client - * @param vecp Where to store list (UTF-8) - * @param nvecp Where to store number of items, or NULL - * @return 0 on success, non-0 on error - */ -int disorder_users(disorder_client *c, - char ***vecp, int *nvecp) { - return disorder_simple_list(c, vecp, nvecp, "users", (char *)0); -} - /** @brief Get recently added tracks * @param c Client * @param vecp Where to store pointer to list (UTF-8) @@ -958,16 +874,6 @@ int disorder_rtp_address(disorder_client *c, char **addressp, char **portp) { return 0; } -/** @brief List scheduled events - * @param c Client - * @param idsp Where to put list of event IDs - * @param nidsp Where to put count of event IDs, or NULL - * @return 0 on success, non-0 on error - */ -int disorder_schedule_list(disorder_client *c, char ***idsp, int *nidsp) { - return disorder_simple_list(c, idsp, nidsp, "schedule-list", (char *)0); -} - /** @brief Get details of a scheduled event * @param c Client * @param id Event ID @@ -1037,31 +943,6 @@ int disorder_schedule_add(disorder_client *c, return rc; } -/** @brief Get the contents of a playlist - * @param c Client - * @param playlist Playlist to get - * @param tracksp Where to put list of tracks - * @param ntracksp Where to put count of tracks - * @return 0 on success, non-0 on error - */ -int disorder_playlist_get(disorder_client *c, const char *playlist, - char ***tracksp, int *ntracksp) { - return disorder_simple_list(c, tracksp, ntracksp, - "playlist-get", playlist, (char *)0); -} - -/** @brief List all readable playlists - * @param c Client - * @param playlistsp Where to put list of playlists - * @param nplaylistsp Where to put count of playlists - * @return 0 on success, non-0 on error - */ -int disorder_playlists(disorder_client *c, - char ***playlistsp, int *nplaylistsp) { - return disorder_simple_list(c, playlistsp, nplaylistsp, - "playlists", (char *)0); -} - /** @brief Set the contents of a playlst * @param c Client * @param playlist Playlist to modify diff --git a/lib/client.h b/lib/client.h index 34ac4b3..c4b19e4 100644 --- a/lib/client.h +++ b/lib/client.h @@ -60,8 +60,6 @@ int disorder_rescan(disorder_client *c); int disorder_playing(disorder_client *c, struct queue_entry **qp); int disorder_recent(disorder_client *c, struct queue_entry **qp); int disorder_queue(disorder_client *c, struct queue_entry **qp); -int disorder_directories(disorder_client *c, const char *dir, const char *re, - char ***vecp, int *nvecp); int disorder_files(disorder_client *c, const char *dir, const char *re, char ***vecp, int *nvecp); int disorder_allfiles(disorder_client *c, const char *dir, const char *re, diff --git a/scripts/protocol b/scripts/protocol index b3ba0fc..46a1cbf 100755 --- a/scripts/protocol +++ b/scripts/protocol @@ -76,7 +76,7 @@ sub simple { # string(CMD, SUMMARY, DETAIL, [[NAME,DESCR], [NAME,DESCR], ...], [RETURN, DESCR]) # -# Response is yes/no or failure +# Response is a string, or failure, or 555 for "none". sub string { my $cmd = shift; my $summary = shift; @@ -117,9 +117,10 @@ sub string { # TODO } -# string(CMD, SUMMARY, DETAIL, [[NAME,DESCR], [NAME,DESCR], ...]) +# string_login(CMD, SUMMARY, DETAIL, [[NAME,DESCR], [NAME,DESCR], ...]) # -# Response is yes/no or failure +# Like string(), but the server returns a username, which we squirrel +# away rather than returning to the caller. sub string_login { my $cmd = shift; my $summary = shift; @@ -210,6 +211,50 @@ sub boolean { # TODO } +# list(CMD, SUMMARY, DETAIL, [[NAME,DESCR], [NAME,DESCR], ...], [RETURN, DESCR]) +# +# Response is a a list of strings in a dot-stuffed body +sub list { + my $cmd = shift; + my $summary = shift; + my $detail = shift; + my $args = shift; + my $return = shift; + + my $cmdc = $cmd; + $cmdc =~ s/-/_/g; + # Synchronous C API + push(@h, "/** \@brief $summary\n", + " *\n", + " * $detail\n", + " *\n", + map(" * \@param $_->[0] $_->[1]\n", @$args), + " * \@param $return->[0]p $return->[1]\n", + " * \@param n$return->[0]p Number of elements in $return->[0]p\n", + " * \@return 0 on success, non-0 on error\n", + " */\n", + "int disorder_$cmdc(disorder_client *c", + map(", const char *$_->[0]", @$args), + ", char ***$return->[0]p, int *n$return->[0]p);\n", + "\n"); + push(@c, "int disorder_$cmdc(disorder_client *c", + map(", const char *$_->[0]", @$args), + ", char ***$return->[0]p, int *n$return->[0]p) {\n", + " return disorder_simple_list(c, $return->[0]p, n$return->[0]p, \"$cmd\"", + map(", $_->[0]", @$args), + ", (char *)0);\n", + "}\n\n"); + + # Asynchronous C API + # TODO + + # Python API + # TODO + + # Java API + # TODO +} + # TODO other command classes # Front matter ---------------------------------------------------------------- @@ -255,7 +300,12 @@ simple("adduser", ["password", "Initial password"], ["rights", "Initial rights (optional)"]]); -# TODO allfiles +list("allfiles", + "List files and directories in a directory", + "See 'files' and 'dirs' for more specific lists.", + [["dir", "Directory to list (optional)"], + ["re", "Regexp that results must match (optional)"]], + ["files", "List of matching files and directories"]); string_login("confirm", "Confirm registration", @@ -273,7 +323,12 @@ simple("deluser", "Requires the 'admin' right.", [["user", "User to delete"]]); -# TODO dirs +list("dirs", + "List directories in a directory", + "", + [["dir", "Directory to list (optional)"], + ["re", "Regexp that results must match (optional)"]], + ["files", "List of matching directories"]); simple("disable", "Disable play", @@ -304,7 +359,12 @@ boolean("exists", [["track", "Track name"]], ["exists", "1 if the track exists and 0 otherwise"]); -# TODO files +list("files", + "List files in a directory", + "", + [["dir", "Directory to list (optional)"], + ["re", "Regexp that results must match (optional)"]], + ["files", "List of matching files"]); string("get", "Get a track preference", @@ -362,14 +422,11 @@ simple("playlist-delete", "Requires the 'play' right and permission to modify the playlist.", [["playlist", "Playlist to delete"]]); -# TODO playlist-get - -# TODO playlist-get-share - -simple("playlist-lock", - "Lock a playlist", - "Requires the 'play' right and permission to modify the playlist. A given connection may lock at most one playlist.", - [["playlist", "Playlist to delete"]]); +list("playlist-get", + "List the contents of a playlist", + "Requires the 'read' right and oermission to read the playlist.", + [["playlist", "Playlist name"]], + ["tracks", "List of tracks in playlist"]); string("playlist-get-share", "Get a playlist's sharing status", @@ -377,6 +434,11 @@ string("playlist-get-share", [["playlist", "Playlist to read"]], ["share", "Sharing status (\"public\", \"private\" or \"shared\")"]); +simple("playlist-lock", + "Lock a playlist", + "Requires the 'play' right and permission to modify the playlist. A given connection may lock at most one playlist.", + [["playlist", "Playlist to delete"]]); + simple("playlist-set-share", "Set a playlist's sharing status", "Requires the 'play' right and permission to modify the playlist.", @@ -388,7 +450,11 @@ simple("playlist-unlock", "The playlist to unlock is implicit in the connection.", []); -# TODO playlists +list("playlists", + "List playlists", + "Requires the 'read' right. Only playlists that you have permission to read are returned.", + [], + ["playlists", "Playlist names"]); # TODO prefs @@ -472,9 +538,17 @@ simple("schedule-del", # TODO schedule-get -# TODO schedule-list +list("schedule-list", + "List scheduled events", + "This just lists IDs. Use 'schedule-get' to retrieve more detail", + [], + ["ids", "List of event IDs"]); -# TODO search +list("search", + "Search for tracks", + "Terms are either keywords or tags formatted as 'tag:TAG-NAME'.", + [["terms", "List of search terms"]], + ["tracks", "List of matching tracks"]); simple("set", "Set a track preference", @@ -491,9 +565,17 @@ simple("set-global", # TODO shutdown (also needs documenting) -# TODO stats +list("stats", + "Get server statistics", + "The details of what the server reports are not really defined. The returned strings are intended to be printed out one to a line..", + [], + ["stats", "List of server information strings."]); -# TODO tags +list("tags", + "Get a list of known tags", + "Only tags which apply to at least one track are returned.", + [], + ["tags", "List of tags"]); simple("unset", "Unset a track preference", @@ -515,7 +597,11 @@ string("userinfo", ["property", "Property to read"]], ["value", "Value of property"]); -# TODO users +list("users", + "Get a list of users", + "", + [], + ["users", "List of users"]); string("version", "Get the server version",