add new favorites to stats

This commit is contained in:
cwilvx
2024-10-14 17:23:29 +03:00
parent c1d7c73649
commit 99f9bc80c9
4 changed files with 68 additions and 21 deletions
+41 -15
View File
@@ -12,7 +12,7 @@ from datetime import datetime, timedelta
from collections import defaultdict from collections import defaultdict
import locale import locale
from app.db.userdata import ScrobbleTable from app.db.userdata import FavoritesTable, ScrobbleTable
from app.lib.extras import get_extra_info from app.lib.extras import get_extra_info
from app.models.album import Album from app.models.album import Album
from app.models.stats import StatItem from app.models.stats import StatItem
@@ -295,27 +295,39 @@ def get_stats():
""" """
Get the stats for the user. Get the stats for the user.
""" """
start_time, end_time = get_date_range("week") period = "week"
start_time, end_time = get_date_range(period)
said_period = period
match period:
case "week":
said_period = "this week"
case "month":
said_period = "this month"
case "year":
said_period = "this year"
case "alltime":
said_period = "all time"
count = len(TrackStore.get_flat_list())
total_tracks = StatItem( total_tracks = StatItem(
"trackcount", "trackcount",
"Total tracks", "in your library",
len(TrackStore.get_flat_list()), f"{count} track{'' if count == 1 else 's'}",
)
tracks, playcount, playduration = (
get_tracks_in_period(start_time, end_time)
) )
tracks, playcount, playduration = get_tracks_in_period(start_time, end_time)
playcount = StatItem( playcount = StatItem(
"streams", "streams",
"Track plays last week", said_period,
playcount, f"{playcount} track{'' if playcount == 1 else 's'} played",
) )
playduration = StatItem( playduration = StatItem(
"playtime", "playtime",
"Playtime last week", said_period,
seconds_to_time_string(playduration), f"{seconds_to_time_string(playduration)} listened",
) )
tracks = sorted(tracks, key=lambda t: t.playduration, reverse=True) tracks = sorted(tracks, key=lambda t: t.playduration, reverse=True)
@@ -323,8 +335,20 @@ def get_stats():
# Find the top track from the last 7 days # Find the top track from the last 7 days
top_track = StatItem( top_track = StatItem(
"toptrack", "toptrack",
"Top track last week", f"Top track {said_period}",
tracks[0].title if len(tracks) > 0 else "-", (
tracks[0].title + " - " + tracks[0].artists[0]["name"]
if len(tracks) > 0
else ""
),
tracks[0].image if len(tracks) > 0 else None,
)
fav_count = FavoritesTable.count_favs_in_period(start_time, end_time)
favorites = StatItem(
"favorites",
said_period,
f"{fav_count} {'new' if period != 'alltime' else ''} favorite{'' if fav_count == 1 else 's'}",
) )
return { return {
@@ -332,6 +356,8 @@ def get_stats():
top_track, top_track,
playcount, playcount,
playduration, playduration,
favorites,
total_tracks, total_tracks,
] ],
} "dates": format_date(start_time, end_time),
}, 200
+16
View File
@@ -8,6 +8,7 @@ from sqlalchemy import (
String, String,
and_, and_,
delete, delete,
func,
insert, insert,
select, select,
update, update,
@@ -248,6 +249,21 @@ class FavoritesTable(Base):
result, total = cls.get_all_of_type("artist", start, limit) result, total = cls.get_all_of_type("artist", start, limit)
return favorites_to_dataclass(result), total return favorites_to_dataclass(result), total
@classmethod
def count_favs_in_period(cls, start_time: int, end_time: int):
result = cls.execute(
select(func.count(cls.id)).where(
and_(cls.timestamp >= start_time, cls.timestamp <= end_time)
)
)
result = result.fetchone()
if result:
return result[0]
return 0
class ScrobbleTable(Base): class ScrobbleTable(Base):
__tablename__ = "scrobble" __tablename__ = "scrobble"
+1
View File
@@ -6,3 +6,4 @@ class StatItem:
cssclass: str cssclass: str
text: str text: str
value: str | int value: str | int
image: str | None = None
+10 -6
View File
@@ -70,29 +70,33 @@ def get_date_range(duration: str):
""" """
Returns a tuple of dates representing the start and end of a given duration. Returns a tuple of dates representing the start and end of a given duration.
""" """
date_range = None
match duration: match duration:
case "week": case "week":
return ( date_range = (
pendulum.now().subtract().start_of("week").timestamp(), pendulum.now().subtract().start_of("week").timestamp(),
pendulum.now().end_of("week").timestamp(), pendulum.now().end_of("week").timestamp(),
) )
case "month": case "month":
return ( date_range = (
pendulum.now().subtract().start_of("month").timestamp(), pendulum.now().subtract().start_of("month").timestamp(),
pendulum.now().end_of("month").timestamp(), pendulum.now().end_of("month").timestamp(),
) )
case "year": case "year":
return ( date_range = (
pendulum.now().subtract().start_of("year").timestamp(), pendulum.now().subtract().start_of("year").timestamp(),
pendulum.now().end_of("year").timestamp(), pendulum.now().end_of("year").timestamp(),
) )
case "alltime": case "alltime":
return (float(0), pendulum.now().timestamp()) date_range = (float(0), pendulum.now().timestamp())
case _: case _:
raise ValueError(f"Invalid duration: {duration}") raise ValueError(f"Invalid duration: {duration}")
return (int(date_range[0]), int(date_range[1]))
def get_duration_in_seconds(duration: str) -> float:
def get_duration_in_seconds(duration: str) -> int:
""" """
Returns the number of seconds in a given duration. Returns the number of seconds in a given duration.
""" """
@@ -104,6 +108,6 @@ def get_duration_in_seconds(duration: str) -> float:
case "year": case "year":
return 31556926 return 31556926
case "alltime": case "alltime":
return pendulum.now().timestamp() return int(pendulum.now().timestamp())
raise ValueError(f"Invalid duration: {duration}") raise ValueError(f"Invalid duration: {duration}")