mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-11 15:03:24 -05:00
[jsonapi,mpd,conf] save playlist via JSON api
- new endpoint api/queue/save?name= to .m3u via library_save() - refact for common cfg for playlist save options
This commit is contained in:
parent
d6f45054f0
commit
d28f7f43b7
@ -191,6 +191,16 @@ library {
|
||||
# (played or skipped). Both results are combined with a mix-factor of 0.75:
|
||||
# new rating = 0.75 * stable rating + 0.25 * rolling rating)
|
||||
# rating_updates = false
|
||||
|
||||
# Allows creating, deleting and modifying m3u playlists in the library directories.
|
||||
# Defaults to being disabled.
|
||||
# allow_modifying_stored_playlists = false
|
||||
|
||||
# A directory in one of the library directories that will be used as the default
|
||||
# playlist directory. forked-dapd creates new playlists in this directory if only
|
||||
# a playlist name is provided by the mpd client (requires "allow_modify_stored_playlists"
|
||||
# set to true).
|
||||
# default_playlist_directory = ""
|
||||
}
|
||||
|
||||
# Local audio output
|
||||
@ -320,16 +330,6 @@ mpd {
|
||||
# the playlist like MPD does. Note that some dacp clients do not show
|
||||
# the playqueue if playback is stopped.
|
||||
# clear_queue_on_stop_disable = false
|
||||
|
||||
# Allows creating, deleting and modifying m3u playlists in the library directories.
|
||||
# Defaults to being disabled.
|
||||
# allow_modifying_stored_playlists = false
|
||||
|
||||
# A directory in one of the library directories that will be used as the default
|
||||
# playlist directory. forked-dapd creates new playlists in this directory if only
|
||||
# a playlist name is provided by the mpd client (requires "allow_modify_stored_playlists"
|
||||
# set to true).
|
||||
# default_playlist_directory = ""
|
||||
}
|
||||
|
||||
# SQLite configuration (allows to modify the operation of the SQLite databases)
|
||||
|
@ -103,6 +103,8 @@ static cfg_opt_t sec_library[] =
|
||||
CFG_INT("pipe_sample_rate", 44100, CFGF_NONE),
|
||||
CFG_INT("pipe_bits_per_sample", 16, CFGF_NONE),
|
||||
CFG_BOOL("rating_updates", cfg_false, CFGF_NONE),
|
||||
CFG_BOOL("allow_modifying_stored_playlists", cfg_false, CFGF_NONE),
|
||||
CFG_STR("default_playlist_directory", NULL, CFGF_NONE),
|
||||
CFG_END()
|
||||
};
|
||||
|
||||
@ -178,8 +180,6 @@ static cfg_opt_t sec_mpd[] =
|
||||
CFG_INT("port", 6600, CFGF_NONE),
|
||||
CFG_INT("http_port", 0, CFGF_NONE),
|
||||
CFG_BOOL("clear_queue_on_stop_disable", cfg_false, CFGF_NONE),
|
||||
CFG_BOOL("allow_modifying_stored_playlists", cfg_false, CFGF_NONE),
|
||||
CFG_STR("default_playlist_directory", NULL, CFGF_NONE),
|
||||
CFG_END()
|
||||
};
|
||||
|
||||
|
@ -30,6 +30,8 @@
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <regex.h>
|
||||
@ -57,6 +59,10 @@
|
||||
# include "spotify.h"
|
||||
#endif
|
||||
|
||||
static bool allow_modifying_stored_playlists;
|
||||
static char *default_pl_dir;
|
||||
|
||||
|
||||
/* -------------------------------- HELPERS --------------------------------- */
|
||||
|
||||
static inline void
|
||||
@ -2903,6 +2909,44 @@ jsonapi_reply_library_playlist_tracks(struct httpd_request *hreq)
|
||||
return HTTP_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
jsonapi_reply_queue_save(struct httpd_request *hreq)
|
||||
{
|
||||
const char *param;
|
||||
int ret = 0;
|
||||
char buf[PATH_MAX+7];
|
||||
char *plsname = NULL;
|
||||
|
||||
if ((param = evhttp_find_header(hreq->query, "name")) == NULL)
|
||||
{
|
||||
DPRINTF(E_LOG, L_WEB, "Invalid argument, missing 'name'\n");
|
||||
return HTTP_BADREQUEST;
|
||||
}
|
||||
|
||||
if (!allow_modifying_stored_playlists)
|
||||
{
|
||||
DPRINTF(E_LOG, L_WEB, "Saving playlists disabled in cfg, ignoring request\n");
|
||||
return 403;
|
||||
}
|
||||
|
||||
if (access(default_pl_dir, W_OK) < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_WEB, "Invalid playlist save directory=%s\n", default_pl_dir);
|
||||
return 403;
|
||||
}
|
||||
|
||||
plsname = atrim(param);
|
||||
snprintf(buf, PATH_MAX+7, "/file:%s/%s", default_pl_dir, plsname);
|
||||
free(plsname);
|
||||
|
||||
ret = library_queue_save(buf);
|
||||
|
||||
if (ret < 0)
|
||||
return HTTP_INTERNAL;
|
||||
|
||||
return HTTP_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
jsonapi_reply_library_genres(struct httpd_request *hreq)
|
||||
{
|
||||
@ -3486,6 +3530,7 @@ static struct httpd_uri_map adm_handlers[] =
|
||||
{ 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_DELETE, "^/api/queue/items/[[:digit:]]+$", jsonapi_reply_queue_tracks_delete },
|
||||
{ EVHTTP_REQ_POST, "^/api/queue/save$", jsonapi_reply_queue_save},
|
||||
|
||||
{ EVHTTP_REQ_GET, "^/api/library/playlists$", jsonapi_reply_library_playlists },
|
||||
{ EVHTTP_REQ_GET, "^/api/library/playlists/[[:digit:]]+$", jsonapi_reply_library_playlist },
|
||||
@ -3557,6 +3602,9 @@ jsonapi_request(struct evhttp_request *req, struct httpd_uri_parsed *uri_parsed)
|
||||
case HTTP_BADREQUEST: /* 400 Bad Request */
|
||||
httpd_send_error(req, status_code, "Bad Request");
|
||||
break;
|
||||
case 403:
|
||||
httpd_send_error(req, status_code, "Forbidden");
|
||||
break;
|
||||
case HTTP_NOTFOUND: /* 404 Not Found */
|
||||
httpd_send_error(req, status_code, "Not Found");
|
||||
break;
|
||||
@ -3600,6 +3648,22 @@ jsonapi_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
default_pl_dir = NULL;
|
||||
allow_modifying_stored_playlists = cfg_getbool(cfg_getsec(cfg, "library"), "allow_modifying_stored_playlists");
|
||||
if (allow_modifying_stored_playlists)
|
||||
{
|
||||
default_pl_dir = cfg_getstr(cfg_getsec(cfg, "library"), "default_playlist_directory");
|
||||
if (default_pl_dir == NULL)
|
||||
{
|
||||
allow_modifying_stored_playlists = false;
|
||||
DPRINTF(E_LOG, L_WEB, "Invalid playlist save directory, disabling\n");
|
||||
}
|
||||
else if (access(default_pl_dir, W_OK) < 0)
|
||||
{
|
||||
DPRINTF(E_WARN, L_WEB, "Non-writable playlist save directory=%s\n", default_pl_dir);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -4843,8 +4843,8 @@ int mpd_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
allow_modifying_stored_playlists = cfg_getbool(cfg_getsec(cfg, "mpd"), "allow_modifying_stored_playlists");
|
||||
pl_dir = cfg_getstr(cfg_getsec(cfg, "mpd"), "default_playlist_directory");
|
||||
allow_modifying_stored_playlists = cfg_getbool(cfg_getsec(cfg, "library"), "allow_modifying_stored_playlists");
|
||||
pl_dir = cfg_getstr(cfg_getsec(cfg, "library"), "default_playlist_directory");
|
||||
if (pl_dir)
|
||||
default_pl_dir = safe_asprintf("/file:%s", pl_dir);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user