|
from fastapi import ( |
|
APIRouter, |
|
Depends, |
|
HTTPException, |
|
UploadFile, |
|
status, |
|
Security, |
|
) |
|
from models.music import Song |
|
from db.supabase_service import get_supabase |
|
from typing import Annotated, List, Tuple |
|
from supabase import Client |
|
from utils.auth import get_id |
|
from fastapi.encoders import jsonable_encoder |
|
from utils.exceptions import BAD_REQUEST |
|
|
|
router = APIRouter(tags=["Song"], prefix="/song") |
|
|
|
|
|
|
|
@router.post("", description="Upload music file") |
|
async def upload_music( |
|
supabase: Annotated[Client, Depends(get_supabase)], |
|
id: Annotated[str, Security(get_id)], |
|
music: UploadFile, |
|
name: str | None = None, |
|
): |
|
if music.content_type != "audio/mpeg": |
|
raise HTTPException( |
|
status_code=status.HTTP_400_BAD_REQUEST, |
|
detail="Only mp3 file is accepted", |
|
) |
|
try: |
|
if not name: |
|
name = music.filename |
|
f = await music.read() |
|
supabase.storage.from_("songs").upload( |
|
path=music.filename, file=f, file_options={"content-type": "audio/mpeg"} |
|
) |
|
supabase.table("songs").insert( |
|
{"name": name, "name_in_storage": music.filename, "user_id": id} |
|
).execute() |
|
return {"detail": "Music uploaded"} |
|
except: |
|
raise BAD_REQUEST |
|
|
|
|
|
|
|
@router.get("/link", description="Get url of music file") |
|
async def get_link_to_music( |
|
supabase: Annotated[Client, Depends(get_supabase)], |
|
id: Annotated[str, Security(get_id)], |
|
name_in_storage: str, |
|
): |
|
try: |
|
res = supabase.storage.from_("songs").create_signed_url( |
|
path=name_in_storage, expires_in=3600 |
|
) |
|
return res |
|
except: |
|
raise BAD_REQUEST |
|
|
|
|
|
|
|
@router.get( |
|
"/search", description="Get list of all music", response_model=List[Song] |
|
) |
|
async def get_music( |
|
supabase: Annotated[Client, Depends(get_supabase)], |
|
id: Annotated[str, Security(get_id)], |
|
query: str | None = None, |
|
) -> List[Song]: |
|
try: |
|
if query: |
|
res = ( |
|
supabase.table("songs") |
|
.select("*") |
|
.ilike("name", f"%{query}%") |
|
.execute() |
|
.dict()["data"] |
|
) |
|
else: |
|
res = supabase.table("songs").select("*").execute().dict()["data"] |
|
return res |
|
except: |
|
raise BAD_REQUEST |
|
|
|
|
|
|
|
@router.delete("", description="Delete music") |
|
async def delete_music( |
|
supabase: Annotated[Client, Depends(get_supabase)], |
|
user_id: Annotated[str, Security(get_id)], |
|
song: Song, |
|
): |
|
try: |
|
if song.user_id != user_id: |
|
raise HTTPException( |
|
status_code=status.HTTP_400_BAD_REQUEST, |
|
detail="You are not the owner of this music", |
|
) |
|
supabase.storage.from_("songs").remove([song.name_in_storage]) |
|
supabase.table("songs").delete().eq("id", song.id).execute() |
|
return {"detail": "Music deleted"} |
|
except: |
|
raise |
|
|
|
|
|
|
|
@router.patch("/info", description="Change music info") |
|
async def change_music_info( |
|
supabase: Annotated[Client, Depends(get_supabase)], |
|
user_id: Annotated[str, Security(get_id)], |
|
song: Song, |
|
): |
|
try: |
|
if song.user_id != user_id: |
|
raise HTTPException( |
|
status_code=status.HTTP_400_BAD_REQUEST, |
|
detail="You are not the owner of this music", |
|
) |
|
supabase.table("songs").update( |
|
jsonable_encoder( |
|
song, exclude={"id", "user_id", "created_at", "name_in_storage"} |
|
) |
|
).eq("id", song.id).execute() |
|
return {"detail": "Music info updated"} |
|
except: |
|
raise BAD_REQUEST |
|
|