diff --git a/src/library.c b/src/library.c index e1dc1fb9..1d2660d0 100644 --- a/src/library.c +++ b/src/library.c @@ -47,6 +47,12 @@ #include "listener.h" #include "player.h" +struct playlist_add_param +{ + const char *vp_playlist; + const char *vp_item; +}; + static struct commands_base *cmdbase; static pthread_t tid_library; @@ -725,6 +731,134 @@ library_update_trigger(void) commands_exec_async(cmdbase, update_trigger, NULL); } +static enum command_state +playlist_add(void *arg, int *retval) +{ + struct playlist_add_param *param = arg; + int i; + int ret = LIBRARY_ERROR; + + DPRINTF(E_DBG, L_LIB, "Adding item '%s' to playlist '%s'\n", param->vp_item, param->vp_playlist); + + for (i = 0; sources[i]; i++) + { + if (sources[i]->disabled || !sources[i]->playlist_add) + { + DPRINTF(E_DBG, L_LIB, "Library source '%s' is disabled or does not support playlist_add\n", sources[i]->name); + continue; + } + + ret = sources[i]->playlist_add(param->vp_playlist, param->vp_item); + + if (ret == LIBRARY_OK) + { + DPRINTF(E_DBG, L_LIB, "Adding item '%s' to playlist '%s' with library source '%s'\n", param->vp_item, param->vp_playlist, sources[i]->name); + listener_notify(LISTENER_STORED_PLAYLIST); + break; + } + } + + *retval = ret; + return COMMAND_END; +} + +int +library_playlist_add(const char *vp_playlist, const char *vp_item) +{ + struct playlist_add_param param; + + if (library_is_scanning()) + return -1; + + param.vp_playlist = vp_playlist; + param.vp_item = vp_item; + return commands_exec_sync(cmdbase, playlist_add, NULL, ¶m); +} + +static enum command_state +playlist_remove(void *arg, int *retval) +{ + const char *virtual_path; + int i; + int ret = LIBRARY_ERROR; + + virtual_path = arg; + + DPRINTF(E_DBG, L_LIB, "Removing playlist at path '%s'\n", virtual_path); + + for (i = 0; sources[i]; i++) + { + if (sources[i]->disabled || !sources[i]->playlist_remove) + { + DPRINTF(E_DBG, L_LIB, "Library source '%s' is disabled or does not support playlist_remove\n", sources[i]->name); + continue; + } + + ret = sources[i]->playlist_remove(virtual_path); + + if (ret == LIBRARY_OK) + { + DPRINTF(E_DBG, L_LIB, "Removing playlist '%s' with library source '%s'\n", virtual_path, sources[i]->name); + listener_notify(LISTENER_STORED_PLAYLIST); + break; + } + } + + *retval = ret; + return COMMAND_END; +} + +int +library_playlist_remove(char *virtual_path) +{ + if (library_is_scanning()) + return -1; + + return commands_exec_sync(cmdbase, playlist_remove, NULL, virtual_path); +} + +static enum command_state +queue_save(void *arg, int *retval) +{ + const char *virtual_path; + int i; + int ret = LIBRARY_ERROR; + + virtual_path = arg; + + DPRINTF(E_DBG, L_LIB, "Saving queue to path '%s'\n", virtual_path); + + for (i = 0; sources[i]; i++) + { + if (sources[i]->disabled || !sources[i]->queue_save) + { + DPRINTF(E_DBG, L_LIB, "Library source '%s' is disabled or does not support queue_save\n", sources[i]->name); + continue; + } + + ret = sources[i]->queue_save(virtual_path); + + if (ret == LIBRARY_OK) + { + DPRINTF(E_DBG, L_LIB, "Saving queue to path '%s' with library source '%s'\n", virtual_path, sources[i]->name); + listener_notify(LISTENER_STORED_PLAYLIST); + break; + } + } + + *retval = ret; + return COMMAND_END; +} + +int +library_queue_save(char *path) +{ + if (library_is_scanning()) + return -1; + + return commands_exec_sync(cmdbase, queue_save, NULL, path); +} + /* * Execute the function 'func' with the given argument 'arg' in the library thread. * diff --git a/src/library.h b/src/library.h index a72c5957..c4586e07 100644 --- a/src/library.h +++ b/src/library.h @@ -70,6 +70,21 @@ struct library_source * Scans metadata for the media file with the given path into the given mfi */ int (*scan_metadata)(const char *path, struct media_file_info *mfi); + + /* + * Save queue as a new playlist under the given virtual path + */ + int (*playlist_add)(const char *vp_playlist, const char *vp_item); + + /* + * Removes the playlist under the given virtual path + */ + int (*playlist_remove)(const char *virtual_path); + + /* + * Save queue as a new playlist under the given virtual path + */ + int (*queue_save)(const char *virtual_path); }; @@ -103,6 +118,15 @@ library_is_exiting(); void library_update_trigger(void); +int +library_playlist_add(const char *vp_playlist, const char *vp_item); + +int +library_playlist_remove(char *virtual_path); + +int +library_queue_save(char *path); + int library_exec_async(command_function func, void *arg); diff --git a/src/listener.h b/src/listener.h index 61421077..8a557fa9 100644 --- a/src/listener.h +++ b/src/listener.h @@ -16,6 +16,8 @@ enum listener_event_type LISTENER_OPTIONS = (1 << 4), /* The library has been modified */ LISTENER_DATABASE = (1 << 5), + /* A stored playlist has been modified (create, delete, add, rename) */ + LISTENER_STORED_PLAYLIST = (1 << 6), }; typedef void (*notify)(enum listener_event_type type);