Add Bandcamp discovery via public API (no scraping) - browse new releases by genre tag

This commit is contained in:
root
2026-03-31 09:58:28 -05:00
parent be30a47bbb
commit 152f217675
7 changed files with 295 additions and 301 deletions

View File

@@ -1,58 +1,25 @@
from fastapi import APIRouter, Depends, HTTPException, Query
from pydantic import BaseModel
from fastapi import APIRouter, Depends, Query
from app.core.security import get_current_user
from app.models.user import User
from app.services.bandcamp import search_bandcamp, get_embed_data
from app.services.bandcamp import discover_by_tag, get_trending_tags
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]$"),
@router.get("/discover")
async def bandcamp_discover(
tags: str = Query(..., description="Comma-separated tags, e.g. 'indie-rock,shoegaze'"),
sort: str = Query("new", description="Sort: new, rec, or pop"),
page: int = Query(1),
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]
tag_list = [t.strip() for t in tags.split(",") if t.strip()]
if not tag_list:
return []
return await discover_by_tag(tag_list, sort=sort, page=page)
@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"),
)
@router.get("/tags")
async def bandcamp_tags(user: User = Depends(get_current_user)):
return await get_trending_tags()