Files
anotherboobsdirectory/packages/backend/app/routers/celebrities.py
2025-10-10 20:50:46 +02:00

121 lines
5.7 KiB
Python

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