mirror of
https://github.com/owntone/owntone-server.git
synced 2025-04-29 06:37:56 -04:00
[db/queue] Support adding non-library items at a given position to the
queue
This commit is contained in:
parent
d2390933e9
commit
8d8663e93d
43
src/db.c
43
src/db.c
@ -4678,7 +4678,7 @@ queue_add_item(struct db_queue_item *item, int pos, int shuffle_pos, int queue_v
|
|||||||
|
|
||||||
query = sqlite3_mprintf(Q_TMPL,
|
query = sqlite3_mprintf(Q_TMPL,
|
||||||
item->file_id, item->song_length, item->data_kind, item->media_kind,
|
item->file_id, item->song_length, item->data_kind, item->media_kind,
|
||||||
pos, pos, item->path, item->virtual_path, item->title,
|
pos, shuffle_pos, item->path, item->virtual_path, item->title,
|
||||||
item->artist, item->album_artist, item->album, item->genre, item->songalbumid,
|
item->artist, item->album_artist, item->album, item->genre, item->songalbumid,
|
||||||
item->time_modified, item->artist_sort, item->album_sort, item->album_artist_sort, item->year,
|
item->time_modified, item->artist_sort, item->album_sort, item->album_artist_sort, item->year,
|
||||||
item->track, item->disc, queue_version);
|
item->track, item->disc, queue_version);
|
||||||
@ -4760,28 +4760,48 @@ db_queue_add_by_queryafteritemid(struct query_params *qp, uint32_t item_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
db_queue_add_start(struct db_queue_add_info *queue_add_info)
|
db_queue_add_start(struct db_queue_add_info *queue_add_info, int pos)
|
||||||
{
|
{
|
||||||
|
int queue_count;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
memset(queue_add_info, 0, sizeof(struct db_queue_add_info));
|
memset(queue_add_info, 0, sizeof(struct db_queue_add_info));
|
||||||
queue_add_info->queue_version = queue_transaction_begin();
|
queue_add_info->queue_version = queue_transaction_begin();
|
||||||
|
|
||||||
queue_add_info->pos = db_queue_get_count();
|
queue_count = db_queue_get_count();
|
||||||
if (queue_add_info->pos < 0)
|
if (queue_count < 0)
|
||||||
{
|
{
|
||||||
ret = -1;
|
ret = -1;
|
||||||
queue_transaction_end(ret, queue_add_info->queue_version);
|
queue_transaction_end(ret, queue_add_info->queue_version);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
queue_add_info->pos = queue_count;
|
||||||
|
queue_add_info->shuffle_pos = queue_count;
|
||||||
|
|
||||||
|
if (pos >= 0 && pos < queue_count)
|
||||||
|
queue_add_info->pos = pos;
|
||||||
|
|
||||||
|
queue_add_info->start_pos = queue_add_info->pos;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
db_queue_add_end(struct db_queue_add_info *queue_add_info, int ret)
|
db_queue_add_end(struct db_queue_add_info *queue_add_info, int ret)
|
||||||
{
|
{
|
||||||
|
char *query;
|
||||||
|
|
||||||
|
// Update pos for all items from the given position
|
||||||
|
if (ret == 0)
|
||||||
|
{
|
||||||
|
query = sqlite3_mprintf("UPDATE queue SET pos = pos + %d, queue_version = %d WHERE pos >= %d AND queue_version < %d;",
|
||||||
|
queue_add_info->count, queue_add_info->queue_version, queue_add_info->start_pos, queue_add_info->queue_version);
|
||||||
|
ret = db_query_run(query, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
queue_transaction_end(ret, queue_add_info->queue_version);
|
queue_transaction_end(ret, queue_add_info->queue_version);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -4790,9 +4810,16 @@ db_queue_add_item(struct db_queue_add_info *queue_add_info, struct db_queue_item
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
fixup_tags_queue_item(item);
|
fixup_tags_queue_item(item);
|
||||||
ret = queue_add_item(item, queue_add_info->pos, queue_add_info->pos, queue_add_info->queue_version);
|
ret = queue_add_item(item, queue_add_info->pos, queue_add_info->shuffle_pos, queue_add_info->queue_version);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
queue_add_info->pos++;
|
{
|
||||||
|
queue_add_info->pos++;
|
||||||
|
queue_add_info->shuffle_pos++;
|
||||||
|
queue_add_info->count++;
|
||||||
|
|
||||||
|
if (queue_add_info->new_item_id == 0)
|
||||||
|
queue_add_info->new_item_id = (int) sqlite3_last_insert_rowid(hdl);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
8
src/db.h
8
src/db.h
@ -474,7 +474,11 @@ struct db_queue_item
|
|||||||
struct db_queue_add_info
|
struct db_queue_add_info
|
||||||
{
|
{
|
||||||
int queue_version;
|
int queue_version;
|
||||||
|
int start_pos;
|
||||||
int pos;
|
int pos;
|
||||||
|
int shuffle_pos;
|
||||||
|
int count;
|
||||||
|
int new_item_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
char *
|
char *
|
||||||
@ -787,9 +791,9 @@ int
|
|||||||
db_queue_add_by_fileid(int id, char reshuffle, uint32_t item_id, int position, int *count, int *new_item_id);
|
db_queue_add_by_fileid(int id, char reshuffle, uint32_t item_id, int position, int *count, int *new_item_id);
|
||||||
|
|
||||||
int
|
int
|
||||||
db_queue_add_start(struct db_queue_add_info *queue_add_info);
|
db_queue_add_start(struct db_queue_add_info *queue_add_info, int pos);
|
||||||
|
|
||||||
void
|
int
|
||||||
db_queue_add_end(struct db_queue_add_info *queue_add_info, int ret);
|
db_queue_add_end(struct db_queue_add_info *queue_add_info, int ret);
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -1680,6 +1680,7 @@ jsonapi_reply_queue_tracks_add(struct httpd_request *hreq)
|
|||||||
char *uri;
|
char *uri;
|
||||||
const char *id;
|
const char *id;
|
||||||
int pos = -1;
|
int pos = -1;
|
||||||
|
int count = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
|
||||||
@ -1709,35 +1710,41 @@ jsonapi_reply_queue_tracks_add(struct httpd_request *hreq)
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
count = 0;
|
||||||
|
|
||||||
if (strncmp(uri, "library:artist:", strlen("library:artist:")) == 0)
|
if (strncmp(uri, "library:artist:", strlen("library:artist:")) == 0)
|
||||||
{
|
{
|
||||||
id = uri + (strlen("library:artist:"));
|
id = uri + (strlen("library:artist:"));
|
||||||
pos += queue_tracks_add_artist(id, pos);
|
count = queue_tracks_add_artist(id, pos);
|
||||||
}
|
}
|
||||||
else if (strncmp(uri, "library:album:", strlen("library:album:")) == 0)
|
else if (strncmp(uri, "library:album:", strlen("library:album:")) == 0)
|
||||||
{
|
{
|
||||||
id = uri + (strlen("library:album:"));
|
id = uri + (strlen("library:album:"));
|
||||||
pos += queue_tracks_add_album(id, pos);
|
count = queue_tracks_add_album(id, pos);
|
||||||
}
|
}
|
||||||
else if (strncmp(uri, "library:track:", strlen("library:track:")) == 0)
|
else if (strncmp(uri, "library:track:", strlen("library:track:")) == 0)
|
||||||
{
|
{
|
||||||
id = uri + (strlen("library:track:"));
|
id = uri + (strlen("library:track:"));
|
||||||
pos += queue_tracks_add_track(id, pos);
|
count = queue_tracks_add_track(id, pos);
|
||||||
}
|
}
|
||||||
else if (strncmp(uri, "library:playlist:", strlen("library:playlist:")) == 0)
|
else if (strncmp(uri, "library:playlist:", strlen("library:playlist:")) == 0)
|
||||||
{
|
{
|
||||||
id = uri + (strlen("library:playlist:"));
|
id = uri + (strlen("library:playlist:"));
|
||||||
pos += queue_tracks_add_playlist(id, pos);
|
count = queue_tracks_add_playlist(id, pos);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ret = library_queue_add(uri);
|
ret = library_queue_add(uri, pos, &count, NULL);
|
||||||
if (ret != LIBRARY_OK)
|
if (ret != LIBRARY_OK)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_WEB, "Invalid uri '%s'\n", uri);
|
DPRINTF(E_LOG, L_WEB, "Invalid uri '%s'\n", uri);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
pos += count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pos >= 0)
|
||||||
|
pos += count;
|
||||||
}
|
}
|
||||||
while ((uri = strtok(NULL, ",")));
|
while ((uri = strtok(NULL, ",")));
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ library_add_media(struct media_file_info *mfi)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
library_queue_add(const char *path)
|
library_queue_add(const char *path, int position, int *count, int *new_item_id)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int ret;
|
int ret;
|
||||||
@ -159,7 +159,7 @@ library_queue_add(const char *path)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = sources[i]->queue_add(path);
|
ret = sources[i]->queue_add(path, position, count, new_item_id);
|
||||||
|
|
||||||
if (ret == LIBRARY_OK)
|
if (ret == LIBRARY_OK)
|
||||||
{
|
{
|
||||||
|
@ -84,7 +84,7 @@ struct library_source
|
|||||||
/*
|
/*
|
||||||
* Add item for the given path to the current queue
|
* Add item for the given path to the current queue
|
||||||
*/
|
*/
|
||||||
int (*queue_add)(const char *path);
|
int (*queue_add)(const char *path, int position, int *count, int *new_item_id);
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -94,7 +94,7 @@ int
|
|||||||
library_add_playlist_info(const char *path, const char *title, const char *virtual_path, enum pl_type type, int parent_pl_id, int dir_id);
|
library_add_playlist_info(const char *path, const char *title, const char *virtual_path, enum pl_type type, int parent_pl_id, int dir_id);
|
||||||
|
|
||||||
int
|
int
|
||||||
library_queue_add(const char *path);
|
library_queue_add(const char *path, int position, int *count, int *new_item_id);
|
||||||
|
|
||||||
void
|
void
|
||||||
library_rescan();
|
library_rescan();
|
||||||
|
@ -1676,7 +1676,7 @@ map_media_file_to_queue_item(struct db_queue_item *queue_item, struct media_file
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
queue_add_stream(const char *path)
|
queue_add_stream(const char *path, int position, int *count, int *new_item_id)
|
||||||
{
|
{
|
||||||
struct media_file_info mfi;
|
struct media_file_info mfi;
|
||||||
struct db_queue_item item;
|
struct db_queue_item item;
|
||||||
@ -1690,11 +1690,18 @@ queue_add_stream(const char *path)
|
|||||||
|
|
||||||
map_media_file_to_queue_item(&item, &mfi);
|
map_media_file_to_queue_item(&item, &mfi);
|
||||||
|
|
||||||
ret = db_queue_add_start(&queue_add_info);
|
ret = db_queue_add_start(&queue_add_info, position);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
{
|
{
|
||||||
ret = db_queue_add_item(&queue_add_info, &item);
|
ret = db_queue_add_item(&queue_add_info, &item);
|
||||||
db_queue_add_end(&queue_add_info, ret);
|
ret = db_queue_add_end(&queue_add_info, ret);
|
||||||
|
if (ret == 0)
|
||||||
|
{
|
||||||
|
if (count)
|
||||||
|
*count = queue_add_info.count;
|
||||||
|
if (new_item_id)
|
||||||
|
*new_item_id = queue_add_info.new_item_id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free_queue_item(&item, 1);
|
free_queue_item(&item, 1);
|
||||||
@ -1704,11 +1711,11 @@ queue_add_stream(const char *path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
queue_add(const char *uri)
|
queue_add(const char *uri, int position, int *count, int *new_item_id)
|
||||||
{
|
{
|
||||||
if (strncasecmp(uri, "http://", strlen("http://")) == 0)
|
if (strncasecmp(uri, "http://", strlen("http://")) == 0)
|
||||||
{
|
{
|
||||||
queue_add_stream(uri);
|
queue_add_stream(uri, position, count, new_item_id);
|
||||||
return LIBRARY_OK;
|
return LIBRARY_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1699,7 +1699,7 @@ mpd_command_add(struct evbuffer *evbuf, int argc, char **argv, char **errmsg, st
|
|||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
{
|
{
|
||||||
// Given path is not in the library, check if it is possible to add as a non-library queue item
|
// Given path is not in the library, check if it is possible to add as a non-library queue item
|
||||||
ret = library_queue_add(argv[1]);
|
ret = library_queue_add(argv[1], -1, NULL, NULL);
|
||||||
if (ret != LIBRARY_OK)
|
if (ret != LIBRARY_OK)
|
||||||
{
|
{
|
||||||
*errmsg = safe_asprintf("Failed to add song '%s' to playlist (unkown path)", argv[1]);
|
*errmsg = safe_asprintf("Failed to add song '%s' to playlist (unkown path)", argv[1]);
|
||||||
@ -1737,7 +1737,7 @@ mpd_command_addid(struct evbuffer *evbuf, int argc, char **argv, char **errmsg,
|
|||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
{
|
{
|
||||||
// Given path is not in the library, directly add it as a new queue item
|
// Given path is not in the library, directly add it as a new queue item
|
||||||
ret = library_queue_add(argv[1]);
|
ret = library_queue_add(argv[1], to_pos, NULL, NULL);
|
||||||
if (ret != LIBRARY_OK)
|
if (ret != LIBRARY_OK)
|
||||||
{
|
{
|
||||||
*errmsg = safe_asprintf("Failed to add song '%s' to playlist (unkown path)", argv[1]);
|
*errmsg = safe_asprintf("Failed to add song '%s' to playlist (unkown path)", argv[1]);
|
||||||
|
@ -997,7 +997,7 @@ map_track_to_queueitem(struct db_queue_item *item, const struct spotify_track *t
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
queue_add_track(const char *uri)
|
queue_add_track(const char *uri, int position, int *count, int *new_item_id)
|
||||||
{
|
{
|
||||||
json_object *response;
|
json_object *response;
|
||||||
struct spotify_track track;
|
struct spotify_track track;
|
||||||
@ -1015,11 +1015,18 @@ queue_add_track(const char *uri)
|
|||||||
|
|
||||||
map_track_to_queueitem(&item, &track, NULL);
|
map_track_to_queueitem(&item, &track, NULL);
|
||||||
|
|
||||||
ret = db_queue_add_start(&queue_add_info);
|
ret = db_queue_add_start(&queue_add_info, position);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
{
|
{
|
||||||
ret = db_queue_add_item(&queue_add_info, &item);
|
ret = db_queue_add_item(&queue_add_info, &item);
|
||||||
db_queue_add_end(&queue_add_info, ret);
|
ret = db_queue_add_end(&queue_add_info, ret);
|
||||||
|
if (ret == 0)
|
||||||
|
{
|
||||||
|
if (count)
|
||||||
|
*count = queue_add_info.count;
|
||||||
|
if (new_item_id)
|
||||||
|
*new_item_id = queue_add_info.new_item_id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free_queue_item(&item, 1);
|
free_queue_item(&item, 1);
|
||||||
@ -1061,7 +1068,7 @@ queue_add_album_tracks(json_object *item, int index, int total, void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
queue_add_album(const char *uri)
|
queue_add_album(const char *uri, int position, int *count, int *new_item_id)
|
||||||
{
|
{
|
||||||
char *album_endpoint_uri = NULL;
|
char *album_endpoint_uri = NULL;
|
||||||
char *endpoint_uri = NULL;
|
char *endpoint_uri = NULL;
|
||||||
@ -1073,7 +1080,7 @@ queue_add_album(const char *uri)
|
|||||||
json_album = request_endpoint_with_token_refresh(album_endpoint_uri);
|
json_album = request_endpoint_with_token_refresh(album_endpoint_uri);
|
||||||
parse_metadata_album(json_album, ¶m.album);
|
parse_metadata_album(json_album, ¶m.album);
|
||||||
|
|
||||||
ret = db_queue_add_start(¶m.queue_add_info);
|
ret = db_queue_add_start(¶m.queue_add_info, position);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -1081,7 +1088,9 @@ queue_add_album(const char *uri)
|
|||||||
|
|
||||||
ret = request_pagingobject_endpoint(endpoint_uri, queue_add_album_tracks, NULL, NULL, true, ¶m);
|
ret = request_pagingobject_endpoint(endpoint_uri, queue_add_album_tracks, NULL, NULL, true, ¶m);
|
||||||
|
|
||||||
db_queue_add_end(¶m.queue_add_info, ret);
|
ret = db_queue_add_end(¶m.queue_add_info, ret);
|
||||||
|
if (ret == 0 && count)
|
||||||
|
*count = param.queue_add_info.count;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
free(album_endpoint_uri);
|
free(album_endpoint_uri);
|
||||||
@ -1128,13 +1137,13 @@ queue_add_playlist_tracks(json_object *item, int index, int total, void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
queue_add_playlist(const char *uri)
|
queue_add_playlist(const char *uri, int position, int *count, int *new_item_id)
|
||||||
{
|
{
|
||||||
char *endpoint_uri;
|
char *endpoint_uri;
|
||||||
struct db_queue_add_info queue_add_info;
|
struct db_queue_add_info queue_add_info;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = db_queue_add_start(&queue_add_info);
|
ret = db_queue_add_start(&queue_add_info, position);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -1142,7 +1151,9 @@ queue_add_playlist(const char *uri)
|
|||||||
|
|
||||||
ret = request_pagingobject_endpoint(endpoint_uri, queue_add_playlist_tracks, NULL, NULL, true, &queue_add_info);
|
ret = request_pagingobject_endpoint(endpoint_uri, queue_add_playlist_tracks, NULL, NULL, true, &queue_add_info);
|
||||||
|
|
||||||
db_queue_add_end(&queue_add_info, ret);
|
ret = db_queue_add_end(&queue_add_info, ret);
|
||||||
|
if (ret == 0 && count)
|
||||||
|
*count = queue_add_info.count;
|
||||||
|
|
||||||
free(endpoint_uri);
|
free(endpoint_uri);
|
||||||
|
|
||||||
@ -1150,21 +1161,21 @@ queue_add_playlist(const char *uri)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
queue_add(const char *uri)
|
queue_add(const char *uri, int position, int *count, int *new_item_id)
|
||||||
{
|
{
|
||||||
if (strncasecmp(uri, "spotify:track:", strlen("spotify:track:")) == 0)
|
if (strncasecmp(uri, "spotify:track:", strlen("spotify:track:")) == 0)
|
||||||
{
|
{
|
||||||
queue_add_track(uri);
|
queue_add_track(uri, position, count, new_item_id);
|
||||||
return LIBRARY_OK;
|
return LIBRARY_OK;
|
||||||
}
|
}
|
||||||
else if (strncasecmp(uri, "spotify:album:", strlen("spotify:album:")) == 0)
|
else if (strncasecmp(uri, "spotify:album:", strlen("spotify:album:")) == 0)
|
||||||
{
|
{
|
||||||
queue_add_album(uri);
|
queue_add_album(uri, position, count, new_item_id);
|
||||||
return LIBRARY_OK;
|
return LIBRARY_OK;
|
||||||
}
|
}
|
||||||
else if (strncasecmp(uri, "spotify:", strlen("spotify:")) == 0)
|
else if (strncasecmp(uri, "spotify:", strlen("spotify:")) == 0)
|
||||||
{
|
{
|
||||||
queue_add_playlist(uri);
|
queue_add_playlist(uri, position, count, new_item_id);
|
||||||
return LIBRARY_OK;
|
return LIBRARY_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user