""" 配置分类管理模块 支持从指定目录扫描配置分类,每个分类包含 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