PCM_Report/config_category.py

196 lines
5.9 KiB
Python

"""
配置分类管理模块
支持从指定目录扫描配置分类,每个分类包含 default.json 和模板文件
"""
import os
import json
from pathlib import Path
from typing import List, Dict, Optional
from dataclasses import dataclass
@dataclass
class ConfigCategory:
"""配置分类"""
name: str # 分类名称(目录名)
path: Path # 分类目录路径
config_path: Path # config.json 路径
template_path: Optional[Path] # 模板文件路径
script_path: Optional[Path] # 脚本文件路径 (table.py)
class ConfigCategoryManager:
"""配置分类管理器"""
# 配置目录名称(在可执行文件同级)
CONFIG_DIR_NAME = "configs"
# 固定的文件名
CONFIG_FILENAME = "config.json"
TEMPLATE_FILENAME = "template.docx"
SCRIPT_FILENAME = "table.py"
def __init__(self, base_dir: Optional[Path] = None):
"""
初始化配置分类管理器
Args:
base_dir: 基础目录,默认为当前文件所在目录
"""
if base_dir is None:
base_dir = Path(__file__).resolve().parent
self.base_dir = base_dir
self.config_root = base_dir / self.CONFIG_DIR_NAME
def ensure_config_dir(self) -> Path:
"""确保配置目录存在,如果不存在则创建"""
self.config_root.mkdir(parents=True, exist_ok=True)
return self.config_root
def scan_categories(self) -> List[ConfigCategory]:
"""
扫描所有配置分类
Returns:
配置分类列表
"""
categories = []
# 确保配置目录存在
if not self.config_root.exists():
return categories
# 遍历配置目录下的所有子目录
for item in self.config_root.iterdir():
if not item.is_dir():
continue
# 检查是否包含固定的配置文件名
config_path = item / self.CONFIG_FILENAME
if not config_path.exists():
continue
# 检查是否包含固定的模板文件名
template_path = item / self.TEMPLATE_FILENAME
if not template_path.exists():
template_path = None
# 检查是否包含固定的脚本文件名
script_path = item / self.SCRIPT_FILENAME
if not script_path.exists():
script_path = None
# 创建分类对象
category = ConfigCategory(
name=item.name,
path=item,
config_path=config_path,
template_path=template_path,
script_path=script_path
)
categories.append(category)
# 按名称排序
categories.sort(key=lambda c: c.name)
return categories
def get_category(self, name: str) -> Optional[ConfigCategory]:
"""
获取指定名称的配置分类
Args:
name: 分类名称
Returns:
配置分类对象,如果未找到则返回 None
"""
categories = self.scan_categories()
for category in categories:
if category.name == name:
return category
return None
def get_category_names(self) -> List[str]:
"""
获取所有配置分类名称
Returns:
分类名称列表
"""
categories = self.scan_categories()
return [c.name for c in categories]
def create_category(self, name: str, config_data: Optional[Dict] = None,
template_source: Optional[Path] = None) -> ConfigCategory:
"""
创建新的配置分类
Args:
name: 分类名称
config_data: 配置数据(字典),如果为 None 则创建空配置
template_source: 模板文件源路径,如果提供则复制到分类目录
Returns:
创建的配置分类对象
"""
# 确保配置根目录存在
self.ensure_config_dir()
# 创建分类目录
category_dir = self.config_root / name
category_dir.mkdir(parents=True, exist_ok=True)
# 创建固定名称的配置文件
config_path = category_dir / self.CONFIG_FILENAME
if config_data is None:
config_data = {}
with config_path.open('w', encoding='utf-8') as f:
json.dump(config_data, f, ensure_ascii=False, indent=2)
# 复制模板文件(如果提供),使用固定名称
template_path = None
if template_source and template_source.exists():
template_path = category_dir / self.TEMPLATE_FILENAME
import shutil
shutil.copy2(template_source, template_path)
return ConfigCategory(
name=name,
path=category_dir,
config_path=config_path,
template_path=template_path
)
def delete_category(self, name: str) -> bool:
"""
删除配置分类
Args:
name: 分类名称
Returns:
是否成功删除
"""
category = self.get_category(name)
if category is None:
return False
try:
import shutil
shutil.rmtree(category.path)
return True
except Exception:
return False
def get_default_category_manager() -> ConfigCategoryManager:
"""获取默认的配置分类管理器(单例模式)"""
if not hasattr(get_default_category_manager, '_instance'):
get_default_category_manager._instance = ConfigCategoryManager()
return get_default_category_manager._instance