Compare commits

...

7 Commits
1.8.1 ... 1.8.3

Author SHA1 Message Date
0bc3b86820 🔖 1.8.3
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-05-08 00:00:12 +08:00
pre-commit-ci[bot]
57d0b15242 ⬆️ auto update by pre-commit hooks (#538)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.11.6 → v0.11.8](https://github.com/astral-sh/ruff-pre-commit/compare/v0.11.6...v0.11.8)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-05-07 15:52:35 +00:00
呵呵です
56fe45efcf 适配新成就模板 (#540)
*  完善Achievement模型

*  添加一些alias

*  更新模板 schemas

* 🐛 修复类型错误
2025-05-07 23:51:13 +08:00
13f005179f 添加 schema 注释到 pyproject.toml
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-04-28 04:13:05 +08:00
243a8a286d 🔖 1.8.2 2025-04-28 04:09:04 +08:00
8b7de6745b 添加 development 模式 2025-04-28 04:08:55 +08:00
d0fc82d88d 添加开发依赖 nonebot-plugin-tarina-lang-turbo 2025-04-28 04:06:48 +08:00
10 changed files with 163 additions and 31 deletions

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.11.6 rev: v0.11.8
hooks: hooks:
- id: ruff - id: ruff
args: [--fix, --exit-non-zero-on-fix] args: [--fix, --exit-non-zero-on-fix]

View File

@@ -18,6 +18,7 @@ class ScopedConfig(BaseModel):
request_timeout: float = 30.0 request_timeout: float = 30.0
screenshot_quality: float = 2 screenshot_quality: float = 2
proxy: Proxy = Field(default_factory=Proxy) proxy: Proxy = Field(default_factory=Proxy)
development: bool = False
class Config(BaseModel): class Config(BaseModel):

View File

@@ -1,25 +1,93 @@
from typing import TypeAlias from datetime import datetime
from enum import IntEnum
from typing import Literal, TypeAlias
from pydantic import BaseModel from pydantic import BaseModel, Field
from ..base import FailedModel, SuccessModel from ..base import FailedModel, SuccessModel
class RankType(IntEnum):
PERCENTILE = 1
ISSUE = 2
ZENITH = 3
PERCENTILELAX = 4
PERCENTILEVLAX = 5
PERCENTILEMLAX = 6
class ValueType(IntEnum):
NONE = 0
NUMBER = 1
TIME = 2
TIME_INV = 3
FLOOR = 4
ISSUE = 5
NUMBER_INV = 6
class ArType(IntEnum):
UNRANKED = 0
RANKED = 1
COMPETITIVE = 2
class Rank(IntEnum):
NONE = 0
BRONZE = 1
SILVER = 2
GOLD = 3
PLATINUM = 4
DIAMOND = 5
ISSUED = 100
class Ally(BaseModel):
id: str = Field(alias='_id')
username: str
role: Literal['anon', 'user', 'bot', 'halfmod', 'mod', 'admin', 'sysop', 'hidden', 'banned']
country: str | None = None
supporter: bool
avatar_revision: int | None = None
class X(BaseModel):
ally: Ally | None = None
class Achievement(BaseModel): class Achievement(BaseModel):
# 这**都是些啥 # 这**都是些啥
k: int achievement_id: int = Field(alias='k')
o: int category: str
rt: int primary_name: str = Field(alias='name')
vt: int objective: str = Field(alias='object')
flavor_text: str = Field(alias='desc')
order: int = Field(alias='o')
rank_type: RankType = Field(alias='rt')
value_type: ValueType = Field(alias='vt')
ar_type: ArType = Field(alias='art')
min: int min: int
deci: int deci: int
name: str
object: str
category: str
hidden: bool hidden: bool
desc: str nolb: bool
event: str | None = None
event_past: bool | None = None
disabled: bool | None = None
pair: bool | None = None
achieved_score: float | None = Field(None, alias='v')
a: float | None = None
t: datetime | None = None
pos: int | None = None
total: int | None = None
rank: Rank | None = None
x: X | None = None
n: str n: str
stub: bool
tiebreak: int
notifypb: bool
id: str | None = Field(None, alias='_id')
progress: float | None = None
stub: bool | None = None
class AchievementsSuccessModel(SuccessModel): class AchievementsSuccessModel(SuccessModel):

View File

@@ -11,6 +11,7 @@ from ....utils.metrics import get_metrics
from ....utils.render import render from ....utils.render import render
from ....utils.render.schemas.base import Avatar from ....utils.render.schemas.base import Avatar
from ....utils.render.schemas.v2.tetrio.user.info import ( from ....utils.render.schemas.v2.tetrio.user.info import (
Achievement,
Badge, Badge,
Best, Best,
Blitz, Blitz,
@@ -33,7 +34,7 @@ from .tools import flow_to_history, handling_special_value
async def make_query_image_v2(player: Player) -> bytes: async def make_query_image_v2(player: Player) -> bytes:
( (
(user, user_info, league, sprint, blitz, zen), (user, user_info, league, sprint, blitz, zen),
(avatar_revision, banner_revision, leagueflow, zenith, zenithex), (avatar_revision, banner_revision, leagueflow, zenith, zenithex, achievements),
) = await gather( ) = await gather(
gather( gather(
player.user, player.user,
@@ -49,6 +50,7 @@ async def make_query_image_v2(player: Player) -> bytes:
player.get_leagueflow(), player.get_leagueflow(),
player.get_summaries('zenith'), player.get_summaries('zenith'),
player.get_summaries('zenithex'), player.get_summaries('zenithex'),
player.get_summaries('achievements'),
), ),
) )
if sprint.data.record is not None: if sprint.data.record is not None:
@@ -110,7 +112,20 @@ async def make_query_image_v2(player: Player) -> bytes:
], ],
xp=user_info.data.xp, xp=user_info.data.xp,
ar=user_info.data.ar, ar=user_info.data.ar,
achievements=user_info.data.achievements, achievements=[
Achievement(
key=i.achievement_id,
rank_type=i.rank_type,
ar_type=i.ar_type,
stub=i.stub,
rank=i.rank,
achieved_score=i.achieved_score,
pos=i.pos,
progress=i.progress,
total=i.total,
)
for i in achievements.data
],
playtime=play_time, playtime=play_time,
join_at=user_info.data.ts, join_at=user_info.data.ts,
), ),

