Merge pull request #637 from chme/jsonapi_files

New JSON API endpoint for files view
This commit is contained in:
chme 2018-12-23 09:28:50 +01:00 committed by GitHub
commit 0eae6d710c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 376 additions and 28 deletions

View File

@ -587,7 +587,12 @@ POST /api/queue/items/add
**Response** **Response**
On success returns the HTTP `204 No Content` success status response code. On success returns the HTTP `200 OK` success status response code.
| Key | Type | Value |
| --------------- | -------- | ----------------------------------------- |
| count | integer | number of tracks added to the queue |
**Example** **Example**
@ -595,6 +600,12 @@ On success returns the HTTP `204 No Content` success status response code.
curl -X POST "http://localhost:3689/api/queue/items/add?uris=library:playlist:68,library:artist:2932599850102967727" curl -X POST "http://localhost:3689/api/queue/items/add?uris=library:playlist:68,library:artist:2932599850102967727"
``` ```
```json
{
"count": 42
}
```
### Moving a queue item ### Moving a queue item
@ -673,6 +684,7 @@ curl -X PUT "http://localhost:3689/api/queue/items/2"
| GET | [/api/library/albums/{id}/tracks](#list-album-tracks) | Get list of tracks for an album | | GET | [/api/library/albums/{id}/tracks](#list-album-tracks) | Get list of tracks for an album |
| GET | [/api/library/genres](#list-genres) | Get list of genres | | GET | [/api/library/genres](#list-genres) | Get list of genres |
| GET | [/api/library/count](#get-count-of-tracks-artists-and-albums) | Get count of tracks, artists and albums | | GET | [/api/library/count](#get-count-of-tracks-artists-and-albums) | Get count of tracks, artists and albums |
| GET | [/api/library/files](#list-local-directories) | Get list of directories in the local library |
| GET | [/api/update](#trigger-rescan) | Trigger a library rescan | | GET | [/api/update](#trigger-rescan) | Trigger a library rescan |
@ -1205,7 +1217,7 @@ curl -X GET "http://localhost:3689/api/library/albums/1/tracks"
``` ```
### list genres ### List genres
Get list of genres Get list of genres
@ -1377,6 +1389,105 @@ curl -X GET "http://localhost:3689/api/library/count?expression=data_kind+is+fil
``` ```
### List local directories
List the local directories and the directory contents (tracks and playlists)
**Endpoint**
```http
GET /api/library/files
```
**Query parameters**
| Parameter | Value |
| --------------- | ----------------------------------------------------------- |
| directory | *(Optional)* A path to a directory in your local library. |
**Response**
| Key | Type | Value |
| --------------- | -------- | ----------------------------------------- |
| directories | array | Array of [`directory`](#directory-object) objects containing the sub directories |
| tracks | object | [`paging`](#paging-object) object containing [`track`](#track-object) objects that matches the `directory` |
| playlists | object | [`paging`](#paging-object) object containing [`playlist`](#playlist-object) objects that matches the `directory` |
**Example**
```shell
curl -X GET "http://localhost:3689/api/library/files?directory=/music/srv"
```
```json
{
"directories": [
{
"path": "/music/srv/Audiobooks"
},
{
"path": "/music/srv/Music"
},
{
"path": "/music/srv/Playlists"
},
{
"path": "/music/srv/Podcasts"
}
],
"tracks": {
"items": [
{
"id": 1,
"title": "input.pipe",
"artist": "Unknown artist",
"artist_sort": "Unknown artist",
"album": "Unknown album",
"album_sort": "Unknown album",
"album_id": "4201163758598356043",
"album_artist": "Unknown artist",
"album_artist_sort": "Unknown artist",
"album_artist_id": "4187901437947843388",
"genre": "Unknown genre",
"year": 0,
"track_number": 0,
"disc_number": 0,
"length_ms": 0,
"play_count": 0,
"skip_count": 0,
"time_added": "2018-11-24T08:41:35Z",
"seek_ms": 0,
"media_kind": "music",
"data_kind": "pipe",
"path": "/music/srv/input.pipe",
"uri": "library:track:1",
"artwork_url": "/artwork/item/1"
}
],
"total": 1,
"offset": 0,
"limit": -1
},
"playlists": {
"items": [
{
"id": 8,
"name": "radio",
"path": "/music/srv/radio.m3u",
"smart_playlist": true,
"uri": "library:playlist:8"
}
],
"total": 1,
"offset": 0,
"limit": -1
}
}
```
### Trigger rescan ### Trigger rescan
Trigger a library rescan Trigger a library rescan
@ -1774,6 +1885,7 @@ curl --include \
| ------------------ | -------- | ----------------------------------------- | | ------------------ | -------- | ----------------------------------------- |
| id | string | Track id | | id | string | Track id |
| title | string | Title | | title | string | Title |
| title_sort | string | Sort title |
| artist | string | Track artist name | | artist | string | Track artist name |
| artist_sort | string | Track artist sort name | | artist_sort | string | Track artist sort name |
| album | string | Album name | | album | string | Album name |
@ -1788,8 +1900,11 @@ curl --include \
| track_number | integer | Track number | | track_number | integer | Track number |
| disc_number | integer | Disc number | | disc_number | integer | Disc number |
| length_ms | integer | Track length in milliseconds | | length_ms | integer | Track length in milliseconds |
| rating | integer | Track rating (ranges from 0 to 100) |
| play_count | integer | How many times the track was played | | play_count | integer | How many times the track was played |
| skip_count | integer | How many times the track was skipped |
| time_played | string | Timestamp in `ISO 8601` format | | time_played | string | Timestamp in `ISO 8601` format |
| time_skipped | string | Timestamp in `ISO 8601` format |
| time_added | string | Timestamp in `ISO 8601` format | | time_added | string | Timestamp in `ISO 8601` format |
| date_released | string | Date in the format `yyyy-mm-dd` | | date_released | string | Date in the format `yyyy-mm-dd` |
| seek_ms | integer | Resume point in milliseconds (available only for podcasts and audiobooks) | | seek_ms | integer | Resume point in milliseconds (available only for podcasts and audiobooks) |
@ -1817,6 +1932,12 @@ curl --include \
| name | string | Name of genre | | name | string | Name of genre |
### `directory` object
| Key | Type | Value |
| --------------- | -------- | ----------------------------------------- |
| path | string | Directory path |
### Artwork urls ### Artwork urls

View File

@ -3850,7 +3850,7 @@ db_group_persistentid_byid(int id, int64_t *persistentid)
/* Directories */ /* Directories */
int int
db_directory_id_byvirtualpath(char *virtual_path) db_directory_id_byvirtualpath(const char *virtual_path)
{ {
#define Q_TMPL "SELECT d.id FROM directories d WHERE d.virtual_path = '%q';" #define Q_TMPL "SELECT d.id FROM directories d WHERE d.virtual_path = '%q';"
char *query; char *query;
@ -3873,6 +3873,30 @@ db_directory_id_byvirtualpath(char *virtual_path)
#undef Q_TMPL #undef Q_TMPL
} }
int
db_directory_id_bypath(const char *path)
{
#define Q_TMPL "SELECT d.id FROM directories d WHERE d.path = '%q';"
char *query;
int ret;
query = sqlite3_mprintf(Q_TMPL, path);
if (!query)
{
DPRINTF(E_LOG, L_DB, "Out of memory for query string\n");
return 0;
}
ret = db_file_id_byquery(query);
sqlite3_free(query);
return ret;
#undef Q_TMPL
}
int int
db_directory_enum_start(struct directory_enum *de) db_directory_enum_start(struct directory_enum *de)
{ {
@ -3944,6 +3968,7 @@ db_directory_enum_fetch(struct directory_enum *de, struct directory_info *di)
disabled = sqlite3_column_int64(de->stmt, 3); disabled = sqlite3_column_int64(de->stmt, 3);
di->disabled = (disabled != 0); di->disabled = (disabled != 0);
di->parent_id = sqlite3_column_int(de->stmt, 4); di->parent_id = sqlite3_column_int(de->stmt, 4);
di->path = (char *)sqlite3_column_text(de->stmt, 5);
return 0; return 0;
} }
@ -3961,8 +3986,8 @@ db_directory_enum_end(struct directory_enum *de)
static int static int
db_directory_add(struct directory_info *di, int *id) db_directory_add(struct directory_info *di, int *id)
{ {
#define QADD_TMPL "INSERT INTO directories (virtual_path, db_timestamp, disabled, parent_id)" \ #define QADD_TMPL "INSERT INTO directories (virtual_path, db_timestamp, disabled, parent_id, path)" \
" VALUES (TRIM(%Q), %d, %d, %d);" " VALUES (TRIM(%Q), %d, %d, %d, TRIM(%Q));"
char *query; char *query;
char *errmsg; char *errmsg;
@ -3977,7 +4002,7 @@ db_directory_add(struct directory_info *di, int *id)
DPRINTF(E_LOG, L_DB, "Directory name ends with space: '%s'\n", di->virtual_path); DPRINTF(E_LOG, L_DB, "Directory name ends with space: '%s'\n", di->virtual_path);
} }
query = sqlite3_mprintf(QADD_TMPL, di->virtual_path, di->db_timestamp, di->disabled, di->parent_id); query = sqlite3_mprintf(QADD_TMPL, di->virtual_path, di->db_timestamp, di->disabled, di->parent_id, di->path);
if (!query) if (!query)
{ {
@ -4016,14 +4041,14 @@ db_directory_add(struct directory_info *di, int *id)
static int static int
db_directory_update(struct directory_info *di) db_directory_update(struct directory_info *di)
{ {
#define QADD_TMPL "UPDATE directories SET virtual_path = TRIM(%Q), db_timestamp = %d, disabled = %d, parent_id = %d" \ #define QADD_TMPL "UPDATE directories SET virtual_path = TRIM(%Q), db_timestamp = %d, disabled = %d, parent_id = %d, path = TRIM(%Q)" \
" WHERE id = %d;" " WHERE id = %d;"
char *query; char *query;
char *errmsg; char *errmsg;
int ret; int ret;
/* Add */ /* Add */
query = sqlite3_mprintf(QADD_TMPL, di->virtual_path, di->db_timestamp, di->disabled, di->parent_id, di->id); query = sqlite3_mprintf(QADD_TMPL, di->virtual_path, di->db_timestamp, di->disabled, di->parent_id, di->path, di->id);
if (!query) if (!query)
{ {
@ -4053,7 +4078,7 @@ db_directory_update(struct directory_info *di)
} }
int int
db_directory_addorupdate(char *virtual_path, int disabled, int parent_id) db_directory_addorupdate(char *virtual_path, char *path, int disabled, int parent_id)
{ {
struct directory_info di; struct directory_info di;
int id; int id;
@ -4064,6 +4089,7 @@ db_directory_addorupdate(char *virtual_path, int disabled, int parent_id)
di.id = id; di.id = id;
di.parent_id = parent_id; di.parent_id = parent_id;
di.virtual_path = virtual_path; di.virtual_path = virtual_path;
di.path = path;
di.disabled = disabled; di.disabled = disabled;
di.db_timestamp = (uint64_t)time(NULL); di.db_timestamp = (uint64_t)time(NULL);

View File

@ -412,6 +412,7 @@ enum directory_ids {
struct directory_info { struct directory_info {
uint32_t id; uint32_t id;
char *virtual_path; char *virtual_path;
char *path;
uint32_t db_timestamp; uint32_t db_timestamp;
uint32_t disabled; uint32_t disabled;
uint32_t parent_id; uint32_t parent_id;
@ -698,7 +699,10 @@ db_group_persistentid_byid(int id, int64_t *persistentid);
/* Directories */ /* Directories */
int int
db_directory_id_byvirtualpath(char *virtual_path); db_directory_id_byvirtualpath(const char *virtual_path);
int
db_directory_id_bypath(const char *path);
int int
db_directory_enum_start(struct directory_enum *de); db_directory_enum_start(struct directory_enum *de);
@ -710,7 +714,7 @@ void
db_directory_enum_end(struct directory_enum *de); db_directory_enum_end(struct directory_enum *de);
int int
db_directory_addorupdate(char *virtual_path, int disabled, int parent_id); db_directory_addorupdate(char *virtual_path, char *path, int disabled, int parent_id);
void void
db_directory_ping_bymatch(char *virtual_path); db_directory_ping_bymatch(char *virtual_path);

View File

@ -161,7 +161,8 @@
" virtual_path VARCHAR(4096) NOT NULL," \ " virtual_path VARCHAR(4096) NOT NULL," \
" db_timestamp INTEGER DEFAULT 0," \ " db_timestamp INTEGER DEFAULT 0," \
" disabled INTEGER DEFAULT 0," \ " disabled INTEGER DEFAULT 0," \
" parent_id INTEGER DEFAULT 0" \ " parent_id INTEGER DEFAULT 0," \
" path VARCHAR(4096) DEFAULT NULL" \
");" ");"
#define T_QUEUE \ #define T_QUEUE \
@ -239,17 +240,17 @@
#define Q_DIR1 \ #define Q_DIR1 \
"INSERT INTO directories (id, virtual_path, db_timestamp, disabled, parent_id)" \ "INSERT INTO directories (id, virtual_path, db_timestamp, disabled, parent_id, path)" \
" VALUES (1, '/', 0, 0, 0);" " VALUES (1, '/', 0, 0, 0, NULL);"
#define Q_DIR2 \ #define Q_DIR2 \
"INSERT INTO directories (id, virtual_path, db_timestamp, disabled, parent_id)" \ "INSERT INTO directories (id, virtual_path, db_timestamp, disabled, parent_id, path)" \
" VALUES (2, '/file:', 0, 0, 1);" " VALUES (2, '/file:', 0, 0, 1, '/');"
#define Q_DIR3 \ #define Q_DIR3 \
"INSERT INTO directories (id, virtual_path, db_timestamp, disabled, parent_id)" \ "INSERT INTO directories (id, virtual_path, db_timestamp, disabled, parent_id, path)" \
" VALUES (3, '/http:', 0, 0, 1);" " VALUES (3, '/http:', 0, 0, 1, NULL);"
#define Q_DIR4 \ #define Q_DIR4 \
"INSERT INTO directories (id, virtual_path, db_timestamp, disabled, parent_id)" \ "INSERT INTO directories (id, virtual_path, db_timestamp, disabled, parent_id, path)" \
" VALUES (4, '/spotify:', 0, 4294967296, 1);" " VALUES (4, '/spotify:', 0, 4294967296, 1, NULL);"
#define Q_QUEUE_VERSION \ #define Q_QUEUE_VERSION \
"INSERT INTO admin (key, value) VALUES ('queue_version', '0');" "INSERT INTO admin (key, value) VALUES ('queue_version', '0');"

View File

@ -26,7 +26,7 @@
* is a major upgrade. In other words minor version upgrades permit downgrading * is a major upgrade. In other words minor version upgrades permit downgrading
* forked-daapd after the database was upgraded. */ * forked-daapd after the database was upgraded. */
#define SCHEMA_VERSION_MAJOR 19 #define SCHEMA_VERSION_MAJOR 19
#define SCHEMA_VERSION_MINOR 11 #define SCHEMA_VERSION_MINOR 12
int int
db_init_indices(sqlite3 *hdl); db_init_indices(sqlite3 *hdl);

View File

@ -1698,6 +1698,27 @@ static const struct db_upgrade_query db_upgrade_v1911_queries[] =
}; };
#define U_V1912_ALTER_DIRECTORIES_ADD_PATH \
"ALTER TABLE directories ADD COLUMN path VARCHAR(4096) DEFAULT NULL;"
#define U_V1912_UPDATE_FILE_DIRECTORIES_PATH \
"UPDATE directories SET path = SUBSTR(path, 7) WHERE virtual_path like '/file:/%';"
#define U_V1912_UPDATE_FILE_ROOT_PATH \
"UPDATE directories SET path = '/' WHERE virtual_path = '/file:';"
#define U_V1912_SCVER_MINOR \
"UPDATE admin SET value = '12' WHERE key = 'schema_version_minor';"
static const struct db_upgrade_query db_upgrade_v1912_queries[] =
{
{ U_V1912_ALTER_DIRECTORIES_ADD_PATH, "alter table directories add column path" },
{ U_V1912_UPDATE_FILE_DIRECTORIES_PATH, "set paths for '/file:' directories" },
{ U_V1912_UPDATE_FILE_ROOT_PATH, "set path for '/file:' directory" },
{ U_V1912_SCVER_MINOR, "set schema_version_minor to 12" },
};
int int
db_upgrade(sqlite3 *hdl, int db_ver) db_upgrade(sqlite3 *hdl, int db_ver)
{ {
@ -1884,6 +1905,14 @@ db_upgrade(sqlite3 *hdl, int db_ver)
ret = db_generic_upgrade(hdl, db_upgrade_v1911_queries, ARRAY_SIZE(db_upgrade_v1911_queries)); ret = db_generic_upgrade(hdl, db_upgrade_v1911_queries, ARRAY_SIZE(db_upgrade_v1911_queries));
if (ret < 0) if (ret < 0)
return -1; return -1;
/* FALLTHROUGH */
case 1911:
ret = db_generic_upgrade(hdl, db_upgrade_v1912_queries, ARRAY_SIZE(db_upgrade_v1912_queries));
if (ret < 0)
return -1;
break; break;
default: default:

View File

@ -182,6 +182,7 @@ track_to_json(struct db_media_file_info *dbmfi)
safe_json_add_int_from_string(item, "id", dbmfi->id); safe_json_add_int_from_string(item, "id", dbmfi->id);
safe_json_add_string(item, "title", dbmfi->title); safe_json_add_string(item, "title", dbmfi->title);
safe_json_add_string(item, "title_sort", dbmfi->title_sort);
safe_json_add_string(item, "artist", dbmfi->artist); safe_json_add_string(item, "artist", dbmfi->artist);
safe_json_add_string(item, "artist_sort", dbmfi->artist_sort); safe_json_add_string(item, "artist_sort", dbmfi->artist_sort);
safe_json_add_string(item, "album", dbmfi->album); safe_json_add_string(item, "album", dbmfi->album);
@ -197,6 +198,7 @@ track_to_json(struct db_media_file_info *dbmfi)
safe_json_add_int_from_string(item, "disc_number", dbmfi->disc); safe_json_add_int_from_string(item, "disc_number", dbmfi->disc);
safe_json_add_int_from_string(item, "length_ms", dbmfi->song_length); safe_json_add_int_from_string(item, "length_ms", dbmfi->song_length);
safe_json_add_int_from_string(item, "rating", dbmfi->rating);
safe_json_add_int_from_string(item, "play_count", dbmfi->play_count); safe_json_add_int_from_string(item, "play_count", dbmfi->play_count);
safe_json_add_int_from_string(item, "skip_count", dbmfi->skip_count); safe_json_add_int_from_string(item, "skip_count", dbmfi->skip_count);
safe_json_add_time_from_string(item, "time_played", dbmfi->time_played, true); safe_json_add_time_from_string(item, "time_played", dbmfi->time_played, true);
@ -266,6 +268,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 +549,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)
@ -1275,6 +1327,7 @@ static int
play_item_at_position(const char *param) play_item_at_position(const char *param)
{ {
uint32_t position; uint32_t position;
struct player_status status;
struct db_queue_item *queue_item; struct db_queue_item *queue_item;
int ret; int ret;
@ -1286,7 +1339,9 @@ play_item_at_position(const char *param)
return HTTP_BADREQUEST; return HTTP_BADREQUEST;
} }
queue_item = db_queue_fetch_bypos(position, 0); player_get_status(&status);
queue_item = db_queue_fetch_bypos(position, status.shuffle);
if (!queue_item) if (!queue_item)
{ {
DPRINTF(E_LOG, L_WEB, "No queue item at position '%d'\n", position); DPRINTF(E_LOG, L_WEB, "No queue item at position '%d'\n", position);
@ -1690,6 +1745,7 @@ jsonapi_reply_queue_tracks_add(struct httpd_request *hreq)
const char *id; const char *id;
int pos = -1; int pos = -1;
int count = 0; int count = 0;
json_object *reply;
int ret = 0; int ret = 0;
@ -1759,10 +1815,19 @@ jsonapi_reply_queue_tracks_add(struct httpd_request *hreq)
free(uris); free(uris);
if (ret == 0)
{
reply = json_object_new_object();
json_object_object_add(reply, "count", json_object_new_int(count));
ret = evbuffer_add_printf(hreq->reply, "%s", json_object_to_json_string(reply));
jparse_free(reply);
}
if (ret < 0) if (ret < 0)
return HTTP_INTERNAL; return HTTP_INTERNAL;
return HTTP_NOCONTENT; return HTTP_OK;
} }
static int static int
@ -2609,6 +2674,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 +3143,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 },

View File

@ -749,7 +749,7 @@ process_directory(char *path, int parent_id, int flags)
if (ret < 0) if (ret < 0)
return; return;
dir_id = db_directory_addorupdate(virtual_path, 0, parent_id); dir_id = db_directory_addorupdate(virtual_path, path, 0, parent_id);
if (dir_id <= 0) if (dir_id <= 0)
{ {
DPRINTF(E_LOG, L_SCAN, "Insert or update of directory failed '%s'\n", virtual_path); DPRINTF(E_LOG, L_SCAN, "Insert or update of directory failed '%s'\n", virtual_path);
@ -876,7 +876,7 @@ process_parent_directories(char *path)
if (ret < 0) if (ret < 0)
return 0; return 0;
dir_id = db_directory_addorupdate(virtual_path, 0, dir_id); dir_id = db_directory_addorupdate(virtual_path, buf, 0, dir_id);
if (dir_id <= 0) if (dir_id <= 0)
{ {
DPRINTF(E_LOG, L_SCAN, "Insert or update of directory failed '%s'\n", virtual_path); DPRINTF(E_LOG, L_SCAN, "Insert or update of directory failed '%s'\n", virtual_path);

View File

@ -1250,7 +1250,7 @@ prepare_directories(const char *artist, const char *album)
DPRINTF(E_LOG, L_SPOTIFY, "Virtual path exceeds PATH_MAX (/spotify:/%s)\n", artist); DPRINTF(E_LOG, L_SPOTIFY, "Virtual path exceeds PATH_MAX (/spotify:/%s)\n", artist);
return -1; return -1;
} }
dir_id = db_directory_addorupdate(virtual_path, 0, DIR_SPOTIFY); dir_id = db_directory_addorupdate(virtual_path, NULL, 0, DIR_SPOTIFY);
if (dir_id <= 0) if (dir_id <= 0)
{ {
DPRINTF(E_LOG, L_SPOTIFY, "Could not add or update directory '%s'\n", virtual_path); DPRINTF(E_LOG, L_SPOTIFY, "Could not add or update directory '%s'\n", virtual_path);
@ -1262,7 +1262,7 @@ prepare_directories(const char *artist, const char *album)
DPRINTF(E_LOG, L_SPOTIFY, "Virtual path exceeds PATH_MAX (/spotify:/%s/%s)\n", artist, album); DPRINTF(E_LOG, L_SPOTIFY, "Virtual path exceeds PATH_MAX (/spotify:/%s/%s)\n", artist, album);
return -1; return -1;
} }
dir_id = db_directory_addorupdate(virtual_path, 0, dir_id); dir_id = db_directory_addorupdate(virtual_path, NULL, 0, dir_id);
if (dir_id <= 0) if (dir_id <= 0)
{ {
DPRINTF(E_LOG, L_SPOTIFY, "Could not add or update directory '%s'\n", virtual_path); DPRINTF(E_LOG, L_SPOTIFY, "Could not add or update directory '%s'\n", virtual_path);