diff --git a/liteyuki/liteyuki_main/core.py b/liteyuki/liteyuki_main/core.py index cd3eb9f..afc5784 100644 --- a/liteyuki/liteyuki_main/core.py +++ b/liteyuki/liteyuki_main/core.py @@ -9,12 +9,12 @@ from nonebot.exception import MockApiException from nonebot.internal.matcher import Matcher from nonebot.permission import SUPERUSER -from liteyuki.utils.config import get_config, load_from_yaml -from liteyuki.utils.data_manager import StoredConfig, TempConfig, common_db -from liteyuki.utils.language import get_user_lang -from liteyuki.utils.ly_typing import T_Bot, T_MessageEvent -from liteyuki.utils.message import Markdown as md, broadcast_to_superusers -from liteyuki.utils.reloader import Reloader +from liteyuki.utils.base.config import get_config, load_from_yaml +from liteyuki.utils.base.data_manager import StoredConfig, TempConfig, common_db +from liteyuki.utils.base.language import get_user_lang +from liteyuki.utils.base.ly_typing import T_Bot, T_MessageEvent +from liteyuki.utils.message import * +from liteyuki.utils.base.reloader import Reloader from .api import update_liteyuki require("nonebot_plugin_alconna"), require("nonebot_plugin_apscheduler") diff --git a/liteyuki/liteyuki_main/loader.py b/liteyuki/liteyuki_main/loader.py index b31940d..9f19f7c 100644 --- a/liteyuki/liteyuki_main/loader.py +++ b/liteyuki/liteyuki_main/loader.py @@ -1,12 +1,9 @@ -import os.path -import shutil - import nonebot.plugin from liteyuki.utils import init_log -from liteyuki.utils.data_manager import InstalledPlugin, plugin_db -from liteyuki.utils.resource import load_resource_from_dir, load_resources -from liteyuki.utils.tools import check_for_package +from liteyuki.utils.base.data_manager import InstalledPlugin, plugin_db +from liteyuki.utils.base.resource import load_resources +from liteyuki.utils.message.tools import check_for_package load_resources() init_log() diff --git a/liteyuki/liteyuki_main/runtime.py b/liteyuki/liteyuki_main/runtime.py index 9e69aef..12ed990 100644 --- a/liteyuki/liteyuki_main/runtime.py +++ b/liteyuki/liteyuki_main/runtime.py @@ -1,4 +1,3 @@ -import json import platform import nonebot @@ -7,13 +6,12 @@ from cpuinfo import get_cpu_info from nonebot import on_command from nonebot.adapters.onebot.v11 import MessageSegment from nonebot.permission import SUPERUSER -from playwright.async_api import async_playwright from liteyuki.utils import __NAME__, __VERSION__, load_from_yaml -from liteyuki.utils.htmlrender import template2image -from liteyuki.utils.language import Language, get_default_lang, get_user_lang -from liteyuki.utils.ly_typing import T_Bot, T_MessageEvent -from liteyuki.utils.resource import get_path -from liteyuki.utils.tools import convert_size +from liteyuki.utils.message.html_tool import template2image +from liteyuki.utils.base.language import Language, get_default_lang, get_user_lang +from liteyuki.utils.base.ly_typing import T_Bot, T_MessageEvent +from liteyuki.utils.base.resource import get_path +from liteyuki.utils.message.tools import convert_size stats = on_command("status", aliases={"状态"}, priority=5, permission=SUPERUSER) diff --git a/liteyuki/plugins/liteyuki_eventpush.py b/liteyuki/plugins/liteyuki_eventpush.py index f93edd0..8196634 100644 --- a/liteyuki/plugins/liteyuki_eventpush.py +++ b/liteyuki/plugins/liteyuki_eventpush.py @@ -2,9 +2,9 @@ import nonebot from nonebot import on_message, require from nonebot.plugin import PluginMetadata -from liteyuki.utils.data import Database, LiteModel -from liteyuki.utils.ly_typing import T_Bot, T_MessageEvent -from liteyuki.utils.message import Markdown as md +from liteyuki.utils.base.data import Database, LiteModel +from liteyuki.utils.base.ly_typing import T_Bot, T_MessageEvent +from liteyuki.utils.message.message import MarkdownMessage as md require("nonebot_plugin_alconna") from nonebot_plugin_alconna import on_alconna diff --git a/liteyuki/plugins/liteyuki_markdowntest.py b/liteyuki/plugins/liteyuki_markdowntest.py index 4205320..c648590 100644 --- a/liteyuki/plugins/liteyuki_markdowntest.py +++ b/liteyuki/plugins/liteyuki_markdowntest.py @@ -1,13 +1,13 @@ -import nonebot from nonebot import on_command from nonebot.params import CommandArg from nonebot.permission import SUPERUSER from nonebot.plugin import PluginMetadata -from liteyuki.utils.ly_typing import T_Bot, T_MessageEvent, v11 -from liteyuki.utils.message import Markdown as md +from liteyuki.utils.base.ly_typing import T_Bot, T_MessageEvent, v11 +from liteyuki.utils.message.message import MarkdownMessage as md, broadcast_to_superusers -md_test = on_command("mdts", aliases={"会话md"}, permission=SUPERUSER) +md_test = on_command("mdts", permission=SUPERUSER) +btn_test = on_command("btnts", permission=SUPERUSER) placeholder = { "[": "[", @@ -28,6 +28,15 @@ async def _(bot: T_Bot, event: T_MessageEvent, arg: v11.Message = CommandArg()): session_id=event.user_id if event.message_type == "private" else event.group_id ) +@btn_test.handle() +async def _(bot: T_Bot, event: T_MessageEvent, arg: v11.Message = CommandArg()): + await md.send_btn( + str(arg), + bot, + message_type=event.message_type, + session_id=event.user_id if event.message_type == "private" else event.group_id + ) + __author__ = "snowykami" __plugin_meta__ = PluginMetadata( name="轻雪Markdown测试", diff --git a/liteyuki/plugins/liteyuki_minigame/game.py b/liteyuki/plugins/liteyuki_minigame/game.py index 64f46f0..f5b1e1c 100644 --- a/liteyuki/plugins/liteyuki_minigame/game.py +++ b/liteyuki/plugins/liteyuki_minigame/game.py @@ -1,6 +1,6 @@ import random from pydantic import BaseModel -from liteyuki.utils.message import Markdown as md +from liteyuki.utils.message.message import MarkdownMessage as md class Dot(BaseModel): diff --git a/liteyuki/plugins/liteyuki_minigame/minesweeper.py b/liteyuki/plugins/liteyuki_minigame/minesweeper.py index 004adbc..8fdece9 100644 --- a/liteyuki/plugins/liteyuki_minigame/minesweeper.py +++ b/liteyuki/plugins/liteyuki_minigame/minesweeper.py @@ -1,7 +1,7 @@ from nonebot import require -from ...utils.ly_typing import T_Bot, T_MessageEvent -from ...utils.message import Markdown as md +from liteyuki.utils.base.ly_typing import T_Bot, T_MessageEvent +from liteyuki.utils.message.message import MarkdownMessage as md require("nonebot_plugin_alconna") from .game import Minesweeper diff --git a/liteyuki/plugins/liteyuki_pacman/common.py b/liteyuki/plugins/liteyuki_pacman/common.py index f61fa5f..5a7b626 100644 --- a/liteyuki/plugins/liteyuki_pacman/common.py +++ b/liteyuki/plugins/liteyuki_pacman/common.py @@ -4,9 +4,9 @@ from typing import Optional import aiofiles import nonebot.plugin -from liteyuki.utils.data import LiteModel -from liteyuki.utils.data_manager import GlobalPlugin, Group, User, group_db, plugin_db, user_db -from liteyuki.utils.ly_typing import T_MessageEvent +from liteyuki.utils.base.data import LiteModel +from liteyuki.utils.base.data_manager import GlobalPlugin, Group, User, group_db, plugin_db, user_db +from liteyuki.utils.base.ly_typing import T_MessageEvent class PluginTag(LiteModel): diff --git a/liteyuki/plugins/liteyuki_pacman/npm.py b/liteyuki/plugins/liteyuki_pacman/npm.py index 3243257..8520207 100644 --- a/liteyuki/plugins/liteyuki_pacman/npm.py +++ b/liteyuki/plugins/liteyuki_pacman/npm.py @@ -12,12 +12,12 @@ from nonebot.internal.matcher import Matcher from nonebot.message import run_preprocessor from nonebot.permission import SUPERUSER from nonebot.plugin import Plugin -from liteyuki.utils.data_manager import InstalledPlugin -from liteyuki.utils.language import get_user_lang -from liteyuki.utils.ly_typing import T_Bot -from liteyuki.utils.message import Markdown as md -from liteyuki.utils.permission import GROUP_ADMIN, GROUP_OWNER -from liteyuki.utils.tools import clamp +from liteyuki.utils.base.data_manager import InstalledPlugin +from liteyuki.utils.base.language import get_user_lang +from liteyuki.utils.base.ly_typing import T_Bot +from liteyuki.utils.message.message import MarkdownMessage as md +from liteyuki.utils.base.permission import GROUP_ADMIN, GROUP_OWNER +from liteyuki.utils.message.tools import clamp from .common import * require("nonebot_plugin_alconna") diff --git a/liteyuki/plugins/liteyuki_pacman/rpm.py b/liteyuki/plugins/liteyuki_pacman/rpm.py index b2fb8e9..5c81027 100644 --- a/liteyuki/plugins/liteyuki_pacman/rpm.py +++ b/liteyuki/plugins/liteyuki_pacman/rpm.py @@ -1,16 +1,14 @@ # 轻雪资源包管理器 import os -import nonebot import yaml from nonebot import require from nonebot.permission import SUPERUSER -from liteyuki.utils.config import get_config -from liteyuki.utils.language import get_user_lang -from liteyuki.utils.ly_typing import T_Bot, T_MessageEvent -from liteyuki.utils.message import Markdown as md -from liteyuki.utils.resource import (ResourceMetadata, add_resource_pack, change_priority, check_exist, check_status, get_loaded_resource_packs, get_resource_metadata, load_resources, remove_resource_pack) +from liteyuki.utils.base.language import get_user_lang +from liteyuki.utils.base.ly_typing import T_Bot, T_MessageEvent +from liteyuki.utils.message.message import MarkdownMessage as md +from liteyuki.utils.base.resource import (ResourceMetadata, add_resource_pack, change_priority, check_exist, check_status, get_loaded_resource_packs, get_resource_metadata, load_resources, remove_resource_pack) require("nonebot_plugin_alconna") from nonebot_plugin_alconna import Alconna, Args, on_alconna, Arparma, Subcommand diff --git a/liteyuki/plugins/liteyuki_user/profile_manager.py b/liteyuki/plugins/liteyuki_user/profile_manager.py index 5091b0f..aef6879 100644 --- a/liteyuki/plugins/liteyuki_user/profile_manager.py +++ b/liteyuki/plugins/liteyuki_user/profile_manager.py @@ -3,11 +3,11 @@ from typing import Optional import pytz from nonebot import require -from liteyuki.utils.data import LiteModel -from liteyuki.utils.data_manager import User, user_db -from liteyuki.utils.language import Language, get_all_lang, get_user_lang -from liteyuki.utils.ly_typing import T_Bot, T_MessageEvent -from liteyuki.utils.message import Markdown as md +from liteyuki.utils.base.data import LiteModel +from liteyuki.utils.base.data_manager import User, user_db +from liteyuki.utils.base.language import Language, get_all_lang, get_user_lang +from liteyuki.utils.base.ly_typing import T_Bot, T_MessageEvent +from liteyuki.utils.message.message import MarkdownMessage as md from .const import representative_timezones_list require("nonebot_plugin_alconna") diff --git a/liteyuki/plugins/liteyuki_weather/models.py b/liteyuki/plugins/liteyuki_weather/models.py index bbc73c1..a3804c5 100644 --- a/liteyuki/plugins/liteyuki_weather/models.py +++ b/liteyuki/plugins/liteyuki_weather/models.py @@ -1,5 +1,4 @@ -from nonebot import on_command -from liteyuki.utils.data import LiteModel +from liteyuki.utils.base.data import LiteModel class Location(LiteModel): diff --git a/liteyuki/plugins/liteyuki_weather/qweather.py b/liteyuki/plugins/liteyuki_weather/qweather.py index d029ca7..9b88f2c 100644 --- a/liteyuki/plugins/liteyuki_weather/qweather.py +++ b/liteyuki/plugins/liteyuki_weather/qweather.py @@ -1,10 +1,9 @@ from nonebot import require -from jieba import lcut -from liteyuki.utils.ly_typing import T_MessageEvent +from liteyuki.utils.base.ly_typing import T_MessageEvent require("nonebot_plugin_alconna") -from nonebot_plugin_alconna import on_alconna, Alconna, Subcommand, Args, MultiVar, Arparma +from nonebot_plugin_alconna import on_alconna, Alconna, Args, MultiVar, Arparma @on_alconna( diff --git a/liteyuki/utils/__init__.py b/liteyuki/utils/__init__.py index 0c4bda8..9ee4e1e 100644 --- a/liteyuki/utils/__init__.py +++ b/liteyuki/utils/__init__.py @@ -10,9 +10,9 @@ __VERSION__ = "6.2.8" # 60201 import requests -from liteyuki.utils.config import load_from_yaml, config -from .log import init_log -from .data_manager import auto_migrate +from liteyuki.utils.base.config import load_from_yaml, config +from liteyuki.utils.base.log import init_log +from liteyuki.utils.base.data_manager import auto_migrate major, minor, patch = map(int, __VERSION__.split(".")) __VERSION_I__ = major * 10000 + minor * 100 + patch diff --git a/liteyuki/utils/plugin.py b/liteyuki/utils/base/__init__.py similarity index 100% rename from liteyuki/utils/plugin.py rename to liteyuki/utils/base/__init__.py diff --git a/liteyuki/utils/config.py b/liteyuki/utils/base/config.py similarity index 92% rename from liteyuki/utils/config.py rename to liteyuki/utils/base/config.py index 7a59149..641164c 100644 --- a/liteyuki/utils/config.py +++ b/liteyuki/utils/base/config.py @@ -4,9 +4,9 @@ import nonebot import yaml from pydantic import BaseModel -from liteyuki.utils.data_manager import StoredConfig, common_db -from liteyuki.utils.ly_typing import T_Bot -from liteyuki.utils.tools import random_hex_string +from .data_manager import StoredConfig, common_db +from .ly_typing import T_Bot +from ..message.tools import random_hex_string config = {} # 全局配置,确保加载后读取 diff --git a/liteyuki/utils/data.py b/liteyuki/utils/base/data.py similarity index 100% rename from liteyuki/utils/data.py rename to liteyuki/utils/base/data.py diff --git a/liteyuki/utils/data_manager.py b/liteyuki/utils/base/data_manager.py similarity index 97% rename from liteyuki/utils/data_manager.py rename to liteyuki/utils/base/data_manager.py index 4f12835..15d559d 100644 --- a/liteyuki/utils/data_manager.py +++ b/liteyuki/utils/base/data_manager.py @@ -2,7 +2,7 @@ import os from pydantic import Field -from liteyuki.utils.data import LiteModel, Database as DB +from .data import LiteModel, Database as DB DATA_PATH = "data/liteyuki" diff --git a/liteyuki/utils/language.py b/liteyuki/utils/base/language.py similarity index 100% rename from liteyuki/utils/language.py rename to liteyuki/utils/base/language.py diff --git a/liteyuki/utils/log.py b/liteyuki/utils/base/log.py similarity index 96% rename from liteyuki/utils/log.py rename to liteyuki/utils/base/log.py index 192951b..240ab21 100644 --- a/liteyuki/utils/log.py +++ b/liteyuki/utils/base/log.py @@ -2,13 +2,13 @@ import sys import loguru from typing import TYPE_CHECKING from .config import load_from_yaml -from .language import Language, get_default_lang +from .language import get_default_lang logger = loguru.logger if TYPE_CHECKING: # avoid sphinx autodoc resolve annotation failed # because loguru module do not have `Logger` class actually - from loguru import Logger, Record + from loguru import Record def default_filter(record: "Record"): diff --git a/liteyuki/utils/ly_api.py b/liteyuki/utils/base/ly_api.py similarity index 97% rename from liteyuki/utils/ly_api.py rename to liteyuki/utils/base/ly_api.py index e9e7ad9..d866d62 100644 --- a/liteyuki/utils/ly_api.py +++ b/liteyuki/utils/base/ly_api.py @@ -8,8 +8,8 @@ import psutil import requests from aiohttp import FormData -from . import __VERSION_I__, __VERSION__, __NAME__ -from .config import config, load_from_yaml +from .. import __VERSION_I__, __VERSION__, __NAME__ +from .config import load_from_yaml class LiteyukiAPI: diff --git a/liteyuki/utils/ly_typing.py b/liteyuki/utils/base/ly_typing.py similarity index 100% rename from liteyuki/utils/ly_typing.py rename to liteyuki/utils/base/ly_typing.py diff --git a/liteyuki/utils/permission.py b/liteyuki/utils/base/permission.py similarity index 57% rename from liteyuki/utils/permission.py rename to liteyuki/utils/base/permission.py index dbf092d..581e88c 100644 --- a/liteyuki/utils/permission.py +++ b/liteyuki/utils/base/permission.py @@ -1,7 +1,5 @@ from nonebot.adapters.onebot import v11 -from liteyuki.utils.ly_typing import T_GroupMessageEvent, T_MessageEvent - GROUP_ADMIN = v11.GROUP_ADMIN GROUP_OWNER = v11.GROUP_OWNER diff --git a/liteyuki/utils/reloader.py b/liteyuki/utils/base/reloader.py similarity index 100% rename from liteyuki/utils/reloader.py rename to liteyuki/utils/base/reloader.py diff --git a/liteyuki/utils/resource.py b/liteyuki/utils/base/resource.py similarity index 99% rename from liteyuki/utils/resource.py rename to liteyuki/utils/base/resource.py index eca08ff..462af8e 100644 --- a/liteyuki/utils/resource.py +++ b/liteyuki/utils/base/resource.py @@ -42,7 +42,7 @@ def load_resource_from_dir(path: str): metadata["path"] = path metadata["folder"] = os.path.basename(path) if os.path.exists(os.path.join(path, "lang")): - from liteyuki.utils.language import load_from_dir + from liteyuki.utils.base.language import load_from_dir load_from_dir(os.path.join(path, "lang")) _loaded_resource_packs.insert(0, ResourceMetadata(**metadata)) diff --git a/liteyuki/utils/message/__init__.py b/liteyuki/utils/message/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/liteyuki/utils/htmlrender.py b/liteyuki/utils/message/html_tool.py similarity index 100% rename from liteyuki/utils/htmlrender.py rename to liteyuki/utils/message/html_tool.py diff --git a/liteyuki/utils/message/markdown.py b/liteyuki/utils/message/markdown.py new file mode 100644 index 0000000..2e08f3b --- /dev/null +++ b/liteyuki/utils/message/markdown.py @@ -0,0 +1,186 @@ +import base64 +from io import BytesIO +from urllib.parse import quote + +import aiohttp +from PIL import Image + +from ..base.config import get_config +from ..base.ly_typing import T_Bot + + +def markdown_escape(text: str) -> str: + """ + 转义Markdown特殊字符 + Args: + text: str: 文本 + + Returns: + str: 转义后文本 + """ + text = text.replace("\n", r"\n").replace('"', r'\\\"') + spacial_chars = r"\`*_{}[]()#+-.!" + for char in spacial_chars: + text = text.replace(char, "\\" + char) + return text + + +def escape_decorator(func): + def wrapper(text: str): + return func(markdown_escape(text)) + + return wrapper + + +class MarkdownComponent: + @staticmethod + @escape_decorator + def heading(text: str, level: int = 1) -> str: + """标题""" + assert 1 <= level <= 6, "标题级别应在 1-6 之间" + return f"{'#' * level} {text}" + + @staticmethod + @escape_decorator + def bold(text: str) -> str: + """粗体""" + return f"**{text}**" + + @staticmethod + @escape_decorator + def italic(text: str) -> str: + """斜体""" + return f"*{text}*" + + @staticmethod + @escape_decorator + def strike(text: str) -> str: + """删除线""" + return f"~~{text}~~" + + @staticmethod + @escape_decorator + def code(text: str) -> str: + """行内代码""" + return f"`{text}`" + + @staticmethod + @escape_decorator + def code_block(text: str, language: str = "") -> str: + """代码块""" + return f"```{language}\n{text}\n```" + + @staticmethod + @escape_decorator + def quote(text: str) -> str: + """引用""" + return f"> {text}" + + @staticmethod + @escape_decorator + def link(text: str, url: str, symbol: bool = True) -> str: + """ + 链接 + + Args: + text: 链接文本 + url: 链接地址 + symbol: 是否显示链接图标, mqqapi请使用False + """ + return f"[{'🔗' if symbol else ''}{text}]({quote(url)})" + + @staticmethod + @escape_decorator + def image(url: str, *, size: tuple[int, int]) -> str: + """ + 图片,本地图片不建议直接使用 + Args: + url: 图片链接 + size: 图片大小 + + Returns: + markdown格式的图片 + """ + return f"![image #{size[0]}px #{size[1]}px]({url})" + + @staticmethod + @escape_decorator + async def auto_image(image: str | bytes, bot: T_Bot) -> str: + """ + 自动获取图片大小 + Args: + image: 本地图片路径 | 图片url http/file | 图片bytes + bot: bot对象,用于上传图片到图床 + + Returns: + markdown格式的图片 + """ + if isinstance(image, bytes): + # 传入为二进制图片 + image_obj = Image.open(BytesIO(image)) + base64_string = base64.b64encode(image_obj.tobytes()).decode("utf-8") + url = await bot.call_api("upload_image", file=f"base64://{base64_string}") + size = image_obj.size + elif isinstance(image, str): + # 传入链接或本地路径 + if image.startswith("http"): + # 网络请求 + async with aiohttp.ClientSession() as session: + async with session.get(image) as resp: + image_data = await resp.read() + url = image + size = Image.open(BytesIO(image_data)).size + + else: + # 本地路径/file:// + image_obj = Image.open(image.replace("file://", "")) + base64_string = base64.b64encode(image_obj.tobytes()).decode("utf-8") + url = await bot.call_api("upload_image", file=f"base64://{base64_string}") + size = image_obj.size + else: + raise ValueError("图片类型错误") + + return MarkdownComponent.image(url, size=size) + + @staticmethod + @escape_decorator + def table(data: list[list[any]]) -> str: + """ + 表格 + Args: + data: 表格数据,二维列表 + Returns: + markdown格式的表格 + """ + # 表头 + table = "|".join(map(str, data[0])) + "\n" + table += "|".join([":-:" for _ in range(len(data[0]))]) + "\n" + # 表内容 + for row in data[1:]: + table += "|".join(map(str, row)) + "\n" + return table + + +class Mqqapi: + @staticmethod + @escape_decorator + def cmd(text: str, cmd: str, enter: bool = True, reply: bool = False, use_cmd_start: bool = True) -> str: + """ + 生成点击回调文本 + Args: + text: 显示内容 + cmd: 命令 + enter: 是否自动发送 + reply: 是否回复 + use_cmd_start: 是否使用配置的命令前缀 + + Returns: + [text](mqqapi://) markdown格式的可点击回调文本,类似于链接 + """ + + if use_cmd_start: + command_start = get_config("command_start", []) + if command_start: + # 若命令前缀不为空,则使用配置的第一个命令前缀 + cmd = f"{command_start[0]}{cmd}" + return f"[{text}](mqqapi://aio/inlinecmd?command={quote(cmd)}&reply={str(reply).lower()}&enter={str(enter).lower()})" diff --git a/liteyuki/utils/message.py b/liteyuki/utils/message/message.py similarity index 81% rename from liteyuki/utils/message.py rename to liteyuki/utils/message/message.py index a612db8..84442be 100644 --- a/liteyuki/utils/message.py +++ b/liteyuki/utils/message/message.py @@ -1,4 +1,3 @@ -import asyncio import base64 import io from urllib.parse import quote @@ -8,12 +7,14 @@ from PIL import Image import aiohttp import nonebot from nonebot import require -from nonebot.adapters.onebot import v11, v12 -from typing import Any +from nonebot.adapters.onebot import v11 +from typing import Any, Type -from . import load_from_yaml -from .ly_api import liteyuki_api -from .ly_typing import T_Bot, T_Message, T_MessageEvent +from nonebot.internal.adapter import MessageSegment +from nonebot.internal.adapter.message import TM + +from .. import load_from_yaml +from ..base.ly_typing import T_Bot, T_Message, T_MessageEvent require("nonebot_plugin_htmlrender") from nonebot_plugin_htmlrender import md_to_pic @@ -28,12 +29,12 @@ async def broadcast_to_superusers(message: str | T_Message, markdown: bool = Fal for bot in nonebot.get_bots().values(): for user_id in config.get("superusers", []): if markdown: - await Markdown.send_md(message, bot, message_type="private", session_id=user_id) + await MarkdownMessage.send_md(message, bot, message_type="private", session_id=user_id) else: await bot.send_private_msg(user_id=user_id, message=message) -class Markdown: +class MarkdownMessage: @staticmethod async def send_md( markdown: str, @@ -158,8 +159,8 @@ class Markdown: if method == 2: base64_string = base64.b64encode(image).decode("utf-8") data = await bot.call_api("upload_image", file=f"base64://{base64_string}") - await Markdown.send_md(Markdown.image(data, Image.open(io.BytesIO(image)).size), bot, event=event, message_type=message_type, - session_id=session_id, **kwargs) + await MarkdownMessage.send_md(MarkdownMessage.image(data, Image.open(io.BytesIO(image)).size), bot, event=event, message_type=message_type, + session_id=session_id, **kwargs) # 其他实现端方案 else: @@ -171,8 +172,8 @@ class Markdown: ))["message_id"] image_url = (await bot.get_msg(message_id=image_message_id))["message"][0]["data"]["url"] image_size = Image.open(io.BytesIO(image)).size - image_md = Markdown.image(image_url, image_size) - return await Markdown.send_md(image_md, bot, message_type=message_type, session_id=session_id, event=event, **kwargs) + image_md = MarkdownMessage.image(image_url, image_size) + return await MarkdownMessage.send_md(image_md, bot, message_type=message_type, session_id=session_id, event=event, **kwargs) if data is None: data = await bot.send_msg( @@ -251,7 +252,7 @@ class Markdown: async with aiohttp.ClientSession() as session: async with session.get(url) as resp: image = Image.open(io.BytesIO(await resp.read())) - return Markdown.image(url, image.size) + return MarkdownMessage.image(url, image.size) except Exception as e: nonebot.logger.error(f"get image error: {e}") return "[Image Error]" @@ -270,58 +271,3 @@ class Markdown: for char in chars: text = text.replace(char, f"\\\\{char}") return text - - @staticmethod - def H1(text: str, end="\n") -> str: - """H1标题""" - return f"# {text}{end}" - - @staticmethod - def H2(text: str, end="\n") -> str: - """H2标题""" - return f"## {text}{end}" - - @staticmethod - def H3(text: str, end="\n") -> str: - """H3标题""" - return f"### {text}{end}" - - @staticmethod - def H4(text: str, end="\n") -> str: - """H4标题""" - return f"#### {text}{end}" - - @staticmethod - def H5(text: str, end="\n") -> str: - """H5标题""" - return f"##### {text}{end}" - - @staticmethod - def H6(text: str, end="\n") -> str: - """H6标题""" - return f"###### {text}{end}" - - @staticmethod - def Bold(text: str) -> str: - """加粗""" - return f"**{text}**" - - @staticmethod - def Italic(text: str) -> str: - """斜体""" - return f"*{text}*" - - @staticmethod - def BoldItalic(text: str) -> str: - """粗斜体""" - return f"***{text}***" - - @staticmethod - def Underline(text: str) -> str: - """下划线""" - return f"__{text}__" - - @staticmethod - def Strike(text: str) -> str: - """删除线""" - return f"~~{text}~~" diff --git a/liteyuki/utils/tools.py b/liteyuki/utils/message/tools.py similarity index 100% rename from liteyuki/utils/tools.py rename to liteyuki/utils/message/tools.py diff --git a/main.py b/main.py index 79459e5..7682997 100644 --- a/main.py +++ b/main.py @@ -1,12 +1,10 @@ -import os.path - import nonebot from nonebot.adapters.onebot import v11, v12 from liteyuki.utils import init -from liteyuki.utils.config import load_from_yaml -from liteyuki.utils.data_manager import StoredConfig, common_db -from liteyuki.utils.ly_api import liteyuki_api +from liteyuki.utils.base.config import load_from_yaml +from liteyuki.utils.base.data_manager import StoredConfig, common_db +from liteyuki.utils.base.ly_api import liteyuki_api init()