from typing import Any, List, Optional from fastapi import APIRouter, Depends, File, HTTPException, Query, UploadFile from sqlalchemy.orm import Session from app import crud, models, schemas from app.api import deps from app.core.config import settings from app.utils.file_storage import save_upload_file, validate_image_file router = APIRouter() @router.get("/", response_model=List[schemas.Album]) def read_albums( db: Session = Depends(deps.get_db), skip: int = 0, limit: int = 100, title: Optional[str] = Query(None, description="Filter albums by title"), artist_id: Optional[str] = Query(None, description="Filter albums by artist ID"), ) -> Any: """ Retrieve albums. """ if artist_id: albums = crud.album.get_by_artist(db, artist_id=artist_id, skip=skip, limit=limit) elif title: albums = crud.album.search_by_title(db, title=title, skip=skip, limit=limit) else: albums = crud.album.get_multi(db, skip=skip, limit=limit) return albums @router.post("/", response_model=schemas.Album) def create_album( *, db: Session = Depends(deps.get_db), album_in: schemas.AlbumCreate, current_user: models.User = Depends(deps.get_current_active_superuser), ) -> Any: """ Create new album. """ # Verify artist exists artist = crud.artist.get(db, id=album_in.artist_id) if not artist: raise HTTPException( status_code=404, detail="Artist not found", ) album = crud.album.create(db, obj_in=album_in) return album @router.post("/{album_id}/cover", response_model=schemas.Album) async def upload_album_cover( *, db: Session = Depends(deps.get_db), album_id: str, file: UploadFile = File(...), current_user: models.User = Depends(deps.get_current_active_superuser), ) -> Any: """ Upload a cover image for an album. """ album = crud.album.get(db, id=album_id) if not album: raise HTTPException( status_code=404, detail="Album not found", ) validate_image_file(file) # Save the album cover filename = save_upload_file( file, settings.ALBUM_COVERS_DIR, file_id=album_id, ) # Update the album's cover_image field album_in = schemas.AlbumUpdate(cover_image=filename) album = crud.album.update(db, db_obj=album, obj_in=album_in) return album @router.get("/{album_id}", response_model=schemas.Album) def read_album( *, db: Session = Depends(deps.get_db), album_id: str, ) -> Any: """ Get album by ID. """ album = crud.album.get(db, id=album_id) if not album: raise HTTPException( status_code=404, detail="Album not found", ) return album @router.put("/{album_id}", response_model=schemas.Album) def update_album( *, db: Session = Depends(deps.get_db), album_id: str, album_in: schemas.AlbumUpdate, current_user: models.User = Depends(deps.get_current_active_superuser), ) -> Any: """ Update an album. """ album = crud.album.get(db, id=album_id) if not album: raise HTTPException( status_code=404, detail="Album not found", ) # Verify artist exists if artist_id is provided if album_in.artist_id: artist = crud.artist.get(db, id=album_in.artist_id) if not artist: raise HTTPException( status_code=404, detail="Artist not found", ) album = crud.album.update(db, db_obj=album, obj_in=album_in) return album @router.delete("/{album_id}", response_model=schemas.Album) def delete_album( *, db: Session = Depends(deps.get_db), album_id: str, current_user: models.User = Depends(deps.get_current_active_superuser), ) -> Any: """ Delete an album. """ album = crud.album.get(db, id=album_id) if not album: raise HTTPException( status_code=404, detail="Album not found", ) album = crud.album.remove(db, id=album_id) return album