Compare commits

...

11 Commits
1.7.0 ... 1.7.2

Author SHA1 Message Date
9806050e33 🔖 1.7.2
Some checks failed
Code Coverage / Test (macos-latest, 3.10) (push) Has been cancelled
Code Coverage / Test (macos-latest, 3.11) (push) Has been cancelled
Code Coverage / Test (macos-latest, 3.12) (push) Has been cancelled
Code Coverage / Test (ubuntu-latest, 3.10) (push) Has been cancelled
Code Coverage / Test (ubuntu-latest, 3.11) (push) Has been cancelled
Code Coverage / Test (ubuntu-latest, 3.12) (push) Has been cancelled
Code Coverage / Test (windows-latest, 3.10) (push) Has been cancelled
Code Coverage / Test (windows-latest, 3.11) (push) Has been cancelled
Code Coverage / Test (windows-latest, 3.12) (push) Has been cancelled
TypeCheck / TypeCheck (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Code Coverage / check (push) Has been cancelled
2025-03-20 03:35:19 +08:00
461327749f 🐛 修爆炸 2025-03-20 03:34:34 +08:00
renovate[bot]
208582d313 ⬆️ Upgrade dependency prettier to v3.5.3 (#533)
Some checks are pending
Code Coverage / Test (macos-latest, 3.10) (push) Waiting to run
Code Coverage / Test (macos-latest, 3.11) (push) Waiting to run
Code Coverage / Test (macos-latest, 3.12) (push) Waiting to run
Code Coverage / Test (ubuntu-latest, 3.10) (push) Waiting to run
Code Coverage / Test (ubuntu-latest, 3.11) (push) Waiting to run
Code Coverage / Test (ubuntu-latest, 3.12) (push) Waiting to run
Code Coverage / Test (windows-latest, 3.10) (push) Waiting to run
Code Coverage / Test (windows-latest, 3.11) (push) Waiting to run
Code Coverage / Test (windows-latest, 3.12) (push) Waiting to run
Code Coverage / check (push) Blocked by required conditions
TypeCheck / TypeCheck (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-19 06:13:30 +08:00
pre-commit-ci[bot]
90f655259d ⬆️ auto update by pre-commit hooks (#532)
* ⬆️ auto update by pre-commit hooks

updates:
- [github.com/astral-sh/ruff-pre-commit: v0.9.6 → v0.11.0](https://github.com/astral-sh/ruff-pre-commit/compare/v0.9.6...v0.11.0)

* 🚨 auto fix by pre-commit hooks

* 🚨 添加一个 noqa(

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: shoucandanghehe <wallfjjd@gmail.com>
2025-03-19 06:11:18 +08:00
renovate[bot]
2ef400ca28 ⬆️ Upgrade dependency prettier to v3.5.2 (#531)
Some checks failed
Code Coverage / Test (macos-latest, 3.10) (push) Has been cancelled
Code Coverage / Test (macos-latest, 3.11) (push) Has been cancelled
Code Coverage / Test (macos-latest, 3.12) (push) Has been cancelled
Code Coverage / Test (ubuntu-latest, 3.10) (push) Has been cancelled
Code Coverage / Test (ubuntu-latest, 3.11) (push) Has been cancelled
Code Coverage / Test (ubuntu-latest, 3.12) (push) Has been cancelled
Code Coverage / Test (windows-latest, 3.10) (push) Has been cancelled
Code Coverage / Test (windows-latest, 3.11) (push) Has been cancelled
Code Coverage / Test (windows-latest, 3.12) (push) Has been cancelled
TypeCheck / TypeCheck (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Code Coverage / check (push) Has been cancelled
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-25 02:02:57 +08:00
renovate[bot]
616a64bd6a ⬆️ Upgrade dependency prettier to v3.5.1 (#530)
Some checks failed
Code Coverage / Test (macos-latest, 3.10) (push) Has been cancelled
Code Coverage / Test (macos-latest, 3.11) (push) Has been cancelled
Code Coverage / Test (macos-latest, 3.12) (push) Has been cancelled
Code Coverage / Test (ubuntu-latest, 3.10) (push) Has been cancelled
Code Coverage / Test (ubuntu-latest, 3.11) (push) Has been cancelled
Code Coverage / Test (ubuntu-latest, 3.12) (push) Has been cancelled
Code Coverage / Test (windows-latest, 3.10) (push) Has been cancelled
Code Coverage / Test (windows-latest, 3.11) (push) Has been cancelled
Code Coverage / Test (windows-latest, 3.12) (push) Has been cancelled
TypeCheck / TypeCheck (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Code Coverage / check (push) Has been cancelled
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-14 02:40:56 +08:00
pre-commit-ci[bot]
bb8943d4c3 ⬆️ auto update by pre-commit hooks (#529)
Some checks failed
Code Coverage / Test (macos-latest, 3.10) (push) Waiting to run
Code Coverage / Test (macos-latest, 3.11) (push) Waiting to run
Code Coverage / Test (macos-latest, 3.12) (push) Waiting to run
Code Coverage / Test (ubuntu-latest, 3.10) (push) Waiting to run
Code Coverage / Test (ubuntu-latest, 3.11) (push) Waiting to run
Code Coverage / Test (ubuntu-latest, 3.12) (push) Waiting to run
Code Coverage / Test (windows-latest, 3.10) (push) Waiting to run
Code Coverage / Test (windows-latest, 3.11) (push) Waiting to run
Code Coverage / Test (windows-latest, 3.12) (push) Waiting to run
Code Coverage / check (push) Blocked by required conditions
TypeCheck / TypeCheck (push) Waiting to run
CodeQL / Analyze (python) (push) Has been cancelled
* ⬆️ auto update by pre-commit hooks

updates:
- [github.com/astral-sh/ruff-pre-commit: v0.8.3 → v0.9.6](https://github.com/astral-sh/ruff-pre-commit/compare/v0.8.3...v0.9.6)

* 🚨 auto fix by pre-commit hooks

* ♻️ 重命名 typing 为 typedefs

* ♻️ 使用 Annotated 代替默认值

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: shoucandanghehe <wallfjjd@gmail.com>
2025-02-13 04:18:36 +08:00
5e45db8cf5 🔖 1.7.1
Some checks failed
Code Coverage / Test (macos-latest, 3.10) (push) Has been cancelled
Code Coverage / Test (macos-latest, 3.11) (push) Has been cancelled
Code Coverage / Test (macos-latest, 3.12) (push) Has been cancelled
Code Coverage / Test (ubuntu-latest, 3.10) (push) Has been cancelled
Code Coverage / Test (ubuntu-latest, 3.11) (push) Has been cancelled
Code Coverage / Test (ubuntu-latest, 3.12) (push) Has been cancelled
Code Coverage / Test (windows-latest, 3.10) (push) Has been cancelled
Code Coverage / Test (windows-latest, 3.11) (push) Has been cancelled
Code Coverage / Test (windows-latest, 3.12) (push) Has been cancelled
TypeCheck / TypeCheck (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Code Coverage / check (push) Has been cancelled
2024-12-21 01:46:08 +08:00
renovate[bot]
2020deadac ⬆️ Upgrade astral-sh/setup-uv action to v5 (#527)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-20 17:43:24 +00:00
呵呵です
ce7bce6e20 🐛 修爆炸 (#528)
* 🐛 修爆炸

* 🐛 修复类型错误
2024-12-21 01:41:58 +08:00
pre-commit-ci[bot]
d4b690f682 ⬆️ auto update by pre-commit hooks (#524)
Some checks failed
Code Coverage / Test (macos-latest, 3.10) (push) Has been cancelled
Code Coverage / Test (macos-latest, 3.11) (push) Has been cancelled
Code Coverage / Test (macos-latest, 3.12) (push) Has been cancelled
Code Coverage / Test (ubuntu-latest, 3.10) (push) Has been cancelled
Code Coverage / Test (ubuntu-latest, 3.11) (push) Has been cancelled
Code Coverage / Test (ubuntu-latest, 3.12) (push) Has been cancelled
Code Coverage / Test (windows-latest, 3.10) (push) Has been cancelled
Code Coverage / Test (windows-latest, 3.11) (push) Has been cancelled
Code Coverage / Test (windows-latest, 3.12) (push) Has been cancelled
TypeCheck / TypeCheck (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Code Coverage / check (push) Has been cancelled
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.8.1 → v0.8.3](https://github.com/astral-sh/ruff-pre-commit/compare/v0.8.1...v0.8.3)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-12-18 21:28:36 +00:00
49 changed files with 89 additions and 69 deletions

View File

@@ -14,7 +14,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v4 - uses: astral-sh/setup-uv@v5
name: Setup UV name: Setup UV
with: with:
enable-cache: true enable-cache: true

View File

@@ -28,7 +28,7 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Setup uv - name: Setup uv
uses: astral-sh/setup-uv@v4 uses: astral-sh/setup-uv@v5
with: with:
enable-cache: true enable-cache: true
cache-suffix: ${{ env.PYTHON_VERSION }}_${{ env.OS }} cache-suffix: ${{ env.PYTHON_VERSION }}_${{ env.OS }}

View File

@@ -9,7 +9,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v4 - uses: astral-sh/setup-uv@v5
name: Setup UV name: Setup UV
with: with:
enable-cache: true enable-cache: true

View File

@@ -7,7 +7,7 @@ ci:
autoupdate_commit_msg: ':arrow_up: auto update by pre-commit hooks' autoupdate_commit_msg: ':arrow_up: auto update by pre-commit hooks'
repos: repos:
- repo: https://github.com/astral-sh/ruff-pre-commit - repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.8.1 rev: v0.11.0
hooks: hooks:
- id: ruff - id: ruff
args: [--fix, --exit-non-zero-on-fix] args: [--fix, --exit-non-zero-on-fix]

View File

@@ -11,7 +11,7 @@ from nonebot_plugin_orm import AsyncSession, get_session
from nonebot_plugin_user import User from nonebot_plugin_user import User
from sqlalchemy import select from sqlalchemy import select
from ..utils.typing import AllCommandType, BaseCommandType, GameType, TETRIOCommandType from ..utils.typedefs import AllCommandType, BaseCommandType, GameType, TETRIOCommandType
from .models import Bind, TriggerHistoricalData from .models import Bind, TriggerHistoricalData
UTC = timezone.utc UTC = timezone.utc

View File

@@ -9,7 +9,7 @@ from sqlalchemy import JSON, DateTime, Dialect, String, TypeDecorator
from sqlalchemy.orm import Mapped, MappedAsDataclass, mapped_column from sqlalchemy.orm import Mapped, MappedAsDataclass, mapped_column
from typing_extensions import override from typing_extensions import override
from ..utils.typing import AllCommandType, GameType from ..utils.typedefs import AllCommandType, GameType
class PydanticType(TypeDecorator): class PydanticType(TypeDecorator):

View File

@@ -3,7 +3,7 @@ from typing import Generic, TypeVar
from pydantic import BaseModel from pydantic import BaseModel
from ..utils.typing import GameType from ..utils.typedefs import GameType
T = TypeVar('T', bound=GameType) T = TypeVar('T', bound=GameType)

View File

@@ -7,7 +7,7 @@ from sqlalchemy.orm import Mapped, MappedAsDataclass, mapped_column
from ....db.models import PydanticType from ....db.models import PydanticType
from .schemas.base import SuccessModel from .schemas.base import SuccessModel
from .typing import Records, Summaries from .typedefs import Records, Summaries
class TETRIOHistoricalData(MappedAsDataclass, Model): class TETRIOHistoricalData(MappedAsDataclass, Model):

View File

@@ -27,7 +27,7 @@ from .schemas.summaries.base import User as SummariesUser
from .schemas.summaries.league import LeagueSuccessModel from .schemas.summaries.league import LeagueSuccessModel
from .schemas.user import User from .schemas.user import User
from .schemas.user_info import UserInfo, UserInfoSuccess from .schemas.user_info import UserInfo, UserInfoSuccess
from .typing import Records, Summaries from .typedefs import Records, Summaries
class RecordModeType(str, Enum): class RecordModeType(str, Enum):
@@ -46,7 +46,7 @@ class RecordKey(NamedTuple):
record_type: RecordType record_type: RecordType
def to_records(self) -> Records: def to_records(self) -> Records:
return cast(Records, f'{self.mode_type.value}_{self.record_type.value}') return cast('Records', f'{self.mode_type.value}_{self.record_type.value}')
class Player: class Player:
@@ -89,7 +89,7 @@ class Player:
@property @property
def _request_user_parameter(self) -> str: def _request_user_parameter(self) -> str:
return self.user_id or cast(str, self.user_name).lower() return self.user_id or cast('str', self.user_name).lower()
@property @property
async def user(self) -> User: async def user(self) -> User:

View File

@@ -3,7 +3,7 @@ from typing import Literal
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from ...typing import Prisecter from ...typedefs import Prisecter
class AggregateStats(BaseModel): class AggregateStats(BaseModel):

View File

@@ -3,7 +3,7 @@ from typing import Any
from nonebot.compat import PYDANTIC_V2 from nonebot.compat import PYDANTIC_V2
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from ...typing import Prisecter from ...typedefs import Prisecter
class Parameter(BaseModel): class Parameter(BaseModel):

View File

@@ -3,11 +3,11 @@ from typing import Literal
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from ...typing import Rank, ValidRank from ...typedefs import Rank, ValidRank
from ..base import ArCounts, FailedModel, P, SuccessModel from ..base import ArCounts, FailedModel, P, SuccessModel
class League(BaseModel): class BaseLeague(BaseModel):
gamesplayed: int gamesplayed: int
gameswon: int gameswon: int
tr: float tr: float
@@ -16,13 +16,22 @@ class League(BaseModel):
bestrank: ValidRank bestrank: ValidRank
glicko: float glicko: float
rd: float rd: float
apm: float
pps: float
vs: float
decaying: bool decaying: bool
class Entry(BaseModel): class InvalidLeague(BaseLeague):
pps: float | None
apm: None
vs: None
class League(BaseLeague):
pps: float
apm: float
vs: float
class BaseEntry(BaseModel):
id: str = Field(..., alias='_id') id: str = Field(..., alias='_id')
username: str username: str
role: Literal['anon', 'user', 'bot', 'halfmod', 'mod', 'admin', 'sysop'] role: Literal['anon', 'user', 'bot', 'halfmod', 'mod', 'admin', 'sysop']
@@ -30,7 +39,6 @@ class Entry(BaseModel):
xp: float xp: float
country: str | None = None country: str | None = None
supporter: bool | None = None supporter: bool | None = None
league: League
gamesplayed: int gamesplayed: int
gameswon: int gameswon: int
gametime: float gametime: float
@@ -39,8 +47,16 @@ class Entry(BaseModel):
p: P p: P
class InvalidEntry(BaseEntry):
league: InvalidLeague
class Entry(BaseEntry):
league: League
class Data(BaseModel): class Data(BaseModel):
entries: list[Entry] entries: list[Entry | InvalidEntry]
class BySuccessModel(SuccessModel): class BySuccessModel(SuccessModel):

View File

@@ -3,7 +3,7 @@ from typing import Literal
from nonebot.compat import PYDANTIC_V2 from nonebot.compat import PYDANTIC_V2
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from ...typing import Rank, S1Rank, S1ValidRank from ...typedefs import Rank, S1Rank, S1ValidRank
from ..base import SuccessModel from ..base import SuccessModel
if PYDANTIC_V2: if PYDANTIC_V2:

View File

@@ -11,7 +11,7 @@ from ...db import trigger
from . import alc, command from . import alc, command
from .constant import GAME_TYPE from .constant import GAME_TYPE
from .models import TETRIOUserConfig from .models import TETRIOUserConfig
from .typing import Template from .typedefs import Template
command.add( command.add(
Subcommand( Subcommand(

View File

@@ -3,7 +3,7 @@ from typing import Literal
from yarl import URL from yarl import URL
from .api.typing import ValidRank from .api.typedefs import ValidRank
GAME_TYPE: Literal['IO'] = 'IO' GAME_TYPE: Literal['IO'] = 'IO'

View File

@@ -14,6 +14,7 @@ from . import command
from .api.leaderboards import by from .api.leaderboards import by
from .api.schemas.base import P from .api.schemas.base import P
from .api.schemas.leaderboards import Parameter from .api.schemas.leaderboards import Parameter
from .api.schemas.leaderboards.by import Entry
from .constant import GAME_TYPE from .constant import GAME_TYPE
command.add( command.add(
@@ -84,6 +85,7 @@ async def _(
join_at=None, join_at=None,
) )
for i in league.data.entries for i in league.data.entries
if isinstance(i, Entry)
], ],
), ),
) )

View File

@@ -7,8 +7,8 @@ from sqlalchemy.orm import Mapped, MappedAsDataclass, mapped_column, relationshi
from ...db.models import PydanticType from ...db.models import PydanticType
from .api.schemas.leaderboards.by import BySuccessModel, Entry from .api.schemas.leaderboards.by import BySuccessModel, Entry
from .api.typing import ValidRank from .api.typedefs import ValidRank
from .typing import Template from .typedefs import Template
class TETRIOUserConfig(MappedAsDataclass, Model): class TETRIOUserConfig(MappedAsDataclass, Model):

View File

@@ -16,13 +16,13 @@ from sqlalchemy import select
from ....db import query_bind_info, trigger from ....db import query_bind_info, trigger
from ....i18n import Lang from ....i18n import Lang
from ....utils.exception import FallbackError from ....utils.exception import FallbackError
from ....utils.typing import Me from ....utils.typedefs import Me
from ... import add_block_handlers, alc from ... import add_block_handlers, alc
from .. import command, get_player from .. import command, get_player
from ..api import Player from ..api import Player
from ..constant import GAME_TYPE from ..constant import GAME_TYPE
from ..models import TETRIOUserConfig from ..models import TETRIOUserConfig
from ..typing import Template from ..typedefs import Template
from .v1 import make_query_image_v1 from .v1 import make_query_image_v1
from .v2 import make_query_image_v2 from .v2 import make_query_image_v2

View File

@@ -43,9 +43,9 @@ async def make_query_image_v2(player: Player) -> bytes:
play_time: str | None play_time: str | None
if (game_time := handling_special_value(user_info.data.gametime)) is not None: if (game_time := handling_special_value(user_info.data.gametime)) is not None:
if game_time // 3600 > 0: if game_time // 3600 > 0:
play_time = f'{game_time//3600:.0f}h {game_time % 3600 // 60:.0f}m {game_time % 60:.0f}s' play_time = f'{game_time // 3600:.0f}h {game_time % 3600 // 60:.0f}m {game_time % 60:.0f}s'
elif game_time // 60 > 0: elif game_time // 60 > 0:
play_time = f'{game_time//60:.0f}m {game_time % 60:.0f}s' play_time = f'{game_time // 60:.0f}m {game_time % 60:.0f}s'
else: else:
play_time = f'{game_time:.0f}s' play_time = f'{game_time:.0f}s'
else: else:

View File

@@ -25,7 +25,7 @@ from ..models import TETRIOLeagueHistorical, TETRIOLeagueStats, TETRIOLeagueStat
if TYPE_CHECKING: if TYPE_CHECKING:
from ..api.schemas.leaderboards.by import BySuccessModel from ..api.schemas.leaderboards.by import BySuccessModel
from ..api.typing import Rank from ..api.typedefs import Rank
UTC = timezone.utc UTC = timezone.utc
@@ -95,7 +95,7 @@ async def get_tetra_league_data() -> None:
players: list[Entry] = [] players: list[Entry] = []
for result in results: for result in results:
players.extend(result.data.entries) players.extend([i for i in result.data.entries if isinstance(i, Entry)])
players.sort(key=lambda x: x.league.tr, reverse=True) players.sort(key=lambda x: x.league.tr, reverse=True)
rank_player_mapping: defaultdict[Rank, list[Entry]] = defaultdict(list) rank_player_mapping: defaultdict[Rank, list[Entry]] = defaultdict(list)

View File

@@ -21,7 +21,7 @@ from ....utils.screenshot import screenshot
from .. import alc from .. import alc
from ..constant import GAME_TYPE from ..constant import GAME_TYPE
from ..models import TETRIOLeagueStats from ..models import TETRIOLeagueStats
from ..typing import Template from ..typedefs import Template
from . import command from . import command
command.add( command.add(

View File

@@ -17,7 +17,7 @@ from ....utils.render import render
from ....utils.render.schemas.tetrio.rank.detail import Data, SpecialData from ....utils.render.schemas.tetrio.rank.detail import Data, SpecialData
from ....utils.screenshot import screenshot from ....utils.screenshot import screenshot
from .. import alc from .. import alc
from ..api.typing import ValidRank from ..api.typedefs import ValidRank
from ..constant import GAME_TYPE from ..constant import GAME_TYPE
from ..models import TETRIOLeagueStats from ..models import TETRIOLeagueStats
from . import command from . import command

View File

@@ -1,7 +1,7 @@
from arclet.alconna import Arg, ArgFlag from arclet.alconna import Arg, ArgFlag
from nonebot_plugin_alconna import Args, At, Subcommand from nonebot_plugin_alconna import Args, At, Subcommand
from ....utils.typing import Me from ....utils.typedefs import Me
from .. import command as base_command from .. import command as base_command
from .. import get_player from .. import get_player

View File

@@ -22,7 +22,7 @@ from ....utils.render.schemas.base import Avatar
from ....utils.render.schemas.tetrio.record.base import Finesse, Max, Mini, Tspins, User from ....utils.render.schemas.tetrio.record.base import Finesse, Max, Mini, Tspins, User
from ....utils.render.schemas.tetrio.record.blitz import Record, Statistic from ....utils.render.schemas.tetrio.record.blitz import Record, Statistic
from ....utils.screenshot import screenshot from ....utils.screenshot import screenshot
from ....utils.typing import Me from ....utils.typedefs import Me
from .. import alc from .. import alc
from ..api.player import Player from ..api.player import Player
from ..constant import GAME_TYPE from ..constant import GAME_TYPE

View File

@@ -22,7 +22,7 @@ from ....utils.render.schemas.base import Avatar
from ....utils.render.schemas.tetrio.record.base import Finesse, Max, Mini, Statistic, Tspins, User from ....utils.render.schemas.tetrio.record.base import Finesse, Max, Mini, Statistic, Tspins, User
from ....utils.render.schemas.tetrio.record.sprint import Record from ....utils.render.schemas.tetrio.record.sprint import Record
from ....utils.screenshot import screenshot from ....utils.screenshot import screenshot
from ....utils.typing import Me from ....utils.typedefs import Me
from .. import alc from .. import alc
from ..api.player import Player from ..api.player import Player
from ..constant import GAME_TYPE from ..constant import GAME_TYPE

View File

@@ -2,7 +2,7 @@ from arclet.alconna import Arg, ArgFlag
from nonebot_plugin_alconna import Args, At, Subcommand from nonebot_plugin_alconna import Args, At, Subcommand
from ...utils.exception import MessageFormatError from ...utils.exception import MessageFormatError
from ...utils.typing import Me from ...utils.typedefs import Me
from .. import add_block_handlers, alc, command from .. import add_block_handlers, alc, command
from .api import Player from .api import Player
from .constant import USER_NAME from .constant import USER_NAME

View File

@@ -18,7 +18,7 @@ from ...utils.render.schemas.base import People
from ...utils.render.schemas.top_info import Data as InfoData from ...utils.render.schemas.top_info import Data as InfoData
from ...utils.render.schemas.top_info import Info from ...utils.render.schemas.top_info import Info
from ...utils.screenshot import screenshot from ...utils.screenshot import screenshot
from ...utils.typing import Me from ...utils.typedefs import Me
from . import alc from . import alc
from .api import Player from .api import Player
from .api.schemas.user_profile import Data, UserProfile from .api.schemas.user_profile import Data, UserProfile

View File

@@ -2,7 +2,7 @@ from arclet.alconna import Arg, ArgFlag
from nonebot_plugin_alconna import Args, At, Subcommand from nonebot_plugin_alconna import Args, At, Subcommand
from ...utils.exception import MessageFormatError from ...utils.exception import MessageFormatError
from ...utils.typing import Me from ...utils.typedefs import Me
from .. import add_block_handlers, alc, command from .. import add_block_handlers, alc, command
from .api import Player from .api import Player
from .constant import USER_NAME from .constant import USER_NAME

View File

@@ -64,7 +64,7 @@ class Player:
query = {'teaId': self.teaid} query = {'teaId': self.teaid}
else: else:
path = 'getUsernameInfo' path = 'getUsernameInfo'
query = {'username': cast(str, self.user_name)} query = {'username': cast('str', self.user_name)}
raw_user_info = await request.failover_request( raw_user_info = await request.failover_request(
[i / path % query for i in BASE_URL], failover_code=[502], failover_exc=(TimeoutException,) [i / path % query for i in BASE_URL], failover_code=[502], failover_exc=(TimeoutException,)
) )
@@ -91,7 +91,7 @@ class Player:
if self._user_profile.get(params) is None: if self._user_profile.get(params) is None:
raw_user_profile = await request.failover_request( raw_user_profile = await request.failover_request(
[ [
i / 'getProfile' % {'id': self.teaid or cast(str, self.user_name), **other_parameter} i / 'getProfile' % {'id': self.teaid or cast('str', self.user_name), **other_parameter}
for i in BASE_URL for i in BASE_URL
], ],
failover_code=[502], failover_code=[502],

View File

@@ -24,7 +24,7 @@ from ...utils.render.avatar import get_avatar as get_random_avatar
from ...utils.render.schemas.base import People, Ranking from ...utils.render.schemas.base import People, Ranking
from ...utils.render.schemas.tos_info import Info, Multiplayer, Radar from ...utils.render.schemas.tos_info import Info, Multiplayer, Radar
from ...utils.screenshot import screenshot from ...utils.screenshot import screenshot
from ...utils.typing import Me, Number from ...utils.typedefs import Me, Number
from . import alc from . import alc
from .api import Player from .api import Player
from .api.schemas.user_info import UserInfoSuccess from .api.schemas.user_info import UserInfoSuccess
@@ -258,7 +258,7 @@ def make_query_text(user_info: UserInfoSuccess, game_data: GameData | None) -> U
if user_data.ranked_games == '0': if user_data.ranked_games == '0':
message += '暂无段位统计数据' message += '暂无段位统计数据'
else: else:
message += f', 段位分 {round(float(user_data.rating_now),2)}±{round(float(user_data.rd_now),2)} ({round(float(user_data.vol_now),2)}) ' message += f', 段位分 {round(float(user_data.rating_now), 2)}±{round(float(user_data.rd_now), 2)} ({round(float(user_data.vol_now), 2)}) '
if game_data is None: if game_data is None:
message += ', 暂无游戏数据' message += ', 暂无游戏数据'
else: else:
@@ -266,7 +266,7 @@ def make_query_text(user_info: UserInfoSuccess, game_data: GameData | None) -> U
message += f"\nL'PM: {game_data.metrics.lpm} ( {game_data.metrics.pps} pps )" message += f"\nL'PM: {game_data.metrics.lpm} ( {game_data.metrics.pps} pps )"
message += f'\nAPM: {game_data.metrics.apm} ( x{game_data.metrics.apl} )' message += f'\nAPM: {game_data.metrics.apm} ( x{game_data.metrics.apl} )'
message += f'\nADPM: {game_data.metrics.adpm} ( x{game_data.metrics.adpl} ) ( {game_data.metrics.vs}vs )' message += f'\nADPM: {game_data.metrics.adpm} ( x{game_data.metrics.adpl} ) ( {game_data.metrics.vs}vs )'
message += f'\n40L: {float(user_data.pb_sprint)/1000:.2f}s' if user_data.pb_sprint != '2147483647' else '' message += f'\n40L: {float(user_data.pb_sprint) / 1000:.2f}s' if user_data.pb_sprint != '2147483647' else ''
message += f'\nMarathon: {user_data.pb_marathon}' if user_data.pb_marathon != '0' else '' message += f'\nMarathon: {user_data.pb_marathon}' if user_data.pb_marathon != '0' else ''
message += f'\nChallenge: {user_data.pb_challenge}' if user_data.pb_challenge != '0' else '' message += f'\nChallenge: {user_data.pb_challenge}' if user_data.pb_challenge != '0' else ''
return UniMessage(message) return UniMessage(message)

View File

@@ -2,7 +2,7 @@ from functools import cache
from hashlib import sha256 from hashlib import sha256
from ipaddress import IPv4Address, IPv6Address from ipaddress import IPv4Address, IPv6Address
from pathlib import Path as FilePath from pathlib import Path as FilePath
from typing import TYPE_CHECKING, ClassVar, Literal from typing import TYPE_CHECKING, Annotated, ClassVar, Literal
from aiofiles import open as aopen from aiofiles import open as aopen
from fastapi import BackgroundTasks, FastAPI, Path, status from fastapi import BackgroundTasks, FastAPI, Path, status
@@ -69,9 +69,9 @@ def _(page_hash: str) -> HTMLResponse:
@app.get('/host/resource/tetrio/{resource_type}/{user_id}', status_code=status.HTTP_200_OK) @app.get('/host/resource/tetrio/{resource_type}/{user_id}', status_code=status.HTTP_200_OK)
async def _( async def _(
resource_type: Literal['avatars', 'banners'], resource_type: Literal['avatars', 'banners'],
user_id: Annotated[str, Path(regex=r'^[a-f0-9]{24}$')],
revision: int, revision: int,
background_tasks: BackgroundTasks, background_tasks: BackgroundTasks,
user_id: str = Path(regex=r'^[a-f0-9]{24}$'),
) -> Response: ) -> Response:
if not (path := CACHE_PATH / 'tetrio' / resource_type / f'{user_id}_{revision}.png').exists(): if not (path := CACHE_PATH / 'tetrio' / resource_type / f'{user_id}_{revision}.png').exists():
image = img_to_png( image = img_to_png(

View File

@@ -23,7 +23,9 @@ def limit(limit: timedelta) -> Callable[[Callable[P, Coroutine[Any, Any, T]]], C
nonlocal last_call nonlocal last_call
async with lock: async with lock:
if (diff := (time() - last_call)) < limit_seconds: if (diff := (time() - last_call)) < limit_seconds:
logger.debug(f'func: {func.__name__} trigger limit, wait {(limit_time:=limit_seconds-diff):.3f}s') logger.debug(
f'func: {func.__name__} trigger limit, wait {(limit_time := limit_seconds - diff):.3f}s'
)
await sleep(limit_time) await sleep(limit_time)
last_call = time() last_call = time()
return await func(*args, **kwargs) return await func(*args, **kwargs)

View File

@@ -1,6 +1,6 @@
from typing import overload from typing import overload
from .typing import Number from .typedefs import Number
class TetrisMetricsBaseWithPPS: class TetrisMetricsBaseWithPPS:

View File

@@ -156,7 +156,7 @@ class SkinManager:
class Skin(ABC): class Skin(ABC):
def __new__(cls, *args: Any, **kwargs: Any) -> Self: # noqa: ANN401, ARG003 def __new__(cls, *args: Any, **kwargs: Any) -> Self: # noqa: ANN401, ARG004
instance = super().__new__(cls) instance = super().__new__(cls)
SkinManager.register(instance) SkinManager.register(instance)
return instance return instance

View File

@@ -2,7 +2,7 @@ from typing import Literal
from pydantic import BaseModel from pydantic import BaseModel
from ...typing import Number from ...typedefs import Number
class Avatar(BaseModel): class Avatar(BaseModel):

View File

@@ -2,7 +2,7 @@ from datetime import datetime
from pydantic import BaseModel from pydantic import BaseModel
from ......games.tetrio.api.typing import ValidRank from ......games.tetrio.api.typedefs import ValidRank
class SpecialData(BaseModel): class SpecialData(BaseModel):

View File

@@ -2,7 +2,7 @@ from datetime import datetime
from pydantic import BaseModel from pydantic import BaseModel
from ......games.tetrio.api.typing import ValidRank from ......games.tetrio.api.typedefs import ValidRank
class ItemData(BaseModel): class ItemData(BaseModel):

View File

@@ -2,7 +2,7 @@ from datetime import datetime
from pydantic import BaseModel from pydantic import BaseModel
from ......games.tetrio.api.typing import ValidRank from ......games.tetrio.api.typedefs import ValidRank
class AverageData(BaseModel): class AverageData(BaseModel):

View File

@@ -2,7 +2,7 @@ from datetime import datetime
from pydantic import BaseModel from pydantic import BaseModel
from .....typing import Number from .....typedefs import Number
class TetraLeagueHistoryData(BaseModel): class TetraLeagueHistoryData(BaseModel):

View File

@@ -1,7 +1,7 @@
from pydantic import BaseModel from pydantic import BaseModel
from ......games.tetrio.api.typing import Rank from ......games.tetrio.api.typedefs import Rank
from .....typing import Number from .....typedefs import Number
from ...base import People, Ranking from ...base import People, Ranking
from .base import TetraLeagueHistoryData from .base import TetraLeagueHistoryData

View File

@@ -3,8 +3,8 @@ from typing import Literal
from pydantic import BaseModel from pydantic import BaseModel
from ......games.tetrio.api.typing import Rank from ......games.tetrio.api.typedefs import Rank
from .....typing import Number from .....typedefs import Number
from ...base import Avatar from ...base import Avatar
from .base import TetraLeagueHistoryData from .base import TetraLeagueHistoryData

View File

@@ -2,8 +2,8 @@ from datetime import datetime
from pydantic import BaseModel from pydantic import BaseModel
from ......games.tetrio.api.typing import Rank from ......games.tetrio.api.typedefs import Rank
from .....typing import Number from .....typedefs import Number
from ...base import Avatar from ...base import Avatar

View File

@@ -1,6 +1,6 @@
from pydantic import BaseModel from pydantic import BaseModel
from ...typing import Number from ...typedefs import Number
from .base import People from .base import People

View File

@@ -1,6 +1,6 @@
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from ...typing import Number from ...typedefs import Number
from .base import People, Ranking from .base import People, Ranking

8
pnpm-lock.yaml generated
View File

@@ -10,15 +10,15 @@ importers:
devDependencies: devDependencies:
prettier: prettier:
specifier: ^3.3.3 specifier: ^3.3.3
version: 3.4.2 version: 3.5.3
packages: packages:
prettier@3.4.2: prettier@3.5.3:
resolution: {integrity: sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==} resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==}
engines: {node: '>=14'} engines: {node: '>=14'}
hasBin: true hasBin: true
snapshots: snapshots:
prettier@3.4.2: {} prettier@3.5.3: {}

View File

@@ -1,6 +1,6 @@
[project] [project]
name = "nonebot-plugin-tetris-stats" name = "nonebot-plugin-tetris-stats"
version = "1.7.0" version = "1.7.2"
description = "一款基于 NoneBot2 的用于查询 Tetris 相关游戏数据的插件" description = "一款基于 NoneBot2 的用于查询 Tetris 相关游戏数据的插件"
readme = "README.md" readme = "README.md"
authors = [{ name = "shoucandanghehe", email = "wallfjjd@gmail.com" }] authors = [{ name = "shoucandanghehe", email = "wallfjjd@gmail.com" }]
@@ -158,7 +158,7 @@ defineConstant = { PYDANTIC_V2 = true }
typeCheckingMode = "standard" typeCheckingMode = "standard"
[tool.bumpversion] [tool.bumpversion]
current_version = "1.7.0" current_version = "1.7.2"
tag = true tag = true
sign_tags = true sign_tags = true
tag_name = "{new_version}" tag_name = "{new_version}"