"""Cloudinary helpers for quiz audio/images and optional StorageBackend.""" from __future__ import annotations import logging from app.core.config import settings logger = logging.getLogger(__name__) _CONFIGURED = False def ensure_cloudinary_configured() -> bool: """Configure cloudinary SDK once; return False if credentials missing.""" global _CONFIGURED if _CONFIGURED: return True cloud_name = (settings.CLOUDINARY_CLOUD_NAME or "").strip() api_key = (settings.CLOUDINARY_API_KEY or "").strip() api_secret = (settings.CLOUDINARY_API_SECRET or "").strip() if not cloud_name or not api_key or not api_secret: return False try: import cloudinary cloudinary.config( cloud_name=cloud_name, api_key=api_key, api_secret=api_secret, secure=True, ) _CONFIGURED = True return True except Exception as exc: logger.warning("Cloudinary configure failed: %s", exc) return False def cloudinary_public_url(public_id: str, resource_type: str, ext: str) -> str: """Build delivery URL: .../video/upload/audio/{uuid}.mp3 or .../image/upload/images/{uuid}.png""" cloud_name = (settings.CLOUDINARY_CLOUD_NAME or "").strip() fmt = ext.lstrip(".") folder_id = public_id.strip("/") if resource_type == "video": return f"https://res.cloudinary.com/{cloud_name}/video/upload/{folder_id}.{fmt}" return f"https://res.cloudinary.com/{cloud_name}/image/upload/{folder_id}.{fmt}" def cloudinary_resource_exists(public_id: str, resource_type: str) -> bool: if not ensure_cloudinary_configured(): return False try: import cloudinary.api cloudinary.api.resource(public_id, resource_type=resource_type) return True except Exception: return False