[json-api] Setting of track attribs time_played/time_skipped and make generic

This commit is contained in:
ejurgensen 2024-10-17 23:31:46 +02:00
parent 750f83b7e0
commit 12f728629f
3 changed files with 53 additions and 63 deletions

View File

@ -59,6 +59,22 @@
# include "inputs/spotify.h" # include "inputs/spotify.h"
#endif #endif
struct track_attribs
{
enum library_attrib type;
const char *name;
};
// Currently these must all be uint32
static const struct track_attribs track_attribs[] =
{
{ LIBRARY_ATTRIB_PLAY_COUNT, "play_count", },
{ LIBRARY_ATTRIB_SKIP_COUNT, "skip_count", },
{ LIBRARY_ATTRIB_TIME_PLAYED, "time_played", },
{ LIBRARY_ATTRIB_TIME_SKIPPED, "time_skipped", },
{ LIBRARY_ATTRIB_RATING, "rating", },
{ LIBRARY_ATTRIB_USERMARK, "usermark", },
};
static bool allow_modifying_stored_playlists; static bool allow_modifying_stored_playlists;
static char *default_playlist_directory; static char *default_playlist_directory;
@ -3221,6 +3237,7 @@ jsonapi_reply_library_tracks_put(struct httpd_request *hreq)
int err; int err;
int32_t track_id; int32_t track_id;
int i; int i;
int j;
request = jparse_obj_from_evbuffer(hreq->in_body); request = jparse_obj_from_evbuffer(hreq->in_body);
if (!request) if (!request)
@ -3257,13 +3274,18 @@ jsonapi_reply_library_tracks_put(struct httpd_request *hreq)
goto error; goto error;
} }
// These are async, so no error check for (j = 0; j < ARRAY_SIZE(track_attribs); j++)
if (jparse_contains_key(track, "rating", json_type_int)) {
library_item_attrib_save(track_id, LIBRARY_ATTRIB_RATING, jparse_int_from_obj(track, "rating")); if (!jparse_contains_key(track, track_attribs[j].name, json_type_int))
if (jparse_contains_key(track, "usermark", json_type_int)) continue;
library_item_attrib_save(track_id, LIBRARY_ATTRIB_USERMARK, jparse_int_from_obj(track, "usermark"));
if (jparse_contains_key(track, "play_count", json_type_int)) ret = jparse_int_from_obj(track, track_attribs[j].name);
library_item_attrib_save(track_id, LIBRARY_ATTRIB_PLAY_COUNT, jparse_int_from_obj(track, "play_count")); if (ret < 0)
continue;
// async, so no error check
library_item_attrib_save(track_id, track_attribs[j].type, ret);
}
i++; i++;
} }
@ -3286,6 +3308,7 @@ jsonapi_reply_library_tracks_put_byid(struct httpd_request *hreq)
const char *param; const char *param;
uint32_t val; uint32_t val;
int ret; int ret;
int i;
ret = safe_atoi32(hreq->path_parts[3], &track_id); ret = safe_atoi32(hreq->path_parts[3], &track_id);
if (ret < 0 || !db_file_id_exists(track_id)) if (ret < 0 || !db_file_id_exists(track_id))
@ -3294,66 +3317,32 @@ jsonapi_reply_library_tracks_put_byid(struct httpd_request *hreq)
return HTTP_NOTFOUND; return HTTP_NOTFOUND;
} }
param = httpd_query_value_find(hreq->query, "play_count"); for (i = 0; i < ARRAY_SIZE(track_attribs); i++)
if (param)
{ {
if (strcmp(param, "increment") == 0) param = httpd_query_value_find(hreq->query, track_attribs[i].name);
if (!param)
continue;
// Special cases
if (track_attribs[i].type == LIBRARY_ATTRIB_PLAY_COUNT && strcmp(param, "increment") == 0)
{ {
db_file_inc_playcount(track_id); db_file_inc_playcount(track_id);
continue;
} }
else if (strcmp(param, "reset") == 0) if (track_attribs[i].type == LIBRARY_ATTRIB_PLAY_COUNT && strcmp(param, "reset") == 0)
{ {
db_file_reset_playskip_count(track_id); db_file_reset_playskip_count(track_id);
continue;
} }
else if (safe_atou32(param, &val) == 0)
{
library_item_attrib_save(track_id, LIBRARY_ATTRIB_PLAY_COUNT, val);
}
else
{
DPRINTF(E_WARN, L_WEB, "Invalid play_count value '%s' for track '%d'.\n", param, track_id);
return HTTP_BADREQUEST;
}
}
param = httpd_query_value_find(hreq->query, "skip_count");
if (param)
{
ret = safe_atou32(param, &val); ret = safe_atou32(param, &val);
if (ret < 0) if (ret < 0)
{ {
DPRINTF(E_WARN, L_WEB, "Invalid skip_count value '%s' for track '%d'.\n", param, track_id); DPRINTF(E_WARN, L_WEB, "Invalid %s value '%s' for track '%d'.\n", track_attribs[i].name, param, track_id);
return HTTP_BADREQUEST; return HTTP_BADREQUEST;
} }
library_item_attrib_save(track_id, LIBRARY_ATTRIB_SKIP_COUNT, val); library_item_attrib_save(track_id, track_attribs[i].type, val);
}
param = httpd_query_value_find(hreq->query, "rating");
if (param)
{
ret = safe_atou32(param, &val);
if (ret < 0 || val > DB_FILES_RATING_MAX)
{
DPRINTF(E_WARN, L_WEB, "Invalid rating value '%s' for track '%d'.\n", param, track_id);
return HTTP_BADREQUEST;
}
library_item_attrib_save(track_id, LIBRARY_ATTRIB_RATING, val);
}
// Retreive marked tracks via "/api/search?type=tracks&expression=usermark+=+1"
param = httpd_query_value_find(hreq->query, "usermark");
if (param)
{
ret = safe_atou32(param, &val);
if (ret < 0)
{
DPRINTF(E_WARN, L_WEB, "Invalid usermark value '%s' for track '%d'.\n", param, track_id);
return HTTP_BADREQUEST;
}
library_item_attrib_save(track_id, LIBRARY_ATTRIB_USERMARK, val);
} }
return HTTP_OK; return HTTP_OK;

