diff options
author | Kyomotoi <[email protected]> | 2021-04-24 16:20:19 +0800 |
---|---|---|
committer | Kyomotoi <[email protected]> | 2021-04-24 16:20:19 +0800 |
commit | e01b1ed882a01d03b763e9b06b8b5d0608fc5f21 (patch) | |
tree | a2226a4c1c505f66d5226a1ddae02038ad92a046 /ATRI/plugins | |
parent | 0678347859176671d5ff11852f339336a595e2f5 (diff) | |
download | ATRI-e01b1ed882a01d03b763e9b06b8b5d0608fc5f21.tar.gz ATRI-e01b1ed882a01d03b763e9b06b8b5d0608fc5f21.tar.bz2 ATRI-e01b1ed882a01d03b763e9b06b8b5d0608fc5f21.zip |
✨🔥🎨🐛♻️📝 更新
新增:开发工具中ub paste,再也不怕长消息了。
新增:错误处理两项`ReadFileError`、`FormatError`
修复:bot退群显示被自己踢出群
删除:Service部分内容
删除:hitokoto本地库,改用请求
优化:b站小程序抓取
重构:bot管理部分,对命令进行简化
Diffstat (limited to 'ATRI/plugins')
-rw-r--r-- | ATRI/plugins/admin.py | 439 | ||||
-rw-r--r-- | ATRI/plugins/anime_search.py | 20 | ||||
-rw-r--r-- | ATRI/plugins/essential.py | 4 | ||||
-rw-r--r-- | ATRI/plugins/help.py | 2 | ||||
-rw-r--r-- | ATRI/plugins/hitokoto.py | 35 | ||||
-rw-r--r-- | ATRI/plugins/manage/__init__.py | 8 | ||||
-rw-r--r-- | ATRI/plugins/manage/modules/block.py | 143 | ||||
-rw-r--r-- | ATRI/plugins/manage/modules/broadcast.py | 72 | ||||
-rw-r--r-- | ATRI/plugins/manage/modules/debug.py | 131 | ||||
-rw-r--r-- | ATRI/plugins/manage/modules/dormant.py | 44 | ||||
-rw-r--r-- | ATRI/plugins/manage/modules/request.py | 121 | ||||
-rw-r--r-- | ATRI/plugins/manage/modules/service.py | 205 | ||||
-rw-r--r-- | ATRI/plugins/manage/modules/shutdown.py | 34 | ||||
-rw-r--r-- | ATRI/plugins/rich/__init__.py | 93 |
14 files changed, 837 insertions, 514 deletions
diff --git a/ATRI/plugins/admin.py b/ATRI/plugins/admin.py deleted file mode 100644 index 85ed805..0000000 --- a/ATRI/plugins/admin.py +++ /dev/null @@ -1,439 +0,0 @@ -import json -import asyncio -from random import randint -from pathlib import Path - -from nonebot.permission import SUPERUSER -from nonebot.adapters.cqhttp.permission import GROUP_ADMIN, GROUP_OWNER -from nonebot.adapters.cqhttp import ( - Bot, - MessageEvent, - GroupMessageEvent, - PrivateMessageEvent -) -from nonebot.typing import T_State - -from ATRI.config import Config -from ATRI.service import Service as sv -from ATRI.exceptions import load_error -from ATRI.utils.file import open_file - - -ESSENTIAL_DIR = Path('.') / 'ATRI' / 'data' / 'database' / 'essential' - - -__doc__ = """ -好友申请处理 -权限组:维护者 -用法: - /friendreq list - /friendreq (y/n) reqid -补充: - reqid: 申请码 -""" - -request_friend = sv.on_command( - cmd="/friendreq", - docs=__doc__, - permission=SUPERUSER -) - -@request_friend.handle() -async def _request_friend(bot: Bot, event: MessageEvent) -> None: - msg = str(event.message).split(" ") - key = msg[0] - data = {} - path = ESSENTIAL_DIR / "request_friend.json" - try: - data = json.loads(path.read_bytes()) - except: - await request_friend.finish("读取数据失败,可能并没有请求...") - - if key == "list": - msg0 = "" - for i in data.keys(): - msg0 += f"{i} | {data[i]['user_id']} | {data[i]['comment']}\n" - - msg = "好友申请列表如下:\n" - msg += msg0 - await request_friend.finish(msg) - - elif key == "y": - arg = msg[1] - await bot.set_friend_add_request(flag=arg, approve=True) - await request_friend.finish(f"完成~!已同意 {data[arg]['user_id']} 的申请") - - elif key == "n": - arg = msg[1] - await bot.set_friend_add_request(flag=arg, approve=False) - await request_friend.finish(f"完成~!已拒绝 {data[arg]['user_id']} 的申请") - - else: - await request_friend.finish("阿...请检查输入——!") - - -__doc__ = """ -群聊申请处理 -权限组:维护者 -用法: - /groupreq list - /groupreq (y/n) reqid -补充: - reqid: 申请码 -""" - -request_group = sv.on_command( - cmd="/groupreq", - docs=__doc__, - permission=SUPERUSER -) - -@request_group.handle() -async def _request_group(bot: Bot, event: MessageEvent) -> None: - msg = str(event.message).split(" ") - key = msg[0] - data = {} - path = ESSENTIAL_DIR / "request_group.json" - try: - data = json.loads(path.read_bytes()) - except FileExistsError: - await request_friend.finish("读取数据失败,可能并没有请求...") - - if key == "list": - msg0 = "" - for i in data.keys(): - msg0 += f"{i} | {data[i]['sub_type']} | {data[i]['user_id']} | {data[i]['comment']}\n" - - msg = "群申请列表如下:\n" - msg += msg0 - await request_friend.finish(msg) - - elif key == "y": - arg = msg[1] - try: - await bot.set_group_add_request(flag=arg, - sub_type=data[arg]['sub_type'], - approve=False) - await request_friend.finish(f"完成~!已同意 {data[arg]['user_id']} 的申请") - except: - await request_friend.finish("请检查输入的值是否正确——!") - - elif key == "n": - arg = msg[1] - try: - await bot.set_group_add_request(flag=arg, - sub_type=data[arg]['sub_type'], - approve=False) - await request_friend.finish(f"完成~!已拒绝 {data[arg]['user_id']} 的申请") - except: - await request_friend.finish("请检查输入的值是否正确——!") - - else: - await request_friend.finish("阿...请检查输入——!") - - -__doc__ = """ -广播 -权限组:维护者 -用法: - /bc 内容 -""" - -broadcast = sv.on_command( - cmd="/bc", - docs=__doc__, - permission=SUPERUSER -) - -async def _broadcast(bot: Bot, event: MessageEvent, state: T_State) -> None: - msg = str(event.message).strip() - if msg: - state["msg"] = msg - [email protected]("msg", prompt="请告诉咱需要群发的内容~!") -async def _bd(bot: Bot, event: MessageEvent, state: T_State) -> None: - msg = state["msg"] - group_list = await bot.get_group_list() - succ_list = [] - err_list = [] - - for group in group_list: - await asyncio.sleep(randint(0, 2)) - try: - await bot.send_group_msg(group_id=group["group_id"], - message=msg) - except: - err_list.append(group["group_id"]) - - msg0 = "" - for i in err_list: - msg0 += f" {i}\n" - - repo_msg = ( - f"推送消息:\n{msg}\n" - "————————\n" - f"总共:{len(group_list)}\n" - f"成功推送:{len(succ_list)}\n" - f"失败[{len(err_list)}]个:\n" - ) + msg0 - - await broadcast.finish(repo_msg) - - -__doc__ = """ -错误堆栈查看 -权限组:维护者 -用法: - /track 追踪ID -""" - -track_error = sv.on_command( - cmd="/track", - docs=__doc__, - permission=SUPERUSER -) - -@track_error.handle() -async def _track_error(bot: Bot, event: MessageEvent, state: T_State) -> None: - msg = str(event.message).strip() - if msg: - state["msg"] = msg - -@track_error.got("msg", prompt="请告诉咱追踪ID!") -async def _(bot: Bot, event: MessageEvent, state: T_State) -> None: - track_id = state["msg"] - data = {} - - try: - data = load_error(track_id) - except: - await track_error.finish("Ignore track ID!") - - msg0 = ( - f"ID: {track_id}\n" - f"Time: {data['time']}\n" - f"Prompt: {data['prompt']}\n" - f"{data['content']}" - ) - - await track_error.finish(msg0) - - -__doc__ = """ -获取控制台信息 -权限组:维护者 -用法: - /getlog level line -补充: - level: 等级(info, warning, error, debug) - line: 行数(最近20行:-20) -""" - -get_log = sv.on_command( - cmd="/getlog", - docs=__doc__, - permission=SUPERUSER -) - -@get_log.handle() -async def _get_log(bot: Bot, event: GroupMessageEvent) -> None: - user = str(event.user_id) - group = event.group_id - node = [] - msg = str(event.message).split(" ") - try: - rows = msg[1] - except: - await get_log.finish("格式/gl level rows") - - if msg[0] == "info": - level = "info" - elif msg[0] == "warning": - level = "warning" - elif msg[0] == "error": - level = "error" - elif msg[0] == "debug": - level = "debug" - else: - await get_log.finish("格式/gl level rows") - - path = LOGGER_DIR / level / f"{NOW_TIME}-INFO.log" # type: ignore - logs = await open_file(path, "readlines") - - try: - content = logs[int(rows):] # type: ignore - repo = "\n".join(content).replace("[36mATRI[0m", "ATRI") - node = [{ - "type": "node", - "data": {"name": "ERROR REPO", "uin": user, "content": repo} - }] - except IndexError: - await get_log.finish(f"行数错误...max: {len(logs)}") # type: ignore - - await bot.send_group_forward_msg(group_id=group, messages=node) - - -__doc__ = """ -紧急停机 -权限组:维护者 -用法: - /down -""" - -shutdown = sv.on_command( - cmd="/down", - docs=__doc__, - permission=SUPERUSER -) - -async def _shutdown(bot: Bot, event: MessageEvent, state: T_State) -> None: - msg = str(event.message).strip() - if msg: - state["msg"] = msg - [email protected]("msg", prompt="WARNING,此项操作将强行终止bot运行,是否继续(y/n)") -async def __shutdown(bot: Bot, event: MessageEvent, state: T_State) -> None: - if state["msg"] == "y": - await bot.send(event, "咱还会醒来的,一定") - exit(0) - else: - await shutdown.finish("再考虑下先吧 ;w;") - - -__doc__ = """ -懒得和你废话,block了 -权限组:维护者 -用法: - /block (u,g) (int) (0,1) -补充: - u:QQ - g:QQ群 - int: 对应号码 - 0,1:对应布尔值False, True - 范围为全局 -示例: - /block u 114514 1 - 执行对QQ号为114514的封禁 -""" - -block = sv.on_command( - cmd="/block", - docs=__doc__, - permission=SUPERUSER -) - -async def _block(bot: Bot, event: MessageEvent) -> None: - msg = str(event.message).split(' ') - _type = msg[0] - arg = msg[1] - is_enabled = bool(int(msg[2])) - b_type = "" - - status = "封禁" if is_enabled else "解封" - - if _type == "g": - sv.BlockSystem.control_list(is_enabled=is_enabled, group=arg) - b_type = "Group" - elif _type == "u": - sv.BlockSystem.control_list(is_enabled, user=arg) - b_type = "User" - else: - await block.finish("请检查输入...") - - await block.finish(f"已成功将[{b_type}@{arg}]{status}") - - -__doc__ = """ -功能开关控制 -权限组:维护者,群管理 -用法: - 对于维护者: - /service 目标指令 u+uid,g+gid,global 0,1 - 对于群管理: - /service 目标指令 0,1 -补充: - user:QQ号 - group:QQ群号 - global:全局 - 0,1:对应布尔值False, True -示例: - 对于维护者: - /service /status u123456789 1 - 对于群管理: - /service /status 1 -""" - -service_control = sv.on_command( - cmd='/service', - docs=__doc__, - permission=SUPERUSER|GROUP_OWNER|GROUP_ADMIN -) - -@service_control.handle() -async def _service_control(bot: Bot, event: GroupMessageEvent) -> None: - msg = str(event.message).split(' ') - user = str(event.user_id) - cmd = msg[0] - _type = msg[1] - - if msg[0] == "": - await service_control.finish('请检查输入~!') - - if user in Config.BotSelfConfig.superusers: - is_enabled = int(msg[2]) - status = "启用" if bool(is_enabled) else "禁用" - - if _type == "global": - sv.control_service(cmd, True, is_enabled) - await service_control.finish(f"{cmd}已针对[{_type}]实行[{status}]") - else: - print(_type) - if "u" in _type: - qq = _type.replace('u', '') - sv.control_service(cmd, False, is_enabled, user=qq) - elif "g" in _type: - group = _type.replace('g', '') - sv.control_service(cmd, False, is_enabled, group=group) - else: - await service_control.finish("请检查输入~!") - await service_control.finish(f"{cmd}已针对[{_type}]实行[{status}]") - else: - group = str(event.group_id) - is_enabled = int(_type) - sv.control_service(cmd, False, is_enabled, group=group) - status = "启用" if bool(is_enabled) else "禁用" - await service_control.finish(f"{cmd}已针对[{_type}]实行[{status}]") - -@service_control.handle() -async def _serv(bot: Bot, event: PrivateMessageEvent) -> None: - await service_control.finish("此功能仅在群聊中触发") - - -__doc__ = """ -休眠bot,不处理任何信息 -权限组:维护者 -用法: - /dormant (0,1) -补充: - 0,1: 对应布尔值(False,True) -""" - -dormant = sv.on_command( - cmd='/dormant', - docs=__doc__, - permission=SUPERUSER -) - -async def _dormant(bot: Bot, event: MessageEvent) -> None: - msg = str(event.message).strip() - if msg == "1": - sv.Dormant.control_dormant(True) - stat = "已进入休眠状态...期间咱不会回应任何人的消息哦..." - else: - sv.Dormant.control_dormant(False) - stat = "唔...回复精神力!" - await dormant.finish(stat) diff --git a/ATRI/plugins/anime_search.py b/ATRI/plugins/anime_search.py index e0c7c85..0dba9d7 100644 --- a/ATRI/plugins/anime_search.py +++ b/ATRI/plugins/anime_search.py @@ -1,5 +1,6 @@ import re import json +from aiohttp import FormData from nonebot.adapters.cqhttp.message import MessageSegment from nonebot.adapters.cqhttp import Bot, MessageEvent @@ -11,6 +12,7 @@ from ATRI.rule import is_in_service from ATRI.exceptions import RequestTimeOut from ATRI.utils.request import get_bytes from ATRI.utils.translate import to_simple_string +from ATRI.utils.ub_paste import paste URL = "https://trace.moe/api/search?url=" @@ -32,10 +34,9 @@ anime_search = sv.on_command( @anime_search.args_parser # type: ignore async def _load_anime(bot: Bot, event: MessageEvent, state: T_State) -> None: msg = str(event.message) - quit_list = ['算了', '罢了', '不搜了'] + quit_list = ['算了', '罢了', '不搜了', '取消'] if msg in quit_list: await anime_search.finish('好吧...') - if not msg: await anime_search.reject('图呢?') else: @@ -94,7 +95,7 @@ async def _deal_search(bot: Bot, t = 0 - msg0 = f"> {MessageSegment.at(event.user_id)}" + msg0 = f"> {event.sender.nickname}" for i in result: t += 1 s = "%.2f%%" % (i[1][0] * 100) @@ -105,4 +106,15 @@ async def _deal_search(bot: Bot, f"Time: {i[1][1]} {i[1][2]}" ) - await anime_search.finish(Message(msg0)) + if len(result) == 2: + await anime_search.finish(Message(msg0)) + else: + data = FormData() + data.add_field('poster', 'ATRI running log') + data.add_field('syntax', 'text') + data.add_field('expiration', 'day') + data.add_field('content', msg0) + + repo = f"> {event.sender.nickname}\n" + repo = repo + f"详细请移步此处~\n{await paste(data)}" + await anime_search.finish(repo)
\ No newline at end of file diff --git a/ATRI/plugins/essential.py b/ATRI/plugins/essential.py index 9304279..3ebaa36 100644 --- a/ATRI/plugins/essential.py +++ b/ATRI/plugins/essential.py @@ -261,6 +261,8 @@ async def _group_member_event(bot: Bot, event: GroupIncreaseNoticeEvent) -> None @group_member_event.handle() async def _gro(bot: Bot, event: GroupDecreaseNoticeEvent) -> None: if event.is_tome(): + if event.user_id != event.self_id: + return msg = ( "呜呜呜,主人" f"咱被群 {event.group_id} 里的 {event.operator_id} 扔出来了..." @@ -279,7 +281,7 @@ group_admin_event = sv.on_notice() @group_admin_event.handle() async def _group_admin_event(bot: Bot, event: GroupAdminNoticeEvent) -> None: - if event.is_tome(): + if not event.is_tome(): return for superuser in Config.BotSelfConfig.superusers: diff --git a/ATRI/plugins/help.py b/ATRI/plugins/help.py index 7d01d53..32d3f65 100644 --- a/ATRI/plugins/help.py +++ b/ATRI/plugins/help.py @@ -21,7 +21,7 @@ __doc__ = """ help = sv.on_command( cmd="/help", - docs=__doc__, + docs=__doc__ ) @help.handle() diff --git a/ATRI/plugins/hitokoto.py b/ATRI/plugins/hitokoto.py index 83469be..2b8d81f 100644 --- a/ATRI/plugins/hitokoto.py +++ b/ATRI/plugins/hitokoto.py @@ -1,16 +1,18 @@ -import os import json -from pathlib import Path from random import choice, randint from nonebot.adapters.cqhttp import Bot, MessageEvent from ATRI.rule import is_in_service, to_bot from ATRI.service import Service as sv -from ATRI.exceptions import LoadingError +from ATRI.exceptions import RequestTimeOut from ATRI.utils.list import count_list, del_list_aim +from ATRI.utils.request import get_bytes - -HITOKOTO_DIR = Path('.') / 'ATRI' / 'data' / 'database' / 'hitokoto' +URL = [ + "https://cdn.jsdelivr.net/gh/hitokoto-osc/[email protected]/sentences/a.json", + "https://cdn.jsdelivr.net/gh/hitokoto-osc/[email protected]/sentences/b.json", + "https://cdn.jsdelivr.net/gh/hitokoto-osc/[email protected]/sentences/c.json" +] sick_list = [] @@ -18,17 +20,14 @@ __doc__ = """ 抑郁一下 权限组:所有人 用法: - @一言 - @抑郁一下 - @网抑云 -补充: - @:at Bot + @ 一言 """ hitokoto = sv.on_command( cmd='一言', + aliases={'抑郁一下', '网抑云'}, docs=__doc__, - rule=is_in_service('一言') + rule=is_in_service('一言') & to_bot() ) @hitokoto.handle() @@ -36,10 +35,6 @@ async def _hitokoto(bot: Bot, event: MessageEvent) -> None: global sick_list msg = str(event.message) user = event.get_user_id() - hito_key = ['一言', '抑郁一下', '网抑云'] - - if msg not in hito_key: - return if count_list(sick_list, user) == 3: sick_list.append(user) @@ -53,11 +48,9 @@ async def _hitokoto(bot: Bot, event: MessageEvent) -> None: await hitokoto.finish(msg) else: sick_list.append(user) - rd = choice(os.listdir(HITOKOTO_DIR)) - path = HITOKOTO_DIR / rd - data = {} + url = choice(URL) try: - data = json.loads(path.read_bytes()) - except LoadingError: - raise LoadingError("Loading error!") + data = json.loads(await get_bytes(url)) + except RequestTimeOut: + raise RequestTimeOut("Request failed!") await hitokoto.finish(data[randint(1, len(data) - 1)]['hitokoto']) diff --git a/ATRI/plugins/manage/__init__.py b/ATRI/plugins/manage/__init__.py new file mode 100644 index 0000000..c60171e --- /dev/null +++ b/ATRI/plugins/manage/__init__.py @@ -0,0 +1,8 @@ +import nonebot as nb +from pathlib import Path + + +_sub_plugins = set() + +_sub_plugins |= nb.load_plugins( + str((Path(__file__).parent / 'modules').resolve())) diff --git a/ATRI/plugins/manage/modules/block.py b/ATRI/plugins/manage/modules/block.py new file mode 100644 index 0000000..65a6a86 --- /dev/null +++ b/ATRI/plugins/manage/modules/block.py @@ -0,0 +1,143 @@ +from nonebot.typing import T_State +from nonebot.permission import SUPERUSER +from nonebot.adapters.cqhttp import Bot, MessageEvent + +from ATRI.service import Service as sv + + +__doc__ = """ +封禁用户 +权限组:维护者 +用法: + 封禁用户 QQ号 +""" + +block_user = sv.on_command( + cmd="封禁用户", + docs=__doc__, + permission=SUPERUSER +) + +@block_user.args_parser # type: ignore +async def _block_user_load(bot: Bot, + event: MessageEvent, + state: T_State) -> None: + msg = str(event.message).strip() + cancel = ['算了', '罢了'] + if msg in cancel: + await block_user.finish('好吧...') + if not msg: + await block_user.reject('是谁呢?!GKD!') + else: + state['noob'] = msg + +@block_user.handle() +async def _block_user(bot: Bot, event: MessageEvent, state: T_State) -> None: + noob = state['noob'] + sv.BlockSystem.control_list(True, user=noob) + msg = f"用户[{noob}]已被封禁(;′⌒`)" + await block_user.finish(msg) + + +__doc__ = """ +解封用户 +权限组:维护者 +用法: + 解封用户 QQ号 +""" + +unblock_user = sv.on_command( + cmd="解封用户", + docs=__doc__, + permission=SUPERUSER +) + +@unblock_user.args_parser # type: ignore +async def _unblock_user_load(bot: Bot, + event: MessageEvent, + state: T_State) -> None: + msg = str(event.message).strip() + cancel = ['算了', '罢了'] + if msg in cancel: + await unblock_user.finish('好吧...') + if not msg: + await unblock_user.reject('要原谅谁呢...') + else: + state['forgive'] = msg + +@unblock_user.handle() +async def _unblock_user(bot: Bot, event: MessageEvent, state: T_State) -> None: + forgive = state['forgive'] + sv.BlockSystem.control_list(False, user=forgive) + msg = f"用户[{forgive}]已被解封ヾ(´・ω・`)ノ" + await unblock_user.finish(msg) + + +__doc__ = """ +封禁群 +权限组:维护者 +用法: + 封禁群 群号 +""" + +block_group = sv.on_command( + cmd="封禁群", + docs=__doc__, + permission=SUPERUSER +) + +@block_group.args_parser # type: ignore +async def _block_group_load(bot: Bot, + event: MessageEvent, + state: T_State) -> None: + msg = str(event.message).strip() + cancel = ['算了', '罢了'] + if msg in cancel: + await block_user.finish('好吧...') + if not msg: + await block_user.reject('是哪个群?!GKD!') + else: + state['noob_g'] = msg + +@block_group.handle() +async def _block_group(bot: Bot, event: MessageEvent, state: T_State) -> None: + noob_g = state['noob_g'] + sv.BlockSystem.control_list(True, group=noob_g) + msg = f"群[{noob_g}]已被封禁(;′⌒`)" + await block_user.finish(msg) + + +__doc__ = """ +解封群 +权限组:维护者 +用法: + 解封 群号 +""" + +unblock_group = sv.on_command( + cmd="解封群", + docs=__doc__, + permission=SUPERUSER +) + +@unblock_group.args_parser # type: ignore +async def _unblock_group_load(bot: Bot, + event: MessageEvent, + state: T_State) -> None: + msg = str(event.message).strip() + cancel = ['算了', '罢了'] + if msg in cancel: + await block_user.finish('好吧...') + if not msg: + await block_user.reject('要原谅哪个群呢...') + else: + state['forgive_g'] = msg + +@unblock_group.handle() +async def _unblock_group(bot: Bot, + event: MessageEvent, + state: T_State) -> None: + forgive_g = state['forgive_g'] + sv.BlockSystem.control_list(False, group=forgive_g) + msg = f"群[{forgive_g}]已被解封ヾ(´・ω・`)ノ" + await unblock_user.finish(msg) diff --git a/ATRI/plugins/manage/modules/broadcast.py b/ATRI/plugins/manage/modules/broadcast.py new file mode 100644 index 0000000..5086fcf --- /dev/null +++ b/ATRI/plugins/manage/modules/broadcast.py @@ -0,0 +1,72 @@ +import asyncio +from random import randint + +from nonebot.typing import T_State +from nonebot.permission import SUPERUSER +from nonebot.adapters.cqhttp import Bot, MessageEvent + +from ATRI.service import Service as sv + + +__doc__ = """ +群发内容 +权限组:维护者 +用法: + 广播 内容 +""" + +broadcast = sv.on_command( + cmd="广播", + docs=__doc__, + permission=SUPERUSER +) + [email protected]_parser # type: ignore +async def _broadcast_load(bot: Bot, + event: MessageEvent, + state: T_State) -> None: + msg = str(event.message) + quit_list = ['算了', '罢了', '取消'] + if msg in quit_list: + await broadcast.finish('好吧...') + if not msg: + await broadcast.reject('想群发啥呢0w0') + else: + state['msg'] = msg + +async def _broadcast(bot: Bot, event: MessageEvent, state: T_State) -> None: + msg = str(event.message).strip() + if msg: + state['msg'] = msg + [email protected]('msg', prompt='请告诉咱需要群发的内容~!') +async def _deal_broadcast(bot: Bot, + event: MessageEvent, + state: T_State) -> None: + msg = state['msg'] + group_list = await bot.get_group_list() + succ_list = [] + err_list = [] + + for group in group_list: + await asyncio.sleep(randint(0, 2)) + try: + await bot.send_group_msg(group_id=group["group_id"], + message=msg) + except BaseException: + err_list.append(group["group_id"]) + + msg0 = "" + for i in err_list: + msg0 += f" {i}\n" + + repo_msg = ( + f"推送消息:\n{msg}\n" + "————————\n" + f"总共:{len(group_list)}\n" + f"成功推送:{len(succ_list)}\n" + f"失败[{len(err_list)}]个:\n" + ) + msg0 + + await broadcast.finish(repo_msg) diff --git a/ATRI/plugins/manage/modules/debug.py b/ATRI/plugins/manage/modules/debug.py new file mode 100644 index 0000000..66a84cf --- /dev/null +++ b/ATRI/plugins/manage/modules/debug.py @@ -0,0 +1,131 @@ +from aiohttp import FormData + +from nonebot.typing import T_State +from nonebot.permission import SUPERUSER +from nonebot.adapters.cqhttp import Bot, MessageEvent +from nonebot.adapters.cqhttp.message import MessageSegment + +from ATRI.service import Service as sv +from ATRI.log import LOGGER_DIR, NOW_TIME +from ATRI.utils.file import open_file +from ATRI.utils.ub_paste import paste +from ATRI.exceptions import load_error + + +level_list = ['info', 'warning', 'error', 'debug'] + + +__doc__ = """ +获取控制台信息 +权限组:维护者 +用法: + 获取log 等级 行数 +示例: + 获取log info -20(最新20行) +""" + +get_console = sv.on_command( + cmd="获取log", + aliases={'获取LOG', '获取控制台', '获取控制台信息'}, + docs=__doc__, + permission=SUPERUSER +) + +@get_console.handle() +async def _get_console(bot: Bot, event: MessageEvent, state: T_State) -> None: + msg = str(event.message).strip() + if msg: + state['level'] = msg + +@get_console.got('level', prompt='需要获取的等级是?') +async def _got(bot: Bot, event: MessageEvent, state: T_State) -> None: + quit_list = ['算了', '罢了', '不了'] + if state['level'] in quit_list: + await get_console.finish('好吧...') + +@get_console.got('line', prompt='需要获取的行数是?') +async def _deal_get(bot: Bot, event: MessageEvent, state: T_State) -> None: + level = state['level'] + line = state['line'] + repo = str() + + path = LOGGER_DIR / f"{level}" / f"{NOW_TIME}.log" + logs = await open_file(path, 'readlines') + + try: + content = logs[int(line):] # type: ignore + repo = "\n".join(content).replace("[36mATRI[0m", "ATRI") + except IndexError: + await get_console.finish(f'行数错误...max: {len(logs)}') # type: ignore + + data = FormData() + data.add_field('poster', 'ATRI running log') + data.add_field('syntax', 'text') + data.add_field('expiration', 'day') + data.add_field('content', repo) + + msg0 = f"> {event.sender.nickname}\n" + msg0 = msg0 + f"详细请移步此处~\n{await paste(data)}" + await track_error.finish(msg0) + + +__doc__ = """ +追踪错误 +权限组:维护者 +用法: + track 追踪ID +""" + +track_error = sv.on_command( + cmd="track", + aliases={'追踪'}, + docs=__doc__, + permission=SUPERUSER +) + +@track_error.args_parser # type: ignore +async def _track_error_load(bot: Bot, + event: MessageEvent, + state: T_State) -> None: + msg = str(event.message).strip() + cancel = ['算了', '罢了'] + if msg in cancel: + await track_error.finish('好吧...') + if not msg: + await track_error.reject('欸?!要开始debug了吗,请提供追踪ID...Ծ‸Ծ') + else: + state['track'] = msg + +@track_error.handle() +async def _track_error(bot: Bot, event: MessageEvent, state: T_State) -> None: + msg = str(event.message).strip() + if msg: + state['track'] = msg + +@track_error.got('track', prompt='欸?!要开始debug了吗,请提供追踪ID...Ծ‸Ծ') +async def _deal_track(bot: Bot, event: MessageEvent, state: T_State) -> None: + track_id = state['track'] + data = dict() + + try: + data = load_error(track_id) + except BaseException: + await track_error.finish('未发现对应ID呢...(⇀‸↼‶)') + + msg = ( + f"ID: [{track_id}]\n" + f"Time: [{data['time']}]\n" + f"Prompt: [{data['prompt']}]\n" + "——————\n" + f"{data['content']}" + ) + + data = FormData() + data.add_field('poster', track_id) + data.add_field('syntax', 'text') + data.add_field('expiration', 'day') + data.add_field('content', msg) + + msg0 = f"> {event.sender.nickname}\n" + msg0 = msg0 + f"详细请移步此处~\n{await paste(data)}" + await track_error.finish(msg0) diff --git a/ATRI/plugins/manage/modules/dormant.py b/ATRI/plugins/manage/modules/dormant.py new file mode 100644 index 0000000..5274eaa --- /dev/null +++ b/ATRI/plugins/manage/modules/dormant.py @@ -0,0 +1,44 @@ +from nonebot.permission import SUPERUSER +from nonebot.adapters.cqhttp import Bot, MessageEvent + +from ATRI.service import Service as sv + + +__doc__ = """ +休眠,不处理任何信息 +权限组:维护者 +用法: + @ 休眠 +""" + +dormant_enabled = sv.on_command( + cmd='休眠', + docs=__doc__, + permission=SUPERUSER +) + +@dormant_enabled.handle() +async def _dormant_enabled(bot: Bot, event: MessageEvent) -> None: + sv.Dormant.control_dormant(True) + msg = "已进入休眠状态...期间咱不会回应任何人的消息哦..." + await dormant_enabled.finish(msg) + + +__doc__ = """ +苏醒,开始处理信息 +权限组:维护者 +用法: + @ 苏醒 +""" + +dormant_disabled = sv.on_command( + cmd='休眠', + docs=__doc__, + permission=SUPERUSER +) + +@dormant_disabled.handle() +async def _dormant_disabled(bot: Bot, event: MessageEvent) -> None: + sv.Dormant.control_dormant(False) + msg = "唔...早上好...——哇哈哈" + await dormant_disabled.finish(msg)
\ No newline at end of file diff --git a/ATRI/plugins/manage/modules/request.py b/ATRI/plugins/manage/modules/request.py new file mode 100644 index 0000000..c90ed66 --- /dev/null +++ b/ATRI/plugins/manage/modules/request.py @@ -0,0 +1,121 @@ +import re +import json +from pathlib import Path + +from nonebot.typing import T_State +from nonebot.permission import SUPERUSER +from nonebot.adapters.cqhttp import Bot, MessageEvent + +from ATRI.service import Service as sv +from ATRI.exceptions import ReadFileError, FormatError + + +ESSENTIAL_DIR = Path('.') / 'ATRI' / 'data' / 'database' / 'essential' + + +__doc__ = """ +查看好友/群申请列表 +权限组:维护者 +用法: + 查看申请列表 +""" + +req_list = sv.on_command( + cmd="申请列表", + docs=__doc__, + permission=SUPERUSER +) + +@req_list.handle() +async def _req_list(bot: Bot, event: MessageEvent, state: T_State) -> None: + path_f = ESSENTIAL_DIR / 'request_friend.json' + path_g = ESSENTIAL_DIR / 'request_group.json' + data_f, data_g = dict() + try: + data_f = json.loads(path_f.read_bytes()) + except ReadFileError: + msg_f = "[读取文件失败]" + try: + data_g = json.loads(path_g.read_bytes()) + except ReadFileError: + msg_g = "[读取文件失败]" + + msg_f = str() + for i in data_f.keys(): + msg_f += f"{i} | {data_f[i]['user_id']} | {data_f[i]['comment']}\n" + + msg_g = str() + for i in data_g.keys(): + msg_g += f"{i} | {data_g[i]['sub_type']} | {data_g[i]['user_id']} | {data_g[i]['comment']}\n" + + msg = ( + "好友/群申请列表如下:\n" + "· 好友:\n" + f"{msg_f}" + "· 群:\n" + f"{msg_g}" + ) + await req_list.finish(msg) + + +req_deal = sv.on_regex( + r'[同意|拒绝][好友|群]申请', + permission=SUPERUSER +) + +@req_deal.handle() +async def _req_deal(bot: Bot, event: MessageEvent, state: T_State) -> None: + msg = str(event.message).split(' ') + arg = re.findall(r'[同意|拒绝][好友|群]申请', msg[0]) + app = arg[0] + _type = arg[1] + + if not msg[1]: + await req_deal.finish(f'正确用法!速看\n{app}{_type}申请 (reqid)') + + path = ESSENTIAL_DIR / "request_group.json" + data_g = dict() + try: + data_g = json.loads(path.read_bytes()) + except FileExistsError: + await req_deal.finish("读取群数据失败,可能并没有请求...") + + reqid = msg[1] + if app == "同意": + if _type == "好友": + try: + await bot.set_friend_add_request(flag=reqid, + approve=True) + await req_deal.finish(f"完成~!已同意申请") + except FormatError: + await req_deal.finish('请检查输入的值是否正确——!') + elif _type == "群": + try: + await bot.set_group_add_request(flag=reqid, + sub_type=data_g[reqid]['sub_type'], + approve=True) + await req_deal.finish(f"完成~!已同意申请") + except FormatError: + await req_deal.finish('请检查输入的值是否正确——!') + else: + await req_deal.finish('请检查输入的值是否正确——!') + elif app == "拒绝": + if _type == "好友": + try: + await bot.set_friend_add_request(flag=reqid, + approve=False) + await req_deal.finish(f"完成~!已拒绝申请") + except FormatError: + await req_deal.finish('请检查输入的值是否正确——!') + elif _type == "群": + try: + await bot.set_group_add_request(flag=reqid, + sub_type=data_g[reqid]['sub_type'], + approve=False) + await req_deal.finish(f"完成~!已拒绝申请") + except FormatError: + await req_deal.finish('请检查输入的值是否正确——!') + else: + await req_deal.finish('请检查输入的值是否正确——!') + else: + await req_deal.finish('请检查输入的值是否正确——!') diff --git a/ATRI/plugins/manage/modules/service.py b/ATRI/plugins/manage/modules/service.py new file mode 100644 index 0000000..8bb7e9c --- /dev/null +++ b/ATRI/plugins/manage/modules/service.py @@ -0,0 +1,205 @@ +from nonebot.typing import T_State +from nonebot.permission import SUPERUSER +from nonebot.adapters.cqhttp.permission import GROUP_ADMIN, GROUP_OWNER +from nonebot.adapters.cqhttp import ( + Bot, + MessageEvent, + GroupMessageEvent, + PrivateMessageEvent +) + +from ATRI.service import Service as sv + + +__doc__ = """ +启用功能,针对单群 +权限组:维护者,群管理 +用法: + 启用 目标命令 +示例: + 启用 以图搜图 +""" + +cur_service_ena = sv.on_command( + cmd="启用功能", + docs=__doc__, + permission=SUPERUSER|GROUP_ADMIN|GROUP_OWNER +) + +@cur_service_ena.args_parser # type: ignore +async def _cur_ena_load(bot: Bot, + event: GroupMessageEvent, + state: T_State) -> None: + msg = str(event.message).strip() + quit_list = ['算了', '罢了', '取消'] + if msg in quit_list: + await cur_service_ena.finish('好吧...') + if not msg: + await cur_service_ena.reject('请告诉咱目标命令!') + else: + state['service_e'] = msg + +@cur_service_ena.handle() +async def _cur_ena(bot: Bot, + event: GroupMessageEvent, + state: T_State) -> None: + msg = str(event.message).strip() + if msg: + state['service_e'] = msg + +@cur_service_ena.got('service_e', prompt='请告诉咱目标命令!') +async def _deal_cur_ena(bot: Bot, + event: GroupMessageEvent, + state: T_State) -> None: + cmd = state['service_e'] + group = str(event.group_id) + sv.control_service(cmd, False, True, group=group) + await cur_service_ena.finish(f'成功!本群已启用:{cmd}') + +@cur_service_ena.handle() +async def _refuse_cur_ena(bot: Bot, + event: PrivateMessageEvent, + state: T_State) -> None: + await cur_service_ena.finish('只能在群聊中决定哦...') + + +__doc__ = """ +禁用功能,针对单群 +权限组:维护者,群管理 +用法: + 禁用 目标命令 +示例: + 禁用 以图搜图 +""" + +cur_service_dis = sv.on_command( + cmd="禁用功能", + docs=__doc__, + permission=SUPERUSER|GROUP_ADMIN|GROUP_OWNER +) + +@cur_service_dis.args_parser # type: ignore +async def _cur_dis_load(bot: Bot, + event: GroupMessageEvent, + state: T_State) -> None: + msg = str(event.message).strip() + quit_list = ['算了', '罢了', '取消'] + if msg in quit_list: + await cur_service_dis.finish('好吧...') + if not msg: + await cur_service_dis.reject('请告诉咱目标命令!') + else: + state['service_d'] = msg + +@cur_service_dis.handle() +async def _cur_dis(bot: Bot, + event: GroupMessageEvent, + state: T_State) -> None: + msg = str(event.message).strip() + if msg: + state['service_d'] = msg + +@cur_service_dis.got('service_d', prompt='请告诉咱目标命令!') +async def _deal_cur_dis(bot: Bot, + event: GroupMessageEvent, + state: T_State) -> None: + cmd = state['service_d'] + group = str(event.group_id) + sv.control_service(cmd, False, False, group=group) + await cur_service_dis.finish(f'成功!本群已禁用:{cmd}') + +@cur_service_dis.handle() +async def _refuse_cur_dis(bot: Bot, + event: PrivateMessageEvent, + state: T_State) -> None: + await cur_service_dis.finish('只能在群聊中决定哦...') + + +__doc__ = """ +全局启用功能 +权限组:维护者 +用法: + 全局启用 目标命令 +示例: + 全局启用 以图搜图 +""" + +glo_service_ena = sv.on_command( + cmd="全局启用", + docs=__doc__, + permission=SUPERUSER +) + +@glo_service_ena.args_parser # type: ignore +async def _glo_ena_load(bot: Bot, + event: MessageEvent, + state: T_State) -> None: + msg = str(event.message).strip() + quit_list = ['算了', '罢了', '取消'] + if msg in quit_list: + await glo_service_ena.finish('好吧...') + if not msg: + await glo_service_ena.reject('请告诉咱目标命令!') + else: + state['service_e_g'] = msg + +@glo_service_ena.handle() +async def _glo_ena(bot: Bot, + event: MessageEvent, + state: T_State) -> None: + msg = str(event.message).strip() + if msg: + state['service_e_g'] = msg + +@glo_service_ena.got('service_e_g', prompt='请告诉咱目标命令!') +async def _deal_glo_ena(bot: Bot, + event: MessageEvent, + state: T_State) -> None: + cmd = state['service_e_g'] + sv.control_service(cmd, True, True) + await glo_service_ena.finish(f'成功!已全局启用:{cmd}') + + +__doc__ = """ +全局禁用功能 +权限组:维护者 +用法: + 禁用启用 目标命令 +示例: + 禁用启用 以图搜图 +""" + +glo_service_dis = sv.on_command( + cmd="全局禁用", + docs=__doc__, + permission=SUPERUSER +) + +@glo_service_dis.args_parser # type: ignore +async def _glo_dis_load(bot: Bot, + event: MessageEvent, + state: T_State) -> None: + msg = str(event.message).strip() + quit_list = ['算了', '罢了', '取消'] + if msg in quit_list: + await glo_service_dis.finish('好吧...') + if not msg: + await glo_service_dis.reject('请告诉咱目标命令!') + else: + state['service_d_g'] = msg + +@glo_service_dis.handle() +async def _glo_dis(bot: Bot, + event: MessageEvent, + state: T_State) -> None: + msg = str(event.message).strip() + if msg: + state['service_d_g'] = msg + +@glo_service_dis.got('service_d_g', prompt='请告诉咱目标命令!') +async def _deal_glo_dis(bot: Bot, + event: MessageEvent, + state: T_State) -> None: + cmd = state['service_d_g'] + sv.control_service(cmd, True, False) + await glo_service_dis.finish(f'成功!已全局禁用:{cmd}') diff --git a/ATRI/plugins/manage/modules/shutdown.py b/ATRI/plugins/manage/modules/shutdown.py new file mode 100644 index 0000000..11b2b1b --- /dev/null +++ b/ATRI/plugins/manage/modules/shutdown.py @@ -0,0 +1,34 @@ +from nonebot.typing import T_State +from nonebot.permission import SUPERUSER +from nonebot.adapters.cqhttp import Bot, MessageEvent + +from ATRI.service import Service as sv + + +__doc__ = """ +紧急停机 +权限组:维护者 +用法: + @ 关机 +""" + +shutdown = sv.on_command( + cmd="关机", + docs=__doc__, + permission=SUPERUSER +) + +async def _shutdown(bot: Bot, event: MessageEvent, state: T_State) -> None: + msg = str(event.message).strip() + if msg: + state["msg"] = msg + [email protected]("msg", prompt="[WARNING]此项操作将强行终止bot运行,是否继续(y/n)") +async def __shutdown(bot: Bot, event: MessageEvent, state: T_State) -> None: + t = ['y', 'Y', '是'] + if state["msg"] in t: + await bot.send(event, "咱还会醒来的,一定") + exit(0) + else: + await shutdown.finish("再考虑下吧 ;w;") diff --git a/ATRI/plugins/rich/__init__.py b/ATRI/plugins/rich/__init__.py index 9d5d6a9..cd4c5bd 100644 --- a/ATRI/plugins/rich/__init__.py +++ b/ATRI/plugins/rich/__init__.py @@ -1,7 +1,10 @@ import re import json +from random import choice from aiohttp.client import ClientSession + from nonebot.adapters.cqhttp import Bot, MessageEvent +from nonebot.adapters.cqhttp.message import MessageSegment from ATRI.service import Service as sv from ATRI.utils.request import get_bytes @@ -11,6 +14,10 @@ from .data_source import dec temp_list = [] +img_url = [ + "https://cdn.jsdelivr.net/gh/Kyomotoi/CDN@master/project/ATRI/fkrich.png", + "https://cdn.jsdelivr.net/gh/Kyomotoi/CDN@master/project/ATRI/xixi.jpg" +] bilibili_rich = sv.on_message() @@ -18,59 +25,49 @@ bilibili_rich = sv.on_message() @bilibili_rich.handle() async def _bilibili_rich(bot: Bot, event: MessageEvent) -> None: global temp_list - msg = str(event.raw_message).replace("\\", "") - bv = False - - if "qqdocurl" not in msg: - if "av" in msg: - try: + try: + msg = str(event.raw_message).replace("\\", "") + bv = False + + if "qqdocurl" not in msg: + if "av" in msg: av = re.findall(r"(av\d+)", msg)[0].replace('av', '') - except: - return - else: - try: + else: bv = re.findall(r"(BV\w+)", msg) av = str(dec(bv[0])) - except: - return - else: - patt = r"(?:(?:https?|ftp):\/\/)?[\w/\-?=%.]+\.[\w/\-&?=%.]+" - bv_url = re.findall(patt, msg) - bv_url = bv_url[3] - async with ClientSession() as session: - async with session.get( - url=bv_url) as r: - bv = re.findall(r"(BV\w+)", str(r.url)) - av = dec(bv[0]) - - if not bv: - if "av" in msg: - try: + else: + patt = r"(?:(?:https?|ftp):\/\/)?[\w/\-?=%.]+\.[\w/\-&?=%.]+" + bv_url = re.findall(patt, msg) + bv_url = bv_url[3] + async with ClientSession() as session: + async with session.get(url=bv_url) as r: + bv = re.findall(r"(BV\w+)", str(r.url)) + av = dec(bv[0]) + + if not bv: + if "av" in msg: av = re.findall(r"(av\d+)", msg)[0].replace('av', '') - except: + else: return - else: + + if count_list(temp_list, av) == 4: + await bot.send(event, "你是怕别人看不到么发这么多次?") + temp_list = del_list_aim(temp_list, av) return - - if count_list(temp_list, av) == 4: - await bot.send(event, "你是怕别人看不到么发这么多次?") - temp_list = del_list_aim(temp_list, av) - return - - temp_list.append(av) - - try: + + temp_list.append(av) + URL = f"https://api.kyomotoi.moe/api/bilibili/v2/?aid={av}" - except: + data = json.loads(await get_bytes(URL))['data'] + repo = ( + f"{data['bvid']} INFO:\n" + f"Title: {data['title']}\n" + f"Link: {data['short_link']}\n" + "にまねげぴのTencent rich!" + ) + await bot.send( + event, + MessageSegment.image(file=choice(img_url))) + await bilibili_rich.finish(repo) + except BaseException: return - data = json.loads(await get_bytes(URL))['data'] - repo = ( - f"{av} INFO:\n" - f"Title: {data['title']}\n" - f"Bid: {data['bvid']}\n" - f"View: {data['stat']['view']} Like: {data['stat']['like']}\n" - f"Coin: {data['stat']['coin']} Share: {data['stat']['share']}\n" - f"Link: {data['short_link']}\n" - "にまねげぴのTencent rich!" - ) - await bilibili_rich.finish(repo) |