feat: 优化整体项目
This commit is contained in:
@@ -18,6 +18,7 @@ from utils.decorators import (
|
||||
on_file_message,
|
||||
on_emoji_message
|
||||
)
|
||||
from utils.redis_cache import RedisCache, get_cache
|
||||
import pymysql
|
||||
from WechatHook import WechatHookClient
|
||||
from minio import Minio
|
||||
@@ -39,6 +40,7 @@ class MessageLogger(PluginBase):
|
||||
super().__init__()
|
||||
self.config = None
|
||||
self.db_config = None
|
||||
self.redis_cache = None # Redis 缓存实例
|
||||
|
||||
# 创建独立的日志记录器
|
||||
self._setup_logger()
|
||||
@@ -83,9 +85,22 @@ class MessageLogger(PluginBase):
|
||||
|
||||
self.db_config = self.config["database"]
|
||||
|
||||
# 初始化 Redis 缓存
|
||||
redis_config = self.config.get("redis", {})
|
||||
if redis_config.get("enabled", False):
|
||||
self.log.info("正在初始化 Redis 缓存...")
|
||||
self.redis_cache = RedisCache(redis_config)
|
||||
if self.redis_cache.enabled:
|
||||
self.log.success(f"Redis 缓存初始化成功,TTL={redis_config.get('ttl', 3600)}秒")
|
||||
else:
|
||||
self.log.warning("Redis 缓存初始化失败,将不使用缓存")
|
||||
self.redis_cache = None
|
||||
else:
|
||||
self.log.info("Redis 缓存未启用")
|
||||
|
||||
# 初始化 MinIO 客户端
|
||||
self.minio_client = Minio(
|
||||
"101.201.65.129:19000",
|
||||
"115.190.113.141:19000",
|
||||
access_key="admin",
|
||||
secret_key="80012029Lz",
|
||||
secure=False
|
||||
@@ -216,7 +231,7 @@ class MessageLogger(PluginBase):
|
||||
return ("", "", "", "", "0")
|
||||
|
||||
async def download_image_and_upload(self, bot, cdnurl: str, aeskey: str) -> str:
|
||||
"""下载图片并上传到 MinIO"""
|
||||
"""下载图片并上传到 MinIO,同时缓存 base64 供其他插件使用"""
|
||||
try:
|
||||
temp_file = Path(__file__).parent / f"temp_{uuid.uuid4().hex}.jpg"
|
||||
success = await bot.cdn_download(cdnurl, aeskey, str(temp_file), file_type=2)
|
||||
@@ -225,12 +240,26 @@ class MessageLogger(PluginBase):
|
||||
|
||||
# 等待文件下载完成
|
||||
import asyncio
|
||||
import base64
|
||||
for _ in range(50):
|
||||
if temp_file.exists() and temp_file.stat().st_size > 0:
|
||||
break
|
||||
await asyncio.sleep(0.1)
|
||||
|
||||
if temp_file.exists() and temp_file.stat().st_size > 0:
|
||||
# 读取文件并缓存 base64(供 AIChat 等插件使用)
|
||||
with open(temp_file, "rb") as f:
|
||||
image_data = f.read()
|
||||
base64_data = f"data:image/jpeg;base64,{base64.b64encode(image_data).decode()}"
|
||||
|
||||
# 缓存到 Redis(5分钟过期)
|
||||
redis_cache = get_cache()
|
||||
if redis_cache and redis_cache.enabled:
|
||||
media_key = RedisCache.generate_media_key(cdnurl, aeskey)
|
||||
if media_key:
|
||||
redis_cache.cache_media(media_key, base64_data, "image", ttl=300)
|
||||
self.log.debug(f"图片已缓存到 Redis: {media_key[:20]}...")
|
||||
|
||||
media_url = await self.upload_file_to_minio(str(temp_file), "images")
|
||||
temp_file.unlink()
|
||||
return media_url
|
||||
@@ -326,13 +355,25 @@ class MessageLogger(PluginBase):
|
||||
return ""
|
||||
|
||||
async def download_and_upload(self, url: str, file_type: str, ext: str) -> str:
|
||||
"""下载文件并上传到 MinIO"""
|
||||
"""下载文件并上传到 MinIO,同时缓存 base64 供其他插件使用"""
|
||||
try:
|
||||
import base64
|
||||
# 下载文件
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.get(url, timeout=aiohttp.ClientTimeout(total=10)) as resp:
|
||||
if resp.status == 200:
|
||||
data = await resp.read()
|
||||
|
||||
# 缓存表情包 base64(供 AIChat 等插件使用)
|
||||
if file_type == "emojis" and data:
|
||||
redis_cache = get_cache()
|
||||
if redis_cache and redis_cache.enabled:
|
||||
base64_data = f"data:image/gif;base64,{base64.b64encode(data).decode()}"
|
||||
media_key = RedisCache.generate_media_key(cdnurl=url)
|
||||
if media_key:
|
||||
redis_cache.cache_media(media_key, base64_data, "emoji", ttl=300)
|
||||
self.log.debug(f"表情包已缓存到 Redis: {media_key[:20]}...")
|
||||
|
||||
# 保存到临时文件
|
||||
temp_file = Path(__file__).parent / f"temp_{uuid.uuid4().hex}{ext}"
|
||||
temp_file.write_bytes(data)
|
||||
@@ -374,7 +415,7 @@ class MessageLogger(PluginBase):
|
||||
)
|
||||
|
||||
# 返回访问 URL
|
||||
url = f"http://101.201.65.129:19000/{self.minio_bucket}/{object_name}"
|
||||
url = f"http://115.190.113.141:19000/{self.minio_bucket}/{object_name}"
|
||||
self.log.debug(f"文件上传成功: {url}")
|
||||
return url
|
||||
|
||||
@@ -405,29 +446,45 @@ class MessageLogger(PluginBase):
|
||||
avatar_url = ""
|
||||
|
||||
if is_group and self.config["behavior"]["fetch_avatar"]:
|
||||
try:
|
||||
self.log.info(f"尝试获取用户信息: from_wxid={from_wxid}, sender_wxid={sender_wxid}")
|
||||
user_info = await bot.get_user_info_in_chatroom(from_wxid, sender_wxid)
|
||||
self.log.info(f"获取到用户信息: {user_info}")
|
||||
cache_hit = False
|
||||
|
||||
if user_info:
|
||||
# 处理不同的数据结构
|
||||
if isinstance(user_info.get("nickName"), dict):
|
||||
nickname = user_info.get("nickName", {}).get("string", "")
|
||||
# 1. 先尝试从 Redis 缓存获取
|
||||
if self.redis_cache and self.redis_cache.enabled:
|
||||
cached_info = self.redis_cache.get_user_basic_info(from_wxid, sender_wxid)
|
||||
if cached_info:
|
||||
nickname = cached_info.get("nickname", "")
|
||||
avatar_url = cached_info.get("avatar_url", "")
|
||||
if nickname and avatar_url:
|
||||
cache_hit = True
|
||||
self.log.debug(f"[缓存命中] {sender_wxid}: {nickname}")
|
||||
|
||||
# 2. 缓存未命中,调用 API 获取
|
||||
if not cache_hit:
|
||||
try:
|
||||
self.log.info(f"[缓存未命中] 调用API获取用户信息: {sender_wxid}")
|
||||
user_info = await bot.get_user_info_in_chatroom(from_wxid, sender_wxid)
|
||||
|
||||
if user_info:
|
||||
# 处理不同的数据结构
|
||||
if isinstance(user_info.get("nickName"), dict):
|
||||
nickname = user_info.get("nickName", {}).get("string", "")
|
||||
else:
|
||||
nickname = user_info.get("nickName", "")
|
||||
|
||||
avatar_url = user_info.get("bigHeadImgUrl", "")
|
||||
self.log.info(f"API获取成功: nickname={nickname}, avatar_url={avatar_url[:50] if avatar_url else ''}...")
|
||||
|
||||
# 3. 将用户信息存入 Redis 缓存
|
||||
if self.redis_cache and self.redis_cache.enabled and nickname:
|
||||
self.redis_cache.set_user_info(from_wxid, sender_wxid, user_info)
|
||||
self.log.debug(f"[已缓存] {sender_wxid}: {nickname}")
|
||||
else:
|
||||
nickname = user_info.get("nickName", "")
|
||||
self.log.warning(f"用户信息为空: {sender_wxid}")
|
||||
|
||||
avatar_url = user_info.get("bigHeadImgUrl", "")
|
||||
self.log.info(f"解析用户信息: nickname={nickname}, avatar_url={avatar_url[:50]}...")
|
||||
else:
|
||||
self.log.warning(f"用户信息为空: {sender_wxid}")
|
||||
except Exception as e:
|
||||
self.log.error(f"获取用户信息失败: {e}")
|
||||
|
||||
except Exception as e:
|
||||
self.log.error(f"获取用户信息失败: {e}")
|
||||
import traceback
|
||||
self.log.error(f"详细错误: {traceback.format_exc()}")
|
||||
|
||||
# 如果获取失败,从历史记录中查找
|
||||
# 4. 如果仍然没有获取到,从历史记录中查找
|
||||
if not nickname or not avatar_url:
|
||||
self.log.info(f"尝试从历史记录获取用户信息: {sender_wxid}")
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user