from fastapi import APIRouter, Depends, HTTPException, File, UploadFile from sqlalchemy.orm import Session from typing import List import uuid import shutil from .. import crud, models, schemas from ..database import get_db router = APIRouter( prefix="/api/celebrities", tags=["celebrities"], responses={404: {"description": "Not found"}}, ) @router.post("/", response_model=schemas.Celebrity, status_code=201) def create_celebrity(celebrity: schemas.CelebrityCreate, db: Session = Depends(get_db)): # Qui potresti aggiungere un check per vedere se una celebrità con lo stesso nome esiste già return crud.create_celebrity(db=db, celebrity=celebrity) @router.get("/", response_model=List[schemas.Celebrity]) def read_celebrities(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)): celebrities = crud.get_celebrities(db, skip=skip, limit=limit) return celebrities @router.get("/{celebrity_id}", response_model=schemas.Celebrity) def read_celebrity(celebrity_id: int, db: Session = Depends(get_db)): db_celebrity = crud.get_celebrity(db, celebrity_id=celebrity_id) if db_celebrity is None: raise HTTPException(status_code=404, detail="Celebrity not found") return db_celebrity @router.put("/{celebrity_id}", response_model=schemas.Celebrity) def update_celebrity(celebrity_id: int, celebrity: schemas.CelebrityUpdate, db: Session = Depends(get_db)): db_celebrity = crud.update_celebrity(db, celebrity_id=celebrity_id, celebrity_update=celebrity) if db_celebrity is None: raise HTTPException(status_code=404, detail="Celebrity not found") return db_celebrity @router.delete("/{celebrity_id}", response_model=schemas.Celebrity) def delete_celebrity(celebrity_id: int, db: Session = Depends(get_db)): db_celebrity = crud.delete_celebrity(db, celebrity_id=celebrity_id) if db_celebrity is None: raise HTTPException(status_code=404, detail="Celebrity not found") return db_celebrity # --- NUOVI ENDPOINT PER LE IMMAGINI --- @router.post("/{celebrity_id}/images", response_model=schemas.Image, status_code=201) def upload_celebrity_image(celebrity_id: int, file: UploadFile = File(...), db: Session = Depends(get_db)): db_celebrity = crud.get_celebrity(db, celebrity_id=celebrity_id) if db_celebrity is None: raise HTTPException(status_code=404, detail="Celebrity not found") file_extension = file.filename.split('.')[-1] unique_filename = f"{uuid.uuid4()}.{file_extension}" file_location = f"uploads/{unique_filename}" with open(file_location, "wb+") as file_object: shutil.copyfileobj(file.file, file_object) return crud.create_celebrity_image(db=db, celebrity_id=celebrity_id, file_path=unique_filename) @router.post("/{celebrity_id}/images/from-url", response_model=schemas.Image, status_code=201) async def add_image_from_url(celebrity_id: int, request: schemas.ImageUrlRequest, db: Session = Depends(get_db)): db_celebrity = crud.get_celebrity(db, celebrity_id=celebrity_id) if not db_celebrity: raise HTTPException(status_code=404, detail="Celebrity not found") url = str(request.url) try: async with httpx.AsyncClient() as client: # Eseguiamo prima una richiesta HEAD per controllare il tipo e la dimensione head_response = await client.head(url, follow_redirects=True, timeout=10) head_response.raise_for_status() content_type = head_response.headers.get('content-type') if not content_type or not content_type.startswith('image/'): raise HTTPException(status_code=400, detail="URL does not point to a valid image.") # Limite di dimensione (es. 10MB) content_length = int(head_response.headers.get('content-length', 0)) if content_length > 10 * 1024 * 1024: raise HTTPException(status_code=400, detail="Image size exceeds 10MB limit.") # Scarica l'immagine get_response = await client.get(url, follow_redirects=True, timeout=30) get_response.raise_for_status() # Determina l'estensione del file file_extension = content_type.split('/')[-1] if file_extension == 'jpeg': file_extension = 'jpg' unique_filename = f"{uuid.uuid4()}.{file_extension}" file_location = f"uploads/{unique_filename}" with open(file_location, "wb") as file_object: file_object.write(get_response.content) return crud.create_celebrity_image(db=db, celebrity_id=celebrity_id, file_path=unique_filename) except httpx.RequestError as exc: raise HTTPException(status_code=400, detail=f"Failed to fetch image from URL: {exc}") except Exception as e: raise HTTPException(status_code=500, detail=f"An internal error occurred: {e}") @router.put("/{celebrity_id}/profile-image", response_model=schemas.Celebrity) def set_celebrity_profile_image(celebrity_id: int, request: schemas.SetProfileImageRequest, db: Session = Depends(get_db)): updated_celebrity = crud.set_profile_image(db, celebrity_id=celebrity_id, image_id=request.image_id) if updated_celebrity is None: raise HTTPException(status_code=404, detail="Celebrity or Image not found, or image does not belong to celebrity.") return updated_celebrity # NOTA: Un approccio più RESTful sarebbe /api/images/{image_id} in un router dedicato. # Per semplicità, lo inseriamo qui. @router.delete("/images/{image_id}", response_model=schemas.Image) def delete_image(image_id: int, db: Session = Depends(get_db)): db_image = crud.delete_image(db, image_id=image_id) if db_image is None: raise HTTPException(status_code=404, detail="Image not found") return db_image