96 lines
3.1 KiB
Python
96 lines
3.1 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Literal
|
|
|
|
from app.database import Beatmap, Beatmapset, BeatmapsetResp, FavouriteBeatmapset, User
|
|
from app.dependencies.database import get_db
|
|
from app.dependencies.fetcher import get_fetcher
|
|
from app.dependencies.user import get_current_user
|
|
from app.fetcher import Fetcher
|
|
|
|
from .router import router
|
|
|
|
from fastapi import Depends, Form, HTTPException, Query, Security
|
|
from fastapi.responses import RedirectResponse
|
|
from httpx import HTTPError
|
|
from sqlmodel import select
|
|
from sqlmodel.ext.asyncio.session import AsyncSession
|
|
|
|
|
|
@router.get("/beatmapsets/lookup", tags=["beatmapset"], response_model=BeatmapsetResp)
|
|
async def lookup_beatmapset(
|
|
beatmap_id: int = Query(),
|
|
current_user: User = Security(get_current_user, scopes=["public"]),
|
|
db: AsyncSession = Depends(get_db),
|
|
fetcher: Fetcher = Depends(get_fetcher),
|
|
):
|
|
beatmap = await Beatmap.get_or_fetch(db, fetcher, bid=beatmap_id)
|
|
resp = await BeatmapsetResp.from_db(
|
|
beatmap.beatmapset, session=db, user=current_user
|
|
)
|
|
return resp
|
|
|
|
|
|
@router.get("/beatmapsets/{sid}", tags=["beatmapset"], response_model=BeatmapsetResp)
|
|
async def get_beatmapset(
|
|
sid: int,
|
|
current_user: User = Security(get_current_user, scopes=["public"]),
|
|
db: AsyncSession = Depends(get_db),
|
|
fetcher: Fetcher = Depends(get_fetcher),
|
|
):
|
|
try:
|
|
beatmapset = await Beatmapset.get_or_fetch(db, fetcher, sid)
|
|
return await BeatmapsetResp.from_db(
|
|
beatmapset, session=db, include=["recent_favourites"], user=current_user
|
|
)
|
|
except HTTPError:
|
|
raise HTTPException(status_code=404, detail="Beatmapset not found")
|
|
|
|
|
|
@router.get("/beatmapsets/{beatmapset}/download", tags=["beatmapset"])
|
|
async def download_beatmapset(
|
|
beatmapset: int,
|
|
no_video: bool = Query(True, alias="noVideo"),
|
|
current_user: User = Security(get_current_user, scopes=["*"]),
|
|
):
|
|
if current_user.country_code == "CN":
|
|
return RedirectResponse(
|
|
f"https://txy1.sayobot.cn/beatmaps/download/"
|
|
f"{'novideo' if no_video else 'full'}/{beatmapset}?server=auto"
|
|
)
|
|
else:
|
|
return RedirectResponse(
|
|
f"https://api.nerinyan.moe/d/{beatmapset}?noVideo={no_video}"
|
|
)
|
|
|
|
|
|
@router.post("/beatmapsets/{beatmapset}/favourites", tags=["beatmapset"])
|
|
async def favourite_beatmapset(
|
|
beatmapset: int,
|
|
action: Literal["favourite", "unfavourite"] = Form(),
|
|
current_user: User = Security(get_current_user, scopes=["*"]),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
existing_favourite = (
|
|
await db.exec(
|
|
select(FavouriteBeatmapset).where(
|
|
FavouriteBeatmapset.user_id == current_user.id,
|
|
FavouriteBeatmapset.beatmapset_id == beatmapset,
|
|
)
|
|
)
|
|
).first()
|
|
|
|
if (action == "favourite" and existing_favourite) or (
|
|
action == "unfavourite" and not existing_favourite
|
|
):
|
|
return
|
|
|
|
if action == "favourite":
|
|
favourite = FavouriteBeatmapset(
|
|
user_id=current_user.id, beatmapset_id=beatmapset
|
|
)
|
|
db.add(favourite)
|
|
else:
|
|
await db.delete(existing_favourite)
|
|
await db.commit()
|