97 lines
3.0 KiB
Python
97 lines
3.0 KiB
Python
#!/usr/bin/env python3
|
|
"""Run QQnote scripts with QQsci config injected as environment variables."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
SCRIPT_MAP = {
|
|
"generate_zotero_ai_note": "generate_zotero_ai_note.py",
|
|
"summarize_zotero_table": "summarize_zotero_table.py",
|
|
"audit_zotero_ai_notes": "audit_zotero_ai_notes.py",
|
|
}
|
|
|
|
|
|
def skill_root() -> Path:
|
|
return Path(__file__).resolve().parents[1]
|
|
|
|
|
|
def load_json(path: Path) -> dict:
|
|
if not path.exists():
|
|
return {}
|
|
return json.loads(path.read_text(encoding="utf-8"))
|
|
|
|
|
|
def merged_config(root: Path) -> dict:
|
|
template = load_json(root / "config" / "config.template.json")
|
|
local = load_json(root / "config" / "config.local.json")
|
|
|
|
def merge(base: dict, override: dict) -> dict:
|
|
out = dict(base)
|
|
for key, value in override.items():
|
|
if isinstance(value, dict) and isinstance(out.get(key), dict):
|
|
out[key] = merge(out[key], value)
|
|
else:
|
|
out[key] = value
|
|
return out
|
|
|
|
return merge(template, local)
|
|
|
|
|
|
def set_if_present(env: dict[str, str], key: str, value: object) -> None:
|
|
if key in env and env[key]:
|
|
return
|
|
if value is None:
|
|
return
|
|
text = str(value)
|
|
if text:
|
|
env[key] = text
|
|
|
|
|
|
def build_env(config: dict) -> dict[str, str]:
|
|
env = os.environ.copy()
|
|
deepseek = config.get("deepseek") or {}
|
|
zotero = config.get("zotero") or {}
|
|
|
|
set_if_present(env, deepseek.get("env_api_key", "AWESOMEGPT_API_KEY"), deepseek.get("api_key"))
|
|
set_if_present(env, deepseek.get("env_base_url", "AWESOMEGPT_BASE_URL"), deepseek.get("base_url"))
|
|
set_if_present(env, deepseek.get("env_model", "AWESOMEGPT_MODEL"), deepseek.get("model"))
|
|
set_if_present(env, zotero.get("env_web_api_key", "ZOTERO_API_KEY"), zotero.get("web_api_key"))
|
|
set_if_present(env, zotero.get("env_user_id", "ZOTERO_USER_ID"), zotero.get("user_id"))
|
|
return env
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("--script", required=True, choices=sorted(SCRIPT_MAP))
|
|
parser.add_argument("--qqnote-path", default="")
|
|
parser.add_argument("qqnote_args", nargs=argparse.REMAINDER)
|
|
args = parser.parse_args()
|
|
|
|
root = skill_root()
|
|
config = merged_config(root)
|
|
qqnote = Path(args.qqnote_path or (config.get("qqnote") or {}).get("skill_path") or "")
|
|
if not qqnote:
|
|
qqnote = Path.home() / ".codex" / "skills" / "QQnote-skill"
|
|
script = qqnote / "scripts" / SCRIPT_MAP[args.script]
|
|
if not script.exists():
|
|
print(f"QQnote script not found: {script}", file=sys.stderr)
|
|
return 2
|
|
|
|
extra_args = list(args.qqnote_args)
|
|
if extra_args and extra_args[0] == "--":
|
|
extra_args = extra_args[1:]
|
|
|
|
command = [sys.executable, str(script), *extra_args]
|
|
return subprocess.call(command, env=build_env(config))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|