diff --git a/app/api/scrobble/__init__.py b/app/api/scrobble/__init__.py index e06665ce..6573fa8d 100644 --- a/app/api/scrobble/__init__.py +++ b/app/api/scrobble/__init__.py @@ -1,4 +1,5 @@ from dataclasses import dataclass +from itertools import groupby from math import e from pprint import pprint from flask_openapi3 import Tag @@ -8,6 +9,7 @@ from app.api.apischemas import TrackHashSchema from typing import Literal from datetime import datetime, timedelta from collections import defaultdict +import locale from app.db.userdata import ScrobbleTable from app.lib.extras import get_extra_info @@ -128,10 +130,10 @@ def get_top_tracks(query: TopTracksQuery): start_time = end_time - query.duration previous_start_time = start_time - query.duration - current_period_tracks, current_period_scrobbles = get_tracks_in_period( + current_period_tracks, current_period_scrobbles, duration = get_tracks_in_period( start_time, end_time ) - previous_period_tracks, previous_period_scrobbles = get_tracks_in_period( + previous_period_tracks, previous_period_scrobbles, _ = get_tracks_in_period( previous_start_time, start_time ) scrobble_trend = ( @@ -165,7 +167,7 @@ def get_top_tracks(query: TopTracksQuery): return { "tracks": response, "scrobbles": { - "text": f"{current_period_scrobbles} total play{'' if current_period_scrobbles == 1 else 's'}", + "text": f"{current_period_scrobbles} total play{'' if current_period_scrobbles == 1 else 's'} ({seconds_to_time_string(duration)})", "trend": scrobble_trend, }, }, 200 @@ -292,3 +294,49 @@ def get_top_albums(query: TopAlbumsQuery): def sort_albums(albums: list[Album], order_by: Literal["playcount", "playduration"]): return sorted(albums, key=lambda x: getattr(x, order_by), reverse=True) + + +@api.get("/stats") +def get_stats(): + """ + Get the stats for the user. + """ + now = int(datetime.now().timestamp()) + one_week_ago = now - 23731580 + + total_tracks = { + "class": "trackcount", + "text": "Total tracks", + "value": len(TrackStore.get_flat_list()), + } + last_7_days_data, last_7_days_playcount, last_7_days_playduration = ( + get_tracks_in_period(one_week_ago, now) + ) + + last_7_days_playcount = { + "class": "streams", + "text": "Track plays last week", + "value": last_7_days_playcount, + } + + last_7_days_playduration = { + "class": "playtime", + "text": "Playtime last week", + "value": seconds_to_time_string(last_7_days_playduration), + } + + # Find the top track from the last 7 days + top_track = { + "class": "toptrack", + "text": "Top track last week", + "value": last_7_days_data[0].title, + } + + return { + "stats": [ + last_7_days_playcount, + last_7_days_playduration, + total_tracks, + top_track, + ] + } diff --git a/app/utils/dates.py b/app/utils/dates.py index 82172946..e0e45bc9 100644 --- a/app/utils/dates.py +++ b/app/utils/dates.py @@ -56,11 +56,11 @@ def seconds_to_time_string(seconds): if hours > 0: if minutes > 0: - return f"{hours} hr{'s' if hours > 1 else ''}, {minutes} minute{'s' if minutes > 1 else ''}" + return f"{hours} hr{'s' if hours > 1 else ''}, {minutes} min{'s' if minutes > 1 else ''}" return f"{hours} hr{'s' if hours > 1 else ''}" if minutes > 0: - return f"{minutes} minute{'s' if minutes > 1 else ''}" + return f"{minutes} min{'s' if minutes > 1 else ''}" - return f"{remaining_seconds} second{'' if remaining_seconds == 1 else 's'}" + return f"{remaining_seconds} sec" diff --git a/app/utils/stats.py b/app/utils/stats.py index aa841d31..ab4af25a 100644 --- a/app/utils/stats.py +++ b/app/utils/stats.py @@ -56,6 +56,7 @@ def get_albums_in_period(start_time: int, end_time: int): def get_tracks_in_period(start_time: int, end_time: int): scrobbles = ScrobbleTable.get_all_in_period(start_time, end_time) tracks: dict[str, Track] = {} + duration = 0 for scrobble in scrobbles: if scrobble.trackhash not in tracks: @@ -70,8 +71,9 @@ def get_tracks_in_period(start_time: int, end_time: int): tracks[scrobble.trackhash].playcount += 1 tracks[scrobble.trackhash].playduration += scrobble.duration + duration += scrobble.duration - return list(tracks.values()), len(scrobbles) + return list(tracks.values()), len(scrobbles), duration T = TypeVar("T")