async def system_status(app: Ariadne, group: Group, all_info: ArgResult, info: ArgResult, storage: ArgResult): mem = psutil.virtual_memory() memory_message = MessageChain( "内存相关:\n" f" 内存总大小:{round(mem.total / (1024 ** 3), 2)}GB\n" f" 内存使用量:{round(mem.used / (1024 ** 3), 2)}GB / {round(mem.total / (1024 ** 3), 2)}GB ({round(mem.used / mem.total * 100, 2)}%)\n" f" 内存空闲量:{round(mem.free / (1024 ** 3), 2)}GB / {round(mem.total / (1024 ** 3), 2)}GB ({round(mem.free / mem.total* 100, 2)}%)" ) cpu_message = MessageChain( "CPU相关:\n" f" CPU 物理核心数:{psutil.cpu_count(logical=False)}\n" f" CPU总体占用:{psutil.cpu_percent()}%\n" f" CPU频率:{psutil.cpu_freq().current}MHz") disk_message = MessageChain( "磁盘相关:\n" + " 图库占用空间:\n " + '\n '.join([ *[ f"{path_name}:{round(sum([os.path.getsize(path + file) for file in os.listdir(path)]) / (1024 ** 3), 2)}GB" if os.path.exists(path) else f"{path_name}:路径不存在" for path_name, path in image_path.items() ] ])) if all_info.matched or (not info.matched and not storage.matched): await app.sendGroupMessage( group, cpu_message + "\n" + memory_message + "\n" + disk_message) elif info.matched: await app.sendGroupMessage(group, cpu_message + "\n" + memory_message) elif storage.matched: await app.sendGroupMessage(group, disk_message)
async def saucenao_search(api_key: str, proxies: Optional[str] = None, *, url: Optional[str] = None, file: Optional[BinaryIO] = None) -> MessageChain: if not url and not file: raise ValueError("You should give url or file!") if not api_key: return MessageChain("未配置SAUCENAO_API_KEY!") async with Network(proxies=proxies) as client: saucenao = SauceNAO(client=client, api_key=api_key) if url: resp = await saucenao.search(url=url) elif file: resp = await saucenao.search(file=file) if not resp.raw: return MessageChain("SAUCENAO未搜索到结果!") resp = resp.raw[0] return MessageChain([ Plain("SAUCENAO搜索到以下结果:\n"), Image(data_bytes=await get_thumb(resp.thumbnail, proxies)), Plain(f"\n标题:{resp.title}\n"), Plain(f"相似度:{resp.similarity}%\n"), Plain(f"作者:{resp.author}\n"), Plain(f"pixiv图像 id:{resp.pixiv_id}\n" if resp.pixiv_id else ''), Plain(f"pixiv画师 id:{resp.member_id}\n" if resp.member_id else ''), Plain(f"链接:{resp.url}") ])
async def ehentai_search(proxies: Optional[str] = None, cookies: Optional[str] = None, ex: bool = False, *, url: Optional[str] = None, file: Optional[BinaryIO] = None) -> MessageChain: if not url and not file: raise ValueError("You should offer url or file!") if ex and not cookies: raise ValueError( "If you use EXHentai Searcher, you should offer cookies!") async with Network(proxies=proxies, cookies=cookies) as client: ehentai = EHentai(client=client) if url: resp = await ehentai.search(url=url, ex=ex) elif file: resp = await ehentai.search(file=file, ex=ex) if not resp.raw: return MessageChain("EHentai未搜索到结果!") resp = resp.raw[0] return MessageChain([ Plain("EHentai搜索到以下结果:\n"), Image(data_bytes=await get_thumb(resp.thumbnail, proxies)), Plain(f"\n标题:{resp.title}\n"), Plain(f"类别:{resp.type}\n"), Plain(f"上传日期:{resp.date}\n"), Plain(f"标签:{', '.join(resp.tags)}\n"), Plain(f"链接:{resp.url}") ])
async def random_cave(app: Ariadne, group: Group): content = db.random_cave() if content: await app.sendMessage(group, MessageChain(send_fmt.format(**content))) else: await app.sendMessage(group, MessageChain(["没有回声洞条目, 使用 “.cave -a” 添加一条吧!"]))
async def grant_permission_process(group_id: int, member_id: int, new_level: int) -> MessageChain: if await grant_permission(group_id, member_id, new_level): return MessageChain( f"修改成功!\n{member_id} permission level: {new_level}") else: return MessageChain("出现错误,请查看日志!")
async def limit(event: GroupMessage) -> NoReturn: if await Permission.get(event.sender.group, event.sender) >= override_level: return member = event.sender.id group = event.sender.group.id if not await group_setting.get_setting(group, Setting.frequency_limit): return frequency_limit_instance = await FrequencyLimit.get_frequency_limit_dict( ) await frequency_limit_instance.add_record(group, member, weight) if frequency_limit_instance.blacklist_judge(group, member): if not frequency_limit_instance.announce_judge(group, member): await frequency_limit_instance.blacklist_announced( group, member) await ariadne_ctx.get().sendGroupMessage( group, MessageChain("检测到大量请求,加入黑名单一小时!"), quote=event.messageChain.getFirst(Source)) raise ExecutionStop() if frequency_limit_instance.get( group, member, func_name) + weight >= total_weight: await ariadne_ctx.get().sendGroupMessage( group, MessageChain("超过频率调用限制!"), quote=event.messageChain.getFirst(Source)) raise ExecutionStop() else: await frequency_limit_instance.update(group, weight) return
async def joke(app: Ariadne, group: Group, keyword: RegexResult): keyword = keyword.result.asDisplay() if keyword in joke_non_replace.keys(): await app.sendGroupMessage( group, MessageChain(random.choice(joke_non_replace[keyword]))) else: await app.sendGroupMessage( group, MessageChain(random.choice(jokes).replace("%name%", keyword)))
async def dd_check(app: Ariadne, group: Group, message: MessageChain, username: RegexResult): if not username.result.asDisplay().strip(): return await app.sendGroupMessage(group, MessageChain("空白名怎么查啊kora!"), quote=message.getFirst(Source)) res = await get_reply(username.result.asDisplay().strip()) await app.sendGroupMessage( group, MessageChain(res if isinstance(res, str) else [Image(data_bytes=res)]), quote=message.getFirst(Source) )
async def up_pool_(app: Ariadne, group: Group, member: Member, message: MessageChain): if not await user_permission_require(group, member, 3): await app.sendMessage(group, MessageChain('只有群管理才能更新卡池'), quote=message.getFirst(Source)) return await app.sendMessage(group, MessageChain('正在更新卡池')) _ = await init_pool_list() await app.sendMessage(group, MessageChain('更新卡池完成'))
async def pdf_searcher(app: Ariadne, message: MessageChain, group: Group, keyword: RegexResult): base_url = "https://zh.sg1lib.org" keyword = keyword.result.asDisplay().strip() url = f"{base_url}/s/?q={keyword}" async with aiohttp.ClientSession(connector=TCPConnector( verify_ssl=False)) as session: async with session.get(url=url, proxy=proxy) as resp: html = await resp.read() soup = BeautifulSoup(html, "html.parser") try: divs = soup.find("div", { "id": "searchResultBox" }).find_all("div", {"class": "resItemBox resItemBoxBooks exactMatch"}) except AttributeError: await app.sendGroupMessage( group, MessageChain( f"请检查{base_url}是否可以正常访问!若不可以请检查代理是否正常,若代理正常可能为域名更换,请向仓库提出PR")) return count = 0 books = [] text = "搜索到以下结果:\n\n" for div in divs: count += 1 if count > 5: break name = div.find("h3").get_text().strip() href = div.find("h3").find("a", href=True)["href"] # cover = div.find("table").find("img")["src"] first_div = div.find("table").find("table").find("div") publisher = first_div.get_text().strip() if re.search( '.*?title="Publisher".*?', str(first_div)) else None authors = div.find("div", {"class": "authors"}).get_text().strip() text += f"{count}.\n" text += f"名字:{name}\n" text += f"作者:{authors}\n" if authors else "" text += f"出版社:{publisher}\n" if publisher else "" text += f"页面链接:{base_url + href}\n\n" books.append({ "name": name, # "cover": cover, "href": base_url + href, "publisher": publisher, "authors": authors }) if not books: text = "未搜索到结果呢 >A<\n要不要换个关键词试试呢~" await app.sendGroupMessage(group, MessageChain(text), quote=message.getFirst(Source))
async def wait_for_chain(chain: MessageChain, i_sender: Member): if i_sender.id == sender.id and i_sender.group.id == sender.group.id: await chain.download_binary() chain = chain.include(Plain, Image) if chain: if chain.asDisplay() != "取消": id: int = db.add_cave(sender.name, chain) await app.sendMessage(group, MessageChain([f"添加成功,ID: {id}"])) else: await app.sendMessage(group, MessageChain(["请发送图片或文本"])) return True
async def emoji_mix(app: Ariadne, message: MessageChain, group: Group, emoji1: RegexResult, emoji2: RegexResult): emoji1 = emoji1.result.asDisplay() emoji2 = emoji2.result.asDisplay() result = await mix_emoji(emoji1, emoji2) if isinstance(result, str): await app.sendGroupMessage(group, MessageChain(result), quote=message.getFirst(Source)) elif isinstance(result, bytes): await app.sendGroupMessage(group, MessageChain([Image(data_bytes=result)]), quote=message.getFirst(Source))
async def genshin_resource_points(app: Ariadne, message: MessageChain, group: Group, resource_name: RegexResult): resource_name = resource_name.result.asDisplay().strip() if check_resource_exists(resource_name): await get_resource_list() await app.sendGroupMessage(group, MessageChain("正在生成位置....")) await app.sendGroupMessage(group, await query_resource(resource_name), quote=message.getFirst(Source)) else: await app.sendGroupMessage( group, MessageChain(f"未查找到 {resource_name} 资源,可通过 “原神资源列表” 获取全部资源名称.."), quote=message.getFirst(Source))
async def get_result(keyword: str) -> MessageChain: url = "https://api.jikipedia.com/go/search_definitions" headers = {"Content-Type": "application/json;charset=UTF-8"} payload = {"phrase": keyword, "page": 1} async with get_running(Adapter).session.post( url=url, headers=headers, data=json.dumps(payload)) as resp: result = await resp.json() if result.get("category") == "ban_enabled": return MessageChain("请求过多,已达到访问上限,请稍后再试。") result = result["data"][0] return MessageChain([ f"{result['term']['title']}\n\n", f"标签:{'、'.join(tag['name'] for tag in result['tags'])}\n\n", f"释义:{result['content']}" ])
async def search(*, keyword: Optional[str] = None, data_bytes: Optional[bytes] = None) -> MessageChain: search_url = "https://xslist.org/search?lg=en&query=" pic_search_url = "https://xslist.org/search/pic" if not keyword and not data_bytes: raise ValueError("You should give keyword or data_bytes!") elif keyword: keyword = keyword.strip() async with get_running(Adapter).session.get(search_url + keyword, proxy=proxy) as resp: html = await resp.text() elif data_bytes: async with get_running(Adapter).session.post(pic_search_url, data={ "pic": data_bytes, "lg": "en" }, proxy=proxy) as resp: html = await resp.text() soup = BeautifulSoup(html, "html.parser") lis = soup.find_all("li") if not lis: return MessageChain(f"没有找到关于 {keyword} 的结果呢~换个关键词试试?") msgs = [] for li in lis: avatar = li.find("img")["src"] async with get_running(Adapter).session.get(avatar, proxy=proxy) as resp: avatar = await resp.read() msgs.append( MessageChain([ Image(data_bytes=avatar), Plain('\n'), Plain(li.find("h3").find("a")["title"]), Plain('\n'), Plain(li.find("p").get_text().replace("<br />", '\n')) ])) return msgs[0] if len(msgs) == 1 else MessageChain([ Forward([ ForwardNode( senderId=config.bot_qq, time=datetime.now(), senderName="SAGIRI BOT", messageChain=msg, ) for msg in msgs ]) ])
async def get_review( group: Group, member: Member, review_type: str, target: str, topK: int, mask: Optional[Image] ) -> MessageChain: group_id = group.id member_id = member.id time = datetime.now() time_right = time.strftime("%Y-%m-%d %H:%M:%S") if review_type in ("年内", "今年", "年度"): timep = time - relativedelta(years=1) time_left = (time - relativedelta(years=1)).strftime("%Y-%m-%d %H:%M:%S") elif review_type == ("月内", "本月", "月度"): timep = time - relativedelta(months=1) time_left = (time - relativedelta(months=1)).strftime("%Y-%m-%d %H:%M:%S") else: timep = time - relativedelta(days=1) time_left = (time - relativedelta(days=1)).strftime("%Y-%m-%d %H:%M:%S") sql = select( ChatRecord.id, ChatRecord.time, ChatRecord.group_id, ChatRecord.member_id, ChatRecord.seg, ).where( ChatRecord.group_id == group_id, ChatRecord.member_id == member_id if target == "member" else True, ChatRecord.time < time, ChatRecord.time > timep, ) if not (res := list(await orm.fetchall(sql))): return MessageChain("没有你的发言记录呐~")
async def random_character(app: Ariadne, message: MessageChain, group: Group): await app.sendGroupMessage(group, MessageChain("\n".join([ f"{k}:{random.choice(character_dict[k])}" for k in character_dict.keys() ])), quote=message.getFirst(Source))
async def get_github_trending() -> MessageChain: url = "https://github.com/trending" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " "Chrome/87.0.4280.141 Safari/537.36 " } async with get_running(Adapter).session.get(url=url, headers=headers, proxy=proxy) as resp: html = await resp.read() soup = BeautifulSoup(html, "html.parser") articles = soup.find_all("article", {"class": "Box-row"}) text_list = [f"随机数:{random.randint(0, 10000)}", "\ngithub实时热榜:\n"] index = 0 for i in articles: try: index += 1 title = i.find('h1').get_text().replace('\n', '').replace( ' ', '').replace('\\', ' \\ ') text_list.append(f"\n{index}. {title}\n") text_list.append(f"\n {i.find('p').get_text().strip()}\n") except: pass text = "".join(text_list).replace("#", "") return MessageChain(text)
async def image_searcher(app: Ariadne, message: MessageChain, group: Group, member: Member, image: ElementResult): @Waiter.create_using_function(listening_events=[GroupMessage]) async def image_waiter( waiter_group: Group, waiter_member: Member, waiter_message: MessageChain ): if waiter_group.id == group.id and waiter_member.id == member.id: if waiter_message.has(Image): return waiter_message.getFirst(Image).url else: return False if not image.matched: try: await app.sendMessage( group, MessageChain.create("请在30s内发送要处理的图片"), quote=message[Source][0] ) image = await asyncio.wait_for(inc.wait(image_waiter), 30) if not image: return await app.sendGroupMessage( group, MessageChain("未检测到图片,请重新发送,进程退出"), quote=message.getFirst(Source) ) except asyncio.TimeoutError: return await app.sendGroupMessage( group, MessageChain("图片等待超时,进程退出"), quote=message.getFirst(Source) ) else: image = image.result.url await app.sendGroupMessage(group, MessageChain("已收到图片,正在进行搜索..."), quote=message.getFirst(Source)) tasks = [ asyncio.create_task(saucenao_search(SAUCENAO_API_KEY, proxy, url=image)), asyncio.create_task(ascii2d_search(proxy, url=image)), asyncio.create_task(ehentai_search(proxy, url=image)), asyncio.create_task(google_search(proxy, url=image)), asyncio.create_task(baidu_search(url=image)) ] msgs = await asyncio.gather(*tasks) await app.sendGroupMessage(group, MessageChain([ Forward([ ForwardNode( senderId=config.bot_qq, time=datetime.now(), senderName="SAGIRI BOT", messageChain=msg, ) for msg in msgs ]) ]))
async def memes(app: Ariadne, message: MessageChain, group: Group, prefix: RegexResult, content: RegexResult): prefix = prefix.result.asDisplay().strip() content = [content.result.asDisplay()] result = None if prefix == "nokia": result = await Memes.make_nokia(content) elif prefix == "鲁迅说": result = await Memes.make_luxunsay(content) elif prefix == "喜报": result = await Memes.make_goodnews(content) elif prefix == "记仇": result = await Memes.make_jichou(content) elif prefix in ("狂爱", "狂粉"): result = await Memes.make_fanatic(content) elif prefix == "低语": result = await Memes.make_diyu(content) elif prefix == "别说了": result = await Memes.make_shutup(content) elif prefix == "一巴掌": result = await Memes.make_slap(content) elif prefix == "滚屏": result = await Memes.make_scroll(content) else: content = shlex.split(content[0]) for key in gif_subtitle_memes.keys(): if prefix in gif_subtitle_memes[key]["aliases"]: if len(content) != len(gif_subtitle_memes[key]["pieces"]): await app.sendGroupMessage( group, MessageChain( f"参数数量不符,需要输入{len(gif_subtitle_memes[key]['pieces'])}段文字,若包含空格请加引号" ), quote=message.getFirst(Source)) return else: result = await Memes.gif_func(gif_subtitle_memes[key], content) if result: await app.sendGroupMessage( group, MessageChain([ Image(data_bytes=result.getvalue()) if isinstance( result, BytesIO) else Plain(text=result) ]), quote=message.getFirst(Source))
async def execute_blacklist_remove(member_id: int, group: Group, operator: Member) -> MessageChain: try: if not await user_permission_require(group, operator, 2): return MessageChain("权限不足,爬!") if not await orm.fetchone( select(BlackList.member_id, BlackList.group_id).where( BlackList.member_id == member_id, BlackList.group_id == group.id)): return MessageChain(f"{member_id} 不在本群黑名单中!") await orm.delete( BlackList, [BlackList.member_id == member_id, BlackList.group_id == group.id]) return MessageChain(f"{member_id} 移除本群黑名单成功") except Exception as e: logger.error(traceback.format_exc()) return MessageChain(str(e))
async def github_info(app: Ariadne, message: MessageChain, group: Group, image: ArgResult, keyword: RegexResult): image = image.matched keyword = keyword.result.asDisplay() url = "https://api.github.com/search/repositories?q=" img_url = "https://opengraph.githubassets.com/c9f4179f4d560950b2355c82aa2b7750bffd945744f9b8ea3f93cc24779745a0/" async with get_running(Adapter).session.get(url=url + keyword) as resp: result = (await resp.json())["items"] if not result: await app.sendGroupMessage(group, MessageChain("没有搜索到结果呢~"), quote=message.getFirst(Source)) elif image: img_url += result[0]["full_name"] async with get_running(Adapter).session.get(img_url) as resp: content = await resp.read() await app.sendGroupMessage(group, MessageChain([Image(data_bytes=content)]), quote=message.getFirst(Source)) else: result = result[0] name = result["name"] owner = result["owner"]["login"] description = result["description"] repo_url = result["html_url"] stars = result["stargazers_count"] watchers = result["watchers"] language = result["language"] forks = result["forks"] issues = result["open_issues"] repo_license = result["license"]["key"] if result["license"] else "无" msg = MessageChain([ Plain(text=f"名称:{name}\n"), Plain(text=f"作者:{owner}\n"), Plain(text=f"描述:{description}\n"), Plain(text=f"链接:{repo_url}\n"), Plain(text=f"stars:{stars}\n"), Plain(text=f"watchers:{watchers}\n"), Plain(text=f"forks:{forks}\n"), Plain(text=f"issues:{issues}\n"), Plain(text=f"language:{language}\n"), Plain(text=f"license:{repo_license}") ]) try: await app.sendGroupMessage(group, msg, quote=message.getFirst(Source)) except MessageTooLong: await app.sendGroupMessage( group, MessageChain([Image(data_bytes=TextEngine([GraiaAdapter(msg)]).draw())]), quote=message.getFirst(Source) )
async def speak(app: Ariadne, message: MessageChain, group: Group, voice_type: ArgResult, content: RegexResult): text = content.result.asDisplay() voice_type = voice_type.result if voice_type.matched else await group_setting.get_setting( group.id, Setting.voice) if voice_type == "off": return None if voice := await Speak.aget_voice(text, voice_type): if isinstance(voice, str): await app.sendGroupMessage(group, MessageChain(voice), quote=message.getFirst(Source)) elif isinstance(voice, bytes): await app.sendGroupMessage( group, MessageChain( [Voice(data_bytes=await silkcoder.async_encode(voice))]))
async def xslist_handler(app: Ariadne, group: Group, keyword: RegexResult, image: ElementResult): if image.matched: await app.sendGroupMessage(group, await search(data_bytes=await image.result.get_bytes())) elif keyword.matched: keyword = keyword.result.asDisplay().strip() await app.sendGroupMessage(group, await search(keyword=keyword)) else: await app.sendGroupMessage(group, MessageChain("什么都没有,你让我查什么好呢~"))
async def cp_generator(app: Ariadne, message: MessageChain, group: Group, attack: RegexResult, defence: RegexResult): attack = attack.result.asDisplay() defence = defence.result.asDisplay() template = random.choice(cp_data["data"]) content = template.replace("<攻>", attack).replace("<受>", defence) await app.sendGroupMessage(group, MessageChain(content), quote=message.getFirst(Source))
async def execute_setting_update(group: Group, member: Member, command: str) -> MessageChain: """ setting -set setu=True real=True 多命令执行 """ commands = command[13:].split(" ") error_commands = [] success_commands = [] for command in commands: try: command = command.strip() # .replace("-", "") if not command: continue func, value = command.split("=") func = camel_to_underscore(func) value = (True if value == "True" else False) if value in [ "True", "False" ] else value if func in command_index.keys(): if command_index[func].is_valid(value): """ update """ if await user_permission_require( group, member, command_index[func].level): try: await orm.insert_or_update( Setting, [Setting.group_id == group.id], {func: value}) await group_setting.modify_setting( group, func, value) success_commands.append(f"{func} -> {value}") except Exception as e: error_commands.append((command, str(e))) logger.error(traceback.format_exc()) else: error_commands.append( (command, f"权限不足,要求权限等级{command_index[func].level}")) else: error_commands.append(( f"{func} -> {value}", f"期望值:{','.join([str(valid_value) for valid_value in command_index[func].valid_values])}" )) else: error_commands.append((command, "未找到此命令")) except ValueError: error_commands.append((command, "格式非法!应为 func=value")) response_text = f"共解析{len(commands)}条命令,\n其中{len(success_commands)}条执行成功,{len(error_commands)}条失败" if success_commands: response_text += "\n\n成功命令:" for i in success_commands: response_text += f"\n{i}" if error_commands: response_text += "\n\n失败命令:" for i in error_commands: response_text += f"\n{i[0]} | {i[1]}" return MessageChain(response_text)
async def message_merger(app: Ariadne, message: MessageChain, group: Group, msg_to_merge: RegexResult): await app.sendGroupMessage( group, MessageChain([ Image(data_bytes=TextEngine([GraiaAdapter(msg_to_merge.result)], min_width=1080).draw()) ]), quote=message.getFirst(Source))
async def phantom_tank(app: Ariadne, message: MessageChain, group: Group, colorful: RegexResult, img1: ElementResult, img2: ElementResult): async with get_running(Adapter).session.get(url=img1.result.url) as resp: display_img = PIL.Image.open(BytesIO(await resp.read())) async with get_running(Adapter).session.get(url=img2.result.url) as resp: hide_img = PIL.Image.open(BytesIO(await resp.read())) if colorful.matched: msg = MessageChain([ Image(data_bytes=await PhantomTank.colorful_tank( display_img, hide_img)) ]) else: msg = MessageChain([ Image( data_bytes=await PhantomTank.make_tank(display_img, hide_img)) ]) await app.sendGroupMessage(group, msg, quote=message.getFirst(Source))
async def wolfram_alpha(app: Ariadne, message: MessageChain, group: Group, content: RegexResult): question = content.result.asDisplay() if not api_key or api_key == "wolfram_alpha_key": return MessageItem( MessageChain.create([Plain(text="尚未配置wolfram_alpha_key!")]), QuoteSource()) url = f"https://api.wolframalpha.com/v1/simple?i={question.replace('+', '%2B')}&appid={api_key}" async with get_running(Adapter).session.get(url=url) as resp: if resp.status == 200: res = await resp.read() await app.sendGroupMessage(group, MessageChain([Image(data_bytes=res)]), quote=message.getFirst(Source)) else: await app.sendGroupMessage(group, MessageChain(await resp.text()), quote=message.getFirst(Source))
async def random_wife(app: Ariadne, message: MessageChain, group: Group): await app.sendGroupMessage( group, MessageChain([ Image( url= f"https://www.thiswaifudoesnotexist.net/example-{random.randint(1, 100000)}.jpg" ) ]), quote=message.getFirst(Source))