zhenxun_bot/zhenxun/builtin_plugins/help/_utils.py
2024-08-15 23:52:19 +08:00

251 lines
9.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
import random
from typing import Dict
from zhenxun.configs.config import Config
from zhenxun.configs.path_config import DATA_PATH, IMAGE_PATH, TEMPLATE_PATH
from zhenxun.models.group_console import GroupConsole
from zhenxun.models.plugin_info import PluginInfo
from zhenxun.utils.enum import BlockType, PluginType
from zhenxun.utils.image_utils import BuildImage, build_sort_image, group_image
from ._config import Item
GROUP_HELP_PATH = DATA_PATH / "group_help"
GROUP_HELP_PATH.mkdir(exist_ok=True, parents=True)
for f in os.listdir(GROUP_HELP_PATH):
group_help_image = GROUP_HELP_PATH / f
group_help_image.unlink()
BACKGROUND_PATH = IMAGE_PATH / "background" / "help" / "simple_help"
LOGO_PATH = TEMPLATE_PATH / "menu" / "res" / "logo"
class HelpImageBuild:
def __init__(self):
self._data: list[PluginInfo] = []
self._sort_data: Dict[str, list[PluginInfo]] = {}
self._image_list = []
self.icon2str = {
"normal": "fa fa-cog",
"原神相关": "fa fa-circle-o",
"常规插件": "fa fa-cubes",
"联系管理员": "fa fa-envelope-o",
"抽卡相关": "fa fa-credit-card-alt",
"来点好康的": "fa fa-picture-o",
"数据统计": "fa fa-bar-chart",
"一些工具": "fa fa-shopping-cart",
"商店": "fa fa-shopping-cart",
"其它": "fa fa-tags",
"群内小游戏": "fa fa-gamepad",
}
async def sort_type(self):
"""
对插件按照菜单类型分类
"""
if not self._data:
self._data = await PluginInfo.filter(
menu_type__not="",
load_status=True,
plugin_type__in=[PluginType.NORMAL, PluginType.HIDDEN],
)
if not self._sort_data:
for plugin in self._data:
menu_type = plugin.menu_type or "normal"
if menu_type == "normal":
menu_type = "功能"
if not self._sort_data.get(menu_type):
self._sort_data[menu_type] = []
self._sort_data[menu_type].append(plugin)
async def build_image(self, group_id: str | None):
if group_id:
help_image = GROUP_HELP_PATH / f"{group_id}.png"
else:
help_image = IMAGE_PATH / f"SIMPLE_HELP.png"
build_type = Config.get_config("help", "TYPE")
if build_type == "HTML":
byt = await self.build_html_image(group_id)
with open(help_image, "wb") as f:
f.write(byt)
else:
img = await self.build_pil_image(group_id)
await img.save(help_image)
async def build_html_image(self, group_id: str | None) -> bytes:
from nonebot_plugin_htmlrender import template_to_pic
await self.sort_type()
classify = {}
for menu in self._sort_data:
for plugin in self._sort_data[menu]:
sta = 0
if not plugin.status:
if group_id and plugin.block_type in [
BlockType.ALL,
BlockType.GROUP,
]:
sta = 2
if not group_id and plugin.block_type in [
BlockType.ALL,
BlockType.PRIVATE,
]:
sta = 2
if group_id and (
group := await GroupConsole.get_or_none(group_id=group_id)
):
if f"{plugin.module}:super," in group.block_plugin:
sta = 2
if f"{plugin.module}," in group.block_plugin:
sta = 1
if classify.get(menu):
classify[menu].append(Item(plugin_name=plugin.name, sta=sta))
else:
classify[menu] = [Item(plugin_name=plugin.name, sta=sta)]
max_len = 0
flag_index = -1
max_data = None
plugin_list = []
for index, plu in enumerate(classify.keys()):
if plu in self.icon2str.keys():
icon = self.icon2str[plu]
else:
icon = "fa fa-pencil-square-o"
logo = LOGO_PATH / random.choice(os.listdir(LOGO_PATH))
data = {
"name": plu if plu != "normal" else "功能",
"items": classify[plu],
"icon": icon,
"logo": str(logo.absolute()),
}
if len(classify[plu]) > max_len:
max_len = len(classify[plu])
flag_index = index
max_data = data
plugin_list.append(data)
del plugin_list[flag_index]
plugin_list.insert(0, max_data)
pic = await template_to_pic(
template_path=str((TEMPLATE_PATH / "menu").absolute()),
template_name="zhenxun_menu.html",
templates={"plugin_list": plugin_list},
pages={
"viewport": {"width": 1903, "height": 975},
"base_url": f"file://{TEMPLATE_PATH}",
},
wait=2,
)
return pic
async def build_pil_image(self, group_id: str | None) -> BuildImage:
"""构造帮助图片
参数:
group_id: 群号
"""
self._image_list = []
await self.sort_type()
font_size = 24
build_type = Config.get_config("help", "TYPE")
font = BuildImage.load_font("HYWenHei-85W.ttf", 20)
for idx, menu_type in enumerate(self._sort_data.keys()):
plugin_list = self._sort_data[menu_type]
wh_list = [
BuildImage.get_text_size(f"{x.id}.{x.name}", font) for x in plugin_list
]
wh_list.append(BuildImage.get_text_size(menu_type, font))
# sum_height = sum([x[1] for x in wh_list])
if build_type == "VV":
sum_height = 50 * len(plugin_list) + 10
else:
sum_height = (font_size + 6) * len(plugin_list) + 10
max_width = max([x[0] for x in wh_list]) + 30
bk = BuildImage(
max_width + 40,
sum_height + 50,
font_size=30,
color="#a7d1fc",
font="CJGaoDeGuo.otf",
)
title_size = bk.getsize(menu_type)
max_width = max_width if max_width > title_size[0] else title_size[0]
B = BuildImage(
max_width + 40,
sum_height,
font_size=font_size,
color="white" if not idx % 2 else "black",
)
curr_h = 10
group = await GroupConsole.get_or_none(group_id=group_id)
for i, plugin in enumerate(plugin_list):
text_color = (255, 255, 255) if idx % 2 else (0, 0, 0)
if group and f"{plugin.module}," in group.block_plugin:
text_color = (252, 75, 13)
pos = None
# 禁用状态划线
if plugin.block_type in [BlockType.ALL, BlockType.GROUP] or (
group and f"super:{plugin.module}," in group.block_plugin
):
w = curr_h + int(B.getsize(plugin.name)[1] / 2) + 2
pos = (
7,
w,
B.getsize(plugin.name)[0] + 35,
w,
)
if build_type == "VV":
name_image = await self.build_name_image( # type: ignore
max_width,
plugin.name,
"black" if not idx % 2 else "white",
text_color,
pos,
)
await B.paste(name_image, (0, curr_h), center_type="width")
curr_h += name_image.h + 5
else:
await B.text((10, curr_h), f"{plugin.id}.{plugin.name}", text_color)
if pos:
await B.line(pos, (236, 66, 7), 3)
curr_h += font_size + 5
await bk.text((0, 14), menu_type, center_type="width")
await bk.paste(B, (0, 50))
await bk.transparent(2)
# await bk.acircle_corner(point_list=['lt', 'rt'])
self._image_list.append(bk)
image_group, h = group_image(self._image_list)
async def _a(image: BuildImage):
await image.filter("GaussianBlur", 5)
B = await build_sort_image(
image_group,
h,
background_path=BACKGROUND_PATH,
background_handle=_a,
)
w = 10
h = 10
for msg in [
"目前支持的功能列表:",
"可以通过 ‘帮助 [功能名称或功能Id] 来获取对应功能的使用方法",
]:
text = await BuildImage.build_text_image(msg, "HYWenHei-85W.ttf", 24)
await B.paste(text, (w, h))
h += 50
if msg == "目前支持的功能列表:":
w += 50
text = await BuildImage.build_text_image(
"注: 红字代表功能被群管理员禁用,红线代表功能正在维护",
"HYWenHei-85W.ttf",
24,
(231, 74, 57),
)
await B.paste(
text,
(300, 10),
)
return B