TravelContentCreator/domain/poster/template_manager.py

179 lines
5.3 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
模板管理器
负责模板的加载、缓存和管理
"""
import logging
import importlib
from typing import Dict, Any, Optional, List, Type
from pathlib import Path
logger = logging.getLogger(__name__)
class TemplateManager:
"""
模板管理器
职责:
- 从数据库或默认配置加载模板
- 动态加载模板处理器类
- 缓存模板实例
"""
# 默认模板配置
DEFAULT_TEMPLATES = {
'vibrant': {
'id': 'vibrant',
'name': '活力风格',
'handler_path': 'poster.templates.vibrant_template',
'class_name': 'VibrantTemplate',
'description': '适合景点、活动等充满活力的场景',
'is_active': True
},
'business': {
'id': 'business',
'name': '商务风格',
'handler_path': 'poster.templates.business_template',
'class_name': 'BusinessTemplate',
'description': '适合酒店、房地产等商务场景',
'is_active': True
}
}
def __init__(self, db_service=None):
"""
初始化模板管理器
Args:
db_service: 数据库服务(可选)
"""
self._db_service = db_service
self._templates: Dict[str, Dict[str, Any]] = {}
self._instances: Dict[str, Any] = {}
self._load_templates()
def _load_templates(self):
"""加载模板配置"""
# 尝试从数据库加载
if self._db_service:
try:
db_templates = self._db_service.get_active_poster_templates()
if db_templates:
self._templates = {t['id']: t for t in db_templates}
logger.info(f"从数据库加载了 {len(self._templates)} 个模板")
return
except Exception as e:
logger.warning(f"从数据库加载模板失败: {e}")
# 使用默认模板
self._templates = self.DEFAULT_TEMPLATES.copy()
logger.info("使用默认模板配置")
def reload(self):
"""重新加载模板"""
self._instances.clear()
self._load_templates()
def get_template_info(self, template_id: str) -> Optional[Dict[str, Any]]:
"""
获取模板信息
Args:
template_id: 模板 ID
Returns:
模板信息字典
"""
return self._templates.get(template_id)
def get_template_handler(self, template_id: str):
"""
获取模板处理器实例
Args:
template_id: 模板 ID
Returns:
模板处理器实例
"""
# 检查缓存
if template_id in self._instances:
return self._instances[template_id]
# 获取模板信息
template_info = self._templates.get(template_id)
if not template_info:
logger.error(f"未找到模板: {template_id}")
return None
# 动态加载
handler_path = template_info.get('handler_path')
class_name = template_info.get('class_name')
if not handler_path or not class_name:
logger.error(f"模板 {template_id} 缺少 handler_path 或 class_name")
return None
try:
module = importlib.import_module(handler_path)
template_class = getattr(module, class_name)
instance = template_class()
# 缓存实例
self._instances[template_id] = instance
logger.info(f"加载模板处理器: {template_id} -> {class_name}")
return instance
except Exception as e:
logger.error(f"加载模板处理器失败: {template_id}, {e}")
return None
def list_templates(self, active_only: bool = True) -> List[Dict[str, Any]]:
"""
列出所有模板
Args:
active_only: 是否只返回激活的模板
Returns:
模板列表
"""
templates = []
for template_id, info in self._templates.items():
if active_only and not info.get('is_active', True):
continue
templates.append({
'id': template_id,
'name': info.get('name', template_id),
'description': info.get('description', ''),
'is_active': info.get('is_active', True),
})
return templates
def has_template(self, template_id: str) -> bool:
"""检查模板是否存在"""
return template_id in self._templates
def update_stats(self, template_id: str, success: bool, duration: float):
"""
更新模板使用统计
Args:
template_id: 模板 ID
success: 是否成功
duration: 耗时(秒)
"""
if self._db_service:
try:
self._db_service.update_template_usage_stats(
template_id, success, duration
)
except Exception as e:
logger.warning(f"更新模板统计失败: {e}")