summaryrefslogtreecommitdiff
path: root/routers/profile.py
diff options
context:
space:
mode:
Diffstat (limited to 'routers/profile.py')
-rw-r--r--routers/profile.py91
1 files changed, 91 insertions, 0 deletions
diff --git a/routers/profile.py b/routers/profile.py
new file mode 100644
index 0000000..1986257
--- /dev/null
+++ b/routers/profile.py
@@ -0,0 +1,91 @@
+from fastapi import APIRouter, Depends, Request
+from fastapi.templating import Jinja2Templates
+from sqlalchemy.orm import Session
+
+from database import get_db
+from models import Film
+
+router = APIRouter(tags=["profile"])
+templates = Jinja2Templates(directory="templates")
+
+
+def _diary_films(db: Session) -> list[Film]:
+ return (
+ db.query(Film)
+ .filter(Film.shelf == "diary", Film.date_watched.is_not(None))
+ .order_by(Film.date_watched.desc())
+ .all()
+ )
+
+
+def _build_profile_payload(films: list[Film]) -> dict:
+ from collections import Counter
+ from services.countries import split_country_names
+ from services.film_people import split_credit_names
+
+ if not films:
+ return {
+ "total_watched": 0,
+ "average_stars": 0,
+ "most_watched_directors": [],
+ "star_distribution": [{"stars": stars, "count": 0} for stars in (0, 1, 2, 3)],
+ "films_per_country": [],
+ "recent_films": [],
+ }
+
+ countries = Counter()
+ directors = Counter()
+ star_counts = Counter({0: 0, 1: 0, 2: 0, 3: 0})
+
+ total_stars = 0
+ valid_ratings = 0
+
+ for film in films:
+ country_names = split_country_names(film.country)
+ countries.update(country_names)
+
+ directors.update(split_credit_names(film.director))
+
+ stars = film.stars if film.stars in {0, 1, 2, 3} else 0
+ star_counts[stars] += 1
+ if film.stars in {0, 1, 2, 3}:
+ total_stars += film.stars
+ valid_ratings += 1
+
+ total_watched = len(films)
+ average_stars = round(total_stars / valid_ratings, 1) if valid_ratings else 0
+
+ return {
+ "total_watched": total_watched,
+ "average_stars": average_stars,
+ "most_watched_directors": [
+ {"director": director, "count": count}
+ for director, count in sorted(directors.items(), key=lambda item: (-item[1], item[0]))[:5]
+ ],
+ "star_distribution": [{"stars": stars, "count": star_counts[stars]} for stars in (0, 1, 2, 3)],
+ "films_per_country": [
+ {"country": country, "count": count}
+ for country, count in sorted(countries.items(), key=lambda item: (-item[1], item[0]))[:10]
+ ],
+ "recent_films": [
+ {
+ "id": film.id,
+ "title": film.title,
+ "poster_url": film.poster_url,
+ "date_watched": film.date_watched.isoformat() if film.date_watched else None,
+ "stars": film.stars,
+ }
+ for film in films[:4]
+ ],
+ }
+
+
+@router.get("/tyler")
+async def public_profile(request: Request, db: Session = Depends(get_db)):
+ films = _diary_films(db)
+ payload = _build_profile_payload(films)
+ return templates.TemplateResponse(
+ request=request,
+ name="profile.html",
+ context={"request": request, **payload},
+ )