summaryrefslogtreecommitdiff
path: root/routers/profile.py
blob: 1986257008942c0426247bafb6c40a4ca9a966b0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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},
    )