async def get_thumb(comic_info: dict) -> Image: if os.path.exists(f"{SEARCH_CACHE_PATH}/{comic_info['_id']}.jpg"): return Image(path=f"{SEARCH_CACHE_PATH}/{comic_info['_id']}.jpg") else: return Image(data_bytes=await pica.download_image( url= f"{comic_info['thumb']['fileServer']}/static/{comic_info['thumb']['path']}", path=f"{SEARCH_CACHE_PATH}/{comic_info['_id']}.jpg" if SEARCH_CACHE else None))
async def search_bangumi(img: Image) -> MessageChain: url = f"https://api.trace.moe/search?anilistInfo&url={img.url}" async with aiohttp.ClientSession() as session: async with session.post(url=url, proxy=proxy if proxy != "proxy" else '') as resp: result = await resp.json() # print(result) if result := result.get("result"): # print(json.dumps(result[0], indent=4)) title_native = result[0]["anilist"]["title"]["native"] title_romaji = result[0]["anilist"]["title"]["romaji"] title_english = result[0]["anilist"]["title"]["english"] file_name = result[0]["filename"] similarity = round(float(result[0]["similarity"]) * 100, 2) time_from = result[0]["from"] time_to = result[0]["to"] thumbnail_url = result[0]["image"] async with aiohttp.ClientSession() as session: async with session.get(url=thumbnail_url) as resp: thumbnail_content = await resp.read() message = await MessageChainUtils.messagechain_to_img( MessageChain.create([ Plain(text="搜索到结果:\n"), Image(data_bytes=thumbnail_content), Plain(text=f"番剧名: {title_native}\n"), Plain(text=f"罗马音名: {title_romaji}\n"), Plain(text=f"英文名: {title_english}\n"), Plain(text=f"文件名: {file_name}\n"), Plain(text=f"时间: {sec_to_str(time_from)} ~ {sec_to_str(time_to)}\n"), Plain(text=f"相似度: {similarity}%"), ]) ) return message
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 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 handle(app: Ariadne, message: MessageChain, group: Group, member: Member, content: RegexResult, image: ElementResult): msg = content.result.asDisplay() img = await image.result.get_bytes() msg = await get_translate(msg) w2b = BuildImage(0, 0, background=BytesIO(img)) w2b.convert("L") msg_sp = msg.split("<|>") w, h = w2b.size add_h, font_size = init_h_font_size(h) bg = BuildImage(w, h + add_h, color="black", font_size=font_size) bg.paste(w2b) chinese_msg = formalization_msg(msg) if not bg.check_font_size(chinese_msg): if len(msg_sp) == 1: centered_text(bg, chinese_msg, add_h) else: centered_text(bg, chinese_msg + "<|>" + msg_sp[1], add_h) elif not bg.check_font_size(msg_sp[0]): centered_text(bg, msg, add_h) else: ratio = (bg.getsize(msg_sp[0])[0] + 20) / bg.w add_h = add_h * ratio bg.resize(ratio) centered_text(bg, msg, add_h) return MessageItem( MessageChain.create([Image(data_bytes=bg.pic2bytes())]), QuoteSource())
def exportPicture(fileName, suffix, options, id): imgName = fileName.split('.')[0] + '.' + suffix.lower() CMD = mathematicaCMD(fileName) + f' -format {suffix} > {imgName}' runCMD(CMD, id, options) print('>> ', imgName) result = Image.fromLocalFile(imgName) return result
async def swallowed(image: Union[int, str]) -> MessageItem: avatar = await AvatarFunPic.get_pil_avatar(image) frame_locs = [(180, 60, 100, 100), (184, 75, 100, 100), (183, 98, 100, 100), (179, 118, 110, 100), (156, 194, 150, 48), (178, 136, 122, 69), (175, 66, 122, 85), (170, 42, 130, 96), (175, 34, 118, 95), (179, 35, 110, 93), (180, 54, 102, 93), (183, 58, 97, 92), (174, 35, 120, 94), (179, 35, 109, 93), (181, 54, 101, 92), (182, 59, 98, 92), (183, 71, 90, 96), (180, 131, 92, 101)] raw_frames = [f"{os.getcwd()}/statics/SwallowedFrames/frame{i}.png" for i in range(23)] raw_frames = [IMG.open(i).convert('RGBA') for i in raw_frames] avatar_frames = [] for i in range(len(frame_locs)): frame = IMG.new('RGBA', (480, 400), (255, 255, 255, 0)) x, y, l, w = frame_locs[i] avatar_resized = avatar.resize((l, w), IMG.ANTIALIAS) frame.paste(avatar_resized, (x, y)) img = raw_frames[i] frame.paste(img, mask=img) avatar_frames.append(frame) frames = [] for i in range(2): frames.extend(avatar_frames[0:12]) frames.extend(avatar_frames[0:8]) frames.extend(avatar_frames[12:18]) frames.extend(raw_frames[18:23]) output = BytesIO() imageio.mimsave(output, frames, format='gif', duration=0.06) return MessageItem(MessageChain.create([Image(data_bytes=output.getvalue())]), Normal())
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 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 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 qrcode_generator(app: Ariadne, message: MessageChain, group: Group, content: RegexResult): content = content.result.asDisplay() qrcode_img = qrcode.make(content) bytes_io = BytesIO() qrcode_img.save(bytes_io) await app.sendGroupMessage(group, MessageChain( [Image(data_bytes=bytes_io.getvalue())]), 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))
async def support(image: Union[int, str]) -> MessageItem: avatar = await AvatarFunPic.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(data_bytes=output.getvalue())]), Normal())
def get_tarot() -> MessageChain: card, filename = Tarot.get_random_tarot() card_dir = random.choice(['normal', 'reverse']) card_type = '正位' if card_dir == 'normal' else '逆位' content = f"{card['name']} ({card['name-en']}) {card_type}\n牌意:{card['meaning'][card_dir]}" elements = [] img_path = f"{os.getcwd()}/statics/tarot/{card_dir}/{filename + '.jpg'}" if filename and os.path.exists(img_path): elements.append(Image(path=img_path)) elements.append(Plain(text=content)) return MessageChain(elements)
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 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 AvatarFunPic.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(data_bytes=output.getvalue())]), Normal())
def gacha_info(pool=DEFAULT_POOL) -> MessageChain: # UP角色信息 info_txt = f'当前卡池为 {pool} ,UP信息如下:\n' up_info = [] for _5_star in POOL[pool]['5_star_UP']: im = IMG.open(Gacha.get_png_path(_5_star)) im = Gacha.pic2bytes(im) up_info.append(Image(data_bytes=im)) up_info.append(Plain(text=f"\n{_5_star} ★★★★★")) for _4_star in POOL[pool]['4_star_UP']: im = IMG.open(Gacha.get_png_path(_4_star)) im = Gacha.pic2bytes(im) up_info.append(Image(data_bytes=im)) up_info.append(Plain(text=f"\n{_4_star} ★★★★")) if not up_info: # 如果up_info是空的,表示当前是常驻池没有UP up_info.append(Plain(text="常驻池没有UP")) return MessageChain.create([Plain(text=info_txt)] + up_info)
async def command_handler(app: Ariadne, group: Group, params: WildcardMatch): player_name = params.result.asDisplay() player_uuid = await apis.MojangPlayerUuidApi.get(player_name) if not player_uuid.existed: await app.sendGroupMessage(group, MessageChain.create([Plain(f'「{player_name}」不存在')])) return async with aiohttp.ClientSession() as session: async with session.get(f'https://crafatar.com/renders/body/{player_uuid.id}?overlay') as resp: if resp.status == 200: image = await resp.content.read() await app.sendGroupMessage(group, MessageChain.create([Image(data_bytes=image)])) else: err_msg = await resp.text() await app.sendGroupMessage(group, MessageChain.create([Plain(f'Crafatar Error: {err_msg.strip()[:64]}')]))
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 super_resolution(image_data: bytes, resize: bool = False) -> MessageItem: start = time.time() image = IMG.open(BytesIO(image_data)) image_size = image.size[0] * image.size[1] if image_size > max_size: if not resize: await mutex.acquire() SuperResolution.processing = False mutex.release() return MessageItem( MessageChain.create([ Plain( text= "图片尺寸过大!请发送1080p以内即像素数小于 1920×1080=2073600的照片!\n"), Plain( text= f"此图片尺寸为:{image.size[0]}×{image.size[1]}={image_size}!" ) ]), QuoteSource()) length = 1 for b in str(max_size / image_size).split('.')[1]: if b == '0': length += 1 else: break magnification = round(max_size / image_size, length + 1) image = image.resize((round(image.size[0] * magnification), round(image.size[1] * magnification))) image_array: np.ndarray = image.__array__() output, _ = await loop.run_in_executor(None, upsampler.enhance, image_array, 2) result = BytesIO() img = IMG.fromarray(output) img.save(result, format='PNG') # format: PNG / JPEG end = time.time() use_time = round(end - start, 2) await mutex.acquire() SuperResolution.processing = False mutex.release() return MessageItem( MessageChain.create([ Plain(text=f"超分完成!处理用时:{use_time}s\n"), Plain(text=f"由于像素过大,图片已进行缩放,结果可能不如原图片清晰\n" if resize else ""), Image(data_bytes=result.getvalue()) ]), QuoteSource())
async def command_handler(app: Ariadne, group: Group, params: WildcardMatch): player_name = params.result.asDisplay() result = await apis.CustomSkinLoaderApi.get('https://littleskin.cn/csl', player_name) if not result.player_existed: await app.sendGroupMessage(group, MessageChain.create([Plain(f'「{player_name}」不存在')])) else: bs_root = 'https://littleskin.cn' preview_images: List[Image] = list() for texture in [result.skin_hash, result.cape_hash]: if texture: preview_images.append(Image(data_bytes=await apis.getTexturePreview( bs_root, texture))) await app.sendGroupMessage(group, MessageChain.create([*preview_images, Plain(f'''「{player_name}」 Skin: {result.skin_hash[:7]} [{result.skin_type}] Cape: {result.cape_hash[:7] if result.cape_existed else None}''')]))
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 throw(image: Union[int, str]) -> MessageItem: avatar = await AvatarFunPic.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(data_bytes=output.getvalue())]), Normal())
async def get_leetcode_daily_question(language: str = "Zh") -> MessageChain: if language != "Zh" and language != "En": raise ValueError("Language only can be Zh or En!") question_slug_data = await get_daily_question_json() question_slug = question_slug_data["data"]["todayRecord"][0]["question"][ "questionTitleSlug"] content = await get_question_content(question_slug, language) content = image_in_html_to_text(content) message_list = [] for i in content: if i: if re.match(r"img\[[0-9]+]:", i): if url := i.replace( re.findall(r"img\[[0-9]+]:", i, re.S)[0], ''): message_list.append(Image(url=url)) else: message_list.append(Plain(text=i))
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 crawl(image: Union[int, str]) -> MessageItem: avatar = await AvatarFunPic.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(data_bytes=output.getvalue())]), Normal())
def gacha_90(self, frequency=90) -> MessageChain: # 抽一井 if not (self.pool in POOL.keys()): return MessageChain('当前卡池已结束,请使用 原神卡池切换 切换其他卡池') gacha_txt = "" for self.current_times in range(frequency): new_gacha = self.gacha_one() if not (new_gacha in POOL[self.pool]['3_star_not_UP']): # 抽一井时图片上不保留3星的武器 self.gacha_list.append(new_gacha) self.add_gacha_all_statistics(new_gacha) # 把所有抽卡结果添加到gacha_all_statistics用于最后统计 self.update_last(new_gacha) # 更新第一次抽到的计数 gacha_txt += f"★★★★★×{self.gacha_rarity_statistics['5星']} ★★★★×{self.gacha_rarity_statistics['4星']} ★★★×{self.gacha_rarity_statistics['3星']}\n" mes = [ Plain(text='本次祈愿得到以下角色装备:\n'), Image(data_bytes=self.pic2bytes(self.concat_pic())), Plain(text=f'\n{gacha_txt}') ] if self.last_4: # 如果self.last_4为0表示没有抽到,这句话就不写了,下边3个判断标准一样 mes.append(Plain(text=f'第 {self.last_4} 抽首次出现4★!\n')) if self.last_4_up: mes.append(Plain(text=f'第 {self.last_4_up} 抽首次出现4★UP!\n')) if self.last_5: mes.append(Plain(text=f'第 {self.last_5} 抽首次出现5★!\n')) if self.last_5_up: mes.append(Plain(text=f'第 {self.last_5_up} 抽首次出现5★UP!\n')) most_arms = self.get_most_arms() mes.append(Plain(text=f"本次抽取最多的装备是 {most_arms['name']} {self.is_star(most_arms['name'])} ,共抽取到 {most_arms['most']} 次\n")) if self.is_guaranteed(frequency): mes.append(Plain(text="居然全是保底,你脸也太黑了\n")) mes.append(Plain(text=f"\n* 本次抽取卡池为 {self.pool} \n* 发送 原神卡池切换 可切换卡池")) return MessageChain.create(mes)
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 AvatarFunPic.get_pil_avatar(operator_image) user_img = await AvatarFunPic.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 AvatarFunPic.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 AvatarFunPic.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(data_bytes=output.getvalue())]), Normal())
async def query_resource(resource_name: str) -> Optional[MessageChain]: global CENTER_POINT planning_route: bool = False if resource_name and resource_name[-2:] in ["路径", "路线"]: resource_name = resource_name[:-2].strip() planning_route = True if not resource_name or resource_name not in resource_name_list: return None map_ = Map(resource_name, CENTER_POINT, planning_route=planning_route, ratio=MAP_RATIO) count = map_.get_resource_count() rand = await asyncio.get_event_loop().run_in_executor( None, map_.generate_resource_icon_in_map) return MessageChain.create([ Image(path=str(IMAGE_PATH / "genshin" / "temp" / f"genshin_map_{rand}.png")), Plain(text=f"\n\n※ {resource_name} 一共找到 {count} 个位置点\n※ 数据来源于米游社wiki") ])
async def send_newspaper(app: Ariadne): image_content = None for i in range(3): try: image_content = await get_image() break except Exception as e: logger.error(f"第 {i + 1} 次日报加载失败\n{e}") await asyncio.sleep(3) if not image_content: return logger.error("日报获取失败!") for group in await app.getGroupList(): if not await group_setting.get_setting(group, Setting.daily_newspaper): continue try: await app.sendMessage( group, MessageChain.create(Image(data_bytes=image_content))) except AccountMuted: continue await asyncio.sleep(random.randint(3, 6))