mirror of
https://github.com/A-Minos/nonebot-plugin-tetris-stats.git
synced 2026-03-05 05:36:54 +08:00
115 lines
4.4 KiB
Python
115 lines
4.4 KiB
Python
from typing import overload
|
|
|
|
from nonebot.compat import type_validate_json
|
|
|
|
from ....db import anti_duplicate_add
|
|
from ....utils.exception import RequestError
|
|
from ....utils.request import splice_url
|
|
from ..constant import BASE_URL, USER_ID, USER_NAME
|
|
from .cache import Cache
|
|
from .models import TETRIOHistoricalData
|
|
from .schemas.base import FailedModel
|
|
from .schemas.user import User
|
|
from .schemas.user_info import UserInfo, UserInfoSuccess
|
|
from .schemas.user_records import SoloModeRecord, UserRecords, UserRecordsSuccess, Zen
|
|
|
|
|
|
class Player:
|
|
@overload
|
|
def __init__(self, *, user_id: str, trust: bool = False): ...
|
|
@overload
|
|
def __init__(self, *, user_name: str, trust: bool = False): ...
|
|
def __init__(self, *, user_id: str | None = None, user_name: str | None = None, trust: bool = False):
|
|
self.user_id = user_id
|
|
self.user_name = user_name
|
|
if not trust:
|
|
if self.user_id is not None:
|
|
if not USER_ID.match(self.user_id):
|
|
msg = 'Invalid user id'
|
|
raise ValueError(msg)
|
|
elif self.user_name is not None:
|
|
if not USER_NAME.match(self.user_name):
|
|
msg = 'Invalid user name'
|
|
raise ValueError(msg)
|
|
else:
|
|
msg = 'Invalid user'
|
|
raise ValueError(msg)
|
|
self.__user: User | None = None
|
|
self._user_info: UserInfoSuccess | None = None
|
|
self._user_records: UserRecordsSuccess | None = None
|
|
|
|
@property
|
|
def _request_user_parameter(self) -> str:
|
|
if self.user_id is not None:
|
|
return self.user_id
|
|
if self.user_name is not None:
|
|
return self.user_name.lower()
|
|
msg = 'Invalid user'
|
|
raise ValueError(msg)
|
|
|
|
@property
|
|
async def user(self) -> User:
|
|
if self.__user is None:
|
|
user_info = await self.get_info()
|
|
self.__user = User(
|
|
ID=user_info.data.user.id,
|
|
name=user_info.data.user.username,
|
|
)
|
|
self.user_id = user_info.data.user.id
|
|
self.user_name = user_info.data.user.username
|
|
return self.__user
|
|
|
|
async def get_info(self) -> UserInfoSuccess:
|
|
"""Get User Info"""
|
|
if self._user_info is None:
|
|
raw_user_info = await Cache.get(splice_url([BASE_URL, 'users/', f'{self._request_user_parameter}']))
|
|
user_info: UserInfo = type_validate_json(UserInfo, raw_user_info) # type: ignore[arg-type]
|
|
if isinstance(user_info, FailedModel):
|
|
msg = f'用户信息请求错误:\n{user_info.error}'
|
|
raise RequestError(msg)
|
|
self._user_info = user_info
|
|
await anti_duplicate_add(
|
|
TETRIOHistoricalData,
|
|
TETRIOHistoricalData(
|
|
user_unique_identifier=(await self.user).unique_identifier,
|
|
api_type='User Info',
|
|
data=user_info,
|
|
update_time=user_info.cache.cached_at,
|
|
),
|
|
)
|
|
return self._user_info
|
|
|
|
async def get_records(self) -> UserRecordsSuccess:
|
|
"""Get User Records"""
|
|
if self._user_records is None:
|
|
raw_user_records = await Cache.get(
|
|
splice_url([BASE_URL, 'users/', f'{self._request_user_parameter}/', 'records'])
|
|
)
|
|
user_records: UserRecords = type_validate_json(UserRecords, raw_user_records) # type: ignore[arg-type]
|
|
if isinstance(user_records, FailedModel):
|
|
msg = f'用户Solo数据请求错误:\n{user_records.error}'
|
|
raise RequestError(msg)
|
|
self._user_records = user_records
|
|
await anti_duplicate_add(
|
|
TETRIOHistoricalData,
|
|
TETRIOHistoricalData(
|
|
user_unique_identifier=(await self.user).unique_identifier,
|
|
api_type='User Records',
|
|
data=user_records,
|
|
update_time=user_records.cache.cached_at,
|
|
),
|
|
)
|
|
return self._user_records
|
|
|
|
@property
|
|
async def sprint(self) -> SoloModeRecord:
|
|
return (await self.get_records()).data.records.sprint
|
|
|
|
@property
|
|
async def blitz(self) -> SoloModeRecord:
|
|
return (await self.get_records()).data.records.blitz
|
|
|
|
@property
|
|
async def zen(self) -> Zen:
|
|
return (await self.get_records()).data.zen
|