"""运行时路径解析。 本地环境: - 仓库根 = scripts/main.py 的父目录的父目录 - data/ 在仓库根下 - output/ 在仓库根下 - .env 在仓库根下 宿主环境(jiangchang_skill_core 提供)会覆写这些路径到 {JIANGCHANG_DATA_ROOT}/{JIANGCHANG_USER_ID}/{slug}/... """ from __future__ import annotations import os from pathlib import Path from util.constants import SKILL_SLUG # util/runtime_paths.py → scripts/util/ → scripts/ → 仓库根(再上两级) _THIS_FILE = Path(__file__).resolve() _SCRIPTS_DIR = _THIS_FILE.parent.parent # scripts/ _SKILL_ROOT = _SCRIPTS_DIR.parent # alert-contract-expiring-hr/ def get_skill_root() -> Path: """返回 skill 仓库根目录。""" # 优先尊重环境变量(宿主设置过) env_root = os.environ.get("JIANGCHANG_SKILL_ROOT") if env_root: return Path(env_root) return _SKILL_ROOT def get_data_dir() -> Path: """返回 SQLite DB 与种子数据目录。""" env_dir = os.environ.get("JIANGCHANG_DATA_DIR") if env_dir: return Path(env_dir) return get_skill_root() / "data" def get_db_path() -> Path: """返回 SQLite DB 文件路径。""" env_db = os.environ.get("DB_PATH") if env_db: return Path(env_db) return get_data_dir() / f"{SKILL_SLUG}.db" def get_output_dir() -> Path: """返回 HTML 报告输出目录。""" env_out = os.environ.get("HTML_OUTPUT_DIR") if env_out: return Path(env_out) return get_skill_root() / "output" def get_env_path() -> Path: """返回 .env 路径(仓库根 / 当前工作目录)。""" return get_skill_root() / ".env" def get_dispatch_dir() -> Path: """返回派发 payload JSON 输出目录。""" return get_data_dir() / "dispatch" def get_logs_dir() -> Path: """返回日志目录(RotatingFileHandler 默认落地点)。""" env_dir = os.environ.get("JIANGCHANG_LOGS_DIR") if env_dir: return Path(env_dir) return get_data_dir() / "logs" def get_input_dir() -> Path: """返回用户主动投放的输入目录(含 contracts/*.csv + materials/*.{pdf,docx,doc})。""" env_dir = os.environ.get("INPUT_DIR") if env_dir: return Path(env_dir) return get_data_dir() / "input" def get_input_contracts_dir() -> Path: return get_input_dir() / "contracts" def get_input_materials_dir() -> Path: return get_input_dir() / "materials" def get_examples_dir() -> Path: """返回样例数据目录。""" return get_skill_root() / "examples" def get_templates_dir() -> Path: """返回 Jinja2 模板目录。""" return _SCRIPTS_DIR.parent / "scripts" / "templates" def ensure_dirs() -> None: """确保所有需要的目录存在。""" for d in ( get_data_dir(), get_output_dir(), get_dispatch_dir(), get_logs_dir(), get_input_dir(), get_input_contracts_dir(), get_input_materials_dir(), ): d.mkdir(parents=True, exist_ok=True)