forked from bot/app
fix: 插件列表显示错误问题
This commit is contained in:
parent
ca0bfe0181
commit
de0c073c26
16
README.md
16
README.md
@ -14,18 +14,19 @@
|
|||||||
<div align=center><h4>轻量,高效,易于扩展</h4></div>
|
<div align=center><h4>轻量,高效,易于扩展</h4></div>
|
||||||
|
|
||||||
- 基于[Nonebot2]("https://github.com/nonebot/nonebot2"),有良好的生态支持
|
- 基于[Nonebot2]("https://github.com/nonebot/nonebot2"),有良好的生态支持
|
||||||
- 集成了上一代轻雪的优点和~~缺点~~
|
- 开箱即用,无需复杂配置
|
||||||
|
- 新的点击交互模式,拒绝手打指令
|
||||||
- 支持一切Onebot标准通信,后续会支持更多的平台
|
- 支持一切Onebot标准通信,后续会支持更多的平台
|
||||||
|
|
||||||
## 手动安装和部署
|
## 手动安装和部署
|
||||||
|
|
||||||
1. 安装`Git`和`Python3.10+`
|
1. 安装`Git`和`Python3.10+`
|
||||||
2. 克隆项目到本地`git clone https://github.com/snowykami/LiteyukiBot`
|
2. 克隆项目`git clone https://github.com/snowykami/LiteyukiBot`
|
||||||
3. 切换到轻雪目录`cd LiteyukiBot`
|
3. 切换目录`cd LiteyukiBot`
|
||||||
4. 安装依赖`pip install -r requirements.txt`
|
4. 安装依赖`pip install -r requirements.txt`(如果多个Python环境请指定后安装`pythonx -m pip install -r requirements.txt`)
|
||||||
5. 启动`python main.py`
|
5. 启动`python main.py`
|
||||||
|
|
||||||
## 一键部署脚本(复制到本地保存执行)
|
## 一键部署脚本
|
||||||
|
|
||||||
#### 提前部署好`Python3.10+`环境和`Git`环境
|
#### 提前部署好`Python3.10+`环境和`Git`环境
|
||||||
|
|
||||||
@ -41,12 +42,11 @@ echo Install finished! Please click "start.bat" to start the bot!
|
|||||||
```
|
```
|
||||||
|
|
||||||
#### Linux
|
#### Linux
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/snowykami/LiteyukiBot
|
git clone https://github.com/snowykami/LiteyukiBot
|
||||||
cd LiteyukiBot
|
cd LiteyukiBot
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
echo python3 main.py > start.sh
|
echo python3.10 main.py > start.sh
|
||||||
chmod +x start.sh
|
chmod +x start.sh
|
||||||
echo Install finished! Please run "sh start.sh" to start the bot!
|
echo Install finished! Please run "sh start.sh" to start the bot!
|
||||||
```
|
```
|
||||||
@ -65,7 +65,7 @@ echo Install finished! Please run "sh start.sh" to start the bot!
|
|||||||
| 地址 | ws://`host`:`port`/onebot/v11 | 地址取决于配置文件,默认为`20216`端口 |
|
| 地址 | ws://`host`:`port`/onebot/v11 | 地址取决于配置文件,默认为`20216`端口 |
|
||||||
|
|
||||||
### 推荐方案(QQ)
|
### 推荐方案(QQ)
|
||||||
1. 使用`Lagrange.Core`,`Lagrange.Core`支持多种协议
|
1. 使用`Lagrange.OneBot`,点按交互目前仅支持`Lagrange.OneBot`,详细请看[Lagrange.OneBot]()
|
||||||
2. 云崽的`icqq-plugin`和`ws-plugin`进行通信
|
2. 云崽的`icqq-plugin`和`ws-plugin`进行通信
|
||||||
3. `Go-cqhttp`(目前已经半死不活了)
|
3. `Go-cqhttp`(目前已经半死不活了)
|
||||||
4. 人工实现的`Onebot`协议,自己整一个WebSocket客户端,看着QQ的消息,然后给轻雪传输数据
|
4. 人工实现的`Onebot`协议,自己整一个WebSocket客户端,看着QQ的消息,然后给轻雪传输数据
|
||||||
|
4
main.py
4
main.py
@ -1,12 +1,16 @@
|
|||||||
import nonebot
|
import nonebot
|
||||||
|
|
||||||
from nonebot.adapters.onebot import v11, v12
|
from nonebot.adapters.onebot import v11, v12
|
||||||
|
|
||||||
|
from src.utils import logger
|
||||||
from src.utils.config import load_from_yaml
|
from src.utils.config import load_from_yaml
|
||||||
|
|
||||||
|
nonebot.logger = logger
|
||||||
nonebot.init(**load_from_yaml("config.yml"))
|
nonebot.init(**load_from_yaml("config.yml"))
|
||||||
|
|
||||||
adapters = [v11.Adapter, v12.Adapter]
|
adapters = [v11.Adapter, v12.Adapter]
|
||||||
driver = nonebot.get_driver()
|
driver = nonebot.get_driver()
|
||||||
|
|
||||||
for adapter in adapters:
|
for adapter in adapters:
|
||||||
driver.register_adapter(adapter)
|
driver.register_adapter(adapter)
|
||||||
|
|
||||||
|
@ -11,6 +11,4 @@ psutil==5.9.8
|
|||||||
pydantic==2.6.4
|
pydantic==2.6.4
|
||||||
pytz==2024.1
|
pytz==2024.1
|
||||||
PyYAML~=6.0.1
|
PyYAML~=6.0.1
|
||||||
typing_extensions~=4.10.0
|
|
||||||
starlette~=0.36.3
|
starlette~=0.36.3
|
||||||
pip==24.0
|
|
@ -3,7 +3,6 @@ import os
|
|||||||
import nonebot.plugin
|
import nonebot.plugin
|
||||||
|
|
||||||
from src.utils.data_manager import InstalledPlugin, plugin_db
|
from src.utils.data_manager import InstalledPlugin, plugin_db
|
||||||
from src.utils.language import load_from_dir
|
|
||||||
from src.utils.resource import load_resource_from_dir
|
from src.utils.resource import load_resource_from_dir
|
||||||
|
|
||||||
THIS_PLUGIN_NAME = os.path.basename(os.path.dirname(__file__))
|
THIS_PLUGIN_NAME = os.path.basename(os.path.dirname(__file__))
|
||||||
|
@ -7,7 +7,7 @@ from nonebot.permission import SUPERUSER
|
|||||||
from nonebot.plugin import PluginMetadata
|
from nonebot.plugin import PluginMetadata
|
||||||
|
|
||||||
from src.utils.message import send_markdown
|
from src.utils.message import send_markdown
|
||||||
from src.utils.typing import T_Message, T_Bot, v11, T_MessageEvent
|
from src.utils.ly_typing import T_Message, T_Bot, v11, T_MessageEvent
|
||||||
|
|
||||||
md_test = on_command("mdts", aliases={"会话md"}, permission=SUPERUSER)
|
md_test = on_command("mdts", aliases={"会话md"}, permission=SUPERUSER)
|
||||||
md_group = on_command("mdg", aliases={"群md"}, permission=SUPERUSER)
|
md_group = on_command("mdg", aliases={"群md"}, permission=SUPERUSER)
|
||||||
|
@ -7,7 +7,7 @@ from nonebot.plugin import PluginMetadata
|
|||||||
from nonebot_plugin_alconna import on_alconna
|
from nonebot_plugin_alconna import on_alconna
|
||||||
from src.utils.data import LiteModel
|
from src.utils.data import LiteModel
|
||||||
from src.utils.message import send_markdown
|
from src.utils.message import send_markdown
|
||||||
from src.utils.typing import T_Bot, T_MessageEvent
|
from src.utils.ly_typing import T_Bot, T_MessageEvent
|
||||||
from src.utils.data import Database
|
from src.utils.data import Database
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ import nonebot.plugin
|
|||||||
|
|
||||||
from src.utils.data import Database, LiteModel
|
from src.utils.data import Database, LiteModel
|
||||||
from src.utils.data_manager import GroupChat, InstalledPlugin, User, group_db, plugin_db, user_db
|
from src.utils.data_manager import GroupChat, InstalledPlugin, User, group_db, plugin_db, user_db
|
||||||
from src.utils.typing import T_MessageEvent
|
from src.utils.ly_typing import T_MessageEvent
|
||||||
|
|
||||||
LNPM_COMMAND_START = "lnpm"
|
LNPM_COMMAND_START = "lnpm"
|
||||||
|
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
import json
|
|
||||||
import os.path
|
import os.path
|
||||||
import shutil
|
|
||||||
import sys
|
import sys
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
import aiofiles
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import nonebot
|
import nonebot
|
||||||
import pip
|
import pip
|
||||||
@ -14,11 +10,9 @@ from nonebot.permission import SUPERUSER
|
|||||||
from nonebot_plugin_alconna import Alconna, Args, Subcommand, on_alconna
|
from nonebot_plugin_alconna import Alconna, Args, Subcommand, on_alconna
|
||||||
|
|
||||||
from src.utils.language import get_user_lang
|
from src.utils.language import get_user_lang
|
||||||
|
from src.utils.ly_typing import T_Bot
|
||||||
from src.utils.message import Markdown as md, send_markdown
|
from src.utils.message import Markdown as md, send_markdown
|
||||||
from src.utils.resource import get_res
|
|
||||||
from src.utils.typing import T_Bot, T_MessageEvent
|
|
||||||
from .common import *
|
from .common import *
|
||||||
from src.utils.data_manager import InstalledPlugin
|
|
||||||
|
|
||||||
npm_alc = on_alconna(
|
npm_alc = on_alconna(
|
||||||
Alconna(
|
Alconna(
|
||||||
@ -38,7 +32,7 @@ npm_alc = on_alconna(
|
|||||||
alias=["i", "安装"],
|
alias=["i", "安装"],
|
||||||
),
|
),
|
||||||
Subcommand(
|
Subcommand(
|
||||||
"remove",
|
"uninstall",
|
||||||
Args["plugin_name", str],
|
Args["plugin_name", str],
|
||||||
alias=["rm", "移除", "卸载"],
|
alias=["rm", "移除", "卸载"],
|
||||||
),
|
),
|
||||||
@ -136,12 +130,12 @@ async def _(result: Arparma, event: T_MessageEvent, bot: T_Bot):
|
|||||||
event=event
|
event=event
|
||||||
)
|
)
|
||||||
|
|
||||||
elif result.subcommands.get("remove"):
|
elif result.subcommands.get("uninstall"):
|
||||||
plugin_module_name: str = result.subcommands["remove"].args.get("plugin_name")
|
plugin_module_name: str = result.subcommands["uninstall"].args.get("plugin_name")
|
||||||
found_installed_plugin: InstalledPlugin = plugin_db.first(InstalledPlugin, "module_name = ?", plugin_module_name)
|
found_installed_plugin: InstalledPlugin = plugin_db.first(InstalledPlugin, "module_name = ?", plugin_module_name)
|
||||||
if found_installed_plugin:
|
if found_installed_plugin:
|
||||||
plugin_db.delete(InstalledPlugin, "module_name = ?", plugin_module_name)
|
plugin_db.delete(InstalledPlugin, "module_name = ?", plugin_module_name)
|
||||||
reply = f"{ulang.get('npm.remove_success', NAME=found_installed_plugin.module_name)}"
|
reply = f"{ulang.get('npm.uninstall_success', NAME=found_installed_plugin.module_name)}"
|
||||||
await npm_alc.finish(reply)
|
await npm_alc.finish(reply)
|
||||||
else:
|
else:
|
||||||
await npm_alc.finish(ulang.get("npm.plugin_not_installed", NAME=plugin_module_name))
|
await npm_alc.finish(ulang.get("npm.plugin_not_installed", NAME=plugin_module_name))
|
||||||
|
@ -2,6 +2,7 @@ import os
|
|||||||
|
|
||||||
import nonebot.plugin
|
import nonebot.plugin
|
||||||
from nonebot import on_command
|
from nonebot import on_command
|
||||||
|
from nonebot.exception import FinishedException
|
||||||
from nonebot.internal.matcher import Matcher
|
from nonebot.internal.matcher import Matcher
|
||||||
from nonebot.message import run_preprocessor
|
from nonebot.message import run_preprocessor
|
||||||
from nonebot.permission import SUPERUSER
|
from nonebot.permission import SUPERUSER
|
||||||
@ -10,7 +11,7 @@ from nonebot_plugin_alconna import on_alconna, Alconna, Args, Arparma
|
|||||||
from src.utils.data_manager import GroupChat, InstalledPlugin, User, group_db, plugin_db, user_db
|
from src.utils.data_manager import GroupChat, InstalledPlugin, User, group_db, plugin_db, user_db
|
||||||
from src.utils.message import Markdown as md, send_markdown
|
from src.utils.message import Markdown as md, send_markdown
|
||||||
from src.utils.permission import GROUP_ADMIN, GROUP_OWNER
|
from src.utils.permission import GROUP_ADMIN, GROUP_OWNER
|
||||||
from src.utils.typing import T_Bot, T_MessageEvent
|
from src.utils.ly_typing import T_Bot, T_MessageEvent
|
||||||
from src.utils.language import get_user_lang
|
from src.utils.language import get_user_lang
|
||||||
from .common import get_plugin_can_be_toggle, get_plugin_current_enable, get_plugin_default_enable
|
from .common import get_plugin_can_be_toggle, get_plugin_current_enable, get_plugin_default_enable
|
||||||
from .installer import get_store_plugin, npm_update
|
from .installer import get_store_plugin, npm_update
|
||||||
@ -62,12 +63,12 @@ async def _(event: T_MessageEvent, bot: T_Bot):
|
|||||||
if await SUPERUSER(bot, event):
|
if await SUPERUSER(bot, event):
|
||||||
plugin_in_database = plugin_db.first(InstalledPlugin, 'module_name = ?', plugin.module_name)
|
plugin_in_database = plugin_db.first(InstalledPlugin, 'module_name = ?', plugin.module_name)
|
||||||
# 添加移除插件
|
# 添加移除插件
|
||||||
btn_remove = (
|
btn_uninstall = (
|
||||||
md.button(lang.get('npm.uninstall'), f'npm remove {plugin.module_name}')) if plugin_in_database else lang.get(
|
md.button(lang.get('npm.uninstall'), f'npm uninstall {plugin.module_name}')) if plugin_in_database else lang.get(
|
||||||
'npm.uninstall')
|
'npm.uninstall')
|
||||||
btn_toggle_global = lang.get('npm.disable') if plugin.metadata and not plugin.metadata.extra.get('toggleable') \
|
btn_toggle_global = lang.get('npm.disable') if plugin.metadata and not plugin.metadata.extra.get('toggleable') \
|
||||||
else md.button(lang.get('npm.disable_global'), f'disable-plugin {plugin.module_name} true')
|
else md.button(lang.get('npm.disable_global'), f'disable-plugin {plugin.module_name} true')
|
||||||
reply += f" {btn_remove} {btn_toggle_global}"
|
reply += f" {btn_uninstall} {btn_toggle_global}"
|
||||||
|
|
||||||
reply += "\n\n***\n"
|
reply += "\n\n***\n"
|
||||||
await send_markdown(reply, bot, event=event)
|
await send_markdown(reply, bot, event=event)
|
||||||
@ -100,7 +101,7 @@ async def _(result: Arparma, event: T_MessageEvent, bot: T_Bot):
|
|||||||
if await GROUP_ADMIN(bot, event) or await GROUP_OWNER(bot, event) or await SUPERUSER(bot, event):
|
if await GROUP_ADMIN(bot, event) or await GROUP_OWNER(bot, event) or await SUPERUSER(bot, event):
|
||||||
session = group_db.first(GroupChat, "group_id = ?", event.group_id, default=GroupChat(group_id=event.group_id))
|
session = group_db.first(GroupChat, "group_id = ?", event.group_id, default=GroupChat(group_id=event.group_id))
|
||||||
else:
|
else:
|
||||||
return
|
raise FinishedException(ulang.get("Permission Denied"))
|
||||||
# 启用 已停用的默认启用插件 将其从停用列表移除
|
# 启用 已停用的默认启用插件 将其从停用列表移除
|
||||||
# 启用 已停用的默认停用插件 将其放到启用列表
|
# 启用 已停用的默认停用插件 将其放到启用列表
|
||||||
# 停用 已启用的默认启用插件 将其放到停用列表
|
# 停用 已启用的默认启用插件 将其放到停用列表
|
||||||
@ -134,4 +135,5 @@ async def _(result: Arparma, event: T_MessageEvent, bot: T_Bot):
|
|||||||
@run_preprocessor
|
@run_preprocessor
|
||||||
async def _(event: T_MessageEvent, matcher: Matcher):
|
async def _(event: T_MessageEvent, matcher: Matcher):
|
||||||
plugin = matcher.plugin
|
plugin = matcher.plugin
|
||||||
|
# TODO 插件启用/停用检查hook
|
||||||
nonebot.logger.info(f"Plugin: {plugin.module_name}")
|
nonebot.logger.info(f"Plugin: {plugin.module_name}")
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from arclet.alconna import Arparma
|
from nonebot_plugin_alconna import Alconna, Args, Arparma, Subcommand, on_alconna
|
||||||
from nonebot import on_command
|
|
||||||
from nonebot.params import CommandArg
|
|
||||||
from nonebot_plugin_alconna import on_alconna, Alconna, Args, Arparma, Option, Subcommand
|
|
||||||
|
|
||||||
from src.utils.data import LiteModel
|
from src.utils.data import LiteModel
|
||||||
from src.utils.typing import T_Bot, T_Message, T_MessageEvent
|
|
||||||
from src.utils.data_manager import User, user_db
|
from src.utils.data_manager import User, user_db
|
||||||
from src.utils.language import Language, get_all_lang, get_user_lang
|
from src.utils.language import Language, get_all_lang, get_user_lang
|
||||||
|
from src.utils.ly_typing import T_Bot, T_MessageEvent
|
||||||
from src.utils.message import Markdown as md, send_markdown
|
from src.utils.message import Markdown as md, send_markdown
|
||||||
|
|
||||||
profile_alc = on_alconna(
|
profile_alc = on_alconna(
|
||||||
@ -134,5 +131,5 @@ def set_profile(key: str, value: str) -> bool:
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
elif key == 'timezone':
|
elif key == 'timezone':
|
||||||
# TODO
|
# TODO 其他个人信息项目的实现
|
||||||
pass
|
pass
|
||||||
|
@ -32,8 +32,8 @@ npm.search_no_result=No result found
|
|||||||
npm.too_many_results=Too many results found, {HIDE_NUM} hidden, please refine your search
|
npm.too_many_results=Too many results found, {HIDE_NUM} hidden, please refine your search
|
||||||
npm.install_success={NAME} installed successfully
|
npm.install_success={NAME} installed successfully
|
||||||
npm.install_failed={NAME} installation failed, please check the console for more information, or visit the plugin's {HOMEPAGE}
|
npm.install_failed={NAME} installation failed, please check the console for more information, or visit the plugin's {HOMEPAGE}
|
||||||
npm.remove_success={NAME} uninstalled successfully
|
npm.uninstall_success={NAME} uninstalled successfully
|
||||||
npm.remove_failed={NAME} uninstallation failed
|
npm.uninstall_failed={NAME} uninstallation failed
|
||||||
npm.load_failed={NAME} loading failed, please check the console for more information, or visit the plugin's {HOMEPAGE}
|
npm.load_failed={NAME} loading failed, please check the console for more information, or visit the plugin's {HOMEPAGE}
|
||||||
npm.plugin_not_found={NAME} not found, please check the plugin's name
|
npm.plugin_not_found={NAME} not found, please check the plugin's name
|
||||||
npm.plugin_not_installed={NAME} is not installed
|
npm.plugin_not_installed={NAME} is not installed
|
||||||
|
@ -32,8 +32,8 @@ npm.search_no_result = 検索結果がありません
|
|||||||
npm.too_many_results = 検索結果が多すぎます。{HIDE_NUM} 件の結果が非表示になりました
|
npm.too_many_results = 検索結果が多すぎます。{HIDE_NUM} 件の結果が非表示になりました
|
||||||
npm.install_success = {NAME} が正常にインストールされました
|
npm.install_success = {NAME} が正常にインストールされました
|
||||||
npm.install_failed = {NAME} のインストールに失敗しました, 詳細はログを参照してください, またはプラグインの作者に連絡してください{HOMEPAGE}
|
npm.install_failed = {NAME} のインストールに失敗しました, 詳細はログを参照してください, またはプラグインの作者に連絡してください{HOMEPAGE}
|
||||||
npm.remove_success = {NAME} が正常にアンインストールされました
|
npm.uninstall_success = {NAME} が正常にアンインストールされました
|
||||||
npm.remove_failed = {NAME} のアンインストールに失敗しました
|
npm.uninstall_failed = {NAME} のアンインストールに失敗しました
|
||||||
npm.load_failed = {NAME} の読み込みに失敗しました,詳細はログを参照してください, またはプラグインの作者に連絡してください{HOMEPAGE}
|
npm.load_failed = {NAME} の読み込みに失敗しました,詳細はログを参照してください, またはプラグインの作者に連絡してください{HOMEPAGE}
|
||||||
npm.plugin_not_found = {NAME} は見つかりません,スペルをチェックしてください
|
npm.plugin_not_found = {NAME} は見つかりません,スペルをチェックしてください
|
||||||
npm.plugin_not_installed = {NAME} はインストールされていません
|
npm.plugin_not_installed = {NAME} はインストールされていません
|
||||||
|
@ -32,8 +32,8 @@ npm.search_no_result=无搜索结果
|
|||||||
npm.too_many_results=内容过多,{HIDE_NUM}项已隐藏,请限制关键字搜索
|
npm.too_many_results=内容过多,{HIDE_NUM}项已隐藏,请限制关键字搜索
|
||||||
npm.install_success={NAME} 安装成功
|
npm.install_success={NAME} 安装成功
|
||||||
npm.install_failed={NAME} 安装失败,请查看日志获取详细信息,如不能解决,请访问{HOMEPAGE}寻求帮助
|
npm.install_failed={NAME} 安装失败,请查看日志获取详细信息,如不能解决,请访问{HOMEPAGE}寻求帮助
|
||||||
npm.remove_success={NAME} 卸载成功
|
npm.uninstall_success={NAME} 卸载成功
|
||||||
npm.remove_failed={NAME} 卸载失败
|
npm.uninstall_failed={NAME} 卸载失败
|
||||||
npm.load_failed={NAME} 加载失败,请在控制台查看详细信息,检查依赖或配置是否正确,如不能解决,请访问{HOMEPAGE}寻求帮助
|
npm.load_failed={NAME} 加载失败,请在控制台查看详细信息,检查依赖或配置是否正确,如不能解决,请访问{HOMEPAGE}寻求帮助
|
||||||
npm.plugin_not_found=未在商店中找到 {NAME},请尝试更新商店信息或检查拼写
|
npm.plugin_not_found=未在商店中找到 {NAME},请尝试更新商店信息或检查拼写
|
||||||
npm.plugin_not_installed={NAME} 未安装
|
npm.plugin_not_installed={NAME} 未安装
|
||||||
|
@ -32,8 +32,8 @@ npm.search_no_result=無搜尋結果
|
|||||||
npm.too_many_results=結果過多,已隱藏 {HIDE_NUM} 項,請儘量精確搜尋
|
npm.too_many_results=結果過多,已隱藏 {HIDE_NUM} 項,請儘量精確搜尋
|
||||||
npm.install_success={NAME} 安裝成功
|
npm.install_success={NAME} 安裝成功
|
||||||
npm.install_failed={NAME} 安裝失敗,請查看日誌以獲取詳細資訊,如無法解決,請訪問{HOMEPAGE}尋求協助
|
npm.install_failed={NAME} 安裝失敗,請查看日誌以獲取詳細資訊,如無法解決,請訪問{HOMEPAGE}尋求協助
|
||||||
npm.remove_success={NAME} 卸載成功
|
npm.uninstall_success={NAME} 卸載成功
|
||||||
npm.remove_failed={NAME} 卸載失敗
|
npm.uninstall_failed={NAME} 卸載失敗
|
||||||
npm.load_failed={NAME} 載入失敗,請在控制台檢查詳細資訊,確認依賴項目或配置是否正確,如無法解決,請訪問{HOMEPAGE}尋求協助
|
npm.load_failed={NAME} 載入失敗,請在控制台檢查詳細資訊,確認依賴項目或配置是否正確,如無法解決,請訪問{HOMEPAGE}尋求協助
|
||||||
npm.plugin_not_found=在商店中找不到 {NAME},請嘗試更新商店資訊或檢查拼寫
|
npm.plugin_not_found=在商店中找不到 {NAME},請嘗試更新商店資訊或檢查拼寫
|
||||||
npm.plugin_not_installed={NAME} 未安裝
|
npm.plugin_not_installed={NAME} 未安裝
|
||||||
|
@ -32,8 +32,8 @@ npm.search_no_result=没找到任何东西哦~
|
|||||||
npm.too_many_results=好多东西,隐藏了 {HIDE_NUM} 个,搜寻更准确些吧!
|
npm.too_many_results=好多东西,隐藏了 {HIDE_NUM} 个,搜寻更准确些吧!
|
||||||
npm.install_success={NAME} 安装成功啦~
|
npm.install_success={NAME} 安装成功啦~
|
||||||
npm.install_failed={NAME} 安装失败了,去 {HOMEPAGE} 寻求帮助吧!
|
npm.install_failed={NAME} 安装失败了,去 {HOMEPAGE} 寻求帮助吧!
|
||||||
npm.remove_success={NAME} 卸载成功啦~
|
npm.uninstall_success={NAME} 卸载成功啦~
|
||||||
npm.remove_failed={NAME} 卸载失败了~
|
npm.uninstall_failed={NAME} 卸载失败了~
|
||||||
npm.load_failed={NAME} 装载失败了,去 {HOMEPAGE} 寻求帮助吧!
|
npm.load_failed={NAME} 装载失败了,去 {HOMEPAGE} 寻求帮助吧!
|
||||||
npm.plugin_not_found=没在商店里找到 {NAME} 呢~
|
npm.plugin_not_found=没在商店里找到 {NAME} 呢~
|
||||||
npm.plugin_not_installed={NAME} 没有安装~
|
npm.plugin_not_installed={NAME} 没有安装~
|
||||||
|
@ -32,8 +32,8 @@ npm.search_no_result=無搜尋之結果
|
|||||||
npm.too_many_results=内容過多,{HIDE_NUM}項已隱藏,請限制關鍵字搜尋
|
npm.too_many_results=内容過多,{HIDE_NUM}項已隱藏,請限制關鍵字搜尋
|
||||||
npm.install_success={NAME} 安裝成功
|
npm.install_success={NAME} 安裝成功
|
||||||
npm.install_failed={NAME} 安裝失敗,詳情可見於日誌,如不能解決,請訪{HOMEPAGE}求助
|
npm.install_failed={NAME} 安裝失敗,詳情可見於日誌,如不能解決,請訪{HOMEPAGE}求助
|
||||||
npm.remove_success={NAME} 卸載成功
|
npm.uninstall_success={NAME} 卸載成功
|
||||||
npm.remove_failed={NAME} 卸載失敗
|
npm.uninstall_failed={NAME} 卸載失敗
|
||||||
npm.load_failed={NAME} 載入失敗,詳細信息可於控制臺查詢,檢查依賴或設置是否正確,如不能解決,請訪{HOMEPAGE}求助
|
npm.load_failed={NAME} 載入失敗,詳細信息可於控制臺查詢,檢查依賴或設置是否正確,如不能解決,請訪{HOMEPAGE}求助
|
||||||
npm.plugin_not_found=未在商店中見{NAME},可嘗試更新商店信息或檢查拼寫
|
npm.plugin_not_found=未在商店中見{NAME},可嘗試更新商店信息或檢查拼寫
|
||||||
npm.plugin_not_installed={NAME} 未安裝
|
npm.plugin_not_installed={NAME} 未安裝
|
||||||
|
1
src/utils/__init__.py
Normal file
1
src/utils/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
from .log import logger
|
@ -7,7 +7,7 @@ from collections.abc import Iterable
|
|||||||
|
|
||||||
import nonebot
|
import nonebot
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from typing_extensions import Any
|
from typing import Any
|
||||||
|
|
||||||
BaseIterable = list | tuple | set | dict
|
BaseIterable = list | tuple | set | dict
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
import json
|
import json
|
||||||
import locale
|
import locale
|
||||||
import os
|
import os
|
||||||
from typing_extensions import Any
|
from typing import Any
|
||||||
|
|
||||||
import nonebot
|
import nonebot
|
||||||
|
|
||||||
|
88
src/utils/log.py
Normal file
88
src/utils/log.py
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
import sys
|
||||||
|
import logging
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
import loguru
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
# avoid sphinx autodoc resolve annotation failed
|
||||||
|
# because loguru module do not have `Logger` class actually
|
||||||
|
from loguru import Logger, Record
|
||||||
|
|
||||||
|
# logger = logging.getLogger("nonebot")
|
||||||
|
logger: "Logger" = loguru.logger
|
||||||
|
"""NoneBot 日志记录器对象。
|
||||||
|
|
||||||
|
默认信息:
|
||||||
|
|
||||||
|
- 格式: `[%(asctime)s %(name)s] %(levelname)s: %(message)s`
|
||||||
|
- 等级: `INFO` ,根据 `config.log_level` 配置改变
|
||||||
|
- 输出: 输出至 stdout
|
||||||
|
|
||||||
|
用法:
|
||||||
|
```python
|
||||||
|
from nonebot.log import logger
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
# default_handler = logging.StreamHandler(sys.stdout)
|
||||||
|
# default_handler.setFormatter(
|
||||||
|
# logging.Formatter("[%(asctime)s %(name)s] %(levelname)s: %(message)s"))
|
||||||
|
# logger.addHandler(default_handler)
|
||||||
|
|
||||||
|
|
||||||
|
class LoguruHandler(logging.Handler): # pragma: no cover
|
||||||
|
"""logging 与 loguru 之间的桥梁,将 logging 的日志转发到 loguru。"""
|
||||||
|
|
||||||
|
def emit(self, record: logging.LogRecord):
|
||||||
|
try:
|
||||||
|
level = logger.level(record.levelname).name
|
||||||
|
except ValueError:
|
||||||
|
level = record.levelno
|
||||||
|
|
||||||
|
frame, depth = sys._getframe(6), 6
|
||||||
|
while frame and frame.f_code.co_filename == logging.__file__:
|
||||||
|
frame = frame.f_back
|
||||||
|
depth += 1
|
||||||
|
|
||||||
|
logger.opt(depth=depth, exception=record.exc_info).log(
|
||||||
|
level, record.getMessage()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def default_filter(record: "Record"):
|
||||||
|
"""默认的日志过滤器,根据 `config.log_level` 配置改变日志等级。"""
|
||||||
|
log_level = record["extra"].get("nonebot_log_level", "INFO")
|
||||||
|
levelno = logger.level(log_level).no if isinstance(log_level, str) else log_level
|
||||||
|
return record["level"].no >= levelno
|
||||||
|
|
||||||
|
|
||||||
|
default_format: str = (
|
||||||
|
"<g>{time:MM-DD HH:mm:ss}</g> "
|
||||||
|
"<lvl>[{level.icon}]</lvl> "
|
||||||
|
"<c><{name}></c> "
|
||||||
|
"{message}"
|
||||||
|
)
|
||||||
|
"""默认日志格式"""
|
||||||
|
|
||||||
|
logger.remove()
|
||||||
|
logger_id = logger.add(
|
||||||
|
sys.stdout,
|
||||||
|
level=0,
|
||||||
|
diagnose=False,
|
||||||
|
filter=default_filter,
|
||||||
|
format=default_format,
|
||||||
|
)
|
||||||
|
|
||||||
|
logger.level("DEBUG", color="<cyan>", icon="㊙️DEBU")
|
||||||
|
logger.level("INFO", color="<white>", icon="ℹ️INFO")
|
||||||
|
logger.level("SUCCESS", color="<green>", icon="✅SUCC")
|
||||||
|
logger.level("WARNING", color="<yellow>", icon="⚠️WARN")
|
||||||
|
logger.level("ERROR", color="<red>", icon="☢️ERRO")
|
||||||
|
|
||||||
|
"""默认日志处理器 id"""
|
||||||
|
|
||||||
|
__autodoc__ = {
|
||||||
|
"logger_id": False
|
||||||
|
}
|
@ -1,20 +1,20 @@
|
|||||||
import nonebot
|
import nonebot
|
||||||
from nonebot.adapters.onebot import v11, v12
|
from nonebot.adapters.onebot import v11, v12
|
||||||
from typing_extensions import Any
|
from typing import Any
|
||||||
|
|
||||||
from .tools import de_escape, encode_url
|
from .tools import de_escape, encode_url
|
||||||
from .typing import T_Bot, T_MessageEvent
|
from .ly_typing import T_Bot, T_MessageEvent
|
||||||
|
|
||||||
|
|
||||||
async def send_markdown(markdown: str, bot: T_Bot, *, message_type: str = None, session_id: str | int = None, event: T_MessageEvent = None, **kwargs) -> dict[str, Any]:
|
async def send_markdown(markdown: str, bot: T_Bot, *, message_type: str = None, session_id: str | int = None, event: T_MessageEvent = None, **kwargs) -> dict[
|
||||||
|
str, Any]:
|
||||||
formatted_md = de_escape(markdown).replace("\n", r"\n").replace("\"", r'\\\"')
|
formatted_md = de_escape(markdown).replace("\n", r"\n").replace("\"", r'\\\"')
|
||||||
if event is not None and message_type is None:
|
if event is not None and message_type is None:
|
||||||
message_type = event.message_type
|
message_type = event.message_type
|
||||||
session_id = event.user_id if event.message_type == "private" else event.group_id
|
session_id = event.user_id if event.message_type == "private" else event.group_id
|
||||||
try:
|
try:
|
||||||
forward_data = await bot.call_api(
|
forward_id = await bot.call_api(
|
||||||
api="send_private_forward_msg",
|
api="send_forward_msg",
|
||||||
user_id=bot.self_id,
|
|
||||||
messages=[
|
messages=[
|
||||||
v11.MessageSegment(
|
v11.MessageSegment(
|
||||||
type="node",
|
type="node",
|
||||||
@ -27,7 +27,7 @@ async def send_markdown(markdown: str, bot: T_Bot, *, message_type: str = None,
|
|||||||
"data": {
|
"data": {
|
||||||
"content": '{"content":"%s"}' % formatted_md
|
"content": '{"content":"%s"}' % formatted_md
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -41,15 +41,14 @@ async def send_markdown(markdown: str, bot: T_Bot, *, message_type: str = None,
|
|||||||
v11.MessageSegment(
|
v11.MessageSegment(
|
||||||
type="longmsg",
|
type="longmsg",
|
||||||
data={
|
data={
|
||||||
"id": forward_data["forward_id"]
|
"id": forward_id
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
**kwargs
|
**kwargs
|
||||||
|
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
nonebot.logger.warning("send_markdown error, send as plane text: %s" % e)
|
nonebot.logger.warning("send_markdown error, send as plain text: %s" % e.__repr__())
|
||||||
if isinstance(bot, v11.Bot):
|
if isinstance(bot, v11.Bot):
|
||||||
data = await bot.send_msg(
|
data = await bot.send_msg(
|
||||||
message_type=message_type,
|
message_type=message_type,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from nonebot.adapters.onebot import v11
|
from nonebot.adapters.onebot import v11
|
||||||
|
|
||||||
from src.utils.typing import T_GroupMessageEvent, T_MessageEvent
|
from src.utils.ly_typing import T_GroupMessageEvent, T_MessageEvent
|
||||||
|
|
||||||
GROUP_ADMIN = v11.GROUP_ADMIN
|
GROUP_ADMIN = v11.GROUP_ADMIN
|
||||||
GROUP_OWNER = v11.GROUP_OWNER
|
GROUP_OWNER = v11.GROUP_OWNER
|
||||||
|
@ -2,7 +2,7 @@ import os
|
|||||||
|
|
||||||
import nonebot
|
import nonebot
|
||||||
import yaml
|
import yaml
|
||||||
from typing_extensions import Any
|
from typing import Any
|
||||||
|
|
||||||
from src.utils.data import LiteModel
|
from src.utils.data import LiteModel
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user