View File

@@ -12,6 +12,7 @@ from nonebot_plugin_apscheduler import scheduler
from nonebot_plugin_orm import get_session from nonebot_plugin_orm import get_session
from sqlalchemy import select from sqlalchemy import select
from ....config.config import config
from ....utils.exception import RequestError from ....utils.exception import RequestError
from ....utils.retry import retry from ....utils.retry import retry
from .. import alc from .. import alc
@@ -136,14 +137,16 @@ async def get_tetra_league_data() -> None:
await session.commit() await session.commit()
@driver.on_startup if not config.tetris.development:
async def _() -> None:
async with get_session() as session: @driver.on_startup
latest_time = await session.scalar( async def _() -> None:
select(TETRIOLeagueStats.update_time).order_by(TETRIOLeagueStats.id.desc()).limit(1) async with get_session() as session:
) latest_time = await session.scalar(
if latest_time is None or datetime.now(tz=UTC) - latest_time.replace(tzinfo=UTC) > timedelta(hours=6): select(TETRIOLeagueStats.update_time).order_by(TETRIOLeagueStats.id.desc()).limit(1)
await get_tetra_league_data() )
if latest_time is None or datetime.now(tz=UTC) - latest_time.replace(tzinfo=UTC) > timedelta(hours=6):
await get_tetra_league_data()
from . import all, detail # noqa: A004, E402 from . import all, detail # noqa: A004, E402

View File

