115 lines
3.0 KiB
Python
115 lines
3.0 KiB
Python
"""运行时路径解析。
|
||
|
||
本地环境:
|
||
- 仓库根 = 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)
|