async def rub(operator_image: Union[int, str], target_image: Union[int, str]) -> MessageItem: user_locs = [(39, 91, 75, 75, 0), (49, 101, 75, 75, 0), (67, 98, 75, 75, 0), (55, 86, 75, 75, 0), (61, 109, 75, 75, 0), (65, 101, 75, 75, 0)] self_locs = [(102, 95, 70, 80, 0), (108, 60, 50, 100, 0), (97, 18, 65, 95, 0), (65, 5, 75, 75, -20), (95, 57, 100, 55, -70), (109, 107, 65, 75, 0)] frames = [] self_img = await AvatarFunPicHandler.get_pil_avatar(operator_image) user_img = await AvatarFunPicHandler.get_pil_avatar(target_image) for i in range(6): frame = IMG.open(f'{os.getcwd()}/statics/RubFrames/frame{i}.png' ).convert('RGBA') x, y, w, h, angle = user_locs[i] user_img_new = (await AvatarFunPicHandler.resize_img( user_img, w, h, angle)).convert("RGBA") frame.paste(user_img_new, (x, y), mask=user_img_new) x, y, w, h, angle = self_locs[i] self_img_new = (await AvatarFunPicHandler.resize_img( self_img, w, h, angle)).convert("RGBA") frame.paste(self_img_new, (x, y), mask=self_img_new) frames.append(frame) output = BytesIO() imageio.mimsave(output, frames, format='gif', duration=0.05) return MessageItem( MessageChain.create([Image.fromUnsafeBytes(output.getvalue())]), Normal(GroupStrategy()))
async def generate_messagechain(info: dict) -> MessageChain: data = info["data"] chain_list = [] chain_list.append(Plain(text=f"【标题】{data['title']}\n")) img_url = data['pic'] async with aiohttp.ClientSession() as session: async with session.get(url=img_url) as resp: img_content = await resp.read() chain_list.append(Image.fromUnsafeBytes(img_content)) chain_list.append(Plain(text=f"\n【分区】{bilibili_partition_dict[str(data['tid'])]['name']}->{data['tname']}\n")) chain_list.append(Plain(text=f"【视频类型】{'原创' if data['copyright'] == 1 else '转载'}\n")) chain_list.append(Plain(text=f"【投稿时间】{time.strftime('%Y-%m-%d', time.localtime(int(data['pubdate'])))}\n")) chain_list.append(Plain(text=f"【视频长度】{sec_format(data['duration'])}\n")) chain_list.append(Plain(text=f"【UP主】\n 【名字】{data['owner']['name']}\n 【UID】:{data['owner']['mid']}\n")) if "staff" in data: char = "\n" chain_list.append(Plain(text=f"""【合作成员】\n{char.join([f"【{staff['title']}】{staff['name']}" for staff in data['staff']])}\n""")) chain_list.append(Plain(text="【视频数据】\n")) chain_list.append(Plain(text=f" 【播放量】{data['stat']['view']}\n")) chain_list.append(Plain(text=f" 【弹幕量】{data['stat']['danmaku']}\n")) chain_list.append(Plain(text=f" 【评论量】{data['stat']['reply']}\n")) chain_list.append(Plain(text=f" 【点赞量】{data['stat']['like']}\n")) chain_list.append(Plain(text=f" 【投币量】{data['stat']['coin']}\n")) chain_list.append(Plain(text=f" 【收藏量】{data['stat']['favorite']}\n")) chain_list.append(Plain(text=f" 【转发量】{data['stat']['share']}\n")) chara, charb = "\\n", "\n" chain_list.append(Plain(text=f"【简介】{data['desc'].replace(chara, charb)}\n")) chain_list.append(Plain(text=f"【AV】av{data['aid']}\n")) chain_list.append(Plain(text=f"【BV】{data['bvid']}\n")) chain_list.append(Plain(text=f"【链接】https://www.bilibili.com/video/av{data['aid']}")) return MessageChain.create(chain_list)
async def get_message(group: Group, member: Member, display_img: IMG, hide_img: IMG): return MessageItem( MessageChain.create([ Image.fromUnsafeBytes(await PhantomTankHandler.make_tank( display_img, hide_img)) ]), QuoteSource(GroupStrategy()))
async def send(self, app: Slave, yummy: [], group: Group, prefix: str): try: yande: PictureRipperListener.dataClass = yummy[0] img_byte: bytes = await yande.get() msg = [Image.fromUnsafeBytes(img_byte)] if self.ym == "ehentai" and hasattr(yande, 'gid'): msg.append(Plain(f'{yande.gid}/{yande.token}')) with enter_message_send_context(UploadMethods.Group): msg_chain = await MeCh.create(msg).build() image: Image = msg_chain.__root__[0] bot_message = await app.sendGroupMessage( group, msg_chain) # At(sender.id), Plain(prefix_ + data_.purl), if len(self.GCache) >= 150: self.GCache.pop(list(self.GCache.keys())[0]) logger.info('Cache is full,pop first one') ext = yande.url.split('.')[-1] self.GCache[(group.id << 32) + bot_message.messageId] = [ image, ext, yande.id, yande.__class__.__name__ ] logger.info(f"{prefix}sent,tags:{yande.tags}") await self.reCallYms(app, bot_message.messageId, 60) except asyncio.TimeoutError as e: logger.exception("[YummyPictures]: " + 'Timeout' + str(e)) raise e except ValueError as e: logger.exception("[YummyPictures]: " + 'Size check failed' + str(e)) raise e
async def xiaolaodi(app: GraiaMiraiApplication, group: Group, message: MessageChain, member: Member): if '小老弟' in message.asDisplay() and message.has(At): xiaolaodi = IMG.open(Path(__file__).parent/'小老弟.png') if (at_u := message.get(At)[0].target) == app.connect_info.account: text = '我哪里像小老弟了,小老弟' to = member.id user = at_u else: text = '' to = at_u user = member.id user_pic = f'http://q1.qlogo.cn/g?b=qq&nk={user}&s=640' to_pic = f'http://q1.qlogo.cn/g?b=qq&nk={to}&s=640' async with aiohttp.request("GET",user_pic) as r: user_pic = await r.read() user_pic = IMG.open(BytesIO(user_pic)) async with aiohttp.request("GET",to_pic) as r: to_pic = await r.read() to_pic = IMG.open(BytesIO(to_pic)) user_box = (18,9,87,78) to_box = (173,23,232,82) user_pic = user_pic.resize((user_box[2] - user_box[0], user_box[3] - user_box[1])) to_pic = to_pic.resize((to_box[2] - to_box[0], to_box[3] - to_box[1])) xiaolaodi.paste(user_pic,user_box) xiaolaodi.paste(to_pic,to_box) out = BytesIO() xiaolaodi.save(out, format='PNG') await app.sendGroupMessage(group, MessageChain.create([ Plain(text = text), Image.fromUnsafeBytes(out.getvalue())]))
async def keyword_reply( app: GraiaMiraiApplication, message: MessageChain, group: Group ): message_serialization = message.asSerializationString() message_serialization = message_serialization.replace( "[mirai:source:" + re.findall(r'\[mirai:source:(.*?)]', message_serialization, re.S)[0] + "]", "" ) if re.match(r"\[mirai:image:{.*}\..*]", message_serialization): message_serialization = re.findall(r"\[mirai:image:{(.*?)}\..*]", message_serialization, re.S)[0] sql = f"SELECT * FROM keywordReply WHERE keyword='{message_serialization}'" if result := await execute_sql(sql): replies = [] for i in range(len(result)): content_type = result[i][1] content = result[i][2] replies.append([content_type, content]) # print(replies) final_reply = random.choice(replies) content_type = final_reply[0] content = final_reply[1] try: if content_type == "img": await app.sendGroupMessage(group, MessageChain.create([Image.fromUnsafeBytes(base64.b64decode(content))])) elif content_type == "text": await app.sendGroupMessage(group, MessageChain.create([Plain(text=content)])) else: await app.sendGroupMessage(group, MessageChain.create([Plain(text=f"unknown content_type:{content_type}")])) except AccountMuted: pass
async def subscriptionCheckTask(self, app: Slave): while True: new_videos: list = await self.ripper.checkSubscriptionsUpdate() if new_videos: q2v = vrConfig.getConfig(self.ripper.ripper).get('quote2video') for video in new_videos: user_id = video[0] video_link = video[1] video_info = await self.ripper.getVideo(video_link) author = Plain(video_info['author'] + '\n') time = Plain(video_info['time']) public = '' if video_info['public'] else '隐藏' ty = Plain('提交' + public + ('视频' if video_info['video'] else '图片') + '\n') title = Plain(video_info['title'] + '\n') connector = await IwaraRipper.getConnector() img_byte = await request(url=video_info['thumbnail'], connector=connector) thumbnail = Image.fromUnsafeBytes(img_byte) info = Plain(f"\n{video_info['info']}\n" if video_info['info'] else '') link = Plain(self.ripper.host + video_info['url']) youtube = Plain('\nyoutube' if video_info['youtube'] else '') msg = [author, time, ty, title, thumbnail, info, link, youtube] qq = vrConfig.getConfig(self.ripper.ripper).get('qq') bot_msg = await app.sendFriendMessage(qq, MeCh.create(msg)) q2v[bot_msg.messageId] = [user_id, video_link] await vrConfig.save(self.ripper.ripper) else: logger.debug('nothing was post') await asyncio.sleep(30 * 60)
async def COVID(app: GraiaMiraiApplication, group: Group): back = await get_COVID_19() await app.sendGroupMessage( group, MessageChain.create([ Plain("新型冠状病毒前10:\n" + "\n".join(back[0])), Image.fromUnsafeBytes(back[1]) ]))
async def ghost_tank(app: GraiaMiraiApplication, group: Group, member: Member, para: MessageChain): if len(p := messages.get(Image)) == 2: pics = asyncio.gather(*[i.http_to_bytes() for i in p]) b = bytesIO() gray_car(*pics).save(b, format='PNG') await app.sendGroupMessage( group, MessageChain.create([Image.fromUnsafeBytes(b.getvalue())]))
async def handle(app: GraiaMiraiApplication, message: MessageChain, group: Group, member: Member): if re.match(r"qrcode .+", message.asDisplay()): await update_user_call_count_plus1(group, member, UserCalledCount.functions, "functions") content = message.asDisplay()[7:] qrcode_img = qrcode.make(content) bytes_io = BytesIO() qrcode_img.save(bytes_io) return MessageItem(MessageChain.create([Image.fromUnsafeBytes(bytes_io.getvalue())]), QuoteSource(GroupStrategy())) else: return None
async def group_message_listener(app: GraiaMiraiApplication, group: Group, message: MessageChain, member: Member): if message.asDisplay() == "单抽": times = user.get_times(member.id) rarity, char = await gacha(times=times) await user.change(member.id, member.name, rarity, char) await app.sendGroupMessage( group, MessageChain.create([ Image.fromLocalFile("chars/{}/{}".format(rarity, char)), Plain( text="{}: {}".format(rarity_text_dict[rarity], char[:-4])) ])) elif message.asDisplay() == "十连": rarity_list, char_list = [], [] for i in range(10): times = user.get_times(member.id) rarity, char = await gacha(times=times) await user.change(member.id, member.name, rarity, char) rarity_list.append(rarity) char_list.append(char) result_file, result_str = await ten_img_make(rarity_list, char_list) await app.sendGroupMessage( group, MessageChain.create( [Image.fromUnsafeBytes(result_file), Plain(text=result_str)])) if "浊心斯卡蒂.png" in char_list: await app.sendGroupMessage( group, MessageChain.create( [Voice_LocalFile(filepath="浊心斯卡蒂_干员报到.amr")])) await app.sendGroupMessage( group, MessageChain.create([ Plain( text= "我在等你,博士。我等你太久,太久了,我甚至已经忘了为什么要在这里等你......不过这些都不重要了。不再那么重要了。" ) ])) elif message.asDisplay().startswith("查询"): await app.sendGroupMessage( group, MessageChain.create( [Plain(text=user.query(member.id, member.name))])) elif message.asDisplay() == "清除": user.delete(member.id) await app.sendGroupMessage( group, MessageChain.create([ Plain( text="号码: {}\n昵称: {}\n清除完成".format(member.id, member.name)) ]))
async def gosencho_en_hoshi_style_image_generator(group: Group, member: Member, message: MessageChain) -> MessageItem: try: _, left_text, right_text = message.asDisplay().split(" ") try: img_byte = BytesIO() GoSenChoEnHoShiStyleUtils.genImage(word_a=left_text, word_b=right_text).save(img_byte, format='PNG') return MessageItem(MessageChain.create([Image.fromUnsafeBytes(img_byte.getvalue())]), Normal(GroupStrategy())) except TypeError: return MessageItem(MessageChain.create([Plain(text="不支持的内容!不要给我一些稀奇古怪的东西!")]), Normal(GroupStrategy())) except ValueError: return MessageItem(MessageChain.create([Plain(text="参数非法!使用格式:5000兆 text1 text2")]), Normal(GroupStrategy()))
async def get_steam_game_search(group: Group, member: Member, keyword: str) -> MessageItem: url = "https://steamstats.cn/api/steam/search?q=%s&page=1&format=json&lang=zh-hans" % keyword headers = { "accept": "application/json, text/plain, */*", "accept-encoding": "gzip, deflate, br", "accept-language": "zh-CN,zh;q=0.9,zh-TW;q=0.8,en-US;q=0.7,en;q=0.6", "pragma": "no-cache", "referer": "https://steamstats.cn/", "sec-fetch-dest": "empty", "sec-fetch-mode": "cors", "sec-fetch-site": "same-origin", "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36" } async with aiohttp.ClientSession() as session: async with session.get(url=url, headers=headers) as resp: result = await resp.json() if len(result["data"]["results"]) == 0: return MessageItem( MessageChain.create([ Plain(text=f"搜索不到{keyword}呢~检查下有没有吧~偷偷告诉你,搜英文名的效果可能会更好哟~") ]), QuoteSource(GroupStrategy())) else: result = result["data"]["results"][0] async with aiohttp.ClientSession() as session: async with session.get(url=result["avatar"]) as resp: img_content = await resp.read() description = await SteamGameInfoSearchHandler.get_steam_game_description( result["app_id"]) return MessageItem( MessageChain.create([ Plain(text="\n搜索到以下信息:\n"), Plain(text="游戏:%s (%s)\n" % (result["name"], result["name_cn"])), Plain(text="游戏id:%s\n" % result["app_id"]), Image.fromUnsafeBytes(img_content), Plain(text="游戏描述:%s\n" % description), Plain( text="\nSteamUrl:https://store.steampowered.com/app/%s/" % result["app_id"]) ]), QuoteSource(GroupStrategy()))
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] else: try: quote_source: GroupMessage = await app.messageFromId(quote.id) image: Image = quote_source.messageChain.get(Image)[0] ext = 'jpg' except UnknownTarget: mec = MeCh.create([At(message.sender.id), Plain('不在本地与消息缓存中,无法保存')]) await app.sendGroupMessage(message.sender.group, mec) return te = await saveUrlPicture(image.url, image.imageId, '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 keyword_detect(keyword: str): if re.match(r"\[mirai:image:{.*}\..*]", keyword): keyword = re.findall(r"\[mirai:image:{(.*?)}\..*]", keyword, re.S)[0] if result := list(await orm.fetchall( select(KeywordReply.reply, KeywordReply.reply_type).where( KeywordReply.keyword == keyword))): reply, reply_type = random.choice(result) return MessageItem( MessageChain.create([ Plain(text=reply) if reply_type == "text" else Image.fromUnsafeBytes(base64.b64decode(reply)) ]), Normal(GroupStrategy()))
async def support(image: Union[int, str]) -> MessageItem: avatar = await AvatarFunPicHandler.get_pil_avatar(image) support = IMG.open(f'{os.getcwd()}/statics/support.png') frame = IMG.new('RGBA', (1293, 1164), (255, 255, 255, 0)) avatar = avatar.resize((815, 815), IMG.ANTIALIAS).rotate(23, expand=True) frame.paste(avatar, (-172, -17)) frame.paste(support, mask=support) frame = frame.convert('RGB') output = BytesIO() frame.save(output, format='jpeg') return MessageItem( MessageChain.create([Image.fromUnsafeBytes(output.getvalue())]), Normal(GroupStrategy()))
async def get_bangumi_info(group: Group, member: Member, keyword: str) -> MessageItem: headers = { "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36" } url = "https://api.bgm.tv/search/subject/%s?type=2&responseGroup=Large&max_results=1" % parse.quote( keyword) async with aiohttp.ClientSession() as session: async with session.post(url=url, headers=headers) as resp: data = await resp.json() if "code" in data.keys() and data["code"] == 404 or not data["list"]: return MessageItem( MessageChain.create([Plain(text=f"番剧 {keyword} 未搜索到结果!")]), QuoteSource(GroupStrategy())) bangumi_id = data["list"][0]["id"] url = "https://api.bgm.tv/subject/%s?responseGroup=medium" % bangumi_id async with aiohttp.ClientSession() as session: async with session.post(url=url, headers=headers) as resp: data = await resp.json() name = data["name"] cn_name = data["name_cn"] summary = data["summary"] img_url = data["images"]["large"] score = data["rating"]["score"] rank = data["rank"] if "rank" in data.keys() else None rating_total = data["rating"]["total"] async with aiohttp.ClientSession() as session: async with session.get(url=img_url) as resp: img_content = await resp.read() message = MessageChain.create([ Plain(text="查询到以下信息:\n"), Image.fromUnsafeBytes(img_content), Plain(text=f"名字:{name}\n\n中文名字:{cn_name}\n\n"), Plain(text=f"简介:{summary}\n\n"), Plain(text=f"bangumi评分:{score}(参与评分{rating_total}人)"), Plain(text=f"\n\nbangumi排名:{rank}" if rank else "") ]) # print(message) return MessageItem( await MessageChainUtils.messagechain_to_img(message=message, max_width=1080, img_fixed=True), QuoteSource(GroupStrategy()))
async def petpet(image: Union[int, str], flip=False, squish=0, fps=20) -> MessageItem: """生成PetPet 将输入的头像生成为所需的 PetPet 并输出 参数 path: str 为头像路径 flip: bool 为是否横向反转头像 squish: float 为一个 [0, 1] 之间的数,为挤压量 fps: int 为输出 gif 每秒显示的帧数 返回 bool 但是会输出一个符合参数的 gif """ gif_frames = [] avatar = await AvatarFunPicHandler.get_pil_avatar(image) # 生成每一帧 for i in range(5): gif_frames.append(await AvatarFunPicHandler.make_frame(avatar, i, squish=squish, flip=flip)) if not os.path.exists(f"{os.getcwd()}/statics/temp/"): os.mkdir(f"{os.getcwd()}/statics/temp/") md5 = hashlib.md5(str(image).encode("utf-8")).hexdigest() await AvatarFunPicHandler.save_gif( gif_frames, f"{os.getcwd()}/statics/temp/tempPetPet-{md5}.gif", fps=fps) with open(f"{os.getcwd()}/statics/temp/tempPetPet-{md5}.gif", "rb") as r: image_bytes = r.read() os.remove(f"{os.getcwd()}/statics/temp/tempPetPet-{md5}.gif") return MessageItem( MessageChain.create([Image.fromUnsafeBytes(image_bytes)]), Normal(GroupStrategy()))
async def ripped(image: Union[int, str]) -> MessageItem: ripped = IMG.open(f"{os.getcwd()}/statics/ripped.png") frame = IMG.new('RGBA', (1080, 804), (255, 255, 255, 0)) avatar = await AvatarFunPicHandler.get_pil_avatar(image) left = avatar.resize((385, 385)).rotate(24, expand=True) right = avatar.resize((385, 385)).rotate(-11, expand=True) frame.paste(left, (-5, 355)) frame.paste(right, (649, 310)) frame.paste(ripped, mask=ripped) frame = frame.convert('RGB') output = BytesIO() frame.save(output, format='jpeg') return MessageItem( MessageChain.create([Image.fromUnsafeBytes(output.getvalue())]), Normal(GroupStrategy()))
async def phantom_tank(app: GraiaMiraiApplication, message: MessageChain, group: Group): message_text = "".join([plain.text for plain in message.get(Plain)]).strip() if message_text in ["幻影", "彩色幻影"]: if len(message[Image]) != 2: try: await app.sendGroupMessage(group, MessageChain.create([Plain(text="非预期图片数量!请按 `显示图 隐藏图` 顺序发送,共两张")])) except AccountMuted: pass return None if globals()["signal"] >= 2: try: await app.sendGroupMessage(group, MessageChain.create([Plain(text=f"目前有{signal}个任务正在处理,请稍后再试!")])) except AccountMuted: pass return None globals()["signal"] += 1 try: await app.sendGroupMessage(group, MessageChain.create([Plain(text="converting")])) except AccountMuted: pass im_1 = message[Image][0] async with aiohttp.ClientSession() as session: async with session.get(url=im_1.url) as resp: img_content = await resp.read() display_img = IMG.open(BytesIO(img_content)) im_2 = message[Image][1] async with aiohttp.ClientSession() as session: async with session.get(url=im_2.url) as resp: img_content = await resp.read() hide_img = IMG.open(BytesIO(img_content)) try: await app.sendGroupMessage( group, MessageChain.create([ Image.fromUnsafeBytes(await make_tank(display_img, hide_img) if message_text == "幻影" else await colorful_tank(display_img, hide_img)) # Image.fromUnsafeBytes(await colorful_tank(display_img, hide_img)) ]) ) except AccountMuted: pass globals()["signal"] -= 1
async def sendURaNai(force=False): files = os.listdir(self.PATH_URN + pack) random.seed(seed) randint = random.randint(1, len(files)) if pack == 'princess/': bio = io.BytesIO() self.drawing_pic(randint, pack).save(bio, format='JPEG') img: Image = Image.fromUnsafeBytes(bio.getvalue()) else: img: Image = Image.fromLocalFile(self.PATH_URN + pack + f'URaNai{randint}.jpg') msg = [At(message.sender.id), img] if force: msg.append(Plain(f'已花费5只{self.Economy.unit}')) await app.sendGroupMessage(message.sender.group.id, MeCh.create(msg)) random.seed(None)
async def search_bangumi(img: Image) -> MessageChain: url = f"https://trace.moe/api/search?url={img.url}" async with aiohttp.ClientSession() as session: async with session.post(url=url) as resp: result = await resp.json() if docs := result["docs"]: print(json.dumps(docs[0], indent=4)) title_chinese = docs[0]["title_chinese"] title_origin = docs[0]["title_chinese"] file_name = docs[0]["filename"] anilist_id = docs[0]["anilist_id"] time_from = docs[0]["from"] time_to = docs[0]["to"] t = docs[0]["at"] tokenthumb = docs[0]["tokenthumb"] thumbnail_url = f"https://media.trace.moe/image/{anilist_id}/{quote(file_name)}?t={t}&token={tokenthumb}&size=l" print(thumbnail_url) async with aiohttp.ClientSession() as session: async with session.get(url=thumbnail_url) as resp: thumbnail_content = await resp.read() # url = f"https://anilist.co/anime/{anilist_id}" # async with aiohttp.ClientSession() as session: # async with session.get(url=url) as resp: # result = await resp.json() # result = result[0] # start_date = f"{result['startDate']['year']}-{result['startDate']['month']}-{result['startDate']['day']}" # end_date = f"{result['endDate']['year']}-{result['endDate']['month']}-{result['endDate']['day']}" # score = result["averageScore"] message = MessageChain.create([ Plain(text="搜索到结果:\n"), Image.fromUnsafeBytes(thumbnail_content), Plain(text=f"name: {title_origin}\n"), Plain(text=f"Chinese name: {title_chinese}\n"), Plain(text=f"file name: {file_name}\n"), Plain( text= f"time: {sec_to_str(time_from)} ~ {sec_to_str(time_to)}\n" ), # Plain(text=f"score: {score}\n"), # Plain(text=f"Broadcast date: {start_date} ~ {end_date}\n") ]) return message
async def kiss(operator_image: Union[int, str], target_image: Union[int, str]) -> MessageItem: """ Author: https://github.com/SuperWaterGod """ gif_frames = [] operator = await AvatarFunPicHandler.get_pil_avatar(operator_image) target = await AvatarFunPicHandler.get_pil_avatar(target_image) operator = operator.resize((40, 40), IMG.ANTIALIAS) size = operator.size r2 = min(size[0], size[1]) circle = IMG.new('L', (r2, r2), 0) draw = ImageDraw.Draw(circle) draw.ellipse((0, 0, r2, r2), fill=255) alpha = IMG.new('L', (r2, r2), 255) alpha.paste(circle, (0, 0)) operator.putalpha(alpha) target = target.resize((50, 50), IMG.ANTIALIAS) size = target.size r2 = min(size[0], size[1]) circle = IMG.new('L', (r2, r2), 0) draw = ImageDraw.Draw(circle) draw.ellipse((0, 0, r2, r2), fill=255) alpha = IMG.new('L', (r2, r2), 255) alpha.paste(circle, (0, 0)) target.putalpha(alpha) md5 = hashlib.md5( str(str(operator_image) + str(target_image)).encode("utf-8")).hexdigest() for i in range(1, 14): gif_frames.append(await AvatarFunPicHandler.kiss_make_frame( operator, target, i)) await AvatarFunPicHandler.save_gif( gif_frames, f"{os.getcwd()}/statics/temp/tempKiss-{md5}.gif", fps=25) with open(f"{os.getcwd()}/statics/temp/tempKiss-{md5}.gif", 'rb') as r: img_content = r.read() os.remove(f"{os.getcwd()}/statics/temp/tempKiss-{md5}.gif") return MessageItem( MessageChain.create([Image.fromUnsafeBytes(img_content)]), Normal(GroupStrategy()))
async def get_result(group: Group, member: Member, question: str) -> MessageItem: api_key = get_config("wolframAlphaKey") if api_key == "wolframAlphaKey": return MessageItem( MessageChain.create([Plain(text="尚未配置wolframAlphaKey!")]), QuoteSource(GroupStrategy())) url = f"https://api.wolframalpha.com/v1/simple?i={question.replace('+', '%2B')}&appid={api_key}" async with aiohttp.ClientSession() as session: async with session.get(url=url) as resp: if resp.status == 200: res = await resp.read() return MessageItem( MessageChain.create([Image.fromUnsafeBytes(res)]), QuoteSource(GroupStrategy())) else: return MessageItem( MessageChain.create([Plain(text=await resp.text())]), QuoteSource(GroupStrategy()))
async def formula2img(str_latex, img_size=(5, 3), font_size=20) -> MessageItem: fig = plt.figure(figsize=img_size) ax = fig.add_axes([0, 0, 1, 1]) ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) ax.set_xticks([]) ax.set_yticks([]) plt.text(0.5, 0.5, str_latex, fontsize=font_size, verticalalignment='center', horizontalalignment='center') bytes_io = BytesIO() plt.savefig(bytes_io) return MessageItem( MessageChain.create([Image.fromUnsafeBytes(bytes_io.getvalue())]), QuoteSource(GroupStrategy()))
async def throw(image: Union[int, str]) -> MessageItem: avatar = await AvatarFunPicHandler.get_pil_avatar(image) mask = IMG.new('L', avatar.size, 0) draw = ImageDraw.Draw(mask) offset = 1 draw.ellipse( (offset, offset, avatar.size[0] - offset, avatar.size[1] - offset), fill=255) mask = mask.filter(ImageFilter.GaussianBlur(0)) avatar.putalpha(mask) avatar = avatar.rotate(random.randint(1, 360), IMG.BICUBIC) avatar = avatar.resize((143, 143), IMG.ANTIALIAS) throw = IMG.open(f"{os.getcwd()}/statics/throw.png") throw.paste(avatar, (15, 178), mask=avatar) throw = throw.convert('RGB') output = BytesIO() throw.save(output, format='jpeg') return MessageItem( MessageChain.create([Image.fromUnsafeBytes(output.getvalue())]), Normal(GroupStrategy()))
async def petpet(member_id: int, flip=False, squish=0, fps=20) -> MessageItem: """生成PetPet 将输入的头像生成为所需的 PetPet 并输出 参数 path: str 为头像路径 flip: bool 为是否横向反转头像 squish: float 为一个 [0, 1] 之间的数,为挤压量 fps: int 为输出 gif 每秒显示的帧数 返回 bool 但是会输出一个符合参数的 gif """ gif_frames = [] url = f'http://q1.qlogo.cn/g?b=qq&nk={str(member_id)}&s=640' async with aiohttp.ClientSession() as session: async with session.get(url=url) as resp: img_content = await resp.read() avatar = IMG.open(BytesIO(img_content)) # 生成每一帧 for i in range(5): gif_frames.append(await AvatarFunPicHandler.make_frame(avatar, i, squish=squish, flip=flip)) if not os.path.exists(f"{os.getcwd()}/statics/temp/"): os.mkdir(f"{os.getcwd()}/statics/temp/") await AvatarFunPicHandler.save_gif(gif_frames, f"{os.getcwd()}/statics/temp/tempPetPet-{member_id}.gif", fps=fps) with open(f"{os.getcwd()}/statics/temp/tempPetPet-{member_id}.gif", "rb") as r: image_bytes = r.read() os.remove(f"{os.getcwd()}/statics/temp/tempPetPet-{member_id}.gif") return MessageItem(MessageChain.create([Image.fromUnsafeBytes(image_bytes)]), Normal(GroupStrategy()))
async def make_illust_message(illust: dict) -> MessageChain: """ 将给定illust按照模板转换为message :param illust: 给定illust :return: 转换后的message """ msg = Template(reply_pattern).render( title=Plain(illust["title"]), author=Plain(illust["user"]["name"]), author_id=Plain(illust["user"]["id"]), caption=Plain(illust["caption"]), tags=Plain(" ".join(map(lambda x: x["name"], illust["tags"]))), id=Plain(str(illust["id"])) ) illegal_tags = [] for tag in block_tags: if has_tag(illust, tag): illegal_tags.append(tag) if len(illegal_tags) > 0: block_msg = Template(block_message).render( tag=Plain(' '.join(illegal_tags)) ) if block_mode == "escape_img": return msg.plusWith(block_msg) elif block_mode == "fully_block": return block_msg else: raise ValueError("illegal block_mode value: " + block_mode) try: b = await cache_illust(illust) img_msg = MessageChain.create([Image.fromUnsafeBytes(b)]) except asyncio.TimeoutError: img_msg = MessageChain.create([Plain(download_timeout_message)]) except Exception as e: img_msg = MessageChain.create([Plain(f"{type(e)} {str(e)}")]) msg.plus(img_msg) return msg
async def friend_message_listener(app: GraiaMiraiApplication, friend: Friend, message: MessageChain): if message.asDisplay() == "单抽": times = user.get_times(friend.id) rarity, char = await gacha(times=times) await user.change(friend.id, friend.nickname, rarity, char) await app.sendFriendMessage( friend, MessageChain.create([ Image.fromLocalFile("chars/{}/{}".format(rarity, char)), Plain( text="{}: {}".format(rarity_text_dict[rarity], char[:-4])) ])) elif message.asDisplay() == "十连": rarity_list, char_list = [], [] for i in range(10): times = user.get_times(friend.id) rarity, char = await gacha(times=times) await user.change(friend.id, friend.nickname, rarity, char) rarity_list.append(rarity) char_list.append(char) result_file, result_str = await ten_img_make(rarity_list, char_list) await app.sendFriendMessage( friend, MessageChain.create( [Image.fromUnsafeBytes(result_file), Plain(text=result_str)])) elif message.asDisplay().startswith("查询"): await app.sendFriendMessage( friend, MessageChain.create( [Plain(text=user.query(friend.id, friend.nickname))])) elif message.asDisplay() == "清除": user.delete(friend.id) await app.sendFriendMessage( friend, MessageChain.create([ Plain(text="号码: {}\n昵称: {}\n清除完成".format( friend.id, friend.nickname)) ]))
async def crawl(image: Union[int, str]) -> MessageItem: avatar = await AvatarFunPicHandler.get_pil_avatar(image) mask = IMG.new('L', avatar.size, 0) draw = ImageDraw.Draw(mask) offset = 1 draw.ellipse( (offset, offset, avatar.size[0] - offset, avatar.size[1] - offset), fill=255) mask = mask.filter(ImageFilter.GaussianBlur(0)) avatar.putalpha(mask) images = [i for i in os.listdir(f"{os.getcwd()}/statics/crawl")] crawl = IMG.open( f"{os.getcwd()}/statics/crawl/{random.choice(images)}").resize( (500, 500), IMG.ANTIALIAS) avatar = avatar.resize((100, 100), IMG.ANTIALIAS) crawl.paste(avatar, (0, 400), mask=avatar) crawl = crawl.convert('RGB') output = BytesIO() crawl.save(output, format='jpeg') return MessageItem( MessageChain.create([Image.fromUnsafeBytes(output.getvalue())]), Normal(GroupStrategy()))