[jsonapi] Add new endpoint "api/library/files"

This endpoint allows traversing the directory tree of the local library.
This commit is contained in:
chme 2018-11-24 12:15:31 +01:00
parent 070379edef
commit e6dc2a5845
1 changed files with 152 additions and 0 deletions

View File

@ -266,6 +266,24 @@ genre_to_json(const char *genre)
return item; return item;
} }
static json_object *
directory_to_json(struct directory_info *directory_info)
{
json_object *item;
if (directory_info == NULL)
{
return NULL;
}
item = json_object_new_object();
safe_json_add_string(item, "path", directory_info->path);
// json_object_object_add(item, "id", json_object_new_int(directory_info->id));
// json_object_object_add(item, "parent_id", json_object_new_int(directory_info->parent_id));
return item;
}
static int static int
fetch_tracks(struct query_params *query_params, json_object *items, int *total) fetch_tracks(struct query_params *query_params, json_object *items, int *total)
@ -529,6 +547,38 @@ fetch_genres(struct query_params *query_params, json_object *items, int *total)
return ret; return ret;
} }
static int
fetch_directories(int parent_id, json_object *items)
{
json_object *item;
int ret;
struct directory_info subdir;
struct directory_enum dir_enum;
memset(&dir_enum, 0, sizeof(struct directory_enum));
dir_enum.parent_id = parent_id;
ret = db_directory_enum_start(&dir_enum);
if (ret < 0)
goto error;
while ((ret = db_directory_enum_fetch(&dir_enum, &subdir)) == 0 && subdir.id > 0)
{
item = directory_to_json(&subdir);
if (!item)
{
ret = -1;
goto error;
}
json_object_array_add(items, item);
}
error:
db_directory_enum_end(&dir_enum);
return ret;
}
static int static int
query_params_limit_set(struct query_params *query_params, struct httpd_request *hreq) query_params_limit_set(struct query_params *query_params, struct httpd_request *hreq)
@ -2609,6 +2659,107 @@ jsonapi_reply_library_count(struct httpd_request *hreq)
return HTTP_OK; return HTTP_OK;
} }
static int
jsonapi_reply_library_files(struct httpd_request *hreq)
{
const char *param;
int directory_id;
json_object *reply;
json_object *directories;
struct query_params query_params;
json_object *tracks;
json_object *tracks_items;
json_object *playlists;
json_object *playlists_items;
int total;
int ret;
param = evhttp_find_header(hreq->query, "directory");
directory_id = DIR_FILE;
if (param)
{
directory_id = db_directory_id_bypath(param);
if (directory_id <= 0)
return HTTP_INTERNAL;
}
reply = json_object_new_object();
// Add sub directories to response
directories = json_object_new_array();
json_object_object_add(reply, "directories", directories);
ret = fetch_directories(directory_id, directories);
if (ret < 0)
{
goto error;
}
// Add tracks to response
tracks = json_object_new_object();
json_object_object_add(reply, "tracks", tracks);
tracks_items = json_object_new_array();
json_object_object_add(tracks, "items", tracks_items);
memset(&query_params, 0, sizeof(struct query_params));
ret = query_params_limit_set(&query_params, hreq);
if (ret < 0)
goto error;
query_params.type = Q_ITEMS;
query_params.sort = S_NAME;
query_params.filter = db_mprintf("(f.directory_id = %d)", directory_id);
ret = fetch_tracks(&query_params, tracks_items, &total);
free(query_params.filter);
if (ret < 0)
goto error;
json_object_object_add(tracks, "total", json_object_new_int(total));
json_object_object_add(tracks, "offset", json_object_new_int(query_params.offset));
json_object_object_add(tracks, "limit", json_object_new_int(query_params.limit));
// Add playlists
playlists = json_object_new_object();
json_object_object_add(reply, "playlists", playlists);
playlists_items = json_object_new_array();
json_object_object_add(playlists, "items", playlists_items);
memset(&query_params, 0, sizeof(struct query_params));
ret = query_params_limit_set(&query_params, hreq);
if (ret < 0)
goto error;
query_params.type = Q_PL;
query_params.sort = S_PLAYLIST;
query_params.filter = db_mprintf("(f.directory_id = %d)", directory_id);
ret = fetch_playlists(&query_params, playlists_items, &total);
free(query_params.filter);
if (ret < 0)
goto error;
json_object_object_add(playlists, "total", json_object_new_int(total));
json_object_object_add(playlists, "offset", json_object_new_int(query_params.offset));
json_object_object_add(playlists, "limit", json_object_new_int(query_params.limit));
// Build JSON response
ret = evbuffer_add_printf(hreq->reply, "%s", json_object_to_json_string(reply));
if (ret < 0)
DPRINTF(E_LOG, L_WEB, "browse: Couldn't add directories to response buffer.\n");
error:
jparse_free(reply);
if (ret < 0)
return HTTP_INTERNAL;
return HTTP_OK;
}
static int static int
search_tracks(json_object *reply, struct httpd_request *hreq, const char *param_query, struct smartpl *smartpl_expression, enum media_kind media_kind) search_tracks(json_object *reply, struct httpd_request *hreq, const char *param_query, struct smartpl *smartpl_expression, enum media_kind media_kind)
{ {
@ -2977,6 +3128,7 @@ static struct httpd_uri_map adm_handlers[] =
{ EVHTTP_REQ_GET, "^/api/library/albums/[[:digit:]]+/tracks$", jsonapi_reply_library_album_tracks }, { EVHTTP_REQ_GET, "^/api/library/albums/[[:digit:]]+/tracks$", jsonapi_reply_library_album_tracks },
{ EVHTTP_REQ_GET, "^/api/library/genres$", jsonapi_reply_library_genres}, { EVHTTP_REQ_GET, "^/api/library/genres$", jsonapi_reply_library_genres},
{ EVHTTP_REQ_GET, "^/api/library/count$", jsonapi_reply_library_count }, { EVHTTP_REQ_GET, "^/api/library/count$", jsonapi_reply_library_count },
{ EVHTTP_REQ_GET, "^/api/library/files$", jsonapi_reply_library_files },
{ EVHTTP_REQ_GET, "^/api/search$", jsonapi_reply_search }, { EVHTTP_REQ_GET, "^/api/search$", jsonapi_reply_search },