Files
growth_report/config/config.py
2025-12-13 19:44:27 +08:00

131 lines
4.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
import sys
# 尝试导入 toml 解析库
try:
import tomllib as toml # Python 3.11+
except ImportError:
try:
import tomli as toml # pip install tomli
except ImportError:
print("错误: 缺少 TOML 解析库。请运行: pip install tomli")
sys.exit(1)
def get_base_dir():
"""
获取程序运行的基准目录 (即 EXE 所在的目录 或 开发环境的项目根目录)
用于确定 output_folder 等需要写入的路径。
"""
if getattr(sys, 'frozen', False):
# 打包环境: EXE 所在目录
return os.path.dirname(sys.executable)
else:
# 开发环境: 项目根目录 (假设此脚本在 utils/ 文件夹中,需要向上两级)
return os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
def get_resource_path(relative_path):
"""
智能路径获取:
1. 优先检查 EXE 旁边是否有该文件 (外部资源)。
2. 如果没有,则使用 EXE 内部打包的资源 (内部资源)。
"""
# 1. 获取外部基准路径
base_path = get_base_dir()
# 拼接外部路径
external_path = os.path.join(base_path, relative_path)
# 如果外部文件存在,直接返回 (优先使用用户修改过的文件)
if os.path.exists(external_path):
return external_path
# 2. 如果外部不存在,且处于打包环境,则回退到内部临时目录 (sys._MEIPASS)
if getattr(sys, 'frozen', False):
# sys._MEIPASS 是 PyInstaller 解压临时文件的目录
internal_path = os.path.join(sys._MEIPASS, relative_path)
if os.path.exists(internal_path):
return internal_path
# 3. 默认返回外部路径
# (如果都没找到,让报错信息指向外部路径,提示用户文件缺失)
return external_path
# ==========================================
# 1. 配置加载 (Config Loader)
# ==========================================
def load_config(config_filename="config.toml"):
"""读取 TOML 配置文件"""
# 1. 智能获取配置文件路径
# (优先找 EXE 旁边的 config.toml找不到则用打包在里面的)
config_path = get_resource_path(config_filename)
if not os.path.exists(config_path):
print(f"错误: 找不到配置文件 {config_filename}")
print(f"尝试寻找的路径是: {config_path}")
# 如果是打包环境,提示用户可能需要把 config.toml 复制出来
if getattr(sys, 'frozen', False):
print("提示: 请确保 config.toml 位于程序同级目录下,或已正确打包。")
sys.exit(1)
try:
with open(config_path, "rb") as f:
data = toml.load(f)
# 获取基准目录(用于 output_folder
base_dir = get_base_dir()
# 将 TOML 的层级结构映射回扁平结构
# ⚠️ 注意:
# - 读取类文件 (模板, Excel, 图片, 字体) 使用 get_resource_path (支持内外回退)
# - 写入类文件夹 (output_folder) 使用 os.path.join(base_dir, ...) (必须在外部)
config = {
"root_path": base_dir,
# --- 资源文件 (使用智能路径) ---
# 假设 config.toml 里写的是 "report_template.pptx",文件在 templates 文件夹下
"source_file": get_resource_path(
os.path.join("templates", data["paths"]["source_file"])
),
# 假设 config.toml 里写的是 "names.xlsx",文件在 data 文件夹下
# 如果 config.toml 里写的是 "data/names.xlsx",则不需要 os.path.join("data", ...)
"excel_file": get_resource_path(
os.path.join("data", data["paths"]["excel_file"])
),
"image_folder": get_resource_path(
os.path.join("data", data["paths"]["image_folder"])
),
"fonts_dir": get_resource_path(
os.path.join(data["paths"]["fonts_dir"])
),
# --- 输出文件夹 (必须强制在外部,不能指向临时目录) ---
"output_folder": os.path.join(base_dir, data["paths"]["output_folder"]),
# --- 其他配置 ---
"class_name": data["class_info"]["class_name"],
"teachers": data["class_info"]["teachers"],
"default_comment": data["defaults"].get("default_comment", "暂无评语"),
"age_group": data["defaults"].get("age_group", "大班上学期"),
"ai": data["ai"],
}
return config
except KeyError as e:
print(f"配置文件格式错误,缺少键值: {e}")
sys.exit(1)
except Exception as e:
print(f"读取配置文件出错: {e}")
import traceback
traceback.print_exc()
sys.exit(1)