forked from bot/app
fix: 插件列表显示错误问题
This commit is contained in:
parent
933979ceaa
commit
2711d8844b
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
.cache/
|
.cache/
|
||||||
data/
|
data/
|
||||||
|
db/
|
||||||
plugins/
|
plugins/
|
||||||
_config.yml
|
_config.yml
|
||||||
config.example.yml
|
config.example.yml
|
||||||
|
@ -6,8 +6,10 @@ dash==2.16.1
|
|||||||
nonebot2[fastapi]==2.2.1
|
nonebot2[fastapi]==2.2.1
|
||||||
nonebot-adapter-onebot==2.4.3
|
nonebot-adapter-onebot==2.4.3
|
||||||
nonebot-plugin-alconna==0.41.0
|
nonebot-plugin-alconna==0.41.0
|
||||||
|
pip==24.0
|
||||||
psutil==5.9.8
|
psutil==5.9.8
|
||||||
pydantic==2.6.4
|
pydantic==2.6.4
|
||||||
PyYAML~=6.0.1
|
PyYAML~=6.0.1
|
||||||
typing_extensions~=4.10.0
|
typing_extensions~=4.10.0
|
||||||
starlette~=0.36.3
|
starlette~=0.36.3
|
||||||
|
pip==24.0
|
@ -1,8 +1,10 @@
|
|||||||
import nonebot
|
import nonebot
|
||||||
from nonebot.plugin import PluginMetadata
|
from nonebot.plugin import PluginMetadata
|
||||||
from src.utils.language import get_system_lang
|
from src.utils.language import get_system_lang
|
||||||
|
from src.utils.data_manager import *
|
||||||
from .loader import *
|
from .loader import *
|
||||||
from .webdash import *
|
from .webdash import *
|
||||||
|
from src.utils.config import config
|
||||||
|
|
||||||
__author__ = "snowykami"
|
__author__ = "snowykami"
|
||||||
__plugin_meta__ = PluginMetadata(
|
__plugin_meta__ = PluginMetadata(
|
||||||
@ -10,9 +12,12 @@ __plugin_meta__ = PluginMetadata(
|
|||||||
description="轻雪主程序插件,包含了许多初始化的功能",
|
description="轻雪主程序插件,包含了许多初始化的功能",
|
||||||
usage="",
|
usage="",
|
||||||
homepage="https://github.com/snowykami/LiteyukiBot",
|
homepage="https://github.com/snowykami/LiteyukiBot",
|
||||||
|
extra={
|
||||||
|
"liteyuki_plugin": True,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
from src.utils.config import config
|
auto_migrate()
|
||||||
|
|
||||||
sys_lang = get_system_lang()
|
sys_lang = get_system_lang()
|
||||||
nonebot.logger.info(sys_lang.get("main.current_language", LANG=sys_lang.get("language.name")))
|
nonebot.logger.info(sys_lang.get("main.current_language", LANG=sys_lang.get("language.name")))
|
||||||
|
@ -2,6 +2,7 @@ import os
|
|||||||
|
|
||||||
import nonebot.plugin
|
import nonebot.plugin
|
||||||
|
|
||||||
|
from src.utils.data_manager import InstalledPlugin, plugin_db
|
||||||
from src.utils.language import load_from_dir
|
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
|
||||||
|
|
||||||
@ -11,3 +12,8 @@ load_resource_from_dir(RESOURCE_PATH)
|
|||||||
|
|
||||||
nonebot.plugin.load_plugins("src/plugins")
|
nonebot.plugin.load_plugins("src/plugins")
|
||||||
nonebot.plugin.load_plugins("plugins")
|
nonebot.plugin.load_plugins("plugins")
|
||||||
|
|
||||||
|
installed_plugins = plugin_db.all(InstalledPlugin)
|
||||||
|
if installed_plugins:
|
||||||
|
for install_plugin in plugin_db.all(InstalledPlugin):
|
||||||
|
nonebot.load_plugin(install_plugin.module_name)
|
@ -52,4 +52,7 @@ __plugin_meta__ = PluginMetadata(
|
|||||||
description="用于测试Markdown的插件",
|
description="用于测试Markdown的插件",
|
||||||
usage="",
|
usage="",
|
||||||
homepage="https://github.com/snowykami/LiteyukiBot",
|
homepage="https://github.com/snowykami/LiteyukiBot",
|
||||||
|
extra={
|
||||||
|
"liteyuki_plugin": True,
|
||||||
|
}
|
||||||
)
|
)
|
@ -104,8 +104,8 @@ async def _(event: T_MessageEvent, bot: T_Bot):
|
|||||||
for l in str(event.message).split("\n"):
|
for l in str(event.message).split("\n"):
|
||||||
msg_formatted += f"**{l.strip()}**\n"
|
msg_formatted += f"**{l.strip()}**\n"
|
||||||
push_message = (
|
push_message = (
|
||||||
f"> From {event.sender.nickname}@{push.source.session_type}.{push.source.session_id}\n> Bot {bot.self_id}\n\n"
|
f"> From {event.sender.nickname}@{push.source.session_type}.{push.source.session_id}\n> Bot {bot.self_id}\n\n"
|
||||||
f"{msg_formatted}")
|
f"{msg_formatted}")
|
||||||
await send_markdown(push_message, bot2, event=event)
|
await send_markdown(push_message, bot2, event=event)
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -116,4 +116,7 @@ __plugin_meta__ = PluginMetadata(
|
|||||||
description="事件推送插件,支持单向和双向推送,支持跨Bot推送",
|
description="事件推送插件,支持单向和双向推送,支持跨Bot推送",
|
||||||
usage="",
|
usage="",
|
||||||
homepage="https://github.com/snowykami/LiteyukiBot",
|
homepage="https://github.com/snowykami/LiteyukiBot",
|
||||||
|
extra={
|
||||||
|
"liteyuki_plugin": True,
|
||||||
|
}
|
||||||
)
|
)
|
@ -3,7 +3,6 @@ from .manager import *
|
|||||||
from .installer import *
|
from .installer import *
|
||||||
from .helper import *
|
from .helper import *
|
||||||
|
|
||||||
|
|
||||||
__author__ = "snowykami"
|
__author__ = "snowykami"
|
||||||
__plugin_meta__ = PluginMetadata(
|
__plugin_meta__ = PluginMetadata(
|
||||||
name="轻雪插件管理",
|
name="轻雪插件管理",
|
||||||
@ -16,4 +15,7 @@ __plugin_meta__ = PluginMetadata(
|
|||||||
),
|
),
|
||||||
type="application",
|
type="application",
|
||||||
homepage="https://github.com/snowykami/LiteyukiBot",
|
homepage="https://github.com/snowykami/LiteyukiBot",
|
||||||
|
extra={
|
||||||
|
"liteyuki_plugin": True,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
from src.utils.data import Database, LiteModel
|
from src.utils.data import Database, LiteModel
|
||||||
from src.utils.data_manager import plugin_db
|
from src.utils.data_manager import InstalledPlugin, plugin_db
|
||||||
|
|
||||||
LNPM_COMMAND_START = "lnpm"
|
LNPM_COMMAND_START = "lnpm"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class InstalledPlugin(LiteModel):
|
|
||||||
module_name: str
|
|
||||||
|
|
||||||
|
|
||||||
plugin_db.auto_migrate(InstalledPlugin)
|
|
||||||
|
@ -5,26 +5,24 @@ import sys
|
|||||||
from io import StringIO
|
from io import StringIO
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
import aiofiles
|
||||||
|
import aiohttp
|
||||||
import nonebot
|
import nonebot
|
||||||
|
import pip
|
||||||
from arclet.alconna import Arparma, MultiVar
|
from arclet.alconna import Arparma, MultiVar
|
||||||
from nonebot.permission import SUPERUSER
|
from nonebot.permission import SUPERUSER
|
||||||
from nonebot.utils import run_sync
|
from nonebot_plugin_alconna import Alconna, Args, Subcommand, on_alconna
|
||||||
from nonebot_plugin_alconna import on_alconna, Alconna, Args, Subcommand
|
|
||||||
import pip
|
|
||||||
|
|
||||||
import aiohttp, aiofiles
|
|
||||||
from typing_extensions import Any
|
|
||||||
|
|
||||||
from src.utils.language import get_user_lang
|
from src.utils.language import get_user_lang
|
||||||
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.resource import get_res
|
||||||
from src.utils.typing import T_Bot, T_MessageEvent
|
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(
|
||||||
"lnpm",
|
["lnpm", "插件管理"],
|
||||||
Subcommand(
|
Subcommand(
|
||||||
"update",
|
"update",
|
||||||
alias=["u"],
|
alias=["u"],
|
||||||
@ -93,40 +91,54 @@ async def _(result: Arparma, event: T_MessageEvent, bot: T_Bot):
|
|||||||
btn_install = md.button(ulang.get('npm.install'), 'lnpm install %s' % plugin.module_name)
|
btn_install = md.button(ulang.get('npm.install'), 'lnpm install %s' % plugin.module_name)
|
||||||
link_page = md.link(ulang.get('npm.homepage'), plugin.homepage)
|
link_page = md.link(ulang.get('npm.homepage'), plugin.homepage)
|
||||||
|
|
||||||
reply += (f"\n{btn_install} | **{plugin.name}**\n"
|
reply += (f"\n{btn_install} **{plugin.name}**\n"
|
||||||
f"\n > **{plugin.desc}**\n"
|
f"\n > **{plugin.desc}**\n"
|
||||||
f"\n > {ulang.get('npm.author')}: {plugin.author} | {link_page}\n\n***\n")
|
f"\n > {ulang.get('npm.author')}: {plugin.author} {link_page}\n\n***\n")
|
||||||
if len(rs) > max_show:
|
if len(rs) > max_show:
|
||||||
reply += f"\n{ulang.get('npm.too_many_results')}"
|
reply += f"\n{ulang.get('npm.too_many_results', HIDE_NUM=len(rs) - max_show)}"
|
||||||
else:
|
else:
|
||||||
reply = ulang.get("npm.search_no_result")
|
reply = ulang.get("npm.search_no_result")
|
||||||
await send_markdown(reply, bot, event=event)
|
await send_markdown(reply, bot, event=event)
|
||||||
|
|
||||||
elif result.subcommands.get("install"):
|
elif result.subcommands.get("install"):
|
||||||
plugin_name: str = result.subcommands["install"].args.get("plugin_name")
|
plugin_module_name: str = result.subcommands["install"].args.get("plugin_name")
|
||||||
r, log = npm_install(plugin_name)
|
await npm_alc.send(ulang.get("npm.installing", NAME=plugin_module_name))
|
||||||
|
r, log = npm_install(plugin_module_name)
|
||||||
|
log = log.replace("\\", "/")
|
||||||
if r:
|
if r:
|
||||||
nonebot.load_plugin(plugin_name)
|
nonebot.load_plugin(plugin_module_name) # 加载插件
|
||||||
installed_plugin = InstalledPlugin(module_name=plugin_name)
|
installed_plugin = InstalledPlugin(module_name=plugin_module_name) # 构造插件信息模型
|
||||||
store_plugin = await get_store_plugin(plugin_name)
|
store_plugin = await get_store_plugin(plugin_module_name) # 获取商店中的插件信息
|
||||||
plugin_db.save(installed_plugin)
|
found_in_db_plugin = plugin_db.first(InstalledPlugin, "module_name = ?", plugin_module_name) # 查询数据库中是否已经安装
|
||||||
await send_markdown(
|
if found_in_db_plugin is None:
|
||||||
f"**{ulang.get('npm.install_success', NAME=store_plugin.name)}**\n\n"
|
plugin_db.save(installed_plugin)
|
||||||
f"```\n{log}\n```",
|
info = ulang.get('npm.install_success', NAME=store_plugin.name).replace('_', r'\\_') # markdown转义
|
||||||
bot,
|
await send_markdown(
|
||||||
event=event
|
f"{info}\n\n"
|
||||||
)
|
f"```\n{log}\n```",
|
||||||
|
bot,
|
||||||
|
event=event
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
await npm_alc.finish(ulang.get('npm.plugin_already_installed', NAME=store_plugin.name))
|
||||||
else:
|
else:
|
||||||
|
info = ulang.get('npm.install_failed', NAME=plugin_module_name).replace('_', r'\\_')
|
||||||
await send_markdown(
|
await send_markdown(
|
||||||
f"{ulang.get('npm.install_success', NAME=plugin_name)}\n\n"
|
f"{info}\n\n"
|
||||||
f"```\n{log}\n```",
|
f"```\n{log}\n```",
|
||||||
bot,
|
bot,
|
||||||
event=event
|
event=event
|
||||||
)
|
)
|
||||||
|
|
||||||
elif result.subcommands.get("remove"):
|
elif result.subcommands.get("remove"):
|
||||||
plugin_name: str = result.subcommands["remove"].args.get("plugin_name")
|
plugin_module_name: str = result.subcommands["remove"].args.get("plugin_name")
|
||||||
await npm_alc.finish(ulang.get("npm.remove_success"))
|
found_installed_plugin: InstalledPlugin = plugin_db.first(InstalledPlugin, "module_name = ?", plugin_module_name)
|
||||||
|
if found_installed_plugin:
|
||||||
|
plugin_db.delete(InstalledPlugin, "module_name = ?", plugin_module_name)
|
||||||
|
reply = f"{ulang.get('npm.remove_success', NAME=found_installed_plugin.module_name)}"
|
||||||
|
await npm_alc.finish(reply)
|
||||||
|
else:
|
||||||
|
await npm_alc.finish(ulang.get("npm.plugin_not_installed", NAME=plugin_module_name))
|
||||||
|
|
||||||
|
|
||||||
async def npm_update() -> bool:
|
async def npm_update() -> bool:
|
||||||
@ -212,19 +224,25 @@ def npm_install(plugin_module_name) -> tuple[bool, str]:
|
|||||||
sys.stderr = buffer
|
sys.stderr = buffer
|
||||||
|
|
||||||
mirrors = [
|
mirrors = [
|
||||||
"https://pypi.tuna.tsinghua.edu.cn/simple",
|
"https://pypi.mirrors.cqupt.edu.cn/simple", # 重庆邮电大学
|
||||||
"https://pypi.mirrors.cqupt.edu.cn/simple/",
|
"https://pypi.tuna.tsinghua.edu.cn/simple", # 清华大学
|
||||||
"https://pypi.org/simple",
|
"https://pypi.liteyuki.icu/simple", # 轻雪镜像
|
||||||
|
"https://pypi.org/simple", # 官方源
|
||||||
]
|
]
|
||||||
|
|
||||||
# 使用pip安装包,对每个镜像尝试一次,成功后返回值
|
# 使用pip安装包,对每个镜像尝试一次,成功后返回值
|
||||||
success = False
|
success = False
|
||||||
for mirror in mirrors:
|
for mirror in mirrors:
|
||||||
try:
|
try:
|
||||||
|
nonebot.logger.info(f"npm_install try mirror: {mirror}")
|
||||||
result = pip.main(['install', plugin_module_name, "-i", mirror])
|
result = pip.main(['install', plugin_module_name, "-i", mirror])
|
||||||
success = result == 0
|
success = result == 0
|
||||||
break
|
if success:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
nonebot.logger.warning(f"npm_install failed, try next mirror.")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
||||||
success = False
|
success = False
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -2,12 +2,14 @@ import nonebot.plugin
|
|||||||
from nonebot import on_command
|
from nonebot import on_command
|
||||||
from nonebot.permission import SUPERUSER
|
from nonebot.permission import SUPERUSER
|
||||||
|
|
||||||
|
from src.utils.data_manager import InstalledPlugin, plugin_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.typing import T_Bot, T_MessageEvent
|
from src.utils.typing import T_Bot, T_MessageEvent
|
||||||
from src.utils.language import get_user_lang
|
from src.utils.language import get_user_lang
|
||||||
|
|
||||||
list_plugins = on_command("list-plugin", aliases={"列出插件", "插件列表"}, priority=0, permission=SUPERUSER)
|
list_plugins = on_command("list-plugin", aliases={"列出插件", "插件列表"}, priority=0)
|
||||||
toggle_plugin = on_command("enable-plugin", aliases={"启用插件", "禁用插件", "disable-plugin"}, priority=0, permission=SUPERUSER)
|
toggle_plugin = on_command("enable-plugin", aliases={"启用插件", "停用插件", "disable-plugin"}, priority=0, permission=SUPERUSER)
|
||||||
|
|
||||||
|
|
||||||
@list_plugins.handle()
|
@list_plugins.handle()
|
||||||
@ -16,12 +18,24 @@ async def _(event: T_MessageEvent, bot: T_Bot):
|
|||||||
reply = f"# {lang.get('npm.loaded_plugins')} | {lang.get('npm.total', TOTAL=len(nonebot.get_loaded_plugins()))} \n***"
|
reply = f"# {lang.get('npm.loaded_plugins')} | {lang.get('npm.total', TOTAL=len(nonebot.get_loaded_plugins()))} \n***"
|
||||||
for plugin in nonebot.get_loaded_plugins():
|
for plugin in nonebot.get_loaded_plugins():
|
||||||
# 检查是否有 metadata 属性
|
# 检查是否有 metadata 属性
|
||||||
|
btn_help = md.button(lang.get('npm.help'), f'help {plugin.name}', False)
|
||||||
|
reply += f"\n{btn_help} "
|
||||||
if plugin.metadata:
|
if plugin.metadata:
|
||||||
reply += (f"\n{md.button(lang.get('npm.help'), 'help %s' % plugin.name, False, False)} "
|
reply += (f"**{plugin.metadata.name}**\n"
|
||||||
f"**{plugin.metadata.name}**\n"
|
f"\n > {plugin.metadata.description}")
|
||||||
f"\n > {plugin.metadata.description}\n\n***\n")
|
|
||||||
else:
|
else:
|
||||||
reply += (f"\n{md.button(lang.get('npm.help'), 'help %s' % plugin.name, False, False)} "
|
reply += (f"**{plugin.name}**\n"
|
||||||
f"**{plugin.name}**\n"
|
f"\n > {lang.get('npm.no_description')}")
|
||||||
f"\n > {lang.get('npm.no_description')}\n\n***\n")
|
# if await GROUP_ADMIN(bot=bot, event=event) or await GROUP_OWNER(bot=bot, event=event) or await SUPERUSER(bot=bot, event=event):
|
||||||
|
if await GROUP_ADMIN(bot, event) or await GROUP_OWNER(bot, event) or await SUPERUSER(bot, event):
|
||||||
|
btn_enable = md.button(lang.get('npm.enable'), f'enable-plugin {plugin.module_name}')
|
||||||
|
btn_disable = md.button(lang.get('npm.disable'), f'disable-plugin {plugin.module_name}')
|
||||||
|
reply += f"\n > {btn_enable} {btn_disable}"
|
||||||
|
if await SUPERUSER(bot, event):
|
||||||
|
plugin_in_database = plugin_db.first(InstalledPlugin, 'module_name = ?', plugin.module_name)
|
||||||
|
btn_remove = (
|
||||||
|
md.button(lang.get('npm.uninstall'), f'lnpm remove {plugin.module_name}')) if plugin_in_database else lang.get(
|
||||||
|
'npm.uninstall')
|
||||||
|
reply += f" {btn_remove}"
|
||||||
|
reply += "\n\n***\n"
|
||||||
await send_markdown(reply, bot, event=event)
|
await send_markdown(reply, bot, event=event)
|
||||||
|
@ -8,4 +8,7 @@ __plugin_meta__ = PluginMetadata(
|
|||||||
description="用户管理插件",
|
description="用户管理插件",
|
||||||
usage="",
|
usage="",
|
||||||
homepage="https://github.com/snowykami/LiteyukiBot",
|
homepage="https://github.com/snowykami/LiteyukiBot",
|
||||||
|
extra={
|
||||||
|
"liteyuki_plugin": True,
|
||||||
|
}
|
||||||
)
|
)
|
@ -10,6 +10,8 @@ main.monitor.swap=SWAP
|
|||||||
main.monitor.disk=Disk
|
main.monitor.disk=Disk
|
||||||
main.monitor.usage=Usage
|
main.monitor.usage=Usage
|
||||||
|
|
||||||
|
data_manager.migrate_success=Model {NAME} migration successful
|
||||||
|
|
||||||
npm.loaded_plugins=Loaded plugins
|
npm.loaded_plugins=Loaded plugins
|
||||||
npm.total=Total {TOTAL}
|
npm.total=Total {TOTAL}
|
||||||
npm.help=Help
|
npm.help=Help
|
||||||
@ -17,14 +19,18 @@ npm.disable=Disable
|
|||||||
npm.enable=Enable
|
npm.enable=Enable
|
||||||
npm.install=Install
|
npm.install=Install
|
||||||
npm.uninstall=Uninstall
|
npm.uninstall=Uninstall
|
||||||
|
npm.installing=Installing {NAME}...
|
||||||
|
npm.cannot_uninstall=Cannot uninstall
|
||||||
npm.no_description=No description
|
npm.no_description=No description
|
||||||
npm.store_update_success=Plugin store data updated successfully
|
npm.store_update_success=Plugin store data updated successfully
|
||||||
npm.store_update_failed=Plugin store data update failed
|
npm.store_update_failed=Plugin store data update failed
|
||||||
npm.search_result=Search results
|
npm.search_result=Search results
|
||||||
npm.search_no_result=No result found
|
npm.search_no_result=No result found
|
||||||
npm.too_many_results=Too many results found, 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
|
npm.install_failed={NAME} installation failed
|
||||||
|
npm.plugin_not_installed={NAME} is not installed
|
||||||
|
npm.plugin_already_installed={NAME} is already installed
|
||||||
npm.author=Author
|
npm.author=Author
|
||||||
npm.homepage=Homepage
|
npm.homepage=Homepage
|
||||||
npm.next_page=Next
|
npm.next_page=Next
|
||||||
|
@ -10,6 +10,8 @@ main.monitor.swap=スワップ
|
|||||||
main.monitor.disk=ディスク
|
main.monitor.disk=ディスク
|
||||||
main.monitor.usage=使用率
|
main.monitor.usage=使用率
|
||||||
|
|
||||||
|
data_manager.migrate_success=データが正常に移行されました {NAME}
|
||||||
|
|
||||||
npm.loaded_plugins=読み込まれたプラグイン
|
npm.loaded_plugins=読み込まれたプラグイン
|
||||||
npm.total=合計 {TOTAL}
|
npm.total=合計 {TOTAL}
|
||||||
npm.help=ヘルプ
|
npm.help=ヘルプ
|
||||||
@ -17,14 +19,18 @@ npm.disable=無効
|
|||||||
npm.enable=有効
|
npm.enable=有効
|
||||||
npm.install=インストール
|
npm.install=インストール
|
||||||
npm.uninstall=アンインストール
|
npm.uninstall=アンインストール
|
||||||
|
npm.installing={NAME} インストール中
|
||||||
|
npm.cannot_uninstall=このプラグインはアンインストールできません
|
||||||
npm.no_description=説明なし
|
npm.no_description=説明なし
|
||||||
npm.store_update_success=プラグインストアのデータが正常に更新されました
|
npm.store_update_success=プラグインストアのデータが正常に更新されました
|
||||||
npm.store_update_failed=プラグインストアのデータの更新に失敗しました
|
npm.store_update_failed=プラグインストアのデータの更新に失敗しました
|
||||||
npm.search_result=検索結果
|
npm.search_result=検索結果
|
||||||
npm.search_no_result=検索結果がありません
|
npm.search_no_result=検索結果がありません
|
||||||
npm.too_many_results=検索結果が多すぎます。ページをめくってください
|
npm.too_many_results=検索結果が多すぎます。{HIDE_NUM} 件の結果が非表示になりました
|
||||||
npm.install_success={NAME} が正常にインストールされました
|
npm.install_success={NAME} が正常にインストールされました
|
||||||
npm.install_failed={NAME} のインストールに失敗しました
|
npm.install_failed={NAME} のインストールに失敗しました
|
||||||
|
npm.plugin_not_installed={NAME} はインストールされていません
|
||||||
|
npm.plugin_already_installed={NAME} は既にインストールされています
|
||||||
npm.author=著者
|
npm.author=著者
|
||||||
npm.homepage=ホームページ
|
npm.homepage=ホームページ
|
||||||
npm.next_page=次のページ
|
npm.next_page=次のページ
|
||||||
|
@ -10,6 +10,8 @@ main.monitor.swap=交换空间
|
|||||||
main.monitor.disk=磁盘
|
main.monitor.disk=磁盘
|
||||||
main.monitor.usage=使用率
|
main.monitor.usage=使用率
|
||||||
|
|
||||||
|
data_manager.migrate_success=数据模型{NAME}迁移成功
|
||||||
|
|
||||||
npm.loaded_plugins=已加载插件
|
npm.loaded_plugins=已加载插件
|
||||||
npm.total=总计 {TOTAL}
|
npm.total=总计 {TOTAL}
|
||||||
npm.help=帮助
|
npm.help=帮助
|
||||||
@ -17,16 +19,22 @@ npm.disable=停用
|
|||||||
npm.enable=启用
|
npm.enable=启用
|
||||||
npm.install=安装
|
npm.install=安装
|
||||||
npm.uninstall=卸载
|
npm.uninstall=卸载
|
||||||
|
npm.installing=正在安装 {NAME}
|
||||||
|
npm.cannot_uninstall=无法卸载
|
||||||
npm.no_description=无描述
|
npm.no_description=无描述
|
||||||
npm.store_update_success=插件商店数据更新成功
|
npm.store_update_success=插件商店数据更新成功
|
||||||
npm.store_update_failed=插件商店数据更新失败
|
npm.store_update_failed=插件商店数据更新失败
|
||||||
npm.search_result=搜索结果
|
npm.search_result=搜索结果
|
||||||
npm.search_no_result=无搜索结果
|
npm.search_no_result=无搜索结果
|
||||||
npm.too_many_results=搜索结果过多,请限制关键字
|
npm.too_many_results=搜索结果过多,{HIDE_NUM}已隐藏,请限制关键字
|
||||||
npm.install_success={NAME} 安装成功
|
npm.install_success={NAME} 安装成功
|
||||||
npm.install_failed={NAME} 安装失败
|
npm.install_failed={NAME} 安装失败
|
||||||
|
npm.remove_success={NAME} 卸载成功
|
||||||
|
npm.remove_failed={NAME} 卸载失败
|
||||||
|
npm.plugin_not_installed={NAME} 未安装
|
||||||
|
npm.plugin_already_installed={NAME} 已安装,请勿重复安装
|
||||||
npm.author=作者
|
npm.author=作者
|
||||||
npm.homepage=主页
|
npm.homepage=项目主页
|
||||||
npm.next_page=下一页
|
npm.next_page=下一页
|
||||||
npm.prev_page=上一页
|
npm.prev_page=上一页
|
||||||
|
|
||||||
|
@ -88,12 +88,11 @@ class Database(BaseORMAdapter):
|
|||||||
}
|
}
|
||||||
|
|
||||||
DEFAULT_TYPE = {
|
DEFAULT_TYPE = {
|
||||||
'TEXT': '',
|
'TEXT' : '',
|
||||||
'INTEGER': 0,
|
'INTEGER': 0,
|
||||||
'REAL': 0.0
|
'REAL' : 0.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FOREIGNID = 'FOREIGNID'
|
FOREIGNID = 'FOREIGNID'
|
||||||
JSON = 'JSON'
|
JSON = 'JSON'
|
||||||
ID = '$ID'
|
ID = '$ID'
|
||||||
@ -115,6 +114,7 @@ class Database(BaseORMAdapter):
|
|||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
table_name = ''
|
||||||
for model in args:
|
for model in args:
|
||||||
model: type(LiteModel)
|
model: type(LiteModel)
|
||||||
# 检测并创建表,若模型未定义id字段则使用自增主键,有定义的话使用id字段,且id有可能为字符串
|
# 检测并创建表,若模型未定义id字段则使用自增主键,有定义的话使用id字段,且id有可能为字符串
|
||||||
@ -161,6 +161,7 @@ class Database(BaseORMAdapter):
|
|||||||
self.cursor.execute(f'ALTER TABLE {table_name} DROP COLUMN {field}')
|
self.cursor.execute(f'ALTER TABLE {table_name} DROP COLUMN {field}')
|
||||||
|
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
|
nonebot.logger.success(f'Table {table_name} migrated successfully')
|
||||||
|
|
||||||
def save(self, *models: LiteModel) -> int | tuple:
|
def save(self, *models: LiteModel) -> int | tuple:
|
||||||
"""存储数据,检查id字段,如果有id字段则更新,没有则插入
|
"""存储数据,检查id字段,如果有id字段则更新,没有则插入
|
||||||
@ -171,9 +172,12 @@ class Database(BaseORMAdapter):
|
|||||||
Returns:
|
Returns:
|
||||||
id: 数据id,如果有多个数据则返回id元组
|
id: 数据id,如果有多个数据则返回id元组
|
||||||
"""
|
"""
|
||||||
|
|
||||||
ids = []
|
ids = []
|
||||||
for model in models:
|
for model in models:
|
||||||
table_name = model.__class__.__name__
|
table_name = model.__class__.__name__
|
||||||
|
if not self._detect_for_table(table_name):
|
||||||
|
raise ValueError(f'表{table_name}不存在,请先迁移')
|
||||||
key_list = []
|
key_list = []
|
||||||
value_list = []
|
value_list = []
|
||||||
# 处理外键,添加前缀'$IDFieldName'
|
# 处理外键,添加前缀'$IDFieldName'
|
||||||
@ -227,6 +231,17 @@ class Database(BaseORMAdapter):
|
|||||||
|
|
||||||
return json.dumps(return_data)
|
return json.dumps(return_data)
|
||||||
|
|
||||||
|
def _detect_for_table(self, table_name: str) -> bool:
|
||||||
|
"""在进行增删查改前检测表是否存在
|
||||||
|
|
||||||
|
Args:
|
||||||
|
table_name: 表名
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
"""
|
||||||
|
return self.cursor.execute(f'SELECT * FROM sqlite_master WHERE type = "table" AND name = ?', (table_name,)).fetchone()
|
||||||
|
|
||||||
def first(self, model: type(LiteModel), conditions, *args, default: Any = None) -> LiteModel | None:
|
def first(self, model: type(LiteModel), conditions, *args, default: Any = None) -> LiteModel | None:
|
||||||
"""查询第一条数据
|
"""查询第一条数据
|
||||||
|
|
||||||
@ -239,6 +254,10 @@ class Database(BaseORMAdapter):
|
|||||||
Returns: 数据
|
Returns: 数据
|
||||||
"""
|
"""
|
||||||
table_name = model.__name__
|
table_name = model.__name__
|
||||||
|
|
||||||
|
if not self._detect_for_table(table_name):
|
||||||
|
return default
|
||||||
|
|
||||||
self.cursor.execute(f'SELECT * FROM {table_name} WHERE {conditions}', args)
|
self.cursor.execute(f'SELECT * FROM {table_name} WHERE {conditions}', args)
|
||||||
if row_data := self.cursor.fetchone():
|
if row_data := self.cursor.fetchone():
|
||||||
data = dict(row_data)
|
data = dict(row_data)
|
||||||
@ -258,7 +277,8 @@ class Database(BaseORMAdapter):
|
|||||||
"""
|
"""
|
||||||
table_name = model.__name__
|
table_name = model.__name__
|
||||||
|
|
||||||
# 检测表是否存在,否则返回None
|
if not self._detect_for_table(table_name):
|
||||||
|
return default
|
||||||
|
|
||||||
if conditions:
|
if conditions:
|
||||||
self.cursor.execute(f'SELECT * FROM {table_name} WHERE {conditions}', args)
|
self.cursor.execute(f'SELECT * FROM {table_name} WHERE {conditions}', args)
|
||||||
@ -281,27 +301,13 @@ class Database(BaseORMAdapter):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
table_name = model.__name__
|
table_name = model.__name__
|
||||||
|
|
||||||
|
if not self._detect_for_table(table_name):
|
||||||
|
return
|
||||||
nonebot.logger.debug(f'DELETE FROM {table_name} WHERE {conditions}')
|
nonebot.logger.debug(f'DELETE FROM {table_name} WHERE {conditions}')
|
||||||
self.cursor.execute(f'DELETE FROM {table_name} WHERE {conditions}', args)
|
self.cursor.execute(f'DELETE FROM {table_name} WHERE {conditions}', args)
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
|
|
||||||
def update(self, model: type(LiteModel), conditions: str, *args, operation: str):
|
|
||||||
"""更新数据
|
|
||||||
|
|
||||||
Args:
|
|
||||||
model: 模型
|
|
||||||
conditions: 查询条件
|
|
||||||
*args: 参数化查询条件参数
|
|
||||||
operation: 更新操作
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
|
|
||||||
"""
|
|
||||||
table_name = model.__name__
|
|
||||||
nonebot.logger.debug(f'UPDATE {table_name} SET {operation} WHERE {conditions}')
|
|
||||||
self.cursor.execute(f'UPDATE {table_name} SET {operation} WHERE {conditions}', args)
|
|
||||||
self.conn.commit()
|
|
||||||
|
|
||||||
def convert_to_dict(self, data: dict) -> dict:
|
def convert_to_dict(self, data: dict) -> dict:
|
||||||
"""将json字符串转换为字典
|
"""将json字符串转换为字典
|
||||||
|
|
||||||
@ -318,7 +324,7 @@ class Database(BaseORMAdapter):
|
|||||||
for k, v in d.items():
|
for k, v in d.items():
|
||||||
if k.startswith(self.FOREIGNID):
|
if k.startswith(self.FOREIGNID):
|
||||||
new_d[k.replace(self.FOREIGNID, '')] = load(
|
new_d[k.replace(self.FOREIGNID, '')] = load(
|
||||||
dict(self.cursor.execute(f'SELECT * FROM {v.split(":",2)[1]} WHERE id = ?', (v.split(":",2)[2],)).fetchone()))
|
dict(self.cursor.execute(f'SELECT * FROM {v.split(":", 2)[1]} WHERE id = ?', (v.split(":", 2)[2],)).fetchone()))
|
||||||
elif k.startswith(self.JSON):
|
elif k.startswith(self.JSON):
|
||||||
new_d[k.replace(self.JSON, '')] = load(json.loads(v))
|
new_d[k.replace(self.JSON, '')] = load(json.loads(v))
|
||||||
else:
|
else:
|
||||||
@ -327,7 +333,7 @@ class Database(BaseORMAdapter):
|
|||||||
new_d = []
|
new_d = []
|
||||||
for i, v in enumerate(d):
|
for i, v in enumerate(d):
|
||||||
if isinstance(v, str) and v.startswith(self.ID):
|
if isinstance(v, str) and v.startswith(self.ID):
|
||||||
new_d.append(load(dict(self.cursor.execute(f'SELECT * FROM {v.split(":",2)[1]} WHERE id = ?', (v.split(":",2)[2],)).fetchone())))
|
new_d.append(load(dict(self.cursor.execute(f'SELECT * FROM {v.split(":", 2)[1]} WHERE id = ?', (v.split(":", 2)[2],)).fetchone())))
|
||||||
elif isinstance(v, BaseIterable):
|
elif isinstance(v, BaseIterable):
|
||||||
new_d.append(load(v))
|
new_d.append(load(v))
|
||||||
else:
|
else:
|
||||||
|
@ -14,4 +14,10 @@ class User(LiteModel):
|
|||||||
lang: str = "en"
|
lang: str = "en"
|
||||||
|
|
||||||
|
|
||||||
user_db.auto_migrate(User)
|
class InstalledPlugin(LiteModel):
|
||||||
|
module_name: str
|
||||||
|
|
||||||
|
|
||||||
|
def auto_migrate():
|
||||||
|
user_db.auto_migrate(User)
|
||||||
|
plugin_db.auto_migrate(InstalledPlugin)
|
||||||
|
@ -9,6 +9,7 @@ from typing_extensions import Any
|
|||||||
|
|
||||||
import nonebot
|
import nonebot
|
||||||
|
|
||||||
|
from src.utils.config import config
|
||||||
from src.utils.data_manager import User, user_db
|
from src.utils.data_manager import User, user_db
|
||||||
|
|
||||||
_default_lang_code = "en"
|
_default_lang_code = "en"
|
||||||
@ -133,7 +134,10 @@ def get_user_lang(user_id: str) -> Language:
|
|||||||
"""
|
"""
|
||||||
获取用户的语言代码
|
获取用户的语言代码
|
||||||
"""
|
"""
|
||||||
user = user_db.first(User, "user_id = ?", user_id, default=User(user_id=user_id, username="Unknown", lang="en"))
|
user = user_db.first(User, "user_id = ?", user_id, default=User(
|
||||||
|
user_id=user_id,
|
||||||
|
username="Unknown",
|
||||||
|
lang=config.get("default_language", get_system_lang_code())))
|
||||||
return Language(user.lang)
|
return Language(user.lang)
|
||||||
|
|
||||||
|
|
||||||
|
7
src/utils/permission.py
Normal file
7
src/utils/permission.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
from nonebot.adapters.onebot import v11
|
||||||
|
|
||||||
|
from src.utils.typing import T_GroupMessageEvent, T_MessageEvent
|
||||||
|
|
||||||
|
GROUP_ADMIN = v11.GROUP_ADMIN
|
||||||
|
GROUP_OWNER = v11.GROUP_OWNER
|
||||||
|
|
Loading…
Reference in New Issue
Block a user