Add Bandcamp search and Listening Room page

Implement Bandcamp search service with autocomplete API and HTML
scraping fallback. Add /api/bandcamp/search and /api/bandcamp/embed
endpoints. Create Listening Room page with search, embedded player,
and queue management. Add navigation entry and Bandcamp link on
recommendation cards.
This commit is contained in:
root
2026-03-30 23:38:14 -05:00
parent 3303cd1507
commit dd4df6a070
8 changed files with 673 additions and 3 deletions

View File

@@ -0,0 +1,58 @@
from fastapi import APIRouter, Depends, HTTPException, Query
from pydantic import BaseModel
from app.core.security import get_current_user
from app.models.user import User
from app.services.bandcamp import search_bandcamp, get_embed_data
router = APIRouter(prefix="/bandcamp", tags=["bandcamp"])
class BandcampResult(BaseModel):
title: str
artist: str
art_url: str | None = None
bandcamp_url: str
item_type: str
class BandcampEmbedResponse(BaseModel):
embed_url: str
title: str
artist: str
art_url: str | None = None
@router.get("/search", response_model=list[BandcampResult])
async def bandcamp_search(
q: str = Query(..., min_length=1),
type: str = Query("t", pattern="^[tab]$"),
user: User = Depends(get_current_user),
):
"""Search Bandcamp for tracks, albums, or artists."""
results = await search_bandcamp(q.strip(), item_type=type)
return [BandcampResult(**r) for r in results]
@router.get("/embed", response_model=BandcampEmbedResponse)
async def bandcamp_embed(
url: str = Query(..., min_length=1),
user: User = Depends(get_current_user),
):
"""Get embed data for a Bandcamp URL."""
if "bandcamp.com" not in url:
raise HTTPException(status_code=400, detail="Not a valid Bandcamp URL")
data = await get_embed_data(url.strip())
if not data:
raise HTTPException(
status_code=404,
detail="Could not extract embed data from this Bandcamp page",
)
return BandcampEmbedResponse(
embed_url=data["embed_url"],
title=data["title"],
artist=data["artist"],
art_url=data.get("art_url"),
)