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