summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--routers/films.py7
-rw-r--r--services/tmdb.py31
-rw-r--r--templates/director.html14
3 files changed, 48 insertions, 4 deletions
diff --git a/routers/films.py b/routers/films.py
index 4bb7cc9..afcf0ae 100644
--- a/routers/films.py
+++ b/routers/films.py
@@ -444,7 +444,7 @@ async def update_film_stars(film_id: int, request: Request, db: Session = Depend
@router.get("/director/{director_name}")
-def director_detail(director_name: str, request: Request, db: Session = Depends(get_db)):
+async def director_detail(director_name: str, request: Request, db: Session = Depends(get_db)):
films = _director_films(db, director_name)
if not films:
raise HTTPException(status_code=404, detail="Director not found.")
@@ -477,12 +477,17 @@ def director_detail(director_name: str, request: Request, db: Session = Depends(
)[0][0]
average_stars = round(sum(film.stars for film in films) / len(films), 1)
+ from services.tmdb import director_info
+ director_data = await director_info(display_name)
+
return templates.TemplateResponse(
request=request,
name="director.html",
context={
"request": request,
"director_name": display_name,
+ "director_image": director_data["image"],
+ "director_biography": director_data["biography"],
"films": films,
"director_summary": {
"total_films_logged": len(films),
diff --git a/services/tmdb.py b/services/tmdb.py
index b3adf17..e749f09 100644
--- a/services/tmdb.py
+++ b/services/tmdb.py
@@ -205,6 +205,37 @@ async def find_movie(
await active_client.aclose()
+async def director_info(director_name: str, key: str | None = None, client: httpx.AsyncClient | None = None) -> dict:
+ """Search for a director by name and return their image and biography."""
+ try:
+ active_client = client
+ owns_client = False
+ if not active_client:
+ active_client = httpx.AsyncClient()
+ owns_client = True
+
+ response = await active_client.get(
+ "https://api.themoviedb.org/3/search/person",
+ params={"api_key": key or api_key(), "query": director_name},
+ )
+ response.raise_for_status()
+ results = response.json().get("results", [])
+
+ if not results:
+ return {"image": None, "biography": None}
+
+ person = results[0]
+ image = poster_url(person.get("profile_path"))
+ biography = (person.get("biography") or "").strip() or None
+
+ return {"image": image, "biography": biography}
+ except Exception:
+ return {"image": None, "biography": None}
+ finally:
+ if owns_client:
+ await active_client.aclose()
+
+
def apply_metadata_to_film(film, metadata: dict) -> bool:
changed = False
fill_if_empty = {
diff --git a/templates/director.html b/templates/director.html
index 3257ee9..98ef9d6 100644
--- a/templates/director.html
+++ b/templates/director.html
@@ -3,9 +3,17 @@
{% block title %}{{ director_name }} · Lumière{% endblock %}
{% block content %}
- <section class="page-heading">
- <p class="eyebrow">Director</p>
- <h1>{{ director_name }}</h1>
+ <section class="page-heading" style="display: flex; gap: 32px; align-items: flex-start;">
+ <div style="flex: 1;">
+ <p class="eyebrow">Director</p>
+ <h1 style="margin: 0;">{{ director_name }}</h1>
+ {% if director_biography %}
+ <p style="margin: 16px 0 0 0; color: var(--muted); line-height: 1.6; font-size: 15px;">{{ director_biography }}</p>
+ {% endif %}
+ </div>
+ {% if director_image %}
+ <img src="{{ director_image }}" alt="{{ director_name }}" style="width: 160px; height: auto; border-radius: 8px; flex-shrink: 0;" loading="lazy" />
+ {% endif %}
</section>
<section class="director-summary" aria-label="Director summary">