mirror of
https://github.com/owntone/owntone-server.git
synced 2024-12-25 22:55:56 -05:00
[jsonapi] Add support for updating queue_item metadata (closes #1153)
This commit also changes db.c's sort_tag_create to always recreate sort tags, so that they match source tags, should they have changed. Unclear to me why the previous solution didn't do that, so will probably regret this change when it dawns on me.
This commit is contained in:
parent
275d66b6ad
commit
aaffa4a83f
@ -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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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**
|
**Endpoint**
|
||||||
|
|
||||||
@ -711,6 +711,13 @@ PUT /api/queue/items/{id}
|
|||||||
| Parameter | Value |
|
| Parameter | Value |
|
||||||
| --------------- | ----------------------------------------------------------- |
|
| --------------- | ----------------------------------------------------------- |
|
||||||
| new_position | The new position for the queue item in the current queue. |
|
| 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**
|
**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"
|
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
|
### Removing a queue item
|
||||||
|
|
||||||
|
13
src/db.c
13
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 */
|
/* Note: include terminating NUL in string length for u8_normalize */
|
||||||
|
|
||||||
if (*sort_tag)
|
free(*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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!src_tag || ((len = strlen(src_tag)) == 0))
|
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, " \
|
"file_id = %d, song_length = %d, data_kind = %d, media_kind = %d, " \
|
||||||
"pos = %d, shuffle_pos = %d, path = '%q', virtual_path = %Q, " \
|
"pos = %d, shuffle_pos = %d, path = '%q', virtual_path = %Q, " \
|
||||||
"title = %Q, artist = %Q, album_artist = %Q, album = %Q, " \
|
"title = %Q, artist = %Q, album_artist = %Q, album = %Q, " \
|
||||||
"composer = %Q," \
|
"composer = %Q, " \
|
||||||
"genre = %Q, time_modified = %d, " \
|
"genre = %Q, time_modified = %d, " \
|
||||||
"songalbumid = %" PRIi64 ", songartistid = %" PRIi64 ", " \
|
"songalbumid = %" PRIi64 ", songartistid = %" PRIi64 ", " \
|
||||||
"artist_sort = %Q, album_sort = %Q, album_artist_sort = %Q, " \
|
"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;
|
char *query;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
fixup_tags_queue_item(qi);
|
||||||
|
|
||||||
queue_version = queue_transaction_begin();
|
queue_version = queue_transaction_begin();
|
||||||
|
|
||||||
query = sqlite3_mprintf(Q_TMPL,
|
query = sqlite3_mprintf(Q_TMPL,
|
||||||
|
@ -2533,33 +2533,15 @@ jsonapi_reply_queue_tracks_add(struct httpd_request *hreq)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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;
|
uint32_t new_position;
|
||||||
const char *param;
|
|
||||||
struct player_status status;
|
struct player_status status;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = safe_atou32(hreq->uri_parsed->path_parts[3], &item_id);
|
if (safe_atou32(new, &new_position) < 0)
|
||||||
if (ret < 0)
|
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_WEB, "No valid item id given '%s'\n", hreq->uri_parsed->path);
|
DPRINTF(E_LOG, L_WEB, "No valid item new_position '%s'\n", new);
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
return HTTP_BADREQUEST;
|
return HTTP_BADREQUEST;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2568,10 +2550,60 @@ jsonapi_reply_queue_tracks_move(struct httpd_request *hreq)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_WEB, "Moving item '%d' to new position %d failed\n", item_id, new_position);
|
DPRINTF(E_LOG, L_WEB, "Moving item '%d' to new position %d failed\n", item_id, new_position);
|
||||||
|
|
||||||
return HTTP_INTERNAL;
|
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;
|
return HTTP_NOCONTENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4345,7 +4377,7 @@ static struct httpd_uri_map adm_handlers[] =
|
|||||||
{ EVHTTP_REQ_GET, "^/api/queue$", jsonapi_reply_queue },
|
{ EVHTTP_REQ_GET, "^/api/queue$", jsonapi_reply_queue },
|
||||||
{ EVHTTP_REQ_PUT, "^/api/queue/clear$", jsonapi_reply_queue_clear },
|
{ EVHTTP_REQ_PUT, "^/api/queue/clear$", jsonapi_reply_queue_clear },
|
||||||
{ EVHTTP_REQ_POST, "^/api/queue/items/add$", jsonapi_reply_queue_tracks_add },
|
{ 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_DELETE, "^/api/queue/items/[[:digit:]]+$", jsonapi_reply_queue_tracks_delete },
|
||||||
{ EVHTTP_REQ_POST, "^/api/queue/save$", jsonapi_reply_queue_save},
|
{ EVHTTP_REQ_POST, "^/api/queue/save$", jsonapi_reply_queue_save},
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user