mirror of
https://github.com/suyiiyii/nonebot-bison.git
synced 2025-06-04 02:26:11 +08:00
🚚 reorganize config_manager
This commit is contained in:
parent
8a20897fe9
commit
6743929ca2
@ -1,411 +0,0 @@
|
||||
import asyncio
|
||||
from datetime import datetime
|
||||
from typing import Annotated, Optional, Type, cast
|
||||
|
||||
from nonebot import logger, on_command
|
||||
from nonebot.adapters import Bot, Event
|
||||
from nonebot.adapters.onebot.v11 import MessageEvent
|
||||
from nonebot.adapters.onebot.v11.event import GroupMessageEvent, PrivateMessageEvent
|
||||
from nonebot.adapters.onebot.v11.message import Message
|
||||
from nonebot.adapters.onebot.v11.permission import GROUP_ADMIN, GROUP_OWNER
|
||||
from nonebot.adapters.onebot.v11.utils import unescape
|
||||
from nonebot.internal.params import ArgStr
|
||||
from nonebot.internal.rule import Rule
|
||||
from nonebot.matcher import Matcher
|
||||
from nonebot.params import ArgPlainText, Depends, EventPlainText, EventToMe
|
||||
from nonebot.permission import SUPERUSER
|
||||
from nonebot.rule import to_me
|
||||
from nonebot.typing import T_State
|
||||
from nonebot_plugin_saa import (
|
||||
MessageFactory,
|
||||
PlatformTarget,
|
||||
TargetQQGroup,
|
||||
extract_target,
|
||||
)
|
||||
|
||||
from .apis import check_sub_target
|
||||
from .config import config
|
||||
from .config.db_config import SubscribeDupException
|
||||
from .platform import Platform, platform_manager
|
||||
from .plugin_config import plugin_config
|
||||
from .types import Category, Target
|
||||
from .utils import parse_text
|
||||
|
||||
|
||||
def _configurable_to_me(to_me: bool = EventToMe()):
|
||||
if plugin_config.bison_to_me:
|
||||
return to_me
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
configurable_to_me = Rule(_configurable_to_me)
|
||||
|
||||
|
||||
common_platform = [
|
||||
p.platform_name
|
||||
for p in filter(
|
||||
lambda platform: platform.enabled and platform.is_common,
|
||||
platform_manager.values(),
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
def ensure_user_info(matcher: Type[Matcher]):
|
||||
async def _check_user_info(state: T_State):
|
||||
if not state.get("target_user_info"):
|
||||
await matcher.finish(
|
||||
"No target_user_info set, this shouldn't happen, please issue"
|
||||
)
|
||||
|
||||
return _check_user_info
|
||||
|
||||
|
||||
async def set_target_user_info(event: Event, state: T_State):
|
||||
user = extract_target(event)
|
||||
state["target_user_info"] = user
|
||||
|
||||
|
||||
def gen_handle_cancel(matcher: Type[Matcher], message: str):
|
||||
async def _handle_cancel(text: Annotated[str, EventPlainText()]):
|
||||
if text == "取消":
|
||||
await matcher.finish(message)
|
||||
|
||||
return Depends(_handle_cancel)
|
||||
|
||||
|
||||
def do_add_sub(add_sub: Type[Matcher]):
|
||||
handle_cancel = gen_handle_cancel(add_sub, "已中止订阅")
|
||||
|
||||
add_sub.handle()(ensure_user_info(add_sub))
|
||||
|
||||
@add_sub.handle()
|
||||
async def init_promote(state: T_State):
|
||||
state["_prompt"] = (
|
||||
"请输入想要订阅的平台,目前支持,请输入冒号左边的名称:\n"
|
||||
+ "".join(
|
||||
[
|
||||
"{}:{}\n".format(
|
||||
platform_name, platform_manager[platform_name].name
|
||||
)
|
||||
for platform_name in common_platform
|
||||
]
|
||||
)
|
||||
+ "要查看全部平台请输入:“全部”\n中止订阅过程请输入:“取消”"
|
||||
)
|
||||
|
||||
@add_sub.got("platform", Message.template("{_prompt}"), [handle_cancel])
|
||||
async def parse_platform(state: T_State, platform: str = ArgPlainText()) -> None:
|
||||
if not isinstance(state["platform"], Message):
|
||||
return
|
||||
if platform == "全部":
|
||||
message = "全部平台\n" + "\n".join(
|
||||
[
|
||||
"{}:{}".format(platform_name, platform.name)
|
||||
for platform_name, platform in platform_manager.items()
|
||||
]
|
||||
)
|
||||
await add_sub.reject(message)
|
||||
elif platform == "取消":
|
||||
await add_sub.finish("已中止订阅")
|
||||
elif platform in platform_manager:
|
||||
state["platform"] = platform
|
||||
else:
|
||||
await add_sub.reject("平台输入错误")
|
||||
|
||||
@add_sub.handle()
|
||||
async def prepare_get_id(matcher: Matcher, state: T_State):
|
||||
cur_platform = platform_manager[state["platform"]]
|
||||
if cur_platform.has_target:
|
||||
state["_prompt"] = (
|
||||
("1." + cur_platform.parse_target_promot + "\n2.")
|
||||
if cur_platform.parse_target_promot
|
||||
else ""
|
||||
) + "请输入订阅用户的id\n查询id获取方法请回复:“查询”"
|
||||
else:
|
||||
matcher.set_arg("raw_id", Message("no id"))
|
||||
state["id"] = "default"
|
||||
state["name"] = await check_sub_target(state["platform"], Target(""))
|
||||
|
||||
@add_sub.got("raw_id", Message.template("{_prompt}"), [handle_cancel])
|
||||
async def got_id(state: T_State, raw_id: str = ArgPlainText()):
|
||||
if state.get("id"):
|
||||
return
|
||||
try:
|
||||
if raw_id == "查询":
|
||||
url = "https://nonebot-bison.netlify.app/usage/#%E6%89%80%E6%94%AF%E6%8C%81%E5%B9%B3%E5%8F%B0%E7%9A%84-uid"
|
||||
title = "Bison所支持的平台UID"
|
||||
content = "查询相关平台的uid格式或获取方式"
|
||||
image = "https://s3.bmp.ovh/imgs/2022/03/ab3cc45d83bd3dd3.jpg"
|
||||
getId_share = f"[CQ:share,url={url},title={title},content={content},image={image}]" # 缩短字符串格式长度,以及方便后续修改为消息段格式
|
||||
await add_sub.reject(Message(getId_share))
|
||||
platform = platform_manager[state["platform"]]
|
||||
raw_id = await platform.parse_target(unescape(raw_id))
|
||||
name = await check_sub_target(state["platform"], raw_id)
|
||||
if not name:
|
||||
await add_sub.reject("id输入错误")
|
||||
state["id"] = raw_id
|
||||
state["name"] = name
|
||||
except (Platform.ParseTargetException):
|
||||
await add_sub.reject("不能从你的输入中提取出id,请检查你输入的内容是否符合预期")
|
||||
else:
|
||||
await add_sub.send(
|
||||
"即将订阅的用户为:{} {} {}\n如有错误请输入“取消”重新订阅".format(
|
||||
state["platform"], state["name"], state["id"]
|
||||
)
|
||||
)
|
||||
|
||||
@add_sub.handle()
|
||||
async def prepare_get_categories(matcher: Matcher, state: T_State):
|
||||
if not platform_manager[state["platform"]].categories:
|
||||
matcher.set_arg("raw_cats", Message(""))
|
||||
state["cats"] = []
|
||||
return
|
||||
state["_prompt"] = "请输入要订阅的类别,以空格分隔,支持的类别有:{}".format(
|
||||
" ".join(list(platform_manager[state["platform"]].categories.values()))
|
||||
)
|
||||
|
||||
@add_sub.got("raw_cats", Message.template("{_prompt}"), [handle_cancel])
|
||||
async def parser_cats(state: T_State, raw_cats: str = ArgPlainText()):
|
||||
if "cats" in state.keys():
|
||||
return
|
||||
res = []
|
||||
if platform_manager[state["platform"]].categories:
|
||||
for cat in raw_cats.split():
|
||||
if cat not in platform_manager[state["platform"]].reverse_category:
|
||||
await add_sub.reject("不支持 {}".format(cat))
|
||||
res.append(platform_manager[state["platform"]].reverse_category[cat])
|
||||
state["cats"] = res
|
||||
|
||||
@add_sub.handle()
|
||||
async def prepare_get_tags(matcher: Matcher, state: T_State):
|
||||
if not platform_manager[state["platform"]].enable_tag:
|
||||
matcher.set_arg("raw_tags", Message(""))
|
||||
state["tags"] = []
|
||||
return
|
||||
state["_prompt"] = '请输入要订阅/屏蔽的标签(不含#号)\n多个标签请使用空格隔开\n订阅所有标签输入"全部标签"\n具体规则回复"详情"'
|
||||
|
||||
@add_sub.got("raw_tags", Message.template("{_prompt}"), [handle_cancel])
|
||||
async def parser_tags(state: T_State, raw_tags: str = ArgPlainText()):
|
||||
if "tags" in state.keys():
|
||||
return
|
||||
if raw_tags == "详情":
|
||||
await add_sub.reject(
|
||||
"订阅标签直接输入标签内容\n屏蔽标签请在标签名称前添加~号\n详见https://nonebot-bison.netlify.app/usage/#%E5%B9%B3%E5%8F%B0%E8%AE%A2%E9%98%85%E6%A0%87%E7%AD%BE-tag"
|
||||
)
|
||||
if raw_tags in ["全部标签", "全部", "全标签"]:
|
||||
state["tags"] = []
|
||||
else:
|
||||
state["tags"] = raw_tags.split()
|
||||
|
||||
@add_sub.handle()
|
||||
async def add_sub_process(state: T_State):
|
||||
user = cast(PlatformTarget, state.get("target_user_info"))
|
||||
assert isinstance(user, PlatformTarget)
|
||||
try:
|
||||
await config.add_subscribe(
|
||||
user=user,
|
||||
target=state["id"],
|
||||
target_name=state["name"],
|
||||
platform_name=state["platform"],
|
||||
cats=state.get("cats", []),
|
||||
tags=state.get("tags", []),
|
||||
)
|
||||
except SubscribeDupException:
|
||||
await add_sub.finish(f"添加 {state['name']} 失败: 已存在该订阅")
|
||||
except Exception as e:
|
||||
await add_sub.finish(f"添加 {state['name']} 失败: {e}")
|
||||
await add_sub.finish("添加 {} 成功".format(state["name"]))
|
||||
|
||||
|
||||
def do_query_sub(query_sub: Type[Matcher]):
|
||||
query_sub.handle()(ensure_user_info(query_sub))
|
||||
|
||||
@query_sub.handle()
|
||||
async def _(bot: Bot, state: T_State):
|
||||
user_info = state["target_user_info"]
|
||||
assert isinstance(user_info, PlatformTarget)
|
||||
sub_list = await config.list_subscribe(user_info)
|
||||
res = "订阅的帐号为:\n"
|
||||
for sub in sub_list:
|
||||
res += "{} {} {}".format(
|
||||
# sub["target_type"], sub["target_name"], sub["target"]
|
||||
sub.target.platform_name,
|
||||
sub.target.target_name,
|
||||
sub.target.target,
|
||||
)
|
||||
platform = platform_manager[sub.target.platform_name]
|
||||
if platform.categories:
|
||||
res += " [{}]".format(
|
||||
", ".join(
|
||||
map(lambda x: platform.categories[Category(x)], sub.categories)
|
||||
)
|
||||
)
|
||||
if platform.enable_tag:
|
||||
res += " {}".format(", ".join(sub.tags))
|
||||
res += "\n"
|
||||
await MessageFactory(await parse_text(res)).send()
|
||||
await query_sub.finish()
|
||||
|
||||
|
||||
def do_del_sub(del_sub: Type[Matcher]):
|
||||
handle_cancel = gen_handle_cancel(del_sub, "删除中止")
|
||||
|
||||
del_sub.handle()(ensure_user_info(del_sub))
|
||||
|
||||
@del_sub.handle()
|
||||
async def send_list(bot: Bot, event: Event, state: T_State):
|
||||
user_info = state["target_user_info"]
|
||||
assert isinstance(user_info, PlatformTarget)
|
||||
try:
|
||||
sub_list = await config.list_subscribe(user_info)
|
||||
assert sub_list
|
||||
except AssertionError:
|
||||
await del_sub.finish("暂无已订阅账号\n请使用“添加订阅”命令添加订阅")
|
||||
else:
|
||||
res = "订阅的帐号为:\n"
|
||||
state["sub_table"] = {}
|
||||
for index, sub in enumerate(sub_list, 1):
|
||||
state["sub_table"][index] = {
|
||||
"platform_name": sub.target.platform_name,
|
||||
"target": sub.target.target,
|
||||
}
|
||||
res += "{} {} {} {}\n".format(
|
||||
index,
|
||||
sub.target.platform_name,
|
||||
sub.target.target_name,
|
||||
sub.target.target,
|
||||
)
|
||||
platform = platform_manager[sub.target.platform_name]
|
||||
if platform.categories:
|
||||
res += " [{}]".format(
|
||||
", ".join(
|
||||
map(
|
||||
lambda x: platform.categories[Category(x)],
|
||||
sub.categories,
|
||||
)
|
||||
)
|
||||
)
|
||||
if platform.enable_tag:
|
||||
res += " {}".format(", ".join(sub.tags))
|
||||
res += "\n"
|
||||
res += "请输入要删除的订阅的序号\n输入'取消'中止"
|
||||
await MessageFactory(await parse_text(res)).send()
|
||||
|
||||
@del_sub.receive(parameterless=[handle_cancel])
|
||||
async def do_del(state: T_State, index_str: str = EventPlainText()):
|
||||
try:
|
||||
index = int(index_str)
|
||||
user_info = state["target_user_info"]
|
||||
assert isinstance(user_info, PlatformTarget)
|
||||
await config.del_subscribe(user_info, **state["sub_table"][index])
|
||||
except Exception as e:
|
||||
await del_sub.reject("删除错误")
|
||||
else:
|
||||
await del_sub.finish("删除成功")
|
||||
|
||||
|
||||
add_sub_matcher = on_command(
|
||||
"添加订阅",
|
||||
rule=configurable_to_me,
|
||||
permission=GROUP_ADMIN | GROUP_OWNER | SUPERUSER,
|
||||
priority=5,
|
||||
block=True,
|
||||
)
|
||||
add_sub_matcher.handle()(set_target_user_info)
|
||||
do_add_sub(add_sub_matcher)
|
||||
|
||||
|
||||
query_sub_matcher = on_command("查询订阅", rule=configurable_to_me, priority=5, block=True)
|
||||
query_sub_matcher.handle()(set_target_user_info)
|
||||
do_query_sub(query_sub_matcher)
|
||||
|
||||
|
||||
del_sub_matcher = on_command(
|
||||
"删除订阅",
|
||||
rule=configurable_to_me,
|
||||
permission=GROUP_ADMIN | GROUP_OWNER | SUPERUSER,
|
||||
priority=5,
|
||||
block=True,
|
||||
)
|
||||
del_sub_matcher.handle()(set_target_user_info)
|
||||
do_del_sub(del_sub_matcher)
|
||||
|
||||
group_manage_matcher = on_command(
|
||||
"群管理", rule=to_me(), permission=SUPERUSER, priority=4, block=True
|
||||
)
|
||||
|
||||
group_handle_cancel = gen_handle_cancel(group_manage_matcher, "已取消")
|
||||
|
||||
|
||||
@group_manage_matcher.handle()
|
||||
async def send_group_list_private(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
await group_manage_matcher.finish(Message("该功能只支持私聊使用,请私聊Bot"))
|
||||
|
||||
|
||||
@group_manage_matcher.handle()
|
||||
async def send_group_list(bot: Bot, event: PrivateMessageEvent, state: T_State):
|
||||
groups = await bot.call_api("get_group_list")
|
||||
res_text = "请选择需要管理的群:\n"
|
||||
group_number_idx = {}
|
||||
for idx, group in enumerate(groups, 1):
|
||||
group_number_idx[idx] = group["group_id"]
|
||||
res_text += f'{idx}. {group["group_id"]} - {group["group_name"]}\n'
|
||||
res_text += "请输入左侧序号\n中止操作请输入'取消'"
|
||||
# await group_manage_matcher.send(res_text)
|
||||
state["_prompt"] = res_text
|
||||
state["group_number_idx"] = group_number_idx
|
||||
|
||||
|
||||
@group_manage_matcher.got(
|
||||
"group_idx", Message.template("{_prompt}"), [group_handle_cancel]
|
||||
)
|
||||
async def do_choose_group_number(state: T_State, group_idx: str = ArgPlainText()):
|
||||
group_number_idx: dict[int, int] = state["group_number_idx"]
|
||||
assert group_number_idx
|
||||
idx = int(group_idx)
|
||||
if idx not in group_number_idx.keys():
|
||||
await group_manage_matcher.reject("请输入正确序号")
|
||||
state["group_idx"] = idx
|
||||
group_number_idx: dict[int, int] = state["group_number_idx"]
|
||||
idx: int = state["group_idx"]
|
||||
group_id = group_number_idx[idx]
|
||||
state["target_user_info"] = TargetQQGroup(group_id=group_id)
|
||||
|
||||
|
||||
@group_manage_matcher.got(
|
||||
"command", "请输入需要使用的命令:添加订阅,查询订阅,删除订阅,取消", [group_handle_cancel]
|
||||
)
|
||||
async def do_dispatch_command(
|
||||
bot: Bot,
|
||||
event: MessageEvent,
|
||||
state: T_State,
|
||||
matcher: Matcher,
|
||||
command: str = ArgStr(),
|
||||
):
|
||||
if command not in {"添加订阅", "查询订阅", "删除订阅", "取消"}:
|
||||
await group_manage_matcher.reject("请输入正确的命令")
|
||||
permission = await matcher.update_permission(bot, event)
|
||||
new_matcher = Matcher.new(
|
||||
"message",
|
||||
Rule(),
|
||||
permission,
|
||||
handlers=None,
|
||||
temp=True,
|
||||
priority=0,
|
||||
block=True,
|
||||
plugin=matcher.plugin,
|
||||
module=matcher.module,
|
||||
expire_time=datetime.now(),
|
||||
default_state=matcher.state,
|
||||
default_type_updater=matcher.__class__._default_type_updater,
|
||||
default_permission_updater=matcher.__class__._default_permission_updater,
|
||||
)
|
||||
if command == "查询订阅":
|
||||
do_query_sub(new_matcher)
|
||||
elif command == "添加订阅":
|
||||
do_add_sub(new_matcher)
|
||||
else:
|
||||
do_del_sub(new_matcher)
|
||||
new_matcher_ins = new_matcher()
|
||||
asyncio.create_task(new_matcher_ins.run(bot, event, state))
|
130
nonebot_bison/config_manager/__init__.py
Normal file
130
nonebot_bison/config_manager/__init__.py
Normal file
@ -0,0 +1,130 @@
|
||||
import asyncio
|
||||
from datetime import datetime
|
||||
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters import Bot
|
||||
from nonebot.adapters.onebot.v11 import MessageEvent
|
||||
from nonebot.adapters.onebot.v11.event import GroupMessageEvent, PrivateMessageEvent
|
||||
from nonebot.adapters.onebot.v11.message import Message
|
||||
from nonebot.adapters.onebot.v11.permission import GROUP_ADMIN, GROUP_OWNER
|
||||
from nonebot.matcher import Matcher
|
||||
from nonebot.params import ArgPlainText, ArgStr
|
||||
from nonebot.permission import SUPERUSER
|
||||
from nonebot.rule import Rule, to_me
|
||||
from nonebot.typing import T_State
|
||||
from nonebot_plugin_saa import TargetQQGroup
|
||||
|
||||
from .add_sub import do_add_sub
|
||||
from .del_sub import do_del_sub
|
||||
from .query_sub import do_query_sub
|
||||
from .utils import (
|
||||
common_platform,
|
||||
configurable_to_me,
|
||||
gen_handle_cancel,
|
||||
set_target_user_info,
|
||||
)
|
||||
|
||||
add_sub_matcher = on_command(
|
||||
"添加订阅",
|
||||
rule=configurable_to_me,
|
||||
permission=GROUP_ADMIN | GROUP_OWNER | SUPERUSER,
|
||||
priority=5,
|
||||
block=True,
|
||||
)
|
||||
add_sub_matcher.handle()(set_target_user_info)
|
||||
do_add_sub(add_sub_matcher)
|
||||
|
||||
|
||||
query_sub_matcher = on_command("查询订阅", rule=configurable_to_me, priority=5, block=True)
|
||||
query_sub_matcher.handle()(set_target_user_info)
|
||||
do_query_sub(query_sub_matcher)
|
||||
|
||||
|
||||
del_sub_matcher = on_command(
|
||||
"删除订阅",
|
||||
rule=configurable_to_me,
|
||||
permission=GROUP_ADMIN | GROUP_OWNER | SUPERUSER,
|
||||
priority=5,
|
||||
block=True,
|
||||
)
|
||||
del_sub_matcher.handle()(set_target_user_info)
|
||||
do_del_sub(del_sub_matcher)
|
||||
|
||||
group_manage_matcher = on_command(
|
||||
"群管理", rule=to_me(), permission=SUPERUSER, priority=4, block=True
|
||||
)
|
||||
|
||||
group_handle_cancel = gen_handle_cancel(group_manage_matcher, "已取消")
|
||||
|
||||
|
||||
@group_manage_matcher.handle()
|
||||
async def send_group_list_private(event: GroupMessageEvent, state: T_State):
|
||||
await group_manage_matcher.finish(Message("该功能只支持私聊使用,请私聊Bot"))
|
||||
|
||||
|
||||
@group_manage_matcher.handle()
|
||||
async def send_group_list(bot: Bot, event: PrivateMessageEvent, state: T_State):
|
||||
groups = await bot.call_api("get_group_list")
|
||||
res_text = "请选择需要管理的群:\n"
|
||||
group_number_idx = {}
|
||||
for idx, group in enumerate(groups, 1):
|
||||
group_number_idx[idx] = group["group_id"]
|
||||
res_text += f'{idx}. {group["group_id"]} - {group["group_name"]}\n'
|
||||
res_text += "请输入左侧序号\n中止操作请输入'取消'"
|
||||
# await group_manage_matcher.send(res_text)
|
||||
state["_prompt"] = res_text
|
||||
state["group_number_idx"] = group_number_idx
|
||||
|
||||
|
||||
@group_manage_matcher.got(
|
||||
"group_idx", Message.template("{_prompt}"), [group_handle_cancel]
|
||||
)
|
||||
async def do_choose_group_number(state: T_State, group_idx: str = ArgPlainText()):
|
||||
group_number_idx: dict[int, int] = state["group_number_idx"]
|
||||
assert group_number_idx
|
||||
idx = int(group_idx)
|
||||
if idx not in group_number_idx.keys():
|
||||
await group_manage_matcher.reject("请输入正确序号")
|
||||
state["group_idx"] = idx
|
||||
group_number_idx: dict[int, int] = state["group_number_idx"]
|
||||
idx: int = state["group_idx"]
|
||||
group_id = group_number_idx[idx]
|
||||
state["target_user_info"] = TargetQQGroup(group_id=group_id)
|
||||
|
||||
|
||||
@group_manage_matcher.got(
|
||||
"command", "请输入需要使用的命令:添加订阅,查询订阅,删除订阅,取消", [group_handle_cancel]
|
||||
)
|
||||
async def do_dispatch_command(
|
||||
bot: Bot,
|
||||
event: MessageEvent,
|
||||
state: T_State,
|
||||
matcher: Matcher,
|
||||
command: str = ArgStr(),
|
||||
):
|
||||
if command not in {"添加订阅", "查询订阅", "删除订阅", "取消"}:
|
||||
await group_manage_matcher.reject("请输入正确的命令")
|
||||
permission = await matcher.update_permission(bot, event)
|
||||
new_matcher = Matcher.new(
|
||||
"message",
|
||||
Rule(),
|
||||
permission,
|
||||
handlers=None,
|
||||
temp=True,
|
||||
priority=0,
|
||||
block=True,
|
||||
plugin=matcher.plugin,
|
||||
module=matcher.module,
|
||||
expire_time=datetime.now(),
|
||||
default_state=matcher.state,
|
||||
default_type_updater=matcher.__class__._default_type_updater,
|
||||
default_permission_updater=matcher.__class__._default_permission_updater,
|
||||
)
|
||||
if command == "查询订阅":
|
||||
do_query_sub(new_matcher)
|
||||
elif command == "添加订阅":
|
||||
do_add_sub(new_matcher)
|
||||
else:
|
||||
do_del_sub(new_matcher)
|
||||
new_matcher_ins = new_matcher()
|
||||
asyncio.create_task(new_matcher_ins.run(bot, event, state))
|
160
nonebot_bison/config_manager/add_sub.py
Normal file
160
nonebot_bison/config_manager/add_sub.py
Normal file
@ -0,0 +1,160 @@
|
||||
from typing import Type, cast
|
||||
|
||||
from nonebot.adapters import Message
|
||||
from nonebot.adapters.onebot.v11 import Message as OB11Message
|
||||
from nonebot.adapters.onebot.v11.utils import unescape
|
||||
from nonebot.matcher import Matcher
|
||||
from nonebot.params import ArgPlainText
|
||||
from nonebot.typing import T_State
|
||||
from nonebot_plugin_saa import PlatformTarget
|
||||
|
||||
from ..apis import check_sub_target
|
||||
from ..config import config
|
||||
from ..config.db_config import SubscribeDupException
|
||||
from ..platform import Platform, platform_manager
|
||||
from ..types import Target
|
||||
from .utils import common_platform, ensure_user_info, gen_handle_cancel
|
||||
|
||||
|
||||
def do_add_sub(add_sub: Type[Matcher]):
|
||||
handle_cancel = gen_handle_cancel(add_sub, "已中止订阅")
|
||||
|
||||
add_sub.handle()(ensure_user_info(add_sub))
|
||||
|
||||
@add_sub.handle()
|
||||
async def init_promote(state: T_State):
|
||||
state["_prompt"] = (
|
||||
"请输入想要订阅的平台,目前支持,请输入冒号左边的名称:\n"
|
||||
+ "".join(
|
||||
[
|
||||
"{}:{}\n".format(
|
||||
platform_name, platform_manager[platform_name].name
|
||||
)
|
||||
for platform_name in common_platform
|
||||
]
|
||||
)
|
||||
+ "要查看全部平台请输入:“全部”\n中止订阅过程请输入:“取消”"
|
||||
)
|
||||
|
||||
@add_sub.got("platform", OB11Message.template("{_prompt}"), [handle_cancel])
|
||||
async def parse_platform(state: T_State, platform: str = ArgPlainText()) -> None:
|
||||
if not isinstance(state["platform"], Message):
|
||||
return
|
||||
if platform == "全部":
|
||||
message = "全部平台\n" + "\n".join(
|
||||
[
|
||||
"{}:{}".format(platform_name, platform.name)
|
||||
for platform_name, platform in platform_manager.items()
|
||||
]
|
||||
)
|
||||
await add_sub.reject(message)
|
||||
elif platform == "取消":
|
||||
await add_sub.finish("已中止订阅")
|
||||
elif platform in platform_manager:
|
||||
state["platform"] = platform
|
||||
else:
|
||||
await add_sub.reject("平台输入错误")
|
||||
|
||||
@add_sub.handle()
|
||||
async def prepare_get_id(matcher: Matcher, state: T_State):
|
||||
cur_platform = platform_manager[state["platform"]]
|
||||
if cur_platform.has_target:
|
||||
state["_prompt"] = (
|
||||
("1." + cur_platform.parse_target_promot + "\n2.")
|
||||
if cur_platform.parse_target_promot
|
||||
else ""
|
||||
) + "请输入订阅用户的id\n查询id获取方法请回复:“查询”"
|
||||
else:
|
||||
matcher.set_arg("raw_id", OB11Message("no id"))
|
||||
state["id"] = "default"
|
||||
state["name"] = await check_sub_target(state["platform"], Target(""))
|
||||
|
||||
@add_sub.got("raw_id", OB11Message.template("{_prompt}"), [handle_cancel])
|
||||
async def got_id(state: T_State, raw_id: str = ArgPlainText()):
|
||||
if state.get("id"):
|
||||
return
|
||||
try:
|
||||
if raw_id == "查询":
|
||||
url = "https://nonebot-bison.netlify.app/usage/#%E6%89%80%E6%94%AF%E6%8C%81%E5%B9%B3%E5%8F%B0%E7%9A%84-uid"
|
||||
title = "Bison所支持的平台UID"
|
||||
content = "查询相关平台的uid格式或获取方式"
|
||||
image = "https://s3.bmp.ovh/imgs/2022/03/ab3cc45d83bd3dd3.jpg"
|
||||
getId_share = f"[CQ:share,url={url},title={title},content={content},image={image}]" # 缩短字符串格式长度,以及方便后续修改为消息段格式
|
||||
await add_sub.reject(OB11Message(getId_share))
|
||||
platform = platform_manager[state["platform"]]
|
||||
raw_id = await platform.parse_target(unescape(raw_id))
|
||||
name = await check_sub_target(state["platform"], raw_id)
|
||||
if not name:
|
||||
await add_sub.reject("id输入错误")
|
||||
state["id"] = raw_id
|
||||
state["name"] = name
|
||||
except (Platform.ParseTargetException):
|
||||
await add_sub.reject("不能从你的输入中提取出id,请检查你输入的内容是否符合预期")
|
||||
else:
|
||||
await add_sub.send(
|
||||
"即将订阅的用户为:{} {} {}\n如有错误请输入“取消”重新订阅".format(
|
||||
state["platform"], state["name"], state["id"]
|
||||
)
|
||||
)
|
||||
|
||||
@add_sub.handle()
|
||||
async def prepare_get_categories(matcher: Matcher, state: T_State):
|
||||
if not platform_manager[state["platform"]].categories:
|
||||
matcher.set_arg("raw_cats", OB11Message(""))
|
||||
state["cats"] = []
|
||||
return
|
||||
state["_prompt"] = "请输入要订阅的类别,以空格分隔,支持的类别有:{}".format(
|
||||
" ".join(list(platform_manager[state["platform"]].categories.values()))
|
||||
)
|
||||
|
||||
@add_sub.got("raw_cats", OB11Message.template("{_prompt}"), [handle_cancel])
|
||||
async def parser_cats(state: T_State, raw_cats: str = ArgPlainText()):
|
||||
if "cats" in state.keys():
|
||||
return
|
||||
res = []
|
||||
if platform_manager[state["platform"]].categories:
|
||||
for cat in raw_cats.split():
|
||||
if cat not in platform_manager[state["platform"]].reverse_category:
|
||||
await add_sub.reject("不支持 {}".format(cat))
|
||||
res.append(platform_manager[state["platform"]].reverse_category[cat])
|
||||
state["cats"] = res
|
||||
|
||||
@add_sub.handle()
|
||||
async def prepare_get_tags(matcher: Matcher, state: T_State):
|
||||
if not platform_manager[state["platform"]].enable_tag:
|
||||
matcher.set_arg("raw_tags", OB11Message(""))
|
||||
state["tags"] = []
|
||||
return
|
||||
state["_prompt"] = '请输入要订阅/屏蔽的标签(不含#号)\n多个标签请使用空格隔开\n订阅所有标签输入"全部标签"\n具体规则回复"详情"'
|
||||
|
||||
@add_sub.got("raw_tags", OB11Message.template("{_prompt}"), [handle_cancel])
|
||||
async def parser_tags(state: T_State, raw_tags: str = ArgPlainText()):
|
||||
if "tags" in state.keys():
|
||||
return
|
||||
if raw_tags == "详情":
|
||||
await add_sub.reject(
|
||||
"订阅标签直接输入标签内容\n屏蔽标签请在标签名称前添加~号\n详见https://nonebot-bison.netlify.app/usage/#%E5%B9%B3%E5%8F%B0%E8%AE%A2%E9%98%85%E6%A0%87%E7%AD%BE-tag"
|
||||
)
|
||||
if raw_tags in ["全部标签", "全部", "全标签"]:
|
||||
state["tags"] = []
|
||||
else:
|
||||
state["tags"] = raw_tags.split()
|
||||
|
||||
@add_sub.handle()
|
||||
async def add_sub_process(state: T_State):
|
||||
user = cast(PlatformTarget, state.get("target_user_info"))
|
||||
assert isinstance(user, PlatformTarget)
|
||||
try:
|
||||
await config.add_subscribe(
|
||||
user=user,
|
||||
target=state["id"],
|
||||
target_name=state["name"],
|
||||
platform_name=state["platform"],
|
||||
cats=state.get("cats", []),
|
||||
tags=state.get("tags", []),
|
||||
)
|
||||
except SubscribeDupException:
|
||||
await add_sub.finish(f"添加 {state['name']} 失败: 已存在该订阅")
|
||||
except Exception as e:
|
||||
await add_sub.finish(f"添加 {state['name']} 失败: {e}")
|
||||
await add_sub.finish("添加 {} 成功".format(state["name"]))
|
69
nonebot_bison/config_manager/del_sub.py
Normal file
69
nonebot_bison/config_manager/del_sub.py
Normal file
@ -0,0 +1,69 @@
|
||||
from typing import Type
|
||||
|
||||
from nonebot.matcher import Matcher
|
||||
from nonebot.params import EventPlainText
|
||||
from nonebot.typing import T_State
|
||||
from nonebot_plugin_saa import MessageFactory, PlatformTarget
|
||||
|
||||
from ..config import config
|
||||
from ..platform import platform_manager
|
||||
from ..types import Category
|
||||
from ..utils import parse_text
|
||||
from .utils import ensure_user_info, gen_handle_cancel
|
||||
|
||||
|
||||
def do_del_sub(del_sub: Type[Matcher]):
|
||||
handle_cancel = gen_handle_cancel(del_sub, "删除中止")
|
||||
|
||||
del_sub.handle()(ensure_user_info(del_sub))
|
||||
|
||||
@del_sub.handle()
|
||||
async def send_list(state: T_State):
|
||||
user_info = state["target_user_info"]
|
||||
assert isinstance(user_info, PlatformTarget)
|
||||
try:
|
||||
sub_list = await config.list_subscribe(user_info)
|
||||
assert sub_list
|
||||
except AssertionError:
|
||||
await del_sub.finish("暂无已订阅账号\n请使用“添加订阅”命令添加订阅")
|
||||
else:
|
||||
res = "订阅的帐号为:\n"
|
||||
state["sub_table"] = {}
|
||||
for index, sub in enumerate(sub_list, 1):
|
||||
state["sub_table"][index] = {
|
||||
"platform_name": sub.target.platform_name,
|
||||
"target": sub.target.target,
|
||||
}
|
||||
res += "{} {} {} {}\n".format(
|
||||
index,
|
||||
sub.target.platform_name,
|
||||
sub.target.target_name,
|
||||
sub.target.target,
|
||||
)
|
||||
platform = platform_manager[sub.target.platform_name]
|
||||
if platform.categories:
|
||||
res += " [{}]".format(
|
||||
", ".join(
|
||||
map(
|
||||
lambda x: platform.categories[Category(x)],
|
||||
sub.categories,
|
||||
)
|
||||
)
|
||||
)
|
||||
if platform.enable_tag:
|
||||
res += " {}".format(", ".join(sub.tags))
|
||||
res += "\n"
|
||||
res += "请输入要删除的订阅的序号\n输入'取消'中止"
|
||||
await MessageFactory(await parse_text(res)).send()
|
||||
|
||||
@del_sub.receive(parameterless=[handle_cancel])
|
||||
async def do_del(state: T_State, index_str: str = EventPlainText()):
|
||||
try:
|
||||
index = int(index_str)
|
||||
user_info = state["target_user_info"]
|
||||
assert isinstance(user_info, PlatformTarget)
|
||||
await config.del_subscribe(user_info, **state["sub_table"][index])
|
||||
except Exception as e:
|
||||
await del_sub.reject("删除错误")
|
||||
else:
|
||||
await del_sub.finish("删除成功")
|
41
nonebot_bison/config_manager/query_sub.py
Normal file
41
nonebot_bison/config_manager/query_sub.py
Normal file
@ -0,0 +1,41 @@
|
||||
from typing import Type
|
||||
|
||||
from nonebot.matcher import Matcher
|
||||
from nonebot.typing import T_State
|
||||
from nonebot_plugin_saa import MessageFactory, PlatformTarget
|
||||
|
||||
from ..config import config
|
||||
from ..platform import platform_manager
|
||||
from ..types import Category
|
||||
from ..utils import parse_text
|
||||
from .utils import ensure_user_info
|
||||
|
||||
|
||||
def do_query_sub(query_sub: Type[Matcher]):
|
||||
query_sub.handle()(ensure_user_info(query_sub))
|
||||
|
||||
@query_sub.handle()
|
||||
async def _(state: T_State):
|
||||
user_info = state["target_user_info"]
|
||||
assert isinstance(user_info, PlatformTarget)
|
||||
sub_list = await config.list_subscribe(user_info)
|
||||
res = "订阅的帐号为:\n"
|
||||
for sub in sub_list:
|
||||
res += "{} {} {}".format(
|
||||
# sub["target_type"], sub["target_name"], sub["target"]
|
||||
sub.target.platform_name,
|
||||
sub.target.target_name,
|
||||
sub.target.target,
|
||||
)
|
||||
platform = platform_manager[sub.target.platform_name]
|
||||
if platform.categories:
|
||||
res += " [{}]".format(
|
||||
", ".join(
|
||||
map(lambda x: platform.categories[Category(x)], sub.categories)
|
||||
)
|
||||
)
|
||||
if platform.enable_tag:
|
||||
res += " {}".format(", ".join(sub.tags))
|
||||
res += "\n"
|
||||
await MessageFactory(await parse_text(res)).send()
|
||||
await query_sub.finish()
|
52
nonebot_bison/config_manager/utils.py
Normal file
52
nonebot_bison/config_manager/utils.py
Normal file
@ -0,0 +1,52 @@
|
||||
from typing import Annotated, Type
|
||||
|
||||
from nonebot.adapters import Event
|
||||
from nonebot.matcher import Matcher
|
||||
from nonebot.params import Depends, EventPlainText, EventToMe
|
||||
from nonebot.rule import Rule
|
||||
from nonebot.typing import T_State
|
||||
from nonebot_plugin_saa import extract_target
|
||||
|
||||
from ..platform import platform_manager
|
||||
from ..plugin_config import plugin_config
|
||||
|
||||
|
||||
def _configurable_to_me(to_me: bool = EventToMe()):
|
||||
if plugin_config.bison_to_me:
|
||||
return to_me
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
configurable_to_me = Rule(_configurable_to_me)
|
||||
|
||||
common_platform = [
|
||||
p.platform_name
|
||||
for p in filter(
|
||||
lambda platform: platform.enabled and platform.is_common,
|
||||
platform_manager.values(),
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
def gen_handle_cancel(matcher: Type[Matcher], message: str):
|
||||
async def _handle_cancel(text: Annotated[str, EventPlainText()]):
|
||||
if text == "取消":
|
||||
await matcher.finish(message)
|
||||
|
||||
return Depends(_handle_cancel)
|
||||
|
||||
|
||||
def ensure_user_info(matcher: Type[Matcher]):
|
||||
async def _check_user_info(state: T_State):
|
||||
if not state.get("target_user_info"):
|
||||
await matcher.finish(
|
||||
"No target_user_info set, this shouldn't happen, please issue"
|
||||
)
|
||||
|
||||
return _check_user_info
|
||||
|
||||
|
||||
async def set_target_user_info(event: Event, state: T_State):
|
||||
user = extract_target(event)
|
||||
state["target_user_info"] = user
|
Loading…
x
Reference in New Issue
Block a user