mirror of
https://github.com/ClovertaTheTrilobita/SanYeCao-Nonebot.git
synced 2026-04-01 22:04:51 +00:00
feat(plugins): 新增 yuc_wiki 插件及相关配置
- 新增 yuc_wiki 插件,支持查询本季新番和动漫信息 - 添加 yuc_wiki 图片存储路径配置 - 更新 .gitignore 忽略 yuc_wiki 图片目录 - 更新 requirements.txt 添加 cssutils 依赖 - 更新 check.py 菜单项,添加 yuc_wiki 相关命令
This commit is contained in:
parent
cf263243ba
commit
79cd63fb8f
6 changed files with 141 additions and 1 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -23,3 +23,4 @@ bili.cookie
|
||||||
/src/resources/image/report/*
|
/src/resources/image/report/*
|
||||||
/src/resources/image/lightnovel/*
|
/src/resources/image/lightnovel/*
|
||||||
/wenku8.cookie
|
/wenku8.cookie
|
||||||
|
/src/resources/image/yuc_wiki/*
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ playwright
|
||||||
nonebot-plugin-htmlrender
|
nonebot-plugin-htmlrender
|
||||||
tenacity
|
tenacity
|
||||||
paramiko
|
paramiko
|
||||||
|
cssutils
|
||||||
|
|
||||||
requests
|
requests
|
||||||
pillow
|
pillow
|
||||||
|
|
|
||||||
120
src/clover_yuc_wiki/yuc_wiki.py
Normal file
120
src/clover_yuc_wiki/yuc_wiki.py
Normal file
|
|
@ -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> 标签
|
||||||
|
hr_tags = soup.find_all('hr')
|
||||||
|
if len(hr_tags) >= 2:
|
||||||
|
second_hr = hr_tags[1]
|
||||||
|
# 删除第二个 <hr> 标签之后的所有内容
|
||||||
|
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("保存图片完成")
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -28,6 +28,9 @@ os.makedirs(daily_news_path, exist_ok=True)
|
||||||
# 轻小说
|
# 轻小说
|
||||||
light_novel_path = path + '/image/lightnovel/'
|
light_novel_path = path + '/image/lightnovel/'
|
||||||
os.makedirs(light_novel_path, exist_ok=True)
|
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/'
|
font_path = path + '/font/'
|
||||||
os.makedirs(font_path, exist_ok=True)
|
os.makedirs(font_path, exist_ok=True)
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ from src.clover_sqlite.models.user import UserList
|
||||||
|
|
||||||
menu = ['/重启','/今日运势','/今日塔罗','/图','/日报','/点歌','/摸摸头','/群老婆','/今日老婆', "/开启ai","/关闭ai","/角色列表","/添加人设", "/更新人设", "/删除人设", "/切换人设", "/管理员注册",
|
menu = ['/重启','/今日运势','/今日塔罗','/图','/日报','/点歌','/摸摸头','/群老婆','/今日老婆', "/开启ai","/关闭ai","/角色列表","/添加人设", "/更新人设", "/删除人设", "/切换人设", "/管理员注册",
|
||||||
'/待办', '/test','/天气','我喜欢你', "❤", "/待办查询", "/新建待办", "/删除待办" ,"/cf","/B站搜索", "/BV搜索", "/喜报", "/悲报", "/luxun","/鲁迅说",
|
'/待办', '/test','/天气','我喜欢你', "❤", "/待办查询", "/新建待办", "/删除待办" ,"/cf","/B站搜索", "/BV搜索", "/喜报", "/悲报", "/luxun","/鲁迅说",
|
||||||
"/奶龙", "/repo", "/info", "/menu", "/轻小说"]
|
"/奶龙", "/repo", "/info", "/menu", "/轻小说",'/本季新番','/新番观察']
|
||||||
|
|
||||||
send_menu = ["/开启ai","/关闭ai","/角色列表","/添加人设", "/更新人设", "/删除人设", "/切换人设", "/管理员注册", '/待办', '/test', '我喜欢你', "❤", "/menu"]
|
send_menu = ["/开启ai","/关闭ai","/角色列表","/添加人设", "/更新人设", "/删除人设", "/切换人设", "/管理员注册", '/待办', '/test', '我喜欢你', "❤", "/menu"]
|
||||||
|
|
||||||
|
|
|
||||||
15
src/plugins/yuc_wiki.py
Normal file
15
src/plugins/yuc_wiki.py
Normal file
|
|
@ -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)))
|
||||||
Loading…
Reference in a new issue