v2-AI-ethic-HOT-explanatory / core /content_sync.py
linxinhua's picture
Deploy: chapters-as-corpus restructure + analyze-input/direct-teaching skills + unified scratch (6 fields) + explicit BASE_DIR shell hint
82cc20c verified
Raw
History Blame Contribute Delete
2.35 kB
"""Mirror chapters from the SSOT (`AI_Ethic_HOT_chatbot/shared_content/`) into
this space's local `skills/case-corpus/references/` folder.
Runs at app startup. On HF Spaces the SSOT folder doesn't exist (it's local-only
design infrastructure, never deployed) — sync is a silent no-op and the deployed
copy is used as-is.
The flow keeps the SSOT as the single editable source: edit chapters in
`shared_content/` → next local `app.py` run mirrors any changes into
`skills/case-corpus/references/` (which is what the bot actually reads at runtime;
this is the only case-related content the bot sees) → `deploy.py` ships the
verified copy.
"""
import sys
from pathlib import Path
import shutil
from core.config_loader import BASE_DIR
# SSOT lives at AI_Ethic_HOT_chatbot/shared_content/, two folders up from this file.
SSOT_PATH = BASE_DIR.parent / "shared_content"
LOCAL_CHAPTERS_PATH = BASE_DIR / "skills" / "case-corpus" / "references"
def sync_chapters_from_ssot():
"""Mirror SSOT chapter files into LOCAL_CHAPTERS_PATH. Idempotent.
- Copies any SSOT *.md whose bytes differ from the local copy (or that doesn't exist locally).
- Removes any local *.md that no longer exists in SSOT.
- Does NOT touch the README.md (we exclude it explicitly so each side can have its own notes).
- Does nothing when SSOT_PATH is absent (HF Space scenario).
"""
if not SSOT_PATH.exists():
return
LOCAL_CHAPTERS_PATH.mkdir(parents=True, exist_ok=True)
ssot_files = {p.name: p for p in SSOT_PATH.glob("*.md") if p.name != "README.md"}
local_files = {p.name: p for p in LOCAL_CHAPTERS_PATH.glob("*.md")}
synced_changes = []
# Copy SSOT → local for any file that's new or differs.
for name, src in ssot_files.items():
dst = local_files.get(name) or (LOCAL_CHAPTERS_PATH / name)
if not dst.exists() or src.read_bytes() != dst.read_bytes():
shutil.copy2(src, dst)
synced_changes.append(f"+{name}" if not local_files.get(name) else f"~{name}")
# Remove any local file that no longer exists in SSOT (pure mirror).
for name in local_files.keys() - ssot_files.keys():
local_files[name].unlink()
synced_changes.append(f"-{name}")
if synced_changes:
print(f"[content_sync] {', '.join(synced_changes)}", file=sys.stderr)