diff --git a/plugins/word_bank/__init__.py b/plugins/word_bank/__init__.py index 38fd6cdc..3e8535db 100644 --- a/plugins/word_bank/__init__.py +++ b/plugins/word_bank/__init__.py @@ -1,7 +1,6 @@ from configs.config import Config import nonebot - Config.add_plugin_config( "word_bank", "WORD_BANK_LEVEL [LEVEL]", @@ -11,6 +10,25 @@ Config.add_plugin_config( default_value=5 ) - +Config.add_plugin_config( + "word_bank", + "WORD_BANK_FUZZY", + False, + help_="模糊匹配", + default_value=False +) +Config.add_plugin_config( + "word_bank", + "WORD_BANK_KEY", + True, + help_="关键字匹配", + default_value=True +) +Config.add_plugin_config( + "word_bank", + "WORD_BANK_MIX", + 25, + help_="查看词条时图片内最多显示条数", + default_value=25 +) nonebot.load_plugins("plugins/word_bank") - diff --git a/plugins/word_bank/message_handle.py b/plugins/word_bank/message_handle.py index 30000959..c401b651 100644 --- a/plugins/word_bank/message_handle.py +++ b/plugins/word_bank/message_handle.py @@ -5,36 +5,40 @@ from configs.path_config import DATA_PATH from nonebot.adapters.onebot.v11 import GroupMessageEvent from utils.utils import get_message_text from nonebot import on_message - +from models.group_member_info import GroupInfoUser __zx_plugin_name__ = "词库问答回复操作 [Hidden]" - data_dir = DATA_PATH / "word_bank" data_dir.mkdir(parents=True, exist_ok=True) - -message_handle = on_message(priority=5, block=True, rule=check) +message_handle = on_message(priority=6, block=True, rule=check) @message_handle.handle() async def _(event: GroupMessageEvent): - path = data_dir / f"{event.group_id}" q = await WordBank.check( event.group_id, get_message_text(event.json()), event.is_tome() ) + await message_handle.send(await get_one_answer(event, q.format, q.answer)) + + +# 处理单条回答 +async def get_one_answer(event, format, _answer, all=1): + path = data_dir / f"{event.group_id}" placeholder_list = ( [ (x.split("<_s>")[0], x.split("<_s>")[1]) - for x in q.format.split("")[:-1] + for x in format.split("")[:-1] ] - if q.format + if format else [] ) answer = "" - _a = q.answer + _a = _answer if not placeholder_list: answer = _a + return answer else: for idx, placeholder in placeholder_list: if placeholder.endswith("jpg"): @@ -42,6 +46,11 @@ async def _(event: GroupMessageEvent): path / placeholder ) else: - answer += _a[: _a.find(f"[__placeholder_{idx}]")] + at(placeholder) - _a = _a[_a.find(f"[__placeholder_{idx}]") + len(f"[__placeholder_{idx}]") :] - await message_handle.send(answer) + if all == 1: + answer += _a[: _a.find(f"[__placeholder_{idx}]")] + at(placeholder) + else: + q = await GroupInfoUser.get_member_info( + int(placeholder), event.group_id) + answer += _a[: _a.find(f"[__placeholder_{idx}]")] + "@" + q.user_name + _a = _a[_a.find(f"[__placeholder_{idx}]") + len(f"[__placeholder_{idx}]"):] + return answer + _a diff --git a/plugins/word_bank/model.py b/plugins/word_bank/model.py index 91e8a5f3..1b5726a7 100644 --- a/plugins/word_bank/model.py +++ b/plugins/word_bank/model.py @@ -5,6 +5,7 @@ from pathlib import Path from configs.path_config import DATA_PATH import re import random +from configs.config import Config class WordBank(db.Model): @@ -83,7 +84,7 @@ class WordBank(db.Model): for x, y in format_: _str += f"{x}<_s>{y}" return await cls._problem_answer_handle( - user_id, group_id, problem, "update", answer=answer,index=index, format_=_str + user_id, group_id, problem, "update", answer=answer, index=index, format_=_str ) @classmethod @@ -113,7 +114,8 @@ class WordBank(db.Model): q = await cls.query.where( (cls.group_id == group_id) & (cls.problem == problem) ).gino.all() - return [x.answer for x in q] if q else None + + return [(x.answer, x.format) for x in q] if q else None @classmethod async def get_group_all_problem(cls, group_id: int) -> List[str]: @@ -154,9 +156,28 @@ class WordBank(db.Model): return x return None else: - q = await cls.query.where( - (cls.group_id == group_id) & (cls.problem == problem) - ).gino.all() + if problem: + FUZZY = Config.get_config("word_bank", "WORD_BANK_FUZZY") + KEY = Config.get_config("word_bank", "WORD_BANK_KEY") + if KEY and FUZZY: + q_fuzzy = await cls.query.where( + (cls.group_id == group_id) & (cls.problem.contains(f'{problem}'))).gino.all() + q_key = await cls.query.where(cls.group_id == group_id).gino.all() + q_key = [x for x in q_key if str(x.problem) in (problem)] + q = q_fuzzy + q_key + elif FUZZY: + q = await cls.query.where( + (cls.group_id == group_id) & (cls.problem.contains(f'{problem}'))).gino.all() + elif KEY: + q = await cls.query.where(cls.group_id == group_id).gino.all() + q = [x for x in q if str(x.problem) in (problem)] + else: + q = await cls.query.where( + (cls.group_id == group_id) & (cls.problem == problem) + ).gino.all() + else: + return None + return random.choice(q) if q else None @classmethod @@ -209,10 +230,6 @@ class WordBank(db.Model): if q: path = DATA_PATH / "word_bank" / f"{group_id}" if index is not None: - _q = [x.problem for x in q] - _q.sort() - prob = _q[index] - index = [x.problem for x in q].index(prob) q = [q[index]] answer = "\n".join([x.answer for x in q]) for x in q: @@ -225,22 +242,19 @@ class WordBank(db.Model): if _path.exists(): _path.unlink() await cls.delete.where( - (cls.problem == problem) + (cls.update_time == x.update_time) + & (cls.problem == problem) & (cls.answer == x.answer) & (cls.group_id == group_id) ).gino.status() return answer elif type_ == "update": - new_format =format_ + new_format = format_ new_answer = answer q = await q.with_for_update().gino.all() if q: path = DATA_PATH / "word_bank" / f"{group_id}" if index is not None: - _q = [x.problem for x in q] - _q.sort() - prob = _q[index] - index = [x.problem for x in q].index(prob) q = [q[index]] else: q = [q[0]] @@ -259,6 +273,8 @@ class WordBank(db.Model): (cls.problem == problem) & (cls.answer == x.answer) & (cls.group_id == group_id) + & (cls.group_id == group_id) + & (cls.update_time == x.update_time) ).gino.status() return True elif type_ == "get": diff --git a/plugins/word_bank/word_hanlde.py b/plugins/word_bank/word_hanlde.py index f37e422f..b6502d29 100644 --- a/plugins/word_bank/word_hanlde.py +++ b/plugins/word_bank/word_hanlde.py @@ -7,6 +7,7 @@ from ._data_source import WordBankBuilder from configs.config import Config from utils.message_builder import image from utils.image_utils import text2image +from .message_handle import get_one_answer from .model import WordBank from nonebot.adapters.onebot.v11 import ( Bot, @@ -18,6 +19,7 @@ from nonebot import on_command import random import os import re +from configs.config import NICKNAME, Config __zx_plugin_name__ = "词库问答 [Admin]" __plugin_usage__ = """ @@ -50,7 +52,7 @@ __plugin_cmd__ = [ __plugin_version__ = 0.1 __plugin_author__ = "HibiKier" __plugin_settings__ = { - "admin_level": Config.get_config("word_bank", "WORD_BANK_LEVEL"), + "admin_level": Config.get_config("word_bank", "WORD_BANK_LEVEL [LEVEL]"), "cmd": ["词库问答", "添加词条", "删除词条", "修改词条", "查看词条"], } @@ -170,29 +172,78 @@ async def _(bot: Bot, event: GroupMessageEvent, arg: Message = CommandArg()): @show_word.handle() -async def _(event: GroupMessageEvent, arg: Message = CommandArg()): +async def _(bot: Bot, event: GroupMessageEvent, arg: Message = CommandArg()): msg = arg.extract_plain_text().strip() if not msg: _problem_list = await WordBank.get_group_all_problem(event.group_id) if not _problem_list: await show_word.finish("该群未收录任何词条..") _problem_list = [f"\t{i}. {x}" for i, x in enumerate(_problem_list)] - await show_word.send( - image( - b64=(await text2image( - "该群已收录的词条:\n\n" + "\n".join(_problem_list), - padding=10, - color="#f9f6f2", - )).pic2bs4() + long_problem_list = len(_problem_list) + max_line = Config.get_config("word_bank", "WORD_BANK_MIX") + if long_problem_list > max_line: + pic_list = [] + mes_list = [] + img_nu = long_problem_list // max_line + one_msg = "该群已收录的词条:" + await show_word.send(one_msg) + for i in range(img_nu + 1): + if _problem_list: + one_img = image( + b64=(await text2image("\n".join(_problem_list[:max_line]), + padding=10, + color="#f9f6f2", + )).pic2bs4() + ) + if img_nu > 2: + pic_list.append(one_img) + else: + await show_word.send(one_img) + del _problem_list[:max_line] + if pic_list: + for img in pic_list: + data = { + "type": "node", + "data": {"name": f"{NICKNAME}", "uin": f"{bot.self_id}", "content": img}, + } + mes_list.append(data) + await bot.send_group_forward_msg(group_id=event.group_id, messages=mes_list) + else: + await show_word.send( + image( + b64=(await text2image( + "该群已收录的词条:\n\n" + "\n".join(_problem_list), + padding=10, + color="#f9f6f2", + )).pic2bs4() + ) ) - ) else: _answer_list = await WordBank.get_group_all_answer(event.group_id, msg) if not _answer_list: await show_word.send("未收录该词条...") + else: - _answer_list = [f"{i}. {x}" for i, x in enumerate(_answer_list)] - await show_word.send(f"词条 {msg} 回答:\n" + "\n".join(_answer_list)) + + # 解析图片和@ + _answer_img_nu_list = [await get_one_answer(event, format, answer, 0) for answer, format in _answer_list] + word_nu = len(_answer_img_nu_list) + img_nu = 0 + answer = f"词条 {msg} 回答:" + for i, x, in enumerate(_answer_img_nu_list): + r = re.findall(rf"\[CQ:image,file=", str(x)) + if r: + img_nu += len(r) + answer += "\n" + f"{i}." + x + if (img_nu > 2 and word_nu > 5) or word_nu > 10 or img_nu > 4: + data = { + "type": "node", + "data": {"name": f"{NICKNAME}", "uin": f"{bot.self_id}", "content": answer}, + } + await bot.send_group_forward_msg(group_id=event.group_id, messages=data) + else: + await show_word.send(answer) + # await show_word.send(f"词条 {msg} 回答:\n" + "\n".join(_answer_list)) async def get__builder(event, _problem, answer, idx):