async def get_mcstatus(addr: str) -> Optional[Message]: try: server = MinecraftServer.lookup(addr) status = await server.async_status() version = status.version.name protocol = status.version.protocol players_online = status.players.online players_max = status.players.max players = status.players.sample player_names = [player.name for player in players] if players else [] description = status.description latency = status.latency favicon = status.favicon except: logger.warning(traceback.format_exc()) return None msg = Message() if favicon: msg.append( MessageSegment.image( "base64://" + favicon.replace("data:image/png;base64,", "") ) ) msg.append( f"服务端版本:{version}\n" f"协议版本:{protocol}\n" f"当前人数:{players_online}/{players_max}\n" f"在线玩家:{'、'.join(player_names)}\n" f"描述文本:{description}\n" f"游戏延迟:{latency}ms" ) return msg
async def search_by_image(img_url) -> Optional[Union[str, Message]]: url = "https://saucenao.com/search.php" params = { "url": img_url, "numres": 1, "testmode": 1, "db": 5, "output_type": 2, "api_key": pixiv_config.saucenao_apikey, } 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", } try: async with httpx.AsyncClient() as client: resp = await client.post(url, params=params, headers=headers, timeout=20) result = resp.json() if result["header"]["status"] == -1: logger.warning( f"post saucenao failed:{result['header']['message']}") return None if result["header"]["status"] == -2: return "24小时内搜索次数到达上限!" if "results" not in result or not result["results"]: return "找不到相似的图片" res = result["results"][0] header = res["header"] data = res["data"] thumb_url = header["thumbnail"] msg = (f"搜索到如下结果:\n" f"相似度:{header['similarity']}%\n" f"题目:{data['title']}\n" f"pixiv id:{data['pixiv_id']}\n" f"作者:{data['member_name']}\n" f"作者id:{data['member_id']}\n" f"链接:{', '.join(data['ext_urls'])}") except Exception as e: logger.warning(f"Error in search_by_image({url}): {e}") return None msgs = Message() msgs.append(msg) msgs.append(MessageSegment.image(thumb_url)) return msgs
async def rss_to_msg(rss: RSS, info: dict) -> Optional[Message]: msg = Message() img = await rss_to_image(rss, info) if not img: return None msg.append(MessageSegment.image(img)) # msg.append(info["link"]) return msg
async def _(event: MessageEvent): username = event.sender.card or event.sender.nickname message = Message(f"来看看 {username} 抽到了什么:") img = await get_tarot() if img: message.append(MessageSegment.image(img)) await tarot.finish(message) else: await tarot.finish("出错了,请稍后再试")
async def split_msg(text: str, split_pattern: str, pattern: str, func) -> Message: texts = re.split(split_pattern, text) msgs = Message() for t in texts: match = re.match(pattern, t) if match: result = await func(match.group(1)) if not result: continue msgs.append(result) else: msgs.append(t) return msgs
async def format_msg(self) -> Optional[Union[str, Message]]: msg = None if self.status == LiveStatus.LIVE: msg = Message() msg.append(f"{self.time}\n" f"{self.up_name} 开播啦!\n" f"{self.title}\n" f"直播间链接:{self.url}") msg.append(MessageSegment.image(self.cover)) return msg elif self.status == LiveStatus.PREPARING: return f"{self.up_name} 下播了" elif self.status == LiveStatus.ROUND: return f"{self.up_name} 下播了(轮播中)"
async def str_to_message(text: str) -> Message: msgs_all = Message() msgs = await split_msg(text, r"(##emoji##.*?##/emoji##)", r"##emoji##(.*?)##/emoji##", replace_emoji) for seg in msgs: if seg.type == "text": msgs_new = await split_msg( seg.data["text"], r"(##img##.*?##/img##)", r"##img##(.*?)##/img##", replace_url, ) msgs_all.extend(msgs_new) else: msgs_all.append(seg) return msgs_all
async def format_msg(self) -> Optional[Message]: img = await get_dynamic_screenshot(self.url) if not img: return None type_msg = { 0: "发布了新动态", 1: "转发了一条动态", 8: "发布了新投稿", 16: "发布了短视频", 64: "发布了新专栏", 256: "发布了新音频", } msg = Message() msg.append(f"{self.name} {type_msg.get(self.type, type_msg[0])}:") msg.append(MessageSegment.image(img)) return msg
async def to_msg(illusts) -> Message: msg = Message() async with PixivClient(proxy=proxy, timeout=20) as client: aapi = AppPixivAPI(client=client, proxy=proxy) await aapi.login(refresh_token=pixiv_config.pixiv_token) for illust in illusts: try: url: str = illust["image_urls"]["large"] url = url.replace("_webp", "").replace("i.pximg.net", "i.pixiv.re") async with httpx.AsyncClient() as client: resp = await client.get(url, timeout=20) result = resp.content if result: msg.append("{} ({})".format(illust["title"], illust["id"])) msg.append(MessageSegment.image(result)) except Exception as e: logger.warning(f"Error downloading image: {e}") return msg
async def get_jiki(keyword: str) -> Tuple[str, Union[str, Message]]: keyword = quote(keyword) search_url = "https://jikipedia.com/search?phrase={}".format(keyword) async with httpx.AsyncClient() as client: resp = await client.get(url=search_url) result = resp.text if "对不起!小鸡词典暂未收录该词条" in result: return "", "" dom = etree.HTML(result, etree.HTMLParser()) card_urls = dom.xpath( "//div[contains(@class, 'masonry')]/div/div/div/a[contains(@class, 'title-container')]/@href" ) if not card_urls: return "", "" card_url = card_urls[0] async with httpx.AsyncClient() as client: resp = await client.get(url=card_url) result = resp.text dom = etree.HTML(result, etree.HTMLParser()) title = dom.xpath( "//div[@class='section card-middle']/div[@class='title-container']/div/h1/text()" )[0] content = dom.xpath( "//div[@class='section card-middle']/div[@class='content']/div")[0] content = content.xpath("string(.)").strip() img_urls = dom.xpath( "//div[@class='section card-middle']/div/div/div[@class='show-images']/img/@src" ) if fuzz.ratio(str(title).lower(), keyword.lower()) < 90: return "", "" msg = Message() msg.append(title + ":\n---------------\n") msg.append(content) for img_url in img_urls: msg.append(MessageSegment.image(file=img_url)) return title, msg