From a6e539b9f6fd1afd0ac8860dd5c58b6b9825ac6d Mon Sep 17 00:00:00 2001 From: SXP-Simon Date: Sun, 22 Feb 2026 16:08:48 +0800 Subject: [PATCH] =?UTF-8?q?fix(report):=20=E5=A2=9E=E5=BC=BA=E5=9B=BE?= =?UTF-8?q?=E7=89=87=E6=95=B0=E6=8D=AE=E6=A0=A1=E9=AA=8C=EF=BC=8C=E7=A1=AE?= =?UTF-8?q?=E4=BF=9D=E7=94=9F=E6=88=90=E6=9C=89=E6=95=88=E5=9B=BE=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- metadata.yaml | 2 +- .../platform/adapters/onebot_adapter.py | 7 ++- src/infrastructure/reporting/generators.py | 46 ++++++++++++++----- 3 files changed, 41 insertions(+), 14 deletions(-) diff --git a/metadata.yaml b/metadata.yaml index 460ad13..ca380ac 100644 --- a/metadata.yaml +++ b/metadata.yaml @@ -1,7 +1,7 @@ name: astrbot_plugin_qq_group_daily_analysis # 这是你的插件的唯一识别名。 display_name: 群分析总结插件 # 插件的显示名称 desc: "[多平台接入开发中] 群日常分析总结插件 - 支持 QQ (aiocqhttp)、Telegram、Discord;生成精美的群聊分析报告,支持话题分析、用户形象、群聊圣经等功能" # 插件简短描述 -version: v4.7.11 # 插件版本号。格式:v1.1.1 或者 v1.1 +version: v4.7.12 # 插件版本号。格式:v1.1.1 或者 v1.1 author: SXP-Simon # 作者 astrbot_version: ">=4.16.0" support_platforms: diff --git a/src/infrastructure/platform/adapters/onebot_adapter.py b/src/infrastructure/platform/adapters/onebot_adapter.py index 94cd1ed..e253984 100644 --- a/src/infrastructure/platform/adapters/onebot_adapter.py +++ b/src/infrastructure/platform/adapters/onebot_adapter.py @@ -475,8 +475,11 @@ class OneBotAdapter(PlatformAdapter): file_str = image_path if not image_path.startswith(("http://", "https://", "base64://")): if os.path.isabs(image_path): - # 如果是绝对路径,保持原样(兼容 Docker 中的 /AstrBot/ 路径) - file_str = f"file:///{image_path}" + # 如果是绝对路径且以 / 开头,只需加 file:// 即可构成 file:/// + if image_path.startswith("/"): + file_str = f"file://{image_path}" + else: + file_str = f"file:///{image_path}" else: # 如果是相对路径,转为绝对路径 file_str = f"file:///{os.path.abspath(image_path)}" diff --git a/src/infrastructure/reporting/generators.py b/src/infrastructure/reporting/generators.py index 07cc1d7..c906a4b 100644 --- a/src/infrastructure/reporting/generators.py +++ b/src/infrastructure/reporting/generators.py @@ -5,6 +5,7 @@ import asyncio import base64 +import os import re from datetime import datetime from pathlib import Path @@ -119,20 +120,43 @@ class ReportGenerator(IReportGenerator): ) if image_data: + # 校验是否为合法图片(防止 T2I 返回 500 错误 HTML 字符流) + is_valid = False + actual_data_head = None + if isinstance(image_data, bytes): - b64 = base64.b64encode(image_data).decode("utf-8") - image_url = f"base64://{b64}" - logger.info( - f"图片生成成功 ({image_options}): [Base64 Data {len(image_data)} bytes]" - ) - return image_url, html_content - elif isinstance(image_data, str): - # Fallback: 如果返回的是字符串(可能是URL或路径) - logger.info(f"图片生成成功 (String): {image_data}") + actual_data_head = image_data[:10] + elif isinstance(image_data, str) and os.path.exists(image_data): + try: + with open(image_data, "rb") as f: + actual_data_head = f.read(10) + except Exception as e: + logger.warning(f"读取图片临时文件失败: {e}") - return image_data, html_content + if actual_data_head: + # 检查 magic numbers (JPEG: FF D8, PNG: 89 50 4E 47) + if actual_data_head.startswith( + b"\xff\xd8" + ) or actual_data_head.startswith(b"\x89PNG"): + is_valid = True + else: + logger.warning( + f"渲染结果似乎不是有效的图片数据 (头部: {actual_data_head.hex()})" + ) - logger.warning(f"渲染策略 {image_options} 返回空数据") + if is_valid: + if isinstance(image_data, bytes): + b64 = base64.b64encode(image_data).decode("utf-8") + image_url = f"base64://{b64}" + logger.info( + f"图片生成成功 ({image_options}): [Base64 Data {len(image_data)} bytes]" + ) + return image_url, html_content + elif isinstance(image_data, str): + logger.info(f"图片生成成功 (String): {image_data}") + return image_data, html_content + + logger.warning(f"渲染策略 {image_options} 返回了无效或空数据") except Exception as e: logger.warning(f"渲染策略 {image_options} 失败: {e}")