mirror of
https://github.com/Andre-Bzk/Rezept0r.git
synced 2026-11-15 15:43:04 +01:00
- Bilder beim Extrahieren lokal cachen (data/images/{id}.ext) und über GET /api/history/{id}/image ausliefern; Löschen bei Verlaufseintrag-Entfernung
- history.db in ./data/ Volume verschoben, damit sie Container-Rebuilds überlebt
- yt-dlp Subprocess-Aufrufe auf Windows gefixt: run_in_executor statt asyncio.create_subprocess_exec (SelectorEventLoop-Kompatibilität)
- ./data:/app/data Docker-Volume für persistente Datenhaltung hinzugefügt
51 lines
1.6 KiB
Python
51 lines
1.6 KiB
Python
"""Local image caching for recipe history."""
|
|
from __future__ import annotations
|
|
import logging
|
|
from pathlib import Path
|
|
from typing import Optional
|
|
|
|
import httpx
|
|
|
|
from app.config import get_settings
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
MIME_TO_EXT = {
|
|
"image/jpeg": "jpg",
|
|
"image/png": "png",
|
|
"image/webp": "webp",
|
|
"image/gif": "gif",
|
|
}
|
|
|
|
|
|
def images_dir() -> Path:
|
|
p = Path(get_settings().images_dir)
|
|
p.mkdir(parents=True, exist_ok=True)
|
|
return p
|
|
|
|
|
|
def find_cached_image(history_id: int) -> Optional[Path]:
|
|
"""Return the cached image Path for a history entry, or None."""
|
|
for ext in MIME_TO_EXT.values():
|
|
p = images_dir() / f"{history_id}.{ext}"
|
|
if p.exists():
|
|
return p
|
|
return None
|
|
|
|
|
|
async def download_and_cache(history_id: int, remote_url: str) -> Optional[str]:
|
|
"""Download image from remote_url, save locally, return local API path or None on failure."""
|
|
try:
|
|
async with httpx.AsyncClient(timeout=15) as client:
|
|
resp = await client.get(remote_url, follow_redirects=True)
|
|
resp.raise_for_status()
|
|
ct = resp.headers.get("content-type", "image/jpeg").split(";")[0].strip()
|
|
ext = MIME_TO_EXT.get(ct, "jpg")
|
|
dest = images_dir() / f"{history_id}.{ext}"
|
|
dest.write_bytes(resp.content)
|
|
log.info("Cached image for history %d → %s", history_id, dest)
|
|
return f"/api/history/{history_id}/image"
|
|
except Exception as exc:
|
|
log.warning("Image cache failed for history %d: %s", history_id, exc)
|
|
return None
|