mirror of
https://github.com/Nezumi-2711/astrbot_plugin_qq_group_daily_analysis.git
synced 2026-09-22 20:01:04 +00:00
refactor: 全局变量重构,受保护成员访问修复,同步 I/O 操作异步化
This commit is contained in:
@@ -32,10 +32,9 @@ class ReportGenerator:
|
||||
# 准备渲染数据
|
||||
render_payload = await self._prepare_render_data(analysis_result)
|
||||
|
||||
# 先渲染HTML模板
|
||||
html_content = self._render_html_template(
|
||||
self.html_templates.get_image_template(), render_payload
|
||||
)
|
||||
# 先渲染HTML模板(使用异步方法)
|
||||
image_template = await self.html_templates.get_image_template_async()
|
||||
html_content = self._render_html_template(image_template, render_payload)
|
||||
|
||||
# 检查HTML内容是否有效
|
||||
if not html_content:
|
||||
@@ -88,9 +87,9 @@ class ReportGenerator:
|
||||
) -> str | None:
|
||||
"""生成PDF格式的分析报告"""
|
||||
try:
|
||||
# 确保输出目录存在
|
||||
# 确保输出目录存在(使用 asyncio.to_thread 避免阻塞)
|
||||
output_dir = Path(self.config_manager.get_pdf_output_dir())
|
||||
output_dir.mkdir(parents=True, exist_ok=True)
|
||||
await asyncio.to_thread(output_dir.mkdir, parents=True, exist_ok=True)
|
||||
|
||||
# 生成文件名
|
||||
current_date = datetime.now().strftime("%Y%m%d")
|
||||
@@ -103,10 +102,9 @@ class ReportGenerator:
|
||||
render_data = await self._prepare_render_data(analysis_result)
|
||||
logger.info(f"PDF 渲染数据准备完成,包含 {len(render_data)} 个字段")
|
||||
|
||||
# 生成 HTML 内容(PDF模板使用{{}}占位符)
|
||||
html_content = self._render_html_template(
|
||||
self.html_templates.get_pdf_template(), render_data
|
||||
)
|
||||
# 生成 HTML 内容(使用异步方法)
|
||||
pdf_template = await self.html_templates.get_pdf_template_async()
|
||||
html_content = self._render_html_template(pdf_template, render_data)
|
||||
|
||||
# 检查HTML内容是否有效
|
||||
if not html_content:
|
||||
|
||||
+48
-18
@@ -3,6 +3,7 @@ HTML模板模块
|
||||
使用Jinja2加载外部HTML模板文件
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
|
||||
from jinja2 import Environment, FileSystemLoader, select_autoescape
|
||||
@@ -21,12 +22,11 @@ class HTMLTemplates:
|
||||
# 缓存不同模板的Jinja2环境
|
||||
self._envs = {}
|
||||
|
||||
def _get_env(self) -> Environment:
|
||||
"""获取当前配置的模板环境"""
|
||||
def _get_env_sync(self) -> Environment:
|
||||
"""获取当前配置的模板环境(同步版本,供 asyncio.to_thread 调用)"""
|
||||
template_name = self.config_manager.get_report_template()
|
||||
|
||||
# 如果环境已缓存且配置未变(这里简单假设配置变了会重新获取,或者我们可以每次都检查)
|
||||
# 为了响应配置热更,我们每次都检查一下或者简单地按需创建
|
||||
# 如果环境已缓存且配置未变
|
||||
if template_name in self._envs:
|
||||
return self._envs[template_name]
|
||||
|
||||
@@ -34,7 +34,6 @@ class HTMLTemplates:
|
||||
if not os.path.exists(template_dir):
|
||||
logger.warning(f"模板目录不存在: {template_dir},回退到 scrapbook")
|
||||
template_dir = os.path.join(self.base_dir, "scrapbook")
|
||||
# 如果 scrapbook 也不存在,那就有大问题了,不过这里假设 scrapbook 一定存在
|
||||
|
||||
env = Environment(
|
||||
loader=FileSystemLoader(template_dir),
|
||||
@@ -45,31 +44,62 @@ class HTMLTemplates:
|
||||
self._envs[template_name] = env
|
||||
return env
|
||||
|
||||
def get_image_template(self) -> str:
|
||||
"""获取图片报告的HTML模板(返回原始模板字符串)"""
|
||||
async def _get_env_async(self) -> Environment:
|
||||
"""获取当前配置的模板环境(异步版本)"""
|
||||
return await asyncio.to_thread(self._get_env_sync)
|
||||
|
||||
def _get_env(self) -> Environment:
|
||||
"""获取当前配置的模板环境(同步版本,向后兼容)"""
|
||||
return self._get_env_sync()
|
||||
|
||||
def _read_template_file_sync(self, filename: str) -> str:
|
||||
"""同步读取模板文件内容"""
|
||||
with open(filename, encoding="utf-8") as f:
|
||||
return f.read()
|
||||
|
||||
async def get_image_template_async(self) -> str:
|
||||
"""获取图片报告的HTML模板(异步版本,返回原始模板字符串)"""
|
||||
try:
|
||||
env = self._get_env()
|
||||
# 获取模板对象
|
||||
env = await self._get_env_async()
|
||||
template = env.get_template("image_template.html")
|
||||
# 读取原始模板文件内容,而不是渲染它
|
||||
with open(template.filename, encoding="utf-8") as f:
|
||||
return f.read()
|
||||
return await asyncio.to_thread(
|
||||
self._read_template_file_sync, template.filename
|
||||
)
|
||||
except Exception as e:
|
||||
# 如果加载失败,返回空字符串让调用者处理
|
||||
logger.error(f"加载图片模板失败: {e}")
|
||||
return ""
|
||||
|
||||
def get_pdf_template(self) -> str:
|
||||
"""获取PDF报告的HTML模板(返回原始模板字符串)"""
|
||||
def get_image_template(self) -> str:
|
||||
"""获取图片报告的HTML模板(同步版本,向后兼容)"""
|
||||
try:
|
||||
env = self._get_env()
|
||||
# 获取模板对象
|
||||
template = env.get_template("image_template.html")
|
||||
with open(template.filename, encoding="utf-8") as f:
|
||||
return f.read()
|
||||
except Exception as e:
|
||||
logger.error(f"加载图片模板失败: {e}")
|
||||
return ""
|
||||
|
||||
async def get_pdf_template_async(self) -> str:
|
||||
"""获取PDF报告的HTML模板(异步版本,返回原始模板字符串)"""
|
||||
try:
|
||||
env = await self._get_env_async()
|
||||
template = env.get_template("pdf_template.html")
|
||||
# 读取原始模板文件内容,而不是渲染它
|
||||
return await asyncio.to_thread(
|
||||
self._read_template_file_sync, template.filename
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"加载PDF模板失败: {e}")
|
||||
return ""
|
||||
|
||||
def get_pdf_template(self) -> str:
|
||||
"""获取PDF报告的HTML模板(同步版本,向后兼容)"""
|
||||
try:
|
||||
env = self._get_env()
|
||||
template = env.get_template("pdf_template.html")
|
||||
with open(template.filename, encoding="utf-8") as f:
|
||||
return f.read()
|
||||
except Exception as e:
|
||||
# 如果加载失败,返回空字符串让调用者处理
|
||||
logger.error(f"加载PDF模板失败: {e}")
|
||||
return ""
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ class AutoScheduler:
|
||||
elif bot_qq_ids:
|
||||
self.bot_manager.set_bot_qq_ids([bot_qq_ids])
|
||||
|
||||
async def _get_platform_id_for_group(self, group_id):
|
||||
async def get_platform_id_for_group(self, group_id):
|
||||
"""根据群ID获取对应的平台ID"""
|
||||
try:
|
||||
# 首先检查已注册的bot实例
|
||||
@@ -355,7 +355,7 @@ class AutoScheduler:
|
||||
else:
|
||||
# 回退到原来的逻辑(单个平台)
|
||||
logger.warning(f"群 {group_id} 没有多个平台可用,使用回退逻辑")
|
||||
platform_id = await self._get_platform_id_for_group(group_id)
|
||||
platform_id = await self.get_platform_id_for_group(group_id)
|
||||
|
||||
if not platform_id:
|
||||
logger.error(f"❌ 群 {group_id} 无法获取平台ID,跳过分析")
|
||||
@@ -621,7 +621,7 @@ class AutoScheduler:
|
||||
)
|
||||
else:
|
||||
logger.warning(f"群 {group_id} 没有多个平台可用,使用回退逻辑")
|
||||
platform_id = await self._get_platform_id_for_group(group_id)
|
||||
platform_id = await self.get_platform_id_for_group(group_id)
|
||||
if not platform_id:
|
||||
logger.error(f"❌ 群 {group_id} 无法获取平台ID,无法发送图片")
|
||||
return False
|
||||
@@ -794,7 +794,7 @@ class AutoScheduler:
|
||||
else:
|
||||
# 回退到原来的逻辑(单个平台)
|
||||
logger.warning(f"群 {group_id} 没有多个平台可用,使用回退逻辑")
|
||||
platform_id = await self._get_platform_id_for_group(group_id)
|
||||
platform_id = await self.get_platform_id_for_group(group_id)
|
||||
|
||||
if not platform_id:
|
||||
logger.error(f"❌ 群 {group_id} 无法获取平台ID,无法发送文本")
|
||||
@@ -874,7 +874,7 @@ class AutoScheduler:
|
||||
else:
|
||||
# 回退到原来的逻辑(单个平台)
|
||||
logger.warning(f"群 {group_id} 没有多个平台可用,使用回退逻辑")
|
||||
platform_id = await self._get_platform_id_for_group(group_id)
|
||||
platform_id = await self.get_platform_id_for_group(group_id)
|
||||
|
||||
if not platform_id:
|
||||
logger.error(f"❌ 群 {group_id} 无法获取平台ID,无法发送PDF")
|
||||
|
||||
Reference in New Issue
Block a user