mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2025-12-15 06:12:53 +08:00
重写帮助,删除 详细帮助 命令
This commit is contained in:
parent
5fb4eccd0f
commit
f496ce4861
@ -296,6 +296,10 @@ PS: **ARM平台** 请使用全量版 同时 **如果你的机器 RAM < 1G 可能
|
||||
|
||||
## 更新
|
||||
|
||||
### 2022/12/10
|
||||
|
||||
* 重写帮助,删除 `详细帮助` 命令
|
||||
|
||||
### 2022/12/4
|
||||
|
||||
* 优化管理代码
|
||||
|
||||
@ -6,7 +6,6 @@ from nonebot.adapters.onebot.v11 import (
|
||||
Message
|
||||
)
|
||||
from nonebot.params import CommandArg
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.rule import to_me
|
||||
from configs.path_config import IMAGE_PATH, DATA_PATH
|
||||
from utils.message_builder import image
|
||||
@ -16,11 +15,12 @@ import os
|
||||
|
||||
__zx_plugin_name__ = "帮助"
|
||||
|
||||
# __plugin_configs__ = {
|
||||
# "TYPE": {"value": "normal", "help": "帮助图片样式 ['normal', 'VV']", "default_value": "normal"}
|
||||
# }
|
||||
|
||||
group_help_path = DATA_PATH / "group_help"
|
||||
help_image = IMAGE_PATH / "help.png"
|
||||
simple_help_image = IMAGE_PATH / "simple_help.png"
|
||||
if help_image.exists():
|
||||
help_image.unlink()
|
||||
if simple_help_image.exists():
|
||||
simple_help_image.unlink()
|
||||
group_help_path.mkdir(exist_ok=True, parents=True)
|
||||
@ -28,21 +28,10 @@ for x in os.listdir(group_help_path):
|
||||
group_help_image = group_help_path / x
|
||||
group_help_image.unlink()
|
||||
|
||||
_help = on_command("详细功能", rule=to_me(), aliases={"详细帮助"}, priority=1, block=True)
|
||||
|
||||
simple_help = on_command("功能", rule=to_me(), aliases={"help", "帮助"}, priority=1, block=True)
|
||||
|
||||
|
||||
@_help.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
if not help_image.exists():
|
||||
if help_image.exists():
|
||||
help_image.unlink()
|
||||
if simple_help_image.exists():
|
||||
simple_help_image.unlink()
|
||||
await create_help_img(None, help_image, simple_help_image)
|
||||
await _help.finish(image("help.png"))
|
||||
|
||||
|
||||
@simple_help.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
|
||||
msg = arg.extract_plain_text().strip()
|
||||
@ -54,20 +43,18 @@ async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
|
||||
msg = msg.replace('-super', '').strip()
|
||||
msg = get_plugin_help(msg, is_super)
|
||||
if msg:
|
||||
await _help.send(image(b64=msg))
|
||||
await simple_help.send(image(b64=msg))
|
||||
else:
|
||||
await _help.send("没有此功能的帮助信息...")
|
||||
await simple_help.send("没有此功能的帮助信息...")
|
||||
else:
|
||||
if isinstance(event, GroupMessageEvent):
|
||||
_image_path = group_help_path / f"{event.group_id}.png"
|
||||
if not _image_path.exists():
|
||||
await create_help_img(event.group_id, help_image, _image_path)
|
||||
await create_help_img(event.group_id, _image_path)
|
||||
await simple_help.send(image(_image_path))
|
||||
else:
|
||||
if not simple_help_image.exists():
|
||||
if help_image.exists():
|
||||
help_image.unlink()
|
||||
if simple_help_image.exists():
|
||||
simple_help_image.unlink()
|
||||
await create_help_img(None, help_image, simple_help_image)
|
||||
await _help.finish(image("simple_help.png"))
|
||||
await create_help_img(None, simple_help_image)
|
||||
await simple_help.finish(image("simple_help.png"))
|
||||
|
||||
@ -1,16 +1,12 @@
|
||||
from .utils import group_image, build_help_image
|
||||
from .utils import HelpImageBuild
|
||||
from utils.image_utils import BuildImage
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from utils.manager import (
|
||||
plugins2settings_manager,
|
||||
admin_manager,
|
||||
plugins_manager,
|
||||
group_manager,
|
||||
)
|
||||
from typing import Optional, List, Tuple
|
||||
from services.log import logger
|
||||
from typing import Optional
|
||||
from pathlib import Path
|
||||
from utils.utils import get_matchers
|
||||
import nonebot
|
||||
|
||||
|
||||
@ -19,259 +15,22 @@ random_bk_path = IMAGE_PATH / "background" / "help" / "simple_help"
|
||||
background = IMAGE_PATH / "background" / "0.png"
|
||||
|
||||
|
||||
async def create_help_img(
|
||||
group_id: Optional[int], help_image: Path, simple_help_image: Path
|
||||
):
|
||||
async def create_help_img(group_id: Optional[int], help_image: Path):
|
||||
"""
|
||||
生成帮助图片
|
||||
:param group_id: 群号
|
||||
:param help_image: 图片路径
|
||||
:param simple_help_image: 简易帮助图片路径
|
||||
"""
|
||||
return await _create_help_img(group_id, help_image, simple_help_image)
|
||||
return await _create_help_img(group_id, help_image)
|
||||
|
||||
|
||||
async def _create_help_img(
|
||||
group_id: Optional[int], help_image: Path, simple_help_image: Path
|
||||
):
|
||||
async def _create_help_img(group_id: Optional[int], help_image: Path):
|
||||
"""
|
||||
生成帮助图片
|
||||
:param group_id: 群号
|
||||
:param help_image: 图片路径
|
||||
:param simple_help_image: 简易帮助图片路径
|
||||
"""
|
||||
width = 0
|
||||
matchers_data = {}
|
||||
_des_tmp = {}
|
||||
_tmp = []
|
||||
tmp_img = BuildImage(0, 0, plain_text="1", font_size=24)
|
||||
font_height = tmp_img.h
|
||||
# 插件分类
|
||||
for matcher in get_matchers(True):
|
||||
plugin_name = None
|
||||
_plugin = matcher.plugin
|
||||
if not _plugin:
|
||||
logger.warning(f"获取 功能:{matcher.plugin_name} 失败...")
|
||||
continue
|
||||
metadata = _plugin.metadata
|
||||
_module = _plugin.module
|
||||
try:
|
||||
plugin_name = metadata.name if metadata else _module.__getattribute__("__zx_plugin_name__")
|
||||
try:
|
||||
plugin_des = metadata.description if metadata else _module.__getattribute__("__plugin_des__")
|
||||
except AttributeError:
|
||||
plugin_des = "_"
|
||||
if (
|
||||
"[hidden]" in plugin_name.lower()
|
||||
or "[admin]" in plugin_name.lower()
|
||||
or "[superuser]" in plugin_name.lower()
|
||||
or plugin_name == "帮助"
|
||||
):
|
||||
continue
|
||||
plugin_type = ("normal",)
|
||||
text_type = 0
|
||||
if plugins2settings_manager.get(
|
||||
matcher.plugin_name
|
||||
) and plugins2settings_manager.get(matcher.plugin_name).plugin_type:
|
||||
plugin_type = tuple(
|
||||
plugins2settings_manager.get_plugin_data(matcher.plugin_name).plugin_type
|
||||
)
|
||||
else:
|
||||
if hasattr(_module, "__plugin_type__"):
|
||||
plugin_type = _module.__getattribute__("__plugin_type__")
|
||||
if len(plugin_type) > 1:
|
||||
try:
|
||||
text_type = int(plugin_type[1])
|
||||
except ValueError as e:
|
||||
logger.warning(f"生成列向帮助排列失败 {plugin_name}: {type(e)}: {e}")
|
||||
plugin_type = plugin_type[0]
|
||||
else:
|
||||
plugin_type = plugin_type[0]
|
||||
try:
|
||||
plugin_cmd = _module.__getattribute__("__plugin_cmd__")
|
||||
plugin_cmd = [x for x in plugin_cmd if "[_superuser]" not in x]
|
||||
except AttributeError:
|
||||
plugin_cmd = []
|
||||
if plugin_type not in matchers_data.keys():
|
||||
matchers_data[plugin_type] = {}
|
||||
if plugin_des in _des_tmp.keys():
|
||||
try:
|
||||
matchers_data[plugin_type][_des_tmp[plugin_des]]["cmd"] = (
|
||||
matchers_data[plugin_type][_des_tmp[plugin_des]]["cmd"]
|
||||
+ plugin_cmd
|
||||
)
|
||||
except KeyError as e:
|
||||
logger.warning(f"{type(e)}: {e}")
|
||||
else:
|
||||
matchers_data[plugin_type][plugin_name] = {
|
||||
"modules": matcher.plugin_name,
|
||||
"des": plugin_des,
|
||||
"cmd": plugin_cmd,
|
||||
"text_type": text_type,
|
||||
}
|
||||
try:
|
||||
if text_type == 0:
|
||||
x = tmp_img.getsize(
|
||||
f'{plugin_name}: {matchers_data[plugin_type][plugin_name]["des"]} ->'
|
||||
+ " / ".join(matchers_data[plugin_type][plugin_name]["cmd"])
|
||||
)[0]
|
||||
width = width if width > x else x
|
||||
except KeyError:
|
||||
pass
|
||||
if plugin_des not in _des_tmp:
|
||||
_des_tmp[plugin_des] = plugin_name
|
||||
except AttributeError as e:
|
||||
logger.warning(f"获取功能 {matcher.plugin_name}: {plugin_name} 设置失败...e:{e}")
|
||||
help_img_list = []
|
||||
simple_help_img_list = []
|
||||
types = list(matchers_data.keys())
|
||||
types.sort()
|
||||
ix = 0
|
||||
# 详细帮助
|
||||
for type_ in types:
|
||||
keys = list(matchers_data[type_].keys())
|
||||
keys.sort()
|
||||
help_str = f"{type_ if type_ != 'normal' else '功能'}:\n\n"
|
||||
simple_help_str = f"{type_ if type_ != 'normal' else '功能'}:\n\n"
|
||||
for i, k in enumerate(keys):
|
||||
# 禁用flag
|
||||
flag = True
|
||||
if plugins_manager.get_plugin_status(
|
||||
matchers_data[type_][k]["modules"], "all"
|
||||
):
|
||||
flag = False
|
||||
if group_id:
|
||||
flag = flag and plugins_manager.get_plugin_status(
|
||||
matchers_data[type_][k]["modules"], "group"
|
||||
)
|
||||
simple_help_str += (
|
||||
f"{i+1}.{k}<|_|~|>"
|
||||
f"{group_manager.get_plugin_status(matchers_data[type_][k]['modules'], group_id) if group_id else '_'}|"
|
||||
f"{flag}\n"
|
||||
)
|
||||
if matchers_data[type_][k]["text_type"] == 1:
|
||||
_x = tmp_img.getsize(
|
||||
f"{i+1}".rjust(5)
|
||||
+ f'.{k}: {matchers_data[type_][k]["des"]} {"->" if matchers_data[type_][k]["cmd"] else ""} '
|
||||
)[0]
|
||||
_str = (
|
||||
f"{i+1}".rjust(5)
|
||||
+ f'.{k}: {matchers_data[type_][k]["des"]} {"->" if matchers_data[type_][k]["cmd"] else ""} '
|
||||
)
|
||||
_str += matchers_data[type_][k]["cmd"][0] + "\n"
|
||||
for c in matchers_data[type_][k]["cmd"][1:]:
|
||||
_str += "".rjust(int(_x * 0.125) + 1) + f"{c}\n"
|
||||
help_str += _str
|
||||
else:
|
||||
help_str += (
|
||||
f"{i+1}".rjust(5)
|
||||
+ f'.{k}: {matchers_data[type_][k]["des"]} {"->" if matchers_data[type_][k]["cmd"] else ""} '
|
||||
+ " / ".join(matchers_data[type_][k]["cmd"])
|
||||
+ "\n"
|
||||
)
|
||||
height = len(help_str.split("\n")) * (font_height + 5)
|
||||
simple_height = len(simple_help_str.split("\n")) * (font_height + 5)
|
||||
A = BuildImage(
|
||||
width + 150, height, font_size=24, color="white" if not ix % 2 else "black"
|
||||
)
|
||||
A.text((10, 10), help_str, (255, 255, 255) if ix % 2 else (0, 0, 0))
|
||||
# 生成各个分类的插件简易帮助图片
|
||||
simple_width = 0
|
||||
for x in [
|
||||
tmp_img.getsize(x.split("<|_|~|>")[0])[0]
|
||||
for x in simple_help_str.split("\n")
|
||||
]:
|
||||
simple_width = simple_width if simple_width > x else x
|
||||
bk = BuildImage(simple_width + 20, simple_height, font_size=24, color="#6495ED")
|
||||
B = BuildImage(
|
||||
simple_width + 20,
|
||||
simple_height,
|
||||
font_size=24,
|
||||
color="white" if not ix % 2 else "black",
|
||||
)
|
||||
# 切分,判断插件开关状态
|
||||
_s_height = 10
|
||||
for _s in simple_help_str.split("\n"):
|
||||
text_color = (255, 255, 255) if ix % 2 else (0, 0, 0)
|
||||
_line_flag = False
|
||||
if "<|_|~|>" in _s:
|
||||
_x = _s.split("<|_|~|>")
|
||||
_flag_sp = _x[-1].split("|")
|
||||
if group_id:
|
||||
if _flag_sp[0].lower() != "true":
|
||||
text_color = (252, 75, 13)
|
||||
if _flag_sp[1].lower() == "true":
|
||||
_line_flag = True
|
||||
_s = _x[0]
|
||||
B.text((10, _s_height), _s, text_color)
|
||||
if _line_flag:
|
||||
B.line(
|
||||
(
|
||||
7,
|
||||
_s_height + int(B.getsize(_s)[1] / 2) + 2,
|
||||
B.getsize(_s)[0] + 11,
|
||||
_s_height + int(B.getsize(_s)[1] / 2) + 2,
|
||||
),
|
||||
(236, 66, 7),
|
||||
3,
|
||||
)
|
||||
_s_height += B.getsize("1")[1] + 5
|
||||
# B.text((10, 10), simple_help_str, (255, 255, 255) if ix % 2 else (0, 0, 0))
|
||||
bk.paste(B, center_type="center")
|
||||
bk.transparent(2)
|
||||
ix += 1
|
||||
help_img_list.append(A)
|
||||
simple_help_img_list.append(bk)
|
||||
height = 0
|
||||
for img in help_img_list:
|
||||
height += img.h
|
||||
if not group_id:
|
||||
A = BuildImage(width + 150, height + 50, font_size=24)
|
||||
A.text(
|
||||
(10, 10), '* 注: ‘*’ 代表可有多个相同参数 ‘?’ 代表可省略该参数 *\n\n" "功能名: 功能简介 -> 指令\n\n'
|
||||
)
|
||||
current_height = 50
|
||||
for img in help_img_list:
|
||||
A.paste(img, (0, current_height))
|
||||
current_height += img.h
|
||||
A.save(help_image)
|
||||
# 详细帮助生成完毕
|
||||
# 简易帮助图片合成
|
||||
height = 0
|
||||
width = 0
|
||||
for img in simple_help_img_list:
|
||||
if img.h > height:
|
||||
height = img.h
|
||||
width += img.w + 10
|
||||
image_group, h = group_image(simple_help_img_list)
|
||||
B = await build_help_image(image_group, h)
|
||||
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
|
||||
B.paste(
|
||||
BuildImage(
|
||||
0,
|
||||
0,
|
||||
plain_text="注: 红字代表功能被群管理员禁用,红线代表功能正在维护",
|
||||
font_size=24,
|
||||
font="HYWenHei-85W.ttf",
|
||||
font_color=(231, 74, 57)
|
||||
),
|
||||
(300, 10),
|
||||
True,
|
||||
)
|
||||
B.save(simple_help_image)
|
||||
(await HelpImageBuild().build_image(group_id)).save(help_image)
|
||||
|
||||
|
||||
def get_plugin_help(msg: str, is_super: bool = False) -> Optional[str]:
|
||||
@ -280,7 +39,9 @@ def get_plugin_help(msg: str, is_super: bool = False) -> Optional[str]:
|
||||
:param msg: 功能cmd
|
||||
:param is_super: 是否为超级用户
|
||||
"""
|
||||
module = plugins2settings_manager.get_plugin_module(msg) or admin_manager.get_plugin_module(msg)
|
||||
module = plugins2settings_manager.get_plugin_module(
|
||||
msg
|
||||
) or admin_manager.get_plugin_module(msg)
|
||||
if module:
|
||||
try:
|
||||
plugin = nonebot.plugin.get_plugin(module)
|
||||
@ -291,7 +52,11 @@ def get_plugin_help(msg: str, is_super: bool = False) -> Optional[str]:
|
||||
"__plugin_superuser_usage__"
|
||||
)
|
||||
else:
|
||||
result = metadata.usage if metadata else plugin.module.__getattribute__("__plugin_usage__")
|
||||
result = (
|
||||
metadata.usage
|
||||
if metadata
|
||||
else plugin.module.__getattribute__("__plugin_usage__")
|
||||
)
|
||||
if result:
|
||||
width = 0
|
||||
for x in result.split("\n"):
|
||||
|
||||
@ -1,28 +1,15 @@
|
||||
from typing import List, Tuple, Dict, Optional, Union
|
||||
from typing import List, Tuple, Dict, Optional
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from utils.image_utils import BuildImage
|
||||
from pydantic import BaseModel
|
||||
from configs.config import Config
|
||||
import os
|
||||
import random
|
||||
|
||||
from utils.manager import plugin_data_manager, group_manager
|
||||
from utils.manager.models import PluginData, PluginType
|
||||
|
||||
background_path = IMAGE_PATH / "background" / "help" / "simple_help"
|
||||
|
||||
# class PluginType(BaseModel):
|
||||
#
|
||||
#
|
||||
# class Plugin(BaseModel):
|
||||
# name: str
|
||||
# plugin_type: PluginType # 插件内部类型,根据name [Hidden] [Admin] [SUPERUSER]
|
||||
# usage: Optional[str]
|
||||
# des: Optional[str]
|
||||
# cmd: Optional[List[str]]
|
||||
# task: Optional[Dict[str, str]]
|
||||
# type: Optional[Tuple[str, int]] # 菜单类型
|
||||
# version: Optional[Union[str, int]]
|
||||
# author: Optional[str]
|
||||
|
||||
|
||||
|
||||
|
||||
async def build_help_image(image_group: List[List[BuildImage]], h: int):
|
||||
bk = None
|
||||
@ -36,6 +23,7 @@ async def build_help_image(image_group: List[List[BuildImage]], h: int):
|
||||
color="#FFEFD5",
|
||||
background=(background_path / bk) if bk else None,
|
||||
)
|
||||
A.filter("GaussianBlur", 5)
|
||||
curr_w = 50
|
||||
for ig in image_group:
|
||||
curr_h = 180
|
||||
@ -121,8 +109,145 @@ def group_image(image_list: List[BuildImage]) -> Tuple[List[List[BuildImage]], i
|
||||
return image_group, max(max_h + 250, max_w + 70)
|
||||
|
||||
|
||||
# class HelpImageBuild:
|
||||
#
|
||||
# def __init__(self):
|
||||
# self._data: Dict[str, List[]] = {}
|
||||
class HelpImageBuild:
|
||||
|
||||
build: Optional["HelpImageBuild"] = None
|
||||
|
||||
def __init__(self):
|
||||
self._data: Dict[str, PluginData] = plugin_data_manager.get_data()
|
||||
self._sort_data: Dict[str, List[PluginData]] = {}
|
||||
self._image_list = []
|
||||
|
||||
def __new__(cls, *args, **kwargs):
|
||||
if not cls.build:
|
||||
cls.build = super().__new__(cls)
|
||||
return cls.build
|
||||
|
||||
def sort_type(self):
|
||||
"""
|
||||
说明:
|
||||
对插件按照菜单类型分类
|
||||
"""
|
||||
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_name_image(
|
||||
self, max_width: int, name: str, color: str, text_color: Tuple[int, int, int], pos: Optional[Tuple[int, int, int, int]]
|
||||
) -> BuildImage:
|
||||
image = BuildImage(max_width - 5, 50, color=color, font_size=24)
|
||||
await image.acircle_corner()
|
||||
await image.atext((0, 0), name, text_color, center_type="center")
|
||||
return image
|
||||
|
||||
async def build_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"]
|
||||
):
|
||||
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_help_image(image_group, h)
|
||||
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
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import random
|
||||
from types import ModuleType
|
||||
from typing import Any
|
||||
|
||||
@ -7,7 +8,7 @@ from utils.manager import (
|
||||
plugins2settings_manager,
|
||||
plugins2cd_manager,
|
||||
plugins2block_manager,
|
||||
plugins2count_manager,
|
||||
plugins2count_manager, plugins_manager,
|
||||
)
|
||||
from configs.config import Config
|
||||
from utils.manager.models import (
|
||||
@ -16,7 +17,7 @@ from utils.manager.models import (
|
||||
PluginCd,
|
||||
PluginData,
|
||||
PluginBlock,
|
||||
PluginCount,
|
||||
PluginCount, Plugin,
|
||||
)
|
||||
from utils.utils import get_matchers
|
||||
|
||||
@ -99,6 +100,13 @@ def init_plugin_info():
|
||||
plugin_count = plugin_count_limit
|
||||
if plugin_cfg := Config.get(plugin_model):
|
||||
plugin_configs = plugin_cfg
|
||||
plugin_status = plugins_manager.get(plugin_model)
|
||||
if not plugin_status:
|
||||
plugin_status = Plugin(
|
||||
plugin_name=plugin_model
|
||||
)
|
||||
plugin_status.author = plugin_author
|
||||
plugin_status.version = plugin_version
|
||||
plugin_data = PluginData(
|
||||
model=plugin_model,
|
||||
name=plugin_name.strip(),
|
||||
@ -107,14 +115,13 @@ def init_plugin_info():
|
||||
des=plugin_des,
|
||||
task=plugin_task,
|
||||
menu_type=menu_type,
|
||||
version=plugin_version,
|
||||
author=plugin_author,
|
||||
plugin_setting=plugin_setting,
|
||||
plugin_cd=plugin_cd,
|
||||
plugin_block=plugin_block,
|
||||
plugin_count=plugin_count,
|
||||
plugin_resources=plugin_resources,
|
||||
plugin_configs=plugin_configs,
|
||||
plugin_status=plugin_status
|
||||
)
|
||||
plugin_data_manager.add_plugin_info(plugin_data)
|
||||
except Exception as e:
|
||||
|
||||
@ -23,15 +23,15 @@ def init_plugins_config():
|
||||
if plugin_data := plugin_data_manager.get(matcher.plugin_name):
|
||||
# 插件配置版本更新或为Version为None或不在存储配置内,当使用metadata时,必定更新
|
||||
if plugin_data.plugin_configs and (
|
||||
isinstance(plugin_data.version, str)
|
||||
isinstance(plugin_data.plugin_status.version, str)
|
||||
or (
|
||||
plugin_data.version is None
|
||||
plugin_data.plugin_status.version is None
|
||||
or (
|
||||
_data.get(matcher.plugin_name)
|
||||
and _data[matcher.plugin_name].keys()
|
||||
!= plugin_data.plugin_configs.keys()
|
||||
)
|
||||
or plugin_data.version
|
||||
or plugin_data.plugin_status.version
|
||||
> plugins_manager.get(matcher.plugin_name).version
|
||||
or matcher.plugin_name not in _data.keys()
|
||||
)
|
||||
|
||||
@ -33,9 +33,9 @@ def init_plugins_data():
|
||||
else:
|
||||
if plugin_data := plugin_data_manager.get(matcher.plugin_name):
|
||||
try:
|
||||
plugin_version = plugin_data.version
|
||||
plugin_version = plugin_data.plugin_status.version
|
||||
plugin_name = plugin_data.name
|
||||
plugin_author = plugin_data.author
|
||||
plugin_author = plugin_data.plugin_status.author
|
||||
if matcher.plugin_name in plugins_manager.keys():
|
||||
plugins_manager[matcher.plugin_name].error = False
|
||||
if matcher.plugin_name not in plugins_manager.keys():
|
||||
|
||||
@ -449,7 +449,7 @@ class BuildImage:
|
||||
说明:
|
||||
显示图片
|
||||
"""
|
||||
self.markImg.show(self.markImg)
|
||||
self.markImg.show()
|
||||
|
||||
async def aresize(self, ratio: float = 0, w: int = 0, h: int = 0):
|
||||
"""
|
||||
@ -693,22 +693,26 @@ class BuildImage:
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
async def acircle_corner(self, radii: int = 30):
|
||||
async def acircle_corner(self, radii: int = 30, point_list: List[Literal["lt", "rt", "lb", "lr"]] = None):
|
||||
"""
|
||||
说明:
|
||||
异步 矩形四角变圆
|
||||
参数:
|
||||
:param radii: 半径
|
||||
:param point_list: 需要变化的角
|
||||
"""
|
||||
await self.loop.run_in_executor(None, self.circle_corner, radii)
|
||||
await self.loop.run_in_executor(None, self.circle_corner, radii, point_list)
|
||||
|
||||
def circle_corner(self, radii: int = 30):
|
||||
def circle_corner(self, radii: int = 30, point_list: List[Literal["lt", "rt", "lb", "lr"]] = None):
|
||||
"""
|
||||
说明:
|
||||
矩形四角变圆
|
||||
参数:
|
||||
:param radii: 半径
|
||||
:param point_list: 需要变化的角
|
||||
"""
|
||||
if not point_list:
|
||||
point_list = ["lt", "rt", "lb", "rb"]
|
||||
# 画圆(用于分离4个角)
|
||||
circle = Image.new("L", (radii * 2, radii * 2), 0)
|
||||
draw = ImageDraw.Draw(circle)
|
||||
@ -716,13 +720,18 @@ class BuildImage:
|
||||
self.markImg = self.markImg.convert("RGBA")
|
||||
w, h = self.markImg.size
|
||||
alpha = Image.new("L", self.markImg.size, 255)
|
||||
alpha.paste(circle.crop((0, 0, radii, radii)), (0, 0))
|
||||
alpha.paste(circle.crop((radii, 0, radii * 2, radii)), (w - radii, 0))
|
||||
alpha.paste(
|
||||
circle.crop((radii, radii, radii * 2, radii * 2)), (w - radii, h - radii)
|
||||
)
|
||||
alpha.paste(circle.crop((0, radii, radii, radii * 2)), (0, h - radii))
|
||||
if "lt" in point_list:
|
||||
alpha.paste(circle.crop((0, 0, radii, radii)), (0, 0))
|
||||
if "rt" in point_list:
|
||||
alpha.paste(circle.crop((radii, 0, radii * 2, radii)), (w - radii, 0))
|
||||
if "lb" in point_list:
|
||||
alpha.paste(circle.crop((0, radii, radii, radii * 2)), (0, h - radii))
|
||||
if "rb" in point_list:
|
||||
alpha.paste(
|
||||
circle.crop((radii, radii, radii * 2, radii * 2)), (w - radii, h - radii)
|
||||
)
|
||||
self.markImg.putalpha(alpha)
|
||||
self.draw = ImageDraw.Draw(self.markImg)
|
||||
|
||||
async def arotate(self, angle: int, expand: bool = False):
|
||||
"""
|
||||
|
||||
@ -116,14 +116,13 @@ class PluginData(BaseModel):
|
||||
des: Optional[str]
|
||||
task: Optional[Dict[str, str]]
|
||||
menu_type: Tuple[Union[str, int], ...] = ("normal",) # 菜单类型
|
||||
version: Optional[Union[str, int]]
|
||||
author: Optional[str]
|
||||
plugin_setting: Optional[PluginSetting]
|
||||
plugin_cd: Optional[PluginCd]
|
||||
plugin_block: Optional[PluginBlock]
|
||||
plugin_count: Optional[PluginCount]
|
||||
plugin_resources: Optional[Dict[str, Union[str, Path]]]
|
||||
plugin_configs: Optional[Dict[str, Dict[str, Any]]]
|
||||
plugin_status: Plugin
|
||||
|
||||
class Config:
|
||||
arbitrary_types_allowed = True
|
||||
|
||||
@ -1,14 +1,16 @@
|
||||
from typing import Dict, Any
|
||||
from typing import Dict, Any, Optional
|
||||
|
||||
from . import StaticData
|
||||
from .models import PluginData
|
||||
|
||||
|
||||
class PluginDataManager:
|
||||
class PluginDataManager(StaticData):
|
||||
"""
|
||||
插件所有信息管理
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(None)
|
||||
self._data: Dict[str, PluginData] = {}
|
||||
|
||||
def add_plugin_info(self, info: PluginData):
|
||||
@ -28,8 +30,6 @@ class PluginDataManager:
|
||||
def __getitem__(self, item) -> PluginData:
|
||||
return self._data.get(item)
|
||||
|
||||
def __str__(self) -> str:
|
||||
return str(self._data)
|
||||
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user