@@ -10,6 +10,8 @@ from nonebot.log import logger
from playwright.__main__ import main from playwright.__main__ import main
from playwright.async_api import Browser, BrowserContext, async_playwright from playwright.async_api import Browser, BrowserContext, async_playwright
from ..config.config import config
driver = get_driver() driver = get_driver()
global_config = driver.config global_config = driver.config
@@ -76,6 +78,7 @@ class BrowserManager:
"""启动浏览器实例""" """启动浏览器实例"""
playwright = await async_playwright().start() playwright = await async_playwright().start()
cls._browser = await playwright.firefox.launch( cls._browser = await playwright.firefox.launch(
headless=not config.tetris.development,
firefox_user_prefs={ firefox_user_prefs={
'network.http.max-persistent-connections-per-server': 64, 'network.http.max-persistent-connections-per-server': 64,
}, },

View File

@@ -12,7 +12,7 @@ from nonebot import get_app, get_driver
from nonebot.log import logger from nonebot.log import logger
from yarl import URL from yarl import URL
from ..config.config import CACHE_PATH from ..config.config import CACHE_PATH, config
from ..games.tetrio.api.cache import request from ..games.tetrio.api.cache import request
from .image import img_to_png from .image import img_to_png
from .templates import TEMPLATES_DIR from .templates import TEMPLATES_DIR
@@ -45,8 +45,14 @@ class HostPage:
async def __aenter__(self) -> str: async def __aenter__(self) -> str:
return self.page_hash return self.page_hash
async def __aexit__(self, exc_type, exc, tb) -> None: # noqa: ANN001 if not config.tetris.development:
self.pages.pop(self.page_hash, None)
async def __aexit__(self, exc_type, exc, tb) -> None: # noqa: ANN001
self.pages.pop(self.page_hash, None)
else:
async def __aexit__(self, exc_type, exc, tb) -> None: # noqa: ANN001
pass
@driver.on_startup @driver.on_startup

View File

@@ -3,6 +3,8 @@ from typing import Literal
from pydantic import BaseModel from pydantic import BaseModel
from .......games.tetrio.api.schemas.summaries.achievements import ArType, RankType
from .......games.tetrio.api.schemas.summaries.achievements import Rank as AchievementRank
from .......games.tetrio.api.typedefs import Rank from .......games.tetrio.api.typedefs import Rank
from ......typedefs import Number from ......typedefs import Number
from ....base import Avatar, Base, HistoryData from ....base import Avatar, Base, HistoryData
@@ -15,6 +17,18 @@ class Badge(BaseModel):
receive_at: datetime | None receive_at: datetime | None
class Achievement(BaseModel):
key: int
rank_type: RankType
ar_type: ArType
stub: bool | None
rank: AchievementRank | None
achieved_score: float | None
pos: int | None
progress: float | None
total: int | None
class User(BaseModel): class User(BaseModel):
id: str id: str
name: str name: str
@@ -37,7 +51,7 @@ class User(BaseModel):
xp: Number xp: Number
ar: Number ar: Number
achievements: list[int] achievements: list[Achievement]
playtime: str | None playtime: str | None
join_at: datetime | None join_at: datetime | None

View File

@@ -1,6 +1,8 @@
#:schema https://json.schemastore.org/uv.json
[project] [project]
name = "nonebot-plugin-tetris-stats" name = "nonebot-plugin-tetris-stats"
version = "1.8.1" version = "1.8.3"
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" }]
@@ -58,6 +60,7 @@ dev = [
"nonebot-adapter-kaiheila>=0.3.4", "nonebot-adapter-kaiheila>=0.3.4",
"nonebot-adapter-onebot>=2.4.6", "nonebot-adapter-onebot>=2.4.6",
"nonebot-adapter-qq>=1.5.3", "nonebot-adapter-qq>=1.5.3",
"nonebot-plugin-tarina-lang-turbo>=0.1.1",
"ruff>=0.7.1", "ruff>=0.7.1",
] ]
typecheck = [ typecheck = [
@@ -159,7 +162,7 @@ defineConstant = { PYDANTIC_V2 = true }
typeCheckingMode = "standard" typeCheckingMode = "standard"
[tool.bumpversion] [tool.bumpversion]
current_version = "1.8.1" current_version = "1.8.3"
tag = true tag = true
sign_tags = true sign_tags = true
tag_name = "{new_version}" tag_name = "{new_version}"
@@ -176,4 +179,4 @@ asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "session" asyncio_default_fixture_loop_scope = "session"
[tool.nonebot] [tool.nonebot]
plugins = ["nonebot_plugin_tetris_stats"] plugins = ["nonebot_plugin_tetris_stats", "nonebot_plugin_tarina_lang_turbo"]

23
uv.lock generated
View File

@@ -1294,7 +1294,7 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/8c/de/8eb6fffecd9c5f129461edcdd7e1ac944f9de15783e3d89c84ed6e0374bc/lxml-5.3.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:aa837e6ee9534de8d63bc4c1249e83882a7ac22bd24523f83fad68e6ffdf41ae", size = 5652903 }, { url = "https://files.pythonhosted.org/packages/8c/de/8eb6fffecd9c5f129461edcdd7e1ac944f9de15783e3d89c84ed6e0374bc/lxml-5.3.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:aa837e6ee9534de8d63bc4c1249e83882a7ac22bd24523f83fad68e6ffdf41ae", size = 5652903 },
{ url = "https://files.pythonhosted.org/packages/95/79/80f4102a08495c100014593680f3f0f7bd7c1333b13520aed855fc993326/lxml-5.3.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:da4c9223319400b97a2acdfb10926b807e51b69eb7eb80aad4942c0516934858", size = 5491813 }, { url = "https://files.pythonhosted.org/packages/95/79/80f4102a08495c100014593680f3f0f7bd7c1333b13520aed855fc993326/lxml-5.3.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:da4c9223319400b97a2acdfb10926b807e51b69eb7eb80aad4942c0516934858", size = 5491813 },
{ url = "https://files.pythonhosted.org/packages/15/f5/9b1f7edf6565ee31e4300edb1bcc61eaebe50a3cff4053c0206d8dc772f2/lxml-5.3.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:dc0e9bdb3aa4d1de703a437576007d366b54f52c9897cae1a3716bb44fc1fc85", size = 5227837 }, { url = "https://files.pythonhosted.org/packages/15/f5/9b1f7edf6565ee31e4300edb1bcc61eaebe50a3cff4053c0206d8dc772f2/lxml-5.3.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:dc0e9bdb3aa4d1de703a437576007d366b54f52c9897cae1a3716bb44fc1fc85", size = 5227837 },
{ url = "https://files.pythonhosted.org/packages/5c/17/c31d94364c02e3492215658917f5590c00edce8074aeb06d05b7771465d9/lxml-5.3.2-cp310-cp310-win32.whl", hash = "sha256:5f94909a1022c8ea12711db7e08752ca7cf83e5b57a87b59e8a583c5f35016ad", size = 3477533 }, { url = "https://files.pythonhosted.org/packages/dd/53/a187c4ccfcd5fbfca01e6c96da39499d8b801ab5dcf57717db95d7a968a8/lxml-5.3.2-cp310-cp310-win32.win32.whl", hash = "sha256:dd755a0a78dd0b2c43f972e7b51a43be518ebc130c9f1a7c4480cf08b4385486", size = 3477533 },
{ url = "https://files.pythonhosted.org/packages/f2/2c/397c5a9d76a7a0faf9e5b13143ae1a7e223e71d2197a45da71c21aacb3d4/lxml-5.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:d64ea1686474074b38da13ae218d9fde0d1dc6525266976808f41ac98d9d7980", size = 3805160 }, { url = "https://files.pythonhosted.org/packages/f2/2c/397c5a9d76a7a0faf9e5b13143ae1a7e223e71d2197a45da71c21aacb3d4/lxml-5.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:d64ea1686474074b38da13ae218d9fde0d1dc6525266976808f41ac98d9d7980", size = 3805160 },
{ url = "https://files.pythonhosted.org/packages/84/b8/2b727f5a90902f7cc5548349f563b60911ca05f3b92e35dfa751349f265f/lxml-5.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9d61a7d0d208ace43986a92b111e035881c4ed45b1f5b7a270070acae8b0bfb4", size = 8163457 }, { url = "https://files.pythonhosted.org/packages/84/b8/2b727f5a90902f7cc5548349f563b60911ca05f3b92e35dfa751349f265f/lxml-5.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9d61a7d0d208ace43986a92b111e035881c4ed45b1f5b7a270070acae8b0bfb4", size = 8163457 },
{ url = "https://files.pythonhosted.org/packages/91/84/23135b2dc72b3440d68c8f39ace2bb00fe78e3a2255f7c74f7e76f22498e/lxml-5.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:856dfd7eda0b75c29ac80a31a6411ca12209183e866c33faf46e77ace3ce8a79", size = 4433445 }, { url = "https://files.pythonhosted.org/packages/91/84/23135b2dc72b3440d68c8f39ace2bb00fe78e3a2255f7c74f7e76f22498e/lxml-5.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:856dfd7eda0b75c29ac80a31a6411ca12209183e866c33faf46e77ace3ce8a79", size = 4433445 },
@@ -1926,9 +1926,26 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/96/2e/6f8e30055aa0c28e19df2659e325b27ea5b6c788dbc8b99591b0935cdaaa/nonebot_plugin_session_orm-0.2.2-py3-none-any.whl", hash = "sha256:ab2bbc9fbf245b3e236789aabb2bef4d501dd720d74002744091503d33548ba7", size = 7842 }, { url = "https://files.pythonhosted.org/packages/96/2e/6f8e30055aa0c28e19df2659e325b27ea5b6c788dbc8b99591b0935cdaaa/nonebot_plugin_session_orm-0.2.2-py3-none-any.whl", hash = "sha256:ab2bbc9fbf245b3e236789aabb2bef4d501dd720d74002744091503d33548ba7", size = 7842 },
] ]
[[package]]
name = "nonebot-plugin-tarina-lang-turbo"
version = "0.1.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "msgspec" },
{ name = "nonebot-plugin-alconna" },
{ name = "nonebot-plugin-localstore" },
{ name = "nonebot-plugin-session" },
{ name = "nonebot2" },
{ name = "tarina" },
]
sdist = { url = "https://files.pythonhosted.org/packages/24/db/f91bceeff96e3e6de959bd31ed8eba1dea9f297f141879bd0a08758fcbfd/nonebot_plugin_tarina_lang_turbo-0.1.1.tar.gz", hash = "sha256:33d0854d39c8fbb07020e7d1c2036943ee90a487ba4da90e0c0c89adc172cd19", size = 124382 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/88/54/be4dc0c899b6f154677cb502b81c3ec8ba5a37ded850f09e47916143c2d7/nonebot_plugin_tarina_lang_turbo-0.1.1-py3-none-any.whl", hash = "sha256:c231dab228e3a52993b282dbdcb5faeebd7aa4e433c9794405651334f54a96a8", size = 7988 },
]
[[package]] [[package]]
name = "nonebot-plugin-tetris-stats" name = "nonebot-plugin-tetris-stats"
version = "1.7.2" version = "1.8.1"
source = { editable = "." } source = { editable = "." }
dependencies = [ dependencies = [
{ name = "aiocache" }, { name = "aiocache" },
@@ -1973,6 +1990,7 @@ dev = [
{ name = "nonebot-adapter-kaiheila" }, { name = "nonebot-adapter-kaiheila" },
{ name = "nonebot-adapter-onebot" }, { name = "nonebot-adapter-onebot" },
{ name = "nonebot-adapter-qq" }, { name = "nonebot-adapter-qq" },
{ name = "nonebot-plugin-tarina-lang-turbo" },
{ name = "ruff" }, { name = "ruff" },
] ]
release = [ release = [
@@ -2037,6 +2055,7 @@ dev = [
{ name = "nonebot-adapter-kaiheila", specifier = ">=0.3.4" }, { name = "nonebot-adapter-kaiheila", specifier = ">=0.3.4" },
{ name = "nonebot-adapter-onebot", specifier = ">=2.4.6" }, { name = "nonebot-adapter-onebot", specifier = ">=2.4.6" },
{ name = "nonebot-adapter-qq", specifier = ">=1.5.3" }, { name = "nonebot-adapter-qq", specifier = ">=1.5.3" },
{ name = "nonebot-plugin-tarina-lang-turbo", specifier = ">=0.1.1" },
{ name = "ruff", specifier = ">=0.7.1" }, { name = "ruff", specifier = ">=0.7.1" },
] ]
release = [{ name = "bump-my-version", specifier = ">=0.28.0" }] release = [{ name = "bump-my-version", specifier = ">=0.28.0" }]