添加 unbind 指令 (#525)

*  添加依赖 nonebot-plugin-waiter

*  添加 unbind 指令
This commit is contained in:
呵呵です
2024-12-19 03:59:22 +08:00
committed by GitHub
parent 96f5d4559d
commit cfcda6f597
11 changed files with 271 additions and 11 deletions

View File

@@ -10,6 +10,7 @@ require_plugins = {
'nonebot_plugin_session',
'nonebot_plugin_user',
'nonebot_plugin_userinfo',
'nonebot_plugin_waiter',
}
for i in require_plugins:

View File

@@ -63,6 +63,23 @@ async def create_or_update_bind(
return status
async def remove_bind(
session: AsyncSession,
user: User,
game_platform: GameType,
) -> bool:
bind = await query_bind_info(
session=session,
user=user,
game_platform=game_platform,
)
if bind is not None:
await session.delete(bind)
await session.commit()
return True
return False
T = TypeVar('T', 'TETRIOHistoricalData', 'TOPHistoricalData', 'TOSHistoricalData')
lock = Lock()

View File

@@ -23,7 +23,7 @@ command = Subcommand(
)
from . import bind, config, list, query, rank, record # noqa: A004, E402
from . import bind, config, list, query, rank, record, unbind # noqa: A004, E402
main_command.add(command)
@@ -35,4 +35,5 @@ __all__ = [
'query',
'rank',
'record',
'unbind',
]

View File

@@ -0,0 +1,75 @@
from hashlib import md5
from nonebot_plugin_alconna import Subcommand
from nonebot_plugin_alconna.uniseg import UniMessage
from nonebot_plugin_orm import get_session
from nonebot_plugin_session import EventSession
from nonebot_plugin_session_orm import get_session_persist_id # type: ignore[import-untyped]
from nonebot_plugin_user import User
from nonebot_plugin_userinfo import BotUserInfo, UserInfo
from nonebot_plugin_waiter import suggest # type: ignore[import-untyped]
from yarl import URL
from ...db import query_bind_info, remove_bind, trigger
from ...utils.host import HostPage, get_self_netloc
from ...utils.image import get_avatar
from ...utils.render import Bind, render
from ...utils.render.schemas.base import Avatar, People
from ...utils.screenshot import screenshot
from . import alc, command
from .api import Player
from .constant import GAME_TYPE
command.add(Subcommand('unbind', help_text='解除绑定 TETR.IO 账号'))
alc.shortcut(
'(?i:io)(?i:解除绑定|解绑|unbind)',
command='tstats TETR.IO unbind',
humanized='io解绑',
)
@alc.assign('TETRIO.unbind')
async def _(nb_user: User, 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,
command_type='unbind',
command_args=[],
),
get_session() as session,
):
if (bind := await query_bind_info(session=session, user=nb_user, game_platform=GAME_TYPE)) is None:
await UniMessage('您还未绑定 TETR.IO 账号').finish()
resp = await suggest('您确定要解绑吗?', ['', ''])
if resp is None or resp.extract_plain_text() == '':
return
player = Player(user_id=bind.game_account, trust=True)
user = await player.user
netloc = get_self_netloc()
async with HostPage(
await render(
'v1/binding',
Bind(
platform='TETR.IO',
status='unlink',
user=People(
avatar=str(
URL(f'http://{netloc}/host/resource/tetrio/avatars/{user.ID}')
% {'revision': avatar_revision}
)
if (avatar_revision := (await player.avatar_revision)) is not None and avatar_revision != 0
else Avatar(type='identicon', hash=md5(user.ID.encode()).hexdigest()), # noqa: S324
name=user.name.upper(),
),
bot=People(
avatar=await get_avatar(bot_info, 'Data URI', '../../static/logo/logo.svg'),
name=bot_info.user_name,
),
command='io绑定{游戏ID}',
),
)
) as page_hash:
await UniMessage.image(raw=await screenshot(f'http://{netloc}/host/{page_hash}.html')).send()
await remove_bind(session=session, user=nb_user, game_platform=GAME_TYPE)

View File

@@ -29,6 +29,10 @@ command.add(
),
help_text='绑定 TOP 账号',
),
Subcommand(
'unbind',
help_text='解除绑定 TOP 账号',
),
Subcommand(
'query',
Args(
@@ -51,9 +55,22 @@ command.add(
)
)
alc.shortcut('(?i:top)(?i:绑定|绑|bind)', {'command': 'tstats TOP bind', 'humanized': 'top绑定'})
alc.shortcut('(?i:top)(?i:查询|查|query|stats)', {'command': 'tstats TOP query', 'humanized': 'top查'})
alc.shortcut(
'(?i:top)(?i:绑定|绑|bind)',
command='tstats TOP bind',
humanized='top绑定',
)
alc.shortcut(
'(?i:top)(?i:解除绑定|解绑|unbind)',
command='tstats TOP unbind',
humanized='top解绑',
)
alc.shortcut(
'(?i:top)(?i:查询|查|query|stats)',
command='tstats TOP query',
humanized='top查',
)
add_block_handlers(alc.assign('TOP.query'))
from . import bind, query # noqa: E402, F401
from . import bind, query, unbind # noqa: E402, F401

View File

@@ -0,0 +1,63 @@
from nonebot_plugin_alconna.uniseg import UniMessage
from nonebot_plugin_orm import get_session
from nonebot_plugin_session import EventSession
from nonebot_plugin_session_orm import get_session_persist_id # type: ignore[import-untyped]
from nonebot_plugin_user import User
from nonebot_plugin_userinfo import BotUserInfo, EventUserInfo, UserInfo
from nonebot_plugin_waiter import suggest # type: ignore[import-untyped]
from ...db import query_bind_info, remove_bind, trigger
from ...utils.host import HostPage, get_self_netloc
from ...utils.image import get_avatar
from ...utils.render import Bind, render
from ...utils.render.schemas.base import People
from ...utils.screenshot import screenshot
from . import alc
from .api import Player
from .constant import GAME_TYPE
@alc.assign('TOP.unbind')
async def _(
nb_user: User,
event_session: EventSession,
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),
game_platform=GAME_TYPE,
command_type='unbind',
command_args=[],
),
get_session() as session,
):
if (bind := await query_bind_info(session=session, user=nb_user, game_platform=GAME_TYPE)) is None:
await UniMessage('您还未绑定 TOP 账号').finish()
resp = await suggest('您确定要解绑吗?', ['', ''])
if resp is None or resp.extract_plain_text() == '':
return
player = Player(user_name=bind.game_account, trust=True)
user = await player.user
netloc = get_self_netloc()
async with HostPage(
await render(
'v1/binding',
Bind(
platform='TOP',
status='unlink',
user=People(
avatar=await get_avatar(event_user_info, 'Data URI', None),
name=user.user_name,
),
bot=People(
avatar=await get_avatar(bot_info, 'Data URI', '../../static/logo/logo.svg'),
name=bot_info.user_name,
),
command='top绑定{游戏ID}',
),
)
) as page_hash:
await UniMessage.image(raw=await screenshot(f'http://{netloc}/host/{page_hash}.html')).send()
await remove_bind(session=session, user=nb_user, game_platform=GAME_TYPE)

