使用 nonebot-plugin-user 进行身份绑定 close #63

This commit is contained in:
2024-06-08 12:03:07 +08:00
parent ce95d8f977
commit ab046fe786
10 changed files with 113 additions and 54 deletions

View File

@@ -5,8 +5,9 @@ require('nonebot_plugin_alconna')
require('nonebot_plugin_apscheduler')
require('nonebot_plugin_localstore')
require('nonebot_plugin_orm')
require('nonebot_plugin_session')
require('nonebot_plugin_session_orm')
require('nonebot_plugin_session')
require('nonebot_plugin_user')
from nonebot_plugin_alconna import namespace # noqa: E402

View File

@@ -0,0 +1,71 @@
"""Migrate to nonobot-plugin-user
迁移 ID: b15844837693
父迁移: 3c25a5a8c050
创建时间: 2024-06-08 02:27:35.227596
"""
from __future__ import annotations
from typing import TYPE_CHECKING
import sqlalchemy as sa
from alembic import op
if TYPE_CHECKING:
from collections.abc import Sequence
revision: str = 'b15844837693'
down_revision: str | Sequence[str] | None = '3c25a5a8c050'
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None
def upgrade(name: str = '') -> None:
if name:
return
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('nonebot_plugin_tetris_stats_bind', schema=None) as batch_op:
batch_op.drop_index('ix_nonebot_plugin_tetris_stats_bind_chat_account')
batch_op.drop_index('ix_nonebot_plugin_tetris_stats_bind_chat_platform')
op.drop_table('nonebot_plugin_tetris_stats_bind')
op.create_table(
'nonebot_plugin_tetris_stats_bind',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('user_id', sa.Integer(), nullable=False),
sa.Column('game_platform', sa.String(length=32), nullable=False),
sa.Column('game_account', sa.String(), nullable=False),
sa.PrimaryKeyConstraint('id', name=op.f('pk_nonebot_plugin_tetris_stats_bind')),
info={'bind_key': 'nonebot_plugin_tetris_stats'},
)
with op.batch_alter_table('nonebot_plugin_tetris_stats_bind', schema=None) as batch_op:
batch_op.create_index(batch_op.f('ix_nonebot_plugin_tetris_stats_bind_user_id'), ['user_id'], unique=False)
# ### end Alembic commands ###
def downgrade(name: str = '') -> None:
if name:
return
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('nonebot_plugin_tetris_stats_bind', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_nonebot_plugin_tetris_stats_bind_user_id'))
op.drop_table('nonebot_plugin_tetris_stats_bind')
op.create_table(
'nonebot_plugin_tetris_stats_bind',
sa.Column('id', sa.INTEGER(), nullable=False),
sa.Column('chat_platform', sa.VARCHAR(length=32), nullable=False),
sa.Column('chat_account', sa.VARCHAR(), nullable=False),
sa.Column('game_platform', sa.VARCHAR(length=32), nullable=False),
sa.Column('game_account', sa.VARCHAR(), nullable=False),
sa.PrimaryKeyConstraint('id', name='pk_nonebot_plugin_tetris_stats_bind'),
)
with op.batch_alter_table('nonebot_plugin_tetris_stats_bind', schema=None) as batch_op:
batch_op.create_index('ix_nonebot_plugin_tetris_stats_bind_chat_platform', ['chat_platform'], unique=False)
batch_op.create_index('ix_nonebot_plugin_tetris_stats_bind_chat_account', ['chat_account'], unique=False)
# ### end Alembic commands ###

View File

@@ -8,6 +8,7 @@ from typing import TYPE_CHECKING, Literal, TypeVar, overload
from nonebot.exception import FinishedException
from nonebot.log import logger
from nonebot_plugin_orm import AsyncSession, get_session
from nonebot_plugin_user import User # type: ignore[import-untyped]
from sqlalchemy import select
from ..utils.typing import CommandType, GameType
@@ -28,37 +29,28 @@ class BindStatus(Enum):
async def query_bind_info(
session: AsyncSession,
chat_platform: str,
chat_account: str,
user: User,
game_platform: GameType,
) -> Bind | None:
return (
await session.scalars(
select(Bind)
.where(Bind.chat_platform == chat_platform)
.where(Bind.chat_account == chat_account)
.where(Bind.game_platform == game_platform)
)
await session.scalars(select(Bind).where(Bind.user_id == user.id).where(Bind.game_platform == game_platform))
).one_or_none()
async def create_or_update_bind(
session: AsyncSession,
chat_platform: str,
chat_account: str,
user: User,
game_platform: GameType,
game_account: str,
) -> BindStatus:
bind = await query_bind_info(
session=session,
chat_platform=chat_platform,
chat_account=chat_account,
user=user,
game_platform=game_platform,
)
if bind is None:
bind = Bind(
chat_platform=chat_platform,
chat_account=chat_account,
user_id=user.id,
game_platform=game_platform,
game_account=game_account,
)

View File

@@ -66,8 +66,7 @@ class PydanticType(TypeDecorator):
class Bind(MappedAsDataclass, Model):
id: Mapped[int] = mapped_column(init=False, primary_key=True)
chat_platform: Mapped[str] = mapped_column(String(32), index=True)
chat_account: Mapped[str] = mapped_column(index=True)
user_id: Mapped[int] = mapped_column(index=True)
game_platform: Mapped[GameType] = mapped_column(String(32))
game_account: Mapped[str]

View File

@@ -1,17 +1,16 @@
from hashlib import md5
from urllib.parse import urlunparse
from nonebot.adapters import Bot, Event
from nonebot_plugin_alconna.uniseg import UniMessage
from nonebot_plugin_orm import get_session
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 nonebot_plugin_user import User # type: ignore[import-untyped]
from nonebot_plugin_userinfo import BotUserInfo, UserInfo # type: ignore[import-untyped]
from ...db import BindStatus, create_or_update_bind, trigger
from ...utils.avatar import get_avatar
from ...utils.host import HostPage, get_self_netloc
from ...utils.platform import get_platform
from ...utils.render import Bind, render
from ...utils.render.schemas.base import Avatar, People
from ...utils.screenshot import screenshot
@@ -21,7 +20,7 @@ from .constant import GAME_TYPE
@alc.assign('bind')
async def _(bot: Bot, event: Event, account: Player, event_session: EventSession, bot_info: UserInfo = BotUserInfo()): # noqa: B008
async def _(nb_user: User, account: Player, event_session: EventSession, bot_info: UserInfo = BotUserInfo()): # noqa: B008
async with trigger(
session_persist_id=await get_session_persist_id(event_session),
game_platform=GAME_TYPE,
@@ -32,8 +31,7 @@ async def _(bot: Bot, event: Event, account: Player, event_session: EventSession
async with get_session() as session:
bind_status = await create_or_update_bind(
session=session,
chat_platform=get_platform(bot),
chat_account=event.get_user_id(),
user=nb_user,
game_platform=GAME_TYPE,
game_account=user.unique_identifier,
)

View File

@@ -1,6 +1,6 @@
import contextlib
from asyncio import gather
from collections import defaultdict
from contextlib import suppress
from datetime import date, datetime, timedelta, timezone
from hashlib import md5
from math import ceil, floor
@@ -10,7 +10,7 @@ from zoneinfo import ZoneInfo
from aiofiles import open
from nonebot import get_driver
from nonebot.adapters import Bot, Event
from nonebot.adapters import Event
from nonebot.compat import type_validate_json
from nonebot.matcher import Matcher
from nonebot_plugin_alconna import At
@@ -20,12 +20,12 @@ from nonebot_plugin_localstore import get_data_file # type: ignore[import-untyp
from nonebot_plugin_orm import get_session
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 nonebot_plugin_user import get_user # type: ignore[import-untyped]
from sqlalchemy import select
from zstandard import ZstdDecompressor
from ...db import query_bind_info, trigger
from ...utils.host import HostPage, get_self_netloc
from ...utils.platform import get_platform
from ...utils.render import render
from ...utils.render.schemas.base import Avatar, Ranking
from ...utils.render.schemas.tetrio_info import Data, Info, Radar, TetraLeague, TetraLeagueHistory
@@ -48,7 +48,7 @@ driver = get_driver()
@alc.assign('query')
async def _(bot: Bot, event: Event, matcher: Matcher, target: At | Me, event_session: EventSession):
async def _(event: Event, matcher: Matcher, target: At | Me, event_session: EventSession):
async with trigger(
session_persist_id=await get_session_persist_id(event_session),
game_platform=GAME_TYPE,
@@ -58,8 +58,9 @@ async def _(bot: Bot, event: Event, matcher: Matcher, target: At | Me, event_ses
async with get_session() as session:
bind = await query_bind_info(
session=session,
chat_platform=get_platform(bot),
chat_account=(target.target if isinstance(target, At) else event.get_user_id()),
user=await get_user(
event_session.platform, target.target if isinstance(target, At) else event.get_user_id()
),
game_platform=GAME_TYPE,
)
if bind is None:
@@ -69,7 +70,7 @@ async def _(bot: Bot, event: Event, matcher: Matcher, target: At | Me, event_ses
user, user_info, user_records = await gather(player.user, player.get_info(), player.get_records())
sprint = user_records.data.records.sprint
blitz = user_records.data.records.blitz
with contextlib.suppress(TypeError):
with suppress(TypeError):
message.image(raw=await make_query_image(user, user_info, sprint.record, blitz.record))
await message.finish()
message += make_query_text(user_info, sprint, blitz)
@@ -87,7 +88,7 @@ async def _(account: Player, event_session: EventSession):
user, user_info, user_records = await gather(account.user, account.get_info(), account.get_records())
sprint = user_records.data.records.sprint
blitz = user_records.data.records.blitz
with contextlib.suppress(TypeError):
with suppress(TypeError):
await UniMessage.image(raw=await make_query_image(user, user_info, sprint.record, blitz.record)).finish()
await make_query_text(user_info, sprint, blitz).finish()

View File

@@ -1,16 +1,15 @@
from urllib.parse import urlunparse
from nonebot.adapters import Bot
from nonebot_plugin_alconna.uniseg import UniMessage
from nonebot_plugin_orm import get_session
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 nonebot_plugin_user import User # type: ignore[import-untyped]
from nonebot_plugin_userinfo import BotUserInfo, EventUserInfo, UserInfo # type: ignore[import-untyped]
from ...db import BindStatus, create_or_update_bind, trigger
from ...utils.avatar import get_avatar
from ...utils.host import HostPage, get_self_netloc
from ...utils.platform import get_platform
from ...utils.render import Bind, render
from ...utils.render.schemas.base import People
from ...utils.screenshot import screenshot
@@ -21,11 +20,11 @@ from .constant import GAME_TYPE
@alc.assign('bind')
async def _(
bot: Bot,
nb_user: User,
account: Player,
event_session: EventSession,
bot_info: UserInfo = BotUserInfo(), # noqa: B008
event_user_info: UserInfo = EventUserInfo(), # noqa: B008
bot_info: UserInfo = BotUserInfo(), # noqa: B008
):
async with trigger(
session_persist_id=await get_session_persist_id(event_session),
@@ -37,8 +36,7 @@ async def _(
async with get_session() as session:
bind_status = await create_or_update_bind(
session=session,
chat_platform=get_platform(bot),
chat_account=event_user_info.user_id,
user=nb_user,
game_platform=GAME_TYPE,
game_account=user.unique_identifier,
)

View File

@@ -1,14 +1,14 @@
from nonebot.adapters import Bot, Event
from nonebot.adapters import Event
from nonebot.matcher import Matcher
from nonebot_plugin_alconna import At
from nonebot_plugin_alconna.uniseg import UniMessage
from nonebot_plugin_orm import get_session
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 nonebot_plugin_user import get_user # type: ignore[import-untyped]
from ...db import query_bind_info, trigger
from ...utils.metrics import get_metrics
from ...utils.platform import get_platform
from ...utils.typing import Me
from ..constant import CANT_VERIFY_MESSAGE
from . import alc
@@ -18,7 +18,7 @@ from .constant import GAME_TYPE
@alc.assign('query')
async def _(bot: Bot, event: Event, matcher: Matcher, target: At | Me, event_session: EventSession):
async def _(event: Event, matcher: Matcher, target: At | Me, event_session: EventSession):
async with trigger(
session_persist_id=await get_session_persist_id(event_session),
game_platform=GAME_TYPE,
@@ -28,8 +28,9 @@ async def _(bot: Bot, event: Event, matcher: Matcher, target: At | Me, event_ses
async with get_session() as session:
bind = await query_bind_info(
session=session,
chat_platform=get_platform(bot),
chat_account=(target.target if isinstance(target, At) else event.get_user_id()),
user=await get_user(
event_session.platform, target.target if isinstance(target, At) else event.get_user_id()
),
game_platform=GAME_TYPE,
)
if bind is None:

View File

@@ -1,16 +1,15 @@
from urllib.parse import urlunparse
from nonebot.adapters import Bot
from nonebot_plugin_alconna.uniseg import UniMessage
from nonebot_plugin_orm import get_session
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 nonebot_plugin_user import User # type: ignore[import-untyped]
from nonebot_plugin_userinfo import BotUserInfo, EventUserInfo, UserInfo # type: ignore[import-untyped]
from ...db import BindStatus, create_or_update_bind, trigger
from ...utils.avatar import get_avatar
from ...utils.host import HostPage, get_self_netloc
from ...utils.platform import get_platform
from ...utils.render import Bind, render
from ...utils.render.schemas.base import People
from ...utils.screenshot import screenshot
@@ -21,11 +20,11 @@ from .constant import GAME_TYPE
@alc.assign('bind')
async def _(
bot: Bot,
nb_user: User,
account: Player,
event_session: EventSession,
bot_info: UserInfo = BotUserInfo(), # noqa: B008
event_user_info: UserInfo = EventUserInfo(), # noqa: B008
bot_info: UserInfo = BotUserInfo(), # noqa: B008
):
async with trigger(
session_persist_id=await get_session_persist_id(event_session),
@@ -37,8 +36,7 @@ async def _(
async with get_session() as session:
bind_status = await create_or_update_bind(
session=session,
chat_platform=get_platform(bot),
chat_account=event_user_info.user_id,
user=nb_user,
game_platform=GAME_TYPE,
game_account=user.unique_identifier,
)

View File

@@ -4,13 +4,14 @@ from http import HTTPStatus
from typing import Literal, NamedTuple
from urllib.parse import urlunparse
from nonebot.adapters import Bot, Event
from nonebot.adapters import Event
from nonebot.matcher import Matcher
from nonebot_plugin_alconna import At
from nonebot_plugin_alconna.uniseg import UniMessage
from nonebot_plugin_orm import get_session
from nonebot_plugin_session import EventSession # type: ignore[import-untyped] # type: ignore[import-untyped]
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 nonebot_plugin_user import get_user # type: ignore[import-untyped]
from nonebot_plugin_userinfo import EventUserInfo, UserInfo # type: ignore[import-untyped]
from ...db import query_bind_info, trigger
@@ -18,7 +19,6 @@ from ...utils.avatar import get_avatar
from ...utils.exception import RequestError
from ...utils.host import HostPage, get_self_netloc
from ...utils.metrics import TetrisMetricsProWithLPMADPM, get_metrics
from ...utils.platform import get_platform
from ...utils.render import render
from ...utils.render.schemas.base import People, Ranking
from ...utils.render.schemas.tos_info import Info, Multiplayer, Radar
@@ -99,8 +99,7 @@ except ImportError:
@alc.assign('query')
async def _( # noqa: PLR0913
bot: Bot,
async def _(
event: Event,
matcher: Matcher,
target: At | Me,
@@ -116,8 +115,9 @@ async def _( # noqa: PLR0913
async with get_session() as session:
bind = await query_bind_info(
session=session,
chat_platform=get_platform(bot),
chat_account=(target.target if isinstance(target, At) else event.get_user_id()),
user=await get_user(
event_session.platform, target.target if isinstance(target, At) else event.get_user_id()
),
game_platform=GAME_TYPE,
)
if bind is None: