From 226a2a336c9f0c503d9cc3d742636fecf424b2ec Mon Sep 17 00:00:00 2001 From: Eilles Date: Sun, 10 May 2026 17:08:50 +0800 Subject: [PATCH] =?UTF-8?q?=E7=8C=9C=E6=88=90=E8=AF=AD=EF=BC=9A=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E4=BB=A3=E7=A0=81=E7=BB=93=E6=9E=84=EF=BC=8C=E6=8F=90?= =?UTF-8?q?=E5=8D=87=E5=8F=AF=E8=AF=BB=E6=80=A7=EF=BC=8C=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=B0=8Fbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trimo_plugin_handle/__init__.py | 129 ++++-------------- .../trimo_plugin_handle/utils.py | 111 ++++++++++++--- 2 files changed, 120 insertions(+), 120 deletions(-) diff --git a/src/nonebot_plugins/trimo_plugin_handle/__init__.py b/src/nonebot_plugins/trimo_plugin_handle/__init__.py index b2732a7..9311f7d 100644 --- a/src/nonebot_plugins/trimo_plugin_handle/__init__.py +++ b/src/nonebot_plugins/trimo_plugin_handle/__init__.py @@ -4,26 +4,22 @@ from typing import Any, Dict from typing_extensions import Annotated import nonebot -from nonebot import on_regex, require, on_command +from nonebot import on_regex, require from nonebot.matcher import Matcher from nonebot.params import RegexDict from nonebot.plugin import PluginMetadata, inherit_supported_adapters from nonebot.rule import to_me from nonebot.utils import run_sync from nonebot.permission import SUPERUSER - -import json -from pypinyin import Style, pinyin +from nonebot.internal.adapter import Bot require("nonebot_plugin_alconna") require("nonebot_plugin_session") from nonebot_plugin_alconna import ( Alconna, - AlconnaQuery, Image, Option, - Query, Text, UniMessage, on_alconna, @@ -33,18 +29,13 @@ from nonebot_plugin_alconna import ( ) from nonebot_plugin_session import SessionId, SessionIdType -from src.utils.base.ly_typing import T_Bot - from .config import Config, handle_config from .data_source import GuessResult, Handle from .utils import ( random_idiom, + wordbase_updater, HANDLE_COMMON_PHRASES, HANDLE_LEGAL_PHRASES, - HANDLE_ANSWER_PHRASES, - handle_common_idiom_path, - handle_all_idiom_path, - handle_answer_path, ) __plugin_meta__ = PluginMetadata( @@ -94,7 +85,7 @@ handle = on_alconna( Alconna( "handle", Option("-s|--strict", default=False, action=store_true), - Option("-d|--hard", default=False, action=store_true), + Option("-d|--difficult", default=False, action=store_true), ), aliases=("猜成语",), rule=to_me() & game_not_running, @@ -171,7 +162,7 @@ async def _( ): nonebot.logger.info(result.options) is_strict = handle_config.handle_strict_mode or result.options["strict"].value - idiom, explanation = random_idiom(result.options["hard"].value) + idiom, explanation = random_idiom(result.options["difficult"].value) game = Handle(idiom, explanation, strict=is_strict) games[user_id] = game @@ -262,9 +253,6 @@ handle_update_pinyin = on_alconna( @handle_update_pinyin.handle() async def _( result: Arparma, - matcher: Matcher, - user_id: UserId, - bot: T_Bot, ): if not ( @@ -283,28 +271,24 @@ async def _( "未在词库中找到该成语,请使用 `新成语 <成语>` 来添加成语" ) - 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, + _, explanation, pinyin_now = wordbase_updater( + idiom, + explanation=None, + pinyin=[ + pinyin1, + pinyin2, + pinyin3, + pinyin4, + ], + hard=None, ) + 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) - ), + "\n\t释义:{}\n\t拼音:{}".format(explanation, " ".join(pinyin_now)), ) ) @@ -318,7 +302,7 @@ handle_update_idiom = on_alconna( args=Args["explanation", str, ""], ), Option( - "-d|--hard", + "-d|--difficult", default=False, action=store_true, ), @@ -335,76 +319,18 @@ handle_update_idiom = on_alconna( @handle_update_idiom.handle() async def _( result: Arparma, - matcher: Matcher, - user_id: UserId, - bot: T_Bot, ): if not (idiom := result.main_args["idiom"]): - await handle_update_idiom.finish("用法:新成语 <成语> [-e|--explanation <释义>] [-d|--hard]") - - existance = idiom in HANDLE_LEGAL_PHRASES - - try: - explanation = result.options["explanation"].args["explanation"] or None - 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, + await handle_update_idiom.finish( + "用法:新成语 <成语> [-e|--explanation <释义>] [-d|--difficult]" ) - if hard := result.options["hard"].value: - if idiom in HANDLE_COMMON_PHRASES: - HANDLE_COMMON_PHRASES.remove(idiom) - json.dump( - HANDLE_COMMON_PHRASES, - handle_common_idiom_path.open("w", encoding="utf-8"), - ensure_ascii=False, - indent=4, - sort_keys=True, - ) - else: - if idiom not in HANDLE_COMMON_PHRASES: - HANDLE_COMMON_PHRASES.append(idiom) - json.dump( - HANDLE_COMMON_PHRASES, - handle_common_idiom_path.open("w", encoding="utf-8"), - ensure_ascii=False, - indent=4, - sort_keys=True, - ) - HANDLE_ANSWER_PHRASES[idiom] = { - "explanation": explanation, - "pinyin": ( - pynow := ( - HANDLE_ANSWER_PHRASES[idiom]["pinyin"].copy() - if existance - else [ - j for i in pinyin(idiom, style=Style.TONE3, v_to_u=True) for j in i - ] - ) - ), - } - json.dump( - HANDLE_ANSWER_PHRASES, - handle_answer_path.open("w", encoding="utf-8"), - ensure_ascii=False, - indent=4, - sort_keys=True, + existance, explanation, pinyin_now = wordbase_updater( + idiom, + explanation=(result.options["explanation"].args["explanation"] or None), + pinyin=None, + hard=(hard := result.options["difficult"].value), ) await handle_update_idiom.finish( @@ -414,7 +340,7 @@ async def _( idiom, len(HANDLE_LEGAL_PHRASES), len(HANDLE_COMMON_PHRASES), - "\n\t释义:{}\n\t拼音:{}".format(explanation, " ".join(pynow)), + "\n\t释义:{}\n\t拼音:{}".format(explanation, " ".join(pinyin_now)), ) ) @@ -445,9 +371,8 @@ handle_answer = on_alconna( @handle_answer.handle() async def _( result: Arparma, - matcher: Matcher, user_id: UserId, - bot: T_Bot, + bot: Bot, ): if result.options["list"].value: diff --git a/src/nonebot_plugins/trimo_plugin_handle/utils.py b/src/nonebot_plugins/trimo_plugin_handle/utils.py index 0a399e1..7ea61af 100644 --- a/src/nonebot_plugins/trimo_plugin_handle/utils.py +++ b/src/nonebot_plugins/trimo_plugin_handle/utils.py @@ -2,7 +2,7 @@ import json import random from io import BytesIO from pathlib import Path -from typing import Dict, List, Tuple, Union, Literal, TypedDict +from typing import Dict, List, Tuple, TypedDict, Optional # from watchdog.observers import Observer # from watchdog.events import FileSystemEventHandler, FileModifiedEvent @@ -10,7 +10,7 @@ from typing import Dict, List, Tuple, Union, Literal, TypedDict from PIL import ImageFont from PIL.Image import Image as IMG from PIL.ImageFont import FreeTypeFont -from pypinyin import Style, pinyin +from pypinyin import Style, pinyin as py_get_pinyin resource_dir = Path(__file__).parent / "resources" fonts_dir = resource_dir / "fonts" @@ -70,10 +70,88 @@ HANDLE_ANSWER_PHRASES: Dict[str, IdiomEntry] = json.load( # json.dump({ i["word"]:{"explanation":i["explanation"], "pinyin":(lambda x : [i for j in pinyin(x, style=Style.TONE3, v_to_u=True) for i in j])(i["word"])} for i in json.load(open("answers_hard-old.json",encoding="utf-8"))},open("answers.json", "w",encoding="utf-8"), ensure_ascii=False, indent=4) +def wordbase_updater( + idiom: str, + explanation: Optional[str] = None, + pinyin: Optional[List[str]] = None, + hard: Optional[bool] = None, +) -> Tuple[bool, str, List[str]]: + """ + idiom: 需要更新或新增的成语词条 + explanation: 词条的释义,若 `None` 且在词库中不存在,则默认为“未提供该成语的解释说明” + pinyin: 词条的拼音,若 `None` 则默认求出拼音 + hard: 是否为难词,若 `None` 则不对难易词库修改 + + return: 是否为新增成语,成语释义,词条的拼音 + """ + if (not idiom) or (len(idiom) != 4): + raise ValueError("不可以非四字成语载入词库") + + if (existance := (idiom in HANDLE_LEGAL_PHRASES)) and (explanation is None): + # 这个判断的顺序必须高于下面的判断语句 + explanation = HANDLE_ANSWER_PHRASES[idiom]["explanation"] + + if explanation is None: + 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, + ) + else: + pinyin = pinyin or HANDLE_ANSWER_PHRASES[idiom]["pinyin"].copy() + if hard: + if idiom in HANDLE_COMMON_PHRASES: + HANDLE_COMMON_PHRASES.remove(idiom) + json.dump( + HANDLE_COMMON_PHRASES, + handle_common_idiom_path.open("w", encoding="utf-8"), + ensure_ascii=False, + indent=4, + sort_keys=True, + ) + else: + if (idiom not in HANDLE_COMMON_PHRASES) and (hard is not None): + HANDLE_COMMON_PHRASES.append(idiom) + json.dump( + HANDLE_COMMON_PHRASES, + handle_common_idiom_path.open("w", encoding="utf-8"), + ensure_ascii=False, + indent=4, + sort_keys=True, + ) + + HANDLE_ANSWER_PHRASES[idiom] = { + "explanation": explanation, + "pinyin": ( + pinyin := ( + pinyin + or [ + j + for i in py_get_pinyin(idiom, style=Style.TONE3, v_to_u=True) + for j in i + ] + ) + ), + } + json.dump( + HANDLE_ANSWER_PHRASES, + handle_answer_path.open("w", encoding="utf-8"), + ensure_ascii=False, + indent=4, + sort_keys=True, + ) + return not existance, explanation, pinyin + + def legal_idiom(word: str) -> bool: return word in HANDLE_LEGAL_PHRASES - def random_idiom(is_hard: bool = False) -> Tuple[str, str]: answer = random.choice(HANDLE_LEGAL_PHRASES if is_hard else HANDLE_COMMON_PHRASES) return answer, HANDLE_ANSWER_PHRASES[answer]["explanation"] @@ -126,22 +204,19 @@ def get_pinyin( idiom: 输入的汉字 return: 返回一个元组,每个元素是一个三元组,分别表示该汉字的声母,韵母,声调 """ - if idiom_entry := HANDLE_ANSWER_PHRASES.get(idiom): - pinyin_per_char = idiom_entry["pinyin"] - if not pinyin_per_char: - pinyin_per_char = [ - j for i in pinyin(idiom, style=Style.TONE3, v_to_u=True) for j in i - ] - idiom_entry["pinyin"] = pinyin_per_char.copy() - handle_answer_path.open("w", encoding="utf-8").write( - json.dumps(HANDLE_ANSWER_PHRASES, ensure_ascii=False, indent=4) - ) - else: - pinyin_per_char = [ - j for i in pinyin(idiom, style=Style.TONE3, v_to_u=True) for j in i - ] - return [split_pinyin(py) for py in pinyin_per_char] + return [ + split_pinyin(py) + for py in ( + wordbase_updater(idiom, explanation=None, pinyin=None, hard=None)[2] + if HANDLE_ANSWER_PHRASES.get(idiom, None) + else [ + j + for i in py_get_pinyin(idiom, style=Style.TONE3, v_to_u=True) + for j in i + ] + ) + ] def save_jpg(frame: IMG) -> BytesIO: