diff --git a/docs/deployment/fandq.md b/docs/deployment/fandq.md index d20a590a..2c9b42d1 100644 --- a/docs/deployment/fandq.md +++ b/docs/deployment/fandq.md @@ -28,6 +28,8 @@ tag: 你需要使用Onebot标准的实现端来连接到轻雪并将消息上报给轻雪,下面已经列出一些推荐的实现端 - `Playwright`安装失败 - 输入`playwright install`安装浏览器 +- 其他问题 + - 加入QQ群[775840726](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=SzmDYbfR6jY94o9KFNon7AwelRyI6M_u&authKey=ygeBdEmdFNyCWuNR4w0M1M8%2B5oDg7k%2FDfN0tzBkYcnbB%2FGHNnlVEnCIGbdftsnn7&noverify=0&group_code=775840726) #### 推荐方案(QQ) diff --git a/liteyuki/liteyuki_main/core.py b/liteyuki/liteyuki_main/core.py index dd99ca80..32ad7839 100644 --- a/liteyuki/liteyuki_main/core.py +++ b/liteyuki/liteyuki_main/core.py @@ -179,6 +179,7 @@ async def _(matcher: Matcher): # system hook @Bot.on_calling_api # 图片模式检测 async def test_for_md_image(bot: T_Bot, api: str, data: dict): + # 截获大图发送,转换为markdown发送 if api in ["send_msg", "send_private_msg", "send_group_msg"] and markdown_image and data.get("user_id") != bot.self_id: if api == "send_msg" and data.get("message_type") == "private" or api == "send_private_msg": session_type = "private" @@ -207,6 +208,7 @@ async def test_for_md_image(bot: T_Bot, api: str, data: dict): @driver.on_startup async def on_startup(): temp_data = common_db.first(TempConfig(), default=TempConfig()) + # 储存重启信息 if temp_data.data.get("reload", False): delta_time = time.time() - temp_data.data.get("reload_time", 0) temp_data.data["delta_time"] = delta_time @@ -221,6 +223,7 @@ async def on_shutdown(): @driver.on_bot_connect async def _(bot: T_Bot): temp_data = common_db.first(TempConfig(), default=TempConfig()) + # 用于重启计时 if temp_data.data.get("reload", False): temp_data.data["reload"] = False reload_bot_id = temp_data.data.get("reload_bot_id", 0) diff --git a/liteyuki/plugins/liteyuki_pacman/common.py b/liteyuki/plugins/liteyuki_pacman/common.py index 8d4b28e1..f61fa5f6 100644 --- a/liteyuki/plugins/liteyuki_pacman/common.py +++ b/liteyuki/plugins/liteyuki_pacman/common.py @@ -123,3 +123,17 @@ def get_plugin_can_be_toggle(plugin_name: str) -> bool: """ plug = nonebot.plugin.get_plugin(plugin_name) return plug.metadata.extra.get("toggleable", True) if plug and plug.metadata else True + + +def get_group_enable(group_id: str) -> bool: + """ + 获取群组是否启用插机器人 + + Args: + group_id (str): 群组ID + + Returns: + bool: 群组是否启用插件 + """ + session: Group = group_db.first(Group(), "group_id = ?", group_id, default=Group(group_id=group_id)) + return session.enable diff --git a/liteyuki/plugins/liteyuki_pacman/npm.py b/liteyuki/plugins/liteyuki_pacman/npm.py index 15cc7fa7..b9f4674f 100644 --- a/liteyuki/plugins/liteyuki_pacman/npm.py +++ b/liteyuki/plugins/liteyuki_pacman/npm.py @@ -5,8 +5,8 @@ import nonebot.plugin import pip from io import StringIO from arclet.alconna import MultiVar -from nonebot import require -from nonebot.exception import FinishedException, IgnoredException +from nonebot import Bot, require +from nonebot.exception import FinishedException, IgnoredException, MockApiException from nonebot.internal.adapter import Event from nonebot.internal.matcher import Matcher from nonebot.message import run_preprocessor @@ -37,32 +37,31 @@ disable = "disable" Subcommand( "enable", Args["plugin_name", str], - alias=["启用"], - + alias=["e", "启用"], ), Subcommand( "disable", Args["plugin_name", str], - alias=["停用"], + alias=["d", "停用"], ), Subcommand( enable_global, Args["plugin_name", str], - alias=["全局启用"], + alias=["eg", "全局启用"], ), Subcommand( disable_global, Args["plugin_name", str], - alias=["全局停用"], + alias=["dg", "全局停用"], ), # 安装部分 Subcommand( "update", - alias=["u"], + alias=["u", "更新"], ), Subcommand( "search", - Args["keywords", MultiVar(str)]["show_num", int, 15], + Args["keywords", MultiVar(str)], alias=["s", "搜索"], ), Subcommand( @@ -79,11 +78,6 @@ disable = "disable" "list", Args["page", int, 1]["num", int, 10], alias=["ls", "列表"], - ), - Subcommand( - "usage", - Args["plugin_name", str], - alias=["详情"], ) ) ).handle() @@ -93,8 +87,8 @@ async def _(result: Arparma, event: T_MessageEvent, bot: T_Bot, npm: Matcher): # 判断会话类型 ulang = get_user_lang(str(event.user_id)) plugin_name = result.args.get("plugin_name") - sc = result.subcommands # 获取子命令 - perm_s = await SUPERUSER(bot, event) # 判断是否为超级用户 + sc = result.subcommands # 获取子命令 + perm_s = await SUPERUSER(bot, event) # 判断是否为超级用户 # 支持对自定义command_start的判断 if sc.get("enable") or result.subcommands.get("disable"): @@ -306,7 +300,7 @@ async def _(result: Arparma, event: T_MessageEvent, bot: T_Bot, npm: Matcher): # 检查是否有 metadata 属性 # 添加帮助按钮 - btn_usage = md.btn_cmd(ulang.get("npm.usage"), f"npm usage {storePlugin.name}", False) + btn_usage = md.btn_cmd(ulang.get("npm.usage"), f"help {storePlugin.name}", False) store_plugin = await get_store_plugin(storePlugin.name) session_enable = get_plugin_session_enable(event, storePlugin.name) if store_plugin: @@ -353,11 +347,49 @@ async def _(result: Arparma, event: T_MessageEvent, bot: T_Bot, npm: Matcher): reply += "\n\n***\n" await md.send_md(reply, bot, event=event) - elif sc.get("usage"): - # TODO - pass else: - pass + await npm.finish(ulang.get("liteyuki.invalid_command")) + + +@on_alconna( + aliases={"群聊"}, + command=Alconna( + "gm", + Subcommand( + enable, + Args["group_id", str, None], + alias=["e", "启用"], + ), + Subcommand( + disable, + Args["group_id", str, None], + alias=["d", "停用"], + ), + ), +).handle() +async def _(event: T_MessageEvent, gm: Matcher, result: Arparma): + ulang = get_user_lang(str(event.user_id)) + to_enable = result.subcommands.get(enable) is not None + group_id = result.subcommands.get(enable, result.subcommands.get(disable)).args.get("group_id") + if group_id is None and event.message_type == "group": + group_id = str(event.group_id) + else: + await gm.finish(ulang.get("liteyuki.invalid_command"), liteyuki_pass=True) + + enabled = get_group_enable(group_id) + if enabled == to_enable: + await gm.finish(ulang.get("liteyuki.group_already", STATUS=ulang.get("npm.enable") if to_enable else ulang.get("npm.disable"), GROUP=group_id), liteyuki_pass=True) + else: + group: Group = group_db.first(Group(), "group_id = ?", group_id, default=Group(group_id=group_id)) + if to_enable: + group.enable = True + else: + group.enable = False + group_db.upsert(group) + await gm.finish( + ulang.get("liteyuki.group_success", STATUS=ulang.get("npm.enable") if to_enable else ulang.get("npm.disable"), GROUP=group_id), + liteyuki_pass=True + ) @run_preprocessor @@ -372,6 +404,15 @@ async def pre_handle(event: Event, matcher: Matcher): raise IgnoredException("Plugin disabled in session") +@Bot.on_calling_api +async def block_disable_session(bot: Bot, api: str, args: dict): + if "group_id" in args and not args.get("liteyuki_pass", False): + group_id = args["group_id"] + if not get_group_enable(group_id): + nonebot.logger.debug(f"Group {group_id} disabled") + raise MockApiException(f"Group {group_id} disabled") + + async def npm_update() -> bool: """ 更新本地插件json缓存 diff --git a/liteyuki/resources/lang/zh-CN.lang b/liteyuki/resources/lang/zh-CN.lang index 13e9c4c2..2d9b6030 100644 --- a/liteyuki/resources/lang/zh-CN.lang +++ b/liteyuki/resources/lang/zh-CN.lang @@ -121,4 +121,7 @@ rpm.move_up=上移 rpm.move_down=下移 rpm.move_top=置顶 -npm.update=更新 \ No newline at end of file +npm.update=更新 + +liteyuki.group_already=群 {GROUP} 已经是 {STATUS} 状态,无需重复操作 +liteyuki.group_success=群 {GROUP} {STATUS} 成功 \ No newline at end of file diff --git a/liteyuki/resources/templates/css/card.css b/liteyuki/resources/templates/css/card.css new file mode 100644 index 00000000..d0700376 --- /dev/null +++ b/liteyuki/resources/templates/css/card.css @@ -0,0 +1,18 @@ +#data-storage { + display: none; +} + +body { + background-repeat: repeat-y; + background-size: cover; + background-position: center; + margin: 20px; +} + +.info-box { + border-radius: 30px; + padding: 30px; + backdrop-filter: blur(10px); + background-color: rgba(0, 0, 0, 0.5); + margin-bottom: 20px; +} \ No newline at end of file diff --git a/liteyuki/resources/templates/css/style.css b/liteyuki/resources/templates/css/style.css index fb01c20b..59a5f861 100644 --- a/liteyuki/resources/templates/css/style.css +++ b/liteyuki/resources/templates/css/style.css @@ -5,7 +5,6 @@ body { color: white; / / 上10px,左右10px,下0px / / margin: 24 px; margin: 20px; - } .info-box { diff --git a/liteyuki/resources/templates/js/status.js b/liteyuki/resources/templates/js/status.js new file mode 100644 index 00000000..288f4924 --- /dev/null +++ b/liteyuki/resources/templates/js/status.js @@ -0,0 +1,9 @@ +const data = JSON.parse(document.getElementById('data').innerText); + +function createPieChartOption(title, data){ + // data为各项占比列表 +} + +function createBarChartOption(title, percent){ + // percent为百分比,最大值为100 +} diff --git a/liteyuki/resources/templates/js/style.js b/liteyuki/resources/templates/js/style.js index 97902af4..49f98e87 100644 --- a/liteyuki/resources/templates/js/style.js +++ b/liteyuki/resources/templates/js/style.js @@ -132,8 +132,7 @@ used += item.value } }) - console.log(used, total) - return used / total * 100 + return (1 - used / total) * 100 } @@ -146,6 +145,7 @@ top: 'center', textStyle: { //文字颜色 + lineHeight: 36, color: '#fff', fontSize: 30 diff --git a/liteyuki/resources/templates/status.html b/liteyuki/resources/templates/status.html new file mode 100644 index 00000000..0e88f158 --- /dev/null +++ b/liteyuki/resources/templates/status.html @@ -0,0 +1,14 @@ + + + + + Liteyuki Status + + + +
{{ data | tojson }}
+
+
+
+ + \ No newline at end of file diff --git a/liteyuki/utils/data_manager.py b/liteyuki/utils/data_manager.py index 1d25074a..4f128354 100644 --- a/liteyuki/utils/data_manager.py +++ b/liteyuki/utils/data_manager.py @@ -28,6 +28,7 @@ class Group(LiteModel): group_name: str = Field(str(), alias="group_name") enabled_plugins: list[str] = Field([], alias="enabled_plugins") disabled_plugins: list[str] = Field([], alias="disabled_plugins") + enable: bool = Field(True, alias="enable") # 群聊全局机器人是否启用 class InstalledPlugin(LiteModel):