import logging from pathlib import Path from app.celery_app import celery_app from app.core.config import settings logger = logging.getLogger(__name__) THUMB_SIZES = [(400, 400), (200, 200)] @celery_app.task(bind=True, max_retries=3, default_retry_delay=10) def generate_thumbnail(self, image_path: str): """Generate thumbnail variants for an uploaded image.""" try: from PIL import Image if settings.STORAGE_BACKEND != "local": logger.info("Thumbnail generation skipped for non-local storage: %s", image_path) return {"status": "skipped", "reason": "non-local storage"} full_path = Path(settings.LOCAL_STORAGE_PATH) / image_path.lstrip("/") if not full_path.exists(): logger.warning("Image not found: %s", full_path) return {"status": "error", "reason": "file not found"} results = [] img = Image.open(full_path) if img.mode in ("RGBA", "P"): img = img.convert("RGB") for w, h in THUMB_SIZES: thumb = img.copy() thumb.thumbnail((w, h), Image.LANCZOS) suffix = full_path.suffix or ".jpg" thumb_name = f"{full_path.stem}_{w}x{h}{suffix}" thumb_path = full_path.parent / thumb_name thumb.save(str(thumb_path), quality=85, optimize=True) results.append(str(thumb_path)) logger.info("Generated thumbnail: %s", thumb_path) return {"status": "ok", "thumbnails": results} except Exception as exc: logger.exception("Thumbnail generation failed for %s", image_path) raise self.retry(exc=exc)