diff --git a/README_JSON_API.md b/README_JSON_API.md index c58880ff..aa847007 100644 --- a/README_JSON_API.md +++ b/README_JSON_API.md @@ -529,7 +529,7 @@ curl -X PUT "http://localhost:3689/api/outputs/0/toggle" | GET | [/api/queue](#list-queue-items) | Get a list of queue items | | PUT | [/api/queue/clear](#clearing-the-queue) | Remove all items from the queue | | POST | [/api/queue/items/add](#adding-items-to-the-queue) | Add items to the queue | -| PUT | [/api/queue/items/{id}](#moving-a-queue-item) | Move a queue item in the queue | +| PUT | [/api/queue/items/{id}](#updating-a-queue-item) | Updating a queue item in the queue | | DELETE | [/api/queue/items/{id}](#removing-a-queue-item) | Remove a queue item form the queue | @@ -690,9 +690,9 @@ curl -X POST "http://localhost:3689/api/queue/items/add?limit=10&clear=true&play } ``` -### Moving a queue item +### Updating a queue item -Move a queue item in the current queue +Update or move a queue item in the current queue **Endpoint** @@ -711,6 +711,13 @@ PUT /api/queue/items/{id} | Parameter | Value | | --------------- | ----------------------------------------------------------- | | new_position | The new position for the queue item in the current queue. | +| title | New track title | +| album | New album title | +| artist | New artist | +| album_artist | New album artist | +| composer | New composer | +| genre | New genre | +| artwork_url | New URL to track artwork | **Response** @@ -722,6 +729,9 @@ On success returns the HTTP `204 No Content` success status response code. curl -X PUT "http://localhost:3689/api/queue/items/3?new_position=0" ``` +```shell +curl -X PUT "http://localhost:3689/api/queue/items/3?title=Awesome%20title&artwork_url=http%3A%2F%2Fgyfgafguf.dk%2Fimages%2Fpige3.jpg" +``` ### Removing a queue item diff --git a/src/db.c b/src/db.c index cd2a98cf..cb1f1172 100644 --- a/src/db.c +++ b/src/db.c @@ -760,14 +760,7 @@ sort_tag_create(char **sort_tag, const char *src_tag) /* Note: include terminating NUL in string length for u8_normalize */ - if (*sort_tag) - { - DPRINTF(E_DBG, L_DB, "Existing sort tag will be normalized: %s\n", *sort_tag); - o_ptr = u8_normalize(UNINORM_NFD, (uint8_t *)*sort_tag, strlen(*sort_tag) + 1, NULL, &len); - free(*sort_tag); - *sort_tag = (char *)o_ptr; - return; - } + free(*sort_tag); if (!src_tag || ((len = strlen(src_tag)) == 0)) { @@ -4774,7 +4767,7 @@ db_queue_update_item(struct db_queue_item *qi) "file_id = %d, song_length = %d, data_kind = %d, media_kind = %d, " \ "pos = %d, shuffle_pos = %d, path = '%q', virtual_path = %Q, " \ "title = %Q, artist = %Q, album_artist = %Q, album = %Q, " \ - "composer = %Q," \ + "composer = %Q, " \ "genre = %Q, time_modified = %d, " \ "songalbumid = %" PRIi64 ", songartistid = %" PRIi64 ", " \ "artist_sort = %Q, album_sort = %Q, album_artist_sort = %Q, " \ @@ -4786,6 +4779,8 @@ db_queue_update_item(struct db_queue_item *qi) char *query; int ret; + fixup_tags_queue_item(qi); + queue_version = queue_transaction_begin(); query = sqlite3_mprintf(Q_TMPL, diff --git a/src/httpd_jsonapi.c b/src/httpd_jsonapi.c index 8f7e12c7..be1d1984 100644 --- a/src/httpd_jsonapi.c +++ b/src/httpd_jsonapi.c @@ -2533,33 +2533,15 @@ jsonapi_reply_queue_tracks_add(struct httpd_request *hreq) } static int -jsonapi_reply_queue_tracks_move(struct httpd_request *hreq) +update_pos(uint32_t item_id, const char *new) { - uint32_t item_id; uint32_t new_position; - const char *param; struct player_status status; int ret; - ret = safe_atou32(hreq->uri_parsed->path_parts[3], &item_id); - if (ret < 0) + if (safe_atou32(new, &new_position) < 0) { - DPRINTF(E_LOG, L_WEB, "No valid item id given '%s'\n", hreq->uri_parsed->path); - - return HTTP_BADREQUEST; - } - - param = evhttp_find_header(hreq->query, "new_position"); - if (!param) - { - DPRINTF(E_LOG, L_WEB, "Missing parameter 'new_position'\n"); - - return HTTP_BADREQUEST; - } - if (safe_atou32(param, &new_position) < 0) - { - DPRINTF(E_LOG, L_WEB, "No valid item new_position '%s'\n", param); - + DPRINTF(E_LOG, L_WEB, "No valid item new_position '%s'\n", new); return HTTP_BADREQUEST; } @@ -2568,10 +2550,60 @@ jsonapi_reply_queue_tracks_move(struct httpd_request *hreq) if (ret < 0) { DPRINTF(E_LOG, L_WEB, "Moving item '%d' to new position %d failed\n", item_id, new_position); - return HTTP_INTERNAL; } + return HTTP_OK; +} + +static inline void +update_str(char **str, const char *new) +{ + free(*str); + *str = strdup(new); +} + +static int +jsonapi_reply_queue_tracks_update(struct httpd_request *hreq) +{ + struct db_queue_item *queue_item; + uint32_t item_id; + const char *param; + bool is_changed; + int ret; + + ret = safe_atou32(hreq->uri_parsed->path_parts[3], &item_id); + if (ret < 0 || !(queue_item = db_queue_fetch_byitemid(item_id))) + { + DPRINTF(E_LOG, L_WEB, "No valid item id given '%s'\n", hreq->uri_parsed->path); + return HTTP_BADREQUEST; + } + + ret = HTTP_OK; + is_changed = false; + if ((param = evhttp_find_header(hreq->query, "new_position"))) + ret = update_pos(item_id, param); + if ((param = evhttp_find_header(hreq->query, "title")) && (is_changed = true)) + update_str(&queue_item->title, param); + if ((param = evhttp_find_header(hreq->query, "album")) && (is_changed = true)) + update_str(&queue_item->album, param); + if ((param = evhttp_find_header(hreq->query, "artist")) && (is_changed = true)) + update_str(&queue_item->artist, param); + if ((param = evhttp_find_header(hreq->query, "album_artist")) && (is_changed = true)) + update_str(&queue_item->album_artist, param); + if ((param = evhttp_find_header(hreq->query, "composer")) && (is_changed = true)) + update_str(&queue_item->composer, param); + if ((param = evhttp_find_header(hreq->query, "genre")) && (is_changed = true)) + update_str(&queue_item->genre, param); + if ((param = evhttp_find_header(hreq->query, "artwork_url")) && (is_changed = true)) + update_str(&queue_item->artwork_url, param); + + if (ret != HTTP_OK) + return ret; + + if (is_changed) + db_queue_update_item(queue_item); + return HTTP_NOCONTENT; } @@ -4345,7 +4377,7 @@ static struct httpd_uri_map adm_handlers[] = { EVHTTP_REQ_GET, "^/api/queue$", jsonapi_reply_queue }, { EVHTTP_REQ_PUT, "^/api/queue/clear$", jsonapi_reply_queue_clear }, { EVHTTP_REQ_POST, "^/api/queue/items/add$", jsonapi_reply_queue_tracks_add }, - { EVHTTP_REQ_PUT, "^/api/queue/items/[[:digit:]]+$", jsonapi_reply_queue_tracks_move }, + { EVHTTP_REQ_PUT, "^/api/queue/items/[[:digit:]]+$", jsonapi_reply_queue_tracks_update }, { EVHTTP_REQ_DELETE, "^/api/queue/items/[[:digit:]]+$", jsonapi_reply_queue_tracks_delete }, { EVHTTP_REQ_POST, "^/api/queue/save$", jsonapi_reply_queue_save},