From c3ab6e6a1ece1a400108dc4838141fa8f1869233 Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Thu, 5 Jan 2023 17:35:22 -0500 Subject: [PATCH] Add support for expanding playlists --- htdocs/js/mpd.js | 4 ++- src/mpd_client.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++-- src/mpd_client.h | 3 +- 3 files changed, 86 insertions(+), 4 deletions(-) diff --git a/htdocs/js/mpd.js b/htdocs/js/mpd.js index 8b571e2..a6e7125 100644 --- a/htdocs/js/mpd.js +++ b/htdocs/js/mpd.js @@ -735,7 +735,9 @@ function webSocketConnect() { break; case 'plist': socket.send( - 'MPD_API_ADD_PLAYLIST,' + + 'MPD_API_EXPAND_PLAYLIST,' + + pagination + + ',' + decodeURIComponent( $(this).attr('uri') ) diff --git a/src/mpd_client.c b/src/mpd_client.c index c3601ee..522199d 100644 --- a/src/mpd_client.c +++ b/src/mpd_client.c @@ -227,9 +227,9 @@ int callback_mpd(struct mg_connection *c) { out_play_track: free(p_charbuf); break; - case MPD_API_ADD_PLAYLIST: + case MPD_API_EXPAND_PLAYLIST: p_charbuf = strdup(c->content); - if (strcmp(strtok(p_charbuf, ","), "MPD_API_ADD_PLAYLIST")) + if (strcmp(strtok(p_charbuf, ","), "MPD_API_EXPAND_PLAYLIST")) goto out_playlist; uint_buf = strtoul(strtok(NULL, ","), NULL, 10); @@ -504,6 +504,17 @@ char *mpd_get_title(struct mpd_song const *song) { return str; } +char *mpd_get_name(struct mpd_song const *song) { + char *str; + + str = (char *)mpd_song_get_tag(song, MPD_TAG_NAME, 0); + if (str == NULL) { + str = basename((char *)mpd_song_get_uri(song)); + } + + return str; +} + char *mpd_get_album(struct mpd_song const *song) { char *str; @@ -781,6 +792,74 @@ int mpd_put_browse(char *buffer, char *path, unsigned int offset) { return cur - buffer; } +int mpd_put_playlist(char *buffer, char *pl_name, unsigned int offset) { + char *cur = buffer; + const char *end = buffer + MAX_SIZE; + struct mpd_entity *entity; + unsigned int entity_count = 0; + + if (!mpd_send_list_playlist_meta(mpd.conn, pl_name)) + RETURN_ERROR_AND_RECOVER("mpd_send_list_playlist_meta"); + + cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"browse\",\"data\":[ "); + + while ((entity = mpd_recv_entity(mpd.conn)) != NULL) { + const struct mpd_song *song; + + if (offset > entity_count) { + mpd_entity_free(entity); + entity_count++; + continue; + } else if (offset + MAX_ELEMENTS_PER_PAGE - 1 < entity_count) { + mpd_entity_free(entity); + cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"wrap\",\"count\":"); + cur += json_emit_int(cur, end - cur, entity_count); + cur += json_emit_raw_str(cur, end - cur, "} "); + break; + } + + switch (mpd_entity_get_type(entity)) { + case MPD_ENTITY_TYPE_UNKNOWN: + break; + + case MPD_ENTITY_TYPE_DIRECTORY: + break; + + case MPD_ENTITY_TYPE_PLAYLIST: + break; + + case MPD_ENTITY_TYPE_SONG: + song = mpd_entity_get_song(entity); + cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"song\",\"uri\":"); + cur += json_emit_quoted_str(cur, end - cur, mpd_song_get_uri(song)); + cur += json_emit_raw_str(cur, end - cur, ",\"album\":"); + cur += json_emit_quoted_str(cur, end - cur, mpd_get_album(song)); + cur += json_emit_raw_str(cur, end - cur, ",\"artist\":"); + cur += json_emit_quoted_str(cur, end - cur, mpd_get_artist(song)); + cur += json_emit_raw_str(cur, end - cur, ",\"duration\":"); + cur += json_emit_int(cur, end - cur, mpd_song_get_duration(song)); + cur += json_emit_raw_str(cur, end - cur, ",\"title\":"); + cur += json_emit_quoted_str(cur, end - cur, mpd_get_name(song)); + cur += json_emit_raw_str(cur, end - cur, "},"); + break; + } + mpd_entity_free(entity); + entity_count++; + } + + if (mpd_connection_get_error(mpd.conn) != MPD_ERROR_SUCCESS || !mpd_response_finish(mpd.conn)) { + fprintf(stderr, "MPD mpd_send_list_playlist_meta: %s\n", mpd_connection_get_error_message(mpd.conn)); + mpd.conn_state = MPD_FAILURE; + return 0; + } + + /* remove last ',' */ + cur--; + + cur += json_emit_raw_str(cur, end - cur, "]}"); + return cur - buffer; +} + int mpd_search(char *buffer, char *searchstr) { int i = 0; char *cur = buffer; diff --git a/src/mpd_client.h b/src/mpd_client.h index ca9c6e3..384e983 100644 --- a/src/mpd_client.h +++ b/src/mpd_client.h @@ -44,7 +44,7 @@ X(MPD_API_GET_MPDHOST) \ X(MPD_API_ADD_TRACK) \ X(MPD_API_ADD_PLAY_TRACK) \ - X(MPD_API_ADD_PLAYLIST) \ + X(MPD_API_EXPAND_PLAYLIST) \ X(MPD_API_PLAY_TRACK) \ X(MPD_API_SAVE_QUEUE) \ X(MPD_API_RM_TRACK) \ @@ -120,6 +120,7 @@ int mpd_put_channels(char *buffer); int mpd_put_current_song(char *buffer); int mpd_put_queue(char *buffer, unsigned int offset); int mpd_put_browse(char *buffer, char *path, unsigned int offset); +int mpd_put_playlist(char *buffer, char *pl_name, unsigned int offset); int mpd_search(char *buffer, char *searchstr); void mpd_disconnect(); #endif -- 2.20.1