fix: 修复表情包重复保存
This commit is contained in:
@@ -232,7 +232,7 @@ class EmojiManager:
|
|||||||
image_hash = hashlib.md5(image_bytes).hexdigest()
|
image_hash = hashlib.md5(image_bytes).hexdigest()
|
||||||
image_format = Image.open(io.BytesIO(image_bytes)).format.lower()
|
image_format = Image.open(io.BytesIO(image_bytes)).format.lower()
|
||||||
# 检查是否已经注册过
|
# 检查是否已经注册过
|
||||||
existing_emoji = db["emoji"].find_one({"filename": filename})
|
existing_emoji = db["emoji"].find_one({"hash": image_hash})
|
||||||
description = None
|
description = None
|
||||||
|
|
||||||
if existing_emoji:
|
if existing_emoji:
|
||||||
|
|||||||
@@ -84,65 +84,6 @@ class ImageManager:
|
|||||||
upsert=True,
|
upsert=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def save_image(
|
|
||||||
self, image_data: Union[str, bytes], url: str = None, description: str = None, is_base64: bool = False
|
|
||||||
) -> Optional[str]:
|
|
||||||
"""保存图像
|
|
||||||
Args:
|
|
||||||
image_data: 图像数据(base64字符串或字节)
|
|
||||||
url: 图像URL
|
|
||||||
description: 图像描述
|
|
||||||
is_base64: image_data是否为base64格式
|
|
||||||
Returns:
|
|
||||||
str: 保存后的文件路径,失败返回None
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
# 转换为字节格式
|
|
||||||
if is_base64:
|
|
||||||
if isinstance(image_data, str):
|
|
||||||
image_bytes = base64.b64decode(image_data)
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
if isinstance(image_data, bytes):
|
|
||||||
image_bytes = image_data
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# 计算哈希值
|
|
||||||
image_hash = hashlib.md5(image_bytes).hexdigest()
|
|
||||||
image_format = Image.open(io.BytesIO(image_bytes)).format.lower()
|
|
||||||
|
|
||||||
# 查重
|
|
||||||
existing = db.images.find_one({"hash": image_hash})
|
|
||||||
if existing:
|
|
||||||
return existing["path"]
|
|
||||||
|
|
||||||
# 生成文件名和路径
|
|
||||||
timestamp = int(time.time())
|
|
||||||
filename = f"{timestamp}_{image_hash[:8]}.{image_format}"
|
|
||||||
file_path = os.path.join(self.IMAGE_DIR, filename)
|
|
||||||
|
|
||||||
# 保存文件
|
|
||||||
with open(file_path, "wb") as f:
|
|
||||||
f.write(image_bytes)
|
|
||||||
|
|
||||||
# 保存到数据库
|
|
||||||
image_doc = {
|
|
||||||
"hash": image_hash,
|
|
||||||
"path": file_path,
|
|
||||||
"url": url,
|
|
||||||
"description": description,
|
|
||||||
"timestamp": timestamp,
|
|
||||||
}
|
|
||||||
db.images.insert_one(image_doc)
|
|
||||||
|
|
||||||
return file_path
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"保存图像失败: {str(e)}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
async def get_image_by_url(self, url: str) -> Optional[str]:
|
async def get_image_by_url(self, url: str) -> Optional[str]:
|
||||||
"""根据URL获取图像路径(带查重)
|
"""根据URL获取图像路径(带查重)
|
||||||
Args:
|
Args:
|
||||||
@@ -168,62 +109,6 @@ class ImageManager:
|
|||||||
logger.error(f"获取图像失败: {str(e)}")
|
logger.error(f"获取图像失败: {str(e)}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
async def get_base64_by_url(self, url: str) -> Optional[str]:
|
|
||||||
"""根据URL获取base64(带查重)
|
|
||||||
Args:
|
|
||||||
url: 图像URL
|
|
||||||
Returns:
|
|
||||||
str: base64字符串,失败返回None
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
image_path = await self.get_image_by_url(url)
|
|
||||||
if not image_path:
|
|
||||||
return None
|
|
||||||
|
|
||||||
with open(image_path, "rb") as f:
|
|
||||||
image_bytes = f.read()
|
|
||||||
return base64.b64encode(image_bytes).decode("utf-8")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"获取base64失败: {str(e)}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
def check_url_exists(self, url: str) -> bool:
|
|
||||||
"""检查URL是否已存在
|
|
||||||
Args:
|
|
||||||
url: 图像URL
|
|
||||||
Returns:
|
|
||||||
bool: 是否存在
|
|
||||||
"""
|
|
||||||
return db.images.find_one({"url": url}) is not None
|
|
||||||
|
|
||||||
def check_hash_exists(self, image_data: Union[str, bytes], is_base64: bool = False) -> bool:
|
|
||||||
"""检查图像是否已存在
|
|
||||||
Args:
|
|
||||||
image_data: 图像数据(base64或字节)
|
|
||||||
is_base64: 是否为base64格式
|
|
||||||
Returns:
|
|
||||||
bool: 是否存在
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
if is_base64:
|
|
||||||
if isinstance(image_data, str):
|
|
||||||
image_bytes = base64.b64decode(image_data)
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
if isinstance(image_data, bytes):
|
|
||||||
image_bytes = image_data
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
image_hash = hashlib.md5(image_bytes).hexdigest()
|
|
||||||
return db.images.find_one({"hash": image_hash}) is not None
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"检查哈希失败: {str(e)}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def get_emoji_description(self, image_base64: str) -> str:
|
async def get_emoji_description(self, image_base64: str) -> str:
|
||||||
"""获取表情包描述,带查重和保存功能"""
|
"""获取表情包描述,带查重和保存功能"""
|
||||||
try:
|
try:
|
||||||
@@ -242,6 +127,11 @@ class ImageManager:
|
|||||||
prompt = "这是一个表情包,使用中文简洁的描述一下表情包的内容和表情包所表达的情感"
|
prompt = "这是一个表情包,使用中文简洁的描述一下表情包的内容和表情包所表达的情感"
|
||||||
description, _ = await self._llm.generate_response_for_image(prompt, image_base64, image_format)
|
description, _ = await self._llm.generate_response_for_image(prompt, image_base64, image_format)
|
||||||
|
|
||||||
|
cached_description = self._get_description_from_db(image_hash, "emoji")
|
||||||
|
if cached_description:
|
||||||
|
logger.warning(f"虽然生成了描述,但找到缓存表情包描述: {cached_description}")
|
||||||
|
return f"[表情包:{cached_description}]"
|
||||||
|
|
||||||
# 根据配置决定是否保存图片
|
# 根据配置决定是否保存图片
|
||||||
if global_config.EMOJI_SAVE:
|
if global_config.EMOJI_SAVE:
|
||||||
# 生成文件名和路径
|
# 生成文件名和路径
|
||||||
@@ -297,6 +187,10 @@ class ImageManager:
|
|||||||
"请用中文描述这张图片的内容。如果有文字,请把文字都描述出来。并尝试猜测这个图片的含义。最多200个字。"
|
"请用中文描述这张图片的内容。如果有文字,请把文字都描述出来。并尝试猜测这个图片的含义。最多200个字。"
|
||||||
)
|
)
|
||||||
description, _ = await self._llm.generate_response_for_image(prompt, image_base64, image_format)
|
description, _ = await self._llm.generate_response_for_image(prompt, image_base64, image_format)
|
||||||
|
cached_description = self._get_description_from_db(image_hash, "emoji")
|
||||||
|
if cached_description:
|
||||||
|
logger.info(f"缓存图片描述: {cached_description}")
|
||||||
|
return f"[图片:{cached_description}]"
|
||||||
|
|
||||||
print(f"描述是{description}")
|
print(f"描述是{description}")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user