修复色图重复发送相同图片

This commit is contained in:
HibiKier 2023-03-18 00:45:22 +08:00
parent 2796083c4c
commit ea54edcbcf
3 changed files with 110 additions and 122 deletions

View File

@ -331,6 +331,10 @@ PS: **ARM平台** 请使用全量版 同时 **如果你的机器 RAM < 1G 可能
## 更新 ## 更新
### 2023/3/18
* 修复色图重复发送相同图片
### 2023/3/12 \[v0.1.6.7] ### 2023/3/12 \[v0.1.6.7]
* 新增`更新武器箱ALL`命令来更新所有武器箱 * 新增`更新武器箱ALL`命令来更新所有武器箱

View File

@ -13,12 +13,13 @@ from nonebot.adapters.onebot.v11 import (
) )
from nonebot.matcher import Matcher from nonebot.matcher import Matcher
from nonebot.message import run_postprocessor 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 nonebot.typing import T_State
from configs.config import NICKNAME, Config from configs.config import NICKNAME, Config
from models.sign_group_user import SignGroupUser from models.sign_group_user import SignGroupUser
from services.log import logger from services.log import logger
from utils.depends import OneCommand
from utils.manager import withdraw_message_manager from utils.manager import withdraw_message_manager
from utils.message_builder import custom_forward_msg from utils.message_builder import custom_forward_msg
from utils.utils import is_number from utils.utils import is_number
@ -27,7 +28,6 @@ from .._model import Setu
from .data_source import ( from .data_source import (
add_data_to_database, add_data_to_database,
check_local_exists_or_download, check_local_exists_or_download,
find_img_index,
gen_message, gen_message,
get_luoxiang, get_luoxiang,
get_setu_list, get_setu_list,
@ -59,7 +59,13 @@ usage
tag至多取前20项| 为或萝莉|少女=萝莉或者少女 tag至多取前20项| 为或萝莉|少女=萝莉或者少女
""".strip() """.strip()
__plugin_des__ = "不要小看涩图啊混蛋!" __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_type__ = ("来点好康的",)
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = "HibiKier" __plugin_author__ = "HibiKier"
@ -130,7 +136,7 @@ setu_data_list = []
@run_postprocessor @run_postprocessor
async def do_something( async def _(
matcher: Matcher, matcher: Matcher,
exception: Optional[Exception], exception: Optional[Exception],
bot: Bot, bot: Bot,
@ -160,7 +166,7 @@ setu_reg = on_regex("(.*)[份|发|张|个|次|点](.*)[瑟|色|涩]图(r?)(.*)$"
async def _( async def _(
bot: Bot, bot: Bot,
event: MessageEvent, event: MessageEvent,
cmd: Tuple[str, ...] = Command(), cmd: str = OneCommand(),
arg: Message = CommandArg(), arg: Message = CommandArg(),
): ):
msg = arg.extract_plain_text().strip() msg = arg.extract_plain_text().strip()
@ -169,16 +175,15 @@ async def _(
user_qq=event.user_id, group_id=event.group_id user_qq=event.user_id, group_id=event.group_id
) )
impression = user.impression impression = user.impression
luox = get_luoxiang(impression) if luox := get_luoxiang(impression):
if luox:
await setu.finish(luox) await setu.finish(luox)
r18 = False r18 = False
num = 1 num = 1
# 是否看r18 # 是否看r18
if cmd[0] == "色图r" and isinstance(event, PrivateMessageEvent): if cmd == "色图r" and isinstance(event, PrivateMessageEvent):
r18 = True r18 = True
num = 10 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"): if not Config.get_config("send_setu", "ALLOW_GROUP_R18"):
await setu.finish( await setu.finish(
random.choice(["这种不好意思的东西怎么可能给这么多人看啦", "羞羞脸!给我滚出克私聊!", "变态变态变态变态大变态!"]) random.choice(["这种不好意思的东西怎么可能给这么多人看啦", "羞羞脸!给我滚出克私聊!", "变态变态变态变态大变态!"])
@ -191,13 +196,12 @@ async def _(
if code != 200: if code != 200:
await setu.finish(setu_list[0], at_sender=True) await setu.finish(setu_list[0], at_sender=True)
setu_img, code = await check_local_exists_or_download(setu_list[0]) setu_img, code = await check_local_exists_or_download(setu_list[0])
msg_id = await setu.send( msg_id = await setu.send(gen_message(setu_list[0]) + setu_img, at_sender=True)
Message(gen_message(setu_list[0])) + setu_img, at_sender=True
)
logger.info( logger.info(
f"(USER {event.user_id}, GROUP " f"发送色图 {setu_list[0].local_id}.jpg",
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})" cmd,
f" 发送色图 {setu_list[0].local_id}.jpd" event.user_id,
getattr(event, "group_id", None),
) )
if msg_id: if msg_id:
withdraw_message_manager.withdraw_message( withdraw_message_manager.withdraw_message(
@ -206,7 +210,7 @@ async def _(
Config.get_config("send_setu", "WITHDRAW_SETU_MESSAGE"), Config.get_config("send_setu", "WITHDRAW_SETU_MESSAGE"),
) )
return 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 = { 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 user_qq=event.user_id, group_id=event.group_id
) )
impression = user.impression impression = user.impression
luox = get_luoxiang(impression) if luox := get_luoxiang(impression):
if luox:
await setu.finish(luox, at_sender=True) await setu.finish(luox, at_sender=True)
num, tags, r18, tags2 = reg_group num, tags, r18, tags2 = reg_group
num = num or 1 num = num or ""
tags = tags[:-1] if tags and tags[-1] == "" else tags tags = tags[:-1] if tags and tags[-1] == "" else tags
if num_key.get(num): if num_key.get(num):
num = num_key[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: if limit and num > limit:
num = limit num = limit
await setu.send(f"一次只能给你看 {num} 张哦") 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( async def send_setu_handle(
@ -273,6 +278,7 @@ async def send_setu_handle(
# 本地先拿图,下载失败补上去 # 本地先拿图,下载失败补上去
setu_list, code = None, 200 setu_list, code = None, 200
setu_count = await Setu.filter(is_r18=r18).count() setu_count = await Setu.filter(is_r18=r18).count()
max_once_num2forward = Config.get_config("send_setu", "MAX_ONCE_NUM2FORWARD")
if ( if (
not Config.get_config("send_setu", "ONLY_USE_LOCAL_SETU") and tags not Config.get_config("send_setu", "ONLY_USE_LOCAL_SETU") and tags
) or setu_count <= 0: ) or setu_count <= 0:
@ -294,14 +300,14 @@ async def send_setu_handle(
# 下载成功的话 # 下载成功的话
if index != -1: if index != -1:
logger.info( logger.info(
f"(USER {event.user_id}, GROUP " f"发送色图 {index}.png",
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})" "command",
f" 发送色图 {index}.png" event.user_id,
getattr(event, "group_id", None),
) )
if ( if (
Config.get_config("send_setu", "MAX_ONCE_NUM2FORWARD") max_once_num2forward
and num and num >= max_once_num2forward
>= Config.get_config("send_setu", "MAX_ONCE_NUM2FORWARD")
and isinstance(event, GroupMessageEvent) and isinstance(event, GroupMessageEvent)
): ):
forward_list.append(Message(f"{text_list[i]}\n{setu_img}")) 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_image = random.choice(setu_list)
setu_list.remove(setu_image) setu_list.remove(setu_image)
if ( if (
Config.get_config("send_setu", "MAX_ONCE_NUM2FORWARD") max_once_num2forward
and num and num >= max_once_num2forward
>= Config.get_config(
"send_setu", "MAX_ONCE_NUM2FORWARD"
)
and isinstance(event, GroupMessageEvent) and isinstance(event, GroupMessageEvent)
): ):
forward_list.append( forward_list.append(
Message( gen_message(setu_image)
gen_message(setu_image) + (
+ ( await check_local_exists_or_download(setu_image)
await check_local_exists_or_download( )[0]
setu_image
)
)[0]
)
) )
else: else:
msg_id = await matcher.send( msg_id = await matcher.send(
Message( gen_message(setu_image)
gen_message(setu_image) + (
+ ( await check_local_exists_or_download(setu_image)
await check_local_exists_or_download( )[0]
setu_image
)
)[0]
)
) )
logger.info( logger.info(
f"(USER {event.user_id}, GROUP " f"发送本地色图 {setu_image.local_id}.png",
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})" "command",
f" 发送本地色图 {setu_image.local_id}.png" event.user_id,
getattr(event, "group_id", None),
) )
else: else:
msg_id = await matcher.send(text_list[i] + "\n" + setu_img) msg_id = await matcher.send(text_list[i] + "\n" + setu_img)
@ -361,7 +357,7 @@ async def send_setu_handle(
) )
except ActionFailed: except ActionFailed:
await matcher.finish("坏了,这张图色过头了,我自己看看就行了!", at_sender=True) await matcher.finish("坏了,这张图色过头了,我自己看看就行了!", at_sender=True)
if forward_list: if forward_list and isinstance(event, GroupMessageEvent):
msg_id = await bot.send_group_forward_msg( msg_id = await bot.send_group_forward_msg(
group_id=event.group_id, group_id=event.group_id,
messages=custom_forward_msg(forward_list, bot.self_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_image = random.choice(setu_list)
setu_list.remove(setu_image) setu_list.remove(setu_image)
if ( if (
Config.get_config("send_setu", "MAX_ONCE_NUM2FORWARD") max_once_num2forward
and num >= Config.get_config("send_setu", "MAX_ONCE_NUM2FORWARD") and num >= max_once_num2forward
and isinstance(event, GroupMessageEvent) and isinstance(event, GroupMessageEvent)
): ):
forward_list.append( forward_list.append(
@ -400,10 +396,8 @@ async def send_setu_handle(
else: else:
try: try:
msg_id = await matcher.send( msg_id = await matcher.send(
Message( gen_message(setu_image)
gen_message(setu_image) + (await check_local_exists_or_download(setu_image))[0]
+ (await check_local_exists_or_download(setu_image))[0]
)
) )
withdraw_message_manager.withdraw_message( withdraw_message_manager.withdraw_message(
event, event,
@ -411,13 +405,14 @@ async def send_setu_handle(
Config.get_config("send_setu", "WITHDRAW_SETU_MESSAGE"), Config.get_config("send_setu", "WITHDRAW_SETU_MESSAGE"),
) )
logger.info( logger.info(
f"(USER {event.user_id}, GROUP " f"发送本地色图 {setu_image.local_id}.png",
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})" "command",
f" 发送本地色图 {setu_image.local_id}.png" event.user_id,
getattr(event, "group_id", None),
) )
except ActionFailed: except ActionFailed:
await matcher.finish("坏了,这张图色过头了,我自己看看就行了!", at_sender=True) await matcher.finish("坏了,这张图色过头了,我自己看看就行了!", at_sender=True)
if forward_list: if forward_list and isinstance(event, GroupMessageEvent):
msg_id = await bot.send_group_forward_msg( msg_id = await bot.send_group_forward_msg(
group_id=event.group_id, group_id=event.group_id,
messages=custom_forward_msg(forward_list, bot.self_id), messages=custom_forward_msg(forward_list, bot.self_id),

View File

@ -3,10 +3,10 @@ import os
import random import random
import re import re
from asyncio.exceptions import TimeoutError 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 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.config import NICKNAME, Config
from configs.path_config import IMAGE_PATH, TEMP_PATH 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.http_utils import AsyncHttpx
from utils.image_utils import compressed_image, get_img_hash from utils.image_utils import compressed_image, get_img_hash
from utils.message_builder import image 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 from .._model import Setu
try:
import ujson as json
except ModuleNotFoundError:
import json
url = "https://api.lolicon.app/setu/v2" url = "https://api.lolicon.app/setu/v2"
path = "_setu" path = "_setu"
r18_path = "_r18" r18_path = "_r18"
@ -42,7 +36,7 @@ async def get_setu_urls(
"size": ["original"], "size": ["original"],
} }
for count in range(3): for count in range(3):
logger.info(f"get_setu_url: count --> {count}") logger.debug(f"尝试获取图片URL第 {count+1}", "色图")
try: try:
response = await AsyncHttpx.get( response = await AsyncHttpx.get(
url, timeout=Config.get_config("send_setu", "TIMEOUT"), params=params 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 return x_urls, x_text_lst, add_databases_list, 200
else: else:
return ["没找到符合条件的色图..."], [], [], 401 return ["没找到符合条件的色图..."], [], [], 401
except TimeoutError: except TimeoutError as e:
pass logger.error(f"获取图片URL超时", "色图", e=e)
except Exception as e: except Exception as e:
logger.error(f"send_setu 访问页面错误 {type(e)}{e}") logger.error(f"访问页面错误", "色图", e=e)
return ["我网线被人拔了..QAQ"], [], [], 999 return ["我网线被人拔了..QAQ"], [], [], 999
@ -93,43 +87,40 @@ async def search_online_setu(
:param id_: 本地id :param id_: 本地id
:param path_: 存储路径 :param path_: 存储路径
""" """
ws_url = Config.get_config("pixiv", "PIXIV_NGINX_URL") url_ = change_pixiv_image_links(url_)
if ws_url:
host_match = re.match(host_pattern, url_)
host = host_match.group(1)
url_ = url_.replace(host, ws_url)
index = random.randint(1, 100000) if id_ is None else id_ 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" 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): for i in range(3):
logger.info(f"search_online_setu --> {i}") logger.debug(f"尝试在线搜索第 {i+1}", "色图")
try: try:
if not await AsyncHttpx.download_file( if not await AsyncHttpx.download_file(
url_, url_,
path_ / file_name, file,
timeout=Config.get_config("send_setu", "TIMEOUT"), timeout=Config.get_config("send_setu", "TIMEOUT"),
): ):
continue continue
if id_ is not None: 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( compressed_image(
path_ / f"{index}.jpg", base_path / f"{index}.jpg",
) )
logger.info(f"下载 lolicon 图片 {url_} 成功, id{index}") logger.info(f"下载 lolicon 图片 {url_} 成功, id{index}")
change_img_md5(path_ / file_name) change_img_md5(file)
return image(path_ / file_name), index return image(file), index
except TimeoutError: except TimeoutError as e:
pass logger.error(f"下载图片超时", "色图", e=e)
except Exception as e: except Exception as e:
logger.error(f"send_setu 下载图片错误 {type(e)}{e}") logger.error(f"下载图片错误", "色图", e=e)
return "图片被小怪兽恰掉啦..!QAQ", -1 return "图片被小怪兽恰掉啦..!QAQ", -1
# 检测本地是否有id涩图无的话则下载 # 检测本地是否有id涩图无的话则下载
async def check_local_exists_or_download( async def check_local_exists_or_download(
setu_image: Setu, setu_image: Setu,
) -> Tuple[MessageSegment, int]: ) -> Tuple[Union[MessageSegment, str], int]:
path_ = None path_ = None
id_ = None id_ = None
if Config.get_config("send_setu", "DOWNLOAD_SETU"): 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) image_list = await Setu.query_image(r18=r18)
if not image_list: if not image_list:
return ["没找到符合条件的色图..."], 998 return ["没找到符合条件的色图..."], 998
return image_list, 200 return image_list, 200 # type: ignore
# 初始化消息 # 初始化消息
def gen_message( def gen_message(setu_image: Setu) -> str:
setu_image: Setu """判断是否获取图片信息
) -> Union[Message, MessageSegment]:
Args:
setu_image (Setu): Setu
Returns:
str: 图片信息
"""
local_id = setu_image.local_id local_id = setu_image.local_id
title = setu_image.title title = setu_image.title
author = setu_image.author author = setu_image.author
pid = setu_image.pid 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"): if Config.get_config("send_setu", "SHOW_INFO"):
return Message( return f"id{local_id}\n" f"title{title}\n" f"author{author}\n" f"PID{pid}\n"
f"id{local_id}\n" return ""
f"title{title}\n"
f"author{author}\n"
f"PID{pid}\n" + image(image_path)
)
return image(image_path)
# 罗翔老师! # 罗翔老师!
def get_luoxiang(impression): def get_luoxiang(impression):
probability = ( initial_setu_probability = Config.get_config(
float(impression) "send_setu", "INITIAL_SETU_PROBABILITY"
+ Config.get_config("send_setu", "INITIAL_SETU_PROBABILITY") * 100
) )
if probability < random.randint(1, 101): if initial_setu_probability:
return ( probability = float(impression) + initial_setu_probability * 100
"我为什么要给你发这个?" if probability < random.randint(1, 101):
+ image( return (
IMAGE_PATH "我为什么要给你发这个?"
/ "luoxiang" + image(
/ random.choice(os.listdir(IMAGE_PATH / "luoxiang")) IMAGE_PATH
/ "luoxiang"
/ random.choice(os.listdir(IMAGE_PATH / "luoxiang"))
)
+ f"\n(快向{NICKNAME}签到提升好感度吧!)"
) )
+ f"\n(快向{NICKNAME}签到提升好感度吧!)"
)
return None 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 = [] urls = []
text_list = [] text_list = []
add_databases_list = [] add_databases_list = []
for i in range(len(data)): for i in range(len(data)):
img_url = data[i]["urls"]["original"] img_url = data[i]["urls"]["original"]
img_url = ( img_url = change_pixiv_image_links(img_url)
img_url.replace("i.pixiv.cat", "i.pximg.net")
if "i.pixiv.cat" in img_url
else img_url
)
title = data[i]["title"] title = data[i]["title"]
author = data[i]["author"] author = data[i]["author"]
pid = data[i]["pid"] pid = data[i]["pid"]