Files

174 lines
5.5 KiB
Python

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from sqlalchemy.orm import selectinload
from typing import List
from app.db.session import get_db
from app.models.models import Playlist, Music, playlist_music
from app.schemas.schemas import Playlist as PlaylistSchema, PlaylistCreate, PlaylistUpdate
router = APIRouter()
@router.get("/", response_model=List[PlaylistSchema])
async def get_playlists(db: AsyncSession = Depends(get_db)):
"""Get all playlists"""
result = await db.execute(
select(Playlist).options(selectinload(Playlist.music_items))
)
playlists = result.scalars().all()
return playlists
@router.post("/", response_model=PlaylistSchema)
async def create_playlist(
playlist: PlaylistCreate,
db: AsyncSession = Depends(get_db)
):
"""Create a new playlist"""
# Check if playlist with same name exists
result = await db.execute(
select(Playlist).where(Playlist.name == playlist.name)
)
existing = result.scalar_one_or_none()
if existing:
raise HTTPException(status_code=400, detail="Playlist already exists")
db_playlist = Playlist(**playlist.model_dump())
db.add(db_playlist)
await db.commit()
await db.refresh(db_playlist, ['music_items'])
return db_playlist
@router.get("/{playlist_id}", response_model=PlaylistSchema)
async def get_playlist(playlist_id: int, db: AsyncSession = Depends(get_db)):
"""Get a specific playlist with all its music"""
result = await db.execute(
select(Playlist).options(selectinload(Playlist.music_items)).where(Playlist.id == playlist_id)
)
playlist = result.scalar_one_or_none()
if not playlist:
raise HTTPException(status_code=404, detail="Playlist not found")
return playlist
@router.put("/{playlist_id}", response_model=PlaylistSchema)
async def update_playlist(
playlist_id: int,
playlist_update: PlaylistUpdate,
db: AsyncSession = Depends(get_db)
):
"""Update playlist details"""
result = await db.execute(
select(Playlist).options(selectinload(Playlist.music_items)).where(Playlist.id == playlist_id)
)
playlist = result.scalar_one_or_none()
if not playlist:
raise HTTPException(status_code=404, detail="Playlist not found")
for field, value in playlist_update.model_dump(exclude_unset=True).items():
setattr(playlist, field, value)
await db.commit()
await db.refresh(playlist, ['music_items'])
return playlist
@router.delete("/{playlist_id}")
async def delete_playlist(playlist_id: int, db: AsyncSession = Depends(get_db)):
"""Delete a playlist"""
result = await db.execute(
select(Playlist).where(Playlist.id == playlist_id)
)
playlist = result.scalar_one_or_none()
if not playlist:
raise HTTPException(status_code=404, detail="Playlist not found")
await db.delete(playlist)
await db.commit()
return {"message": "Playlist deleted successfully"}
@router.post("/{playlist_id}/music/{music_id}")
async def add_music_to_playlist(
playlist_id: int,
music_id: int,
db: AsyncSession = Depends(get_db)
):
"""Add music to playlist"""
# Get playlist with music_items loaded
result = await db.execute(
select(Playlist).options(selectinload(Playlist.music_items)).where(Playlist.id == playlist_id)
)
playlist = result.scalar_one_or_none()
if not playlist:
raise HTTPException(status_code=404, detail="Playlist not found")
# Get music
result = await db.execute(
select(Music).where(Music.id == music_id)
)
music = result.scalar_one_or_none()
if not music:
raise HTTPException(status_code=404, detail="Music not found")
# Check if already in playlist
if music in playlist.music_items:
raise HTTPException(status_code=400, detail="Music already in playlist")
# Add to playlist
playlist.music_items.append(music)
await db.commit()
return {"message": "Music added to playlist"}
@router.delete("/{playlist_id}/music/{music_id}")
async def remove_music_from_playlist(
playlist_id: int,
music_id: int,
db: AsyncSession = Depends(get_db)
):
"""Remove music from playlist"""
# Get playlist with music_items loaded
result = await db.execute(
select(Playlist).options(selectinload(Playlist.music_items)).where(Playlist.id == playlist_id)
)
playlist = result.scalar_one_or_none()
if not playlist:
raise HTTPException(status_code=404, detail="Playlist not found")
# Get music
result = await db.execute(
select(Music).where(Music.id == music_id)
)
music = result.scalar_one_or_none()
if not music:
raise HTTPException(status_code=404, detail="Music not found")
# Remove from playlist
if music in playlist.music_items:
playlist.music_items.remove(music)
await db.commit()
return {"message": "Music removed from playlist"}
else:
raise HTTPException(status_code=404, detail="Music not in playlist")
@router.get("/name/{playlist_name}", response_model=PlaylistSchema)
async def get_playlist_by_name(
playlist_name: str,
db: AsyncSession = Depends(get_db)
):
"""Get playlist by name"""
result = await db.execute(
select(Playlist).options(selectinload(Playlist.music_items)).where(Playlist.name == playlist_name)
)
playlist = result.scalar_one_or_none()
if not playlist:
raise HTTPException(status_code=404, detail="Playlist not found")
return playlist