238 lines
5.4 KiB
Python
238 lines
5.4 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
from enum import Enum
|
|
from typing import Optional
|
|
|
|
from pydantic import BaseModel
|
|
|
|
|
|
class GameMode(str, Enum):
|
|
OSU = "osu"
|
|
TAIKO = "taiko"
|
|
FRUITS = "fruits"
|
|
MANIA = "mania"
|
|
|
|
|
|
class PlayStyle(str, Enum):
|
|
MOUSE = "mouse"
|
|
KEYBOARD = "keyboard"
|
|
TABLET = "tablet"
|
|
TOUCH = "touch"
|
|
|
|
|
|
class Country(BaseModel):
|
|
code: str
|
|
name: str
|
|
|
|
|
|
class Cover(BaseModel):
|
|
custom_url: Optional[str] = None
|
|
url: str
|
|
id: Optional[int] = None
|
|
|
|
|
|
class Level(BaseModel):
|
|
current: int
|
|
progress: int
|
|
|
|
|
|
class GradeCounts(BaseModel):
|
|
ss: int = 0
|
|
ssh: int = 0
|
|
s: int = 0
|
|
sh: int = 0
|
|
a: int = 0
|
|
|
|
|
|
class Statistics(BaseModel):
|
|
count_100: int = 0
|
|
count_300: int = 0
|
|
count_50: int = 0
|
|
count_miss: int = 0
|
|
level: Level
|
|
global_rank: Optional[int] = None
|
|
global_rank_exp: Optional[int] = None
|
|
pp: float = 0.0
|
|
pp_exp: float = 0.0
|
|
ranked_score: int = 0
|
|
hit_accuracy: float = 0.0
|
|
play_count: int = 0
|
|
play_time: int = 0
|
|
total_score: int = 0
|
|
total_hits: int = 0
|
|
maximum_combo: int = 0
|
|
replays_watched_by_others: int = 0
|
|
is_ranked: bool = False
|
|
grade_counts: GradeCounts
|
|
country_rank: Optional[int] = None
|
|
rank: Optional[dict] = None
|
|
|
|
|
|
class Kudosu(BaseModel):
|
|
available: int = 0
|
|
total: int = 0
|
|
|
|
|
|
class MonthlyPlaycount(BaseModel):
|
|
start_date: str
|
|
count: int
|
|
|
|
|
|
class UserAchievement(BaseModel):
|
|
achieved_at: datetime
|
|
achievement_id: int
|
|
|
|
|
|
class RankHighest(BaseModel):
|
|
rank: int
|
|
updated_at: datetime
|
|
|
|
|
|
class RankHistory(BaseModel):
|
|
mode: str
|
|
data: list[int]
|
|
|
|
|
|
class DailyChallengeStats(BaseModel):
|
|
daily_streak_best: int = 0
|
|
daily_streak_current: int = 0
|
|
last_update: Optional[datetime] = None
|
|
last_weekly_streak: Optional[datetime] = None
|
|
playcount: int = 0
|
|
top_10p_placements: int = 0
|
|
top_50p_placements: int = 0
|
|
user_id: int
|
|
weekly_streak_best: int = 0
|
|
weekly_streak_current: int = 0
|
|
|
|
|
|
class Team(BaseModel):
|
|
flag_url: str
|
|
id: int
|
|
name: str
|
|
short_name: str
|
|
|
|
|
|
class Page(BaseModel):
|
|
html: str = ""
|
|
raw: str = ""
|
|
|
|
|
|
class User(BaseModel):
|
|
# 基本信息
|
|
id: int
|
|
username: str
|
|
avatar_url: str
|
|
country_code: str
|
|
default_group: str = "default"
|
|
is_active: bool = True
|
|
is_bot: bool = False
|
|
is_deleted: bool = False
|
|
is_online: bool = True
|
|
is_supporter: bool = False
|
|
is_restricted: bool = False
|
|
last_visit: Optional[datetime] = None
|
|
pm_friends_only: bool = False
|
|
profile_colour: Optional[str] = None
|
|
|
|
# 个人资料
|
|
cover_url: Optional[str] = None
|
|
discord: Optional[str] = None
|
|
has_supported: bool = False
|
|
interests: Optional[str] = None
|
|
join_date: datetime
|
|
location: Optional[str] = None
|
|
max_blocks: int = 100
|
|
max_friends: int = 500
|
|
occupation: Optional[str] = None
|
|
playmode: GameMode = GameMode.OSU
|
|
playstyle: list[PlayStyle] = []
|
|
post_count: int = 0
|
|
profile_hue: Optional[int] = None
|
|
profile_order: list[str] = [
|
|
"me",
|
|
"recent_activity",
|
|
"top_ranks",
|
|
"medals",
|
|
"historical",
|
|
"beatmaps",
|
|
"kudosu",
|
|
]
|
|
title: Optional[str] = None
|
|
title_url: Optional[str] = None
|
|
twitter: Optional[str] = None
|
|
website: Optional[str] = None
|
|
session_verified: bool = False
|
|
support_level: int = 0
|
|
|
|
# 关联对象
|
|
country: Country
|
|
cover: Cover
|
|
kudosu: Kudosu
|
|
statistics: Statistics
|
|
statistics_rulesets: dict[str, Statistics]
|
|
|
|
# 计数信息
|
|
beatmap_playcounts_count: int = 0
|
|
comments_count: int = 0
|
|
favourite_beatmapset_count: int = 0
|
|
follower_count: int = 0
|
|
graveyard_beatmapset_count: int = 0
|
|
guest_beatmapset_count: int = 0
|
|
loved_beatmapset_count: int = 0
|
|
mapping_follower_count: int = 0
|
|
nominated_beatmapset_count: int = 0
|
|
pending_beatmapset_count: int = 0
|
|
ranked_beatmapset_count: int = 0
|
|
ranked_and_approved_beatmapset_count: int = 0
|
|
unranked_beatmapset_count: int = 0
|
|
scores_best_count: int = 0
|
|
scores_first_count: int = 0
|
|
scores_pinned_count: int = 0
|
|
scores_recent_count: int = 0
|
|
|
|
# 历史数据
|
|
account_history: list[dict] = []
|
|
active_tournament_banner: Optional[dict] = None
|
|
active_tournament_banners: list[dict] = []
|
|
badges: list[dict] = []
|
|
current_season_stats: Optional[dict] = None
|
|
daily_challenge_user_stats: Optional[DailyChallengeStats] = None
|
|
groups: list[dict] = []
|
|
monthly_playcounts: list[MonthlyPlaycount] = []
|
|
page: Page = Page()
|
|
previous_usernames: list[str] = []
|
|
rank_highest: Optional[RankHighest] = None
|
|
rank_history: Optional[RankHistory] = None
|
|
rankHistory: Optional[RankHistory] = None # 兼容性别名
|
|
replays_watched_counts: list[dict] = []
|
|
team: Optional[Team] = None
|
|
user_achievements: list[UserAchievement] = []
|
|
|
|
|
|
# OAuth 相关模型
|
|
class TokenRequest(BaseModel):
|
|
grant_type: str
|
|
username: Optional[str] = None
|
|
password: Optional[str] = None
|
|
refresh_token: Optional[str] = None
|
|
client_id: str
|
|
client_secret: str
|
|
scope: str = "*"
|
|
|
|
|
|
class TokenResponse(BaseModel):
|
|
access_token: str
|
|
token_type: str = "Bearer"
|
|
expires_in: int
|
|
refresh_token: str
|
|
scope: str = "*"
|
|
|
|
|
|
class UserCreate(BaseModel):
|
|
username: str
|
|
password: str
|
|
email: str
|
|
country_code: str = "CN"
|