async def get_soup(): url = f"https://du.shadiao.app/api.php?from={get_config('shadiaoAppName')}" async with aiohttp.ClientSession() as session: async with session.get(url=url) as resp: text = await resp.text() return MessageItem(MessageChain.create([Plain(text=text)]), Normal(GroupStrategy()))
async def printDM(app, data, room_id): '''解析并输出数据包的数据''' # 获取数据包的长度,版本和操作类型 packetLen = int(data[:4].hex(), 16) ver = int(data[6:8].hex(), 16) op = int(data[8:12].hex(), 16) # 有的时候可能会两个数据包连在一起发过来,所以利用前面的数据包长度判断, if(len(data) > packetLen): await printDM(app, data[packetLen:], room_id) data = data[:packetLen] # 有时会发送过来 zlib 压缩的数据包,这个时候要去解压。 if(ver == 2): data = zlib.decompress(data[16:]) await printDM(app, data, room_id) return # ver 为1的时候为进入房间后或心跳包服务器的回应。op 为3的时候为房间的人气值。 if(ver == 1): if(op == 3): t = datetime.datetime.now().strftime("[%Y-%m-%d %H:%M:%S,%f") t = t[:len(t) - 3] + ']' print('%s[POPULARITY]: %s: %d' % (t, room_id, int(data[16:].hex(), 16))) return # ver 不为2也不为1目前就只能是0了,也就是普通的 json 数据。 # op 为5意味着这是通知消息,cmd 基本就那几个了。 if(op == 5): try: jd = json.loads(data[16:].decode('utf-8', errors='ignore')) sstr = '' ''' if(jd['cmd'] == 'DANMU_MSG'): sstr = '[DANMU] ' + jd['info'][2][1] + ': ' + jd['info'][1] elif(jd['cmd'] == 'LIVE'): sstr = '[Notice] LIVE Start!' elif(jd['cmd'] == 'PREPARING'): sstr = '[Notice] LIVE Ended!' elif(jd['cmd'] == 'SEND_GIFT'): sstr = '[GIFT]' + jd['data']['uname'] + ' ' + jd['data']['action'] + ' ' + str(jd['data']['num']) + 'x' + jd['data']['giftName'] elif(jd['cmd'] == "INTERACT_WORD"): if jd['data']['msg_type'] == 1: sstr = '[ENTRY] ' + jd['data']['uname'] + ' 进入直播间' elif jd['data']['msg_type'] == 2: sstr = '[FOLLOW] ' + jd['data']['uname'] + ' 关注了直播间' elif(jd['cmd'] == "未知"): print(jd) sstr = '[SHARE] ' + jd['data']['uname'] + ' 分享了直播间' else: sstr = '[OTHER] ' + jd['cmd'] if sstr != '': await app.sendGroupMessage(group, MessageChain.create([Plain(sstr)])) ''' if(jd['cmd'] == 'LIVE'): Localpath = './data/live.json' data = {} fr = open(Localpath, encoding='utf-8') data = json.load(fr) fr.close() info = get_info(room_id) for i in data["data"]: if (room_id != str(i['room_id'])): continue for j in i['group']: sstr = '%s的直播开始啦!\n直播关键帧:' % info['user'] await app.sendGroupMessage(j, MessageChain.create([ Plain(sstr), Image.fromNetworkAddress(info['keyframe']), Plain('\n直播间地址:https://live.bilibili.com/%d' % info['room_id']) ])) break except Exception as e: pass
async def get_pic(image_type: str, group_id: int, sender: int) -> list: """ Return random pics message Args: image_type: The type of picture to return image type list: setu: hPics(animate R-15) setu18: hPics(animate R-18) real: hPics(real person R-15) bizhi: Wallpaper(animate All age) group_id: Group id sender: Sender Examples: assist_process = await get_pic("setu")[0] message = await get_pic("real")[1] Return: [ str: Auxiliary treatment to be done(Such as add statement), MessageChain: Message to be send(MessageChain) ] """ async def color() -> str: base_path = await get_config("setuPath") pic_path = await random_pic(base_path) return pic_path async def color18() -> str: base_path = await get_config("setu18Path") pic_path = await random_pic(base_path) return pic_path async def real() -> str: base_path = await get_config("realPath") pic_path = await random_pic(base_path) return pic_path async def real_highq() -> str: base_path = await get_config("realHighqPath") pic_path = await random_pic(base_path) return pic_path async def wallpaper() -> str: base_path = await get_config("wallpaperPath") pic_path = await random_pic(base_path) return pic_path async def sketch() -> str: base_path = await get_config("sketchPath") pic_path = await random_pic(base_path) return pic_path switch = { "setu": color, "setu18": color18, "real": real, "realHighq": real_highq, "bizhi": wallpaper, "sketch": sketch } target_pic_path = await switch[image_type]() message = MessageChain.create([Image.fromLocalFile(target_pic_path)]) await write_log(image_type, target_pic_path, sender, group_id, True, "img") if image_type == "setu18": operation = await get_setting(group_id, "r18Process") if operation == "revoke": return ["revoke", message, target_pic_path] elif operation == "flashImage": message = MessageChain.create( [Image.fromLocalFile(target_pic_path).asFlash()]) return ["None", message, target_pic_path] return ["None", message, target_pic_path]
async def group_message_listener(app: GraiaMiraiApplication, group: Group, message: MessageChain, member: Member): # print(group) # id=1130879466 name='测试群' accountPerm=<MemberPerm.Member: 'MEMBER'> # print(type(group)) if group.id in config.GROUPS: # print(message.asDisplay()) # print(message.__root__) # print(message.__root__[2].target) # print(type(message.__root__[2].target)) if config.STATE == 0 and message.asDisplay() == "开启bot": await app.sendGroupMessage(group, MessageChain.create([Plain("加载群成员数据")])) group_info = await app.memberList(group) for i in group_info: Player.member_list[i.id] = i.name print(Player.member_list) await app.sendGroupMessage( group, MessageChain.create([Plain("加载成功\n bot已开启")])) # bot start config.STATE = 1 elif config.STATE == 1 and message.asDisplay() == "关闭bot": config.STATE = 0 await app.sendGroupMessage(group, MessageChain.create([Plain("关闭bot")])) elif (config.STATE == 0 and message.asDisplay() == "关闭bot") or \ (config.STATE == 1 and message.asDisplay() == "开启bot"): await app.sendGroupMessage(group, MessageChain.create([Plain("异常操作")])) elif config.STATE == 1: message_return = "" # 申请出刀,解除出刀,完成,击杀,代打,撤回出刀,挂树,查树,强行下树 if message.asDisplay() == "申请出刀": if member.name not in Player.player_list and member.name not in Player.player_on_tree_list: # 正常 Player.player_list.append(member.name) message_return = "%s开始出刀" % member.name elif member.name in Player.player_list: message_return = "您已在出刀序列中" elif member.name in Player.player_on_tree_list: message_return = "您已挂树" elif message.asDisplay() == "解除出刀": if member.name in Player.player_list: Player.player_list.remove(member.name) message_return = "成功解除出刀" elif member.name not in Player.player_list: message_return = "您不在出刀序列中" elif member.name in Player.player_on_tree_list: message_return = "您已挂树" elif message.asDisplay().startswith("完成"): hurtNum = Boss.split_message(Boss, message.asDisplay()) hurtNum = int(hurtNum) if member.name in Player.player_list: message_return = Boss.hurtNum(Boss, member.name, hurtNum) Player.player_list.remove(member.name) elif member.name not in Player.player_list: message_return = "您还没有出刀" elif message.asDisplay().startswith("代打"): print(message.__root__[2].target) print(type(message.__root__[2].target)) name = Player.member_list.get(message.__root__[2].target) print("name", name) hurtNum = int(Boss.split_message(Boss, message.asDisplay())) message_return = Boss.hurtNum(Boss, name, hurtNum) elif message.asDisplay() == "撤回出刀": message_return = Boss.recall_last_hurtNum(Boss, member.name) elif message.asDisplay() == "挂树": if member.name in Player.player_list: Player.player_list.remove(member.name) Player.player_on_tree_list.append(member.name) message_return = "%s挂树" % (member.name) elif member.name not in Player.player_list: message_return = "您还没有出刀" elif member.name in Player.player_on_tree_list: message_return = "您已经挂树" elif message.asDisplay() == "查树": message_return = Player.read_tree(Player) elif message.asDisplay().startswith("强行下树"): if member.name in Player.player_on_tree_list: hurtNum = Boss.split_message(Boss, message.asDisplay()) hurtNum = int(hurtNum) message_return = Boss.hurtNum(Boss, member.name, hurtNum) elif member.name in Player.player_list: message_return = "您没有挂树,请正常报刀" elif member.name not in Player.player_list and member.name not in Player.player_on_tree_list: message_return = "请申请出刀" # boss数据操作 elif message.asDisplay() == "查看": message_return = Boss.get_boss_info(Boss) elif message.asDisplay().startswith("修正"): round, i, boss_remain = Boss.split_message( Boss, message.asDisplay()) round = int(round) i = int(i) boss_remain = int(boss_remain) message_return = Boss.set_boss_info(Boss, round, i, boss_remain) # 会战数据操作 elif message.asDisplay() == "出刀数据": message_return = Player.read(Player, Player.fight_data) elif message.asDisplay() == "读取": message_return = Player.readf(Player) elif message.asDisplay() == "保存": message_return = Player.savef(Player) else: message_return = "" await app.sendGroupMessage( group, MessageChain.create([Plain(message_return)]))
async def IndeedNext(app: GraiaMiraiApplication, group: Group, mesg: MessageChain): msg = getAt(mesg)[1] if '下次一定' in msg: await app.sendGroupMessage(group, MessageChain.create([ Plain(text='下次一定')])) pass
async def blhx(app, group): url = "https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/space_history?visitor_uid=33091201&host_uid=233114659&offset_dynamic_id=0&need_top=1&platform=web" Information = requests.get(url, headers=headers).json() judge = Information['data']['cards'][1] if judge['desc']['type'] == 1: needInformation = Information['data']['cards'][1]['card'] dictInformation = eval(needInformation) msg = dictInformation['item']['content'] message = MessageChain.create( [Plain("碧蓝航线b服动态更新\n================\n"), Plain(msg)]) await app.sendGroupMessage(group, message) elif judge['desc']['type'] == 2: needInformation = Information['data']['cards'][1]['card'] dictInformation = eval(needInformation) try: if (dictInformation['item']['pictures_count'] == 1): pictures = dictInformation['item']['pictures'][0]['img_src'] flag = 0 else: pictures = dictInformation['item']['pictures'] flag = 1 count = dictInformation['item']['pictures_count'] except: pictures = " " msgDict = { "information": dictInformation['item']['description'], "picture_url": pictures } if msgDict['picture_url'] != ' ': if flag == 0: msgDict['picture_url'] = eval( repr(msgDict['picture_url']).replace('\\', '')) await app.sendGroupMessage( group, MessageChain.create([ Plain("碧蓝航线b服动态更新\n================\n"), Plain(msgDict['information']), Image.fromNetworkAddress(msgDict['picture_url']) ])) elif flag == 1: message1 = MessageChain.create([ Plain("碧蓝航线b服动态更新\n================\n"), Plain(msgDict['information']) ]) for i in range(count): msg = MessageChain.join( [Image.fromNetworkAddress(pictures[i]['img_src'])]) #Msg = MessageChain.join(message1, msg) #await app.sendGroupMessage(group, Msg) else: await app.sendGroupMessage( group, MessageChain.create([ Plain("碧蓝航线b服动态更新\n================\n"), Plain(msgDict['information']) ])) elif judge['desc']['type'] == 4: needInformation = Information['data']['cards'][1]['card'] dictInformation = eval(needInformation) pictures = " " msgDict = { "information": dictInformation['item']['content'], "picture_url": pictures } for group in groups: if msgDict['picture_url'] != ' ': msgDict['picture_url'] = eval( repr(msgDict['picture_url']).replace('\\', '')) await app.sendGroupMessage( group, MessageChain.create([ Plain("碧蓝航线b服动态更新\n================\n"), Plain(msgDict['information']), Image.fromNetworkAddress(msgDict['picture_url']) ])) else: await app.sendGroupMessage( group, MessageChain.create([ Plain("碧蓝航线b服动态更新\n================\n"), Plain(msgDict['information']) ]))
if interface.name == "__literature_messagechain__": return result = interface.execution_contexts[-1].literature_detect_result if result: param_value = result.get(interface.name) return param_value if __name__ == "__main__": from graia.application.message.elements.internal import AtAll, At mc = MessageChain.create([ Plain('test n -gt "1 2 tsthd thsd ydj re7u '), At(351453455), Plain(' " "arg arega er ae aghr ae rtyh'), At(656735757), Plain(' "'), ]) l = Literature( "test", "n", parameters={ "n1": SwitchParameter(["--bool-test", "-bt"]), "n2": BoxParameter(["-gt"]), }, ) from devtools import debug debug(l.detect_index(mc)) print(mc.asDisplay())
def MindBoy(app: GraiaMiraiApplication, group: Group, member: Member, message): r = requests.get("https://api.66mz8.com/api/social.php?format=json") data = json.loads(r.text) payload = data['social'] return app.sendGroupMessage(group.id, MessageChain.create([Plain(text=payload)]))
async def get_hero_statics(hero_name: str, hero_position: str) -> MessageItem: if hero_name in lol_hero_name_to_code.keys(): hero_name = lol_hero_name_to_code[hero_name] if hero_name not in lol_hero_name_to_code.values(): return MessageItem( MessageChain.create([Plain(text="没有找到呢~看看是不是英雄名字打错了呐~")]), QuoteSource(GroupStrategy())) headers = { "accept-language": "zh-CN,zh;q=0.9,zh-TW;q=0.8,en-US;q=0.7,en;q=0.6" } url = f"https://www.op.gg/champion/{hero_name}/statistics/" async with aiohttp.ClientSession() as session: async with session.get(url=url, headers=headers) as resp: html = await resp.read() soup = BeautifulSoup(html, "html.parser") lis = soup.find_all("li", {"class": "champion-stats-header__position"}) positions = [li["data-position"].lower() for li in lis] print(positions) if hero_position.lower() not in positions: return MessageItem( MessageChain.create([ Plain(text=f"没有这个位置呢~{hero_name}的位置只有" + "、".join(positions) + "呢!") ]), QuoteSource(GroupStrategy())) data = {} url = f"https://www.op.gg/champion/{hero_name}/statistics/{hero_position}" async with aiohttp.ClientSession() as session: async with session.get(url=url, headers=headers) as resp: html = await resp.read() soup = BeautifulSoup(html, "html.parser") summoner_spell_table = soup.find_all( "table", { "class": "champion-overview__table champion-overview__table--summonerspell" })[0] trs = summoner_spell_table.find_all("tr")[1:] for tr in trs[:2]: print(await LOLItemRaidersHandler.get_img_rates(tr)) skill_imgs = [ "https:" + img["src"] for img in trs[3].find_all( "ul", {"class": "champion-stats__list"})[0].find_all("img") ] while "https://opgg-static.akamaized.net/images/site/champion/blet.png" in skill_imgs: skill_imgs.remove( "https://opgg-static.akamaized.net/images/site/champion/blet.png" ) print(skill_imgs) overview_table = soup.find_all( "table", {"class": "champion-overview__table"})[1] split_tr = overview_table.find_all( "tr", {"class": "champion-overview__row champion-overview__row--first"}) print(len(split_tr)) item_constructions = [[], [], []] index = -1 for tr in overview_table.find_all("tr", {"class": "champion-overview__row"}): if tr in split_tr: index += 1 item_constructions[index].append(tr) # 初始装备 trs = item_constructions[0] for tr in trs: print(await LOLItemRaidersHandler.get_img_rates(tr)) # 推荐建设 trs = item_constructions[1] for tr in trs: print(await LOLItemRaidersHandler.get_img_rates(tr)) # 鞋子 trs = item_constructions[2] for tr in trs: print(await LOLItemRaidersHandler.get_img_rates(tr)) rune_table = soup.find_all( "table", { "class": "champion-overview__table champion-overview__table--rune tabItems" })[0] tbodys = rune_table.find_all("tbody")[1:] rune_data = [] for tbody in tbodys: trs = tbody.find_all("tr") rune_divs = trs[0].find_all("div", {"class": "perk-page-wrap"}) for rune_div in rune_divs: row_data_imgs = [] rune_div_pages = rune_div.find_all("div", {"class": "perk-page"}) rune_div_fragment = rune_div.find_all( "div", {"class": "fragment-page"})[0] for rune_div_page in rune_div_pages: row_imgs = [] rows = rune_div_page.find_all("div", {"class": "perk-page__row"}) row_imgs.append("https:" + rows[0].find_all("img")[0]["src"]) for row in rows[1:]: row_img = [ "https:" + img["src"] for img in row.find_all("img") ] row_imgs.append(row_img) row_data_imgs.append(row_imgs) rune_data.append(row_imgs) row_imgs = [] for row in rune_div_fragment.find_all( "div", {"class": "fragment__row"}): row_img = [ "https:" + img["src"] for img in row.find_all("img") ] row_imgs.append(row_img) row_data_imgs.append(row_imgs) print(json.dumps(row_data_imgs, indent=4)) return MessageItem( MessageChain.create( [Image.fromUnsafeAddress(url) for url in skill_imgs]), QuoteSource(GroupStrategy()))
class GroupWordCloudGeneratorHandler(AbstractHandler): __name__ = "GroupWordCloudGeneratorHandler" __description__ = "群词云生成器" __usage__ = "在群中发送 `我的月/年内总结` 即可查看个人月/年词云\n在群众发送 `本群月/年内总结` 即可查看群组月/年词云(需要权限等级2)" async def handle(self, app: GraiaMiraiApplication, message: MessageChain, group: Group, member: Member): message_text = message.asDisplay() if message_text == "我的月内总结": await update_user_call_count_plus1(group, member, UserCalledCount.functions, "functions") return await self.get_review(group, member, "month", "member") elif message_text == "我的年内总结": await update_user_call_count_plus1(group, member, UserCalledCount.functions, "functions") return await self.get_review(group, member, "year", "member") elif message_text == "本群月内总结": await update_user_call_count_plus1(group, member, UserCalledCount.functions, "functions") return await self.get_review(group, member, "month", "group") elif message_text == "本群年内总结": await update_user_call_count_plus1(group, member, UserCalledCount.functions, "functions") return await self.get_review(group, member, "year", "group") else: return await super().handle(app, message, group, member) @staticmethod async def count_words(sp, n): w = {} for i in sp: if i not in w: w[i] = 1 else: w[i] += 1 top = sorted(w.items(), key=lambda item: (-item[1], item[0])) top_n = top[:n] return top_n @staticmethod async def filter_label(label_list: list) -> list: not_filter = ["草"] image_filter = "mirai:" result = [] for i in label_list: if image_filter in i: continue elif i in not_filter: result.append(i) elif len(i) != 1 and i.find('nbsp') < 0: result.append(i) return result @staticmethod async def draw_word_cloud(read_name) -> bytes: mask = np.array(IMG.open(f'statics/wordcloud/back.jpg')) # print(mask.shape) wc = WordCloud( font_path=f'statics/fonts/STKAITI.TTF', background_color='white', # max_words=500, max_font_size=100, width=1920, height=1080, mask=mask) name = [] value = [] for t in read_name: name.append(t[0]) value.append(t[1]) for i in range(len(name)): name[i] = str(name[i]) dic = dict(zip(name, value)) # print(dic) # print(len(dic.keys())) wc.generate_from_frequencies(dic) image_colors = ImageColorGenerator(mask, default_color=(255, 255, 255)) # print(image_colors.image.shape) wc.recolor(color_func=image_colors) plt.imshow(wc.recolor(color_func=image_colors), interpolation="bilinear") plt.axis("off") bytes_io = BytesIO() img = wc.to_image() img.save(bytes_io, format='PNG') return bytes_io.getvalue() @staticmethod @frequency_limit_require_weight_free(3) async def get_review(group: Group, member: Member, review_type: str, target: str) -> MessageItem: group_id = group.id member_id = member.id time = datetime.now() time_right = time.strftime("%Y-%m-%d %H:%M:%S") if review_type == "year": timep = time - relativedelta(years=1) time_left = (time - relativedelta(years=1)).strftime("%Y-%m-%d %H:%M:%S") tag = "年内" elif review_type == "month": timep = time - relativedelta(months=1) time_left = (time - relativedelta(years=1)).strftime("%Y-%m-%d %H:%M:%S") tag = "月内" else: return MessageItem( MessageChain.create( [Plain(text="Error: review_type invalid!")]), QuoteSource(GroupStrategy())) sql = select(ChatRecord).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(orm.fetchall(sql))): return MessageItem(MessageChain.create([Plain(text="没有你的发言记录呐~")]), QuoteSource(GroupStrategy())) texts = [] for i in res: if i[5]: texts += i[5].split("|") else: texts.append(i[3]) top_n = await GroupWordCloudGeneratorHandler.count_words(texts, 20000) sql = select([func.count()]).select_from(ChatRecord).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(orm.fetchone(sql))): return MessageItem(MessageChain.create([Plain(text="没有你的发言记录呐~")]), QuoteSource(GroupStrategy()))
def Ohayo(app: Mirai, group: Group, member: Member, message: MessageChain): return app.sendGroupMessage(group.id, MessageChain.create([Plain(text="早上好!")]))
for i in res: if i[5]: texts += i[5].split("|") else: texts.append(i[3]) top_n = await GroupWordCloudGeneratorHandler.count_words(texts, 20000) sql = select([func.count()]).select_from(ChatRecord).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(orm.fetchone(sql))): return MessageItem(MessageChain.create([Plain(text="没有你的发言记录呐~")]), QuoteSource(GroupStrategy())) times = res[0][0] return MessageItem( MessageChain.create([ Plain(text="记录时间:\n"), Plain(text=f"{time_left}"), Plain(text="\n---------至---------\n"), Plain(text=f"{time_right}"), Plain( text= f"\n自有记录以来,{'你' if target == 'member' else '本群'}一共发了{times}条消息\n下面是{'你的' if target == 'member' else '本群的'}{tag}词云:\n" ), Image.fromUnsafeBytes( await GroupWordCloudGeneratorHandler.draw_word_cloud(top_n)) ]), QuoteSource(GroupStrategy()))
async def ero_pic(app: GraiaMiraiApplication, group: Group, member: Member, tag): global ero_f, apikey g_setting = ero_setting.get_item(group.id) getup = datetime.fromisoformat(date.today().isoformat() + "T06:30") sleep = datetime.fromisoformat(date.today().isoformat() + "T23:00") lsp = lsps.get_item(group.id, member.id, date.today()) if not g_setting.get('status'): msg = '我们这个群是正经群,不搞这些玩意的' elif member.id in g_setting.get('black_list', []): msg = '黑名单人是没有涩图看的' elif not getup < datetime.now() < sleep and not g_setting.get('compel'): msg = '我要睡觉,不要打扰我' elif lsp.get('t', [0])[-1] >= time.time() - g_setting.get('group_frame', 0): msg = '你太快了,少*点' else: ero_from = g_setting.get('source', 'web') lsp.setdefault('num', 0) lsp.setdefault('t', []) lsp['num'] += 1 lsp['t'].append(time.time()) if ero_from == 'web': parmas = { 'apikey': apikey, 'r18': 0, 'proxy': 'disable', 'size1200': 'true' } if tag: parmas['keyword'] = tag.asDisplay() async with aiohttp.request("GET", url='https://api.lolicon.app/setu/', params=parmas) as r: pic_info = await r.json() if pic_info['code'] == 429: msg = '玛德你们这群lsp调用次数全™用完了' elif not pic_info['data']: msg = MessageChain.create([ At(target=member.id), Plain(text='没搜索到相关色图'), Plain(text=f"\n剩余调用次数:{pic_info['quota']}") ]) else: headers = { 'Referer': 'https://www.pixiv.net/member_illust.php?mode=medium&illust_id', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '\ '(KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36'} single_pic = pic_info['data'][0] async with aiohttp.request("GET", single_pic['url'], headers=headers) as r: setu = await r.read() msg = MessageChain.create([ At(target=member.id), Plain(text='\n您要的涩图'), Plain(text=f"\npid:{single_pic['pid']}"), Plain( text=f"\n{single_pic['title']}/{single_pic['author']}" ), Plain(text=f"\n剩余调用次数:{pic_info['quota']}"), Image.fromUnsafeBytes(setu) ]) elif ero_from == 'local': ero_pics = [Path('data/ero_pic').iterdir()] msg = MessageChain.create( [Image.fromLocalFile(random.choice(ero_pics))]) if msg is not None: await app.sendGroupMessage( group, msg if type(msg) is MessageChain else MessageChain.create( [Plain(msg)]))
async def setting_ero(app: GraiaMiraiApplication, group: Group, member: Member, tag): g_setting = ero_setting.get_item(group.id) if member.id not in ultra_admin: if member.permission not in power[g_setting.get('power', 'none')]: return std_output = StringIO() parser = MessageChainParser( prog='setu_setting', std=std_output, ) subparser = parser.add_subparsers(metavar='command', ) group_setting = subparser.add_parser('group', std=std_output) group_setting.add_argument('-g', '--group', type=int, default=group.id, help='需要执行的组(没有则自动选择所在组)') group_setting.add_argument('-p', '--power', action='store', choices={'none', 'administrator', 'owner'}, help='可操控权限') group_setting.add_argument('-s', '--source', action='store', choices={'web', 'local'}, help='选择涩图来源') status = group_setting.add_mutually_exclusive_group() status.add_argument('-on', action='store_true', help='在群启动涩图功能') status.add_argument('-off', action='store_true', help='在群关闭涩图功能') compel = group_setting.add_mutually_exclusive_group() compel.add_argument('-c', '--compel', action='store_true', help='启动加班模式') compel.add_argument('-r', '--rest', action='store_true', help='关闭加班模式') group_setting.set_defaults(command_type='group') member_setting = subparser.add_parser('member', std=std_output) member_setting.add_argument('-m', '--member', type=MsgString.decode()) member_setting.add_argument('-ab', '--add_black', type=MsgString.decode(), help='添加黑名单') member_setting.add_argument('-db', '--delate_black', type=MsgString.decode(), help='删除黑名单') member_setting.add_argument('-mt', '--member_frame', type=int, help='单人调用涩图间隔(单位s)') member_setting.set_defaults(command_type='member') try: args = parser.parse_args('' if tag is None else tag.asDisplay()) except ParserExit as e: ttf = ImageFont.truetype('src/font/SourceHanSans-Medium.otf', 60) word = std_output.getvalue() back = IMG.new("RGB", ttf.getsize_multiline(word), (0, 0, 0)) draw = ImageDraw.Draw(back) draw.multiline_text((0, 0), word, font=ttf) b = BytesIO() back.save(b, format='JPEG') await app.sendGroupMessage( group, MessageChain.create([ At(member.id), Plain(' ERROR:' if e.status else ' Help:'), Image.fromUnsafeBytes(b.getvalue()) ])) return if args.command_type == 'group': if member.id not in ultra_admin and args.group != group.id: await app.sendGroupMessage( group, MessageChain.create([Plain('你并没有修改其他群的权限')])) return setting_group = ero_setting.get_item(args.group) msg = [] if args.on: setting_group['status'] = True msg.append('涩图模式已启动') elif args.off: setting_group['status'] = False msg.append('涩图模式已关闭') if args.compel: setting_group['compel'] = True msg.append('加班模式已启动') elif args.rest: setting_group['compel'] = False msg.append('加班模式已关闭') if args.source: setting_group['source'] = args.source msg.append(f'涩图来源以更换为:{args.source}') if args.power: setting_group['power'] = args.power msg.append(f'涩图设置权限已更换为:{args.power}') if msg: await app.sendGroupMessage( group, MessageChain.create([Plain('\n'.join(msg))])) ero_setting.commit() if args.command_type == 'member': if member.id not in ultra_admin: await app.sendGroupMessage( group, MessageChain.create([Plain('你并没有这项权限')])) msg = [] g_setting.setdefault('black_list', []) if args.add_black: if ab.has(At): ab_list = [a.target for a in ab.get(At)] else: li = regex.split('[ ,,]', ab.asDisplay().strip()) ab_list = [int(li) for a in li if li.isdigit()] ab_list = [a for a in ab_list if a not in g_setting['black_list']] g_setting['black_list'].extend(ab_list) msg.append(f'已添加{len(ab_list)}人进黑名单') if args.delate_black: if ab.has(At): ab_list = [a.target for a in ab.get(At)] else: li = regex.split('[ ,,]', ab.asDisplay().strip()) ab_list = [int(li) for a in li if li.isdigit()] ab_list = [a for a in ab_list if a in g_setting['black_list']] for a in ab_list: g_setting['black_list'].remove(a) msg.append(f'已删除{len(ab_list)}人出黑名单') if args.member_frame is not None: setting_group['member_frame'] = args.member_frame msg.append(f'单人涩图频率已更换为:{args.member_frame}s') if msg: await app.sendGroupMessage( group, MessageChain.create([Plain('\n'.join(msg))]))
async def PicDeaHandler(self, app: Slave, message: GroupMessage): plains = message.messageChain.get(Plain) quote: Quote = message.messageChain.get(Quote)[0] plain: Plain = quote.origin.get(Plain)[0] if any(text.__dict__['text'].strip() == '好' for text in plains): if not self.Permitted(message): # await app.sendGroupMessage(message.sender.group, [At(message.sender.id), Plain('权限不足')]) pass else: if plain.text == '[图片]': if (message.sender.group.id << 32) + quote.id in self.GCache.keys(): cache = self.GCache[(message.sender.group.id << 32) + quote.id] image: Image = cache[0] ext = cache[1] pid = cache[2] img_type = cache[3] else: try: quote_source: GroupMessage = await app.messageFromId( quote.id) image: Image = quote_source.messageChain.get( Image)[0] ext = 'jpg' pid = image.imageId img_type = 'Other' except UnknownTarget: mec = MeCh.create([ At(message.sender.id), Plain('不在本地与消息缓存中,无法保存') ]) await app.sendGroupMessage(message.sender.group, mec) return name = f'{img_type}_{pid}' te = await saveUrlPicture( image.url, name, 'application/YummyPicture/save/pic', ext) msg = [At(message.sender.id), Plain(te)] await app.sendGroupMessage(message.sender.group, MeCh.create(msg)) elif any(text.__dict__['text'].strip() == '图源' for text in plains): if plain and plain.text in ['[图片]', '[动画表情]']: try: if (k := (message.sender.group.id << 32) + quote.id) in self.GCache.keys(): url = self.GCache[k][0].url else: quote_source: GroupMessage = await app.messageFromId( quote.id) image: Image = quote_source.messageChain.get(Image)[0] url = image.url searcher: Searcher = Searcher() result = await searcher.useApiKey().setUrl(url).get() msg = [] connector: ProxyConnector = ProxyConnector() if proxy := ymConfig.getConfig('setting').get('proxy'): connector = ProxyConnector.from_url(proxy) for one in result: if float(sim := one['header']['similarity']) < 50: continue img_byte = await request( url=one['header']['thumbnail'], connector=connector, close=False) img = Image.fromUnsafeBytes(img_byte) msg.append(img) if 'ext_urls' in one['data']: ext = one['data']['ext_urls'] else: ext = one['header']['thumbnail'] msg.append(Plain(f"相似度{sim}%,链接{ext}"))
async def groupCmdHandler(app: Slave, message: GroupMessage): await self.commandHandler(app, message) async def commandHandler(self, app: Slave, message: GroupMessage): commands: [str] = message.messageChain.asDisplay().split(' ') cmd = commands[0].upper() msg = [] if cmd == self.APP_COMMANDS[0]: info: dict = await EconomyAPI.Economy.money(message.sender.id) b = Plain(f"\n余额: {info['balance']}只{EconomyAPI.unit}") al = info['credit_pay_adjust'] + EconomyAPI.credit_pay['base_balance'] c = Plain(f"\n{EconomyAPI.unit}呗:\n 已用额度: {info['credit_pay_use']}\n 总额度: {al}") p = Plain(f"\n支付方式: {EconomyAPI.payments[info['payment']]}") m = Plain(f"\n.pm 切换支付方式") msg = [At(message.sender.id), b, c, p, m] if cmd == self.APP_COMMANDS[1]: try: if (payment := int(commands[1])) in [1, 3, 2, 4]: await EconomyAPI.Economy.payment(message.sender.id, payment) msg.append(Plain(f"切换到{EconomyAPI.payments[payment]}")) else: msg.append(Plain(f"\n{json.dumps(EconomyAPI.payments, ensure_ascii=False)}")) except (ValueError, IndexError): msg.append(Plain('.pm 1|2|3|4')) await app.sendGroupMessage(message.sender.group.id, MeCh.create(msg)) @staticmethod async def notEnough(app: Slave, message: GroupMessage, price: int): msg = [At(message.sender.id), Plain(f'\n余额不足:) [.mm]查看余额\n单价{price}只{EconomyAPI.unit}')] await app.sendGroupMessage(message.sender.group, MeCh.create(msg))
async def blhxpush(app, preTimestamp): await asyncio.sleep(10) url = "https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/space_history?visitor_uid=33091201&host_uid=233114659&offset_dynamic_id=0&need_top=1&platform=web" Information = requests.get(url, headers=headers).json() while (True): t = time.time() t = int(t) url = "https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/space_history?visitor_uid=33091201&host_uid=233114659&offset_dynamic_id=0&need_top=1&platform=web" Information = requests.get(url, headers=headers).json() try: timestamp = Information['data']['cards'][1]['desc']['timestamp'] except: timestamp = 0 print("当前时间戳为:") print(t) print("上一个动态的时间戳为:") print(preTimestamp) print("当前动态的时间戳为:") print(timestamp) if preTimestamp != timestamp: preTimestamp = timestamp judge = Information['data']['cards'][1] if judge['desc']['type'] == 1: needInformation = Information['data']['cards'][1]['card'] dictInformation = eval(needInformation) msg = dictInformation['item']['content'] for group in groups: message = MessageChain.create( [Plain("碧蓝航线b服动态更新\n================\n"), Plain(msg)]) await app.sendGroupMessage(group, message) elif judge['desc']['type'] == 2: needInformation = Information['data']['cards'][1]['card'] dictInformation = eval(needInformation) try: if (dictInformation['item']['pictures_count'] == 1): pictures = dictInformation['item']['pictures'][0][ 'img_src'] flag = 0 else: pictures = dictInformation['item']['pictures'] flag = 1 count = dictInformation['item']['pictures_count'] except: pictures = " " msgDict = { "information": dictInformation['item']['description'], "picture_url": pictures } for group in groups: if msgDict['picture_url'] != ' ': if flag == 0: msgDict['picture_url'] = eval( repr(msgDict['picture_url']).replace('\\', '')) await app.sendGroupMessage( group, MessageChain.create([ Plain("碧蓝航线b服动态更新\n================\n"), Plain(msgDict['information']), Image.fromNetworkAddress( msgDict['picture_url']) ])) elif flag == 1: message1 = MessageChain.create([ Plain("碧蓝航线b服动态更新\n================\n"), Plain(msgDict['information']) ]) for i in count: pictures[i]['img_src'] = eval( repr(pictures[i]['img_src']).replace( '\\', '')) msg = MessageChain.join([ Image.fromNetworkAddress( pictures[i]['img_src']) ]) Msg = MessageChain.join(message1, msg) await app.sendGroupMessage(group, Msg) else: await app.sendGroupMessage( group, MessageChain.create([ Plain("碧蓝航线b服动态更新\n================\n"), Plain(msgDict['information']) ])) elif judge['desc']['type'] == 4: needInformation = Information['data']['cards'][1]['card'] dictInformation = eval(needInformation) pictures = " " msgDict = { "information": dictInformation['item']['content'], "picture_url": pictures } for group in groups: if msgDict['picture_url'] != ' ': msgDict['picture_url'] = eval( repr(msgDict['picture_url']).replace('\\', '')) await app.sendGroupMessage( group, MessageChain.create([ Plain("碧蓝航线b服动态更新\n================\n"), Plain(msgDict['information']), Image.fromNetworkAddress( msgDict['picture_url']) ])) else: await app.sendGroupMessage( group, MessageChain.create([ Plain("碧蓝航线b服动态更新\n================\n"), Plain(msgDict['information']) ])) await asyncio.sleep(60) else: await asyncio.sleep(60) continue
async def notEnough(app: Slave, message: GroupMessage, price: int): msg = [At(message.sender.id), Plain(f'\n余额不足:) [.mm]查看余额\n单价{price}只{EconomyAPI.unit}')] await app.sendGroupMessage(message.sender.group, MeCh.create(msg))
async def dd_group_add(app: GraiaMiraiApplication, group: Group, member: Member, tag: MessageChain): name = tag.asDisplay().strip() dd_data = yaml.safe_load(data_path.read_text(encoding = 'UTF-8')) dd_data.append(name) data_path.write_text(yaml.safe_dump(dd_data), encoding = 'UTF-8') await app.sendGroupMessage(group, MessageChain.create([Plain(f'增加团队"{name}"成功')]))
async def ouen(app, txt: str, group): add = "msyh.ttc" img = Image.open('./source/4.png') # 控制表情的叠加位置 draw = ImageDraw.Draw(img) mask = img s_background = Image.new("RGBA", (650, 650), (255, 255, 255, 0)) # alpha通道设为0,保证透明度 s_draw = ImageDraw.Draw(s_background) size_max = int(320 / len(txt) * 2) + 1 size_min = int(320 / len(txt)) - 1 print(len(txt)) if len(txt) == 1: font = ImageFont.truetype(add, 180) text_size = draw.textsize(txt, font=font) print(text_size) if abs(text_size[0] - 180) < 30: x, y = 180, 30 else: x, y = 225, 30 elif len(txt) == 2: font = ImageFont.truetype(add, 140) text_size = draw.textsize(txt, font=font) print(text_size) if abs(text_size[0] - 280) < 20: x, y = 130, 50 elif abs(text_size[0] - 210) < 20: x, y = 165, 50 else: x, y = 200, 50 else: x = 110 for size in range(size_max, size_min, -1): font = ImageFont.truetype(add, size) text_size = draw.textsize(txt, font=font) print(text_size) if text_size[0] > 320: continue else: break s = text_size[1] y = -0.0009077705156136529 * \ (pow(s, 2))-0.25326797385620914*s+105.27777777777777 print(y) s_draw.text((x, y), txt, fill=(0, 0, 0), font=font) s_rotate = s_background.rotate(-5, expand=1) # 图像会转动随机的角度 mask.resize(s_rotate.size) out1 = Image.composite(s_rotate, mask, s_rotate) # 第一次复合生成的图片是旋转后去黑色背景图片 mask = out1 out1.show() out1.save("./source/bak.png") await app.sendGroupMessage( group, MessageChain.create([Img.fromLocalFile("./source/bak.png")]))
def detect_index(self, target_chain: MessageChain): target_chain = target_chain.asMerged() detect_result: Dict[str, List[Tuple[MessageIndex, MessageIndex]]] = { "_": [] # 相当于 *args. } chain_frames: List[MessageChain] = target_chain.split(self.delimiter, raw_string=True) # 前缀匹配 if len(self.prefixs) > len(chain_frames): return for index in range(len(self.prefixs)): current_prefix = self.prefixs[index] current_frame = chain_frames[index] if (not current_frame.__root__ or type(current_frame.__root__[0]) is not Plain): return if current_frame.__root__[0].text != current_prefix: return chain_frames = chain_frames[len(self.prefixs):] # 清除无关数据, 开始执行. collections: List[Element] = detect_result["_"] detecting_param = None local_iter = MultiUsageGenerator(enumerate(chain_frames)) # print(list(local_iter)) for iter_item in local_iter: print(92, iter_item) index, current_frame = iter_item current_frame: MessageChain if not current_frame.__root__: collections.append(current_frame) continue if detecting_param and isinstance( self.param_settings[detecting_param], BoxParameter): detect_result[detecting_param] = current_frame detecting_param = None continue splited = current_frame.split("=", raw_string=True) origin_data = self.param_settings_index.get(splited[0].asDisplay()) if not origin_data: if not detecting_param: if current_frame.startswith( '"'): # TODO: 我现在还需要一个更加合理的引号出现判断. # debug("ocur", index, chain_frames, current_frame) afters_root = MessageChain.create( sum( [[*i.__root__, Plain(self.delimiter)] for i in chain_frames[max(0, index - 1):]], [], )[:-1]).asMerged() print("aftersRoot", index, afters_root) break_flag_root = False param_content_root = [] for elem in afters_root.subchain( slice((0, 1), None, None), ignore_text_index=True): print(elem) if break_flag_root: break_flag_root = False break if isinstance(elem, Plain): continue_flag = False for text_index, text_i in enumerate(elem.text): if continue_flag: continue_flag = False continue if text_i == "\\": continue_flag = True if text_i == '"': param_content_root.append( Plain(elem.text[:text_index])) break_flag_root = True break else: # 没找到 param_content_root.append(elem) break else: param_content_root.append(elem) break else: if not break_flag_root: raise ValueError("no closing quotes") param_content_chain_root = MessageChain.create( param_content_root) local_iter.continue_count += len( param_content_chain_root.split(self.delimiter, raw_string=True)) collections.append(param_content_chain_root) else: collections.append(current_frame) continue param_name, setting = origin_data detecting_param = param_name if param_name in detect_result: continue # 用户重复输入了参数 if isinstance(setting, SwitchParameter): # 这里是已经被 catch 到了. if setting.auto_reverse: detect_result[param_name] = not setting.default else: detect_result[param_name] = True elif isinstance(setting, BoxParameter): afters = MessageChain.create( sum( ([i.__root__ for i in splited[1:]] + [[Plain(self.delimiter)]] if len(splited) > 1 else []) + [[*i.__root__, Plain(self.delimiter)] for i in chain_frames[index + 1:]], [], )[:-1]).asMerged() break_flag = False if afters.startswith('"'): param_content = [] for elem in afters.subchain(slice((0, 1), None, None), ignore_text_index=True): if break_flag: break_flag = False break if isinstance(elem, Plain): continue_flag = False for text_index, text_i in enumerate(elem.text): if continue_flag: continue_flag = False continue if text_i == "\\": continue_flag = True if text_i == '"': param_content.append( Plain(elem.text[:text_index])) break_flag = True break else: # 没找到 param_content.append(elem) else: param_content.append(elem) else: if not break_flag: raise ValueError("no closing quotes") param_content_chain = MessageChain.create(param_content) print( param_content, chain_frames[len( param_content_chain. split(self.delimiter, raw_string=True)) + 1:], ) local_iter.continue_count += (len( param_content_chain.split(self.delimiter, raw_string=True)) - 1) detect_result[param_name] = [ MessageChain.create(param_content) ] else: detecting_param = param_name if len(splited) > 1 and not break_flag: local_iter.insert_items.extend([ (index + l_index, value) for l_index, value in enumerate(splited[1:], 1) ]) detecting_param = None else: if detecting_param and detecting_param not in detect_result: if self.param_settings[detecting_param].default is None: raise ValueError("require for " + detecting_param) # 后处理 for k, v in self.param_settings.items(): if isinstance(v, SwitchParameter) and k not in detect_result: detect_result[k] = v.default elif isinstance(v, BoxParameter) and k not in detect_result: detect_result[k] = Force(None) return detect_result
async def messagechain_to_img( message: MessageChain, max_width: int = 1080, font_size: int = 40, spacing: int = 15, padding_x: int = 20, padding_y: int = 15, img_fixed: bool = False, font_path: str = f"{os.getcwd()}/statics/fonts/STKAITI.TTF", ) -> MessageChain: """ 将 MessageChain 转换为图片,仅支持只含有本地图片/文本的 MessageChain Args: message: 要转换的MessageChain max_width: 最大长度 font_size: 字体尺寸 spacing: 行间距 padding_x: x轴距离边框大小 padding_y: y轴距离边框大小 img_fixed: 图片是否适应大小(仅适用于图片小于最大长度时) font_path: 字体文件路径 Examples: msg = await messagechain_to_img(message=message) Returns: MessageChain (内含图片Image类) """ def get_final_text_lines(text: str, text_width: int, font: ImageFont.FreeTypeFont) -> int: lines = text.split("\n") line_count = 0 for line in lines: if not line: line_count += 1 continue line_count += int(math.ceil(float(font.getsize(line)[0]) / float(text_width))) return line_count + 1 font = ImageFont.truetype(font_path, font_size, encoding="utf-8") message = message.asMerged() elements = message.__root__ plains = message.get(Plain) text_gather = "\n".join([plain.text for plain in plains]) # print(max(font.getsize(text)[0] for text in text_gather.split("\n")) + 2 * padding_x) final_width = min(max(font.getsize(text)[0] for text in text_gather.split("\n")) + 2 * padding_x, max_width) text_width = final_width - 2 * padding_x text_height = (font_size + spacing) * get_final_text_lines(text_gather, text_width, font) img_height_sum = 0 temp_img_list = [] images = [element for element in message.__root__ if (isinstance(element, Image_LocalFile) or isinstance(element, Image_UnsafeBytes))] for image in images: if isinstance(image, Image_LocalFile): temp_img = IMG.open(image.filepath) elif isinstance(image, Image_UnsafeBytes): temp_img = IMG.open(BytesIO(image.image_bytes)) else: raise ValueError("messagechain_to_img:仅支持Image_LocalFile和Image_UnsafeBytes类的处理!") img_width, img_height = temp_img.size temp_img_list.append( temp_img := temp_img.resize(( int(final_width - 2 * spacing), int(float(img_height * (final_width - 2 * spacing)) / float(img_width)) )) if img_width > final_width - 2 * spacing or (img_fixed and img_width < final_width - 2 * spacing) else temp_img ) img_height_sum = img_height_sum + temp_img.size[1] final_height = 2 * padding_y + text_height + img_height_sum picture = IMG.new('RGB', (final_width, final_height), (255, 255, 255)) draw = ImageDraw.Draw(picture) present_x = padding_x present_y = padding_y image_index = 0 for element in elements: if isinstance(element, Image) or isinstance(element, Image_UnsafeBytes) or isinstance(element, Image_LocalFile): picture.paste(temp_img_list[image_index], (present_x, present_y)) present_y += (spacing + temp_img_list[image_index].size[1]) image_index += 1 elif isinstance(element, Plain): for char in element.text: if char == "\n": present_y += (font_size + spacing) present_x = padding_x continue if char == "\r": continue if present_x + font.getsize(char)[0] > text_width: present_y += (font_size + spacing) present_x = padding_x draw.text((present_x, present_y), char, font=font, fill=(0, 0, 0)) present_x += font.getsize(char)[0] present_y += (font_size + spacing) present_x = padding_x bytes_io = BytesIO() picture.save(bytes_io, format='PNG') logger.success("消息转图片处理成功!") return MessageChain.create([ Image.fromUnsafeBytes(bytes_io.getvalue()) ])
async def GetHelp(app: GraiaMiraiApplication, group: Group, mesg: MessageChain): msg = getAt(mesg)[1] if msg == '帮助': await app.sendGroupMessage(group, MessageChain.create([ Plain(text='帮助参见:https://github.com/CoTecho/Cobot/blob/master/README.md')])) pass
async def friend_message_listener(app: GraiaMiraiApplication, friend: Friend): await app.sendFriendMessage(friend, MessageChain.create([Plain("好好吃饭啦,夸夸!")]))
async def GoodNight(app: GraiaMiraiApplication, group: Group, mesg: MessageChain): msg = getAt(mesg)[1] if msg == '晚安': await app.sendGroupMessage(group, MessageChain.create([ Plain(text='晚安')])) pass
url=one['header']['thumbnail'], connector=connector, close=False) img = Image.fromUnsafeBytes(img_byte) msg.append(img) if 'ext_urls' in one['data']: ext = one['data']['ext_urls'] else: ext = one['header']['thumbnail'] msg.append(Plain(f"相似度{sim}%,链接{ext}")) if connector: await connector.close() if len(msg) == 0: msg.append(Plain('未搜索到')) await app.sendGroupMessage(message.sender.group, MeCh.create(msg)) except ClientConnectorError: msg = [At(message.sender.id), Plain('爬,老子不开心了')] await app.sendGroupMessage(message.sender.group, MeCh.create(msg)) except UnknownTarget: msg = [ At(message.sender.id), Plain('不在本地与消息缓存中,无法搜索,请重发图片') ] await app.sendGroupMessage(message.sender.group, MeCh.create(msg)) elif any(text.__dict__['text'].strip().lower() == 'x2' for text in plains): if not self.Permitted(message): # await app.sendGroupMessage(message.sender.group, [At(message.sender.id), Plain('权限不足')])
if cmd == '啊?': await self.sendPhilosophy(app, message) if '不' in cmd and len(cmd) > 2: if (pos := cmd.find('不')) != -1: if cmd[pos - 1] == cmd[pos + 1]: msg = [Plain(cmd[pos - 1] if random.randint(0, 1) else f'不{cmd[pos - 1]}')] await app.sendGroupMessage(message.sender.group, MeCh.create(msg)) if cmd == '吃什么': rate = random.randint(0, 100) if rate < 2: eat = '吃屎吧' else: what_we_eat = ttkConfig.getConfig('setting').get('what_we_eat') index = random.randint(0, len(what_we_eat) - 1) eat = f'吃{what_we_eat[index]}' await app.sendGroupMessage(message.sender.group, MeCh.create([Plain(eat)])) async def atOrQuoteHandler(self, app, message: GroupMessage): logger.debug('TalkToMe at handler act') cmd: str = message.messageChain.asDisplay().split(' ')[0] if cmd == '骂他': if self.Economy: if not await self.Economy.Economy.pay(message.sender.id, self.Economy.capitalist, 500): info: dict = await self.Economy.Economy.money(message.sender.id) plain: Plain = Plain( f"你的{self.Economy.unit}不足,你还剩{info['balance']}只{self.Economy.unit},单价500只{self.Economy.unit}") await app.sendGroupMessage(message.sender.group, MeCh.create([plain])) return else: if message.sender.permission == MemberPerm.Member: await app.sendGroupMessage(message.sender.group, MeCh.create([Plain('你骂你爹呢')]))
async def RipperHandler(self, app: Slave, message: GroupMessage, commands: list): commands[0] = commands[0].upper() if './' in commands[0]: args = formatParm(commands) if not args: # await app.sendGroupMessage(message.sender.group, [At(message.sender.id), Plain('格式错误')]) return if self.Economy: count: int = args['count'] if not await self.Economy.Economy.pay( message.sender.id, self.Economy.capitalist, count * 5): await self.notEnough(app, message, 5) return ripper = self.ripperClass() print(ripper) gid = message.sender.group.id self.getRating(self.ym, gid) if args['key'] == 'n': ripper.new() if args['key'] == 'p': ripper.popular().period(args['period']) if args['key'] == 's': ripper.search().tags(args['tags']) if args['key'] == 'r': ripper.random().tags(args['tags']) if args['key'] == 'd': ripper.detail().specific([args['tags'], self.db]) if args['key'] == 'j': ja: JASearcher = JASearcher() ja.useProxy().setID(args['id']) result: dict = await ja.get(args['offset'], args['limit']) msg = [] for re in result: if 'image' in re.keys(): msg.append(Image.fromUnsafeBytes(re['image'])) if 'text' in re.keys(): msg.append(Plain(re['text'])) if not msg: await app.sendGroupMessage(message.sender.group, MeCh.create([Plain('未搜索到')])) return await app.sendGroupMessage(message.sender.group, MeCh.create(msg)) return tasks: List[asyncio.Task] = [] try: result = await ripper.offset(args['offset']).count( args['count']).rating(self.ratings[gid]).get() except ClientConnectorError: msg = [At(message.sender.id), Plain('不给发,爬')] await app.sendGroupMessage(message.sender.group, MeCh.create(msg)) return number = len(result) if not number: msg = [At(message.sender.id), Plain('未搜索到')] await app.sendGroupMessage(message.sender.group, MeCh.create(msg)) return for i, yande in enumerate(result): prefix = f'[{i + 1}/{number}]' if number > 1 else '' task = asyncio.create_task( self.send(app, [yande], message.sender.group, prefix)) if hasattr(yande, 'id'): await self.db.addYummy(yande) tasks.append(task) await asyncio.wait([task], timeout=5) done, pending = await asyncio.wait(tasks, timeout=120) exceptions = [ task.exception() for task in done if task.exception() ] timeouts = [t.cancel() for t in pending] es = len(exceptions) ts = len(timeouts) if es or ts: t_message = f'{ts}个任务超时' if ts else '' e_message = f'{es}个任务异常' if es else '' await app.sendGroupMessage( message.sender.group, MeCh.create([Plain(e_message + t_message)])) logger.warning(f'exceptions{exceptions} timeouts{timeouts}')
async def search_image(img: Image) -> MessageChain: path = "./modules/PixivImageSearcher/tempSavedImage.png" thumbnail_path = "./modules/PixivImageSearcher/tempThumbnail.png" async with aiohttp.ClientSession() as session: async with session.get(url=img.url) as resp: img_content = await resp.read() image = IMG.open(BytesIO(img_content)) image.save(path) # url for headers url = "https://saucenao.com/search.php" # picture url pic_url = img.url # json requesting url url2 = f"https://saucenao.com/search.php?db=999&output_type=2&testmode=1&numres=1&url={pic_url}" # data for posting. payload = { "url": pic_url, "numres": 1, "testmode": 1, "db": 999, "output_type": 2, } # header to fool the website. headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36", "Sec-Fetch-Dest": "document", "Sec-Fetch-Mode": "navigate", "Sec-Fetch-Site": "none", "Sec-Fetch-User": "******", "Referer": url, "Origin": "https://saucenao.com", "Host": "saucenao.com", "cookie": saucenao_cookie } async with aiohttp.ClientSession() as session: async with session.post(url=url, headers=headers, data=payload) as resp: json_data = await resp.json() if json_data["header"]["status"] == -1: return MessageChain.create( [Plain(text=f"错误:{json_data['header']['message']}")]) print(json_data) if not json_data["results"]: return MessageChain.create([Plain(text="没有搜索到结果呐~")]) result = json_data["results"][0] header = result["header"] data = result["data"] async with aiohttp.ClientSession() as session: async with session.get(url=header["thumbnail"]) as resp: img_content = await resp.read() image = IMG.open(BytesIO(img_content)) image.save(thumbnail_path) similarity = header["similarity"] data_str = f"搜索到如下结果:\n\n相似度:{similarity}%\n" for key in data.keys(): if isinstance(data[key], list): data_str += (f"\n{key}:\n " + "\n".join(data[key]) + "\n") else: data_str += f"\n{key}:\n {data[key]}\n" return MessageChain.create( [Image.fromLocalFile(thumbnail_path), Plain(text=f"\n{data_str}")])
# 计算终点坐标. text_index = None latest_element = message_chain.__root__[-1] if isinstance(latest_element, Plain): text_index = len(latest_element.text) stop_index = (len(message_chain.__root__), text_index) match_result[matching_recevier] = (start_index, stop_index) return match_result if __name__ == "__main__": from graia.ptilopsis.signature import Require from graia.ptilopsis.utilles import silce_chain_stop from devtools import debug from graia.application.entry import At # 这里是测试代码 test_message_chain = MessageChain.create([ Plain("test_matchre_test_argumentafterafter23123312323123231232323"), At(123) ]) test_signature_chain = ( FullMatch("test_match"), Require(name="require_1", isGreed=True), (FullMatch("after"), Require(name="require_2")) ) test_station = Station(test_signature_chain) match_result = test_station.match(test_message_chain) debug(match_result) debug({k: silce_chain_stop(silce_chain_start(test_message_chain, v[0]), v[1]) for k, v in match_result.items()})