""" Router: zdjęcia profilowe użytkowników. Ścieżka na dysku: {files_base_dir}/user_files/profile/.ext Endpointy: POST /user_files/profile/upload – przesyłanie zdjęcia profilowego GET /user_files/profile/file/{filename} – pobieranie zdjęcia profilowego DELETE /user_files/profile/file/{filename} – usuwanie zdjęcia profilowego """ from __future__ import annotations import mimetypes from fastapi import APIRouter, Depends, HTTPException, UploadFile, File from fastapi.responses import FileResponse from ..auth import require_api_key from ..storage import save_file, get_stored_file_path, delete_stored_file router = APIRouter(prefix="/user_files/profile", tags=["user_profile"]) _SUBFOLDER = "user_files/profile" # Dla zdjęć profilowych akceptujemy tylko obrazy _ALLOWED_IMAGE_TYPES = frozenset( {"image/jpeg", "image/png", "image/gif", "image/webp"} ) @router.post("/upload", summary="Prześlij zdjęcie profilowe") async def upload_profile_picture( file: UploadFile = File(...), _key: str = Depends(require_api_key), ): content_type = (file.content_type or "").split(";")[0].strip() if content_type not in _ALLOWED_IMAGE_TYPES: raise HTTPException( status_code=415, detail=f"Zdjęcie profilowe musi być obrazem (JPEG/PNG/GIF/WEBP). Otrzymano: {content_type}", ) result = await save_file( file, _SUBFOLDER, convert_image_to_webp=True, image_max_side=512, image_quality=82, ) return {"success": True, "data": result} @router.get("/file/{filename}", summary="Pobierz zdjęcie profilowe") async def serve_profile_picture( filename: str, _key: str = Depends(require_api_key), ): file_path = get_stored_file_path(_SUBFOLDER, filename) mime = mimetypes.guess_type(str(file_path))[0] or "image/jpeg" return FileResponse( path=str(file_path), media_type=mime, headers={"Content-Disposition": f'inline; filename="{filename}"'}, ) @router.delete("/file/{filename}", summary="Usuń zdjęcie profilowe") async def delete_profile_picture( filename: str, _key: str = Depends(require_api_key), ): deleted = delete_stored_file(_SUBFOLDER, filename) return {"success": deleted}