diff --git a/backend/app/api/media.py b/backend/app/api/media.py index 6222318..1eb54e1 100644 --- a/backend/app/api/media.py +++ b/backend/app/api/media.py @@ -12,12 +12,13 @@ async def upload_media( file: UploadFile = File(...), context: str = Query(default="note", pattern="^(product|note|attachment)$"), ): - if file.content_type in ALLOWED_IMAGE_TYPES: + content_type = (file.content_type or "").lower() + if content_type in ALLOWED_IMAGE_TYPES: result = await save_image(file, context=context) - elif file.content_type in ALLOWED_AUDIO_TYPES: + elif content_type in ALLOWED_AUDIO_TYPES: result = await save_audio(file) else: - raise HTTPException(status_code=400, detail=f"Type de fichier non supporté : {file.content_type}") + raise HTTPException(status_code=400, detail=f"Type de fichier non supporté : {content_type}") return MediaUploadResponse(**result) diff --git a/backend/app/services/media.py b/backend/app/services/media.py index 35fa5b7..4872e7b 100644 --- a/backend/app/services/media.py +++ b/backend/app/services/media.py @@ -9,9 +9,14 @@ from app.core.config import settings UPLOAD_DIR: Path = settings.upload_path -ALLOWED_IMAGE_TYPES = {"image/jpeg", "image/png", "image/webp", "image/svg+xml"} +ALLOWED_IMAGE_TYPES = { + "image/jpeg", "image/jpg", "image/png", "image/webp", "image/svg+xml", + "image/heic", "image/heif", +} ALLOWED_AUDIO_TYPES = {"audio/webm", "audio/mp4"} +MAX_ORIG_SIZE = (500, 500) + THUMBNAIL_SIZES = { "product": (150, 150), "note": (300, 300), @@ -20,17 +25,18 @@ THUMBNAIL_SIZES = { async def save_image(file: UploadFile, context: str = "note") -> dict: - if file.content_type not in ALLOWED_IMAGE_TYPES: - raise HTTPException(status_code=400, detail=f"Format non supporté : {file.content_type}") + content_type = (file.content_type or "").lower() + if content_type not in ALLOWED_IMAGE_TYPES: + raise HTTPException(status_code=400, detail=f"Format non supporté : {content_type}") file_id = str(uuid.uuid4()) content = await file.read() orig_dir = UPLOAD_DIR / "images" / "originals" orig_dir.mkdir(parents=True, exist_ok=True) - orig_path = orig_dir / f"{file_id}.webp" - if file.content_type == "image/svg+xml": + if content_type == "image/svg+xml": + orig_path = orig_dir / f"{file_id}.svg" orig_path.write_bytes(content) return { "file_id": file_id, @@ -39,16 +45,20 @@ async def save_image(file: UploadFile, context: str = "note") -> dict: "file_type": "image", } + orig_path = orig_dir / f"{file_id}.webp" img = Image.open(io.BytesIO(content)).convert("RGB") + + # Redimensionne l'original à 500×500 max en conservant l'aspect ratio + img.thumbnail(MAX_ORIG_SIZE, Image.LANCZOS) img.save(orig_path, "WEBP", quality=85) thumb_dir = UPLOAD_DIR / "images" / "thumbnails" thumb_dir.mkdir(parents=True, exist_ok=True) thumb_path = thumb_dir / f"{file_id}_thumb.webp" - size = THUMBNAIL_SIZES.get(context, (300, 300)) - img_thumb = Image.open(io.BytesIO(content)).convert("RGB") - img_thumb.thumbnail(size, Image.LANCZOS) + thumb_size = THUMBNAIL_SIZES.get(context, (300, 300)) + img_thumb = img.copy() + img_thumb.thumbnail(thumb_size, Image.LANCZOS) img_thumb.save(thumb_path, "WEBP", quality=80) return { diff --git a/frontend/nginx.conf b/frontend/nginx.conf index 3bffdda..93f5204 100644 --- a/frontend/nginx.conf +++ b/frontend/nginx.conf @@ -4,6 +4,8 @@ server { root /usr/share/nginx/html; index index.html; + client_max_body_size 15m; + gzip on; gzip_types text/plain text/css application/json application/javascript text/xml application/xml image/svg+xml;