zhenxun_bot/basic_plugins/help/_utils.py
2023-02-09 21:59:40 +08:00

256 lines
9.6 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, List, Optional
from configs.config import Config
from configs.path_config import DATA_PATH, IMAGE_PATH, TEMPLATE_PATH
from utils.decorator import Singleton
from utils.image_utils import BuildImage, build_sort_image, group_image
from utils.manager import group_manager, plugin_data_manager
from utils.manager.models import PluginData, PluginType
from ._config import Item
GROUP_HELP_PATH = DATA_PATH / "group_help"
GROUP_HELP_PATH.mkdir(exist_ok=True, parents=True)
for x in os.listdir(GROUP_HELP_PATH):
group_help_image = GROUP_HELP_PATH / x
group_help_image.unlink()
BACKGROUND_PATH = IMAGE_PATH / "background" / "help" / "simple_help"
LOGO_PATH = TEMPLATE_PATH / "menu" / "res" / "logo"
@Singleton
class HelpImageBuild:
def __init__(self):
self._data: Dict[str, PluginData] = plugin_data_manager.get_data()
self._sort_data: Dict[str, List[PluginData]] = {}
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",
}
def sort_type(self):
"""
说明:
对插件按照菜单类型分类
"""
if not self._sort_data.keys():
for key in self._data.keys():
plugin_data = self._data[key]
if plugin_data.plugin_type == PluginType.NORMAL:
if not self._sort_data.get(plugin_data.menu_type[0]):
self._sort_data[plugin_data.menu_type[0]] = []
self._sort_data[plugin_data.menu_type[0]].append(self._data[key])
async def build_image(self, group_id: Optional[int]):
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)
img.save(help_image)
async def build_html_image(self, group_id: Optional[int]) -> bytes:
from nonebot_plugin_htmlrender import template_to_pic
self.sort_type()
classify = {}
for menu in self._sort_data:
for plugin in self._sort_data[menu]:
sta = 0
if not plugin.plugin_status.status:
if group_id and plugin.plugin_status.block_type in ["all", "group"]:
sta = 2
if not group_id and plugin.plugin_status.block_type in [
"all",
"private",
]:
sta = 2
if group_id and not group_manager.get_plugin_super_status(
plugin.model, group_id
):
sta = 2
if group_id and not group_manager.get_plugin_status(
plugin.model, group_id
):
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: Optional[int]) -> BuildImage:
"""
说明:
构造帮助图片
参数:
:param group_id: 群号
"""
self._image_list = []
self.sort_type()
font_size = 24
build_type = Config.get_config("help", "TYPE")
_image = BuildImage(0, 0, plain_text="1", font_size=font_size)
for idx, menu_type in enumerate(self._sort_data.keys()):
plugin_list = self._sort_data[menu_type]
wh_list = [_image.getsize(x.name) for x in plugin_list]
wh_list.append(_image.getsize(menu_type))
# 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]) + 20
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
for i, plugin_data in enumerate(plugin_list):
text_color = (255, 255, 255) if idx % 2 else (0, 0, 0)
if group_id and not group_manager.get_plugin_status(
plugin_data.model, group_id
):
text_color = (252, 75, 13)
pos = None
# 禁用状态划线
if (
not plugin_data.plugin_status.status
and plugin_data.plugin_status.block_type in ["group", "all"]
) or (group_id and not group_manager.get_plugin_super_status(
plugin_data.model, group_id
)):
w = curr_h + int(B.getsize(plugin_data.name)[1] / 2) + 2
pos = (
7,
w,
B.getsize(plugin_data.name)[0] + 35,
w,
)
if build_type == "VV":
name_image = await self.build_name_image(
max_width,
plugin_data.name,
"black" if not idx % 2 else "white",
text_color,
pos,
)
await B.apaste(
name_image, (0, curr_h), True, center_type="by_width"
)
curr_h += name_image.h + 5
else:
await B.atext(
(10, curr_h), f"{i + 1}.{plugin_data.name}", text_color
)
if pos:
await B.aline(pos, (236, 66, 7), 3)
curr_h += font_size + 5
if menu_type == "normal":
menu_type = "功能"
await bk.atext((0, 14), menu_type, center_type="by_width")
await bk.apaste(B, (0, 50))
await bk.atransparent(2)
# await bk.acircle_corner(point_list=['lt', 'rt'])
self._image_list.append(bk)
image_group, h = group_image(self._image_list)
B = await build_sort_image(
image_group,
h,
background_path=BACKGROUND_PATH,
background_handle=lambda image: image.filter("GaussianBlur", 5),
)
w = 10
h = 10
for msg in [
"目前支持的功能列表:",
"可以通过 ‘帮助[功能名称] 来获取对应功能的使用方法",
]:
text = BuildImage(
0,
0,
plain_text=msg,
font_size=24,
font="HYWenHei-85W.ttf",
)
B.paste(text, (w, h), True)
h += 50
if msg == "目前支持的功能列表:":
w += 50
await B.apaste(
BuildImage(
0,
0,
plain_text="注: 红字代表功能被群管理员禁用,红线代表功能正在维护",
font_size=24,
font="HYWenHei-85W.ttf",
font_color=(231, 74, 57),
),
(300, 10),
True,
)
return B