diff --git a/common/time.py b/common/time.py index e3921b3..d6a3982 100644 --- a/common/time.py +++ b/common/time.py @@ -13,7 +13,7 @@ durationformat_manual: str = "%H hours" def _safe_timedelta(duration: timedelta | int | None): - if duration == None: + if duration is None: return timedelta(0) elif isinstance(duration, int): return timedelta(seconds=duration) diff --git a/games/templates/stats.html b/games/templates/stats.html index f900a58..a276c59 100644 --- a/games/templates/stats.html +++ b/games/templates/stats.html @@ -1,5 +1,6 @@ {% load static %} +{% load duration_formatter %} {% partialdef purchase-name %} {% if purchase.type != 'game' %} @@ -111,7 +112,7 @@ {% for month in month_playtimes %} {{ month.month | date:"F" }} - {{ month.playtime }} + {{ month.playtime | format_duration }} {% endfor %} @@ -157,7 +158,7 @@ Name - Playtime (hours) + Playtime @@ -166,7 +167,7 @@ - {{ game.formatted_playtime }} + {{ game.playtime | format_duration }} {% endfor %} @@ -176,14 +177,14 @@ Platform - Playtime (hours) + Playtime {% for item in total_playtime_per_platform %} {{ item.platform_name }} - {{ item.formatted_playtime }} + {{ item.playtime | format_duration }} {% endfor %} @@ -213,14 +214,14 @@ Name - {% comment %} Date {% endcomment %} + Date {% for purchase in this_year_finished_this_year %} {% partial purchase-name %} - {% comment %} {{ purchase.date_finished | date:"d/m/Y" }} {% endcomment %} + {{ purchase.date_finished | date:"d/m/Y" }} {% endfor %} @@ -232,14 +233,14 @@ Name - {% comment %} Date {% endcomment %} + Date {% for purchase in purchased_this_year_finished_this_year %} {% partial purchase-name %} - {% comment %} {{ purchase.date_finished | date:"d/m/Y" }} {% endcomment %} + {{ purchase.date_finished | date:"d/m/Y" }} {% endfor %} diff --git a/games/templatetags/duration_formatter.py b/games/templatetags/duration_formatter.py new file mode 100644 index 0000000..1ec822a --- /dev/null +++ b/games/templatetags/duration_formatter.py @@ -0,0 +1,12 @@ +from datetime import timedelta + +from django import template + +from common.time import durationformat, format_duration + +register = template.Library() + + +@register.filter(name="format_duration") +def filter_format_duration(duration: timedelta, argument: str = durationformat): + return format_duration(duration, format_string=argument) diff --git a/games/views/general.py b/games/views/general.py index ab6759d..28f615f 100644 --- a/games/views/general.py +++ b/games/views/general.py @@ -22,10 +22,10 @@ def model_counts(request: HttpRequest) -> dict[str, bool]: timestamp_start__day=this_day, timestamp_start__month=this_month, timestamp_start__year=this_year, - ).aggregate(time=Sum(F("duration_calculated") + F("duration_manual")))["time"] + ).aggregate(time=Sum(F("duration_total")))["time"] last_7_played = Session.objects.filter( timestamp_start__gte=(now - timedelta(days=7)) - ).aggregate(time=Sum(F("duration_calculated") + F("duration_manual")))["time"] + ).aggregate(time=Sum(F("duration_total")))["time"] return { "game_available": Game.objects.exists(), @@ -137,19 +137,13 @@ def stats_alltime(request: HttpRequest) -> HttpResponse: ) total_spent = this_year_spendings["total_spent"] or 0 - games_with_playtime = ( - Game.objects.filter(sessions__in=this_year_sessions) - .annotate( - total_playtime=Sum( - F("sessions__duration_calculated") + F("sessions__duration_manual") - ) - ) - .values("id", "name", "total_playtime") - ) + games_with_playtime = Game.objects.filter( + sessions__in=this_year_sessions + ).distinct() month_playtimes = ( this_year_sessions.annotate(month=TruncMonth("timestamp_start")) .values("month") - .annotate(playtime=Sum("duration_calculated")) + .annotate(playtime=Sum("duration_total")) .order_by("month") ) for month in month_playtimes: @@ -162,18 +156,14 @@ def stats_alltime(request: HttpRequest) -> HttpResponse: .first() ) top_10_games_by_playtime = games_with_playtime.order_by("-total_playtime")[:10] - for game in top_10_games_by_playtime: - game["formatted_playtime"] = format_duration(game["total_playtime"], "%2.0H") total_playtime_per_platform = ( this_year_sessions.values("game__platform__name") - .annotate(total_playtime=Sum(F("duration_calculated") + F("duration_manual"))) + .annotate(playtime=Sum(F("duration_total"))) .annotate(platform_name=F("game__platform__name")) - .values("platform_name", "total_playtime") - .order_by("-total_playtime") + .values("platform_name", "playtime") + .order_by("-playtime") ) - for item in total_playtime_per_platform: - item["formatted_playtime"] = format_duration(item["total_playtime"], "%2.0H") backlog_decrease_count = ( Purchase.objects.all().intersection(purchases_finished_this_year).count() @@ -362,7 +352,11 @@ def stats(request: HttpRequest, year: int = 0) -> HttpResponse: ) ) purchased_this_year_finished_this_year = ( - this_year_purchases_without_refunded.filter(games__playevents__ended__year=year) + this_year_purchases_without_refunded.filter( + games__playevents__ended__year=year + ).annotate( + game_name=F("games__name"), date_finished=F("games__playevents__ended") + ) ).order_by("games__playevents__ended") this_year_spendings = this_year_purchases_without_refunded.aggregate( @@ -370,23 +364,15 @@ def stats(request: HttpRequest, year: int = 0) -> HttpResponse: ) total_spent = this_year_spendings["total_spent"] or 0 - games_with_playtime = ( - Game.objects.filter(sessions__in=this_year_sessions) - .annotate( - total_playtime=Sum( - F("sessions__duration_calculated") + F("sessions__duration_manual") - ) - ) - .values("id", "name", "total_playtime") - ) + games_with_playtime = Game.objects.filter( + sessions__in=this_year_sessions + ).distinct() month_playtimes = ( this_year_sessions.annotate(month=TruncMonth("timestamp_start")) .values("month") - .annotate(playtime=Sum("duration_calculated")) + .annotate(playtime=Sum("duration_total")) .order_by("month") ) - for month in month_playtimes: - month["playtime"] = format_duration(month["playtime"], "%2.0H") highest_session_average_game = ( Game.objects.filter(sessions__in=this_year_sessions) @@ -394,19 +380,15 @@ def stats(request: HttpRequest, year: int = 0) -> HttpResponse: .order_by("-session_average") .first() ) - top_10_games_by_playtime = games_with_playtime.order_by("-total_playtime") - for game in top_10_games_by_playtime: - game["formatted_playtime"] = format_duration(game["total_playtime"], "%2.0H") + top_10_games_by_playtime = games_with_playtime.order_by("-playtime") total_playtime_per_platform = ( this_year_sessions.values("game__platform__name") - .annotate(total_playtime=Sum(F("duration_calculated") + F("duration_manual"))) + .annotate(playtime=Sum(F("duration_total"))) .annotate(platform_name=F("game__platform__name")) - .values("platform_name", "total_playtime") - .order_by("-total_playtime") + .values("platform_name", "playtime") + .order_by("-playtime") ) - for item in total_playtime_per_platform: - item["formatted_playtime"] = format_duration(item["total_playtime"], "%2.0H") backlog_decrease_count = ( Purchase.objects.filter(date_purchased__year__lt=year)