summaryrefslogtreecommitdiff
path: root/routers
diff options
context:
space:
mode:
authorTyler Hoang <tyler@tylerhoang.xyz>2026-05-15 01:50:15 -0700
committerTyler Hoang <tyler@tylerhoang.xyz>2026-05-15 01:50:15 -0700
commit20c1d02b40bcb9abb5882d0503e596c82e9819bb (patch)
treea2e8918b7f742b23a580daff7f844c576f31c33d /routers
parent19f2fc05387ed0d7ad5f5fcb2fa92573ece1eae0 (diff)
Refine Lumi stats and detail UX
Diffstat (limited to 'routers')
-rw-r--r--routers/films.py31
-rw-r--r--routers/stats.py20
2 files changed, 51 insertions, 0 deletions
diff --git a/routers/films.py b/routers/films.py
index 56f50c5..21feab8 100644
--- a/routers/films.py
+++ b/routers/films.py
@@ -220,6 +220,34 @@ def _group_films_by_month(films: list[Film]) -> list[dict]:
return grouped
+def _shelf_snapshot(films: list[Film], shelf: str) -> list[dict[str, str | int]]:
+ if shelf == "diary":
+ rated = sum(1 for film in films if film.stars)
+ latest_watch = next((film.date_watched for film in films if film.date_watched), None)
+ return [
+ {"label": "Entries", "value": len(films)},
+ {"label": "Rated", "value": rated},
+ {"label": "Latest", "value": latest_watch.isoformat() if latest_watch else "Not set"},
+ ]
+
+ if shelf == "queue":
+ with_posters = sum(1 for film in films if film.poster_url)
+ with_notes = sum(1 for film in films if film.notes)
+ return [
+ {"label": "Queued", "value": len(films)},
+ {"label": "With posters", "value": with_posters},
+ {"label": "With notes", "value": with_notes},
+ ]
+
+ rated = sum(1 for film in films if film.stars)
+ with_notes = sum(1 for film in films if film.notes)
+ return [
+ {"label": "Entries", "value": len(films)},
+ {"label": "Rated", "value": rated},
+ {"label": "With notes", "value": with_notes},
+ ]
+
+
def _render_shelf(
shelf: str,
request: Request,
@@ -228,6 +256,7 @@ def _render_shelf(
):
query = _get_shelf_query(db, shelf)
total_films = query.count()
+ shelf_snapshot = _shelf_snapshot(query.all(), shelf)
films = query.limit(20).all()
has_more = total_films > 20
@@ -245,6 +274,7 @@ def _render_shelf(
"grouped_films": grouped_films,
"active_shelf": shelf,
"shelf_meta": SHELF_META[shelf],
+ "shelf_snapshot": shelf_snapshot,
"total_films": total_films,
"has_more": has_more,
**notices,
@@ -483,6 +513,7 @@ async def film_detail(film_id: int, request: Request, db: Session = Depends(get_
"request": request,
"film": film,
"active_shelf": film.shelf,
+ "shelf_meta": SHELF_META.get(film.shelf, SHELF_META["diary"]),
"tmdb_context": tmdb_context,
"rewatch_history": rewatch_history,
"ratings": ratings,
diff --git a/routers/stats.py b/routers/stats.py
index d600e5a..ad07e0c 100644
--- a/routers/stats.py
+++ b/routers/stats.py
@@ -65,7 +65,9 @@ def _build_stats_payload(films: list[Film]) -> dict:
watched_with["solo"] += 1
total_watched = len(films)
+ rewatches = sum(1 for film in films if film.rewatch or film.rewatch_count > 0)
total_runtime_minutes = sum(film.runtime for film in films if film.runtime)
+ average_stars = round(sum(film.stars for film in films) / total_watched, 1) if total_watched else 0
title_groups = defaultdict(list)
for film in films:
@@ -90,6 +92,16 @@ def _build_stats_payload(films: list[Film]) -> dict:
rewatch_details.sort(key=lambda x: (-x["watches"], x["title"]))
+ top_director = None
+ if directors:
+ top_director_name, top_director_count = sorted(directors.items(), key=lambda item: (-item[1], item[0]))[0]
+ top_director = {"director": top_director_name, "count": top_director_count}
+
+ top_month = None
+ if months:
+ top_month_key, top_month_count = sorted(months.items(), key=lambda item: (-item[1], item[0]))[0]
+ top_month = {"month": top_month_key, "count": top_month_count}
+
today = date.today()
start_day = today - timedelta(days=364)
trailing_days = []
@@ -105,6 +117,7 @@ def _build_stats_payload(films: list[Film]) -> dict:
},
"total_watched": total_watched,
"total_runtime_minutes": total_runtime_minutes,
+ "average_stars": average_stars,
"films_per_country": [
{"country": country, "count": count}
for country, count in sorted(countries.items(), key=lambda item: (-item[1], item[0]))
@@ -143,6 +156,13 @@ def _build_stats_payload(films: list[Film]) -> dict:
{"watched_with": watched_with_value, "count": count}
for watched_with_value, count in sorted(watched_with.items(), key=lambda item: (-item[1], item[0]))
],
+ "rewatch_rate": {
+ "rewatched": rewatches,
+ "total_watched": total_watched,
+ "rate": round(rewatches / total_watched, 4) if total_watched else 0,
+ },
+ "top_director": top_director,
+ "top_month": top_month,
}