from __future__ import annotations from datetime import datetime from typing import Literal from app.database.lazer_user import User from app.database.statistics import UserStatistics, UserStatisticsResp from app.dependencies.database import Database from app.models.score import GameMode from .router import AllStrModel, router from fastapi import HTTPException, Query from sqlmodel import select class V1User(AllStrModel): user_id: int username: str join_date: datetime count300: int count100: int count50: int playcount: int ranked_score: int total_score: int pp_rank: int level: float pp_raw: float accuracy: float count_rank_ss: int count_rank_ssh: int count_rank_s: int count_rank_sh: int count_rank_a: int country: str total_seconds_played: int pp_country_rank: int events: list[dict] @classmethod async def from_db( cls, session: Database, db_user: User, ruleset: GameMode | None = None ) -> "V1User": ruleset = ruleset or db_user.playmode current_statistics: UserStatistics | None = None for i in await db_user.awaitable_attrs.statistics: if i.mode == ruleset: current_statistics = i break if current_statistics: statistics = await UserStatisticsResp.from_db( current_statistics, session, db_user.country_code ) else: statistics = None return cls( user_id=db_user.id, username=db_user.username, join_date=db_user.join_date, count300=statistics.count_300 if statistics else 0, count100=statistics.count_100 if statistics else 0, count50=statistics.count_50 if statistics else 0, playcount=statistics.play_count if statistics else 0, ranked_score=statistics.ranked_score if statistics else 0, total_score=statistics.total_score if statistics else 0, pp_rank=statistics.global_rank if statistics and statistics.global_rank else 0, level=current_statistics.level_current if current_statistics else 0, pp_raw=statistics.pp if statistics else 0.0, accuracy=statistics.hit_accuracy if statistics else 0, count_rank_ss=current_statistics.grade_ss if current_statistics else 0, count_rank_ssh=current_statistics.grade_ssh if current_statistics else 0, count_rank_s=current_statistics.grade_s if current_statistics else 0, count_rank_sh=current_statistics.grade_sh if current_statistics else 0, count_rank_a=current_statistics.grade_a if current_statistics else 0, country=db_user.country_code, total_seconds_played=statistics.play_time if statistics else 0, pp_country_rank=statistics.country_rank if statistics and statistics.country_rank else 0, events=[], # TODO ) @router.get( "/get_user", response_model=list[V1User], name="获取用户信息", description="获取指定用户的信息。", ) async def get_user( session: Database, user: str = Query(..., alias="u", description="用户"), ruleset_id: int | None = Query(None, alias="m", description="Ruleset ID", ge=0), type: Literal["string", "id"] | None = Query( None, description="用户类型:string 用户名称 / id 用户 ID" ), event_days: int = Query( default=1, ge=1, le=31, description="从现在起所有事件的最大天数" ), ): db_user = ( await session.exec( select(User).where( User.id == user if type == "id" or user.isdigit() else User.username == user, ) ) ).first() if not db_user: return [] try: return [ await V1User.from_db( session, db_user, GameMode.from_int_extra(ruleset_id) if ruleset_id else None, ) ] except KeyError: raise HTTPException(400, "Invalid request")