posters_service.PostersService.render_race_poster() resolves the GP via existing ErgastService._fetch_season_schedule() + CircuitService.get_circuit_layout_by_ergast_data(), rasterises the SVG with cairosvg, recolours the stroke to white, composes onto a 1000×1500 Pillow canvas with text/strips.
Caches results to cache/posters/{season}-{round:02d}-{layout_slug}.png so subsequent hits are file reads.
Dockerfile changes:
Adds libcairo2 + fonts-dejavu-core system packages (~15 MB)
Adds pillow + cairosvg pip packages
Copies the new posters_service.py into the image
Consumer: the new endpoints become url_poster: entries in the Kometa F1 metadata file in the kometa module (separate PR).
Adds two endpoints that return Plex-poster-shaped (1000×1500) PNGs composed in-process:
| URL | Returns |
|---|---|
| `GET /posters/race/{grand_prix_name}/{season}.png` | Race poster with checker strips, "FORMULA 1" wordmark, round/year ribbon, GP name, rasterised track outline, race date |
| `GET /posters/season/{season}.png` | Season poster with "FORMULA 1" + giant year + "WORLD CHAMPIONSHIP" |
**Examples after deploy:**
```
https://f1-circuits.zurag.be/posters/race/Monaco%20Grand%20Prix/2025.png
https://f1-circuits.zurag.be/posters/race/Mexico%20City%20Grand%20Prix/2023.png
https://f1-circuits.zurag.be/posters/season/2025.png
```
**How it works:**
- `posters_service.PostersService.render_race_poster()` resolves the GP via existing `ErgastService._fetch_season_schedule()` + `CircuitService.get_circuit_layout_by_ergast_data()`, rasterises the SVG with `cairosvg`, recolours the stroke to white, composes onto a 1000×1500 Pillow canvas with text/strips.
- Caches results to `cache/posters/{season}-{round:02d}-{layout_slug}.png` so subsequent hits are file reads.
**Dockerfile changes:**
- Adds `libcairo2` + `fonts-dejavu-core` system packages (~15 MB)
- Adds `pillow` + `cairosvg` pip packages
- Copies the new `posters_service.py` into the image
**Consumer:** the new endpoints become `url_poster:` entries in the Kometa F1 metadata file in the kometa module (separate PR).
Adds two endpoints that return Plex-poster-shaped (1000×1500) PNGs composed in-process:
GET /posters/race/{grand_prix_name}/{season}.pngGET /posters/season/{season}.pngExamples after deploy:
How it works:
posters_service.PostersService.render_race_poster()resolves the GP via existingErgastService._fetch_season_schedule()+CircuitService.get_circuit_layout_by_ergast_data(), rasterises the SVG withcairosvg, recolours the stroke to white, composes onto a 1000×1500 Pillow canvas with text/strips.cache/posters/{season}-{round:02d}-{layout_slug}.pngso subsequent hits are file reads.Dockerfile changes:
libcairo2+fonts-dejavu-coresystem packages (~15 MB)pillow+cairosvgpip packagesposters_service.pyinto the imageConsumer: the new endpoints become
url_poster:entries in the Kometa F1 metadata file in the kometa module (separate PR).f4c6a56d1cでマージされています。