855 协议版本-调整完毕内容
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import functools
|
||||
import time
|
||||
import traceback
|
||||
import logging
|
||||
import asyncio
|
||||
from loguru import logger
|
||||
from datetime import datetime
|
||||
from typing import Callable, Dict, Any, Tuple
|
||||
|
||||
@@ -19,14 +20,13 @@ def plugin_stats_decorator(plugin_name: str) -> Callable:
|
||||
装饰器函数
|
||||
"""
|
||||
# 获取日志记录器
|
||||
logger = logging.getLogger(f"StatsCollector.{plugin_name}")
|
||||
logger.debug(f"为插件 '{plugin_name}' 应用统计装饰器")
|
||||
|
||||
def decorator(func: Callable) -> Callable:
|
||||
logger.debug(f"装饰 '{plugin_name}' 的 {func.__name__} 方法")
|
||||
|
||||
@functools.wraps(func)
|
||||
def wrapper(self, message: Dict[str, Any]) -> Tuple[bool, str]:
|
||||
async def async_wrapper(self, message: Dict[str, Any]) -> Tuple[bool, str]:
|
||||
# 获取数据库连接
|
||||
try:
|
||||
logger.debug(f"[{plugin_name}] 开始处理消息")
|
||||
@@ -48,7 +48,122 @@ def plugin_stats_decorator(plugin_name: str) -> Callable:
|
||||
logger.debug(f"[{plugin_name}] 开始执行时间: {datetime.fromtimestamp(start_time).strftime('%Y-%m-%d %H:%M:%S.%f')}")
|
||||
|
||||
try:
|
||||
# 调用原始方法
|
||||
# 调用原始异步方法
|
||||
logger.debug(f"[{plugin_name}] 调用原始方法 {func.__name__}")
|
||||
success, response = await func(self, message)
|
||||
|
||||
# 计算执行时间(毫秒)
|
||||
end_time = time.time()
|
||||
process_time_ms = (end_time - start_time) * 1000
|
||||
logger.debug(f"[{plugin_name}] 执行完成,耗时: {process_time_ms:.2f}ms, 结果: {success}, 响应: {response}")
|
||||
|
||||
# 记录插件调用
|
||||
logger.debug(f"[{plugin_name}] 记录插件调用统计")
|
||||
stats_db.record_plugin_call(
|
||||
plugin_name=plugin_name,
|
||||
command=command,
|
||||
user_id=sender,
|
||||
group_id=roomid,
|
||||
success=success,
|
||||
process_time_ms=process_time_ms
|
||||
)
|
||||
logger.info(f"[{plugin_name}] 成功记录插件调用: {command}, 耗时: {process_time_ms:.2f}ms")
|
||||
|
||||
# 定义不需要记录错误的正常业务状态
|
||||
normal_responses = {
|
||||
"没有权限",
|
||||
"命令格式错误",
|
||||
"请先开启功能",
|
||||
# 可以添加其他正常的业务状态返回
|
||||
}
|
||||
|
||||
# 新增:如果业务代码返回失败,且不属于正常业务状态,则记录错误信息
|
||||
if not success and response and response not in normal_responses:
|
||||
logger.debug(f"[{plugin_name}] 业务代码返回失败,记录错误信息: {response}")
|
||||
try:
|
||||
stats_db.record_error(
|
||||
plugin_name=plugin_name,
|
||||
command=command,
|
||||
user_id=sender,
|
||||
group_id=roomid,
|
||||
error_message=f"业务返回失败: {response}",
|
||||
stack_trace="业务代码捕获的错误,无堆栈信息"
|
||||
)
|
||||
logger.info(f"[{plugin_name}] 成功记录业务失败信息: {response}")
|
||||
except Exception as err_record_error:
|
||||
logger.error(f"[{plugin_name}] 记录业务失败信息出错: {err_record_error}")
|
||||
|
||||
return success, response
|
||||
except Exception as e:
|
||||
# 计算执行时间(毫秒)
|
||||
end_time = time.time()
|
||||
process_time_ms = (end_time - start_time) * 1000
|
||||
|
||||
# 记录错误
|
||||
error_message = str(e)
|
||||
stack_trace = traceback.format_exc()
|
||||
logger.error(f"[{plugin_name}] 执行出错: {error_message}")
|
||||
logger.debug(f"[{plugin_name}] 错误堆栈: {stack_trace}")
|
||||
|
||||
try:
|
||||
# 记录插件调用(失败)
|
||||
logger.debug(f"[{plugin_name}] 记录插件调用失败统计")
|
||||
stats_db.record_plugin_call(
|
||||
plugin_name=plugin_name,
|
||||
command=command, # 使用提取的指令而不是完整内容
|
||||
user_id=sender,
|
||||
group_id=roomid,
|
||||
success=False,
|
||||
process_time_ms=process_time_ms
|
||||
)
|
||||
|
||||
# 记录错误详情
|
||||
logger.debug(f"[{plugin_name}] 记录错误详情")
|
||||
stats_db.record_error(
|
||||
plugin_name=plugin_name,
|
||||
command=command, # 使用提取的指令而不是完整内容
|
||||
user_id=sender,
|
||||
group_id=roomid,
|
||||
error_message=error_message[:500] if error_message else "未知错误", # 限制长度并确保不为空
|
||||
stack_trace=stack_trace[:2000] if stack_trace else "无堆栈信息" # 限制长度并确保不为空
|
||||
)
|
||||
logger.info(f"[{plugin_name}] 成功记录插件错误: {command}, 错误: {error_message}")
|
||||
except Exception as db_error:
|
||||
logger.error(f"[{plugin_name}] 记录插件统计数据失败: {db_error}")
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
# 重新抛出异常,让上层处理
|
||||
raise
|
||||
except Exception as outer_error:
|
||||
logger.error(f"[{plugin_name}] 装饰器外层错误: {outer_error}")
|
||||
logger.error(traceback.format_exc())
|
||||
# 确保原始函数仍然被调用,即使装饰器出错
|
||||
return await func(self, message)
|
||||
|
||||
@functools.wraps(func)
|
||||
def sync_wrapper(self, message: Dict[str, Any]) -> Tuple[bool, str]:
|
||||
# 获取数据库连接
|
||||
try:
|
||||
logger.debug(f"[{plugin_name}] 开始处理消息")
|
||||
db_manager = DBConnectionManager.get_instance()
|
||||
stats_db = StatsDBOperator(db_manager)
|
||||
|
||||
# 提取消息信息
|
||||
content = message.get("content", "")
|
||||
sender = message.get("sender", "")
|
||||
roomid = message.get("roomid", "")
|
||||
|
||||
# 提取指令部分(假设指令是第一个单词或空格前的部分)
|
||||
command = content.strip().split(' ')[0] if content else ""
|
||||
|
||||
logger.debug(f"[{plugin_name}] 消息内容: '{content}', 指令: '{command}', 发送者: {sender}, 群ID: {roomid}")
|
||||
|
||||
# 记录开始时间
|
||||
start_time = time.time()
|
||||
logger.debug(f"[{plugin_name}] 开始执行时间: {datetime.fromtimestamp(start_time).strftime('%Y-%m-%d %H:%M:%S.%f')}")
|
||||
|
||||
try:
|
||||
# 调用原始同步方法
|
||||
logger.debug(f"[{plugin_name}] 调用原始方法 {func.__name__}")
|
||||
success, response = func(self, message)
|
||||
|
||||
@@ -140,6 +255,10 @@ def plugin_stats_decorator(plugin_name: str) -> Callable:
|
||||
# 确保原始函数仍然被调用,即使装饰器出错
|
||||
return func(self, message)
|
||||
|
||||
return wrapper
|
||||
# 根据原始函数是否为异步函数返回相应的包装器
|
||||
if asyncio.iscoroutinefunction(func):
|
||||
return async_wrapper
|
||||
else:
|
||||
return sync_wrapper
|
||||
|
||||
return decorator
|
||||
@@ -1,7 +1,8 @@
|
||||
import functools
|
||||
import time
|
||||
import traceback
|
||||
import logging
|
||||
import asyncio
|
||||
from loguru import logger
|
||||
from typing import Callable, Dict, Any, Tuple, Union
|
||||
|
||||
from db.connection import DBConnectionManager
|
||||
@@ -25,7 +26,7 @@ def points_reward_decorator(points_calculator: Union[int, Callable], source_type
|
||||
|
||||
def decorator(func: Callable) -> Callable:
|
||||
@functools.wraps(func)
|
||||
def wrapper(self, message: Dict[str, Any]) -> Tuple[bool, str]:
|
||||
async def async_wrapper(self, message: Dict[str, Any]) -> Tuple[bool, str]:
|
||||
# 检查权限
|
||||
roomid = message.get("roomid", "")
|
||||
|
||||
@@ -33,7 +34,74 @@ def points_reward_decorator(points_calculator: Union[int, Callable], source_type
|
||||
if GroupBotManager.get_group_permission(roomid, feature) == PermissionStatus.DISABLED:
|
||||
return False, "没有权限"
|
||||
|
||||
# 调用原始方法
|
||||
# 调用原始异步方法
|
||||
success, response = await func(self, message)
|
||||
|
||||
# 如果原始方法执行成功,奖励积分
|
||||
if success:
|
||||
try:
|
||||
# 获取消息信息
|
||||
sender = message.get("sender", "")
|
||||
roomid = message.get("roomid", "")
|
||||
|
||||
if sender and (roomid or sender):
|
||||
# 计算奖励积分数量
|
||||
if callable(points_calculator):
|
||||
# 如果是函数,调用函数计算积分
|
||||
points = points_calculator(self, message, success, response)
|
||||
if not points or points <= 0:
|
||||
# 如果计算结果为0或负数,不奖励积分
|
||||
return success, response
|
||||
else:
|
||||
# 如果是固定值,直接使用
|
||||
points = points_calculator
|
||||
|
||||
# 获取积分来源类型
|
||||
source = PointSource.CHECKIN
|
||||
if source_type.lower() == "game":
|
||||
source = PointSource.GAME
|
||||
elif source_type.lower() != "checkin":
|
||||
source = PointSource.OTHER
|
||||
|
||||
# 奖励积分
|
||||
db_manager = DBConnectionManager.get_instance()
|
||||
points_db = PointsDBOperator(db_manager)
|
||||
|
||||
# 如果description是函数,调用函数获取描述
|
||||
desc = description
|
||||
if callable(description):
|
||||
desc = description(self, message, success, response, points)
|
||||
|
||||
reward_success, reward_result = points_db.add_points(
|
||||
sender, roomid, points, source,
|
||||
desc or f"使用 {self.name if hasattr(self, 'name') else '功能'} 获得奖励"
|
||||
)
|
||||
|
||||
logger.info(f"PointsReward.{self.name if hasattr(self, 'name') else 'Unknown'}")
|
||||
if reward_success:
|
||||
logger.info(f"用户 {sender} 获得 {points} 积分奖励")
|
||||
|
||||
# 如果响应中没有提到积分,添加积分信息
|
||||
if "积分" not in response:
|
||||
response += f"\n\n🎁 恭喜获得 {points} 积分奖励!"
|
||||
else:
|
||||
logger.warning(f"用户 {sender} 积分奖励失败: {reward_result}")
|
||||
except Exception as e:
|
||||
logger.error(f"奖励积分失败: {e}")
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
return success, response
|
||||
|
||||
@functools.wraps(func)
|
||||
def sync_wrapper(self, message: Dict[str, Any]) -> Tuple[bool, str]:
|
||||
# 检查权限
|
||||
roomid = message.get("roomid", "")
|
||||
|
||||
if feature and roomid:
|
||||
if GroupBotManager.get_group_permission(roomid, feature) == PermissionStatus.DISABLED:
|
||||
return False, "没有权限"
|
||||
|
||||
# 调用原始同步方法
|
||||
success, response = func(self, message)
|
||||
|
||||
# 如果原始方法执行成功,奖励积分
|
||||
@@ -76,7 +144,7 @@ def points_reward_decorator(points_calculator: Union[int, Callable], source_type
|
||||
desc or f"使用 {self.name if hasattr(self, 'name') else '功能'} 获得奖励"
|
||||
)
|
||||
|
||||
logger = logging.getLogger(f"PointsReward.{self.name if hasattr(self, 'name') else 'Unknown'}")
|
||||
logger.info(f"PointsReward.{self.name if hasattr(self, 'name') else 'Unknown'}")
|
||||
if reward_success:
|
||||
logger.info(f"用户 {sender} 获得 {points} 积分奖励")
|
||||
|
||||
@@ -86,13 +154,16 @@ def points_reward_decorator(points_calculator: Union[int, Callable], source_type
|
||||
else:
|
||||
logger.warning(f"用户 {sender} 积分奖励失败: {reward_result}")
|
||||
except Exception as e:
|
||||
logger = logging.getLogger("PointsReward")
|
||||
logger.error(f"奖励积分失败: {e}")
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
return success, response
|
||||
|
||||
return wrapper
|
||||
# 根据原始函数是否为异步函数返回相应的包装器
|
||||
if asyncio.iscoroutinefunction(func):
|
||||
return async_wrapper
|
||||
else:
|
||||
return sync_wrapper
|
||||
|
||||
return decorator
|
||||
|
||||
@@ -111,19 +182,90 @@ def plugin_points_cost(points: int, description: str = None, feature: Feature =
|
||||
|
||||
def decorator(func: Callable) -> Callable:
|
||||
@functools.wraps(func)
|
||||
def wrapper(self, message: Dict[str, Any]) -> Tuple[bool, str]:
|
||||
async def async_wrapper(self, message: Dict[str, Any]) -> Tuple[bool, str]:
|
||||
try:
|
||||
# 检查权限
|
||||
roomid = message.get("roomid", "")
|
||||
if feature and roomid:
|
||||
if GroupBotManager.get_group_permission(roomid, feature) == PermissionStatus.DISABLED:
|
||||
gbm = message.get("gbm")
|
||||
if gbm and gbm.get_group_permission(roomid, feature) == PermissionStatus.DISABLED:
|
||||
return False, "没有权限"
|
||||
|
||||
# 检查是否开启了积分获取功能 SIGNIN 和 TASK_GAME 如果没有开启,则不扣积分 请用== == PermissionStatus.DISABLED 判断
|
||||
if GroupBotManager.get_group_permission(roomid,
|
||||
Feature.SIGNIN) == PermissionStatus.DISABLED and GroupBotManager.get_group_permission(
|
||||
roomid, Feature.TASK_GAME) == PermissionStatus.DISABLED:
|
||||
# 检查是否开启了积分获取功能
|
||||
if gbm and gbm.get_group_permission(roomid, Feature.SIGNIN) == PermissionStatus.DISABLED and gbm.get_group_permission(
|
||||
roomid, Feature.TASK_GAME) == PermissionStatus.DISABLED:
|
||||
return await func(self, message)
|
||||
|
||||
# 获取消息信息
|
||||
sender = message.get("sender", "")
|
||||
roomid = message.get("roomid", "")
|
||||
|
||||
if not sender or not (roomid or sender):
|
||||
return await func(self, message)
|
||||
|
||||
# 检查用户积分是否足够
|
||||
db_manager = DBConnectionManager.get_instance()
|
||||
points_db = PointsDBOperator(db_manager)
|
||||
|
||||
plugin_name = self.name if hasattr(self, 'name') else "未知插件"
|
||||
logger.info(f"PointsCost.{plugin_name}")
|
||||
|
||||
user_points = points_db.get_user_points(sender, roomid)
|
||||
if user_points["total_points"] < points:
|
||||
# 积分不足
|
||||
await self.message_util.send_text(
|
||||
f"❌ 积分不足\n无法使用 {plugin_name} 功能\n"
|
||||
f"🪙 先参与积分活动[签到,答题/t]赚取吧!\n"
|
||||
f"💰 有: {user_points['total_points']} | 需: {points} |差: {points - user_points['total_points']} ",
|
||||
(roomid if roomid else sender), sender
|
||||
)
|
||||
logger.info(f"用户 {sender} 积分不足,无法使用功能")
|
||||
return False, "积分不足"
|
||||
|
||||
# 调用原始异步方法
|
||||
success, response = await func(self, message)
|
||||
|
||||
# 如果原始方法执行成功,扣除积分
|
||||
if success:
|
||||
deduct_success, deduct_result = points_db.deduct_points(
|
||||
sender, roomid, points, PointSource.PLUGIN,
|
||||
description or f"使用 {plugin_name} 功能"
|
||||
)
|
||||
|
||||
if deduct_success:
|
||||
logger.info(f"用户 {sender} 使用 {plugin_name} 功能扣除 {points} 积分")
|
||||
|
||||
# 添加对 response 的类型检查
|
||||
if isinstance(response, str) and "积分" not in response:
|
||||
response += f"\n\n💰 已消费 {points} 积分"
|
||||
await self.message_util.send_text(
|
||||
f"💰消费 {points} 积分",
|
||||
(roomid if roomid else sender), sender
|
||||
)
|
||||
else:
|
||||
logger.warning(f"用户 {sender} 积分扣除失败: {deduct_result}")
|
||||
|
||||
return success, response
|
||||
except Exception as e:
|
||||
logger.error(f"积分消费失败: {e}")
|
||||
logger.error(traceback.format_exc())
|
||||
return await func(self, message)
|
||||
|
||||
@functools.wraps(func)
|
||||
def sync_wrapper(self, message: Dict[str, Any]) -> Tuple[bool, str]:
|
||||
try:
|
||||
# 检查权限
|
||||
roomid = message.get("roomid", "")
|
||||
if feature and roomid:
|
||||
gbm = message.get("gbm")
|
||||
if gbm and gbm.get_group_permission(roomid, feature) == PermissionStatus.DISABLED:
|
||||
return False, "没有权限"
|
||||
|
||||
# 检查是否开启了积分获取功能
|
||||
if gbm and gbm.get_group_permission(roomid, Feature.SIGNIN) == PermissionStatus.DISABLED and gbm.get_group_permission(
|
||||
roomid, Feature.TASK_GAME) == PermissionStatus.DISABLED:
|
||||
return func(self, message)
|
||||
|
||||
# 获取消息信息
|
||||
sender = message.get("sender", "")
|
||||
roomid = message.get("roomid", "")
|
||||
@@ -136,7 +278,7 @@ def plugin_points_cost(points: int, description: str = None, feature: Feature =
|
||||
points_db = PointsDBOperator(db_manager)
|
||||
|
||||
plugin_name = self.name if hasattr(self, 'name') else "未知插件"
|
||||
logger = logging.getLogger(f"PointsCost.{plugin_name}")
|
||||
logger.info(f"PointsCost.{plugin_name}")
|
||||
|
||||
user_points = points_db.get_user_points(sender, roomid)
|
||||
if user_points["total_points"] < points:
|
||||
@@ -150,7 +292,7 @@ def plugin_points_cost(points: int, description: str = None, feature: Feature =
|
||||
logger.info(f"用户 {sender} 积分不足,无法使用功能")
|
||||
return False, "积分不足"
|
||||
|
||||
# 调用原始方法
|
||||
# 调用原始同步方法
|
||||
success, response = func(self, message)
|
||||
|
||||
# 如果原始方法执行成功,扣除积分
|
||||
@@ -175,11 +317,14 @@ def plugin_points_cost(points: int, description: str = None, feature: Feature =
|
||||
|
||||
return success, response
|
||||
except Exception as e:
|
||||
logger = logging.getLogger("PointsCost")
|
||||
logger.error(f"积分消费失败: {e}")
|
||||
logger.error(traceback.format_exc())
|
||||
return func(self, message)
|
||||
|
||||
return wrapper
|
||||
# 根据原始函数是否为异步函数返回相应的包装器
|
||||
if asyncio.iscoroutinefunction(func):
|
||||
return async_wrapper
|
||||
else:
|
||||
return sync_wrapper
|
||||
|
||||
return decorator
|
||||
|
||||
@@ -3,7 +3,7 @@ import requests
|
||||
import uuid
|
||||
from typing import Optional
|
||||
from urllib.parse import urlparse
|
||||
import logging
|
||||
from loguru import logger
|
||||
import time
|
||||
|
||||
class MediaDownloader:
|
||||
@@ -16,13 +16,13 @@ class MediaDownloader:
|
||||
Args:
|
||||
download_dir: 下载目录,默认为项目下的 media_downloads 目录
|
||||
"""
|
||||
self.logger = logging.getLogger("MediaDownloader")
|
||||
self.LOG = logger
|
||||
self.download_dir = download_dir or os.path.join(
|
||||
os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
|
||||
"media_downloads"
|
||||
)
|
||||
os.makedirs(self.download_dir, exist_ok=True)
|
||||
self.logger.info(f"媒体下载目录: {self.download_dir}")
|
||||
self.LOG.info(f"媒体下载目录: {self.download_dir}")
|
||||
|
||||
def download_media(self, url: str, file_type: str = None) -> Optional[str]:
|
||||
"""
|
||||
@@ -47,7 +47,7 @@ class MediaDownloader:
|
||||
|
||||
local_path = os.path.join(self.download_dir, filename)
|
||||
|
||||
self.logger.info(f"开始下载媒体文件: {url} -> {local_path}")
|
||||
self.LOG.info(f"开始下载媒体文件: {url} -> {local_path}")
|
||||
|
||||
# 下载文件
|
||||
response = requests.get(url, stream=True, timeout=30)
|
||||
@@ -58,7 +58,7 @@ class MediaDownloader:
|
||||
if chunk:
|
||||
f.write(chunk)
|
||||
|
||||
self.logger.info(f"媒体文件下载成功: {local_path}")
|
||||
self.LOG.info(f"媒体文件下载成功: {local_path}")
|
||||
|
||||
# 下载成功后清理旧文件
|
||||
self.clear_downloads()
|
||||
@@ -66,7 +66,7 @@ class MediaDownloader:
|
||||
return os.path.abspath(local_path)
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"下载媒体文件失败: {url}, 错误: {str(e)}")
|
||||
self.LOG.error(f"下载媒体文件失败: {url}, 错误: {str(e)}")
|
||||
return None
|
||||
|
||||
def _guess_file_type(self, url: str) -> Optional[str]:
|
||||
@@ -138,12 +138,12 @@ class MediaDownloader:
|
||||
try:
|
||||
os.remove(file_path)
|
||||
cleared_count += 1
|
||||
self.logger.debug(f"已删除过期文件: {file_path}")
|
||||
self.LOG.debug(f"已删除过期文件: {file_path}")
|
||||
except Exception as e:
|
||||
self.logger.error(f"删除文件失败 {file_path}: {str(e)}")
|
||||
self.LOG.error(f"删除文件失败 {file_path}: {str(e)}")
|
||||
|
||||
if cleared_count > 0:
|
||||
self.logger.info(f"清理完成,共删除 {cleared_count} 个过期文件")
|
||||
self.LOG.info(f"清理完成,共删除 {cleared_count} 个过期文件")
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"清理下载文件时出错: {str(e)}")
|
||||
self.LOG.error(f"清理下载文件时出错: {str(e)}")
|
||||
@@ -6,15 +6,15 @@
|
||||
# 3.群AI能力 #启用群AI #关闭群AI
|
||||
# 4.群总结能力 #启用群总结 #关闭群总结
|
||||
# 5.sehuatang PDF能力 #启用pdf #关闭pdf
|
||||
import logging
|
||||
from typing import List
|
||||
|
||||
import redis
|
||||
from enum import Enum
|
||||
|
||||
from loguru import logger
|
||||
|
||||
# 连接到本地 Redis 服务
|
||||
r = redis.StrictRedis(host='192.168.2.40', port=6379, db=0, decode_responses=True)
|
||||
logger = logging.getLogger(f"GroupBotManager")
|
||||
|
||||
class PermissionStatus(Enum):
|
||||
"""权限状态枚举"""
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
"""
|
||||
联系人管理器 - 提供全局访问联系人信息的单例类
|
||||
"""
|
||||
import logging
|
||||
|
||||
from loguru import logger
|
||||
from typing import Dict, Optional, List, Tuple
|
||||
|
||||
from gewechat_client import GewechatClient
|
||||
|
||||
from utils.json_converter import json_to_object
|
||||
|
||||
@@ -20,7 +20,7 @@ class ContactManager:
|
||||
_official_accounts: Dict[str, str] = {} # 公众号
|
||||
_head_images: Dict[str, str] = {} # 头像信息
|
||||
_initialized = False
|
||||
_logger = logging.getLogger("ContactManager")
|
||||
_logger = logger
|
||||
_friends: List[Dict] = []
|
||||
_group_contacts_friends: Dict[str, Dict[str, str]] = {}
|
||||
# 定义公共好友列表
|
||||
|
||||
@@ -1,29 +1,24 @@
|
||||
import time
|
||||
from datetime import datetime, timedelta
|
||||
import xml.etree.ElementTree as ET
|
||||
import logging
|
||||
import concurrent.futures # 添加线程池支持
|
||||
import os
|
||||
|
||||
from gewechat_client import GewechatClient
|
||||
|
||||
from db.connection import DBConnectionManager
|
||||
from db.message_storage import MessageStorageDB
|
||||
# 导入积分系统
|
||||
from db.points_db import PointsDBOperator, PointSource
|
||||
from gewechat.call_back_message.message import WxMessage, MessageType
|
||||
from wechat_ipad import WechatAPIClient
|
||||
from wechat_ipad.models.message import WxMessage, MessageType
|
||||
|
||||
# 配置日志
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
||||
)
|
||||
logger = logging.getLogger("MessageStorage")
|
||||
from loguru import logger
|
||||
|
||||
logging = logger
|
||||
|
||||
|
||||
class MessageStorage:
|
||||
|
||||
def __init__(self, client: GewechatClient = None):
|
||||
def __init__(self, client: WechatAPIClient = None):
|
||||
# 获取数据库连接管理器的单例
|
||||
self.db_manager = DBConnectionManager.get_instance()
|
||||
self.message_db = MessageStorageDB(self.db_manager)
|
||||
@@ -123,38 +118,38 @@ class MessageStorage:
|
||||
if not os.path.exists(target_dir):
|
||||
os.makedirs(target_dir, exist_ok=True)
|
||||
# 尝试使用wcf下载图片到分组后的目录
|
||||
json = self.client.download_image(msg.appid, msg.content.xml_content, 2)
|
||||
# {
|
||||
# "ret": 200,
|
||||
# "msg": "操作成功",
|
||||
# "data": {
|
||||
# "fileUrl": "/download/20240720/wx_BTVoJ_o_r6DpxNCNiycFE/0ca5b675-8e2c-4dc1-b288-3c44a40086ec4"
|
||||
# }
|
||||
# }
|
||||
# 解析JSON http://192.168.2.240:2532/download/20250428/wx_3BC6eSHGE5xEm_hH3__7c/03ab5c03-5524-4a39-aabe-27ca014a4d1e.png
|
||||
if json and json.get('data') and json['data'].get('fileUrl'):
|
||||
file_url = json['data']['fileUrl']
|
||||
if file_url:
|
||||
logger.info(f"记录gewe服务端图片路径成功: {msg.msg_id} -> {file_url}")
|
||||
# 后续如果需要使用,则去服务器端提取图片
|
||||
# 直接使用下载后的路径更新数据库
|
||||
self.message_db.update_message_image_path(msg.msg_id, file_url)
|
||||
|
||||
return {
|
||||
'success': True,
|
||||
'message_id': msg.msg_id,
|
||||
'roomid': msg.roomid,
|
||||
'sender': msg.sender,
|
||||
'file_path': file_url
|
||||
}
|
||||
else:
|
||||
return {
|
||||
'success': False,
|
||||
'message_id': msg.msg_id,
|
||||
'roomid': msg.roomid,
|
||||
'sender': msg.sender,
|
||||
'error': "图片下载失败"
|
||||
}
|
||||
# json = self.client.download_image(msg.appid, msg.content.xml_content, 2)
|
||||
# # {
|
||||
# # "ret": 200,
|
||||
# # "msg": "操作成功",
|
||||
# # "data": {
|
||||
# # "fileUrl": "/download/20240720/wx_BTVoJ_o_r6DpxNCNiycFE/0ca5b675-8e2c-4dc1-b288-3c44a40086ec4"
|
||||
# # }
|
||||
# # }
|
||||
# # 解析JSON http://192.168.2.240:2532/download/20250428/wx_3BC6eSHGE5xEm_hH3__7c/03ab5c03-5524-4a39-aabe-27ca014a4d1e.png
|
||||
# if json and json.get('data') and json['data'].get('fileUrl'):
|
||||
# file_url = json['data']['fileUrl']
|
||||
# if file_url:
|
||||
# logger.info(f"记录gewe服务端图片路径成功: {msg.msg_id} -> {file_url}")
|
||||
# # 后续如果需要使用,则去服务器端提取图片
|
||||
# # 直接使用下载后的路径更新数据库
|
||||
# self.message_db.update_message_image_path(msg.msg_id, file_url)
|
||||
#
|
||||
# return {
|
||||
# 'success': True,
|
||||
# 'message_id': msg.msg_id,
|
||||
# 'roomid': msg.roomid,
|
||||
# 'sender': msg.sender,
|
||||
# 'file_path': file_url
|
||||
# }
|
||||
# else:
|
||||
# return {
|
||||
# 'success': False,
|
||||
# 'message_id': msg.msg_id,
|
||||
# 'roomid': msg.roomid,
|
||||
# 'sender': msg.sender,
|
||||
# 'error': "图片下载失败"
|
||||
# }
|
||||
else:
|
||||
return {
|
||||
'success': False,
|
||||
|
||||
Reference in New Issue
Block a user