| 12345678910111213141516171819202122232425262728293031323334 |
- #!/usr/bin/env python3
- # -*- coding: utf-8 -*-
- """交付脱敏 (发给非业主方时用): 把事实契约的**内部面**标题换成已有的脱敏公开标题, 重算逐条 sha 与契约 sha, 重出四个消费者, 再自校验.
- 契约本来就带 display.title_zh_public (BANNED 替换后的), 四个消费者也早已 BANNED 零命中; 只有 display.title_zh 这一处内部面留了原文。
- 用法: python scripts/deliver_desensitize.py --stage <暂存目录> (不动正本; 打包时用暂存目录里的这几个文件覆盖)"""
- from __future__ import annotations
- import argparse, importlib, json, shutil, sys
- from pathlib import Path
- ROOT = Path(__file__).resolve().parents[1]; sys.path.insert(0, str(ROOT / "scripts"))
- def main():
- ap = argparse.ArgumentParser(); ap.add_argument("--stage", required=True); a = ap.parse_args()
- stage = Path(a.stage).resolve(); (stage / "derived").mkdir(parents=True, exist_ok=True)
- m = importlib.import_module("guanlan_facts_contract")
- con = json.loads(m.CONTRACT.read_text(encoding="utf-8"))
- n = 0
- for c in con["claims"]:
- d = c["display"]
- if d.get("banned_hits"):
- d["title_zh"] = d["title_zh_public"]; d["banned_hits"] = 0; n += 1
- c["sha256"] = m.sha(m.canon({k: v for k, v in c.items() if k != "sha256"}).encode("utf-8"))
- con["banned_hits_total"] = 0; con["face"] = "delivery (标题已脱敏; 场名/台号保留 —— 那是本场自己的数据)"
- con["contract_sha256"] = m.sha(m.canon({k: v for k, v in con.items() if k not in ("contract_sha256", "built", "git_head")}).encode("utf-8"))
- cp = stage / m.CONTRACT.name; cp.write_text(json.dumps(con, ensure_ascii=False, indent=1), encoding="utf-8")
- # 用暂存路径重出消费者并自校验 (证明脱敏后整条链仍自洽)
- m.CONTRACT, m.DERIVED = cp, stage / "derived"
- m.render(con, m.DERIVED); bad = m.check()
- print(f"脱敏 {n} 条标题; 契约 sha {con['contract_sha256'][:16]}; 消费者重出 {len(list((stage / 'derived').glob('*')))} 个; 自校验 {'通过' if not bad else bad[:3]}")
- return 0 if not bad else 2
- if __name__ == "__main__":
- sys.exit(main())
|