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}, )