82 lines
2.5 KiB
Python
82 lines
2.5 KiB
Python
"""Fetch landing-page photos (one-time + re-runnable).
|
|
|
|
Downloads royalty-free originals (see SOURCES.md next to the photos),
|
|
resizes to max 1600px wide and stores them as WebP q80 in
|
|
frontend/public/photos/ (self-hosted: no hotlinking, no tracking).
|
|
|
|
Run in the api container (has network + Pillow):
|
|
docker compose exec api /opt/venv/bin/python \\
|
|
/srv/kirche-einfach/frontend/scripts/fetch-photos.py
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
import urllib.request
|
|
from io import BytesIO
|
|
from pathlib import Path
|
|
|
|
try:
|
|
from PIL import Image
|
|
except ImportError:
|
|
sys.exit("Pillow required (present in the api image)")
|
|
|
|
ROOT = Path(__file__).resolve().parent.parent.parent
|
|
OUT = ROOT / "frontend" / "public" / "photos"
|
|
|
|
|
|
def pexels(photo_id: int) -> str:
|
|
return (
|
|
f"https://images.pexels.com/photos/{photo_id}/"
|
|
f"pexels-photo-{photo_id}.jpeg?auto=compress&cs=tinysrgb&w=1600"
|
|
)
|
|
|
|
|
|
PHOTOS = {
|
|
# target file -> (direct file URL, source page for SOURCES.md)
|
|
"hero-church.webp": (
|
|
pexels(31630127),
|
|
"https://www.pexels.com/photo/historic-church-with-bell-tower-in-germany-31630127/",
|
|
),
|
|
"church-pews.webp": (
|
|
pexels(7566207),
|
|
"https://www.pexels.com/photo/church-pews-7566207/",
|
|
),
|
|
"paperwork-desk.webp": (
|
|
pexels(18687845),
|
|
"https://www.pexels.com/photo/desk-with-documents-and-stamps-18687845/",
|
|
),
|
|
"team-laptop.webp": (
|
|
pexels(7793702),
|
|
"https://www.pexels.com/photo/a-team-looking-at-a-laptop-7793702/",
|
|
),
|
|
"pilot-meeting.webp": (
|
|
pexels(5668858),
|
|
"https://www.pexels.com/photo/two-people-shaking-hands-5668858/",
|
|
),
|
|
}
|
|
|
|
|
|
def fetch(url: str) -> bytes:
|
|
req = urllib.request.Request(url, headers={"User-Agent": "kirche-einfach/1.0"})
|
|
with urllib.request.urlopen(req, timeout=120) as response:
|
|
return response.read()
|
|
|
|
|
|
def main() -> None:
|
|
OUT.mkdir(parents=True, exist_ok=True)
|
|
for filename, (url, _page) in PHOTOS.items():
|
|
raw = fetch(url)
|
|
with Image.open(BytesIO(raw)) as img:
|
|
img = img.convert("RGB")
|
|
if img.width > 1600:
|
|
img = img.resize(
|
|
(1600, round(img.height * 1600 / img.width)), Image.LANCZOS
|
|
)
|
|
target = OUT / Path(filename).with_suffix(".webp").name
|
|
img.save(target, "WEBP", quality=80, method=6)
|
|
print(f"wrote {target} ({target.stat().st_size // 1024} KB)")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|