mirror of
https://github.com/A-Minos/nonebot-plugin-tetris-stats.git
synced 2026-03-05 05:36:54 +08:00
✨ TETR.IO 添加 list 命令
This commit is contained in:
@@ -82,6 +82,14 @@ command.add(
|
||||
),
|
||||
),
|
||||
),
|
||||
Subcommand(
|
||||
'list',
|
||||
Option('--max-tr', Arg('max_tr', float), help_text='TR的上限'),
|
||||
Option('--min-tr', Arg('min_tr', float), help_text='TR的下限'),
|
||||
Option('--limit', Arg('limit', int), help_text='查询数量'),
|
||||
Option('--country', Arg('country', str), help_text='国家代码'),
|
||||
help_text='查询 TETR.IO 段位排行榜',
|
||||
),
|
||||
Subcommand(
|
||||
'rank',
|
||||
Args(Arg('rank', ValidRank, notice='TETR.IO 段位')),
|
||||
@@ -155,11 +163,12 @@ alc.shortcut(
|
||||
|
||||
add_block_handlers(alc.assign('TETRIO.query'))
|
||||
|
||||
from . import bind, config, query, rank, record # noqa: E402
|
||||
from . import bind, config, list, query, rank, record # noqa: E402
|
||||
|
||||
__all__ = [
|
||||
'bind',
|
||||
'config',
|
||||
'list',
|
||||
'query',
|
||||
'rank',
|
||||
'record',
|
||||
|
||||
@@ -10,7 +10,7 @@ class _User(BaseModel):
|
||||
username: str
|
||||
role: str
|
||||
xp: float
|
||||
supporter: bool
|
||||
supporter: bool | None = None
|
||||
verified: bool
|
||||
country: str | None = None
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from typing import Literal, NamedTuple, overload
|
||||
from typing import Literal, NamedTuple, TypedDict, overload
|
||||
from urllib.parse import urlencode
|
||||
|
||||
from nonebot.compat import type_validate_json
|
||||
|
||||
@@ -10,6 +11,24 @@ from .schemas.base import FailedModel
|
||||
from .schemas.tetra_league import TetraLeague, TetraLeagueSuccess
|
||||
|
||||
|
||||
class Parameter(TypedDict, total=False):
|
||||
after: float
|
||||
before: float
|
||||
limit: int
|
||||
country: str
|
||||
|
||||
|
||||
async def leaderboard(parameter: Parameter | None = None) -> TetraLeagueSuccess:
|
||||
league: TetraLeague = type_validate_json(
|
||||
TetraLeague, # type: ignore[arg-type]
|
||||
(await Cache.get(splice_url([BASE_URL, 'users/lists/league', f'?{urlencode(parameter or {})}']))),
|
||||
)
|
||||
if isinstance(league, FailedModel):
|
||||
msg = f'排行榜数据请求错误:\n{league.error}'
|
||||
raise RequestError(msg)
|
||||
return league
|
||||
|
||||
|
||||
class FullExport(NamedTuple):
|
||||
model: TetraLeagueSuccess
|
||||
original: bytes
|
||||
|
||||
74
nonebot_plugin_tetris_stats/games/tetrio/list.py
Normal file
74
nonebot_plugin_tetris_stats/games/tetrio/list.py
Normal file
@@ -0,0 +1,74 @@
|
||||
from nonebot_plugin_alconna.uniseg import UniMessage
|
||||
from nonebot_plugin_session import EventSession # type: ignore[import-untyped]
|
||||
from nonebot_plugin_session_orm import get_session_persist_id # type: ignore[import-untyped]
|
||||
|
||||
from ...db import trigger
|
||||
from ...utils.host import HostPage, get_self_netloc
|
||||
from ...utils.metrics import get_metrics
|
||||
from ...utils.render import render
|
||||
from ...utils.render.schemas.tetrio.tetrio_user_list_v2 import List, TetraLeague, User
|
||||
from ...utils.screenshot import screenshot
|
||||
from .. import alc
|
||||
from .api.schemas.tetra_league import ValidLeague
|
||||
from .api.tetra_league import Parameter, leaderboard
|
||||
from .constant import GAME_TYPE
|
||||
|
||||
|
||||
@alc.assign('TETRIO.list')
|
||||
async def _(
|
||||
event_session: EventSession,
|
||||
max_tr: float | None = None,
|
||||
min_tr: float | None = None,
|
||||
limit: int | None = None,
|
||||
country: str | None = None,
|
||||
):
|
||||
async with trigger(
|
||||
session_persist_id=await get_session_persist_id(event_session),
|
||||
game_platform=GAME_TYPE,
|
||||
command_type='list',
|
||||
command_args=[],
|
||||
):
|
||||
parameter: Parameter = {}
|
||||
if max_tr is not None:
|
||||
parameter['after'] = max_tr
|
||||
if min_tr is not None:
|
||||
parameter['before'] = min_tr
|
||||
if limit is not None:
|
||||
parameter['limit'] = limit
|
||||
if country is not None:
|
||||
parameter['country'] = country
|
||||
league = await leaderboard(parameter)
|
||||
async with HostPage(
|
||||
await render(
|
||||
'v2/tetrio/user/list',
|
||||
List(
|
||||
show_index=True,
|
||||
users=[
|
||||
User(
|
||||
id=i.id,
|
||||
name=i.username.upper(),
|
||||
avatar=f'https://tetr.io/user-content/avatars/{i.id}.jpg',
|
||||
country=i.country,
|
||||
verified=i.verified,
|
||||
tetra_league=TetraLeague(
|
||||
rank=i.league.rank,
|
||||
tr=round(i.league.rating, 2),
|
||||
glicko=round(i.league.glicko, 2),
|
||||
rd=round(i.league.rd, 2),
|
||||
decaying=i.league.decaying,
|
||||
pps=(metrics := get_metrics(pps=i.league.pps, apm=i.league.apm, vs=i.league.vs)).pps,
|
||||
apm=metrics.apm,
|
||||
apl=metrics.apl,
|
||||
vs=metrics.vs,
|
||||
adpl=metrics.adpl,
|
||||
),
|
||||
xp=i.xp,
|
||||
join_at=None,
|
||||
)
|
||||
for i in league.data.users
|
||||
if isinstance(i.league, ValidLeague)
|
||||
],
|
||||
),
|
||||
)
|
||||
) as page_hash:
|
||||
await UniMessage.image(raw=await screenshot(f'http://{get_self_netloc()}/host/{page_hash}.html')).finish()
|
||||
Reference in New Issue
Block a user