View File

@ -667,7 +667,7 @@ item_attrib_save(void *arg, int *retval)
switch (param->attrib) switch (param->attrib)
{ {
case LIBRARY_ATTRIB_RATING: case LIBRARY_ATTRIB_RATING:
if (param->value < 0 || param->value > DB_FILES_RATING_MAX) if (param->value > DB_FILES_RATING_MAX)
goto error; goto error;
mfi->rating = param->value; mfi->rating = param->value;
@ -679,26 +679,25 @@ item_attrib_save(void *arg, int *retval)
break; break;
case LIBRARY_ATTRIB_USERMARK: case LIBRARY_ATTRIB_USERMARK:
if (param->value < 0)
goto error;
mfi->usermark = param->value; mfi->usermark = param->value;
break; break;
case LIBRARY_ATTRIB_PLAY_COUNT: case LIBRARY_ATTRIB_PLAY_COUNT:
if (param->value < 0)
goto error;
mfi->play_count = param->value; mfi->play_count = param->value;
break; break;
case LIBRARY_ATTRIB_SKIP_COUNT: case LIBRARY_ATTRIB_SKIP_COUNT:
if (param->value < 0)
goto error;
mfi->skip_count = param->value; mfi->skip_count = param->value;
break; break;
case LIBRARY_ATTRIB_TIME_PLAYED:
mfi->time_played = param->value;
break;
case LIBRARY_ATTRIB_TIME_SKIPPED:
mfi->time_skipped = param->value;
break;
default: default:
goto error; goto error;
} }

View File

@ -53,6 +53,8 @@ enum library_attrib
LIBRARY_ATTRIB_USERMARK, LIBRARY_ATTRIB_USERMARK,
LIBRARY_ATTRIB_PLAY_COUNT, LIBRARY_ATTRIB_PLAY_COUNT,
LIBRARY_ATTRIB_SKIP_COUNT, LIBRARY_ATTRIB_SKIP_COUNT,
LIBRARY_ATTRIB_TIME_PLAYED,
LIBRARY_ATTRIB_TIME_SKIPPED,
}; };
/* /*