diff --git a/README.md b/README.md index 7d449056..952b7771 100644 --- a/README.md +++ b/README.md @@ -331,6 +331,10 @@ PS: **ARM平台** 请使用全量版 同时 **如果你的机器 RAM < 1G 可能 ## 更新 +### 2023/3/18 + +* 修复色图重复发送相同图片 + ### 2023/3/12 \[v0.1.6.7] * 新增`更新武器箱ALL`命令来更新所有武器箱 diff --git a/plugins/send_setu_/send_setu/__init__.py b/plugins/send_setu_/send_setu/__init__.py index fea7a114..7b78db9e 100755 --- a/plugins/send_setu_/send_setu/__init__.py +++ b/plugins/send_setu_/send_setu/__init__.py @@ -13,12 +13,13 @@ from nonebot.adapters.onebot.v11 import ( ) from nonebot.matcher import Matcher from nonebot.message import run_postprocessor -from nonebot.params import Command, CommandArg, RegexGroup +from nonebot.params import CommandArg, RegexGroup from nonebot.typing import T_State from configs.config import NICKNAME, Config from models.sign_group_user import SignGroupUser from services.log import logger +from utils.depends import OneCommand from utils.manager import withdraw_message_manager from utils.message_builder import custom_forward_msg from utils.utils import is_number @@ -27,7 +28,6 @@ from .._model import Setu from .data_source import ( add_data_to_database, check_local_exists_or_download, - find_img_index, gen_message, get_luoxiang, get_setu_list, @@ -59,7 +59,13 @@ usage: tag至多取前20项,| 为或,萝莉|少女=萝莉或者少女 """.strip() __plugin_des__ = "不要小看涩图啊混蛋!" -__plugin_cmd__ = ["色图 ?[id]", "色图 ?[tags]", "色图r ?[tags]", "[1-9]张?[tags]色图", "[1-9]张色图?[tags]"] +__plugin_cmd__ = [ + "色图 ?[id]", + "色图 ?[tags]", + "色图r ?[tags]", + "[1-9]张?[tags]色图", + "[1-9]张色图?[tags]", +] __plugin_type__ = ("来点好康的",) __plugin_version__ = 0.1 __plugin_author__ = "HibiKier" @@ -130,7 +136,7 @@ setu_data_list = [] @run_postprocessor -async def do_something( +async def _( matcher: Matcher, exception: Optional[Exception], bot: Bot, @@ -160,7 +166,7 @@ setu_reg = on_regex("(.*)[份|发|张|个|次|点](.*)[瑟|色|涩]图(r?)(.*)$" async def _( bot: Bot, event: MessageEvent, - cmd: Tuple[str, ...] = Command(), + cmd: str = OneCommand(), arg: Message = CommandArg(), ): msg = arg.extract_plain_text().strip() @@ -169,16 +175,15 @@ async def _( user_qq=event.user_id, group_id=event.group_id ) impression = user.impression - luox = get_luoxiang(impression) - if luox: + if luox := get_luoxiang(impression): await setu.finish(luox) r18 = False num = 1 # 是否看r18 - if cmd[0] == "色图r" and isinstance(event, PrivateMessageEvent): + if cmd == "色图r" and isinstance(event, PrivateMessageEvent): r18 = True num = 10 - elif cmd[0] == "色图r" and isinstance(event, GroupMessageEvent): + elif cmd == "色图r" and isinstance(event, GroupMessageEvent): if not Config.get_config("send_setu", "ALLOW_GROUP_R18"): await setu.finish( random.choice(["这种不好意思的东西怎么可能给这么多人看啦", "羞羞脸!给我滚出克私聊!", "变态变态变态变态大变态!"]) @@ -191,13 +196,12 @@ async def _( if code != 200: await setu.finish(setu_list[0], at_sender=True) setu_img, code = await check_local_exists_or_download(setu_list[0]) - msg_id = await setu.send( - Message(gen_message(setu_list[0])) + setu_img, at_sender=True - ) + msg_id = await setu.send(gen_message(setu_list[0]) + setu_img, at_sender=True) logger.info( - f"(USER {event.user_id}, GROUP " - f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})" - f" 发送色图 {setu_list[0].local_id}.jpd" + f"发送色图 {setu_list[0].local_id}.jpg", + cmd, + event.user_id, + getattr(event, "group_id", None), ) if msg_id: withdraw_message_manager.withdraw_message( @@ -206,7 +210,7 @@ async def _( Config.get_config("send_setu", "WITHDRAW_SETU_MESSAGE"), ) return - await send_setu_handle(bot, setu, event, cmd[0], msg, num, r18) + await send_setu_handle(bot, setu, event, cmd, msg, num, r18) num_key = { @@ -231,11 +235,10 @@ async def _(bot: Bot, event: MessageEvent, reg_group: Tuple[Any, ...] = RegexGro user_qq=event.user_id, group_id=event.group_id ) impression = user.impression - luox = get_luoxiang(impression) - if luox: + if luox := get_luoxiang(impression): await setu.finish(luox, at_sender=True) num, tags, r18, tags2 = reg_group - num = num or 1 + num = num or "一" tags = tags[:-1] if tags and tags[-1] == "的" else tags if num_key.get(num): num = num_key[num] @@ -252,7 +255,9 @@ async def _(bot: Bot, event: MessageEvent, reg_group: Tuple[Any, ...] = RegexGro if limit and num > limit: num = limit await setu.send(f"一次只能给你看 {num} 张哦") - await send_setu_handle(bot, setu_reg, event, "色图r" if r18 else "色图", tags + " " + tags2, num, r18) + await send_setu_handle( + bot, setu_reg, event, "色图r" if r18 else "色图", tags + " " + tags2, num, r18 + ) async def send_setu_handle( @@ -273,6 +278,7 @@ async def send_setu_handle( # 本地先拿图,下载失败补上去 setu_list, code = None, 200 setu_count = await Setu.filter(is_r18=r18).count() + max_once_num2forward = Config.get_config("send_setu", "MAX_ONCE_NUM2FORWARD") if ( not Config.get_config("send_setu", "ONLY_USE_LOCAL_SETU") and tags ) or setu_count <= 0: @@ -294,14 +300,14 @@ async def send_setu_handle( # 下载成功的话 if index != -1: logger.info( - f"(USER {event.user_id}, GROUP " - f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})" - f" 发送色图 {index}.png" + f"发送色图 {index}.png", + "command", + event.user_id, + getattr(event, "group_id", None), ) if ( - Config.get_config("send_setu", "MAX_ONCE_NUM2FORWARD") - and num - >= Config.get_config("send_setu", "MAX_ONCE_NUM2FORWARD") + max_once_num2forward + and num >= max_once_num2forward and isinstance(event, GroupMessageEvent) ): forward_list.append(Message(f"{text_list[i]}\n{setu_img}")) @@ -318,38 +324,28 @@ async def send_setu_handle( setu_image = random.choice(setu_list) setu_list.remove(setu_image) if ( - Config.get_config("send_setu", "MAX_ONCE_NUM2FORWARD") - and num - >= Config.get_config( - "send_setu", "MAX_ONCE_NUM2FORWARD" - ) + max_once_num2forward + and num >= max_once_num2forward and isinstance(event, GroupMessageEvent) ): forward_list.append( - Message( - gen_message(setu_image) - + ( - await check_local_exists_or_download( - setu_image - ) - )[0] - ) + gen_message(setu_image) + + ( + await check_local_exists_or_download(setu_image) + )[0] ) else: msg_id = await matcher.send( - Message( - gen_message(setu_image) - + ( - await check_local_exists_or_download( - setu_image - ) - )[0] - ) + gen_message(setu_image) + + ( + await check_local_exists_or_download(setu_image) + )[0] ) logger.info( - f"(USER {event.user_id}, GROUP " - f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})" - f" 发送本地色图 {setu_image.local_id}.png" + f"发送本地色图 {setu_image.local_id}.png", + "command", + event.user_id, + getattr(event, "group_id", None), ) else: msg_id = await matcher.send(text_list[i] + "\n" + setu_img) @@ -361,7 +357,7 @@ async def send_setu_handle( ) except ActionFailed: await matcher.finish("坏了,这张图色过头了,我自己看看就行了!", at_sender=True) - if forward_list: + if forward_list and isinstance(event, GroupMessageEvent): msg_id = await bot.send_group_forward_msg( group_id=event.group_id, messages=custom_forward_msg(forward_list, bot.self_id), @@ -387,8 +383,8 @@ async def send_setu_handle( setu_image = random.choice(setu_list) setu_list.remove(setu_image) if ( - Config.get_config("send_setu", "MAX_ONCE_NUM2FORWARD") - and num >= Config.get_config("send_setu", "MAX_ONCE_NUM2FORWARD") + max_once_num2forward + and num >= max_once_num2forward and isinstance(event, GroupMessageEvent) ): forward_list.append( @@ -400,10 +396,8 @@ async def send_setu_handle( else: try: msg_id = await matcher.send( - Message( - gen_message(setu_image) - + (await check_local_exists_or_download(setu_image))[0] - ) + gen_message(setu_image) + + (await check_local_exists_or_download(setu_image))[0] ) withdraw_message_manager.withdraw_message( event, @@ -411,13 +405,14 @@ async def send_setu_handle( Config.get_config("send_setu", "WITHDRAW_SETU_MESSAGE"), ) logger.info( - f"(USER {event.user_id}, GROUP " - f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})" - f" 发送本地色图 {setu_image.local_id}.png" + f"发送本地色图 {setu_image.local_id}.png", + "command", + event.user_id, + getattr(event, "group_id", None), ) except ActionFailed: await matcher.finish("坏了,这张图色过头了,我自己看看就行了!", at_sender=True) - if forward_list: + if forward_list and isinstance(event, GroupMessageEvent): msg_id = await bot.send_group_forward_msg( group_id=event.group_id, messages=custom_forward_msg(forward_list, bot.self_id), diff --git a/plugins/send_setu_/send_setu/data_source.py b/plugins/send_setu_/send_setu/data_source.py index e249f160..70cea1cd 100755 --- a/plugins/send_setu_/send_setu/data_source.py +++ b/plugins/send_setu_/send_setu/data_source.py @@ -3,10 +3,10 @@ import os import random import re from asyncio.exceptions import TimeoutError -from typing import List, Optional, Tuple, Union +from typing import Any, List, Optional, Tuple, Union from asyncpg.exceptions import UniqueViolationError -from nonebot.adapters.onebot.v11 import Message, MessageSegment +from nonebot.adapters.onebot.v11 import MessageSegment from configs.config import NICKNAME, Config from configs.path_config import IMAGE_PATH, TEMP_PATH @@ -14,16 +14,10 @@ from services.log import logger from utils.http_utils import AsyncHttpx from utils.image_utils import compressed_image, get_img_hash from utils.message_builder import image -from utils.utils import change_img_md5 +from utils.utils import change_img_md5, change_pixiv_image_links from .._model import Setu -try: - import ujson as json -except ModuleNotFoundError: - import json - - url = "https://api.lolicon.app/setu/v2" path = "_setu" r18_path = "_r18" @@ -42,7 +36,7 @@ async def get_setu_urls( "size": ["original"], } for count in range(3): - logger.info(f"get_setu_url: count --> {count}") + logger.debug(f"尝试获取图片URL第 {count+1} 次", "色图") try: response = await AsyncHttpx.get( url, timeout=Config.get_config("send_setu", "TIMEOUT"), params=params @@ -70,10 +64,10 @@ async def get_setu_urls( return x_urls, x_text_lst, add_databases_list, 200 else: return ["没找到符合条件的色图..."], [], [], 401 - except TimeoutError: - pass + except TimeoutError as e: + logger.error(f"获取图片URL超时", "色图", e=e) except Exception as e: - logger.error(f"send_setu 访问页面错误 {type(e)}:{e}") + logger.error(f"访问页面错误", "色图", e=e) return ["我网线被人拔了..QAQ"], [], [], 999 @@ -93,43 +87,40 @@ async def search_online_setu( :param id_: 本地id :param path_: 存储路径 """ - ws_url = Config.get_config("pixiv", "PIXIV_NGINX_URL") - if ws_url: - host_match = re.match(host_pattern, url_) - host = host_match.group(1) - url_ = url_.replace(host, ws_url) + url_ = change_pixiv_image_links(url_) index = random.randint(1, 100000) if id_ is None else id_ - path_ = IMAGE_PATH / path_ if path_ else TEMP_PATH + base_path = IMAGE_PATH / path_ if path_ else TEMP_PATH file_name = f"{index}_temp_setu.jpg" if path_ == TEMP_PATH else f"{index}.jpg" - path_.mkdir(parents=True, exist_ok=True) + file = base_path / file_name + base_path.mkdir(parents=True, exist_ok=True) for i in range(3): - logger.info(f"search_online_setu --> {i}") + logger.debug(f"尝试在线搜索第 {i+1} 次", "色图") try: if not await AsyncHttpx.download_file( url_, - path_ / file_name, + file, timeout=Config.get_config("send_setu", "TIMEOUT"), ): continue if id_ is not None: - if os.path.getsize(path_ / f"{index}.jpg") > 1024 * 1024 * 1.5: + if os.path.getsize(base_path / f"{index}.jpg") > 1024 * 1024 * 1.5: compressed_image( - path_ / f"{index}.jpg", + base_path / f"{index}.jpg", ) logger.info(f"下载 lolicon 图片 {url_} 成功, id:{index}") - change_img_md5(path_ / file_name) - return image(path_ / file_name), index - except TimeoutError: - pass + change_img_md5(file) + return image(file), index + except TimeoutError as e: + logger.error(f"下载图片超时", "色图", e=e) except Exception as e: - logger.error(f"send_setu 下载图片错误 {type(e)}:{e}") + logger.error(f"下载图片错误", "色图", e=e) return "图片被小怪兽恰掉啦..!QAQ", -1 # 检测本地是否有id涩图,无的话则下载 async def check_local_exists_or_download( setu_image: Setu, -) -> Tuple[MessageSegment, int]: +) -> Tuple[Union[MessageSegment, str], int]: path_ = None id_ = None if Config.get_config("send_setu", "DOWNLOAD_SETU"): @@ -182,45 +173,45 @@ async def get_setu_list( image_list = await Setu.query_image(r18=r18) if not image_list: return ["没找到符合条件的色图..."], 998 - return image_list, 200 + return image_list, 200 # type: ignore # 初始化消息 -def gen_message( - setu_image: Setu -) -> Union[Message, MessageSegment]: +def gen_message(setu_image: Setu) -> str: + """判断是否获取图片信息 + + Args: + setu_image (Setu): Setu + + Returns: + str: 图片信息 + """ local_id = setu_image.local_id title = setu_image.title author = setu_image.author pid = setu_image.pid - path_ = r18_path if setu_image.is_r18 else path - image_path = IMAGE_PATH / path_ / f"{local_id}.jpg" if Config.get_config("send_setu", "SHOW_INFO"): - return Message( - f"id:{local_id}\n" - f"title:{title}\n" - f"author:{author}\n" - f"PID:{pid}\n" + image(image_path) - ) - return image(image_path) + return f"id:{local_id}\n" f"title:{title}\n" f"author:{author}\n" f"PID:{pid}\n" + return "" # 罗翔老师! def get_luoxiang(impression): - probability = ( - float(impression) - + Config.get_config("send_setu", "INITIAL_SETU_PROBABILITY") * 100 + initial_setu_probability = Config.get_config( + "send_setu", "INITIAL_SETU_PROBABILITY" ) - if probability < random.randint(1, 101): - return ( - "我为什么要给你发这个?" - + image( - IMAGE_PATH - / "luoxiang" - / random.choice(os.listdir(IMAGE_PATH / "luoxiang")) + if initial_setu_probability: + probability = float(impression) + initial_setu_probability * 100 + if probability < random.randint(1, 101): + return ( + "我为什么要给你发这个?" + + image( + IMAGE_PATH + / "luoxiang" + / random.choice(os.listdir(IMAGE_PATH / "luoxiang")) + ) + + f"\n(快向{NICKNAME}签到提升好感度吧!)" ) - + f"\n(快向{NICKNAME}签到提升好感度吧!)" - ) return None @@ -243,17 +234,15 @@ async def find_img_index(img_url, user_id): # 处理色图数据 -def _setu_data_process(data: dict, command: str) -> "list, list, list": +def _setu_data_process( + data: dict, command: str +) -> Tuple[List[str], List[str], List[Tuple[Any, ...]]]: urls = [] text_list = [] add_databases_list = [] for i in range(len(data)): img_url = data[i]["urls"]["original"] - img_url = ( - img_url.replace("i.pixiv.cat", "i.pximg.net") - if "i.pixiv.cat" in img_url - else img_url - ) + img_url = change_pixiv_image_links(img_url) title = data[i]["title"] author = data[i]["author"] pid = data[i]["pid"]