diff --git a/CHANGELOG.md b/CHANGELOG.md
index e1498a0..83c1133 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,7 +3,7 @@
## New
* Render notes as Markdown
* Require login by default
-* Add stats for dropped purchases
+* Add stats for dropped purchases, monthly playtimes
## Improved
* mark refunded purchases red on game overview
diff --git a/games/templates/stats.html b/games/templates/stats.html
index 1b664ce..24bbe2b 100644
--- a/games/templates/stats.html
+++ b/games/templates/stats.html
@@ -73,6 +73,19 @@
+
+
Playtime per month
+
+
+ {% for month in month_playtimes %}
+
+ {{ month.month | date:"F" }} |
+ {{ month.playtime }} |
+
+ {% endfor %}
+
+
+
Purchases
diff --git a/games/views.py b/games/views.py
index 3f8399c..2f9581c 100644
--- a/games/views.py
+++ b/games/views.py
@@ -12,8 +12,9 @@ from django.db.models import (
Q,
Sum,
fields,
+ IntegerField,
)
-from django.db.models.functions import TruncDate
+from django.db.models.functions import TruncDate, ExtractMonth, TruncMonth
from django.http import (
HttpRequest,
HttpResponse,
@@ -443,6 +444,15 @@ def stats(request, year: int = 0):
)
.values("id", "name", "total_playtime")
)
+ month_playtimes = (
+ this_year_sessions.annotate(month=TruncMonth("timestamp_start"))
+ .values("month")
+ .annotate(playtime=Sum("duration_calculated"))
+ .order_by("month")
+ )
+ for month in month_playtimes:
+ month["playtime"] = format_duration(month["playtime"], "%2.0H")
+
highest_session_average_game = (
Game.objects.filter(edition__purchase__session__in=this_year_sessions)
.annotate(
@@ -574,6 +584,7 @@ def stats(request, year: int = 0):
"last_play_name": last_play_name,
"last_play_date": last_play_date,
"title": f"{year} Stats",
+ "month_playtimes": month_playtimes,
}
request.session["return_path"] = request.path