aliases
This commit is contained in:
Binary file not shown.
@@ -1,4 +1,5 @@
|
||||
import os
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.orm import Session, joinedload
|
||||
from . import models, schemas
|
||||
|
||||
@@ -6,11 +7,25 @@ def get_celebrity(db: Session, celebrity_id: int):
|
||||
# Usiamo joinedload per caricare in anticipo le relazioni e evitare query N+1
|
||||
return db.query(models.Celebrity).options(
|
||||
joinedload(models.Celebrity.profile_image),
|
||||
joinedload(models.Celebrity.images)
|
||||
joinedload(models.Celebrity.images),
|
||||
joinedload(models.Celebrity.aliases) # Carica anche gli alias
|
||||
).filter(models.Celebrity.id == celebrity_id).first()
|
||||
|
||||
def get_celebrities(db: Session, skip: int = 0, limit: int = 100):
|
||||
return db.query(models.Celebrity).offset(skip).limit(limit).all()
|
||||
def get_celebrities(db: Session, skip: int = 0, limit: int = 100, search: str = None):
|
||||
query = db.query(models.Celebrity).options(
|
||||
joinedload(models.Celebrity.profile_image)
|
||||
)
|
||||
if search:
|
||||
search_term = f"%{search}%"
|
||||
# Esegue un join con la tabella degli alias e filtra per nome o per alias
|
||||
query = query.outerjoin(models.Celebrity.aliases).filter(
|
||||
sa.or_(
|
||||
models.Celebrity.name.ilike(search_term),
|
||||
models.CelebrityAlias.alias_name.ilike(search_term)
|
||||
)
|
||||
).distinct() # distinct() evita duplicati se una celebrità ha più alias che matchano
|
||||
|
||||
return query.offset(skip).limit(limit).all()
|
||||
|
||||
def create_celebrity(db: Session, celebrity: schemas.CelebrityCreate):
|
||||
db_celebrity = models.Celebrity(**celebrity.model_dump())
|
||||
@@ -41,6 +56,23 @@ def delete_celebrity(db: Session, celebrity_id: int):
|
||||
db.commit()
|
||||
return db_celebrity
|
||||
|
||||
# --- Funzioni CRUD per gli Alias ---
|
||||
|
||||
def create_celebrity_alias(db: Session, celebrity_id: int, alias: schemas.CelebrityAliasCreate):
|
||||
db_alias = models.CelebrityAlias(celebrity_id=celebrity_id, alias_name=alias.alias_name)
|
||||
db.add(db_alias)
|
||||
db.commit()
|
||||
db.refresh(db_alias)
|
||||
return db_alias
|
||||
|
||||
def delete_celebrity_alias(db: Session, alias_id: int):
|
||||
db_alias = db.query(models.CelebrityAlias).filter(models.CelebrityAlias.id == alias_id).first()
|
||||
if not db_alias:
|
||||
return None
|
||||
db.delete(db_alias)
|
||||
db.commit()
|
||||
return db_alias
|
||||
|
||||
# --- Funzioni CRUD per le Immagini ---
|
||||
|
||||
def get_image(db: Session, image_id: int):
|
||||
|
||||
Binary file not shown.
@@ -1,8 +1,9 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, File, UploadFile
|
||||
from fastapi import APIRouter, Depends, HTTPException, File, UploadFile, Response
|
||||
from sqlalchemy.orm import Session
|
||||
from typing import List
|
||||
from typing import List, Optional
|
||||
import uuid
|
||||
import shutil
|
||||
import httpx
|
||||
|
||||
from .. import crud, models, schemas
|
||||
from ..database import get_db
|
||||
@@ -15,12 +16,12 @@ router = APIRouter(
|
||||
|
||||
@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à
|
||||
# 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)
|
||||
def read_celebrities(skip: int = 0, limit: int = 100, search: Optional[str] = None, db: Session = Depends(get_db)):
|
||||
celebrities = crud.get_celebrities(db, skip=skip, limit=limit, search=search)
|
||||
return celebrities
|
||||
|
||||
@router.get("/{celebrity_id}", response_model=schemas.Celebrity)
|
||||
@@ -44,7 +45,23 @@ def delete_celebrity(celebrity_id: int, db: Session = Depends(get_db)):
|
||||
raise HTTPException(status_code=404, detail="Celebrity not found")
|
||||
return db_celebrity
|
||||
|
||||
# --- NUOVI ENDPOINT PER LE IMMAGINI ---
|
||||
# --- NUOVI ENDPOINT PER GLI ALIAS ---
|
||||
|
||||
@router.post("/{celebrity_id}/aliases", response_model=schemas.CelebrityAlias, status_code=201)
|
||||
def add_alias_to_celebrity(celebrity_id: int, alias: schemas.CelebrityAliasCreate, 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 crud.create_celebrity_alias(db=db, celebrity_id=celebrity_id, alias=alias)
|
||||
|
||||
@router.delete("/aliases/{alias_id}", status_code=204)
|
||||
def delete_alias(alias_id: int, db: Session = Depends(get_db)):
|
||||
db_alias = crud.delete_celebrity_alias(db, alias_id=alias_id)
|
||||
if db_alias is None:
|
||||
raise HTTPException(status_code=404, detail="Alias not found")
|
||||
return Response(status_code=204)
|
||||
|
||||
# --- ENDPOINT PER LE IMMAGINI ---
|
||||
|
||||
@router.post("/{celebrity_id}/images", response_model=List[schemas.Image], status_code=201)
|
||||
def upload_celebrity_images(celebrity_id: int, files: List[UploadFile] = File(...), db: Session = Depends(get_db)):
|
||||
@@ -69,9 +86,6 @@ def upload_celebrity_images(celebrity_id: int, files: List[UploadFile] = File(..
|
||||
created_images.append(db_image)
|
||||
|
||||
except Exception as e:
|
||||
# Se un file fallisce, potremmo voler continuare con gli altri,
|
||||
# ma per ora lanciamo un'eccezione per l'intero batch.
|
||||
# In un'app di produzione, si potrebbe restituire una risposta parziale.
|
||||
print(f"Failed to upload file {file.filename}: {e}")
|
||||
raise HTTPException(status_code=500, detail=f"Could not upload file: {file.filename}")
|
||||
|
||||
@@ -89,7 +103,6 @@ async def add_image_from_url(celebrity_id: int, request: schemas.ImageUrlRequest
|
||||
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()
|
||||
|
||||
@@ -97,16 +110,13 @@ async def add_image_from_url(celebrity_id: int, request: schemas.ImageUrlRequest
|
||||
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'
|
||||
|
||||
@@ -130,8 +140,6 @@ def set_celebrity_profile_image(celebrity_id: int, request: schemas.SetProfileIm
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user