From a3681216bde44543cacd525dbfe989eef0622939 Mon Sep 17 00:00:00 2001 From: HibiKier <775757368@qq.com> Date: Fri, 30 Aug 2024 23:50:45 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20=E7=88=B6=E7=BA=A7=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=E5=8A=A0=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- zhenxun/builtin_plugins/init/init_plugin.py | 115 ++++++++--------- .../builtin_plugins/plugin_store/__init__.py | 22 ++-- .../plugin_store/data_source.py | 4 +- zhenxun/configs/utils/__init__.py | 2 +- zhenxun/models/plugin_info.py | 13 +- zhenxun/utils/_build_image.py | 116 +++++++++--------- zhenxun/utils/_image_template.py | 20 ++- zhenxun/utils/enum.py | 2 + zhenxun/utils/message.py | 36 ++++-- 9 files changed, 177 insertions(+), 153 deletions(-) diff --git a/zhenxun/builtin_plugins/init/init_plugin.py b/zhenxun/builtin_plugins/init/init_plugin.py index 8581dafe..da018eac 100644 --- a/zhenxun/builtin_plugins/init/init_plugin.py +++ b/zhenxun/builtin_plugins/init/init_plugin.py @@ -2,9 +2,9 @@ import nonebot import aiofiles import ujson as json from ruamel.yaml import YAML -from nonebot.plugin import Plugin from nonebot.drivers import Driver from nonebot import get_loaded_plugins +from nonebot.plugin import Plugin, PluginMetadata from zhenxun.services.log import logger from zhenxun.models.task_info import TaskInfo @@ -41,64 +41,68 @@ async def _handle_setting( plugin_list: 插件列表 limit_list: 插件限制列表 """ - if metadata := plugin.metadata: - extra = metadata.extra - extra_data = PluginExtraData(**extra) - logger.debug(f"{metadata.name}:{plugin.name} -> {extra}", "初始化插件数据") - setting = extra_data.setting or PluginSetting() - if metadata.type == "library": - extra_data.plugin_type = PluginType.HIDDEN - if ( - extra_data.plugin_type - == PluginType.HIDDEN - # and extra_data.plugin_type != "功能" - ): - extra_data.menu_type = "" - plugin_list.append( - PluginInfo( + metadata = plugin.metadata + if not metadata: + if not plugin.sub_plugins: + return + """父插件""" + metadata = PluginMetadata(name=plugin.name, description="", usage="") + extra = metadata.extra + extra_data = PluginExtraData(**extra) + logger.debug(f"{metadata.name}:{plugin.name} -> {extra}", "初始化插件数据") + setting = extra_data.setting or PluginSetting() + if metadata.type == "library": + extra_data.plugin_type = PluginType.HIDDEN + if extra_data.plugin_type == PluginType.HIDDEN: + extra_data.menu_type = "" + if plugin.sub_plugins: + extra_data.plugin_type = PluginType.PARENT + plugin_list.append( + PluginInfo( + module=plugin.name, + module_path=plugin.module_name, + name=metadata.name, + author=extra_data.author, + version=extra_data.version, + level=setting.level, + default_status=setting.default_status, + limit_superuser=setting.limit_superuser, + menu_type=extra_data.menu_type, + cost_gold=setting.cost_gold, + plugin_type=extra_data.plugin_type, + admin_level=extra_data.admin_level, + parent=(plugin.parent_plugin.module_name if plugin.parent_plugin else None), + ) + ) + if extra_data.limits: + limit_list.extend( + PluginLimit( module=plugin.name, module_path=plugin.module_name, - name=metadata.name, - author=extra_data.author, - version=extra_data.version, - level=setting.level, - default_status=setting.default_status, - limit_superuser=setting.limit_superuser, - menu_type=extra_data.menu_type, - cost_gold=setting.cost_gold, - plugin_type=extra_data.plugin_type, - admin_level=extra_data.admin_level, + limit_type=limit._type, + watch_type=limit.watch_type, + status=limit.status, + check_type=limit.check_type, + result=limit.result, + cd=getattr(limit, "cd", None), + max_count=getattr(limit, "max_count", None), ) + for limit in extra_data.limits ) - if extra_data.limits: - limit_list.extend( - PluginLimit( - module=plugin.name, - module_path=plugin.module_name, - limit_type=limit._type, - watch_type=limit.watch_type, - status=limit.status, - check_type=limit.check_type, - result=limit.result, - cd=getattr(limit, "cd", None), - max_count=getattr(limit, "max_count", None), - ) - for limit in extra_data.limits - ) - if extra_data.tasks: - task_list.extend( - ( - task.create_status, - TaskInfo( - module=task.module, - name=task.name, - status=task.status, - run_time=task.run_time, - default_status=task.default_status, - ), - ) - for task in extra_data.tasks + if extra_data.tasks: + task_list.extend( + ( + task.create_status, + TaskInfo( + module=task.module, + name=task.name, + status=task.status, + run_time=task.run_time, + default_status=task.default_status, + ), ) + for task in extra_data.tasks + ) @driver.on_startup @@ -115,8 +119,7 @@ async def _(): module2id = {m["module_path"]: m["id"] for m in module_list} for plugin in get_loaded_plugins(): load_plugin.append(plugin.module_name) - if plugin.metadata: - await _handle_setting(plugin, plugin_list, limit_list, task_list) + await _handle_setting(plugin, plugin_list, limit_list, task_list) create_list = [] update_list = [] for plugin in plugin_list: diff --git a/zhenxun/builtin_plugins/plugin_store/__init__.py b/zhenxun/builtin_plugins/plugin_store/__init__.py index d9c2cc52..4ff8c940 100644 --- a/zhenxun/builtin_plugins/plugin_store/__init__.py +++ b/zhenxun/builtin_plugins/plugin_store/__init__.py @@ -1,12 +1,12 @@ from nonebot.permission import SUPERUSER from nonebot.plugin import PluginMetadata -from nonebot_plugin_alconna import Alconna, Args, Subcommand, on_alconna from nonebot_plugin_session import EventSession +from nonebot_plugin_alconna import Args, Alconna, Subcommand, on_alconna -from zhenxun.configs.utils import PluginExtraData from zhenxun.services.log import logger from zhenxun.utils.enum import PluginType from zhenxun.utils.message import MessageUtils +from zhenxun.configs.utils import PluginExtraData from .data_source import ShopManage @@ -68,6 +68,7 @@ _matcher.shortcut( prefix=True, ) + @_matcher.assign("$main") async def _(session: EventSession): try: @@ -82,9 +83,7 @@ async def _(session: EventSession): @_matcher.assign("add") async def _(session: EventSession, plugin_id: int): try: - await MessageUtils.build_message( - f"正在添加插件 Id: {plugin_id}" - ).send() + await MessageUtils.build_message(f"正在添加插件 Id: {plugin_id}").send() result = await ShopManage.add_plugin(plugin_id) except Exception as e: logger.error(f"添加插件 Id: {plugin_id}失败", "插件商店", session=session, e=e) @@ -107,24 +106,29 @@ async def _(session: EventSession, plugin_id: int): logger.info(f"移除插件 Id: {plugin_id}", "插件商店", session=session) await MessageUtils.build_message(result).send() + @_matcher.assign("search") async def _(session: EventSession, plugin_name_or_author: str): try: result = await ShopManage.search_plugin(plugin_name_or_author) except Exception as e: - logger.error(f"搜索插件 name: {plugin_name_or_author}失败", "插件商店", session=session, e=e) + logger.error( + f"搜索插件 name: {plugin_name_or_author}失败", + "插件商店", + session=session, + e=e, + ) await MessageUtils.build_message( f"搜索插件 name: {plugin_name_or_author} 失败 e: {e}" ).finish() logger.info(f"搜索插件 name: {plugin_name_or_author}", "插件商店", session=session) await MessageUtils.build_message(result).send() + @_matcher.assign("update") async def _(session: EventSession, plugin_id: int): try: - await MessageUtils.build_message( - f"正在更新插件 Id: {plugin_id}" - ).send() + await MessageUtils.build_message(f"正在更新插件 Id: {plugin_id}").send() result = await ShopManage.update_plugin(plugin_id) except Exception as e: logger.error(f"更新插件 Id: {plugin_id}失败", "插件商店", session=session, e=e) diff --git a/zhenxun/builtin_plugins/plugin_store/data_source.py b/zhenxun/builtin_plugins/plugin_store/data_source.py index 5b20ddfd..bc8ff412 100644 --- a/zhenxun/builtin_plugins/plugin_store/data_source.py +++ b/zhenxun/builtin_plugins/plugin_store/data_source.py @@ -211,7 +211,7 @@ class ShopManage: plugin_list = await PluginInfo.filter(load_status=True).values_list( "module", "version" ) - suc_plugin = {p[0]: p[1] for p in plugin_list if p[1]} + suc_plugin = {p[0]: (p[1] or "0.1") for p in plugin_list} data_list = [ [ "已安装" if plugin_info[1]["module"] in suc_plugin else "", @@ -226,7 +226,7 @@ class ShopManage: ] return await ImageTemplate.table_page( "插件列表", - "通过安装/卸载插件 ID 来管理插件", + "通过添加/移除插件 ID 来管理插件", column_name, data_list, text_style=row_style, diff --git a/zhenxun/configs/utils/__init__.py b/zhenxun/configs/utils/__init__.py index 3277222c..d23549bb 100644 --- a/zhenxun/configs/utils/__init__.py +++ b/zhenxun/configs/utils/__init__.py @@ -356,7 +356,7 @@ class ConfigsManager: value = default logger.debug( f"获取配置 MODULE: [{module}] | " - " KEY: [{key}] -> [{value}]" + f" KEY: [{key}] -> [{value}]" ) return value diff --git a/zhenxun/models/plugin_info.py b/zhenxun/models/plugin_info.py index e5eb1b21..964dabad 100644 --- a/zhenxun/models/plugin_info.py +++ b/zhenxun/models/plugin_info.py @@ -2,8 +2,7 @@ from tortoise import fields from zhenxun.services.db_context import Model from zhenxun.utils.enum import BlockType, PluginType - -from .plugin_limit import PluginLimit +from zhenxun.models.plugin_limit import PluginLimit # noqa: F401 class PluginInfo(Model): @@ -45,7 +44,15 @@ class PluginInfo(Model): """调用所需权限等级""" is_delete = fields.BooleanField(default=False, description="是否删除") """是否删除""" + parent = fields.CharField(max_length=255, null=True, description="父插件") + """父插件""" - class Meta: + class Meta: # type: ignore table = "plugin_info" table_description = "插件基本信息" + + @classmethod + async def _run_script(cls): + return [ + "ALTER TABLE plugin_info ADD COLUMN parent character varying(255);", + ] diff --git a/zhenxun/utils/_build_image.py b/zhenxun/utils/_build_image.py index 0f12b1e3..7f353d4b 100644 --- a/zhenxun/utils/_build_image.py +++ b/zhenxun/utils/_build_image.py @@ -1,15 +1,17 @@ -import base64 import math import uuid +import base64 +import itertools +import contextlib from io import BytesIO from pathlib import Path -from typing import Literal, Tuple, TypeAlias, overload +from typing_extensions import Self +from typing import Literal, TypeAlias, overload from nonebot.utils import run_sync -from PIL import Image, ImageDraw, ImageFilter, ImageFont from PIL.Image import Image as tImage from PIL.ImageFont import FreeTypeFont -from typing_extensions import Self +from PIL import Image, ImageDraw, ImageFont, ImageFilter from zhenxun.configs.path_config import FONT_PATH @@ -18,7 +20,7 @@ ModeType = Literal[ ] """图片类型""" -ColorAlias: TypeAlias = str | Tuple[int, int, int] | Tuple[int, int, int, int] | None +ColorAlias: TypeAlias = str | tuple[int, int, int] | tuple[int, int, int, int] | None CenterType = Literal["center", "height", "width"] """ @@ -52,9 +54,7 @@ class BuildImage: self.height = height self.color = color self.font = ( - self.load_font(font, font_size) - if not isinstance(font, FreeTypeFont) - else font + font if isinstance(font, FreeTypeFont) else self.load_font(font, font_size) ) if background: if isinstance(background, bytes): @@ -66,14 +66,14 @@ class BuildImage: else: self.width = self.markImg.width self.height = self.markImg.height - else: - if not width or not height: - raise ValueError("长度和宽度不能为空...") + elif width and height: self.markImg = Image.new(mode, (width, height), color) # type: ignore + else: + raise ValueError("长度和宽度不能为空...") self.draw = ImageDraw.Draw(self.markImg) @property - def size(self) -> Tuple[int, int]: + def size(self) -> tuple[int, int]: return self.markImg.size @classmethod @@ -94,9 +94,9 @@ class BuildImage: text: str, font: str | FreeTypeFont | Path = "HYWenHei-85W.ttf", size: int = 10, - font_color: str | Tuple[int, int, int] = (0, 0, 0), + font_color: str | tuple[int, int, int] = (0, 0, 0), color: ColorAlias = None, - padding: int | Tuple[int, int, int, int] | None = None, + padding: int | tuple[int, int, int, int] | None = None, ) -> Self: """构建文本图片 @@ -116,7 +116,7 @@ class BuildImage: _font = None if isinstance(font, FreeTypeFont): _font = font - elif isinstance(font, (str, Path)): + elif isinstance(font, str | Path): _font = cls.load_font(font, size) width, height = cls.get_text_size(text, _font) if isinstance(padding, int): @@ -161,7 +161,7 @@ class BuildImage: row_count = math.ceil(len(img_list) / row) if row_count == 1: background_width = ( - sum([img.width for img in img_list]) + space * (row - 1) + padding * 2 + sum(img.width for img in img_list) + space * (row - 1) + padding * 2 ) background_height = height * row_count + space * (row_count - 1) + padding * 2 background_image = cls( @@ -189,20 +189,20 @@ class BuildImage: 返回: FreeTypeFont: 字体 """ - path = FONT_PATH / font if type(font) == str else font + path = FONT_PATH / font if type(font) is str else font return ImageFont.truetype(str(path), font_size) @overload @classmethod def get_text_size( cls, text: str, font: FreeTypeFont | None = None - ) -> Tuple[int, int]: ... + ) -> tuple[int, int]: ... @overload @classmethod def get_text_size( cls, text: str, font: str | None = None, font_size: int = 10 - ) -> Tuple[int, int]: ... + ) -> tuple[int, int]: ... @classmethod def get_text_size( @@ -210,7 +210,7 @@ class BuildImage: text: str, font: str | FreeTypeFont | None = "HYWenHei-85W.ttf", font_size: int = 10, - ) -> Tuple[int, int]: + ) -> tuple[int, int]: # sourcery skip: remove-unnecessary-cast """获取该字体下文本需要的长宽 参数: @@ -219,10 +219,10 @@ class BuildImage: font_size: 字体大小 返回: - Tuple[int, int]: 长宽 + tuple[int, int]: 长宽 """ _font = font - if font and type(font) == str: + if font and type(font) is str: _font = cls.load_font(font, font_size) temp_image = Image.new("RGB", (1, 1), (255, 255, 255)) draw = ImageDraw.Draw(temp_image) @@ -232,7 +232,8 @@ class BuildImage: return text_width, text_height + 10 # return _font.getsize(str(text)) # type: ignore - def getsize(self, msg: str) -> Tuple[int, int]: + def getsize(self, msg: str) -> tuple[int, int]: + # sourcery skip: remove-unnecessary-cast """ 获取文字在该图片 font_size 下所需要的空间 @@ -240,7 +241,7 @@ class BuildImage: msg: 文本 返回: - Tuple[int, int]: 长宽 + tuple[int, int]: 长宽 """ temp_image = Image.new("RGB", (1, 1), (255, 255, 255)) draw = ImageDraw.Draw(temp_image) @@ -252,11 +253,11 @@ class BuildImage: def __center_xy( self, - pos: Tuple[int, int], + pos: tuple[int, int], width: int, height: int, center_type: CenterType | None, - ) -> Tuple[int, int]: + ) -> tuple[int, int]: """ 根据居中类型定位xy @@ -266,7 +267,7 @@ class BuildImage: center_type: 居中类型 返回: - Tuple[int, int]: 定位 + tuple[int, int]: 定位 """ # _width, _height = pos if self.width and self.height: @@ -285,7 +286,7 @@ class BuildImage: def paste( self, image: Self | tImage, - pos: Tuple[int, int] = (0, 0), + pos: tuple[int, int] = (0, 0), center_type: CenterType | None = None, ) -> Self: """贴图 @@ -303,7 +304,6 @@ class BuildImage: """ if center_type and center_type not in ["center", "height", "width"]: raise ValueError("center_type must be 'center', 'width' or 'height'") - width, height = 0, 0 _image = image if isinstance(image, BuildImage): _image = image.markImg @@ -317,7 +317,7 @@ class BuildImage: @run_sync def point( - self, pos: Tuple[int, int], fill: Tuple[int, int, int] | None = None + self, pos: tuple[int, int], fill: tuple[int, int, int] | None = None ) -> Self: """ 绘制多个或单独的像素 @@ -335,9 +335,9 @@ class BuildImage: @run_sync def ellipse( self, - pos: Tuple[int, int, int, int], - fill: Tuple[int, int, int] | None = None, - outline: Tuple[int, int, int] | None = None, + pos: tuple[int, int, int, int], + fill: tuple[int, int, int] | None = None, + outline: tuple[int, int, int] | None = None, width: int = 1, ) -> Self: """ @@ -358,13 +358,13 @@ class BuildImage: @run_sync def text( self, - pos: Tuple[int, int], + pos: tuple[int, int], text: str, - fill: str | Tuple[int, int, int] = (0, 0, 0), + fill: str | tuple[int, int, int] = (0, 0, 0), center_type: CenterType | None = None, font: FreeTypeFont | str | Path | None = None, font_size: int = 10, - ) -> Self: + ) -> Self: # sourcery skip: remove-unnecessary-cast """ 在图片上添加文字 @@ -382,11 +382,10 @@ class BuildImage: 异常: ValueError: 居中类型错误 """ - text = str(text) if center_type and center_type not in ["center", "height", "width"]: raise ValueError("center_type must be 'center', 'width' or 'height'") max_length_text = "" - sentence = text.split("\n") + sentence = str(text).split("\n") for x in sentence: max_length_text = x if len(x) > len(max_length_text) else max_length_text if font: @@ -398,7 +397,7 @@ class BuildImage: ttf_w, ttf_h = self.getsize(max_length_text) # type: ignore # ttf_h = ttf_h * len(sentence) pos = self.__center_xy(pos, ttf_w, ttf_h, center_type) - self.draw.text(pos, text, fill=fill, font=font) + self.draw.text(pos, str(text), fill=fill, font=font) return self @run_sync @@ -437,7 +436,7 @@ class BuildImage: if not width and not height and not ratio: raise ValueError("缺少参数...") if self.width and self.height: - if not width and not height and ratio: + if not width and not height: width = int(self.width * ratio) height = int(self.height * ratio) self.markImg = self.markImg.resize((width, height), Image.LANCZOS) # type: ignore @@ -446,7 +445,7 @@ class BuildImage: return self @run_sync - def crop(self, box: Tuple[int, int, int, int]) -> Self: + def crop(self, box: tuple[int, int, int, int]) -> Self: """ 裁剪图片 @@ -475,11 +474,10 @@ class BuildImage: """ self.markImg = self.markImg.convert("RGBA") x, y = self.markImg.size - for i in range(n, x - n): - for k in range(n, y - n): - color = self.markImg.getpixel((i, k)) - color = color[:-1] + (int(100 * alpha_ratio),) - self.markImg.putpixel((i, k), color) + for i, k in itertools.product(range(n, x - n), range(n, y - n)): + color = self.markImg.getpixel((i, k)) + color = color[:-1] + (int(100 * alpha_ratio),) + self.markImg.putpixel((i, k), color) self.draw = ImageDraw.Draw(self.markImg) return self @@ -492,7 +490,7 @@ class BuildImage: buf = BytesIO() self.markImg.save(buf, format="PNG") base64_str = base64.b64encode(buf.getvalue()).decode() - return "base64://" + base64_str + return f"base64://{base64_str}" def pic2bytes(self) -> bytes: """获取bytes @@ -520,8 +518,8 @@ class BuildImage: @run_sync def rectangle( self, - xy: Tuple[int, int, int, int], - fill: Tuple[int, int, int] | None = None, + xy: tuple[int, int, int, int], + fill: tuple[int, int, int] | None = None, outline: str | None = None, width: int = 1, ) -> Self: @@ -543,8 +541,8 @@ class BuildImage: @run_sync def polygon( self, - xy: list[Tuple[int, int]], - fill: Tuple[int, int, int] = (0, 0, 0), + xy: list[tuple[int, int]], + fill: tuple[int, int, int] = (0, 0, 0), outline: int = 1, ) -> Self: """ @@ -564,8 +562,8 @@ class BuildImage: @run_sync def line( self, - xy: Tuple[int, int, int, int], - fill: Tuple[int, int, int] | str = "#D8DEE4", + xy: tuple[int, int, int, int], + fill: tuple[int, int, int] | str = "#D8DEE4", width: int = 1, ) -> Self: """ @@ -605,21 +603,19 @@ class BuildImage: ) draw = ImageDraw.Draw(mask) for offset, fill in (width / -2.0, "black"), (width / 2.0, "white"): - left, top = [(value + offset) * antialias for value in ellipse_box[:2]] - right, bottom = [(value - offset) * antialias for value in ellipse_box[2:]] + left, top = ((value + offset) * antialias for value in ellipse_box[:2]) + right, bottom = ((value - offset) * antialias for value in ellipse_box[2:]) draw.ellipse([left, top, right, bottom], fill=fill) mask = mask.resize(self.markImg.size, Image.LANCZOS) - try: + with contextlib.suppress(ValueError): self.markImg.putalpha(mask) - except ValueError: - pass return self @run_sync def circle_corner( self, radii: int = 30, - point_list: list[Literal["lt", "rt", "lb", "rb"]] = ["lt", "rt", "lb", "rb"], + point_list: list[Literal["lt", "rt", "lb", "rb"]] | None = None, ) -> Self: """ 矩形四角变圆 @@ -631,6 +627,8 @@ class BuildImage: 返回: BuildImage: Self """ + if point_list is None: + point_list = ["lt", "rt", "lb", "rb"] # 画圆(用于分离4个角) img = self.markImg.convert("RGBA") alpha = img.split()[-1] diff --git a/zhenxun/utils/_image_template.py b/zhenxun/utils/_image_template.py index e989accc..a1d4c01b 100644 --- a/zhenxun/utils/_image_template.py +++ b/zhenxun/utils/_image_template.py @@ -1,11 +1,10 @@ import random from io import BytesIO from pathlib import Path -from typing import Any, Callable, Dict +from collections.abc import Callable -from fastapi import background -from PIL.ImageFont import FreeTypeFont from pydantic import BaseModel +from PIL.ImageFont import FreeTypeFont from ._build_image import BuildImage @@ -25,13 +24,13 @@ class RowStyle(BaseModel): class ImageTemplate: - color_list = ["#C2CEFE", "#FFA94C", "#3FE6A0", "#D1D4F5"] + color_list = ["#C2CEFE", "#FFA94C", "#3FE6A0", "#D1D4F5"] # noqa: RUF012 @classmethod async def hl_page( cls, head_text: str, - items: Dict[str, str], + items: dict[str, str], row_space: int = 10, padding: int = 30, ) -> BuildImage: @@ -162,9 +161,9 @@ class ImageTemplate: column_data = [] for i in range(len(column_name)): c = [] - for l in data_list: - if len(l) > i: - c.append(l[i]) + for lst in data_list: + if len(lst) > i: + c.append(lst[i]) else: c.append("") column_data.append(c) @@ -188,7 +187,7 @@ class ImageTemplate: column_name[i], font, 12, "#C8CCCF" ) column_name_image_list.append(column_name_image) - max_h = max([c.height for c in column_name_image_list]) + max_h = max(c.height for c in column_name_image_list) for i, data in enumerate(build_data_list): width = data["width"] + padding * 2 height = (base_h + row_space) * (len(data["data"]) + 1) + padding * 2 @@ -280,10 +279,9 @@ class ImageTemplate: width = 0 height = 0 _, h = BuildImage.get_text_size("A", font) - image_list = [] for s in text.split("\n"): s = s.strip() or "A" w, _ = BuildImage.get_text_size(s, font) - width = width if width > w else w + width = max(width, w) height += h return width, height diff --git a/zhenxun/utils/enum.py b/zhenxun/utils/enum.py index 86d41d13..c0b79342 100644 --- a/zhenxun/utils/enum.py +++ b/zhenxun/utils/enum.py @@ -42,6 +42,8 @@ class PluginType(StrEnum): """依赖插件,一般为没有主动触发命令的插件,受权限控制""" HIDDEN = "HIDDEN" """隐藏插件,一般为没有主动触发命令的插件,不受权限控制,如消息统计""" + PARENT = "PARENT" + """父插件,仅仅标记""" class BlockType(StrEnum): diff --git a/zhenxun/utils/message.py b/zhenxun/utils/message.py index eb6549f2..7ad586fd 100644 --- a/zhenxun/utils/message.py +++ b/zhenxun/utils/message.py @@ -2,20 +2,36 @@ from io import BytesIO from pathlib import Path import nonebot +from pydantic import BaseModel from nonebot.adapters.onebot.v11 import Message, MessageSegment -from nonebot_plugin_alconna import At, Image, Text, UniMessage +from nonebot_plugin_alconna import At, Text, Image, Video, Voice, UniMessage -from zhenxun.configs.config import BotConfig from zhenxun.services.log import logger +from zhenxun.configs.config import BotConfig from zhenxun.utils._build_image import BuildImage driver = nonebot.get_driver() MESSAGE_TYPE = ( - str | int | float | Path | bytes | BytesIO | BuildImage | At | Image | Text + str + | int + | float + | Path + | bytes + | BytesIO + | BuildImage + | At + | Image + | Text + | Voice + | Video ) +class Config(BaseModel): + is_bytes: bool = False + + class MessageUtils: @classmethod @@ -28,20 +44,16 @@ class MessageUtils: 返回: list[Text | Text]: 构造完成的消息列表 """ - is_bytes = False - try: - is_bytes = driver.config.image_to_bytes in ["True", "true"] - except AttributeError: - pass + config = nonebot.get_plugin_config(Config) message_list = [] for msg in msg_list: - if isinstance(msg, (Image, Text, At)): + if isinstance(msg, Image | Text | At | Video | Voice): message_list.append(msg) - elif isinstance(msg, (str, int, float)): + elif isinstance(msg, str | int | float): message_list.append(Text(str(msg))) elif isinstance(msg, Path): if msg.exists(): - if is_bytes: + if config.is_bytes: image = BuildImage.open(msg) message_list.append(Image(raw=image.pic2bytes())) else: @@ -120,7 +132,7 @@ class MessageUtils: forward_data = [] for r_list in msg_list: s = "" - if isinstance(r_list, (UniMessage, list)): + if isinstance(r_list, UniMessage | list): for r in r_list: if isinstance(r, Text): s += str(r)