View File

@@ -34,6 +34,10 @@ command.add(
),
help_text='绑定 茶服 账号',
),
Subcommand(
'unbind',
help_text='解除绑定 TOS 账号',
),
Subcommand(
'query',
Args(
@@ -56,9 +60,22 @@ command.add(
)
)
alc.shortcut('(?i:tos|茶服)(?i:绑定|绑|bind)', {'command': 'tstats TOS bind', 'humanized': '茶服绑定'})
alc.shortcut('(?i:tos|茶服)(?i:查询|查|query|stats)', {'command': 'tstats TOS query', 'humanized': '茶服查'})
alc.shortcut(
'(?i:tos|茶服)(?i:绑定|绑|bind)',
command='tstats TOS bind',
humanized='茶服绑定',
)
alc.shortcut(
'(?i:tos|茶服)(?i:解除绑定|解绑|unbind)',
command='tstats TOS unbind',
humanized='茶服解绑',
)
alc.shortcut(
'(?i:tos|茶服)(?i:查询|查|query|stats)',
command='tstats TOS query',
humanized='茶服查',
)
add_block_handlers(alc.assign('TOS.query'))
from . import bind, query # noqa: E402, F401
from . import bind, query, unbind # noqa: E402, F401

View File

@@ -0,0 +1,66 @@
from nonebot_plugin_alconna.uniseg import UniMessage
from nonebot_plugin_orm import get_session
from nonebot_plugin_session import EventSession
from nonebot_plugin_session_orm import get_session_persist_id # type: ignore[import-untyped]
from nonebot_plugin_user import User
from nonebot_plugin_userinfo import BotUserInfo, EventUserInfo, UserInfo
from nonebot_plugin_waiter import suggest # type: ignore[import-untyped]
from ...db import query_bind_info, remove_bind, trigger
from ...utils.host import HostPage, get_self_netloc
from ...utils.image import get_avatar
from ...utils.render import Bind, render
from ...utils.render.avatar import get_avatar as get_random_avatar
from ...utils.render.schemas.base import People
from ...utils.screenshot import screenshot
from . import alc
from .api import Player
from .constant import GAME_TYPE
@alc.assign('TOP.unbind')
async def _(
nb_user: User,
event_session: EventSession,
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),
game_platform=GAME_TYPE,
command_type='unbind',
command_args=[],
),
get_session() as session,
):
if (bind := await query_bind_info(session=session, user=nb_user, game_platform=GAME_TYPE)) is None:
await UniMessage('您还未绑定 TOP 账号').finish()
resp = await suggest('您确定要解绑吗?', ['', ''])
if resp is None or resp.extract_plain_text() == '':
return
player = Player(user_name=bind.game_account, trust=True)
user = await player.user
netloc = get_self_netloc()
async with HostPage(
await render(
'v1/binding',
Bind(
platform='TOS',
status='unlink',
user=People(
avatar=await get_avatar(event_user_info, 'Data URI', None)
if event_user_info is not None
else get_random_avatar(user.teaid),
name=user.name,
),
bot=People(
avatar=await get_avatar(bot_info, 'Data URI', '../../static/logo/logo.svg'),
name=bot_info.user_name,
),
command='茶服绑定{游戏ID}',
),
)
) as page_hash:
await UniMessage.image(raw=await screenshot(f'http://{netloc}/host/{page_hash}.html')).send()
await remove_bind(session=session, user=nb_user, game_platform=GAME_TYPE)

