mirror of
https://github.com/A-Minos/nonebot-plugin-tetris-stats.git
synced 2026-03-05 05:36:54 +08:00
♻️ Refactor (#318)
* 🔧 启用一些 ruff 的新规则 * ➕ 添加开发依赖 nonebot-adapter-qq * ➕ 添加依赖 nonebot-plugin-session * ➕ 添加依赖 nonebot-plugin-session-orm * 🔧 忽略 ruff 规则 ISC001 format 冲突风险 * 🚨 修复 ruff 警报 * ♻️ 重构! * ♻️ 恢复定时获取 TetraLeague 数据的功能 * ✨ 统一处理需要捕获的错误 * ✨ 记录用户触发的指令
This commit is contained in:
@@ -1,16 +1,14 @@
|
||||
from collections.abc import Callable, Sequence
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
from typing import Any, Literal
|
||||
|
||||
from nonebot.adapters import Message
|
||||
from nonebot.compat import PYDANTIC_V2, type_validate_json
|
||||
from nonebot_plugin_orm import Model
|
||||
from pydantic import BaseModel, ValidationError
|
||||
from sqlalchemy import JSON, DateTime, Dialect, PickleType, String, TypeDecorator
|
||||
from sqlalchemy import JSON, DateTime, Dialect, String, TypeDecorator
|
||||
from sqlalchemy.orm import Mapped, MappedAsDataclass, mapped_column
|
||||
from typing_extensions import override
|
||||
|
||||
from ..game_data_processor.schemas import BaseProcessedData, BaseUser
|
||||
from ..utils.typing import CommandType, GameType
|
||||
|
||||
|
||||
@@ -18,8 +16,16 @@ class PydanticType(TypeDecorator):
|
||||
impl = JSON
|
||||
|
||||
@override
|
||||
def __init__(self, get_model: Callable[[], Sequence[type[BaseModel]]], *args: Any, **kwargs: Any):
|
||||
self.get_model = get_model
|
||||
def __init__(
|
||||
self,
|
||||
get_model: Sequence[Callable[[], Sequence[type[BaseModel]]]],
|
||||
models: set[type[BaseModel]],
|
||||
*args: Any,
|
||||
**kwargs: Any,
|
||||
):
|
||||
for i in get_model:
|
||||
models.update(i())
|
||||
self.models = models
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
if PYDANTIC_V2:
|
||||
@@ -27,7 +33,7 @@ class PydanticType(TypeDecorator):
|
||||
@override
|
||||
def process_bind_param(self, value: Any | None, dialect: Dialect) -> str:
|
||||
# 将 Pydantic 模型实例转换为 JSON
|
||||
if isinstance(value, tuple(self.get_model())):
|
||||
if isinstance(value, tuple(self.pydantic_models)):
|
||||
return value.model_dump_json(by_alias=True) # type: ignore[union-attr]
|
||||
raise TypeError
|
||||
else:
|
||||
@@ -35,7 +41,7 @@ class PydanticType(TypeDecorator):
|
||||
@override
|
||||
def process_bind_param(self, value: Any | None, dialect: Dialect) -> str:
|
||||
# 将 Pydantic 模型实例转换为 JSON
|
||||
if isinstance(value, tuple(self.get_model())):
|
||||
if isinstance(value, tuple(self.pydantic_models)):
|
||||
return value.json(by_alias=True) # type: ignore[union-attr]
|
||||
raise TypeError
|
||||
|
||||
@@ -43,7 +49,7 @@ class PydanticType(TypeDecorator):
|
||||
def process_result_value(self, value: Any | None, dialect: Dialect) -> BaseModel:
|
||||
# 将 JSON 转换回 Pydantic 模型实例
|
||||
if isinstance(value, str | bytes):
|
||||
for i in self.get_model():
|
||||
for i in self.pydantic_models:
|
||||
try:
|
||||
return type_validate_json(i, value)
|
||||
except ValidationError: # noqa: PERF203
|
||||
@@ -59,20 +65,11 @@ class Bind(MappedAsDataclass, Model):
|
||||
game_account: Mapped[str]
|
||||
|
||||
|
||||
class HistoricalData(MappedAsDataclass, Model):
|
||||
class TriggerHistoricalData(MappedAsDataclass, Model):
|
||||
id: Mapped[int] = mapped_column(init=False, primary_key=True)
|
||||
trigger_time: Mapped[datetime] = mapped_column(DateTime)
|
||||
bot_platform: Mapped[str | None] = mapped_column(String(32))
|
||||
bot_account: Mapped[str | None]
|
||||
source_type: Mapped[str | None] = mapped_column(String(32), index=True)
|
||||
source_account: Mapped[str | None] = mapped_column(index=True)
|
||||
message: Mapped[Message | None] = mapped_column(PickleType)
|
||||
game_platform: Mapped[GameType] = mapped_column(String(32), index=True, init=False)
|
||||
command_type: Mapped[CommandType] = mapped_column(String(16), index=True, init=False)
|
||||
command_args: Mapped[list[str]] = mapped_column(JSON, init=False)
|
||||
user_unique_identifier: Mapped[str] = mapped_column(String(32), index=True, init=False)
|
||||
game_user: Mapped[BaseUser] = mapped_column(PydanticType(get_model=BaseUser.__subclasses__), init=False)
|
||||
processed_data: Mapped[BaseProcessedData] = mapped_column(
|
||||
PydanticType(get_model=BaseProcessedData.__subclasses__), init=False
|
||||
)
|
||||
finish_time: Mapped[datetime] = mapped_column(DateTime, init=False)
|
||||
session_persist_id: Mapped[int]
|
||||
game_platform: Mapped[GameType] = mapped_column(String(32), index=True)
|
||||
command_type: Mapped[CommandType | Literal['rank']] = mapped_column(String(16), index=True)
|
||||
command_args: Mapped[list[str]] = mapped_column(JSON)
|
||||
finish_time: Mapped[datetime] = mapped_column(DateTime)
|
||||
|
||||
Reference in New Issue
Block a user