import os import sys # 1. 处理读取库 try: import tomllib as toml_read # Python 3.11+ except ImportError: try: import tomli as toml_read except ImportError: print("错误: 缺少 TOML 读取库。请运行: pip install tomli") sys.exit(1) # 2. 处理写入库 (必须安装 pip install tomli-w) try: import tomli_w as toml_write except ImportError: # 如果没安装,提供一个 fallback 提示 toml_write = None def get_base_dir(): if getattr(sys, "frozen", False): return os.path.dirname(sys.executable) else: # 假设当前文件在项目根目录或根目录下的某个文件夹中 return os.path.dirname(os.path.dirname(os.path.abspath(__file__))) def get_resource_path(relative_path): base_path = get_base_dir() external_path = os.path.join(base_path, relative_path) if os.path.exists(external_path): return external_path if getattr(sys, "frozen", False): internal_path = os.path.join(sys._MEIPASS, relative_path) if os.path.exists(internal_path): return internal_path return external_path # ========================================== # 1. 配置加载 (Config Loader) # ========================================== def load_config(config_filename="config.toml"): config_path = get_resource_path(config_filename) if not os.path.exists(config_path): # 如果彻底找不到,返回一个最小化的默认值,防止程序奔溃 return {"source_file": "", "ai": {"api_key": ""}, "teachers": []} try: with open(config_path, "rb") as f: data = toml_read.load(f) base_dir = get_base_dir() # 使用 .get() 安全获取,防止 KeyError: 'paths' paths = data.get("paths", {}) class_info = data.get("class_info", {}) defaults = data.get("defaults", {}) config = { "root_path": base_dir, "data_folder": os.path.join(os.path.join("data")), # 扁平化映射 "source_file": get_resource_path( os.path.join("templates", paths.get("source_file", "")) ), "excel_file": get_resource_path( os.path.join("data", paths.get("excel_file", "")) ), "image_folder": get_resource_path( os.path.join("data", paths.get("image_folder", "")) ), "fonts_dir": get_resource_path(paths.get("fonts_dir", "fonts")), "output_folder": os.path.join( base_dir, paths.get("output_folder", "output") ), "signature_image": get_resource_path( os.path.join("data", paths.get("signature_image", "signature.png")) ), "class_name": class_info.get("class_name", "未命名班级"), "teachers": class_info.get("teachers", []), "class_type": class_info.get("class_type", 0), "default_comment": defaults.get("default_comment", "暂无评语"), "age_group": defaults.get("age_group", "大班上学期"), "ai": data.get( "ai", {"api_key": "", "api_url": "", "model": "", "prompt": ""} ), } return config except Exception as e: print(f"解析配置文件失败: {e}") return {} # ========================================== # 2. 配置保存 (Config Saver) # ========================================== def save_config(config_data, config_filename="config.toml"): if not toml_write: return False, "未安装 tomli-w 库,无法保存。请运行 pip install tomli-w" base_path = get_base_dir() save_path = os.path.join(base_path, config_filename) try: # 将扁平化的数据重新打包成嵌套结构,以适配 load_config 的读取逻辑 new_data = { "paths": { "source_file": os.path.basename(config_data.get("source_file", "")), "output_folder": os.path.basename( config_data.get("output_folder", "output") ), "excel_file": os.path.basename(config_data.get("excel_file", "")), "image_folder": os.path.basename(config_data.get("image_folder", "")), "fonts_dir": os.path.basename(config_data.get("fonts_dir", "fonts")), "signature_image": get_resource_path( os.path.join( "data", config_data.get("signature_image", "signature.png") ) ), }, "class_info": { "class_name": config_data.get("class_name", ""), "teachers": config_data.get("teachers", []), "class_type": config_data.get("class_type", 0), }, "defaults": { "default_comment": config_data.get("default_comment", ""), "age_group": config_data.get("age_group", ""), }, "ai": config_data.get("ai", {}), } # 写入文件 with open(save_path, "wb") as f: f.write(toml_write.dumps(new_data).encode("utf-8")) return True, f"成功保存到: {save_path}" except Exception as e: return False, f"写入失败: {str(e)}"