View File

@@ -2,7 +2,7 @@ from typing import Literal, TypeAlias
Number: TypeAlias = float | int
GameType: TypeAlias = Literal['IO', 'TOP', 'TOS']
BaseCommandType: TypeAlias = Literal['bind', 'query']
BaseCommandType: TypeAlias = Literal['bind', 'unbind', 'query']
TETRIOCommandType: TypeAlias = BaseCommandType | Literal['rank', 'config', 'list', 'record']
AllCommandType: TypeAlias = BaseCommandType | TETRIOCommandType
Me: TypeAlias = Literal[

View File

@@ -22,6 +22,7 @@ dependencies = [
"nonebot-plugin-session-orm>=0.2.0",
"nonebot-plugin-user>=0.4.4",
"nonebot-plugin-userinfo>=0.2.6",
"nonebot-plugin-waiter>=0.8.0",
"nonebot2[fastapi]>=2.3.3",
"pandas>=2.2.3",
"pillow>=11.0.0",

8
uv.lock generated
View File

@@ -1818,7 +1818,7 @@ wheels = [
[[package]]
name = "nonebot-plugin-tetris-stats"
version = "1.6.2"
version = "1.6.3"
source = { editable = "." }
dependencies = [
{ name = "aiocache" },
@@ -1837,6 +1837,7 @@ dependencies = [
{ name = "nonebot-plugin-session-orm" },
{ name = "nonebot-plugin-user" },
{ name = "nonebot-plugin-userinfo" },
{ name = "nonebot-plugin-waiter" },
{ name = "nonebot2", extra = ["fastapi"] },
{ name = "pandas" },
{ name = "pillow" },
@@ -1845,7 +1846,7 @@ dependencies = [
{ name = "yarl" },
]
[package.dependency-groups]
[package.dev-dependencies]
debug = [
{ name = "matplotlib" },
{ name = "memory-profiler" },
@@ -1898,6 +1899,7 @@ requires-dist = [
{ name = "nonebot-plugin-session-orm", specifier = ">=0.2.0" },
{ name = "nonebot-plugin-user", specifier = ">=0.4.4" },
{ name = "nonebot-plugin-userinfo", specifier = ">=0.2.6" },
{ name = "nonebot-plugin-waiter", specifier = ">=0.8.0" },
{ name = "nonebot2", extras = ["fastapi"], specifier = ">=2.3.3" },
{ name = "pandas", specifier = ">=2.2.3" },
{ name = "pillow", specifier = ">=11.0.0" },
@@ -1906,7 +1908,7 @@ requires-dist = [
{ name = "yarl", specifier = ">=1.16.0" },
]
[package.metadata.dependency-groups]
[package.metadata.requires-dev]
debug = [
{ name = "matplotlib", specifier = ">=3.9.2" },
{ name = "memory-profiler", specifier = ">=0.61.0" },