diff --git a/.gitignore b/.gitignore index 42103025..53aa4128 100644 --- a/.gitignore +++ b/.gitignore @@ -142,7 +142,6 @@ test.py server_ip.py member_activity_handle.py Yu-Gi-Oh/ -search_image/ black_word/ csgo/ fantasy_card/ diff --git a/README.md b/README.md index 08eb1b49..c08eb97a 100644 --- a/README.md +++ b/README.md @@ -236,6 +236,11 @@ __Docker 最新版本由 [Sakuracio](https://github.com/Sakuracio) 提供__ ## 更新 +### 2022/3/18 \[v0.1.4.4] + +* 修复戳一戳无法功能关闭与ban禁用 +* 新增图片搜索 search_image + ### 2022/3/7 * 优化增删权限插件 @@ -301,7 +306,6 @@ __Docker 最新版本由 [Sakuracio](https://github.com/Sakuracio) 提供__ * 适配nonebot.beta2 * 删除图片搜索 nonebot_plugin_picsearcher -* 新增图片搜索 search_image * 替换cos api * 原神签到树脂提醒新增绑定群里,在某群绑定uid就会在某群发送提醒信息(有好友则私聊,需要重新绑定uid * 修改update_info.json diff --git a/__version__ b/__version__ index b7aa5f58..804f21b7 100644 --- a/__version__ +++ b/__version__ @@ -1 +1 @@ -__version__: v0.1.4.3 \ No newline at end of file +__version__: v0.1.4.4 \ No newline at end of file diff --git a/basic_plugins/hooks/_utils.py b/basic_plugins/hooks/_utils.py index 55d08d08..8e7ab0e0 100644 --- a/basic_plugins/hooks/_utils.py +++ b/basic_plugins/hooks/_utils.py @@ -2,6 +2,10 @@ from nonebot.adapters.onebot.v11 import GroupMessageEvent, PrivateMessageEvent from utils.manager import plugins2block_manager, StaticData import time +ignore_rst_module = ["ai", "poke", "dialogue"] + +other_limit_plugins = ["poke"] + class StatusMessageManager(StaticData): diff --git a/basic_plugins/hooks/auth_hook.py b/basic_plugins/hooks/auth_hook.py index ce012e6f..a379937a 100755 --- a/basic_plugins/hooks/auth_hook.py +++ b/basic_plugins/hooks/auth_hook.py @@ -13,7 +13,12 @@ from utils.manager import ( plugins2block_manager, plugins2count_manager, ) -from ._utils import set_block_limit_false, status_message_manager +from ._utils import ( + set_block_limit_false, + status_message_manager, + ignore_rst_module, + other_limit_plugins, +) from nonebot.typing import T_State from typing import Optional from nonebot.adapters.onebot.v11 import ( @@ -37,12 +42,10 @@ _flmt_g = FreqLimiter(Config.get_config("hook", "CHECK_NOTICE_INFO_CD")) _flmt_s = FreqLimiter(Config.get_config("hook", "CHECK_NOTICE_INFO_CD")) _flmt_c = FreqLimiter(Config.get_config("hook", "CHECK_NOTICE_INFO_CD")) -ignore_rst_module = ["ai", "poke", "dialogue"] - # 权限检测 @run_preprocessor -async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State): +async def _(matcher: Matcher, bot: Bot, event: Event, state: T_State): module = matcher.plugin_name plugins2info_dict = plugins2settings_manager.get_data() # 功能的金币检测 ####################################### @@ -64,7 +67,7 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State): await BagUser.spend_gold(event.user_id, event.group_id, cost_gold) try: if ( - (not isinstance(event, MessageEvent) and module != "poke") + (not isinstance(event, MessageEvent) and module not in other_limit_plugins) or await BanUser.is_ban(event.user_id) and str(event.user_id) not in bot.config.superusers ) or ( @@ -88,7 +91,7 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State): except AttributeError: pass # 群黑名单检测 群总开关检测 - if isinstance(event, GroupMessageEvent) or matcher.plugin_name == "poke": + if isinstance(event, GroupMessageEvent) or matcher.plugin_name == other_limit_plugins: try: if ( group_manager.get_group_level(event.group_id) < 0 @@ -145,9 +148,7 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State): raise IgnoredException("权限不足") if module in plugins2info_dict.keys() and matcher.priority not in [1, 9]: # 戳一戳单独判断 - if isinstance(event, GroupMessageEvent) or ( - isinstance(event, PokeNotifyEvent) and event.group_id - ): + if isinstance(event, GroupMessageEvent) or isinstance(event, PokeNotifyEvent) or matcher.plugin_name in other_limit_plugins: if status_message_manager.get(event.group_id) is None: status_message_manager.delete(event.group_id) if plugins2info_dict[module]["level"] > group_manager.get_group_level( diff --git a/basic_plugins/hooks/ban_hook.py b/basic_plugins/hooks/ban_hook.py index 757a7ed6..4f6a85e9 100755 --- a/basic_plugins/hooks/ban_hook.py +++ b/basic_plugins/hooks/ban_hook.py @@ -4,13 +4,16 @@ from nonebot.adapters.onebot.v11.exception import ActionFailed from nonebot.typing import T_State from nonebot.adapters.onebot.v11 import ( Bot, + Event, MessageEvent, + PokeNotifyEvent, GroupMessageEvent, ) from configs.config import Config from models.ban_user import BanUser from utils.utils import is_number, static_flmt, FreqLimiter from utils.message_builder import at +from ._utils import ignore_rst_module, other_limit_plugins Config.add_plugin_config( @@ -25,18 +28,19 @@ _flmt = FreqLimiter(300) # 检查是否被ban @run_preprocessor -async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State): - try: - if ( - await BanUser.is_super_ban(event.user_id) - and str(event.user_id) not in bot.config.superusers - ): - raise IgnoredException("用户处于超级黑名单中") - except AttributeError: - pass - if not isinstance(event, MessageEvent): - return - if matcher.type == "message" and matcher.priority not in [1, 9]: +async def _(matcher: Matcher, bot: Bot, event: Event, state: T_State): + if ( + (isinstance(event, MessageEvent) or isinstance(event, PokeNotifyEvent)) + and matcher.priority not in [1, 9] + ) or matcher.plugin_name in other_limit_plugins: + try: + if ( + await BanUser.is_super_ban(event.user_id) + and str(event.user_id) not in bot.config.superusers + ): + raise IgnoredException("用户处于超级黑名单中") + except AttributeError: + pass if ( await BanUser.is_ban(event.user_id) and str(event.user_id) not in bot.config.superusers @@ -57,7 +61,11 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State): if matcher.priority != 9: try: ban_result = Config.get_config("hook", "BAN_RESULT") - if ban_result and _flmt.check(event.user_id): + if ( + ban_result + and _flmt.check(event.user_id) + and matcher.plugin_name not in ignore_rst_module + ): _flmt.start_cd(event.user_id) await bot.send_group_msg( group_id=event.group_id, @@ -74,7 +82,7 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State): if matcher.priority != 9: try: ban_result = Config.get_config("hook", "BAN_RESULT") - if ban_result: + if ban_result and matcher.plugin_name not in ignore_rst_module: await bot.send_private_msg( user_id=event.user_id, message=at(event.user_id) diff --git a/plugins/genshin/query_user/_models/__init__.py b/plugins/genshin/query_user/_models/__init__.py index 71d11a76..a60285e4 100644 --- a/plugins/genshin/query_user/_models/__init__.py +++ b/plugins/genshin/query_user/_models/__init__.py @@ -254,6 +254,7 @@ class Genshin(db.Model): query = cls.query.where(cls.today_query_uid.contains(str(uid))) x = await query.gino.first() if x: + await cls._add_query_uid(uid, uid) return x.cookie for u in [ x for x in await cls.query.order_by(db.func.random()).gino.all() if x.cookie @@ -356,7 +357,7 @@ class Genshin(db.Model): """ query = cls.query.where(cls.uid == cookie_uid).with_for_update() user = await query.gino.first() - await user.update(today_query_uid=cls.today_query_uid + f"{uid} ").apply() + await user.update(today_query_uid=user.today_query_uid + f"{uid} ").apply() @classmethod async def _get_user_data( diff --git a/plugins/search_image/__init__.py b/plugins/search_image/__init__.py new file mode 100644 index 00000000..7f296034 --- /dev/null +++ b/plugins/search_image/__init__.py @@ -0,0 +1,91 @@ +from nonebot.plugin import on_command +from nonebot.adapters.onebot.v11 import Bot, MessageEvent, GroupMessageEvent, Message +from nonebot.typing import T_State +from services.log import logger +from utils.utils import get_message_img +from utils.message_builder import custom_forward_msg +from nonebot.params import CommandArg, Arg, ArgStr, Depends +from .saucenao import get_saucenao_image + + +__zx_plugin_name__ = "识图" +__plugin_usage__ = """ +usage: + 识别图片 [二次元图片] + 指令: + 识图 [图片] +""".strip() +__plugin_des__ = "以图搜图,看破本源" +__plugin_cmd__ = ["识图"] +__plugin_type__ = ("一些工具",) +__plugin_version__ = 0.1 +__plugin_author__ = "HibiKier" +__plugin_settings__ = { + "level": 5, + "default_status": True, + "limit_superuser": False, + "cmd": ["识图"], +} +__plugin_configs__ = { + "MAX_FIND_IMAGE_COUNT": {"value": 3, "help": "识图返回的最大结果数", "default_value": 3}, + "API_KEY": { + "value": None, + "help": "Saucenao的API_KEY,通过 https://saucenao.com/user.php?page=search-api 注册获取", + }, +} + + +search_image = on_command("识图", block=True, priority=5) + + +async def get_image_info(mod: str, url: str): + if mod == "saucenao": + return await get_saucenao_image(url) + + +def parse_image(key: str): + async def _key_parser( + state: T_State, img: Message = Arg(key) + ): + if not get_message_img(img): + await search_image.reject_arg(key, "请发送要识别的图片!") + state[key] = img + return _key_parser + + +@search_image.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State, arg: Message = CommandArg()): + msg = arg.extract_plain_text().strip() + if msg: + state["mod"] = msg + else: + state["mod"] = "saucenao" + if get_message_img(event.json()): + state["img"] = event.message + + +@search_image.got("img", prompt="图来!", parameterless=[Depends(parse_image("img"))]) +async def _( + bot: Bot, + event: MessageEvent, + state: T_State, + mod: str = ArgStr("mod"), + img: Message = Arg("img"), +): + img = get_message_img(img)[0] + await search_image.send("开始处理图片...") + msg = await get_image_info(mod, img) + if isinstance(msg, str): + await search_image.finish(msg, at_sender=True) + if isinstance(event, GroupMessageEvent): + await bot.send_group_forward_msg( + group_id=event.group_id, messages=custom_forward_msg(msg, bot.self_id) + ) + else: + for m in msg[1:]: + await search_image.send(m) + logger.info( + f"(USER {event.user_id}, GROUP " + f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})" + f" 识图:" + img + ) diff --git a/plugins/search_image/saucenao.py b/plugins/search_image/saucenao.py new file mode 100644 index 00000000..add20a49 --- /dev/null +++ b/plugins/search_image/saucenao.py @@ -0,0 +1,50 @@ +from utils.http_utils import AsyncHttpx +from configs.config import Config +from configs.path_config import TEMP_PATH +from utils.message_builder import image +from typing import Union, List +import random + +API_URL_SAUCENAO = "https://saucenao.com/search.php" +API_URL_ASCII2D = "https://ascii2d.net/search/url/" +API_URL_IQDB = "https://iqdb.org/" + + +async def get_saucenao_image(url: str) -> Union[str, List[str]]: + api_key = Config.get_config("search_image", "API_KEY") + if not api_key: + return "Saucenao 缺失API_KEY!" + + params = { + "output_type": 2, + "api_key": api_key, + "testmode": 1, + "numres": 6, + "db": 999, + "url": url, + } + data = (await AsyncHttpx.post(API_URL_SAUCENAO, params=params)).json() + if data["header"]["status"] != 0: + return "Saucenao识图失败.." + data = data["results"] + data = ( + data + if len(data) < Config.get_config("search_image", "MAX_FIND_IMAGE_COUNT") + else data[: Config.get_config("search_image", "MAX_FIND_IMAGE_COUNT")] + ) + msg_list = [] + index = random.randint(0, 10000) + if await AsyncHttpx.download_file( + url, TEMP_PATH / f"saucenao_search_{index}.jpg" + ): + msg_list.append(image(TEMP_PATH / f"saucenao_search_{index}.jpg")) + for info in data: + similarity = info["header"]["similarity"] + tmp = f"相似度:{similarity}%\n" + for x in info["data"].keys(): + if x != "ext_urls": + tmp += f"{x}:{info['data'][x]}\n" + if "source" not in info["data"].keys(): + tmp += f'source:{info["data"]["ext_urls"][0]}\n' + msg_list.append(tmp[:-1]) + return msg_list diff --git a/plugins/statistics/statistics_handle.py b/plugins/statistics/statistics_handle.py index e83f4e18..029ab2c7 100755 Binary files a/plugins/statistics/statistics_handle.py and b/plugins/statistics/statistics_handle.py differ diff --git a/update_info.json b/update_info.json index a1d8a124..a0f81cac 100644 --- a/update_info.json +++ b/update_info.json @@ -8,8 +8,7 @@ "configs/path_config.py", "configs/utils", "poetry.lock", - "pyproject.toml", - "resources/font" + "pyproject.toml" ], "add_file": [], "delete_file": []