From 0bc1d67cbb413a23b3cf3dce64be13738739b9d3 Mon Sep 17 00:00:00 2001 Message-Id: <0bc1d67cbb413a23b3cf3dce64be13738739b9d3.1715335067.git.mdw@distorted.org.uk> From: Mark Wooding Date: Sat, 5 Jun 2010 18:12:38 +0100 Subject: [PATCH] More commands. Organization: Straylight/Edgeware From: Richard Kettlewell --- lib/client-stubs.c | 14 +++++++++ lib/client-stubs.h | 35 +++++++++++++++++++++ lib/client.c | 35 ++++++++++++--------- lib/client.h | 76 ---------------------------------------------- scripts/protocol | 36 ++++++++++++++++------ 5 files changed, 97 insertions(+), 99 deletions(-) diff --git a/lib/client-stubs.c b/lib/client-stubs.c index b87b925..d0c3103 100644 --- a/lib/client-stubs.c +++ b/lib/client-stubs.c @@ -109,6 +109,16 @@ int disorder_make_cookie(disorder_client *c, char **cookiep) { return dequote(disorder_simple(c, cookiep, "make-cookie", (char *)0), cookiep); } +int disorder_move(disorder_client *c, const char *track, long delta) { + char buf_delta[16]; + byte_snprintf(buf_delta, sizeof buf_delta, "%ld", delta); + return disorder_simple(c, 0, "move", track, buf_delta, (char *)0); +} + +int disorder_moveafter(disorder_client *c, const char *target, char **ids, int nids) { + return disorder_simple(c, 0, "moveafter", target, disorder_list, ids, nids, (char *)0); +} + int disorder_nop(disorder_client *c) { return disorder_simple(c, 0, "nop", (char *)0); } @@ -125,6 +135,10 @@ int disorder_play(disorder_client *c, const char *track, char **idp) { return dequote(disorder_simple(c, idp, "play", track, (char *)0), idp); } +int disorder_playafter(disorder_client *c, const char *target, char **tracks, int ntracks) { + return disorder_simple(c, 0, "playafter", target, disorder_list, tracks, ntracks, (char *)0); +} + int disorder_playlist_delete(disorder_client *c, const char *playlist) { return disorder_simple(c, 0, "playlist-delete", playlist, (char *)0); } diff --git a/lib/client-stubs.h b/lib/client-stubs.h index 231238a..f6c32c8 100644 --- a/lib/client-stubs.h +++ b/lib/client-stubs.h @@ -200,6 +200,29 @@ int disorder_length(disorder_client *c, const char *track, long *lengthp); */ int disorder_make_cookie(disorder_client *c, char **cookiep); +/** @brief Move a track + * + * Requires one of the 'move mine', 'move random' or 'move any' rights depending on how the track came to be added to the queue. + * + * @param c Client + * @param track Track ID or name + * @param delta How far to move the track towards the head of the queue + * @return 0 on success, non-0 on error + */ +int disorder_move(disorder_client *c, const char *track, long delta); + +/** @brief Move multiple tracks + * + * Requires one of the 'move mine', 'move random' or 'move any' rights depending on how the track came to be added to the queue. + * + * @param c Client + * @param target Move after this track, or to head if "" + * @param ids List of tracks to move by ID + * @param nids Length of ids + * @return 0 on success, non-0 on error + */ +int disorder_moveafter(disorder_client *c, const char *target, char **ids, int nids); + /** @brief Do nothing * * Used as a keepalive. No authentication required. @@ -242,6 +265,18 @@ int disorder_pause(disorder_client *c); */ int disorder_play(disorder_client *c, const char *track, char **idp); +/** @brief Play multiple tracks + * + * Requires the 'play' right. + * + * @param c Client + * @param target Insert into queue after this track, or at head if "" + * @param tracks List of track names to play + * @param ntracks Length of tracks + * @return 0 on success, non-0 on error + */ +int disorder_playafter(disorder_client *c, const char *target, char **tracks, int ntracks); + /** @brief Delete a playlist * * Requires the 'play' right and permission to modify the playlist. diff --git a/lib/client.c b/lib/client.c index acd20eb..c96e2f3 100644 --- a/lib/client.c +++ b/lib/client.c @@ -154,6 +154,9 @@ static int check_response(disorder_client *c, char **rp) { /** @brief Marker for a command body */ static const char disorder_body[1]; +/** @brief Marker for a list of args */ +static const char disorder_list[1]; + /** @brief Issue a command and parse a simple response * @param c Client * @param rp Where to store result, or NULL @@ -171,7 +174,13 @@ static const char disorder_body[1]; * * Put @ref disorder_body in the argument list followed by a char ** * and int giving the body to follow the command. If the int is @c -1 - * then the list is assumed to be NULL-terminated. + * then the list is assumed to be NULL-terminated. This may be used + * only once. + * + * Put @ref disorder_list in the argument list followed by a char ** + * and int giving a list of arguments to include. If the int is @c -1 + * then the list is assumed to be NULL-terminated. This may be used + * any number of times. * * Usually you would call this via one of the following interfaces: * - disorder_simple() @@ -200,6 +209,17 @@ static int disorder_simple_v(disorder_client *c, body = va_arg(ap, char **); nbody = va_arg(ap, int); has_body = 1; + } else if(arg == disorder_list) { + char **list = va_arg(ap, char **); + int nlist = va_arg(ap, int); + if(nlist < 0) { + for(nlist = 0; list[nlist]; ++nlist) + ; + } + for(int n = 0; n < nlist; ++n) { + dynstr_append(&d, ' '); + dynstr_append_string(&d, quoteutf8(arg)); + } } else { dynstr_append(&d, ' '); dynstr_append_string(&d, quoteutf8(arg)); @@ -507,19 +527,6 @@ int disorder_close(disorder_client *c) { return ret; } -/** @brief Move a track - * @param c Client - * @param track Track to move (UTF-8) - * @param delta Distance to move by - * @return 0 on success, non-0 on error - */ -int disorder_move(disorder_client *c, const char *track, int delta) { - char d[16]; - - byte_snprintf(d, sizeof d, "%d", delta); - return disorder_simple(c, 0, "move", track, d, (char *)0); -} - static void client_error(const char *msg, void attribute((unused)) *u) { disorder_error(0, "error parsing reply: %s", msg); diff --git a/lib/client.h b/lib/client.h index 4453fc3..6db0eb8 100644 --- a/lib/client.h +++ b/lib/client.h @@ -47,77 +47,18 @@ int disorder_connect_generic(struct config *conf, const char *password, const char *cookie); int disorder_close(disorder_client *c); -int disorder_version(disorder_client *c, char **versionp); -int disorder_remove(disorder_client *c, const char *track); -int disorder_move(disorder_client *c, const char *track, int delta); -int disorder_enable(disorder_client *c); -int disorder_disable(disorder_client *c); -int disorder_scratch(disorder_client *c, const char *id); -int disorder_shutdown(disorder_client *c); -int disorder_reconfigure(disorder_client *c); -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_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, - char ***vecp, int *nvecp); char *disorder_user(disorder_client *c); -int disorder_exists(disorder_client *c, const char *track, int *existsp); -int disorder_enabled(disorder_client *c, int *enabledp); -int disorder_set(disorder_client *c, const char *track, - const char *key, const char *value); -int disorder_unset(disorder_client *c, const char *track, - const char *key); -int disorder_get(disorder_client *c, const char *track, const char *key, - char **valuep); int disorder_prefs(disorder_client *c, const char *track, struct kvp **kp); -int disorder_length(disorder_client *c, const char *track, - long *valuep); -int disorder_search(disorder_client *c, const char *terms, - char ***vecp, int *nvecp); -int disorder_random_enable(disorder_client *c); -int disorder_random_disable(disorder_client *c); -int disorder_random_enabled(disorder_client *c, int *enabledp); -int disorder_stats(disorder_client *c, - char ***vecp, int *nvecp); int disorder_set_volume(disorder_client *c, int left, int right); int disorder_get_volume(disorder_client *c, int *left, int *right); int disorder_log(disorder_client *c, struct sink *s); -int disorder_pause(disorder_client *c); -int disorder_resume(disorder_client *c); -int disorder_tags(disorder_client *c, - char ***vecp, int *nvecp); -int disorder_set_global(disorder_client *c, - const char *key, const char *value); -int disorder_unset_global(disorder_client *c, const char *key); -int disorder_get_global(disorder_client *c, const char *key, char **valuep); int disorder_new_tracks(disorder_client *c, char ***vecp, int *nvecp, int max); int disorder_rtp_address(disorder_client *c, char **addressp, char **portp); -int disorder_adduser(disorder_client *c, - const char *user, const char *password, - const char *rights); -int disorder_deluser(disorder_client *c, const char *user); -int disorder_userinfo(disorder_client *c, const char *user, const char *key, - char **valuep); -int disorder_edituser(disorder_client *c, const char *user, - const char *key, const char *value); -int disorder_users(disorder_client *c, - char ***vecp, int *nvecp); -int disorder_register(disorder_client *c, const char *user, - const char *password, const char *email, - char **confirmp); -int disorder_confirm(disorder_client *c, const char *confirm); -int disorder_make_cookie(disorder_client *c, char **cookiep); const char *disorder_last(disorder_client *c); -int disorder_revoke(disorder_client *c); -int disorder_reminder(disorder_client *c, const char *user); -int disorder_schedule_list(disorder_client *c, char ***idsp, int *nidsp); -int disorder_schedule_del(disorder_client *c, const char *id); int disorder_schedule_get(disorder_client *c, const char *id, struct kvp **actiondatap); int disorder_schedule_add(disorder_client *c, @@ -125,23 +66,6 @@ int disorder_schedule_add(disorder_client *c, const char *priority, const char *action, ...); -int disorder_adopt(disorder_client *c, const char *id); -int disorder_playlist_delete(disorder_client *c, - const char *playlist); -int disorder_playlist_get(disorder_client *c, const char *playlist, - char ***tracksp, int *ntracksp); -int disorder_playlists(disorder_client *c, - char ***playlistsp, int *nplaylists); -int disorder_playlist_get_share(disorder_client *c, const char *playlist, - char **sharep); -int disorder_playlist_set_share(disorder_client *c, const char *playlist, - const char *share); -int disorder_playlist_lock(disorder_client *c, const char *playlist); -int disorder_playlist_unlock(disorder_client *c); -int disorder_playlist_set(disorder_client *c, - const char *playlist, - char **tracks, - int ntracks); #include "client-stubs.h" diff --git a/scripts/protocol b/scripts/protocol index dfdc795..118fda3 100755 --- a/scripts/protocol +++ b/scripts/protocol @@ -44,7 +44,7 @@ sub c_in_decl { return "const char *$name"; } elsif($type eq 'integer') { return "long $name"; - } elsif($type eq 'list') { + } elsif($type eq 'list' or $type eq 'body') { return ("char **$name", "int n$name"); } else { @@ -78,7 +78,7 @@ sub c_param_docs { my $args = shift; my @d = (); for my $arg (@$args) { - if($arg->[0] eq 'list') { + if($arg->[0] eq 'body' or $arg->[0] eq 'list') { push(@d, " * \@param $arg->[1] $arg->[2]\n", " * \@param n$arg->[1] Length of $arg->[1]\n"); @@ -144,10 +144,16 @@ sub simple { if(!defined $return) { my @cargs = (); for my $arg (@$args) { - if($arg->[0] eq 'list') { - push(@cargs, "disorder_body", $arg->[1], "n$arg->[1]"); - } else { + if($arg->[0] eq 'body' or $arg->[0] eq 'list') { + push(@cargs, "disorder_$arg->[0]", $arg->[1], "n$arg->[1]"); + } elsif($arg->[0] eq 'string') { push(@cargs, $arg->[1]); + } elsif($arg->[0] eq 'integer') { + push(@cargs, "buf_$arg->[1]"); + push(@c, " char buf_$arg->[1]\[16];\n", + " byte_snprintf(buf_$arg->[1], sizeof buf_$arg->[1], \"%ld\", $arg->[1]);\n"); + } else { + die "$0: unsupported arg type '$arg->[0]' for '$cmd'\n"; } } push(@c, " return disorder_simple(", @@ -383,9 +389,17 @@ simple("make-cookie", [], ["string", "cookie", "Newly created cookie"]); -# TODO move +simple("move", + "Move a track", + "Requires one of the 'move mine', 'move random' or 'move any' rights depending on how the track came to be added to the queue.", + [["string", "track", "Track ID or name"], + ["integer", "delta", "How far to move the track towards the head of the queue"]]); -# TODO moveafter +simple("moveafter", + "Move multiple tracks", + "Requires one of the 'move mine', 'move random' or 'move any' rights depending on how the track came to be added to the queue.", + [["string", "target", "Move after this track, or to head if \"\""], + ["list", "ids", "List of tracks to move by ID"]]); # TODO new @@ -413,7 +427,11 @@ simple("play", [["string", "track", "Track to play"]], ["string", "id", "Queue ID of new track"]); -# TODO playafter +simple("playafter", + "Play multiple tracks", + "Requires the 'play' right.", + [["string", "target", "Insert into queue after this track, or at head if \"\""], + ["list", "tracks", "List of track names to play"]]); # TODO playing @@ -443,7 +461,7 @@ simple("playlist-set", "Set the contents of a playlist", "Requires the 'play' right and permission to modify the playlist, which must be locked.", [["string", "playlist", "Playlist to modify"], - ["list", "tracks", "New list of tracks for playlist"]]); + ["body", "tracks", "New list of tracks for playlist"]]); simple("playlist-set-share", "Set a playlist's sharing status", -- [mdw]