mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-26 06:03:20 -05:00
Merge pull request #916 from whatdoineed2do/json-playlist-play-count-update
[json] enable playlist play_count
This commit is contained in:
commit
5bd32135ee
@ -747,6 +747,7 @@ curl -X PUT "http://localhost:3689/api/queue/items/2"
|
||||
| GET | [/api/library/playlists](#list-playlists) | Get a list of playlists |
|
||||
| GET | [/api/library/playlists/{id}](#get-a-playlist) | Get a playlist |
|
||||
| GET | [/api/library/playlists/{id}/tracks](#list-playlist-tracks) | Get list of tracks for a playlist |
|
||||
| PUT | [/api/library/playlists/{id}/tracks](#update-playlist-tracks) | Update play count of tracks for a playlist |
|
||||
| GET | [/api/library/playlists/{id}/playlists](#list-playlists-in-a-playlist-folder) | Get list of playlists for a playlist folder |
|
||||
| GET | [/api/library/artists](#list-artists) | Get a list of artists |
|
||||
| GET | [/api/library/artists/{id}](#get-an-artist) | Get an artist |
|
||||
@ -968,6 +969,34 @@ curl -X GET "http://localhost:3689/api/library/playlists/1/tracks"
|
||||
}
|
||||
```
|
||||
|
||||
### Update playlist tracks
|
||||
|
||||
Updates the play count for tracks in a playlists
|
||||
|
||||
**Endpoint**
|
||||
|
||||
```http
|
||||
PUT /api/library/playlists/{id}/tracks
|
||||
```
|
||||
|
||||
**Path parameters**
|
||||
|
||||
| Parameter | Value |
|
||||
| --------------- | -------------------- |
|
||||
| id | Playlist id |
|
||||
|
||||
**Query parameters**
|
||||
|
||||
| Parameter | Value |
|
||||
| --------------- | ----------------------------------------------------------- |
|
||||
| play_count | Either `increment`, `played` or `reset`. `increment` will increment `play_count` and update `time_played`, `played` will be like `increment` but only where `play_count` is 0, `reset` will set `play_count` and `skip_count` to zero and delete `time_played` and `time_skipped` |
|
||||
|
||||
|
||||
**Example**
|
||||
|
||||
```shell
|
||||
curl -X PUT "http://localhost:3689/api/library/playlists/1/tracks?play_count=played"
|
||||
```
|
||||
|
||||
### List playlists in a playlist folder
|
||||
|
||||
|
49
src/db.c
49
src/db.c
@ -2514,10 +2514,10 @@ db_files_get_count(uint32_t *nitems, uint32_t *nstreams, const char *filter)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
db_file_inc_playcount(int id)
|
||||
static void
|
||||
db_file_inc_playcount_byfilter(const char *filter)
|
||||
{
|
||||
#define Q_TMPL "UPDATE files SET play_count = play_count + 1, time_played = %" PRIi64 ", seek = 0 WHERE id = %d;"
|
||||
#define Q_TMPL "UPDATE files SET play_count = play_count + 1, time_played = %" PRIi64 ", seek = 0 WHERE %s;"
|
||||
/*
|
||||
* Rating calculation is taken from from the beets plugin "mpdstats" (see https://beets.readthedocs.io/en/latest/plugins/mpdstats.html)
|
||||
* and adapted to the forked-daapd rating rage (0 to 100).
|
||||
@ -2536,14 +2536,16 @@ db_file_inc_playcount(int id)
|
||||
"UPDATE files "\
|
||||
" SET play_count = play_count + 1, time_played = %" PRIi64 ", seek = 0, "\
|
||||
" rating = CAST(((play_count + 1.0) / (play_count + skip_count + 2.0) * 100 * 0.75) + ((rating + ((100.0 - rating) / 2.0)) * 0.25) AS INT)" \
|
||||
" WHERE id = %d;"
|
||||
" WHERE %s;"
|
||||
char *query;
|
||||
int ret;
|
||||
|
||||
|
||||
if (db_rating_updates)
|
||||
query = sqlite3_mprintf(Q_TMPL_WITH_RATING, (int64_t)time(NULL), id);
|
||||
query = sqlite3_mprintf(Q_TMPL_WITH_RATING, (int64_t)time(NULL), filter);
|
||||
else
|
||||
query = sqlite3_mprintf(Q_TMPL, (int64_t)time(NULL), id);
|
||||
query = sqlite3_mprintf(Q_TMPL, (int64_t)time(NULL), filter);
|
||||
|
||||
if (!query)
|
||||
{
|
||||
DPRINTF(E_LOG, L_DB, "Out of memory for query string\n");
|
||||
@ -2558,6 +2560,41 @@ db_file_inc_playcount(int id)
|
||||
#undef Q_TMPL_WITH_RATING
|
||||
}
|
||||
|
||||
void
|
||||
db_file_inc_playcount_byplid(int id, bool only_unplayed)
|
||||
{
|
||||
char *filter;
|
||||
|
||||
filter = sqlite3_mprintf("path IN (SELECT filepath FROM playlistitems WHERE playlistid = %d) %s",
|
||||
id, only_unplayed ? "AND play_count = 0" : "");
|
||||
|
||||
db_file_inc_playcount_byfilter(filter);
|
||||
sqlite3_free(filter);
|
||||
}
|
||||
|
||||
void
|
||||
db_file_inc_playcount_bysongalbumid(int64_t id, bool only_unplayed)
|
||||
{
|
||||
char *filter;
|
||||
|
||||
filter = sqlite3_mprintf("songalbumid = %" PRIi64 " %s",
|
||||
id, only_unplayed ? "AND play_count = 0" : "");
|
||||
|
||||
db_file_inc_playcount_byfilter(filter);
|
||||
sqlite3_free(filter);
|
||||
}
|
||||
|
||||
void
|
||||
db_file_inc_playcount(int id)
|
||||
{
|
||||
char *filter;
|
||||
|
||||
filter = sqlite3_mprintf("id = %d", id);
|
||||
|
||||
db_file_inc_playcount_byfilter(filter);
|
||||
sqlite3_free(filter);
|
||||
}
|
||||
|
||||
void
|
||||
db_file_inc_skipcount(int id)
|
||||
{
|
||||
|
6
src/db.h
6
src/db.h
@ -580,6 +580,12 @@ db_files_get_count(uint32_t *nitems, uint32_t *nstreams, const char *filter);
|
||||
void
|
||||
db_file_inc_playcount(int id);
|
||||
|
||||
void
|
||||
db_file_inc_playcount_byplid(int id, bool only_unplayed);
|
||||
|
||||
void
|
||||
db_file_inc_playcount_bysongalbumid(int64_t id, bool only_unplayed);
|
||||
|
||||
void
|
||||
db_file_inc_skipcount(int id);
|
||||
|
||||
|
@ -3043,6 +3043,38 @@ jsonapi_reply_library_album_tracks(struct httpd_request *hreq)
|
||||
return HTTP_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
jsonapi_reply_library_album_tracks_put_byid(struct httpd_request *hreq)
|
||||
{
|
||||
const char *param;
|
||||
int64_t album_id;;
|
||||
int ret;
|
||||
|
||||
ret = safe_atoi64(hreq->uri_parsed->path_parts[3], &album_id);
|
||||
if (ret < 0)
|
||||
return HTTP_INTERNAL;
|
||||
|
||||
param = evhttp_find_header(hreq->query, "play_count");
|
||||
if (!param)
|
||||
return HTTP_BADREQUEST;
|
||||
|
||||
if (strcmp(param, "increment") == 0)
|
||||
{
|
||||
db_file_inc_playcount_bysongalbumid(album_id, false);
|
||||
}
|
||||
else if (strcmp(param, "played") == 0)
|
||||
{
|
||||
db_file_inc_playcount_bysongalbumid(album_id, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINTF(E_WARN, L_WEB, "Ignoring invalid play_count param '%s'\n", param);
|
||||
return HTTP_BADREQUEST;
|
||||
}
|
||||
|
||||
return HTTP_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
jsonapi_reply_library_tracks_get_byid(struct httpd_request *hreq)
|
||||
{
|
||||
@ -3358,6 +3390,38 @@ jsonapi_reply_library_playlist_playlists(struct httpd_request *hreq)
|
||||
return HTTP_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
jsonapi_reply_library_playlist_tracks_put_byid(struct httpd_request *hreq)
|
||||
{
|
||||
const char *param;
|
||||
int playlist_id;
|
||||
int ret;
|
||||
|
||||
ret = safe_atoi32(hreq->uri_parsed->path_parts[3], &playlist_id);
|
||||
if (ret < 0)
|
||||
return HTTP_INTERNAL;
|
||||
|
||||
param = evhttp_find_header(hreq->query, "play_count");
|
||||
if (!param)
|
||||
return HTTP_BADREQUEST;
|
||||
|
||||
if (strcmp(param, "increment") == 0)
|
||||
{
|
||||
db_file_inc_playcount_byplid(playlist_id, false);
|
||||
}
|
||||
else if (strcmp(param, "played") == 0)
|
||||
{
|
||||
db_file_inc_playcount_byplid(playlist_id, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINTF(E_WARN, L_WEB, "Ignoring invalid play_count param '%s'\n", param);
|
||||
return HTTP_BADREQUEST;
|
||||
}
|
||||
|
||||
return HTTP_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
jsonapi_reply_queue_save(struct httpd_request *hreq)
|
||||
{
|
||||
@ -3993,6 +4057,7 @@ static struct httpd_uri_map adm_handlers[] =
|
||||
{ EVHTTP_REQ_GET, "^/api/library/playlists$", jsonapi_reply_library_playlists },
|
||||
{ EVHTTP_REQ_GET, "^/api/library/playlists/[[:digit:]]+$", jsonapi_reply_library_playlist },
|
||||
{ EVHTTP_REQ_GET, "^/api/library/playlists/[[:digit:]]+/tracks$", jsonapi_reply_library_playlist_tracks },
|
||||
{ EVHTTP_REQ_PUT, "^/api/library/playlists/[[:digit:]]+/tracks", jsonapi_reply_library_playlist_tracks_put_byid},
|
||||
// { EVHTTP_REQ_POST, "^/api/library/playlists/[[:digit:]]+/tracks$", jsonapi_reply_library_playlists_tracks },
|
||||
// { EVHTTP_REQ_DELETE, "^/api/library/playlists/[[:digit:]]+$", jsonapi_reply_library_playlist_tracks },
|
||||
{ EVHTTP_REQ_GET, "^/api/library/playlists/[[:digit:]]+/playlists", jsonapi_reply_library_playlist_playlists },
|
||||
@ -4002,6 +4067,7 @@ static struct httpd_uri_map adm_handlers[] =
|
||||
{ EVHTTP_REQ_GET, "^/api/library/albums$", jsonapi_reply_library_albums },
|
||||
{ EVHTTP_REQ_GET, "^/api/library/albums/[[:digit:]]+$", jsonapi_reply_library_album },
|
||||
{ EVHTTP_REQ_GET, "^/api/library/albums/[[:digit:]]+/tracks$", jsonapi_reply_library_album_tracks },
|
||||
{ EVHTTP_REQ_PUT, "^/api/library/albums/[[:digit:]]+/tracks$", jsonapi_reply_library_album_tracks_put_byid },
|
||||
{ EVHTTP_REQ_GET, "^/api/library/tracks/[[:digit:]]+$", jsonapi_reply_library_tracks_get_byid },
|
||||
{ EVHTTP_REQ_PUT, "^/api/library/tracks/[[:digit:]]+$", jsonapi_reply_library_tracks_put_byid },
|
||||
{ EVHTTP_REQ_GET, "^/api/library/genres$", jsonapi_reply_library_genres},
|
||||
|
Loading…
x
Reference in New Issue
Block a user