From 79cd63fb8f735c071533970b3fe668c690702ebd Mon Sep 17 00:00:00 2001 From: SlyAimer <2289782085@qq.com> Date: Sun, 16 Feb 2025 14:36:24 +0800 Subject: [PATCH] =?UTF-8?q?feat(plugins):=20=E6=96=B0=E5=A2=9E=20yuc=5Fwik?= =?UTF-8?q?i=20=E6=8F=92=E4=BB=B6=E5=8F=8A=E7=9B=B8=E5=85=B3=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 yuc_wiki 插件,支持查询本季新番和动漫信息 - 添加 yuc_wiki 图片存储路径配置 - 更新 .gitignore 忽略 yuc_wiki 图片目录 - 更新 requirements.txt 添加 cssutils 依赖 - 更新 check.py 菜单项,添加 yuc_wiki 相关命令 --- .gitignore | 1 + requirements.txt | 1 + src/clover_yuc_wiki/yuc_wiki.py | 120 ++++++++++++++++++++++++++++++++ src/configs/path_config.py | 3 + src/plugins/check.py | 2 +- src/plugins/yuc_wiki.py | 15 ++++ 6 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 src/clover_yuc_wiki/yuc_wiki.py create mode 100644 src/plugins/yuc_wiki.py diff --git a/.gitignore b/.gitignore index a45a254..06b38dd 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ bili.cookie /src/resources/image/report/* /src/resources/image/lightnovel/* /wenku8.cookie +/src/resources/image/yuc_wiki/* diff --git a/requirements.txt b/requirements.txt index 574768e..205fd1c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -25,6 +25,7 @@ playwright nonebot-plugin-htmlrender tenacity paramiko +cssutils requests pillow diff --git a/src/clover_yuc_wiki/yuc_wiki.py b/src/clover_yuc_wiki/yuc_wiki.py new file mode 100644 index 0000000..08666a7 --- /dev/null +++ b/src/clover_yuc_wiki/yuc_wiki.py @@ -0,0 +1,120 @@ +import os +from pathlib import Path +import requests +from os import getcwd +from bs4 import BeautifulSoup +from datetime import datetime +from nonebot_plugin_htmlrender import template_to_pic +from src.configs.path_config import yuc_wiki_path + +base_url = "https://yuc.wiki/" +new = "https://yuc.wiki/new" + +async def get_yuc_wiki(keyword): + """ + 获取当季动漫 + """ + try: + if keyword == '本季新番': + template_name = await generate_season_url() + response = requests.get(base_url + f'{template_name}', timeout=10) + else: + template_name = 'forecast_anime' + response = requests.get(new, timeout=10) + + soup = await dispose_html(response) + with open(yuc_wiki_path+f'{template_name}.html', 'w', encoding='utf-8') as f: + f.write(str(soup)) + await get_yuc_wiki_image(template_name,568,1885) + except (Exception, IOError) as e: + print(f"Error occurred: {e}") + + return yuc_wiki_path+f'{template_name}.jpeg' + +async def generate_season_url(): + """ + 获取当前季度 + :return: + """ + now = datetime.now() + quarter_month = ((now.month - 1) // 3) * 3 + 1 + return f"{now.year}{quarter_month:02d}" + +async def dispose_html(response): + """ + 处理html + :param response: + :return: + """ + response.raise_for_status() + soup = BeautifulSoup(response.text, 'html.parser') + # 删除第一个 table 标签 + first_table = soup.select_one('table') + if first_table: + first_table.decompose() + # 批量处理需要删除的标签 + for tag in soup.select('header, aside'): + tag.decompose() + + # 查找第二个
标签 + hr_tags = soup.find_all('hr') + if len(hr_tags) >= 2: + second_hr = hr_tags[1] + # 删除第二个
标签之后的所有内容 + next_element = second_hr.next_sibling + while next_element: + next_sibling = next_element.next_sibling + next_element.extract() + next_element = next_sibling + + # 统一处理资源路径 + for tag in soup.find_all(['a', 'link', 'img', 'script', 'source']): + # 处理图片懒加载 + if tag.name == 'img' and tag.get('data-src'): + tag['src'] = tag['data-src'] + del tag['data-src'] + # 统一修正路径 + attr = 'href' if tag.name in ['a', 'link'] else 'src' + if tag.has_attr(attr): + path = tag[attr].lstrip('/\\') + if not path.startswith(('http://', 'https://')): + tag[attr] = f"{base_url}{path}" + if path.startswith('http://'): + tag[attr] = path.replace('http://', 'https://', 1) + return soup + +async def get_yuc_wiki_image(template_name,width,height): + + file = Path() / yuc_wiki_path / f"{template_name}.jpeg" + if os.path.exists(file): + with file.open("rb") as image_file: + return image_file.read() + + image_bytes = await template_to_pic( + template_path=yuc_wiki_path, + template_name=f'{template_name}.html', + templates={"data": None}, + quality=90, + type="jpeg", + pages={ + "viewport": {"width": width, "height": height}, + "base_url": f"file://{getcwd()}", + }, + wait=2, + ) + await save_img(image_bytes,template_name) + +async def save_img(data: bytes,template_name : str): + + """ + 保存yuc_wiki图片 + :param template_name: + :param data: + :return: + """ + file_path = yuc_wiki_path + f"{template_name}.jpeg" + with open(file_path, "wb") as file: + file.write(data) + print("保存图片完成") + + diff --git a/src/configs/path_config.py b/src/configs/path_config.py index 2eb4898..76d52d3 100644 --- a/src/configs/path_config.py +++ b/src/configs/path_config.py @@ -28,6 +28,9 @@ os.makedirs(daily_news_path, exist_ok=True) # 轻小说 light_novel_path = path + '/image/lightnovel/' os.makedirs(light_novel_path, exist_ok=True) +#yuc_wiki 动漫wiki +yuc_wiki_path = path + '/image/yuc_wiki/' +os.makedirs(yuc_wiki_path, exist_ok=True) # 字体路径 font_path = path + '/font/' os.makedirs(font_path, exist_ok=True) diff --git a/src/plugins/check.py b/src/plugins/check.py index fb484de..b5f0af4 100644 --- a/src/plugins/check.py +++ b/src/plugins/check.py @@ -10,7 +10,7 @@ from src.clover_sqlite.models.user import UserList menu = ['/重启','/今日运势','/今日塔罗','/图','/日报','/点歌','/摸摸头','/群老婆','/今日老婆', "/开启ai","/关闭ai","/角色列表","/添加人设", "/更新人设", "/删除人设", "/切换人设", "/管理员注册", '/待办', '/test','/天气','我喜欢你', "❤", "/待办查询", "/新建待办", "/删除待办" ,"/cf","/B站搜索", "/BV搜索", "/喜报", "/悲报", "/luxun","/鲁迅说", - "/奶龙", "/repo", "/info", "/menu", "/轻小说"] + "/奶龙", "/repo", "/info", "/menu", "/轻小说",'/本季新番','/新番观察'] send_menu = ["/开启ai","/关闭ai","/角色列表","/添加人设", "/更新人设", "/删除人设", "/切换人设", "/管理员注册", '/待办', '/test', '我喜欢你', "❤", "/menu"] diff --git a/src/plugins/yuc_wiki.py b/src/plugins/yuc_wiki.py new file mode 100644 index 0000000..d9b5d27 --- /dev/null +++ b/src/plugins/yuc_wiki.py @@ -0,0 +1,15 @@ +from pathlib import Path +from nonebot.rule import to_me +from nonebot.plugin import on_command +from nonebot.adapters.qq import MessageSegment,MessageEvent +from src.clover_yuc_wiki.yuc_wiki import get_yuc_wiki + + + +yuc_wiki = on_command("本季新番",aliases={'新番观察'} ,rule=to_me(), priority=10, block=True) +@yuc_wiki.handle() +async def handle_function(message: MessageEvent): + keyword = message.get_plaintext().replace("/", "").strip(" ") + yuc_wiki_image = await get_yuc_wiki(keyword) + await yuc_wiki.send("请稍等。。。") + await yuc_wiki.finish(MessageSegment.file_image(Path(yuc_wiki_image)))