diff options
Diffstat (limited to 'routers/profile.py')
| -rw-r--r-- | routers/profile.py | 91 |
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}, + ) |
