猜成语:更优的判断标准

插件管理:提供插件包名
This commit is contained in:
Eilles
2026-05-10 03:16:13 +08:00
parent 5fd6fc88b2
commit 133ad2aca7
6 changed files with 288 additions and 145 deletions
+3 -2
View File
@@ -13,8 +13,8 @@ nonebot_plugin_apscheduler>=0.4.0
nonebot-adapter-satori>=0.11.5 nonebot-adapter-satori>=0.11.5
# pyppeteer>=2.0.0 # pyppeteer>=2.0.0
markdown>=3.3.6 markdown>=3.3.6
zhDateTime>=2.0.0 numba==0.65.1
numpy<2.0.0 numpy==2.2.6
packaging>=23.1 packaging>=23.1
psutil>=5.9.8 psutil>=5.9.8
py-cpuinfo>=9.0.0 py-cpuinfo>=9.0.0
@@ -30,6 +30,7 @@ jieba>=0.42.1
python-dotenv>=1.0.1 python-dotenv>=1.0.1
nonebot_plugin_session nonebot_plugin_session
pypinyin pypinyin
zhDateTime>=2.0.0
Musicreater[full]>=2.4.0 Musicreater[full]>=2.4.0
librosa==0.10.1 librosa==0.10.1
TrimMCStruct TrimMCStruct
+150 -100
View File
@@ -5,7 +5,7 @@ import nonebot.plugin
import pip import pip
from io import StringIO from io import StringIO
from arclet.alconna import MultiVar from arclet.alconna import MultiVar
from nonebot import Bot, require # type: ignore from nonebot import Bot, require # type: ignore
from nonebot.exception import FinishedException, IgnoredException, MockApiException from nonebot.exception import FinishedException, IgnoredException, MockApiException
from nonebot.internal.adapter import Event from nonebot.internal.adapter import Event
from nonebot.internal.matcher import Matcher from nonebot.internal.matcher import Matcher
@@ -25,7 +25,6 @@ from src.utils.message.markdown import MarkdownComponent as mdc, compile_md, esc
from src.utils.message.html_tool import md_to_pic from src.utils.message.html_tool import md_to_pic
from .common import * from .common import *
require("nonebot_plugin_alconna") require("nonebot_plugin_alconna")
from nonebot_plugin_alconna import ( from nonebot_plugin_alconna import (
UniMessage, UniMessage,
@@ -37,6 +36,7 @@ from nonebot_plugin_alconna import (
Option, Option,
OptionResult, OptionResult,
SubcommandResult, SubcommandResult,
store_true,
) )
# const # const
@@ -103,6 +103,11 @@ disable = "disable"
Subcommand( Subcommand(
"list", "list",
Args["page", int, 1]["num", int, 10], Args["page", int, 1]["num", int, 10],
Option(
"-m|--markdown",
action=store_true,
help_text="以 Markdown 交互形式显示列表",
),
alias=["ls", "列表"], alias=["ls", "列表"],
), ),
), ),
@@ -357,120 +362,165 @@ async def _(result: Arparma, event: T_MessageEvent, bot: T_Bot, npm: Matcher):
elif sc.get("list"): elif sc.get("list"):
loaded_plugin_list = sorted(nonebot.get_loaded_plugins(), key=lambda x: x.name) loaded_plugin_list = sorted(nonebot.get_loaded_plugins(), key=lambda x: x.name)
num_per_page = result.subcommands.get("list").args.get("num") num_per_page = result.subcommands["list"].args["num"]
total = len(loaded_plugin_list) // num_per_page + ( total = len(loaded_plugin_list) // num_per_page + (
1 if len(loaded_plugin_list) % num_per_page else 0 1 if len(loaded_plugin_list) % num_per_page else 0
) )
page = clamp(result.subcommands["list"].args["page"], 1, total)
markdown_mode = result.subcommands["list"].options["markdown"].value
page = clamp(result.subcommands.get("list").args.get("page"), 1, total) if not markdown_mode:
# 文字显示模式
# 已加载插件 | 总计10 | 第1/3页 reply = " - {} | {} -\n".format(
reply = ( ulang.get("npm.loaded_plugins"),
f"# {ulang.get('npm.loaded_plugins')} | " ulang.get("npm.page", PAGE=page, TOTAL=total),
f"{ulang.get('npm.total', TOTAL=len(nonebot.get_loaded_plugins()))} | "
f"{ulang.get('npm.page', PAGE=page, TOTAL=total)} \n***\n"
)
permission_oas = (
await GROUP_ADMIN(bot, event)
or await GROUP_OWNER(bot, event)
or await SUPERUSER(bot, event)
)
permission_s = await SUPERUSER(bot, event)
for storePlugin in loaded_plugin_list[
(page - 1)
* num_per_page : min(page * num_per_page, len(loaded_plugin_list))
]:
# 检查是否有 metadata 属性
# 添加帮助按钮
btn_usage = md.btn_cmd(
ulang.get("npm.usage"), f"help {storePlugin.name}", False
) )
store_plugin = await get_store_plugin(storePlugin.name) for pi in range(
session_enable = get_plugin_session_enable(event, storePlugin.name) (page - 1) * num_per_page,
if store_plugin: min(page * num_per_page, len(loaded_plugin_list)),
# btn_homepage = md.btn_link(ulang.get("npm.homepage"), store_plugin.homepage) ):
show_name = store_plugin.name # 遍历插件,通过插件编号
elif storePlugin.metadata: storePlugin = loaded_plugin_list[pi]
# if storePlugin.metadata.extra.get("liteyuki"): store_plugin = await get_store_plugin(storePlugin.name)
# btn_homepage = md.btn_link(ulang.get("npm.homepage"), "https://github.com/snowykami/LiteyukiBot") session_enable = get_plugin_session_enable(event, storePlugin.name)
# else:
# btn_homepage = ulang.get("npm.homepage")
show_name = storePlugin.metadata.name
else:
# btn_homepage = ulang.get("npm.homepage")
show_name = storePlugin.name
ulang.get("npm.no_description")
if storePlugin.metadata: if store_plugin:
reply += f"\n**{md.escape(show_name)}**\n" show_name = store_plugin.name
else: elif storePlugin.metadata:
reply += f"**{md.escape(show_name)}**\n" show_name = storePlugin.metadata.name
else:
show_name = storePlugin.name
ulang.get("npm.no_description")
reply += f"\n > {btn_usage}" reply += "{}. {}".format(pi + 1, show_name)
if permission_oas: if not get_plugin_can_be_toggle(storePlugin.name):
# 添加启用/停用插件按钮 reply += " [{}{}]".format(ulang.get('npm.cannot'), ulang.get(
cmd_toggle = f"npm {'disable' if session_enable else 'enable'} {storePlugin.name}" "npm.disable" if session_enable else "npm.enable"
text_toggle = ulang.get( ))
"npm.disable" if session_enable else "npm.enable"
if not plugin_db.where_one(
InstalledPlugin(), "module_name = ?", storePlugin.name
):
reply += " [{}{}]".format(ulang.get('npm.cannot'), ulang.get("npm.uninstall"))
reply += "\n>\t{}\n".format(storePlugin.name)
await npm.send(reply)
else:
# 已加载插件 | 总计10 | 第1/3页
reply = (
f"# {ulang.get('npm.loaded_plugins')} | "
f"{ulang.get('npm.total', TOTAL=len(nonebot.get_loaded_plugins()))} | "
f"{ulang.get('npm.page', PAGE=page, TOTAL=total)} \n***\n"
)
permission_oas = (
await GROUP_ADMIN(bot, event)
or await GROUP_OWNER(bot, event)
or await SUPERUSER(bot, event)
)
permission_s = await SUPERUSER(bot, event)
for storePlugin in loaded_plugin_list[
(page - 1)
* num_per_page : min(page * num_per_page, len(loaded_plugin_list))
]:
# 检查是否有 metadata 属性
# 添加帮助按钮
btn_usage = md.btn_cmd(
ulang.get("npm.usage"), f"help {storePlugin.name}", False
) )
can_be_toggle = get_plugin_can_be_toggle(storePlugin.name) store_plugin = await get_store_plugin(storePlugin.name)
btn_toggle = ( session_enable = get_plugin_session_enable(event, storePlugin.name)
text_toggle if store_plugin:
if not can_be_toggle # btn_homepage = md.btn_link(ulang.get("npm.homepage"), store_plugin.homepage)
else md.btn_cmd(text_toggle, cmd_toggle) show_name = store_plugin.name
) elif storePlugin.metadata:
reply += f" {btn_toggle}" # if storePlugin.metadata.extra.get("liteyuki"):
# btn_homepage = md.btn_link(ulang.get("npm.homepage"), "https://github.com/snowykami/LiteyukiBot")
# else:
# btn_homepage = ulang.get("npm.homepage")
show_name = storePlugin.metadata.name
else:
# btn_homepage = ulang.get("npm.homepage")
show_name = storePlugin.name
ulang.get("npm.no_description")
if permission_s:
plugin_in_database = plugin_db.where_one( # 何意味? —— 金羿 260510
InstalledPlugin(), "module_name = ?", storePlugin.name if storePlugin.metadata:
reply += f"\n**{md.escape(show_name)}**\n"
else:
reply += f"**{md.escape(show_name)}**\n"
reply += f"\n > {btn_usage}"
if permission_oas:
# 添加启用/停用插件按钮
cmd_toggle = f"npm {'disable' if session_enable else 'enable'} {storePlugin.name}"
text_toggle = ulang.get(
"npm.disable" if session_enable else "npm.enable"
) )
# 添加移除插件和全局切换按钮 can_be_toggle = get_plugin_can_be_toggle(storePlugin.name)
global_enable = get_plugin_global_enable(storePlugin.name) btn_toggle = (
btn_uninstall = ( text_toggle
(
md.btn_cmd(
ulang.get("npm.uninstall"),
f"npm uninstall {storePlugin.name}",
)
)
if plugin_in_database
else ulang.get("npm.uninstall")
)
btn_toggle_global_text = ulang.get(
"npm.disable_global" if global_enable else "npm.enable_global"
)
cmd_toggle_global = f"npm {'disable' if global_enable else 'enable'}-global {storePlugin.name}"
btn_toggle_global = (
btn_toggle_global_text
if not can_be_toggle if not can_be_toggle
else md.btn_cmd(btn_toggle_global_text, cmd_toggle_global) else md.btn_cmd(text_toggle, cmd_toggle)
) )
reply += f" {btn_toggle}"
reply += f" {btn_uninstall} {btn_toggle_global}" if permission_s:
reply += "\n\n***\n" plugin_in_database = plugin_db.where_one(
# 根据页数添加翻页按钮。第一页显示上一页文本而不是按钮,最后一页显示下一页文本而不是按钮 InstalledPlugin(), "module_name = ?", storePlugin.name
btn_prev = ( )
md.btn_cmd( # 添加移除插件和全局切换按钮
ulang.get("npm.prev_page"), f"npm list {page - 1} {num_per_page}" global_enable = get_plugin_global_enable(storePlugin.name)
btn_uninstall = (
(
md.btn_cmd(
ulang.get("npm.uninstall"),
f"npm uninstall {storePlugin.name}",
)
)
if plugin_in_database
else ulang.get("npm.uninstall")
)
btn_toggle_global_text = ulang.get(
"npm.disable_global"
if global_enable
else "npm.enable_global"
)
cmd_toggle_global = f"npm {'disable' if global_enable else 'enable'}-global {storePlugin.name}"
btn_toggle_global = (
btn_toggle_global_text
if not can_be_toggle
else md.btn_cmd(btn_toggle_global_text, cmd_toggle_global)
)
reply += f" {btn_uninstall} {btn_toggle_global}"
reply += "\n\n***\n"
# 根据页数添加翻页按钮。第一页显示上一页文本而不是按钮,最后一页显示下一页文本而不是按钮
btn_prev = (
md.btn_cmd(
ulang.get("npm.prev_page"), f"npm list {page - 1} {num_per_page}"
)
if page > 1
else ulang.get("npm.prev_page")
) )
if page > 1 btn_next = (
else ulang.get("npm.prev_page") md.btn_cmd(
) ulang.get("npm.next_page"), f"npm list {page + 1} {num_per_page}"
btn_next = ( )
md.btn_cmd( if page < total
ulang.get("npm.next_page"), f"npm list {page + 1} {num_per_page}" else ulang.get("npm.next_page")
) )
if page < total reply += f"\n{btn_prev} {page}/{total} {btn_next}"
else ulang.get("npm.next_page") img_bytes = await md_to_pic(reply)
) await UniMessage.send(UniMessage.image(raw=img_bytes))
reply += f"\n{btn_prev} {page}/{total} {btn_next}"
img_bytes = await md_to_pic(reply)
await UniMessage.send(UniMessage.image(raw=img_bytes))
else: else:
if await SUPERUSER(bot, event): if await SUPERUSER(bot, event):
@@ -236,6 +236,79 @@ async def _(matcher: Matcher, user_id: UserId, matched: Dict[str, Any] = RegexDi
await UniMessage.image(raw=await run_sync(game.draw)()).send() await UniMessage.image(raw=await run_sync(game.draw)()).send()
handle_update_pinyin = on_alconna(
Alconna(
"更正成语拼音",
Args["idiom", str, ""],
Args["pinyin1", str, ""],
Args["pinyin2", str, ""],
Args["pinyin3", str, ""],
Args["pinyin4", str, ""],
),
aliases=(
"更新猜成语词库拼音",
"猜成语更新拼音",
"更新猜成语拼音",
"更新成语拼音",
"更正猜成语拼音",
),
use_cmd_start=True,
permission=SUPERUSER,
block=True,
priority=13,
)
@handle_update_pinyin.handle()
async def _(
result: Arparma,
matcher: Matcher,
user_id: UserId,
bot: T_Bot,
):
if not (
(idiom := result.main_args["idiom"])
and (pinyin1 := result.main_args["pinyin1"])
and (pinyin2 := result.main_args["pinyin2"])
and (pinyin3 := result.main_args["pinyin3"])
and (pinyin4 := result.main_args["pinyin4"])
):
await handle_update_pinyin.finish(
"用法:更正成语拼音 <成语> <拼音1> <拼音2> <拼音3> <拼音4>"
)
if idiom not in HANDLE_LEGAL_PHRASES:
await handle_update_pinyin.finish(
"未在词库中找到该成语,请使用 `新成语 <成语>` 来添加成语"
)
HANDLE_ANSWER_PHRASES[idiom]["pinyin"] = pynow = [
pinyin1,
pinyin2,
pinyin3,
pinyin4,
]
json.dump(
HANDLE_ANSWER_PHRASES,
handle_answer_path.open("w", encoding="utf-8"),
ensure_ascii=False,
indent=4,
sort_keys=True,
)
await handle_update_idiom.finish(
"成功修改:{}\n当前词库总数:{}个,普通模式成语:{}\n当前成语信息如下:{}".format(
idiom,
len(HANDLE_LEGAL_PHRASES),
len(HANDLE_COMMON_PHRASES),
"\n\t释义:{}\n\t拼音:{}".format(
HANDLE_ANSWER_PHRASES[idiom]["explanation"], " ".join(pynow)
),
)
)
handle_update_idiom = on_alconna( handle_update_idiom = on_alconna(
Alconna( Alconna(
"新成语", "新成语",
@@ -267,31 +340,39 @@ async def _(
bot: T_Bot, bot: T_Bot,
): ):
try:
if result.options["explanation"].args["explanation"]:
explanation = result.options["explanation"].args["explanation"]
else:
nonebot.logger.info("!!!!这里永远不可能被执行到")
explanation = "未提供该成语的解释说明"
except:
explanation = None
if hard := result.options["hard"].value:
if not explanation:
explanation = "未提供该成语的解释说明"
if not (idiom := result.main_args["idiom"]): if not (idiom := result.main_args["idiom"]):
await handle_update_idiom.finish("请在命令后带上你要增加的成语") await handle_update_idiom.finish("请在命令后带上你要增加的成语")
HANDLE_LEGAL_PHRASES.append(idiom) existance = idiom in HANDLE_LEGAL_PHRASES
json.dump(
HANDLE_LEGAL_PHRASES, try:
handle_all_idiom_path.open("w", encoding="utf-8"), explanation = (
ensure_ascii=False, result.options["explanation"].args["explanation"]
indent=4, if result.options["explanation"].args["explanation"]
sort_keys=True, else None
) )
if not hard: except:
explanation = None
if existance and (not explanation):
# 这个判断的顺序必须高于下面的判断语句
explanation = HANDLE_ANSWER_PHRASES[idiom]["explanation"]
if not explanation:
explanation = "未提供该成语的解释说明"
if not existance:
HANDLE_LEGAL_PHRASES.append(idiom)
json.dump(
HANDLE_LEGAL_PHRASES,
handle_all_idiom_path.open("w", encoding="utf-8"),
ensure_ascii=False,
indent=4,
sort_keys=True,
)
if (not (hard := result.options["hard"].value)) and (
idiom not in HANDLE_COMMON_PHRASES
):
HANDLE_COMMON_PHRASES.append(idiom) HANDLE_COMMON_PHRASES.append(idiom)
json.dump( json.dump(
HANDLE_COMMON_PHRASES, HANDLE_COMMON_PHRASES,
@@ -301,25 +382,33 @@ async def _(
sort_keys=True, sort_keys=True,
) )
if explanation: HANDLE_ANSWER_PHRASES[idiom] = {
HANDLE_ANSWER_PHRASES[idiom] = { "explanation": explanation,
"explanation": explanation, "pinyin": (
"pinyin": [ pynow := (
j for i in pinyin(idiom, style=Style.TONE3, v_to_u=True) for j in i HANDLE_ANSWER_PHRASES[idiom]["pinyin"].copy()
], if existance
} else [
json.dump( j for i in pinyin(idiom, style=Style.TONE3, v_to_u=True) for j in i
HANDLE_ANSWER_PHRASES, ]
handle_answer_path.open("w", encoding="utf-8"), )
ensure_ascii=False, ),
indent=4, }
sort_keys=True, json.dump(
) HANDLE_ANSWER_PHRASES,
handle_answer_path.open("w", encoding="utf-8"),
ensure_ascii=False,
indent=4,
sort_keys=True,
)
await handle_update_idiom.finish( await handle_update_idiom.finish(
"新增成功,当前词库总数:{}\n可用普通模式成语:{}".format( "成功{}{}\n当前词库总数:{}普通模式成语:{}\n当前成语信息如下:{}".format(
"修改" if existance else "新增",
idiom,
len(HANDLE_LEGAL_PHRASES), len(HANDLE_LEGAL_PHRASES),
len(HANDLE_COMMON_PHRASES), len(HANDLE_COMMON_PHRASES),
"\n\t释义:{}\n\t拼音:{}".format(explanation, " ".join(pynow)),
) )
) )
@@ -99,6 +99,7 @@ npm.plugin_already=Plugin {NAME} is already {STATUS}, no need to repeat operatio
npm.toggle_failed=Plugin {NAME} {STATUS} failed: {ERROR} npm.toggle_failed=Plugin {NAME} {STATUS} failed: {ERROR}
npm.toggle_success=Plugin {NAME} {STATUS} successful npm.toggle_success=Plugin {NAME} {STATUS} successful
npm.page=Page {PAGE}/{TOTAL} npm.page=Page {PAGE}/{TOTAL}
npm.cannot=Cannot
npm.update_index=Update Plugin Index npm.update_index=Update Plugin Index
npm.list_plugins=Plugin List npm.list_plugins=Plugin List
npm.disable_session=Disable plugin for current session npm.disable_session=Disable plugin for current session
@@ -99,6 +99,7 @@ npm.plugin_already=插件 {NAME} 已经是 {STATUS} 状态,无需重复操作
npm.toggle_failed=插件 {NAME} {STATUS} 失败: {ERROR} npm.toggle_failed=插件 {NAME} {STATUS} 失败: {ERROR}
npm.toggle_success=插件 {NAME} {STATUS} 成功 npm.toggle_success=插件 {NAME} {STATUS} 成功
npm.page=第{PAGE}/{TOTAL}页 npm.page=第{PAGE}/{TOTAL}页
npm.cannot=不可
npm.update_index=更新插件索引 npm.update_index=更新插件索引
npm.list_plugins=插件列表 npm.list_plugins=插件列表
npm.disable_session=当前会话停用插件 npm.disable_session=当前会话停用插件
@@ -98,7 +98,8 @@ npm.plugin_cannot_be_toggled=不可变易件曰 {NAME} 者
npm.plugin_already=件曰 {NAME} 者,乃{STATUS},勿复行 npm.plugin_already=件曰 {NAME} 者,乃{STATUS},勿复行
npm.toggle_failed=因 {ERROR} 所误,良机尽失,{NAME} 无以{STATUS} npm.toggle_failed=因 {ERROR} 所误,良机尽失,{NAME} 无以{STATUS}
npm.toggle_success=件曰 {NAME} 者,方{STATUS}成 npm.toggle_success=件曰 {NAME} 者,方{STATUS}成
npm.page=第 {PAGE} 之于 {TOTAL} npm.page=第 {PAGE} 之于 {TOTAL}
npm.cannot=不可
npm.update_index=阁引 npm.update_index=阁引
npm.list_plugins=件目 npm.list_plugins=件目
npm.disable_session=是处去 npm.disable_session=是处去
@@ -125,8 +126,8 @@ user.profile.input_value=求 {ATTR} 之量
user.profile.set_success=君 {ATTR} 方设 {VALUE} 而成 user.profile.set_success=君 {ATTR} 方设 {VALUE} 而成
user.profile.set_failed={ATTR} 无以设,子阙否 user.profile.set_failed={ATTR} 无以设,子阙否
rpm.move_up= rpm.move_up=
rpm.move_down= rpm.move_down=
rpm.move_top=归首 rpm.move_top=归首
weather.city_not_found=无城谓 {CITY} 者 weather.city_not_found=无城谓 {CITY} 者
@@ -138,8 +139,8 @@ status.groups=羣
status.plugins=附件 status.plugins=附件
status.resources=件资 status.resources=件资
status.bots=工造灵机 status.bots=工造灵机
status.message_sent=方 status.message_sent=方
status.message_received=方 status.message_received=方
status.cpu=卷枢 status.cpu=卷枢
status.memory=暂贮 status.memory=暂贮
status.swap=变贮 status.swap=变贮
@@ -148,7 +149,7 @@ status.usage=计用
status.total=合 status.total=合
status.used=占 status.used=占
status.free=余 status.free=余
status.runtime= status.runtime=期
status.days=日 status.days=日
status.hours=小时 status.hours=小时
status.minutes=分 status.minutes=分