227 lines
6.3 KiB
Python

from typing import Any, List, Optional
from fastapi import APIRouter, Depends, HTTPException, status, Query
from sqlalchemy.orm import Session
from app.api.deps import get_db, get_current_active_user
from app.models.user import User
from app.schemas.playlist import (
Playlist,
PlaylistCreate,
PlaylistUpdate,
PlaylistWithSongs,
PlaylistSongAdd,
PlaylistSongRemove
)
from app.services.playlist import (
create_playlist,
delete_playlist,
get_playlist,
get_playlists_by_user,
get_public_playlists,
update_playlist,
add_song_to_playlist,
remove_song_from_playlist
)
from app.services.song import get_song
router = APIRouter()
@router.get("/", response_model=List[Playlist])
def read_playlists(
db: Session = Depends(get_db),
skip: int = 0,
limit: int = 100,
search: Optional[str] = Query(None, description="Search by playlist name"),
current_user: User = Depends(get_current_active_user),
) -> Any:
"""
Retrieve user's playlists.
"""
playlists = get_playlists_by_user(
db,
user_id=current_user.id,
skip=skip,
limit=limit,
search=search
)
return playlists
@router.get("/public", response_model=List[Playlist])
def read_public_playlists(
db: Session = Depends(get_db),
skip: int = 0,
limit: int = 100,
search: Optional[str] = Query(None, description="Search by playlist name"),
) -> Any:
"""
Retrieve public playlists.
"""
playlists = get_public_playlists(db, skip=skip, limit=limit, search=search)
return playlists
@router.post("/", response_model=Playlist)
def create_new_playlist(
*,
db: Session = Depends(get_db),
playlist_in: PlaylistCreate,
current_user: User = Depends(get_current_active_user),
) -> Any:
"""
Create new playlist.
"""
playlist = create_playlist(db, obj_in=playlist_in, user_id=current_user.id)
return playlist
@router.get("/{playlist_id}", response_model=PlaylistWithSongs)
def read_playlist(
*,
db: Session = Depends(get_db),
playlist_id: int,
current_user: Optional[User] = Depends(get_current_active_user),
) -> Any:
"""
Get playlist by ID with songs.
"""
playlist = get_playlist(db, playlist_id=playlist_id)
if not playlist:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Playlist not found",
)
# Check if user has access to the playlist
if not playlist.is_public and playlist.user_id != current_user.id:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Not enough permissions to access this playlist",
)
return playlist
@router.put("/{playlist_id}", response_model=Playlist)
def update_playlist_endpoint(
*,
db: Session = Depends(get_db),
playlist_id: int,
playlist_in: PlaylistUpdate,
current_user: User = Depends(get_current_active_user),
) -> Any:
"""
Update a playlist.
"""
playlist = get_playlist(db, playlist_id=playlist_id)
if not playlist:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Playlist not found",
)
# Check if user owns the playlist
if playlist.user_id != current_user.id:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Not enough permissions to modify this playlist",
)
playlist = update_playlist(db, db_obj=playlist, obj_in=playlist_in)
return playlist
@router.delete("/{playlist_id}", status_code=status.HTTP_204_NO_CONTENT, response_model=None)
def delete_playlist_endpoint(
*,
db: Session = Depends(get_db),
playlist_id: int,
current_user: User = Depends(get_current_active_user),
) -> Any:
"""
Delete a playlist.
"""
playlist = get_playlist(db, playlist_id=playlist_id)
if not playlist:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Playlist not found",
)
# Check if user owns the playlist
if playlist.user_id != current_user.id:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Not enough permissions to delete this playlist",
)
delete_playlist(db, id=playlist_id)
return None
@router.post("/{playlist_id}/songs", response_model=PlaylistWithSongs)
def add_song_to_playlist_endpoint(
*,
db: Session = Depends(get_db),
playlist_id: int,
song_data: PlaylistSongAdd,
current_user: User = Depends(get_current_active_user),
) -> Any:
"""
Add a song to a playlist.
"""
playlist = get_playlist(db, playlist_id=playlist_id)
if not playlist:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Playlist not found",
)
# Check if user owns the playlist
if playlist.user_id != current_user.id:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Not enough permissions to modify this playlist",
)
# Check if song exists
song = get_song(db, song_id=song_data.song_id)
if not song:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Song not found",
)
playlist = add_song_to_playlist(db, playlist_id=playlist_id, song_id=song_data.song_id)
return playlist
@router.delete("/{playlist_id}/songs", response_model=PlaylistWithSongs)
def remove_song_from_playlist_endpoint(
*,
db: Session = Depends(get_db),
playlist_id: int,
song_data: PlaylistSongRemove,
current_user: User = Depends(get_current_active_user),
) -> Any:
"""
Remove a song from a playlist.
"""
playlist = get_playlist(db, playlist_id=playlist_id)
if not playlist:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Playlist not found",
)
# Check if user owns the playlist
if playlist.user_id != current_user.id:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Not enough permissions to modify this playlist",
)
playlist = remove_song_from_playlist(db, playlist_id=playlist_id, song_id=song_data.song_id)
return playlist