diff options
author | Kyomotoi <[email protected]> | 2021-07-31 16:16:47 +0800 |
---|---|---|
committer | Kyomotoi <[email protected]> | 2021-07-31 16:16:47 +0800 |
commit | 336eb9d9e98b0bee952c27a50820dbdb350bcc03 (patch) | |
tree | 718d5349232bce0d06cc901707bdd8f478c43314 | |
parent | c485985d3be687d17168512de44ea7b744fea7cc (diff) | |
download | ATRI-336eb9d9e98b0bee952c27a50820dbdb350bcc03.tar.gz ATRI-336eb9d9e98b0bee952c27a50820dbdb350bcc03.tar.bz2 ATRI-336eb9d9e98b0bee952c27a50820dbdb350bcc03.zip |
🔥🚚✨
- 移除:laugh.txt,需要时再拉取
- 移动控制台文件至plugins/console目录下
- 新增:
- 和管理贴贴w
- 正式的可视化前端单页
62 files changed, 2274 insertions, 1049 deletions
diff --git a/ATRI/data/database/funny/laugh.txt b/ATRI/data/database/funny/laugh.txt deleted file mode 100644 index a8bc456..0000000 --- a/ATRI/data/database/funny/laugh.txt +++ /dev/null @@ -1,134 +0,0 @@ -Erdos相信上帝有一本记录所有数学中绝妙证明的书,上帝相信这本书在%name手里 -有一次费马惹怒了%name,于是就有了费马最后定理 -%name从不会用光页边的空白 -%name的Erdos数是-1 -如果%name告诉你他在说谎,他就正在说真话 -%name从大到小列举了所有素数,就知道了素数有无穷多 -%name可以不重复地走遍柯尼斯堡的七座桥 -%name可以倒着写完圆周率的每一位 -当数学家们使用通用语句——设n是一个正整数时,这是在请求%name允许他们这样做 -%name小时候有一次要把正整数从1加到100,于是他用心算把所有正整数的和减去大于100的正整数的和 -不是%name发现了正态分布,而是自然规律在遵从%name的意愿 -一个数学家,一个物理学家,一个工程师走进一家酒吧,侍者说:‘你好,%name教授’ -%name可以走到莫比乌斯带的另一面 -当%name令一个正整数增加1时,那个正整数并没有增加,而是其他正整数减少了1 -%name同时给他自己和罗素剪头发 -%name不能理解什么是随机过程,因为他能预言随机数 -有一次%name证明了一个结论,但他不喜欢这个结论,于是%name把它证伪了 -有些级数是发散的,因为%name觉得它们不值得加起来 -问%name一个定理是否正确可以作为一个定理的严谨证明 -如果没有船,%name可以把狼,羊,菜传送到河对岸 -有一次%name在森林里迷路了,于是他给这个森林添加了一些边把它变成了一棵树 -只有%name知道薛定谔的猫是死是活 -通过故意遗漏证明最后的‘证毕’,%name拯救了热带雨林 -%name可以剔掉奥卡姆剃刀 -你刚证明了一个定理?%name200年前就证明它了。 -空集的定义是%name不会证明的定理构成的集合 -‘我找不到反例’可以被视为一个定理的证明,如果它是%name写下的 -%name把磁铁断为两块时,他得到两个单极磁铁 -费马认为书页边缘写不下自己对费马大定理的证明,%name能证明为什么这个证明这么长 -上帝从不掷骰子,除非%name允许他赢一小会 -平行线在%name让它们相交的地方相交 -当哥德尔听说%name能证明一切命题时,他让%name证明‘存在一个命题%name不能证明’——这就是量子态的来历 -%name可以看到自己头上帽子的颜色 -%name把无穷视为归纳证明的第一个非平凡情况 -%name可以用1种颜色染任何地图 -%name在求不定积分时不需要在最后加上一个常数 -%name无需站在任何人肩膀上就能比别人看的更远 -%name用克莱因瓶喝酒 -%name通过枚举法证伪了哥德尔不完备性定理/n有一次%name发现有一个定理自己不会证——这直接证明了哥德尔不完备定理 -%name有log(n)速度的排序算法 -上帝创造了正整数,剩下的就是%name的工作了 -黎曼是%name发表未公开成果时使用的名字 -%name不用任何公理就能证明一个定理 -一个发现就是一个%name的未公开结果 -%name使用无穷进制写数 -%name可以除以0 -存在一个实数到被%name证明了的定理的双射 -%name从不需要选择公理 -%name在200年前发明了64量子位计算机,但这让他的工作减速了 -难题不会为%name带来麻烦,%name会为难题带来麻烦 -%name说过‘数学是科学的皇后’,你猜谁是国王? -没有比65537大的费马素数,因为%name发现费马将要发现什么了不起的事情,于是把它终结掉了 -发散序列当看到%name在旁边时会收敛 -宇宙通过膨胀让自己的熵增加速度不超过%name证明定理的速度 -Erdos说他知道37个勾股定理的证明,%name说他知道37个黎曼定理的证明,并留给黎曼做练习 -希尔伯特23问题是他收集的%name的手稿中留给读者做练习的那些问题 -只有两件事物是无限的:人类的愚蠢和%name的智慧,而且我对前者不太确定——爱因斯坦 -%name也发现了伽罗瓦理论,但他赢了那场决斗 -%name不能理解P与NP的问题,因为一切对他而言都是常数级别 -%name能心算干掉RSA公钥加密算法 -%name在实数集上使用数归 -%name从不证明任何定理——都是他的引理 -不是%name素数的素数会遭到戏弄 -%name可以做出正17边形——只用直尺 -有一次%name在脑子里构建了所有集合构成的集合 -%name证明了哥德巴赫猜想——通过检查所有情况 -%name可以把毛球捋平 -世界上没有定理,只有%name允许其正确的命题 -%name知道哪些图灵机会停机,因为它们运行前要得到%name批准 -在晚上,定理们围坐在篝火边给%name讲故事 -%name本想证明三色定理,但他喜欢蓝色,所以放弃了 -%name当初面试Google时,被问到‘如果P=NP能够推导出哪些结论’,Jeff回答说:‘P = 0或者N = 1’。而在面试官还没笑完的时候,Jeff检查了一下Google的公钥,然后在黑板上写下了私钥。 -编译器从不警告%name,只有%name警告编译器。 -%name的编码速度在2000年底提高了约40倍,因为他换了USB2.0的键盘。 -%name在提交代码前都会编译一遍,不过是为了检查编译器和链接器有没有出bug。 -%name有时候会调整他的工作环境和设备,不过这是为了保护他的键盘。 -所有指针都指向%name。 -gcc -O4的功能是发送代码给%name重写。 -%name有一次没有通过图灵测试,因为他正确说出了斐波那契数列的第203项的值,在一秒钟内。 -真空中光速曾经是35英里每小时,直到%name%花了一个周末时间优化了一下物理法则。 -%name出生于1969年12月31日午后11点48分,他花了12分钟实现了他的第一个计时器。 -%name既不用Emacs也不用Vim,他直接输入代码到zcat,因为这样更快。 -%name发送以太网封包从不会发生冲突,因为其他封包都吓得逃回了网卡的缓冲区里。 -因为对常数级的时间复杂度感到不满意,%name发明了世界上第一个O(1/n)算法。 -有一次%name去旅行,期间Google的几个服务神秘地罢工了好几天。这是真事。 -%name被迫发明了异步API因为有一天他把一个函数优化到在调用前就返回结果了。 -%name首先写的是二进制代码,然后再写源代码作为文档。 -%name曾经写过一个O(n^2)算法,那是为了解决旅行商问题。 -%name有一次用一句printf实现了一个web服务器。其他工程师添加了数千行注释但依然无法完全解释清楚其工作原理。而这个程序就是今天Google首页的前端。 -%name可以下四子棋时用三步就击败你。 -当你的代码出现未定义行为时,你会得到一个segmentation fault和一堆损坏的数据。当%name的代码出现未定义行为时,一个独角兽会踏着彩虹从天而降并给每个人提供免费的冰激凌。 -当%name运行一个profiler时,循环们都会恐惧地自动展开。 -%name至今还在等待数学家们发现他隐藏在PI的小数点后数字里的笑话。 -%name的键盘只有两个键,1和0。 -%name失眠的时候,就Mapreduce羊。 -%name想听mp3的时候,他只需要把文件cat到/dev/dsp,然后在脑内解码。 -Graham Bell当初发明出电话时,他看到有一个来自%name的未接来电。 -%name的手表显示的是自1970年1月1日的秒数,并且从没慢过一秒。 -%name写程序是从‘cat >/dev/mem’开始的。 -有一天%name出门时把笔记本错拿成了绘画板。在他回去拿笔记本的路上,他在绘图板上写了个俄罗斯方块打发时间。 -%name卡里只有8毛钱,本来想打个6毛的饭结果不小心按了9毛的,哪知机器忽然疯狂地喷出255两饭,被喷得满脸热饭的%name%大叫‘烫烫烫烫烫烫。。。。’ -%name不洗澡是因为水力发电公司运行的是专有软件。 -%name的胡子是由括号构成的。 -%name从来不用洗澡;他只需要运行‘make clean’。 -%name通过把一切都变得free而解决了旅行推销员问题。 -%name的左手和右手分别命名为‘(’和‘)’。 -%name用Emacs写出了Emacs的第一版。 -有些人检查他们的电脑里是否有病毒。病毒检查他们的电脑里是否有%name。 -在一间普通的客厅里有1242件物体可以被%name用来写一个操作系统,包括这房间本身。 -当%name还是个学数手指的小毛孩时,他总是从0开始数。 -%name不去kill一个进程,他只想看它是否胆敢继续运行。 -当%name指向(point at)一台Windows电脑时,它就会出现段错误。 -%name最初的话语是syscalls(系统调用)。 -%name之所以存在是因为他把自己编译成了生命体。 -%name是他自己在Emacs里用Lisp语言编写成的。 -%name能够通过Emacs的ssh客户端程序连接到任何大脑。 -当%name使用浮点数时,它们便没有舍入误差。 -%name不用维护代码。他注视着它们,直到它们带着敬仰改正自己的错误。 -%name不对开源项目作出贡献;开源项目对%name作出贡献。 -%name的胡须里面不是下巴,而是另一撮胡须。如此递归直至无穷。 -%name曾经得过猪流感,但是该病毒很快被GPL污染并且同化了。 -无论何时世界上有人写出一个‘Hello, world’程序,%name总以“Hello”回应。 -%name从不编译,他只要闭上眼睛,就能看见编译器优化时二进制位之间的能量流动被创造出来…… -如果%name有一个1GB的内存,你有一个1GB的内存,那么%name拥有比你更多的内存。 -当%name执行ps -e时,你的名字会出现。 -从来就没有软件开发过程这回事,只有被%name允许存在的一些程序。 -%name的DNA中包含调试符号。尽管他从不需要它们。 -%name的医生能通过CVS采集他的血样。 -对于%name来说,多项式时间就是O(1)。 -%name将会使可口可乐在GPL协议下公布他们的配方。 -%name不需要用鼠标或键盘来操作计算机。他只要凝视着它,直到它完成想要的工作。 -%name就是图灵测试的解答。 -%name其实没有写过CQhttp,只是字母们因为恐惧而组成了CQhttp的源代码。 -当%name%问deno能不能生产环境的时候,他是在准备给deno贡献代码让他能支持生产环境
\ No newline at end of file diff --git a/ATRI/exceptions.py b/ATRI/exceptions.py index 4ce0b17..b49d3a0 100644 --- a/ATRI/exceptions.py +++ b/ATRI/exceptions.py @@ -17,7 +17,7 @@ from .log import logger from .config import BotSelfConfig -ERROR_DIR = Path(".") / "ATRI" / "data" / "errors" +ERROR_DIR = Path(".") / "data" / "errors" os.makedirs(ERROR_DIR, exist_ok=True) @@ -34,7 +34,7 @@ def _save_error(prompt: str, content: str) -> str: track_id=track_id, prompt=prompt, time=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), - content=content, + content=content ) path = ERROR_DIR / f"{track_id}.json" with open(path, "w", encoding="utf-8") as r: @@ -96,7 +96,7 @@ async def _track_error( event: Event, state: T_State, ) -> None: - if exception is None: + if not exception: return try: @@ -110,7 +110,7 @@ async def _track_error( logger.debug(f"A bug has been cumming!!! Track ID: {track_id}") msg = f"呜——出错了...追踪: {track_id}" - + for superusers in BotSelfConfig.superusers: try: await bot.send_private_msg(user_id=superusers, message=msg) diff --git a/ATRI/log.py b/ATRI/log.py index 3766c4c..2c0301d 100644 --- a/ATRI/log.py +++ b/ATRI/log.py @@ -1,14 +1,13 @@ import sys from pathlib import Path from datetime import datetime -from typing import TYPE_CHECKING from nonebot.log import logger from .config import BotSelfConfig -LOGGER_DIR = Path(".") / "ATRI" / "data" / "logs" +LOGGER_DIR = Path(".") / "data" / "logs" LOGGER_DIR.parent.mkdir(exist_ok=True, parents=True) NOW_TIME = datetime.now().strftime("%Y%m%d-%H") diff --git a/ATRI/plugins/anime_search.py b/ATRI/plugins/anime_search.py index 80d8a94..de64501 100644 --- a/ATRI/plugins/anime_search.py +++ b/ATRI/plugins/anime_search.py @@ -24,9 +24,10 @@ __doc__ = """ class Anime(Service): + def __init__(self): Service.__init__(self, "以图搜番", __doc__, rule=is_in_service("以图搜番")) - + @staticmethod async def _request(url: str) -> dict: aim = URL + url @@ -36,12 +37,12 @@ class Anime(Service): raise RequestError("Request failed!") result = await res.json() return result - + @classmethod async def search(cls, url: str) -> str: data = await cls._request(url) data = data["docs"] - + d = dict() for i in range(len(data)): if data[i]["title_chinese"] in d.keys(): @@ -60,7 +61,7 @@ class Anime(Service): f"第{n}集", f"{int(m)}分{int(s)}秒处", ] - + result = sorted(d.items(), key=lambda x: x[1], reverse=True) t = 0 msg0 = str() @@ -73,7 +74,7 @@ class Anime(Service): f"Name: {i[0]}\n" f"Time: {i[1][1]} {i[1][2]}" ) - + if len(result) == 2: return msg0 else: @@ -89,7 +90,6 @@ class Anime(Service): anime_search = Anime().on_command("以图搜番", "发送一张图以搜索可能的番剧") - @anime_search.args_parser # type: ignore async def _get_anime(bot: Bot, event: MessageEvent, state: T_State): msg = str(event.message).strip() @@ -101,18 +101,16 @@ async def _get_anime(bot: Bot, event: MessageEvent, state: T_State): else: state["anime"] = msg - @anime_search.handle() async def _ready_sear(bot: Bot, event: MessageEvent, state: T_State): user_id = event.get_user_id() if not _anime_flmt.check(user_id): await anime_search.finish(_anime_flmt_notice) - + msg = str(event.message).strip() if msg: state["anime"] = msg - @anime_search.got("anime", "图呢?") async def _deal_sear(bot: Bot, event: MessageEvent, state: T_State): user_id = event.get_user_id() @@ -120,7 +118,7 @@ async def _deal_sear(bot: Bot, event: MessageEvent, state: T_State): img = re.findall(r"url=(.*?)]", msg) if not img: await anime_search.reject("请发送图片而不是其它东西!!") - + a = await Anime().search(img[0]) result = f"> {MessageSegment.at(user_id)}\n" + a _anime_flmt.start_cd(user_id) diff --git a/ATRI/plugins/chat/__init__.py b/ATRI/plugins/chat/__init__.py index 391e0f7..79664cc 100644 --- a/ATRI/plugins/chat/__init__.py +++ b/ATRI/plugins/chat/__init__.py @@ -15,22 +15,20 @@ _chat_flmt_notice = choice(["慢...慢一..点❤", "冷静1下", "歇会歇会~ chat = Chat().on_message("闲聊(文爱") - @chat.handle() async def _chat(bot: Bot, event: MessageEvent): + print(1) user_id = event.get_user_id() if not _chat_flmt.check(user_id): await chat.finish(_chat_flmt_notice) - + msg = str(event.message) repo = await Chat().deal(msg, user_id) _chat_flmt.start_cd(user_id) await chat.finish(repo) - my_name_is = Chat().on_command("叫我", "更改闲聊(划掉 文爱)时的称呼", aliases={"我是"}, priority=1) - @my_name_is.args_parser # type: ignore async def _get_name(bot: Bot, event: MessageEvent, state: T_State): msg = str(event.message).strip() @@ -42,30 +40,26 @@ async def _get_name(bot: Bot, event: MessageEvent, state: T_State): else: state["name"] = msg - @my_name_is.handle() async def _name(bot: Bot, event: MessageEvent, state: T_State): user_id = event.get_user_id() if not _chat_flmt.check(user_id): await my_name_is.finish(_chat_flmt_notice) - + msg = str(event.message).strip() if msg: state["name"] = msg - @my_name_is.got("name", "欧尼酱想让咱如何称呼呢!0w0") async def _deal_name(bot: Bot, event: MessageEvent, state: T_State): user_id = event.get_user_id() new_name = state["name"] - repo = choice( - [ - f"好~w 那咱以后就称呼你为{new_name}!", - f"噢噢噢!原来你叫{new_name}阿~", - f"好欸!{new_name}ちゃん~~~", - "很不错的称呼呢w", - ] - ) + repo = choice([ + f"好~w 那咱以后就称呼你为{new_name}!", + f"噢噢噢!原来你叫{new_name}阿~", + f"好欸!{new_name}ちゃん~~~", + "很不错的称呼呢w" + ]) Chat().name_is(user_id, new_name) _chat_flmt.start_cd(user_id) await my_name_is.finish(repo) @@ -73,7 +67,6 @@ async def _deal_name(bot: Bot, event: MessageEvent, state: T_State): say = Chat().on_command("说", "别人让我说啥就说啥(", priority=1) - @say.args_parser # type: ignore async def _get_say(bot: Bot, event: MessageEvent, state: T_State): msg = str(event.message).strip() @@ -85,26 +78,29 @@ async def _get_say(bot: Bot, event: MessageEvent, state: T_State): else: state["say"] = msg - @say.handle() async def _ready_say(bot: Bot, event: MessageEvent, state: T_State): user_id = event.get_user_id() if not _chat_flmt.check(user_id): await say.finish(_chat_flmt_notice) - + msg = str(event.message) if msg: state["say"] = msg - @say.got("say") async def _deal_say(bot: Bot, event: MessageEvent, state: T_State): msg = state["say"] check = CoolqCodeChecker(msg).check if not check: - repo = choice(["不要...", "这个咱不想复读!", "不可以", "不好!"]) + repo = choice([ + "不要...", + "这个咱不想复读!", + "不可以", + "不好!" + ]) await say.finish(repo) - + user_id = event.get_user_id() _chat_flmt.start_cd(user_id) await say.finish(msg) diff --git a/ATRI/plugins/chat/data_source.py b/ATRI/plugins/chat/data_source.py index 74dde96..15c495d 100644 --- a/ATRI/plugins/chat/data_source.py +++ b/ATRI/plugins/chat/data_source.py @@ -15,23 +15,22 @@ __doc__ = """ 好像有点涩?(偏文爱,需at """ -CHAT_PATH = Path(".") / "ATRI" / "data" / "database" / "chat" +CHAT_PATH = Path(".") / "data" / "database" / "chat" os.makedirs(CHAT_PATH, exist_ok=True) KIMO_URL = "https://cdn.jsdelivr.net/gh/Kyomotoi/AnimeThesaurus/data.json" class Chat(Service): + def __init__(self): - Service.__init__( - self, "闲聊", __doc__, rule=to_bot() & is_in_service("闲聊"), priority=5 - ) - + Service.__init__(self, "闲聊", __doc__, rule=to_bot() & is_in_service("闲聊"), priority=5) + @staticmethod async def _request(url: str) -> dict: res = await request.get(url) data = await res.json() return data - + @classmethod async def _generate_data(cls) -> None: file_name = "kimo.json" @@ -45,18 +44,18 @@ class Chat(Service): log.info("生成完成") except WriteError: raise WriteError("Writing kimo words failed!") - + @classmethod async def _load_data(cls) -> dict: file_name = "kimo.json" path = CHAT_PATH / file_name if not path.is_file(): await cls._generate_data() - + with open(path, "r", encoding="utf-8") as r: data = json.loads(r.read()) return data - + @classmethod async def update_data(cls) -> None: log.info("更新闲聊词库ing...") @@ -64,17 +63,17 @@ class Chat(Service): path = CHAT_PATH / file_name if not path.is_file(): await cls._generate_data() - + updata_data = await cls._request(KIMO_URL) data = json.loads(path.read_bytes()) for i in updata_data: if i not in data: data[i] = updata_data[i] - + with open(path, "w", encoding="utf-8") as w: w.write(json.dumps(data, indent=4)) log.info("闲聊词库更新完成") - + @staticmethod def name_is(user_id: str, new_name: str): file_name = "users.json" @@ -83,7 +82,7 @@ class Chat(Service): with open(path, "w", encoding="utf-8") as w: w.write(json.dumps({})) data = {} - + data = json.loads(path.read_bytes()) data[user_id] = new_name try: @@ -91,7 +90,7 @@ class Chat(Service): w.write(json.dumps(data, indent=4)) except ReadFileError: raise ReadFileError("Update user name failed!") - + @staticmethod def load_name(user_id: str) -> str: file_name = "users.json" @@ -100,21 +99,21 @@ class Chat(Service): with open(path, "w", encoding="utf-8") as w: w.write(json.dumps({})) return "你" - + data = json.loads(path.read_bytes()) try: result = data[user_id] except BaseException: result = "你" return result - + @classmethod async def deal(cls, msg: str, user_id: str) -> str: keywords = posseg.lcut(msg) shuffle(keywords) - + data = await cls._load_data() - + repo = str() for i in keywords: a = i.word @@ -126,14 +125,14 @@ class Chat(Service): pass if a in data: repo = data.get(a, str()) - + if not repo: temp_data = list(data) shuffle(temp_data) for i in temp_data: if i in msg: repo = data.get(i, str()) - + a = choice(repo) if type(repo) is list else repo user_name = cls.load_name(user_id) repo = a.replace("你", user_name) diff --git a/ATRI/plugins/code_runner/__init__.py b/ATRI/plugins/code_runner/__init__.py index 3f5697b..dfe6162 100644 --- a/ATRI/plugins/code_runner/__init__.py +++ b/ATRI/plugins/code_runner/__init__.py @@ -13,16 +13,15 @@ _flmt_notice = choice(["慢...慢一..点❤", "冷静1下", "歇会歇会~~"]) code_runner = CodeRunner().on_command("/code", "在线运行一段代码,帮助:/code help") - @code_runner.handle() async def _code_runner(bot: Bot, event: MessageEvent): user_id = event.get_user_id() if not _flmt.check(user_id): await code_runner.finish(_flmt_notice) - + msg = str(event.get_message()) args = msg.split("\n") - + if not args: content = f"> {MessageSegment.at(user_id)}\n" + "请键入 /code help 以获取帮助~!" elif args[0] == "help": @@ -31,6 +30,6 @@ async def _code_runner(bot: Bot, event: MessageEvent): content = f"> {MessageSegment.at(user_id)}\n" + CodeRunner().list_supp_lang() else: content = MessageSegment.at(user_id) + await CodeRunner().runner(msg) - + _flmt.start_cd(user_id) await code_runner.finish(Message(content)) diff --git a/ATRI/plugins/code_runner/data_source.py b/ATRI/plugins/code_runner/data_source.py index 4338697..bbe0d2e 100644 --- a/ATRI/plugins/code_runner/data_source.py +++ b/ATRI/plugins/code_runner/data_source.py @@ -40,9 +40,10 @@ __doc__ = """ class CodeRunner(Service): + def __init__(self): Service.__init__(self, "在线跑代码", __doc__, rule=is_in_service("在线跑代码")) - + @staticmethod def help() -> str: return ( @@ -52,23 +53,23 @@ class CodeRunner(Service): "/code python\n" "print('hello world')" ) - + @staticmethod def list_supp_lang() -> str: msg0 = "咱现在支持的语言如下:\n" msg0 += ", ".join(map(str, SUPPORTED_LANGUAGES.keys())) return msg0 - + @staticmethod async def runner(msg: str): args = msg.split("\n") if not args: return "请检查键入内容..." - + lang = args[0].replace("\r", "") if lang not in SUPPORTED_LANGUAGES: return "该语言暂不支持..." - + del args[0] code = "\n".join(map(str, args)) url = RUN_API_URL_FORMAT.format(lang) @@ -83,14 +84,14 @@ class CodeRunner(Service): } ], "stdin": "", - "command": "", + "command": "" } - + try: res = await request.post(url, json=js) except RequestError: raise RequestError("Request failed!") - + payload = await res.json() sent = False for k in ["stdout", "stderr", "error"]: @@ -99,12 +100,12 @@ class CodeRunner(Service): lines, remained_lines = lines[:10], lines[10:] out = "\n".join(lines) out, remained_out = out[: 60 * 10], out[60 * 10 :] - + if remained_lines or remained_out: out += f"\n(太多了太多了...)" - + if out: return f"\n{k}:\n{out}" - + if not sent: - return "\n运行完成,没任何输出呢..." + return "\n运行完成,没任何输出呢..."
\ No newline at end of file diff --git a/ATRI/plugins/console/__init__.py b/ATRI/plugins/console/__init__.py new file mode 100644 index 0000000..60cc305 --- /dev/null +++ b/ATRI/plugins/console/__init__.py @@ -0,0 +1,76 @@ +from typing import Optional +from datetime import datetime + +from nonebot.typing import T_State +from nonebot.matcher import Matcher +from nonebot.message import run_postprocessor +from nonebot.adapters import Bot, Event + +import ATRI +from ATRI.utils.apscheduler import scheduler +from .data_source import Console +from .drivers import register_route + + +driver = ATRI.driver() + + [email protected]_bot_connect +async def _connect(bot): + Console().store_connect_stat(True) + + [email protected]_bot_disconnect +async def _disconnect(bot): + Console().store_connect_stat(False) + + +msg_freq = 0 +health_freq = 0 +error_freq = 0 + + +record_msg = Console().on_message(block=False) + +@record_msg.handle() +async def _record_msg(bot: Bot, event: Event): + global msg_freq + msg_freq += 1 + + +@run_postprocessor # type: ignore +async def _record_is_error( + matcher: Matcher, + exception: Optional[Exception], + bot: Bot, + event: Event, + state: T_State +): + global health_freq, error_freq + if matcher.type != "message": + if not exception: + health_freq += 1 + else: + error_freq += 1 + + [email protected]_job("interval", minutes=1) +async def _record_data(): + global msg_freq, health_freq, error_freq + now_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + data = { + "time": now_time, + "freq_data": { + "msg": msg_freq, + "health": health_freq, + "error": error_freq + } + } + Console().record_data(data) + msg_freq, health_freq, error_freq = 0, 0, 0 + + +def init(): + register_route() + +init() diff --git a/ATRI/plugins/manege/atri-manege/.gitignore b/ATRI/plugins/console/atri-manege/.gitignore index 403adbc..403adbc 100644 --- a/ATRI/plugins/manege/atri-manege/.gitignore +++ b/ATRI/plugins/console/atri-manege/.gitignore diff --git a/ATRI/plugins/manege/README.md b/ATRI/plugins/console/atri-manege/README.md index 9586585..76a103b 100644 --- a/ATRI/plugins/manege/README.md +++ b/ATRI/plugins/console/atri-manege/README.md @@ -1,9 +1,9 @@ ## ATRI 前端管理界面 能做的事情: - - 功能控制 - - 插件附带信息管理 + - 可视化消息频率、功能调用频率、报错频率 **TODO**: + - [ ] 功能控制 - [ ] 前端UI聊天界面 - [ ] 结合[`nonebot-test`](https://github.com/nonebot/plugin-test)制成属于本项目的测试页面 diff --git a/ATRI/plugins/manege/atri-manege/babel.config.js b/ATRI/plugins/console/atri-manege/babel.config.js index e955840..e955840 100644 --- a/ATRI/plugins/manege/atri-manege/babel.config.js +++ b/ATRI/plugins/console/atri-manege/babel.config.js diff --git a/ATRI/plugins/manege/atri-manege/package-lock.json b/ATRI/plugins/console/atri-manege/package-lock.json index 580e686..580e686 100644 --- a/ATRI/plugins/manege/atri-manege/package-lock.json +++ b/ATRI/plugins/console/atri-manege/package-lock.json diff --git a/ATRI/plugins/manege/atri-manege/package.json b/ATRI/plugins/console/atri-manege/package.json index 56085b3..56085b3 100644 --- a/ATRI/plugins/manege/atri-manege/package.json +++ b/ATRI/plugins/console/atri-manege/package.json diff --git a/ATRI/plugins/console/atri-manege/public/favicon.ico b/ATRI/plugins/console/atri-manege/public/favicon.ico Binary files differnew file mode 100644 index 0000000..df36fcf --- /dev/null +++ b/ATRI/plugins/console/atri-manege/public/favicon.ico diff --git a/ATRI/plugins/console/atri-manege/public/index.html b/ATRI/plugins/console/atri-manege/public/index.html new file mode 100644 index 0000000..bc51465 --- /dev/null +++ b/ATRI/plugins/console/atri-manege/public/index.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width,initial-scale=1.0"> + <link rel="icon" href="<%= BASE_URL %>favicon.ico"> + <title><%= htmlWebpackPlugin.options.title %></title> + <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900"> + <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css"> + </head> + <body> + <noscript> + <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> + </noscript> + <div id="app"></div> + <!-- built files will be auto injected --> + </body> +</html> diff --git a/ATRI/plugins/console/atri-manege/src/App.vue b/ATRI/plugins/console/atri-manege/src/App.vue new file mode 100644 index 0000000..5b0775d --- /dev/null +++ b/ATRI/plugins/console/atri-manege/src/App.vue @@ -0,0 +1,120 @@ +<template> + <v-app> + <v-navigation-drawer app v-model="drawer" class="na-d-0"> + <v-list + nav + dense + > + <v-list-item-group active-class="nattier-blue--text text--accent-4"> + <router-link to="/" tag="v-list-item-title"> + <v-list-item> + <v-list-item-icon> + <v-icon>mdi-home</v-icon> + </v-list-item-icon> + <v-list-item-title>主页 | Home</v-list-item-title> + </v-list-item> + </router-link> + + <router-link to="/control" tag="v-list-item-title"> + <v-list-item> + <v-list-item-icon> + <v-icon>mdi-wrench</v-icon> + </v-list-item-icon> + <v-list-item-title>控制面板 | Control</v-list-item-title> + </v-list-item> + </router-link> + + <router-link to="/data" tag="v-list-item-title"> + <v-list-item> + <v-list-item-icon> + <v-icon>mdi-database</v-icon> + </v-list-item-icon> + <v-list-item-title>数据 | Data</v-list-item-title> + </v-list-item> + </router-link> + + <router-link to="/chat" tag="v-list-item-title"> + <v-list-item> + <v-list-item-icon> + <v-icon>mdi-comment-processing</v-icon> + </v-list-item-icon> + <v-list-item-title>聊天 | Chat</v-list-item-title> + </v-list-item> + </router-link> + + <router-link to="/a-test" tag="v-list-item-title"> + <v-list-item> + <v-list-item-icon> + <v-icon>mdi-debug-step-over</v-icon> + </v-list-item-icon> + <v-list-item-title>测试 | Test</v-list-item-title> + </v-list-item> + </router-link> + </v-list-item-group> + </v-list> + </v-navigation-drawer> + + <v-app-bar app color="white" flat> + <v-app-bar-nav-icon @click="drawer = !drawer"></v-app-bar-nav-icon> + + <router-link to="/" tag="v-toolbar-title"> + <v-toolbar-title>ATRI Console</v-toolbar-title> + </router-link> + + <v-spacer></v-spacer> + + <v-btn href="https://jq.qq.com/?_wv=1027&k=iKLJzM1u" target="_blank" text> + <span class="mr-2">Discuss</span> + <v-icon small>mdi-qqchat</v-icon> + </v-btn> + + <v-btn href="https://github.com/Kyomotoi/ATRI" target="_blank" text> + <span class="mr-2">GitHub</span> + <v-icon small>mdi-link-variant</v-icon> + </v-btn> + </v-app-bar> + + <v-main> + <v-container fluid> + <v-lazy> + <router-view></router-view> + </v-lazy> + </v-container> + </v-main> + + <v-footer app> + <v-divider></v-divider> + <v-container fluid> + <v-row align="center" justify="center"> + <v-col class="text-center" cols="auto"> + <span> <v-icon>mdi-copyright</v-icon> Yours <strong>Kyomotoi</strong> </span> + </v-col> + <v-col class="text-center" cols="auto"> + <span> <v-icon>mdi-github</v-icon> <strong>ATRI</strong> </span> + </v-col> + </v-row> + </v-container> + </v-footer> + </v-app> +</template> + +<script> + +export default { + name: 'App', + + data: () => ({ + drawer: true, + }), +}; +</script> + +<style> +.text-center.a:visited { + color: aliceblue; +} + +.na-d-0 { + background-image: url("https://i.loli.net/2021/07/19/WlFanrZHRQxb5Ay.png"); +} +</style> diff --git a/ATRI/plugins/console/atri-manege/src/assets/logo.png b/ATRI/plugins/console/atri-manege/src/assets/logo.png Binary files differnew file mode 100644 index 0000000..f3d2503 --- /dev/null +++ b/ATRI/plugins/console/atri-manege/src/assets/logo.png diff --git a/ATRI/plugins/console/atri-manege/src/assets/logo.svg b/ATRI/plugins/console/atri-manege/src/assets/logo.svg new file mode 100644 index 0000000..145b6d1 --- /dev/null +++ b/ATRI/plugins/console/atri-manege/src/assets/logo.svg @@ -0,0 +1 @@ +<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 87.5 100"><defs><style>.cls-1{fill:#1697f6;}.cls-2{fill:#7bc6ff;}.cls-3{fill:#1867c0;}.cls-4{fill:#aeddff;}</style></defs><title>Artboard 46</title><polyline class="cls-1" points="43.75 0 23.31 0 43.75 48.32"/><polygon class="cls-2" points="43.75 62.5 43.75 100 0 14.58 22.92 14.58 43.75 62.5"/><polyline class="cls-3" points="43.75 0 64.19 0 43.75 48.32"/><polygon class="cls-4" points="64.58 14.58 87.5 14.58 43.75 100 43.75 62.5 64.58 14.58"/></svg> diff --git a/ATRI/plugins/console/atri-manege/src/data/console/2021-07-24-runtime-freq.json b/ATRI/plugins/console/atri-manege/src/data/console/2021-07-24-runtime-freq.json new file mode 100644 index 0000000..7a85c67 --- /dev/null +++ b/ATRI/plugins/console/atri-manege/src/data/console/2021-07-24-runtime-freq.json @@ -0,0 +1,946 @@ +[ + { + "time": "2021-07-24 15:20:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:21:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:22:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:23:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:24:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:25:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:26:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:27:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:28:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:29:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:30:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:31:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:32:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:33:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:34:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:35:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:36:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:37:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:38:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:39:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:40:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:41:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:42:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:43:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:44:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:45:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:46:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:47:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:48:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:49:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:50:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:51:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:52:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:53:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:54:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:55:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:56:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:57:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:58:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 15:59:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:00:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:01:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:02:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:03:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:04:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:05:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:06:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:07:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:08:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:09:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:10:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:11:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:12:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:13:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:14:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:15:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:16:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:17:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:18:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:19:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:20:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:21:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:22:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:23:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:24:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:25:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:26:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:27:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:28:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:29:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:30:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:31:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:32:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:33:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:34:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:35:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:36:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:37:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:38:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:39:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:40:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:41:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:42:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:43:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:44:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:45:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:46:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:47:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:48:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:49:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:50:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:51:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:52:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:53:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:54:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:55:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:56:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:57:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:58:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 16:59:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 17:00:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 17:01:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 17:02:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 17:03:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 17:04:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 17:05:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 17:06:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 17:07:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 17:08:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 17:09:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 17:10:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 17:12:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 17:13:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 17:14:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 17:15:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 17:16:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 17:17:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + }, + { + "time": "2021-07-24 17:18:20", + "freq": { + "msg": 0, + "health": 0, + "error": 0 + } + } +] diff --git a/ATRI/plugins/console/atri-manege/src/data/console/is_connect.json b/ATRI/plugins/console/atri-manege/src/data/console/is_connect.json new file mode 100644 index 0000000..7fe0350 --- /dev/null +++ b/ATRI/plugins/console/atri-manege/src/data/console/is_connect.json @@ -0,0 +1,3 @@ +{ + "connect": false +}
\ No newline at end of file diff --git a/ATRI/plugins/manege/atri-manege/src/main.js b/ATRI/plugins/console/atri-manege/src/main.js index 917702d..d1a291e 100644 --- a/ATRI/plugins/manege/atri-manege/src/main.js +++ b/ATRI/plugins/console/atri-manege/src/main.js @@ -9,4 +9,4 @@ new Vue({ router, vuetify, render: h => h(App) -}).$mount('#app') +}).$mount('#app'); diff --git a/ATRI/plugins/manege/atri-manege/src/plugins/vuetify.js b/ATRI/plugins/console/atri-manege/src/plugins/vuetify.js index 5bdec19..5bdec19 100644 --- a/ATRI/plugins/manege/atri-manege/src/plugins/vuetify.js +++ b/ATRI/plugins/console/atri-manege/src/plugins/vuetify.js diff --git a/ATRI/plugins/console/atri-manege/src/router/index.js b/ATRI/plugins/console/atri-manege/src/router/index.js new file mode 100644 index 0000000..480f5d0 --- /dev/null +++ b/ATRI/plugins/console/atri-manege/src/router/index.js @@ -0,0 +1,40 @@ +import Vue from 'vue' +import VueRouter from 'vue-router' + +Vue.use(VueRouter) + +const routes = [ + { + path: '/', + name: '主页 | Home', + component: () => import('../views/Home.vue') + }, + { + path: '/control', + name: '控制面板 | Control', + component: () => import('../views/Control.vue') + }, + { + path: '/data', + name: '数据 | Data', + component: () => import('../views/Data.vue') + }, + { + path: '/chat', + name: '聊天 | Chat', + component: () => import('../views/Chat.vue') + }, + { + path: '/a-test', + name: '测试 | Test', + component: () => import('../views/Test.vue') + } +] + +const router = new VueRouter({ + mode: 'history', + base: process.env.BASE_URL, + routes +}) + +export default router diff --git a/ATRI/plugins/console/atri-manege/src/views/Chat.vue b/ATRI/plugins/console/atri-manege/src/views/Chat.vue new file mode 100644 index 0000000..0d4179e --- /dev/null +++ b/ATRI/plugins/console/atri-manege/src/views/Chat.vue @@ -0,0 +1,5 @@ +<template> + <div class="chat"> + <h1>Comming soon...</h1> + </div> +</template> diff --git a/ATRI/plugins/console/atri-manege/src/views/Control.vue b/ATRI/plugins/console/atri-manege/src/views/Control.vue new file mode 100644 index 0000000..ca64a32 --- /dev/null +++ b/ATRI/plugins/console/atri-manege/src/views/Control.vue @@ -0,0 +1,5 @@ +<template> + <div class="control"> + <h1>Comming soon...</h1> + </div> +</template> diff --git a/ATRI/plugins/console/atri-manege/src/views/Data.vue b/ATRI/plugins/console/atri-manege/src/views/Data.vue new file mode 100644 index 0000000..020ac37 --- /dev/null +++ b/ATRI/plugins/console/atri-manege/src/views/Data.vue @@ -0,0 +1,5 @@ +<template> + <div class="data"> + <h1>Comming soon...</h1> + </div> +</template> diff --git a/ATRI/plugins/console/atri-manege/src/views/Home.vue b/ATRI/plugins/console/atri-manege/src/views/Home.vue new file mode 100644 index 0000000..f630139 --- /dev/null +++ b/ATRI/plugins/console/atri-manege/src/views/Home.vue @@ -0,0 +1,251 @@ +<template> + <v-app> + <h1 class="h1-index">ATRI is Running</h1> + + <v-divider></v-divider> + + <v-col> + <h3 class="h3-index">主体状态 | Status</h3> + </v-col> + <v-container> + <v-col> + <v-row> + <v-card height="170" width="400" class="ma-1"> + <v-card-title>WS状态 | Websocket Status</v-card-title> + <div class="text-center"> + <v-chip + class="ma-2" + color="green" + text-color="white" + > + <div id="isConnect"></div> + </v-chip> + </div> + </v-card> + + <v-card height="170" width="400" class="ma-1"> + <v-card-title>自身状态 | Self Status</v-card-title> + <div class="text-center"> + <v-chip + class="ma-2" + color="green" + text-color="white" + > + <div id="selfStatus"></div> + </v-chip> + </div> + </v-card> + </v-row> + </v-col> + </v-container> + + <v-divider></v-divider> + + <v-col> + <h3 class="h3-index">记录仪 | Dashboard</h3> + <div id="container" class="test-box"></div> + </v-col> + </v-app> +</template> + +<script> +import * as echarts from 'echarts' + +export default { + mounted() { + function sleep (time) { + return new Promise((resolve) => setTimeout(resolve, time)); + } + + function isConnect() { + try { + var url = "http://127.0.0.1:20000/bot/is_connect" + var req = new XMLHttpRequest(); + req.open("get", url); + req.send(null); + req.onload = function() { + if (req.status == 200) { + let data = JSON.parse(req.responseText); + if (data.is_connect) { + document.getElementById("isConnect").innerHTML = "Connected"; + } else { + document.getElementById("isConnect").innerHTML = "Lost Connection"; + } + } else { + document.getElementById("isConnect").innerHTML = "Failed to get DATA"; + } + } + } catch { + document.getElementById("isConnect").innerHTML = "ERROR"; + } + } + + function getStatus() { + try { + var url = "http://127.0.0.1:20000/bot/status" + var req = new XMLHttpRequest(); + req.open("get", url); + req.send(null); + req.onload = function() { + if (req.status == 200) { + let data = JSON.parse(req.responseText); + document.getElementById("selfStatus").innerHTML = data.message; + } + } + } catch { + document.getElementById("isConnect").innerHTML = "ERROR"; + } + } + + function dashboard() { + var data_time = ["0"]; + var data_msg = [0]; + var data_health = [0]; + var data_error = [0]; + + try { + var url = "http://127.0.0.1:20000/bot/dashboard_info" + var req = new XMLHttpRequest(); + req.open('GET', url); + req.send(null); + req.onload = function () { + var t_data = JSON.parse(req.responseText); + var t_data_l = t_data.data + for (var i = 0; i < t_data_l.length; i++) { + data_time.push(t_data_l[i].time) + data_msg.push(t_data_l[i].freq_data.msg) + data_health.push(t_data_l[i].freq_data.health) + data_error.push(t_data_l[i].freq_data.error) + } + } + } catch { + document.getElementById("container").innerHTML = "Failed to get DATA!" + return + } + + sleep(100).then( + () => { + let myChart = echarts.init(document.getElementById("container")); + let option = { + title: { + subtext: '数据统计间隔:1分钟', + left: '10' + }, + legend: { + data: ['接受信息', '服务调用成功速率', '服务调用失败速率'] + }, + color: ["#2d85f0", "#ffbc32", "#f4433c"], + tooltip: { + trigger: 'axis' + }, + grid: { + left: '3%', + right: '4%', + bottom: '3%', + containLabel: true + }, + axisPointer: { + show: true, + }, + dataZoom: [ + { + type: 'slider', + show: true, + xAxisIndex: [0], + start: 70, + end: 100 + }, + { + type: 'slider', + show: true, + yAxisIndex: [0] + }, + { + type: 'inside', + xAxisIndex: [0], + start: 70, + end: 100 + }, + { + type: 'inside', + yAxisIndex: [0] + } + ], + toolbox: { + feature: { + dataZoom: { + yAxisIndex: false, + xAxisIndex: false + }, + restore: {}, + saveAsImage: {} + } + }, + xAxis: [ + { + type: 'category', + boundaryGap: false, + axisLine: {onZero: false}, + data: data_time + }, + ], + yAxis: { + type: 'value' + }, + series: [ + { + name: '接受信息', + type: 'line', + areaStyle: {}, + data: data_msg + }, + { + name: '服务调用成功速率', + type: 'line', + areaStyle: {}, + data: data_health + }, + { + name: '服务调用失败速率', + type: 'line', + areaStyle: {}, + data: data_error + } + ] + }; + + console.info(data_time); + console.info(data_msg); + console.info(data_error); + myChart.setOption(option); + window.onresize = myChart.resize; + } + ) + } + + setInterval(isConnect(), 100); + setInterval(getStatus(), 1000); + setInterval(dashboard(), 6000); + } + + +} +</script> + +<style> +.h1-index { + font-size: 240%; + color: #8f8f8f; +} + +.h3-index { + color: #8f8f8f; +} + +.test-box { + width: 100%; + height: 500px; + background-color: white; +} + +</style> diff --git a/ATRI/plugins/console/atri-manege/src/views/Test.vue b/ATRI/plugins/console/atri-manege/src/views/Test.vue new file mode 100644 index 0000000..442a950 --- /dev/null +++ b/ATRI/plugins/console/atri-manege/src/views/Test.vue @@ -0,0 +1,5 @@ +<template> + <div class="test"> + <h1>Comming soon...</h1> + </div> +</template> diff --git a/ATRI/plugins/manege/atri-manege/vue.config.js b/ATRI/plugins/console/atri-manege/vue.config.js index 2ae460b..2ae460b 100644 --- a/ATRI/plugins/manege/atri-manege/vue.config.js +++ b/ATRI/plugins/console/atri-manege/vue.config.js diff --git a/ATRI/plugins/console/data_source.py b/ATRI/plugins/console/data_source.py new file mode 100644 index 0000000..8fe6c04 --- /dev/null +++ b/ATRI/plugins/console/data_source.py @@ -0,0 +1,56 @@ +import os +import json +from pathlib import Path +from datetime import datetime + +from ATRI.service import Service + + +CONSOLE_DIR = Path(".") / "data" / "database" / "console" +os.makedirs(CONSOLE_DIR, exist_ok=True) + + +is_connect = False + + +class Console(Service): + + def __init__(self): + Service.__init__(self, "控制台") + + @staticmethod + def record_data(data: dict) -> None: + now_time = datetime.now().strftime("%Y-%m-%d") + file_name = f"{now_time}-runtime.json" + path = CONSOLE_DIR / file_name + if not path.is_file(): + with open(path ,"w", encoding="utf-8") as w: + w.write(json.dumps(list())) + temp_data = list() + + temp_data: list = json.loads(path.read_bytes()) + temp_data.append(data) + with open(path, "w", encoding="utf-8") as w: + w.write(json.dumps(temp_data, indent=4)) + + @staticmethod + def load_data() -> list: + now_time = datetime.now().strftime("%Y-%m-%d") + file_name = f"{now_time}-runtime.json" + path = CONSOLE_DIR / file_name + if not path.is_file(): + with open(path, "w", encoding="utf-8") as w: + w.write(json.dumps(list())) + return list() + + data: list = json.loads(path.read_bytes()) + return data + + @staticmethod + def store_connect_stat(i: bool): + global is_connect + is_connect = i + + @staticmethod + def is_connect() -> bool: + return is_connect diff --git a/ATRI/plugins/console/drivers.py b/ATRI/plugins/console/drivers.py new file mode 100644 index 0000000..e691a7c --- /dev/null +++ b/ATRI/plugins/console/drivers.py @@ -0,0 +1,37 @@ +from pathlib import Path + +from fastapi.staticfiles import StaticFiles +from fastapi.middleware.cors import CORSMiddleware + +import ATRI +from .view import handle_is_connect, handle_dashboard_info, handle_status + + +origins = [ + "http://localhost.tiangolo.com", + "https://localhost.tiangolo.com", + "http://localhost", + "http://localhost:8080", + "http://localhost:20000" +] + + +def register_route(): + app = ATRI.driver().server_app + app.add_middleware( + CORSMiddleware, + allow_origins=origins, + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"] + ) + + static_path = str((Path(".") / "ATRI" / "plugins" / "console" / "atri-manege" / "dist").absolute()) + + app.get("/bot/is_connect")(handle_is_connect) + app.get("/bot/status")(handle_status) + app.get("/bot/dashboard_info")(handle_dashboard_info) + + app.mount("/", + StaticFiles(directory=static_path, html=True), + name="bot") diff --git a/ATRI/plugins/console/view.py b/ATRI/plugins/console/view.py new file mode 100644 index 0000000..dde3533 --- /dev/null +++ b/ATRI/plugins/console/view.py @@ -0,0 +1,29 @@ +import ATRI +from ..status import info_msg +from .data_source import Console + + +driver = ATRI.driver() + + +async def handle_is_connect(): + data = Console().is_connect() + return { + "status": 200, + "is_connect": data + } + + +async def handle_status(): + return { + "status": 200, + "message": info_msg + } + + +async def handle_dashboard_info(): + data = Console().load_data() + return { + "status": 200, + "data": data + } diff --git a/ATRI/plugins/curse.py b/ATRI/plugins/curse.py index edd6249..b2dbc05 100644 --- a/ATRI/plugins/curse.py +++ b/ATRI/plugins/curse.py @@ -20,9 +20,10 @@ __doc__ = """ class Curse(Service): + def __init__(self): Service.__init__(self, "口臭", __doc__, rule=is_in_service("口臭")) - + @staticmethod async def now() -> str: res = await request.get(URL) @@ -30,17 +31,14 @@ class Curse(Service): return result -normal_curse = Curse().on_command( - "口臭一下", "主命令,骂你一下", aliases={"骂我", "口臭"}, rule=to_bot() -) - +normal_curse = Curse().on_command("口臭一下", "主命令,骂你一下", aliases={"骂我", "口臭"}, rule=to_bot()) @normal_curse.handle() async def _deal_n_curse(bot: Bot, event: MessageEvent): user_id = event.get_user_id() if not _curse_flmt.check(user_id): await normal_curse.finish(_curse_flmt_notice) - + result = await Curse().now() _curse_flmt.start_cd(user_id) await normal_curse.finish(result) @@ -48,13 +46,12 @@ async def _deal_n_curse(bot: Bot, event: MessageEvent): super_curse = Curse().on_regex(r"[来求有](.*?)骂我吗?", "有求必应") - @super_curse.handle() async def _deal_s_curse(bot: Bot, event: MessageEvent): user_id = event.get_user_id() if not _curse_flmt.check(user_id): await normal_curse.finish(_curse_flmt_notice) - + result = await Curse().now() _curse_flmt.start_cd(user_id) await normal_curse.finish(result) diff --git a/ATRI/plugins/essential.py b/ATRI/plugins/essential.py index 0bffb03..2b367a5 100644 --- a/ATRI/plugins/essential.py +++ b/ATRI/plugins/essential.py @@ -36,8 +36,8 @@ from ATRI.utils import CoolqCodeChecker driver = ATRI.driver() bots = nonebot.get_bots() -ESSENTIAL_DIR = Path(".") / "ATRI" / "data" / "database" / "essential" -MANEGE_DIR = Path(".") / "ATRI" / "data" / "database" / "manege" +ESSENTIAL_DIR = Path(".") / "data" / "database" / "essential" +MANEGE_DIR = Path(".") / "data" / "database" / "manege" os.makedirs(ESSENTIAL_DIR, exist_ok=True) os.makedirs(MANEGE_DIR, exist_ok=True) @@ -62,9 +62,9 @@ async def _check_block( with open(path, "w", encoding="utf-8") as w: w.write(json.dumps({})) data = dict() - + data = json.loads(path.read_bytes()) - + user_id = event.get_user_id() if user_id in data: raise IgnoredException(f"Block user: {user_id}") @@ -76,9 +76,9 @@ async def _check_block( with open(path, "w", encoding="utf-8") as w: w.write(json.dumps({})) data = dict() - + data = json.loads(path.read_bytes()) - + group_id = str(event.group_id) if group_id in data: raise IgnoredException(f"Block group: {user_id}") @@ -104,13 +104,13 @@ __doc__ = """ class Essential(Service): + def __init__(self): Service.__init__(self, "基础部件", __doc__) friend_add_event = Essential().on_request("好友添加") - @friend_add_event.handle() async def _friend_add(bot: Bot, event: FriendRequestEvent): """ @@ -130,19 +130,22 @@ async def _friend_add(bot: Bot, event: FriendRequestEvent): with open(path, "w", encoding="utf-8") as w: w.write(json.dumps({})) data = dict() - + apply_code = event.flag apply_comment = event.comment user_id = event.get_user_id() now_time = datetime.now() - + data = json.loads(path.read_bytes()) data[apply_code] = FriendRequestInfo( - user_id=user_id, comment=apply_comment, time=now_time, is_approve=False + user_id=user_id, + comment=apply_comment, + time=now_time, + is_approve=False ) with open(path, "w", encoding="utf-8") as w: w.write(json.dumps(data.dict(), indent=4)) - + repo = ( "咱收到一条好友请求...\n" f"请求人:{user_id}\n" @@ -156,7 +159,6 @@ async def _friend_add(bot: Bot, event: FriendRequestEvent): group_invite_event = Essential().on_request("邀请入群") - @group_invite_event.handle() async def _group_invite(bot: Bot, event: GroupRequestEvent): """ @@ -176,19 +178,22 @@ async def _group_invite(bot: Bot, event: GroupRequestEvent): with open(path, "w", encoding="utf-8") as w: w.write(json.dumps({})) data = dict() - + apply_code = event.flag apply_comment = event.comment user_id = event.get_user_id() now_time = datetime.now() - + data = json.loads(path.read_bytes()) data[apply_code] = GroupRequestInfo( - user_id=user_id, comment=apply_comment, time=now_time, is_approve=False + user_id=user_id, + comment=apply_comment, + time=now_time, + is_approve=False ) with open(path, "w", encoding="utf-8") as w: w.write(json.dumps(data.dict(), indent=4)) - + repo = ( "咱收到一条群聊邀请请求...\n" f"请求人:{user_id}\n" @@ -200,8 +205,24 @@ async def _group_invite(bot: Bot, event: GroupRequestEvent): await bot.send_private_msg(user_id=superuser, message=repo) -group_admin_event = Essential().on_notice("群管理变动") +group_member_event = Essential().on_notice("群成员变动") + +@group_member_event.handle() +async def _group_member_join(bot: Bot, event: GroupIncreaseNoticeEvent): + await asyncio.sleep(randint(1, 6)) + msg = ( + "好欸!事新人!\n" + f"在下 {choice(list(BotSelfConfig.nickname))} 哒!w!" + ) + await group_member_event.finish(msg) +@group_member_event.handle() +async def _group_member_left(bot: Bot, event: GroupDecreaseNoticeEvent): + await asyncio.sleep(randint(1, 6)) + await group_member_event.finish("呜——有人跑了...") + + +group_admin_event = Essential().on_notice("群管理变动") @group_admin_event.handle() async def _group_admin_event(bot: Bot, event: GroupAdminNoticeEvent): @@ -216,7 +237,6 @@ async def _group_admin_event(bot: Bot, event: GroupAdminNoticeEvent): group_ban_event = Essential().on_notice("群禁言变动") - @group_ban_event.handle() async def _group_ban_event(bot: Bot, event: GroupBanNoticeEvent): if not event.is_tome(): @@ -238,12 +258,11 @@ async def _group_ban_event(bot: Bot, event: GroupBanNoticeEvent): recall_event = Essential().on_notice("撤回事件") - @recall_event.handle() async def _recall_group_event(bot: Bot, event: GroupRecallNoticeEvent): if event.is_tome(): return - + try: repo = await bot.get_msg(message_id=event.message_id) except BaseException: @@ -256,7 +275,12 @@ async def _recall_group_event(bot: Bot, event: GroupRecallNoticeEvent): if not check: repo = repo.replace("CQ", "QC") - msg = "主人,咱拿到了一条撤回信息!\n" f"{user}@[群:{group}]\n" "撤回了\n" f"{repo}" + msg = ( + "主人,咱拿到了一条撤回信息!\n" + f"{user}@[群:{group}]\n" + "撤回了\n" + f"{repo}" + ) for superuser in BotSelfConfig.superusers: await bot.send_private_msg(user_id=int(superuser), message=msg) @@ -265,7 +289,7 @@ async def _recall_group_event(bot: Bot, event: GroupRecallNoticeEvent): async def _recall_private_event(bot: Bot, event: FriendRecallNoticeEvent): if event.is_tome(): return - + try: repo = await bot.get_msg(message_id=event.message_id) except BaseException: @@ -277,6 +301,11 @@ async def _recall_private_event(bot: Bot, event: FriendRecallNoticeEvent): if not check: repo = repo.replace("CQ", "QC") - msg = "主人,咱拿到了一条撤回信息!\n" f"{user}@[私聊]" "撤回了\n" f"{repo}" + msg = ( + "主人,咱拿到了一条撤回信息!\n" + f"{user}@[私聊]" + "撤回了\n" + f"{repo}" + ) for superuser in BotSelfConfig.superusers: await bot.send_private_msg(user_id=int(superuser), message=msg) diff --git a/ATRI/plugins/funny/__init__.py b/ATRI/plugins/funny/__init__.py index a22e2d5..4779dda 100644 --- a/ATRI/plugins/funny/__init__.py +++ b/ATRI/plugins/funny/__init__.py @@ -10,16 +10,14 @@ from .data_source import Funny get_laugh = Funny().on_command("来句笑话", "隐晦的笑话...") - @get_laugh.handle() async def _get_laugh(bot: Bot, event: MessageEvent): user_name = event.sender.nickname or "该裙友" - await get_laugh.finish(Funny().idk_laugh(user_name)) + await get_laugh.finish(await Funny().idk_laugh(user_name)) me_re_you = Funny().on_regex(r"我", "我也不懂咋解释", block=False) - @me_re_you.handle() async def _me_re_you(bot: Bot, event: MessageEvent): if randint(0, 15) == 5: @@ -29,16 +27,13 @@ async def _me_re_you(bot: Bot, event: MessageEvent): await me_re_you.finish(content) -fake_msg = Funny().on_command( - "/fakemsg", "伪造假转发内容,格式:qq-name-content\n可构造多条,使用空格隔开,仅限群聊" -) +fake_msg = Funny().on_command("/fakemsg", "伪造假转发内容,格式:qq-name-content\n可构造多条,使用空格隔开,仅限群聊") _fake_daliy_max = DailyLimiter(3) _fake_max_notice = "不能继续下去了!明早再来" _fake_flmt = FreqLimiter(60) _fake_flmt_notice = choice(["慢...慢一..点❤", "冷静1下", "歇会歇会~~"]) - @fake_msg.args_parser # type: ignore async def _perp_fake(bot: Bot, event: GroupMessageEvent, state: T_State): msg = str(event.message).strip() @@ -50,7 +45,6 @@ async def _perp_fake(bot: Bot, event: GroupMessageEvent, state: T_State): else: state["content"] = msg - @fake_msg.handle() async def _ready_fake(bot: Bot, event: GroupMessageEvent, state: T_State): user_id = event.get_user_id() @@ -58,12 +52,11 @@ async def _ready_fake(bot: Bot, event: GroupMessageEvent, state: T_State): await fake_msg.finish(_fake_max_notice) if not _fake_flmt.check(user_id): await fake_msg.finish(_fake_flmt_notice) - + msg = str(event.message).strip() if msg: state["content"] = msg - @fake_msg.got("content", "内容呢?格式:qq-name-content\n可构造多条,以上仅为一条,使用空格隔开") async def _deal_fake(bot: Bot, event: GroupMessageEvent, state: T_State): content = state["content"] @@ -71,7 +64,7 @@ async def _deal_fake(bot: Bot, event: GroupMessageEvent, state: T_State): user_id = event.get_user_id() node = Funny().fake_msg(content) await bot.send_group_forward_msg(group_id=group_id, messages=node) - + _fake_flmt.start_cd(user_id) _fake_daliy_max.increase(user_id) @@ -80,13 +73,12 @@ eat_what = Funny().on_regex(r"大?[今明后]天(.*?)吃[什啥]么?", "我来� _eat_flmt = FreqLimiter(15) - @eat_what.handle() async def _eat_what(bot: Bot, event: MessageEvent): user_id = event.get_user_id() if not _eat_flmt.check(user_id): return - + msg = str(event.get_message()) user_name = event.sender.nickname or "裙友" eat = await Funny().eat_what(user_name, msg) diff --git a/ATRI/plugins/funny/data_source.py b/ATRI/plugins/funny/data_source.py index f298683..f29b0be 100644 --- a/ATRI/plugins/funny/data_source.py +++ b/ATRI/plugins/funny/data_source.py @@ -1,50 +1,67 @@ import re +import os from pathlib import Path from random import choice, randint from nonebot.adapters.cqhttp.utils import unescape -from nonebot.adapters.cqhttp.message import MessageSegment from ATRI.service import Service +from ATRI.log import logger from ATRI.exceptions import RequestError +from ATRI.utils import request from ATRI.utils import request, Translate from ATRI.rule import is_in_service +FUNNY_DIR = Path(".") / "data" +os.makedirs(FUNNY_DIR, exist_ok=True) + + __doc__ = """ 乐1乐,莫当真 """ class Funny(Service): + def __init__(self): Service.__init__(self, "乐", __doc__, rule=is_in_service("乐")) - + @staticmethod - def idk_laugh(name: str) -> str: + async def idk_laugh(name: str) -> str: laugh_list = list() - - file_path = Path(".") / "ATRI" / "data" / "database" / "funny" / "laugh.txt" - with open(file_path, encoding="utf-8") as r: + + file_name = "laugh.txt" + path = FUNNY_DIR / file_name + if not path.is_file(): + logger.warning("未发现笑话相关数据,正在下载并保存...") + url = "https://cdn.jsdelivr.net/gh/Kyomotoi/CDN@master/project/ATRI/laugh.txt" + res = await request.get(url) + context = await res.text() # type: ignore + with open(path, "w", encoding="utf-8") as w: + w.write(context) + logger.warning("完成") + + with open(path, "r", encoding="utf-8") as r: for line in r: laugh_list.append(line.strip("\n")) - + rd: str = choice(laugh_list) result = rd.replace("%name", name) return result - + @staticmethod def me_re_you(msg: str) -> tuple: if "我" in msg and "[CQ" not in msg: return msg.replace("我", "你"), True else: return msg, False - + @staticmethod def fake_msg(text: str) -> list: arg = text.split(" ") node = list() - + for i in arg: args = i.split("-") qq = args[0] @@ -53,7 +70,7 @@ class Funny(Service): dic = {"type": "node", "data": {"name": name, "uin": qq, "content": repo}} node.append(dic) return node - + @staticmethod async def eat_what(name: str, msg: str) -> str: EAT_URL = "https://wtf.hiigara.net/api/run/" @@ -62,7 +79,7 @@ class Funny(Service): pattern_1 = r"(今|明|后|大后)天" arg = re.findall(pattern_0, msg)[0] day = re.match(pattern_1, msg).group(0) # type: ignore - + if arg == "中午": a = f"LdS4K6/{randint(0, 1145141919810)}" url = EAT_URL + a @@ -71,11 +88,11 @@ class Funny(Service): data = await data.json() except RequestError: raise RequestError("Request failed!") - + text = Translate(data["text"]).to_simple().replace("今天", day) get_a = re.search(r"非常(.*?)的", text).group(0) # type: ignore result = text.replace(get_a, "") - + elif arg == "晚上": a = f"KaTMS/{randint(0, 1145141919810)}" url = EAT_URL + a @@ -84,13 +101,17 @@ class Funny(Service): data = await data.json() except RequestError: raise RequestError("Request failed!") - + result = Translate(data["text"]).to_simple().replace("今天", day) - + else: rd = randint(1, 10) if rd == 5: - result = ["吃我吧 ❤", "(脸红)请...请享用咱吧......", "都可以哦~不能挑食呢~"] + result = [ + "吃我吧 ❤", + "(脸红)请...请享用咱吧......", + "都可以哦~不能挑食呢~" + ] return choice(result) else: a = f"JJr1hJ/{randint(0, 1145141919810)}" @@ -100,9 +121,9 @@ class Funny(Service): data = await data.json() except RequestError: raise RequestError("Request failed!") - + text = Translate(data["text"]).to_simple().replace("今天", day) get_a = re.match(r"(.*?)的智商", text).group(0) # type: ignore result = text.replace(get_a, f"{name}的智商") - + return result diff --git a/ATRI/plugins/help/__init__.py b/ATRI/plugins/help/__init__.py index efdd985..357a337 100644 --- a/ATRI/plugins/help/__init__.py +++ b/ATRI/plugins/help/__init__.py @@ -5,10 +5,7 @@ from ATRI.rule import to_bot from .data_source import Helper -main_help = Helper().on_command( - "菜单", "获取食用bot的方法", rule=to_bot(), aliases={"/help", "menu"} -) - +main_help = Helper().on_command("菜单", "获取食用bot的方法", rule=to_bot(), aliases={"/help", "menu"}) @main_help.handle() async def _main_help(bot: Bot, event: MessageEvent): @@ -18,7 +15,6 @@ async def _main_help(bot: Bot, event: MessageEvent): about_me = Helper().on_command("关于", "获取关于bot的信息", rule=to_bot(), aliases={"about"}) - @about_me.handle() async def _about_me(bot: Bot, event: MessageEvent): repo = Helper().about() @@ -27,15 +23,13 @@ async def _about_me(bot: Bot, event: MessageEvent): service_list = Helper().on_command("服务列表", "查看所有可用服务", rule=to_bot(), aliases={"功能列表"}) - @service_list.handle() async def _service_list(bot: Bot, event: MessageEvent): repo = Helper().service_list() await service_list.finish(repo) -service_info = Helper().on_command("帮助", "获取服务详细帮助") - +service_info = Helper().on_command("帮助", "获取服务详细帮助", rule=to_bot()) @service_info.handle() async def _ready_service_info(bot: Bot, event: MessageEvent, state: T_State): @@ -45,10 +39,10 @@ async def _ready_service_info(bot: Bot, event: MessageEvent, state: T_State): cmd = msg[1] except BaseException: cmd = str() - + if not cmd: repo = Helper().service_info(service) await service_info.finish(repo) - + repo = Helper().cmd_info(service, cmd) await service_info.finish(repo) diff --git a/ATRI/plugins/help/data_source.py b/ATRI/plugins/help/data_source.py index 831d1e0..f5104e5 100644 --- a/ATRI/plugins/help/data_source.py +++ b/ATRI/plugins/help/data_source.py @@ -24,9 +24,10 @@ COMMAND_INFO_FORMAT = """ class Helper(Service): + def __init__(self): Service.__init__(self, "帮助", "bot的食用指南~") - + @staticmethod def menu() -> str: return ( @@ -34,9 +35,9 @@ class Helper(Service): "关于 -查看bot基本信息\n" "服务列表 -以查看所有可用服务\n" "帮助 [服务] -以查看对应服务帮助\n" - "Tip: 均需要at触发。菜单 打开此页面" + "Tip: 均需要at触发。菜单 以打开此页面" ) - + @staticmethod def about() -> str: temp_list = list() @@ -50,7 +51,7 @@ class Helper(Service): "想进一步了解:\n" "https://github.com/Kyomotoi/ATRI" ) - + @staticmethod def service_list() -> str: files = os.listdir(SERVICES_DIR) @@ -58,42 +59,42 @@ class Helper(Service): for i in files: service = i.replace(".json", "") temp_list.append(service) - + msg0 = "咱搭载了以下服务~\n" services = " | ".join(map(str, temp_list)) msg0 = msg0 + services - repo = msg0 + "\n帮助 [服务] -以查看对应服务帮助" + repo = msg0 + "\n@ 帮助 [服务] -以查看对应服务帮助" return repo - + @staticmethod def service_info(service: str) -> str: try: data = ServiceTools().load_service(service) except ReadFileError: return "请检查是否输入错误呢..." - + service_name = data.get("service", "error") service_docs = data.get("docs", "error") service_enabled = data.get("enabled", True) - + _service_cmd_list = list(data.get("cmd_list", {"error"})) service_cmd_list = "\n".join(map(str, _service_cmd_list)) - + repo = SERVICE_INFO_FORMAT.format( service=service_name, docs=service_docs, cmd_list=service_cmd_list, - enabled=service_enabled, + enabled=service_enabled ) return repo - + @staticmethod def cmd_info(service: str, cmd: str) -> str: try: data = ServiceTools().load_service(service) except ReadFileError: return "请检查是否输入错误..." - + cmd_list: dict = data["cmd_list"] cmd_info = cmd_list.get(cmd, dict()) if not cmd_info: @@ -101,8 +102,11 @@ class Helper(Service): cmd_type = cmd_info.get("type", "ignore") docs = cmd_info.get("docs", "ignore") aliases = cmd_info.get("aliases", "ignore") - + repo = COMMAND_INFO_FORMAT.format( - cmd=cmd, cmd_type=cmd_type, docs=docs, aliases=aliases + cmd=cmd, + cmd_type=cmd_type, + docs=docs, + aliases=aliases ) return repo diff --git a/ATRI/plugins/manege/__init__.py b/ATRI/plugins/manege/__init__.py index 305cdc5..5180362 100644 --- a/ATRI/plugins/manege/__init__.py +++ b/ATRI/plugins/manege/__init__.py @@ -8,205 +8,139 @@ from nonebot.adapters.cqhttp.permission import GROUP_OWNER, GROUP_ADMIN from .data_source import Manege -# 求1个pr把这里优化,写得我想吐了 - - block_user = Manege().on_command("封禁用户", "对目标用户进行封禁", permission=SUPERUSER) - -@block_user.args_parser # type: ignore -async def _get_block_user(bot: Bot, event: MessageEvent, state: T_State): - msg = str(event.message).strip() - quit_list = ["算了", "罢了"] - if msg in quit_list: - await block_user.finish("...看来有人逃过一劫呢") - if not msg: - await block_user.reject("哪位?GKD!") - else: - state["block_user"] = msg - - @block_user.handle() async def _ready_block_user(bot: Bot, event: MessageEvent, state: T_State): msg = str(event.message).strip() if msg: state["block_user"] = msg - @block_user.got("block_user", "哪位?GKD!") async def _deal_block_user(bot: Bot, event: MessageEvent, state: T_State): user_id = state["block_user"] + quit_list = ["算了", "罢了"] + if user_id in quit_list: + await block_user.finish("...看来有人逃过一劫呢") + is_ok = Manege().block_user(user_id) if not is_ok: await block_user.finish("kuso!封禁失败了...") - + await block_user.finish(f"用户 {user_id} 危!") unblock_user = Manege().on_command("解封用户", "对目标用户进行解封", permission=SUPERUSER) - -@unblock_user.args_parser # type: ignore -async def _get_unblock_user(bot: Bot, event: MessageEvent, state: T_State): - msg = str(event.message).strip() - quit_list = ["算了", "罢了"] - if msg in quit_list: - await unblock_user.finish("...有人又得继续在小黑屋呆一阵子了") - if not msg: - await unblock_user.reject("哪位?GKD!") - else: - state["unblock_user"] = msg - - @unblock_user.handle() async def _ready_unblock_user(bot: Bot, event: MessageEvent, state: T_State): msg = str(event.message).strip() if msg: state["unblock_user"] = msg - @unblock_user.got("unblock_user", "哪位?GKD!") async def _deal_unblock_user(bot: Bot, event: MessageEvent, state: T_State): user_id = state["unblock_user"] + quit_list = ["算了", "罢了"] + if user_id in quit_list: + await unblock_user.finish("...有人又得继续在小黑屋呆一阵子了") + is_ok = Manege().unblock_user(user_id) if not is_ok: await unblock_user.finish("kuso!解封失败了...") - + await unblock_user.finish(f"好欸!{user_id} 重获新生!") block_group = Manege().on_command("封禁群", "对目标群进行封禁", permission=SUPERUSER) - -@block_group.args_parser # type: ignore -async def _get_block_group(bot: Bot, event: MessageEvent, state: T_State): - msg = str(event.message).strip() - quit_list = ["算了", "罢了"] - if msg in quit_list: - await block_group.finish("...看来有一群逃过一劫呢") - if not msg: - await block_group.reject("哪个群?GKD!") - else: - state["block_group"] = msg - - @block_group.handle() async def _ready_block_group(bot: Bot, event: MessageEvent, state: T_State): msg = str(event.message).strip() if msg: state["block_group"] = msg - @block_group.got("block_group", "哪个群?GKD!") async def _deal_block_group(bot: Bot, event: MessageEvent, state: T_State): group_id = state["block_group"] + quit_list = ["算了", "罢了"] + if group_id in quit_list: + await block_group.finish("...看来有一群逃过一劫呢") + is_ok = Manege().block_group(group_id) if not is_ok: await block_group.finish("kuso!封禁失败了...") - + await block_group.finish(f"群 {group_id} 危!") unblock_group = Manege().on_command("解封群", "对目标群进行解封", permission=SUPERUSER) - -@unblock_group.args_parser # type: ignore -async def _get_unblock_group(bot: Bot, event: MessageEvent, state: T_State): - msg = str(event.message).strip() - quit_list = ["算了", "罢了"] - if msg in quit_list: - await unblock_group.finish("...有一群又得继续在小黑屋呆一阵子了") - if not msg: - await unblock_group.reject("哪个群?GKD!") - else: - state["unblock_group"] = msg - - @unblock_group.handle() async def _ready_unblock_group(bot: Bot, event: MessageEvent, state: T_State): msg = str(event.message).strip() if msg: state["unblock_group"] = msg - @unblock_group.got("unblock_group", "哪个群?GKD!") async def _deal_unblock_group(bot: Bot, event: MessageEvent, state: T_State): group_id = state["unblock_group"] + quit_list = ["算了", "罢了"] + if group_id in quit_list: + await unblock_group.finish("...有一群又得继续在小黑屋呆一阵子了") + is_ok = Manege().unblock_group(group_id) if not is_ok: await unblock_group.finish("kuso!解封失败了...") - + await unblock_group.finish(f"好欸!群 {group_id} 重获新生!") global_block_service = Manege().on_command("全局禁用", "全局禁用某服务", permission=SUPERUSER) - -@global_block_service.args_parser # type: ignore -async def _get_global_block_service(bot: Bot, event: MessageEvent, state: T_State): - msg = str(event.message).strip() - quit_list = ["算了", "罢了"] - if msg in quit_list: - await global_block_service.finish("好吧...") - if not msg: - await global_block_service.reject("阿...是哪个服务呢") - else: - state["global_block_service"] = msg - - @global_block_service.handle() async def _ready_block_service(bot: Bot, event: MessageEvent, state: T_State): msg = str(event.message).strip() if msg: state["global_block_service"] = msg - @global_block_service.got("global_block_service", "阿...是哪个服务呢") async def _deal_global_block_service(bot: Bot, event: MessageEvent, state: T_State): block_service = state["global_block_service"] + quit_list = ["算了", "罢了"] + if block_service in quit_list: + await global_block_service.finish("好吧...") + is_ok = Manege().control_global_service(block_service, False) if not is_ok: await global_block_service.finish("kuso!禁用失败了...") - + await global_block_service.finish(f"服务 {block_service} 已被禁用") global_unblock_service = Manege().on_command("全局启用", "全局启用某服务", permission=SUPERUSER) - -@global_unblock_service.args_parser # type: ignore -async def _get_global_unblock_service(bot: Bot, event: MessageEvent, state: T_State): - msg = str(event.message).strip() - quit_list = ["算了", "罢了"] - if msg in quit_list: - await global_unblock_service.finish("好吧...") - if not msg: - await global_unblock_service.reject("阿...是哪个服务呢") - else: - state["global_unblock_service"] = msg - - @global_unblock_service.handle() async def _ready_unblock_service(bot: Bot, event: MessageEvent, state: T_State): msg = str(event.message).strip() if msg: state["global_unblock_service"] = msg - @global_unblock_service.got("global_unblock_service", "阿...是哪个服务呢") async def _deal_global_unblock_service(bot: Bot, event: MessageEvent, state: T_State): - block_service = state["global_unblock_service"] - is_ok = Manege().control_global_service(block_service, True) + unblock_service = state["global_unblock_service"] + quit_list = ["算了", "罢了"] + if unblock_service in quit_list: + await global_unblock_service.finish("好吧...") + + is_ok = Manege().control_global_service(unblock_service, True) if not is_ok: await global_unblock_service.finish("kuso!启用服务失败了...") + + await global_unblock_service.finish(f"服务 {unblock_service} 已启用") - await global_unblock_service.finish(f"服务 {block_service} 已启用") - - -user_block_service = Manege().on_regex( - r"对用户(.*?)禁用(.*)", "针对某一用户禁用服务", permission=SUPERUSER -) +user_block_service = Manege().on_regex(r"对用户(.*?)禁用(.*)", "针对某一用户禁用服务", permission=SUPERUSER) @user_block_service.handle() async def _user_block_service(bot: Bot, event: MessageEvent): @@ -215,17 +149,15 @@ async def _user_block_service(bot: Bot, event: MessageEvent): reg = re.findall(pattern, msg) aim_user = reg[0] aim_service = reg[1] - + is_ok = Manege().control_user_service(aim_service, aim_user, False) if not is_ok: await user_block_service.finish("禁用失败...请检查服务名是否正确") await user_block_service.finish(f"完成~已禁止用户 {aim_user} 使用 {aim_service}") + -user_unblock_service = Manege().on_regex( - r"对用户(.*?)启用(.*)", "针对某一用户启用服务", permission=SUPERUSER -) - +user_unblock_service = Manege().on_regex(r"对用户(.*?)启用(.*)", "针对某一用户启用服务", permission=SUPERUSER) @user_unblock_service.handle() async def _user_unblock_service(bot: Bot, event: MessageEvent): @@ -234,85 +166,51 @@ async def _user_unblock_service(bot: Bot, event: MessageEvent): reg = re.findall(pattern, msg) aim_user = reg[0] aim_service = reg[1] - + is_ok = Manege().control_user_service(aim_service, aim_user, True) if not is_ok: await user_unblock_service.finish("启用失败...请检查服务名是否正确,或者此人并不存在于名单中") await user_unblock_service.finish(f"完成~已允许用户 {aim_user} 使用 {aim_service}") -group_block_service = Manege().on_command( - "禁用", "针对所在群禁用某服务", permission=SUPERUSER | GROUP_OWNER | GROUP_ADMIN -) - - -@group_block_service.args_parser # type: ignore -async def _get_group_block_service(bot: Bot, event: GroupMessageEvent, state: T_State): - msg = str(event.message).strip() - quit_list = ["算了", "罢了"] - if msg in quit_list: - await group_block_service.finish("好吧...") - if not msg: - await group_block_service.reject("阿...是哪个服务呢") - else: - state["group_block_service"] = msg - +group_block_service = Manege().on_command("禁用", "针对所在群禁用某服务", permission=SUPERUSER | GROUP_OWNER | GROUP_ADMIN) @group_block_service.handle() -async def _ready_group_block_service( - bot: Bot, event: GroupMessageEvent, state: T_State -): +async def _ready_group_block_service(bot: Bot, event: GroupMessageEvent, state: T_State): msg = str(event.message).strip() if msg: state["group_block_service"] = msg - @group_block_service.got("group_block_service", "阿...是哪个服务呢") async def _deal_group_block_service(bot: Bot, event: GroupMessageEvent, state: T_State): aim_service = state["group_block_service"] group_id = str(event.group_id) - + quit_list = ["算了", "罢了"] + if aim_service in quit_list: + await group_block_service.finish("好吧...") + is_ok = Manege().control_group_service(aim_service, group_id, False) if not is_ok: await group_block_service.finish("禁用失败...请检查服务名是否输入正确") await group_block_service.finish(f"完成!~已禁止本群使用服务:{aim_service}") -group_unblock_service = Manege().on_command( - "启用", "针对所在群启用某服务", permission=SUPERUSER | GROUP_OWNER | GROUP_ADMIN -) - - -@group_unblock_service.args_parser # type: ignore -async def _get_group_unblock_service( - bot: Bot, event: GroupMessageEvent, state: T_State -): - msg = str(event.message).strip() - quit_list = ["算了", "罢了"] - if msg in quit_list: - await group_unblock_service.finish("好吧...") - if not msg: - await group_unblock_service.reject("阿...是哪个服务呢") - else: - state["group_unblock_service"] = msg - +group_unblock_service = Manege().on_command("启用", "针对所在群启用某服务", permission=SUPERUSER | GROUP_OWNER | GROUP_ADMIN) @group_unblock_service.handle() -async def _ready_group_unblock_service( - bot: Bot, event: GroupMessageEvent, state: T_State -): +async def _ready_group_unblock_service(bot: Bot, event: GroupMessageEvent, state: T_State): msg = str(event.message).strip() if msg: state["group_unblock_service"] = msg - @group_unblock_service.got("group_unblock_service", "阿...是哪个服务呢") -async def _deal_group_unblock_service( - bot: Bot, event: GroupMessageEvent, state: T_State -): +async def _deal_group_unblock_service(bot: Bot, event: GroupMessageEvent, state: T_State): aim_service = state["group_unblock_service"] group_id = str(event.group_id) - + quit_list = ["算了", "罢了"] + if aim_service in quit_list: + await group_unblock_service.finish("好吧...") + is_ok = Manege().control_group_service(aim_service, group_id, True) if not is_ok: await group_unblock_service.finish("启用失败...请检查服务名是否输入正确,或群不存在于名单中") @@ -321,7 +219,6 @@ async def _deal_group_unblock_service( get_friend_add_list = Manege().on_command("获取好友申请", "获取好友申请列表", permission=SUPERUSER) - @get_friend_add_list.handle() async def _get_friend_add_list(bot: Bot, event: MessageEvent): data = Manege().load_friend_apply_list() @@ -336,33 +233,23 @@ async def _get_friend_add_list(bot: Bot, event: MessageEvent): msg0 = "申请人ID | 申请信息 | 申请码\n" + "\n".join(map(str, temp_list)) msg1 = msg0 + "\nTip: 使用 同意/拒绝好友 [申请码] 以决定" await get_friend_add_list.finish(msg1) - + approve_friend_add = Manege().on_command("同意好友", "同意好友申请", permission=SUPERUSER) - -@approve_friend_add.args_parser # type: ignore -async def _get_approve_friend_add(bot: Bot, event: MessageEvent, state: T_State): - msg = str(event.message).strip() - quit_list = ["算了", "罢了"] - if msg in quit_list: - await approve_friend_add.finish("好吧...") - if not msg: - await approve_friend_add.reject("申请码GKD!") - else: - state["approve_friend_add"] = msg - - @approve_friend_add.handle() async def _ready_approve_friend_add(bot: Bot, event: MessageEvent, state: T_State): msg = str(event.message).strip() if msg: state["approve_friend_add"] - @approve_friend_add.got("approve_friend_add", "申请码GKD!") async def _deal_approve_friend_add(bot: Bot, event: MessageEvent, state: T_State): apply_code = state["approve_friend_add"] + quit_list = ["算了", "罢了"] + if apply_code in quit_list: + await approve_friend_add.finish("好吧...") + try: await bot.set_friend_add_request(flag=apply_code, approve=True) except BaseException: @@ -375,29 +262,19 @@ async def _deal_approve_friend_add(bot: Bot, event: MessageEvent, state: T_State refuse_friend_add = Manege().on_command("拒绝好友", "拒绝好友申请", permission=SUPERUSER) - -@refuse_friend_add.args_parser # type: ignore -async def _get_refuse_friend_add(bot: Bot, event: MessageEvent, state: T_State): - msg = str(event.message).strip() - quit_list = ["算了", "罢了"] - if msg in quit_list: - await refuse_friend_add.finish("好吧...") - if not msg: - await refuse_friend_add.reject("申请码GKD!") - else: - state["refuse_friend_add"] = msg - - @refuse_friend_add.handle() async def _ready_refuse_friend_add(bot: Bot, event: MessageEvent, state: T_State): msg = str(event.message).strip() if msg: state["refuse_friend_add"] - @refuse_friend_add.got("refuse_friend_add", "申请码GKD!") async def _deal_refuse_friend_add(bot: Bot, event: MessageEvent, state: T_State): apply_code = state["refuse_friend_add"] + quit_list = ["算了", "罢了"] + if apply_code in quit_list: + await refuse_friend_add.finish("好吧...") + try: await bot.set_friend_add_request(flag=apply_code, approve=False) except BaseException: @@ -410,7 +287,6 @@ async def _deal_refuse_friend_add(bot: Bot, event: MessageEvent, state: T_State) get_group_invite_list = Manege().on_command("获取邀请列表", "获取群邀请列表", permission=SUPERUSER) - @get_group_invite_list.handle() async def _get_group_invite_list(bot: Bot, event: MessageEvent): data = Manege().load_invite_apply_list() @@ -429,33 +305,21 @@ async def _get_group_invite_list(bot: Bot, event: MessageEvent): approve_group_invite = Manege().on_command("同意邀请", "同意群聊邀请", permission=SUPERUSER) - -@approve_group_invite.args_parser # type: ignore -async def _get_approve_group_invite(bot: Bot, event: MessageEvent, state: T_State): - msg = str(event.message).strip() - quit_list = ["算了", "罢了"] - if msg in quit_list: - await approve_group_invite.finish("好吧...") - if not msg: - await approve_group_invite.reject("申请码GKD!") - else: - state["approve_group_invite"] = msg - - @approve_group_invite.handle() async def _ready_approve_group_invite(bot: Bot, event: MessageEvent, state: T_State): msg = str(event.message).strip() if msg: state["approve_group_invite"] - @approve_group_invite.got("approve_group_invite", "申请码GKD!") async def _deal_approve_group_invite(bot: Bot, event: MessageEvent, state: T_State): apply_code = state["approve_group_invite"] + quit_list = ["算了", "罢了"] + if apply_code in quit_list: + await approve_group_invite.finish("好吧...") + try: - await bot.set_group_add_request( - flag=apply_code, sub_type="invite", approve=True - ) + await bot.set_group_add_request(flag=apply_code, sub_type="invite", approve=True) except BaseException: await approve_group_invite.finish("同意失败...尝试下手动?") data = Manege().load_invite_apply_list() @@ -466,33 +330,21 @@ async def _deal_approve_group_invite(bot: Bot, event: MessageEvent, state: T_Sta refuse_group_invite = Manege().on_command("拒绝邀请", "拒绝群聊邀请", permission=SUPERUSER) - -@refuse_group_invite.args_parser # type: ignore -async def _get_refuse_group_invite(bot: Bot, event: MessageEvent, state: T_State): - msg = str(event.message).strip() - quit_list = ["算了", "罢了"] - if msg in quit_list: - await refuse_group_invite.finish("好吧...") - if not msg: - await refuse_group_invite.reject("申请码GKD!") - else: - state["refuse_group_invite"] = msg - - @refuse_group_invite.handle() async def _ready_refuse_group_invite(bot: Bot, event: MessageEvent, state: T_State): msg = str(event.message).strip() if msg: state["refuse_group_invite"] - @refuse_group_invite.got("refuse_group_invite", "申请码GKD!") async def _deal_refuse_group_invite(bot: Bot, event: MessageEvent, state: T_State): apply_code = state["refuse_group_invite"] + quit_list = ["算了", "罢了"] + if apply_code in quit_list: + await refuse_group_invite.finish("好吧...") + try: - await bot.set_group_add_request( - flag=apply_code, sub_type="invite", approve=False - ) + await bot.set_group_add_request(flag=apply_code, sub_type="invite", approve=False) except BaseException: await refuse_group_invite.finish("拒绝失败...尝试下手动?") data = Manege().load_invite_apply_list() @@ -503,7 +355,6 @@ async def _deal_refuse_group_invite(bot: Bot, event: MessageEvent, state: T_Stat track_error = Manege().on_command("追踪", "获取报错信息,传入追踪码", aliases={"/track"}) - @track_error.handle() async def _track_error(bot: Bot, event: MessageEvent): track_id = str(event.message).strip() diff --git a/ATRI/plugins/manege/atri-manege/README.md b/ATRI/plugins/manege/atri-manege/README.md deleted file mode 100644 index e1c03ee..0000000 --- a/ATRI/plugins/manege/atri-manege/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# atri-manege - -## Project setup -``` -npm install -``` - -### Compiles and hot-reloads for development -``` -npm run serve -``` - -### Compiles and minifies for production -``` -npm run build -``` - -### Lints and fixes files -``` -npm run lint -``` - -### Customize configuration -See [Configuration Reference](https://cli.vuejs.org/config/). diff --git a/ATRI/plugins/manege/atri-manege/src/App.vue b/ATRI/plugins/manege/atri-manege/src/App.vue deleted file mode 100644 index d04b4f2..0000000 --- a/ATRI/plugins/manege/atri-manege/src/App.vue +++ /dev/null @@ -1,104 +0,0 @@ -<template> - <v-app> - <v-navigation-drawer app v-model="drawer" class="na-d-0"> - <v-list - nav - dense - > - <v-list-item-group active-class="nattier-blue--text text--accent-4"> - <v-list-item> - <v-list-item-icon> - <v-icon>mdi-home</v-icon> - </v-list-item-icon> - <v-list-item-title>主页 | Home</v-list-item-title> - </v-list-item> - - <v-list-item> - <v-list-item-icon> - <v-icon>mdi-wrench</v-icon> - </v-list-item-icon> - <v-list-item-title>控制台 | Control</v-list-item-title> - </v-list-item> - - <v-list-item> - <v-list-item-icon> - <v-icon>mdi-database</v-icon> - </v-list-item-icon> - <v-list-item-title>数据 | Data</v-list-item-title> - </v-list-item> - - <v-list-item> - <v-list-item-icon> - <v-icon>mdi-comment-processing</v-icon> - </v-list-item-icon> - <v-list-item-title>聊天 | Chat</v-list-item-title> - </v-list-item> - </v-list-item-group> - </v-list> - </v-navigation-drawer> - - <v-app-bar app color="white" flat> - <v-app-bar-nav-icon @click="drawer = !drawer"></v-app-bar-nav-icon> - - <v-toolbar-title>ATRI Console</v-toolbar-title> - - <v-spacer></v-spacer> - - <v-btn href="https://jq.qq.com/?_wv=1027&k=iKLJzM1u" target="_blank" text> - <span class="mr-2">Discuss</span> - <v-icon small>mdi-qqchat</v-icon> - </v-btn> - - <v-btn href="https://github.com/Kyomotoi/ATRI" target="_blank" text> - <span class="mr-2">GitHub</span> - <v-icon small>mdi-link-variant</v-icon> - </v-btn> - </v-app-bar> - - <!-- 根据应用组件来调整你的内容 --> - <v-main> - - <!-- 给应用提供合适的间距 --> - <v-container fluid> - - <!-- 如果使用 vue-router --> - <router-view></router-view> - </v-container> - </v-main> - - <v-footer app> - <v-divider></v-divider> - <v-container fluid> - <v-row align="center" justify="center"> - <v-col class="text-center" cols="auto"> - <span> <v-icon>mdi-copyright</v-icon> Yours <strong>Kyomotoi</strong> </span> - </v-col> - <v-col class="text-center" cols="auto"> - <span> <v-icon>mdi-github</v-icon> <strong>ATRI</strong> </span> - </v-col> - </v-row> - </v-container> - </v-footer> - </v-app> -</template> - -<script> - -export default { - name: 'App', - - data: () => ({ - drawer: true, - }), -}; -</script> - -<style> -.text-center.a:visited { - color: aliceblue; -} - -.na-d-0 { - background-image: url("https://i.loli.net/2021/07/19/WlFanrZHRQxb5Ay.png"); -} -</style>
\ No newline at end of file diff --git a/ATRI/plugins/manege/atri-manege/src/assets/.gitkeep b/ATRI/plugins/manege/atri-manege/src/assets/.gitkeep deleted file mode 100644 index e69de29..0000000 --- a/ATRI/plugins/manege/atri-manege/src/assets/.gitkeep +++ /dev/null diff --git a/ATRI/plugins/manege/atri-manege/src/components/HelloWorld.vue b/ATRI/plugins/manege/atri-manege/src/components/HelloWorld.vue deleted file mode 100644 index 0ff52c0..0000000 --- a/ATRI/plugins/manege/atri-manege/src/components/HelloWorld.vue +++ /dev/null @@ -1,170 +0,0 @@ -<template> - <v-app> - <!-- Running 将由 Fastpi控制 - 正常:Running。非正常(刷新即丢失页面)Error。 - --> - <h1 class="h1-index">ATRI is Running</h1> - - <v-divider></v-divider> - - <v-col> - <h3 class="h3-index">主体状态 | Status</h3> - </v-col> - <v-container> - <v-col> - <v-row> - <v-card height="170" width="400" class="ma-1"> - <!--同上: - 正常:Normal operation。断开:Waiting for connection--> - <v-card-title>WS状态 | Websocket Status</v-card-title> - <div class="text-center"> - <v-chip - class="ma-2" - color="green" - text-color="white" - > - Normal operation - </v-chip> - </div> - </v-card> - - <v-card height="170" width="400" class="ma-1"> - <v-card-title>自身状态 | Self Status</v-card-title> - <div class="text-center"> - <v-chip - class="ma-2" - color="green" - text-color="white" - > - Normal operation - </v-chip> - </div> - </v-card> - </v-row> - </v-col> - </v-container> - - <v-divider></v-divider> - - <v-col> - <h3 class="h3-index">记录仪 | Dashboard</h3> - <div id="container" class="test-box"></div> - </v-col> - </v-app> -</template> - -<script> -import * as echarts from 'echarts' - -export default { - mounted() { - let myChart = echarts.init(document.getElementById("container")); - let option = { - title: { - subtext: '数据统计间隔:1分钟', - left: '10' - }, - legend: { - data: ['接受信息', '发送信息', '服务调用速率', '服务调用失败速率'] - }, - color: ["#32c1e5", "#e5bb32", "#77e532", "#e5323e"], - tooltip: { - trigger: 'axis' - }, - grid: { - left: '3%', - right: '4%', - bottom: '3%', - containLabel: true - }, - axisPointer: { - show: true, - }, - dataZoom: [ - { - type: 'slider', - show: true, - xAxisIndex: [0] - }, - { - type: 'slider', - show: true, - yAxisIndex: [0] - }, - { - type: 'inside', - xAxisIndex: [0] - }, - { - type: 'inside', - yAxisIndex: [0] - } - ], - toolbox: { - feature: { - dataZoom: { - yAxisIndex: false, - xAxisIndex: false - }, - restore: {}, - saveAsImage: {} - } - }, - xAxis: [ - { - type: 'category', - boundaryGap: false, - axisLine: {onZero: false}, - data: ["7-20 20:00", "7-20 20:01", "7-20 20:02", "7-20 20:03", "7-20 20:04", "7-20 20:05", "7-20 20:06", "7-20 20:07"] - }, - ], - yAxis: { - type: 'value' - }, - series: [ - { - name: '接受信息', - type: 'line', - data: [293, 394, 590, 493, 592, 489, 519, 528] - }, - { - name: '发送信息', - type: 'line', - data: [220, 182, 191, 234, 290, 330, 310, 230] - }, - { - name: '服务调用速率', - type: 'line', - data: [150, 232, 201, 154, 190, 330, 209, 291] - }, - { - name: '服务调用失败速率', - type: 'line', - data: [12, 3, 42 ,3, 32, 4, 42, 20] - } - ] - }; - - myChart.setOption(option); - window.onresize = myChart.resize; - } -} -</script> - -<style> -.h1-index { - font-size: 240%; - color: #8f8f8f; -} - -.h3-index { - color: #8f8f8f; -} - -.test-box { - width: 100%; - height: 600px; - background-color: white; -} - -</style> diff --git a/ATRI/plugins/manege/atri-manege/src/router/index.js b/ATRI/plugins/manege/atri-manege/src/router/index.js deleted file mode 100644 index d36779e..0000000 --- a/ATRI/plugins/manege/atri-manege/src/router/index.js +++ /dev/null @@ -1,29 +0,0 @@ -import Vue from 'vue' -import VueRouter from 'vue-router' -import Home from '../views/Home.vue' - -Vue.use(VueRouter) - -const routes = [ - { - path: '/', - name: 'Home', - component: Home - }, - { - path: '/about', - name: 'About', - // route level code-splitting - // this generates a separate chunk (about.[hash].js) for this route - // which is lazy-loaded when the route is visited. - component: () => import(/* webpackChunkName: "about" */ '../views/About.vue') - } -] - -const router = new VueRouter({ - mode: 'history', - base: process.env.BASE_URL, - routes -}) - -export default router diff --git a/ATRI/plugins/manege/atri-manege/src/views/About.vue b/ATRI/plugins/manege/atri-manege/src/views/About.vue deleted file mode 100644 index 3fa2807..0000000 --- a/ATRI/plugins/manege/atri-manege/src/views/About.vue +++ /dev/null @@ -1,5 +0,0 @@ -<template> - <div class="about"> - <h1>This is an about page</h1> - </div> -</template> diff --git a/ATRI/plugins/manege/atri-manege/src/views/Home.vue b/ATRI/plugins/manege/atri-manege/src/views/Home.vue deleted file mode 100644 index 636303a..0000000 --- a/ATRI/plugins/manege/atri-manege/src/views/Home.vue +++ /dev/null @@ -1,15 +0,0 @@ -<template> - <hello-world /> -</template> - -<script> - import HelloWorld from '../components/HelloWorld' - - export default { - name: 'Home', - - components: { - HelloWorld, - }, - } -</script> diff --git a/ATRI/plugins/manege/data_source.py b/ATRI/plugins/manege/data_source.py index c822fff..1eb2048 100644 --- a/ATRI/plugins/manege/data_source.py +++ b/ATRI/plugins/manege/data_source.py @@ -9,8 +9,8 @@ from ATRI.utils import UbuntuPaste from ATRI.exceptions import ReadFileError, load_error -MANEGE_DIR = Path(".") / "ATRI" / "data" / "database" / "manege" -ESSENTIAL_DIR = Path(".") / "ATRI" / "data" / "database" / "essential" +MANEGE_DIR = Path(".") / "data" / "database" / "manege" +ESSENTIAL_DIR = Path(".") / "data" / "database" / "essential" os.makedirs(MANEGE_DIR, exist_ok=True) os.makedirs(ESSENTIAL_DIR, exist_ok=True) @@ -29,6 +29,7 @@ __doc__ = """ class Manege(Service): + def __init__(self): Service.__init__(self, "管理", __doc__, True) @@ -48,10 +49,11 @@ class Manege(Service): with open(path, "w", encoding="utf-8") as w: w.write(json.dumps({})) data = dict() - + data = json.loads(path.read_bytes()) return data - + + @staticmethod def _save_block_user_list(data: dict) -> None: file_name = "block_user.json" @@ -60,10 +62,10 @@ class Manege(Service): with open(path, "w", encoding="utf-8") as w: w.write(json.dumps({})) data = dict() - + with open(path, "w", encoding="utf-8") as w: w.write(json.dumps(data, indent=4)) - + @staticmethod def _load_block_group_list() -> dict: """ @@ -80,10 +82,10 @@ class Manege(Service): with open(path, "w", encoding="utf-8") as w: w.write(json.dumps({})) data = dict() - + data = json.loads(path.read_bytes()) return data - + @staticmethod def _save_block_group_list(data: dict) -> None: file_name = "block_group.json" @@ -92,51 +94,55 @@ class Manege(Service): with open(path, "w", encoding="utf-8") as w: w.write(json.dumps({})) data = dict() - + with open(path, "w", encoding="utf-8") as w: w.write(json.dumps(data, indent=4)) - + @classmethod def block_user(cls, user_id: str) -> bool: data = cls._load_block_user_list() now_time = datetime.now() - data[user_id] = {"time": now_time} + data[user_id] = { + "time": now_time + } try: cls._save_block_user_list(data) return True except BaseException: return False - + @classmethod def unblock_user(cls, user_id: str) -> bool: data: dict = cls._load_block_user_list() if user_id not in data: return False - + try: data.pop(user_id) cls._save_block_user_list(data) return True except BaseException: return False - + @classmethod def block_group(cls, group_id: str) -> bool: data = cls._load_block_group_list() now_time = datetime.now() - data[group_id] = {"time": now_time} + data[group_id] = { + "time": now_time + } try: cls._save_block_group_list(data) return True except BaseException: return False - + @classmethod def unblock_group(cls, group_id: str) -> bool: data: dict = cls._load_block_group_list() if group_id not in data: return False - + try: data.pop(group_id) cls._save_block_group_list(data) @@ -156,7 +162,7 @@ class Manege(Service): data["enabled"] = is_enabled ServiceTools().save_service(data, service) return True - + @staticmethod def control_user_service(service: str, user_id: str, is_enabled: bool) -> bool: """ @@ -167,7 +173,7 @@ class Manege(Service): except BaseException: return False temp_list: list = data.get("disable_user", list()) - + if is_enabled: try: temp_list.remove(user_id) @@ -178,7 +184,7 @@ class Manege(Service): data["disable_user"] = temp_list ServiceTools().save_service(data, service) return True - + @staticmethod def control_group_service(service: str, group_id: str, is_enabled: bool) -> bool: """ @@ -190,7 +196,7 @@ class Manege(Service): except BaseException: return False temp_list: list = data.get("disable_group", list()) - + if is_enabled: try: temp_list.remove(group_id) @@ -213,7 +219,7 @@ class Manege(Service): data = json.loads(path.read_bytes()) return data - + @staticmethod def save_friend_apply_list(data: dict) -> None: file_name = "friend_add.json" @@ -224,7 +230,7 @@ class Manege(Service): with open(path, "w", encoding="utf-8") as w: w.write(json.dumps(data, indent=4)) - + @staticmethod def load_invite_apply_list() -> dict: file_name = "group_invite.json" @@ -236,7 +242,7 @@ class Manege(Service): data = json.loads(path.read_bytes()) return data - + @staticmethod def save_invite_apply_list(data: dict) -> None: file_name = "group_invite.json" @@ -254,19 +260,22 @@ class Manege(Service): data = load_error(track_id) except ReadFileError: return "请检查ID是否正确..." - + prompt = data.get("prompt", "ignore") time = data.get("time", "ignore") content = data.get("content", "ignore") - + msg0 = TRACK_BACK_FORMAT.format( - track_id=track_id, prompt=prompt, time=time, content=content + track_id=track_id, + prompt=prompt, + time=time, + content=content ) f_data = FormData() f_data.add_field("poster", "ATRI running log") f_data.add_field("syntax", "text") f_data.add_field("expiration", "day") f_data.add_field("content", msg0) - + repo = f"详细请移步此处~\n{await UbuntuPaste(f_data).paste()}" return repo diff --git a/ATRI/plugins/repo.py b/ATRI/plugins/repo.py index 9c52610..7939fc6 100644 --- a/ATRI/plugins/repo.py +++ b/ATRI/plugins/repo.py @@ -21,13 +21,13 @@ REPO_FORMAT = """ class Repo(Service): + def __init__(self): Service.__init__(self, "反馈", "向维护者发送消息") - + repo = Repo().on_command("来杯红茶", "向维护者发送消息", aliases={"反馈", "报告"}) - @repo.args_parser # type: ignore async def _get_repo(bot: Bot, event: MessageEvent, state: T_State): msg = str(event.message).strip() @@ -39,7 +39,6 @@ async def _get_repo(bot: Bot, event: MessageEvent, state: T_State): else: state["repo"] = msg - @repo.handle() async def _ready_repo(bot: Bot, event: MessageEvent, state: T_State): user_id = event.get_user_id() @@ -47,24 +46,26 @@ async def _ready_repo(bot: Bot, event: MessageEvent, state: T_State): await repo.finish(_repo_flmt_notice) if not _repo_dlmt.check(user_id): await repo.finish(_repo_dlmt_notice) - + msg = str(event.message).strip() if msg: state["repo"] = msg - @repo.got("repo", "需要反馈的内容呢?~") async def _deal_repo(bot: Bot, event: MessageEvent, state: T_State): msg = state["repo"] user_id = event.get_user_id() - repo_0 = REPO_FORMAT.format(user=user_id, msg=msg) - + repo_0 = REPO_FORMAT.format( + user=user_id, + msg=msg + ) + for superuser in BotSelfConfig.superusers: try: await bot.send_private_msg(user_id=superuser, message=repo_0) except BaseException: await repo.finish("发送失败了呢...") - + _repo_flmt.start_cd(user_id) _repo_dlmt.increase(user_id) await repo.finish("吾辈的心愿已由咱转告维护者!") diff --git a/ATRI/plugins/rich/__init__.py b/ATRI/plugins/rich/__init__.py index 4c5b624..87a2b02 100644 --- a/ATRI/plugins/rich/__init__.py +++ b/ATRI/plugins/rich/__init__.py @@ -9,13 +9,12 @@ _rich_flmt = FreqLimiter(2) bili_rich = Rich().on_message("小程序爪巴", block=False) - @bili_rich.handle() async def _fk_bili(bot: Bot, event: MessageEvent): user_id = event.get_user_id() if not _rich_flmt.check(user_id): return - + msg = str(event.message) try: result, is_ok = await Rich().fk_bili(msg) diff --git a/ATRI/plugins/rich/data_source.py b/ATRI/plugins/rich/data_source.py index 9e59bf5..a59c922 100644 --- a/ATRI/plugins/rich/data_source.py +++ b/ATRI/plugins/rich/data_source.py @@ -8,6 +8,7 @@ from ATRI.exceptions import RequestError URL = f"https://api.kyomotoi.moe/api/bilibili/v2/?aid=" + table = "fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF" tr = dict() for i in range(58): @@ -24,9 +25,10 @@ __doc__ = """ class Rich(Service): + def __init__(self): Service.__init__(self, "小程序处理", __doc__, rule=is_in_service("小程序处理")) - + @staticmethod def _bv_dec(x) -> str: r = 0 @@ -34,7 +36,7 @@ class Rich(Service): r += tr[x[s[i]]] * 58 ** i result = "av" + str((r - add) ^ xor) return result - + @staticmethod def _bv_enc(x) -> str: x = (x ^ xor) + add @@ -42,7 +44,7 @@ class Rich(Service): for i in range(6): r[s[i]] = table[x // 58 ** i % 58] return "".join(r) - + @classmethod async def fk_bili(cls, text: str) -> tuple: """ @@ -51,7 +53,7 @@ class Rich(Service): """ msg = text.replace("\\", "") bv = False - + if "qqdocurl" not in msg: if "av" in msg: av = re.findall(r"(av\d+)", msg) @@ -69,7 +71,7 @@ class Rich(Service): if not bv_url: return "Get value (bv url) failed!", False bv_url = bv_url[3] - + try: res = await request.get(bv_url) except RequestError: @@ -78,7 +80,7 @@ class Rich(Service): if not bv: return "Get value (bv) failed!", False av = cls._bv_dec(bv[0]) - + if not bv: if "av" in msg: av = re.findall(r"(av\d+)", msg) @@ -87,7 +89,7 @@ class Rich(Service): av = av[0].replace("av", "") else: return "Not found av", False - + url = URL + av try: res = await request.get(url) @@ -95,10 +97,11 @@ class Rich(Service): return "Request failed!", False res_data = await res.json() data = res_data["data"] - + result = ( f"{data['bvid']} INFO:\n" f"Title: {data['title']}\n" f"Link: {data['short_link']}" ) return result, True +
\ No newline at end of file diff --git a/ATRI/plugins/saucenao/__init__.py b/ATRI/plugins/saucenao/__init__.py index fddf0eb..468b001 100644 --- a/ATRI/plugins/saucenao/__init__.py +++ b/ATRI/plugins/saucenao/__init__.py @@ -10,13 +10,12 @@ from ATRI.utils.limit import FreqLimiter from .data_source import SaouceNao -_search_flmt = FreqLimiter(5) +_search_flmt = FreqLimiter(10) _search_flmt_notice = choice(["慢...慢一..点❤", "冷静1下", "歇会歇会~~"]) saucenao = SaouceNao().on_command("以图搜图", "透过一张图搜索可能的来源") - @saucenao.args_parser # type: ignore async def _get_img(bot: Bot, event: MessageEvent, state: T_State): msg = str(event.message).strip() @@ -28,18 +27,16 @@ async def _get_img(bot: Bot, event: MessageEvent, state: T_State): else: state["img"] = msg - @saucenao.handle() async def _ready_search(bot: Bot, event: MessageEvent, state: T_State): user_id = event.get_user_id() if not _search_flmt.check(user_id): await saucenao.finish(_search_flmt_notice) - + msg = str(event.message).strip() if msg: state["img"] = msg - @saucenao.got("img", "图呢?") async def _deal_search(bot: Bot, event: MessageEvent, state: T_State): user_id = event.get_user_id() @@ -47,7 +44,7 @@ async def _deal_search(bot: Bot, event: MessageEvent, state: T_State): img = findall(r"url=(.*?)]", msg) if not img: await saucenao.reject("请发送图片而不是其他东西!!") - + a = SaouceNao(SauceNAO.key) result = f"> {MessageSegment.at(user_id)}" + await a.search(img[0]) _search_flmt.start_cd(user_id) diff --git a/ATRI/plugins/saucenao/data_source.py b/ATRI/plugins/saucenao/data_source.py index 6e72c98..d948f91 100644 --- a/ATRI/plugins/saucenao/data_source.py +++ b/ATRI/plugins/saucenao/data_source.py @@ -16,15 +16,8 @@ __doc__ = """ class SaouceNao(Service): - def __init__( - self, - api_key: str = None, - output_type=2, - testmode=1, - dbmaski=32768, - db=5, - numres=5, - ): + + def __init__(self, api_key: str = None, output_type=2, testmode=1, dbmaski=32768, db=5, numres=5): Service.__init__(self, "以图搜图", __doc__, rule=is_in_service("以图搜图")) params = dict() @@ -35,31 +28,31 @@ class SaouceNao(Service): params["db"] = db params["numres"] = numres self.params = params - + async def _request(self, url: str): self.params["url"] = url - + try: res = await request.post(URL, params=self.params) except RequestError: raise RequestError("Request failed!") data = await res.json() return data - + async def search(self, url: str) -> str: data = await self._request(url) res = data["results"] - + result = list() for i in range(len(res)): data = res[i] - + _result = dict() _result["similarity"] = data["header"]["similarity"] _result["index_name"] = data["header"]["index_name"] _result["url"] = choice(data["data"].get("ext_urls", ["None"])) result.append(_result) - + msg0 = str() for i in result: msg0 += ( @@ -68,7 +61,7 @@ class SaouceNao(Service): f"Name: {i['index_name']}\n" f"URL: {i['url'].replace('https://', '')}" ) - + if len(res) <= 3: return msg0 else: diff --git a/ATRI/plugins/setu/__init__.py b/ATRI/plugins/setu/__init__.py index d67d75b..7eb2c61 100644 --- a/ATRI/plugins/setu/__init__.py +++ b/ATRI/plugins/setu/__init__.py @@ -12,10 +12,7 @@ _setu_flmt = FreqLimiter(120) _setu_dlmt = DailyLimiter(5) -random_setu = Setu().on_command( - "来张涩图", "来张随机涩图,冷却2分钟,每天限5张", aliases={"涩图来", "来点涩图", "来份涩图"} -) - +random_setu = Setu().on_command("来张涩图", "来张随机涩图,冷却2分钟,每天限5张", aliases={"涩图来", "来点涩图", "来份涩图"}) @random_setu.handle() async def _random_setu(bot: Bot, event: MessageEvent): @@ -24,9 +21,12 @@ async def _random_setu(bot: Bot, event: MessageEvent): await random_setu.finish() if not _setu_dlmt.check(user_id): await random_setu.finish() - + setu, title, p_id = await Setu().random_setu() - repo = f"Title: {title}\n" f"Pid: {p_id}" + repo = ( + f"Title: {title}\n" + f"Pid: {p_id}" + ) await bot.send(event, repo) msg_1 = await bot.send(event, Message(setu)) event_id = msg_1["message_id"] @@ -38,7 +38,6 @@ async def _random_setu(bot: Bot, event: MessageEvent): tag_setu = Setu().on_regex(r"来[张点丶份](.*?)的[涩色🐍]图", "根据提供的tag查找涩图") - @tag_setu.handle() async def _tag_setu(bot: Bot, event: MessageEvent): user_id = event.get_user_id() @@ -46,15 +45,18 @@ async def _tag_setu(bot: Bot, event: MessageEvent): await random_setu.finish() if not _setu_dlmt.check(user_id): await random_setu.finish() - + msg = str(event.message).strip() pattern = r"来[张点丶份](.*?)的[涩色🐍]图" tag = re.findall(pattern, msg)[0] setu, title, p_id, is_ok = await Setu().tag_setu(tag) if not is_ok: await tag_setu.finish(f"没有 {tag} 的涩图呢...") - repo_0 = f"Title: {title}\n" f"Pid: {p_id}" - + repo_0 = ( + f"Title: {title}\n" + f"Pid: {p_id}" + ) + await bot.send(event, repo_0) msg_1 = await bot.send(event, Message(setu)) event_id = msg_1["message_id"] @@ -75,6 +77,6 @@ async def _scheduler_setu(bot): message_id = msg_0["message_id"] await asyncio.sleep(60) await bot.delete_msg(message_id=message_id) - + except BaseException: pass diff --git a/ATRI/plugins/setu/data_source.py b/ATRI/plugins/setu/data_source.py index 46cf7cb..22fa69f 100644 --- a/ATRI/plugins/setu/data_source.py +++ b/ATRI/plugins/setu/data_source.py @@ -1,3 +1,5 @@ +import base64 +# from pathlib import Path from random import choice from nonebot.adapters.cqhttp import MessageSegment @@ -14,9 +16,10 @@ SCHEDULER_FORMAT = """ class Setu(Service): + def __init__(self): Service.__init__(self, "涩图", "hso!", rule=is_in_service("涩图")) - + @staticmethod async def random_setu() -> tuple: """ @@ -25,13 +28,14 @@ class Setu(Service): res = await request.get(LOLICON_URL) data: dict = await res.json() temp_data: dict = data.get("data", list())[0] - - title = temp_data.get("title", "木陰のねこ") + + title = temp_data.get("title", "木陰のねこ") p_id = temp_data.get("pid", 88124144) url = temp_data["urls"].get("original", "ignore") - setu = MessageSegment.image(url) + + setu = MessageSegment.image(url, timeout=114514) return setu, title, p_id - + @staticmethod async def tag_setu(tag: str) -> tuple: """ @@ -40,18 +44,18 @@ class Setu(Service): url = LOLICON_URL + f"?tag={tag}" res = await request.get(url) data: dict = await res.json() - + temp_data: dict = data.get("data", list())[0] if not temp_data: is_ok = False is_ok = True - - title = temp_data.get("title", "木陰のねこ") + + title = temp_data.get("title", "木陰のねこ") p_id = temp_data.get("pid", 88124144) url = temp_data["urls"].get("original", "ignore") - setu = MessageSegment.image(url) + setu = MessageSegment.image(url, timeout=114514) return setu, title, p_id, is_ok - + @staticmethod async def scheduler() -> str: """ @@ -63,10 +67,13 @@ class Setu(Service): res = await request.get(LOLICON_URL) data: dict = await res.json() temp_data: dict = data.get("data", list())[0] - + tag = choice(temp_data.get("tags", ["女孩子"])) - + url = temp_data["urls"].get("original", "ignore") - setu = MessageSegment.image(url) - repo = SCHEDULER_FORMAT.format(tag=tag, setu=setu) + setu = MessageSegment.image(url, timeout=114514) + repo = SCHEDULER_FORMAT.format( + tag=tag, + setu=setu + ) return repo diff --git a/ATRI/plugins/status/__init__.py b/ATRI/plugins/status/__init__.py index 888a0a7..0567bb4 100644 --- a/ATRI/plugins/status/__init__.py +++ b/ATRI/plugins/status/__init__.py @@ -6,7 +6,6 @@ from .data_source import IsSurvive ping = IsSurvive().on_command("/ping", "检测bot简单信息处理速度") - @ping.handle() async def _ping(bot: Bot, event: MessageEvent): await ping.finish(IsSurvive.ping()) @@ -14,15 +13,18 @@ async def _ping(bot: Bot, event: MessageEvent): status = IsSurvive().on_command("/status", "查看运行资源占用") - @status.handle() async def _status(bot: Bot, event: MessageEvent): msg, _ = IsSurvive.get_status() await status.finish(msg) +info_msg = "アトリは高性能ですから!" + + @scheduler.scheduled_job("interval", minutes=10, misfire_grace_time=15) async def _status_checking(): + global info_msg msg, stat = IsSurvive().get_status() if not stat: await status.finish(msg) diff --git a/ATRI/plugins/status/data_source.py b/ATRI/plugins/status/data_source.py index 189f568..c353313 100644 --- a/ATRI/plugins/status/data_source.py +++ b/ATRI/plugins/status/data_source.py @@ -14,13 +14,14 @@ __doc__ = """ class IsSurvive(Service): + def __init__(self): Service.__init__(self, "状态", __doc__, rule=is_in_service("状态")) @staticmethod def ping() -> str: return "I'm fine." - + @staticmethod def get_status(): log.info("开始检查资源消耗...") @@ -30,7 +31,7 @@ class IsSurvive(Service): disk = psutil.disk_usage("/").percent inteSENT = psutil.net_io_counters().bytes_sent / 1000000 # type: ignore inteRECV = psutil.net_io_counters().bytes_recv / 1000000 # type: ignore - + now = time.time() boot = psutil.boot_time() up_time = str( @@ -39,7 +40,7 @@ class IsSurvive(Service): ) except GetStatusError: raise GetStatusError("Failed to get status.") - + msg = "アトリは、高性能ですから!" if cpu > 90: # type: ignore msg = "咱感觉有些头晕..." @@ -56,7 +57,7 @@ class IsSurvive(Service): else: log.info("资源占用正常") is_ok = True - + msg0 = ( "Self status:\n" f"* CPU: {cpu}%\n" @@ -66,5 +67,5 @@ class IsSurvive(Service): f"* netRECV: {inteRECV}MB\n" f"* Runtime: {up_time}\n" ) + msg - + return msg0, is_ok diff --git a/ATRI/plugins/util/__init__.py b/ATRI/plugins/util/__init__.py index 541ca1b..1e31bff 100644 --- a/ATRI/plugins/util/__init__.py +++ b/ATRI/plugins/util/__init__.py @@ -10,7 +10,6 @@ from .data_source import Encrypt, Utils, Yinglish roll = Utils().on_command("/roll", "骰子~用法:1d10 或 2d10+2d10+more") - @roll.args_parser # type: ignore async def _get_roll(bot: Bot, event: MessageEvent, state: T_State): msg = str(event.message).strip() @@ -22,29 +21,26 @@ async def _get_roll(bot: Bot, event: MessageEvent, state: T_State): else: state["roll"] = msg - @roll.handle() async def _ready_roll(bot: Bot, event: MessageEvent, state: T_State): msg = str(event.message).strip() if msg: state["roll"] = msg - @roll.got("roll", "参数呢?!格式:1d10 或 2d10+2d10+more") async def _deal_roll(bot: Bot, event: MessageEvent, state: T_State): text = state["roll"] match = re.match(r"^([\dd+\s]+?)$", text) - + if not match: await roll.finish("阿——!参数不对!格式:1d10 或 2d10+2d10+more") - + msg = Utils().roll_dice(text) await roll.finish(msg) encrypt_en = Utils().on_command("加密", "我们之前的秘密❤") - @encrypt_en.args_parser # type: ignore async def _get_encr_en_text(bot: Bot, event: MessageEvent, state: T_State): msg = str(event.message).strip() @@ -56,14 +52,12 @@ async def _get_encr_en_text(bot: Bot, event: MessageEvent, state: T_State): else: state["encr_en_text"] = msg - @encrypt_en.handle() async def _ready_en(bot: Bot, event: MessageEvent, state: T_State): msg = str(event.message).strip() if msg: state["encr_en_text"] = msg - @encrypt_en.got("encr_en_text", "内容呢?!") async def _deal_en(bot: Bot, event: MessageEvent, state: T_State): text = state["encr_en_text"] @@ -77,7 +71,6 @@ async def _deal_en(bot: Bot, event: MessageEvent, state: T_State): encrypt_de = Utils().on_command("解密", "解开我们的秘密❤") - @encrypt_de.args_parser # type: ignore async def _get_encr_de_text(bot: Bot, event: MessageEvent, state: T_State): msg = str(event.message).strip() @@ -89,14 +82,12 @@ async def _get_encr_de_text(bot: Bot, event: MessageEvent, state: T_State): else: state["encr_de_text"] = msg - @encrypt_de.handle() async def _ready_de(bot: Bot, event: MessageEvent, state: T_State): msg = str(event.message).strip() if msg: state["encr_de_text"] = msg - @encrypt_de.got("encr_de_text", "内容呢?!") async def _deal_de(bot: Bot, event: MessageEvent, state: T_State): text = state["encr_de_text"] @@ -110,7 +101,6 @@ sepi = Utils().on_command("涩批一下", "将正常的句子涩一涩~") _sepi_flmt = FreqLimiter(3) _sepi_flmt_notice = ["涩批爬", "✌🥵✌"] - @sepi.args_parser # type: ignore async def _get_sepi(bot: Bot, event: MessageEvent, state: T_State): msg = str(event.message).strip() @@ -122,25 +112,23 @@ async def _get_sepi(bot: Bot, event: MessageEvent, state: T_State): else: state["sepi_text"] = msg - @sepi.handle() async def _ready_sepi(bot: Bot, event: MessageEvent, state: T_State): user_id = event.get_user_id() if not _sepi_flmt.check(user_id): await sepi.finish(choice(_sepi_flmt_notice)) - + msg = str(event.message).strip() if msg: state["sepi_text"] = msg - @sepi.got("sepi_text", "内容呢?!") async def _deal_sepi(bot: Bot, event: MessageEvent, state: T_State): user_id = event.get_user_id() msg = state["sepi_text"] if len(msg) < 4: await sepi.finish("这么短?涩不起来!") - + result = Yinglish.deal(msg, random()) _sepi_flmt.start_cd(user_id) await sepi.finish(result) diff --git a/ATRI/plugins/util/data_source.py b/ATRI/plugins/util/data_source.py index 7b36ebe..a6afdf3 100644 --- a/ATRI/plugins/util/data_source.py +++ b/ATRI/plugins/util/data_source.py @@ -14,9 +14,10 @@ __doc__ = """ class Utils(Service): + def __init__(self): Service.__init__(self, "小工具", __doc__, rule=is_in_service("小工具")) - + @staticmethod def roll_dice(par: str) -> str: result = 0 @@ -48,14 +49,13 @@ class Utils(Service): result = f"{par}=({proc})={result}" return result - - + class Encrypt(Utils): """ 某nb改的(逃 总之就是非常nb """ - + cr = "ĀāĂ㥹ÀÁÂÃÄÅ" cc = "ŢţŤťŦŧṪṫṬṭṮṯṰṱ" cn = "ŔŕŘřṘṙŖŗȐȑȒȓṚṛṜṝṞṟɌɍⱤɽᵲᶉɼɾᵳʀRr" @@ -186,9 +186,9 @@ class Encrypt(Utils): return self._decodeBytes(s).decode(encoding) except UnicodeDecodeError: raise ValueError("Decoding failed") - - + class Yinglish(Utils): + @staticmethod def _to_ying(x, y, ying) -> str: if random() > ying: diff --git a/ATRI/plugins/wife/__init__.py b/ATRI/plugins/wife/__init__.py new file mode 100644 index 0000000..a113b8a --- /dev/null +++ b/ATRI/plugins/wife/__init__.py @@ -0,0 +1,139 @@ +import asyncio +from random import choice +from pydantic import BaseModel + +from nonebot.permission import USER +from nonebot.rule import Rule +from nonebot.permission import SUPERUSER +from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent, Message + +from ATRI.utils.limit import FreqLimiter +from .data_source import Wife + + +_tietie_flmt = FreqLimiter(600) + + +tietie_superuser = Wife().on_message("只与维护者贴贴w", rule=Rule(), permission=SUPERUSER, block=False) + +@tietie_superuser.handle() +async def _tietie_superuser(bot: Bot, event: MessageEvent): + user_id = event.get_user_id() + if not _tietie_flmt.check(user_id): + await tietie_superuser.finish() + + result = Wife().to_superuser(user_id) + _tietie_flmt.start_cd(user_id) + await tietie_superuser.finish(Message(result)) + + +_wife_flmt = FreqLimiter(10) + +class MarryInfo(BaseModel): + name: str + sex: str + wife: str + + +get_wife = Wife().on_command("抽老婆", "随机选择一位幸运裙友成为老婆!") + +@get_wife.handle() +async def _get_wife(bot: Bot, event: GroupMessageEvent): + user_id = event.get_user_id() + if not _wife_flmt.check(user_id): + await get_wife.finish() + + group_id = event.group_id + req_user_info: dict = await bot.get_group_member_info(group_id=group_id, user_id=int(user_id)) + req_user_card = req_user_info["card"] + req_user_sex = req_user_info["sex"] + is_nick = "老公" if req_user_sex == "male" else "老婆" + + repo_0 = ( + "现在咱将随机抽取一位幸运裙友\n" + f"成为{req_user_card}的{is_nick}!" + ) + await bot.send(event, repo_0) + await asyncio.sleep(10) + + prep_list = await bot.get_group_member_list(group_id=group_id) + prep_list = [prep.get("user_id", 114514) for prep in prep_list] + + lucky_user = choice(prep_list) + lucky_user_info: dict = await bot.get_group_member_info(group_id=group_id, user_id=lucky_user) + lucky_user_card = lucky_user_info["card"] + lucky_user_sex = lucky_user_info["sex"] + + data = Wife().load_marry_list() + data[lucky_user] = MarryInfo( + name=req_user_card, + sex=is_nick, + wife=user_id + ).dict() + data[user_id] = MarryInfo( + name=lucky_user_card, + sex=lucky_user_sex, + wife=lucky_user + ).dict() + Wife().save_marry_list(data) + + repo_1 = f"好欸!{lucky_user_card}成为了{req_user_card}的{is_nick}" + _wife_flmt.start_cd(user_id) + await get_wife.finish(repo_1) + + +_call_wife_flmt = FreqLimiter(60) + + +call_wife = Wife().on_command("老婆", "呼唤老婆/老公!", aliases={"老公", "老婆!", "老公!"}, permission=USER("114514")) + +@call_wife.handle() +async def _call_wife(bot: Bot, event: MessageEvent): + user_id = event.get_user_id() + if not _wife_flmt.check(user_id): + await call_wife.finish() + + data = Wife().load_marry_list() + if user_id not in data: + return + + wife = data[user_id].get("wife", "ignore") + sex = data[user_id].get("sex", "male") + is_nick = "老公" if sex == "male" else "老婆" + repo = f"你已经有{is_nick}啦!是{wife}噢~" + _call_wife_flmt.start_cd(user_id) + await call_wife.finish(repo) + + +discard_wife = Wife().on_command("我要离婚", "离婚!") + +@discard_wife.handle() +async def _discard_wife(bot: Bot, event: GroupMessageEvent): + user_id = event.get_user_id() + if not _wife_flmt.check(user_id): + await discard_wife.finish() + + await bot.send(event, "真的吗...(y/是)") + msg = str(event.message).strip() + rd_list = ["y", "Y", "是", "确认", "对"] + if msg not in rd_list: + await discard_wife.finish("") + + group_id = event.group_id + group_info: dict = await bot.get_group_member_info(group_id=group_id, user_id=int(user_id)) + user_card = group_info.get("card", "老婆") + + data = Wife().load_marry_list() + if user_id not in data: + await discard_wife.finish("你还没对象呐...") + + discard_user_info = data[user_id] + discard_user_card = discard_user_info["name"] + discard_user_id = discard_user_info["wife"] + + data.pop(user_id) + data.pop(discard_user_id) + Wife().save_marry_list(data) + repo = f"悲,{user_card}抛弃了{discard_user_card}..." + _wife_flmt.start_cd(user_id) + await discard_wife.finish(repo) diff --git a/ATRI/plugins/wife/data_source.py b/ATRI/plugins/wife/data_source.py new file mode 100644 index 0000000..38e8be4 --- /dev/null +++ b/ATRI/plugins/wife/data_source.py @@ -0,0 +1,68 @@ +import os +import json +from random import choice +from pathlib import Path +from nonebot.adapters.cqhttp import MessageSegment + +from ATRI.service import Service +from ATRI.rule import is_in_service + + +WIFE_DIR = Path(".") / "data" / "database" / "wife" +os.makedirs(WIFE_DIR, exist_ok=True) + + +__doc__ = """ +老婆...嘿嘿嘿... +""" + + +class Wife(Service): + + def __init__(self): + Service.__init__(self, "老婆", __doc__, rule=is_in_service("老婆")) + + def to_superuser(self, user_id: str): + """ + 全自动贴贴机,限制只有超级管理员才能贴贴 + """ + content = choice( + [ + "mua!", + "贴贴!", + MessageSegment.image(file="https://cdn.jsdelivr.net/gh/Kyomotoi/CDN@master/project/ATRI/wife0.jpg"), + MessageSegment.image(file="https://cdn.jsdelivr.net/gh/Kyomotoi/CDN@master/project/ATRI/wife1.jpg"), + MessageSegment.image(file="https://cdn.jsdelivr.net/gh/Kyomotoi/CDN@master/project/ATRI/wife2.jpg"), + MessageSegment.image(file="https://cdn.jsdelivr.net/gh/Kyomotoi/CDN@master/project/ATRI/wife3.jpg") + ] + ) + result = MessageSegment.at(user_id) + content + return result + + @staticmethod + def load_marry_list() -> dict: + """ + 读取结婚列表 + """ + file_name = "marry_list.json" + path = WIFE_DIR / file_name + if not path.is_file(): + with open(path, "w", encoding="utf-8") as w: + w.write(json.dumps({})) + + data = json.loads(path.read_bytes()) + return data + + @staticmethod + def save_marry_list(data: dict) -> None: + """ + 存储结婚列表 + """ + file_name = "marry_list.json" + path = WIFE_DIR / file_name + if not path.is_file(): + with open(path, "w", encoding="utf-8") as w: + w.write(json.dumps({})) + + with open(path, "w", encoding="utf-8") as w: + w.write(json.dumps(data, indent=4)) diff --git a/ATRI/service.py b/ATRI/service.py index 378f2ca..cc3243b 100644 --- a/ATRI/service.py +++ b/ATRI/service.py @@ -16,7 +16,7 @@ if TYPE_CHECKING: from nonebot.adapters import Bot, Event -SERVICE_DIR = Path(".") / "ATRI" / "data" / "service" +SERVICE_DIR = Path(".") / "data" / "service" SERVICES_DIR = SERVICE_DIR / "services" os.makedirs(SERVICE_DIR, exist_ok=True) os.makedirs(SERVICES_DIR, exist_ok=True) @@ -58,19 +58,17 @@ class Service: "disable_group": [] } """ - - def __init__( - self, - service: str, - docs: str = None, - only_admin: bool = False, - rule: Optional[Union[Rule, T_RuleChecker]] = None, - permission: Optional[Permission] = None, - handlers: Optional[List[T_Handler]] = None, - temp: bool = False, - priority: int = 1, - state: Optional[T_State] = None, - ): + + def __init__(self, + service: str, + docs: str = None, + only_admin: bool = False, + rule: Optional[Union[Rule, T_RuleChecker]] = None, + permission: Optional[Permission] = None, + handlers: Optional[List[T_Handler]] = None, + temp: bool = False, + priority: int = 1, + state: Optional[T_State] = None): self.service = service self.docs = docs self.only_admin = only_admin @@ -86,7 +84,7 @@ class Service: service = self.service if not docs: docs = self.docs or str() - + path = SERVICES_DIR / f"{service}.json" data = ServiceInfo( service=service, @@ -95,33 +93,33 @@ class Service: enabled=True, only_admin=self.only_admin, disable_user=list(), - disable_group=list(), + disable_group=list() ) try: with open(path, "w", encoding="utf-8") as w: w.write(json.dumps(data.dict(), indent=4)) except WriteError: raise WriteError("Write service info failed!") - + def save_service(self, service_data: dict, service: str = None) -> None: if not service: service = self.service - + path = SERVICES_DIR / f"{service}.json" if not path.is_file(): self._generate_service_config() with open(path, "w", encoding="utf-8") as w: w.write(json.dumps(service_data, indent=4)) - + def load_service(self, service: str = None) -> dict: if not service: service = self.service - + path = SERVICES_DIR / f"{service}.json" if not path.is_file(): self._generate_service_config() - + try: data = json.loads(path.read_bytes()) except ReadFileError: @@ -130,31 +128,29 @@ class Service: self._generate_service_config() data = json.loads(path.read_bytes()) return data - + def _save_cmds(self, cmds: dict) -> None: data = self.load_service(self.service) temp_data: dict = data["cmd_list"] temp_data.update(cmds) self.save_service(data) - + def _load_cmds(self) -> dict: path = SERVICES_DIR / f"{self.service}.json" if not path.is_file(): self._generate_service_config() - + data = json.loads(path.read_bytes()) return data["cmd_list"] - def on_message( - self, - docs: str = None, - rule: Optional[Union[Rule, T_RuleChecker]] = None, - permission: Optional[Permission] = None, - handlers: Optional[List[T_Handler]] = None, - block: bool = True, - priority: int = None, - state: Optional[T_State] = None, - ) -> Type[Matcher]: + def on_message(self, + docs: str = None, + rule: Optional[Union[Rule, T_RuleChecker]] = None, + permission: Optional[Permission] = None, + handlers: Optional[List[T_Handler]] = None, + block: bool = True, + priority: int = None, + state: Optional[T_State] = None) -> Type[Matcher]: if not rule: rule = self.rule if not permission: @@ -165,7 +161,7 @@ class Service: priority = self.priority if not state: state = self.state - + if docs: a = 0 cmd_list = self._load_cmds() @@ -175,10 +171,14 @@ class Service: break else: a += 1 - - cmd_list[_type] = CommandInfo(type=_type, docs=docs, aliases=list()).dict() + + cmd_list[_type] = CommandInfo( + type=_type, + docs=docs, + aliases=list() + ).dict() self._save_cmds(cmd_list) - + matcher = Matcher.new( "message", Rule() & rule, @@ -200,10 +200,14 @@ class Service: break else: a += 1 - - cmd_list[_type] = CommandInfo(type=_type, docs=docs, aliases=list()).dict() + + cmd_list[_type] = CommandInfo( + type=_type, + docs=docs, + aliases=list() + ).dict() self._save_cmds(cmd_list) - + matcher = Matcher.new( "notice", Rule() & self.rule, @@ -225,10 +229,14 @@ class Service: break else: a += 1 - - cmd_list[_type] = CommandInfo(type=_type, docs=docs, aliases=list()).dict() + + cmd_list[_type] =CommandInfo( + type=_type, + docs=docs, + aliases=list() + ).dict() self._save_cmds(cmd_list) - + matcher = Matcher.new( "request", Rule() & self.rule, @@ -255,10 +263,14 @@ class Service: rule = self.rule if not aliases: aliases = set() - - cmd_list[cmd] = CommandInfo(type=_type, docs=docs, aliases=list(aliases)).dict() + + cmd_list[cmd] = CommandInfo( + type=_type, + docs=docs, + aliases=list(aliases) + ).dict() self._save_cmds(cmd_list) - + async def _strip_cmd(bot: "Bot", event: "Event", state: T_State): message = event.get_message() segment = message.pop(0) @@ -272,9 +284,7 @@ class Service: handlers.insert(0, _strip_cmd) commands = set([cmd]) | (aliases or set()) - return self.on_message( - rule=command(*commands) & rule, handlers=handlers, **kwargs - ) + return self.on_message(rule=command(*commands) & rule, handlers=handlers, **kwargs) def on_keyword( self, @@ -285,7 +295,7 @@ class Service: ) -> Type[Matcher]: if not rule: rule = self.rule - + a = 0 cmd_list = self._load_cmds() while True: @@ -294,10 +304,14 @@ class Service: break else: a += 1 - - cmd_list[_type] = CommandInfo(type=_type, docs=docs, aliases=list()).dict() + + cmd_list[_type] = CommandInfo( + type=_type, + docs=docs, + aliases=list() + ).dict() self._save_cmds(cmd_list) - + return self.on_message(rule=keyword(*keywords) & rule, **kwargs) def on_regex( @@ -311,15 +325,20 @@ class Service: _type = "regex" if not rule: rule = self.rule - + cmd_list = self._load_cmds() - cmd_list[pattern] = CommandInfo(type=_type, docs=docs, aliases=list()).dict() + cmd_list[pattern] = CommandInfo( + type=_type, + docs=docs, + aliases=list() + ).dict() self._save_cmds(cmd_list) - + return self.on_message(rule=regex(pattern, flags) & rule, **kwargs) class ServiceTools(object): + @staticmethod def save_service(service_data: dict, service: str) -> None: path = SERVICES_DIR / f"{service}.json" @@ -329,10 +348,10 @@ class ServiceTools(object): "Please delete all file in data/service/services.\n" "Next reboot bot." ) - + with open(path, "w", encoding="utf-8") as w: w.write(json.dumps(service_data, indent=4)) - + @staticmethod def load_service(service: str) -> dict: path = SERVICES_DIR / f"{service}.json" @@ -342,7 +361,7 @@ class ServiceTools(object): "Please delete all file in data/service/services.\n" "Next reboot bot." ) - + with open(path, "r", encoding="utf-8") as r: data = json.loads(r.read()) return data @@ -350,11 +369,11 @@ class ServiceTools(object): @classmethod def auth_service(cls, service, user_id: str = None, group_id: str = None) -> bool: data = cls.load_service(service) - + auth_global = data.get("enabled", True) auth_user = data.get("disable_user", list()) auth_group = data.get("disable_group", list()) - + if user_id: if user_id in auth_user: return False @@ -364,7 +383,7 @@ class ServiceTools(object): return False else: return True - + if not auth_global: return False else: |