#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 補完:把白話解說與 OCR 補正併入資料庫,重寫筆記與網頁。 不連網、不重抓、不重新處理 PDF,全部從既有的 _pipeline/資料庫.json 出發。 cd C:\\Users\\JudyLin\\Documents\\釋字及憲法法庭資料庫 python _pipeline\\補完.py 產出: - 10_釋字/、20_憲判/ 筆記加上「白話解說(AI 生成)」區塊 - 19 篇原本無文字層的意見書補上 OCR 文字 - 釋字及憲法法庭資料庫.html 完整版(含意見書全文) - 釋字及憲法法庭資料庫_輕量版.html 只到理由書與白話解說,意見書留連結 - 00_索引/校驗報告.md 更新 """ import json, sys, time, importlib.util from pathlib import Path PIPE = Path(__file__).resolve().parent ROOT = PIPE.parent spec = importlib.util.spec_from_file_location("builder", PIPE / "建置資料庫.py") B = importlib.util.module_from_spec(spec) spec.loader.exec_module(B) def main(): try: sys.stdout.reconfigure(encoding="utf-8") except Exception: pass dbp = PIPE / "資料庫.json" if not dbp.exists(): print("找不到 _pipeline/資料庫.json,請先執行 建置資料庫.py") sys.exit(1) recs = json.load(open(dbp, encoding="utf-8")) print(f"載入 {len(recs)} 筆") ai = json.load(open(PIPE / "白話解說.json", encoding="utf-8")) ocr = json.load(open(PIPE / "OCR補正.json", encoding="utf-8")) opai_p = PIPE / "意見書白話.json" opai = json.load(open(opai_p, encoding="utf-8")) if opai_p.exists() else {} print(f"白話解說 {len(ai)} 筆;OCR 補正 {len(ocr)} 篇;意見書白話 {len(opai)} 篇") n_ai = n_ocr = 0 for r in recs: if r["k"] in ai: r["ai"] = ai[r["k"]] n_ai += 1 for i, o in enumerate(r["o"], 1): key = f'{r["k"]}#{i}' if key in ocr and not o.get("x"): o["x"] = ocr[key] + "\n\n(本篇原始 PDF 無文字層,以繁體中文 OCR 擷取,可能有辨識誤差;請以官網 PDF 為準)" o.pop("low", None) n_ocr += 1 n_op = 0 for r in recs: for i, o in enumerate(r["o"], 1): key = f'{r["k"]}#{i}' if key in opai: o["ai"] = opai[key] n_op += 1 print(f"併入白話解說 {n_ai} 筆;補上 OCR {n_ocr} 篇;意見書白話 {n_op} 篇") roster = B.derive_judges(recs) nw = sum(1 for r in recs if r["j"]["w"]) npro = len({x for r in recs for x in r["j"]["p"]}) print(f"大法官名冊 {len(roster)} 人;可辨識主筆 {nw} 則;曾提出意見書 {npro} 人") print("重寫 Markdown 筆記與法條索引 …") nlaw = B.write_notes(recs) B.write_index(recs) print("重寫網頁(完整版)…") out1, s1 = B.write_html(recs) print("重寫網頁(輕量版)…") out2, s2 = B.write_html(recs, lite=True, filename="釋字及憲法法庭資料庫_輕量版.html") still = sum(1 for r in recs for o in r["o"] if not o.get("x")) rep = (ROOT / "00_索引" / "校驗報告.md") txt = rep.read_text(encoding="utf-8") if rep.exists() else "# 校驗報告\n" txt += (f"\n\n## 補完({time.strftime('%Y-%m-%d %H:%M:%S')})\n\n" f"- 白話解說:{n_ai} / {len(recs)} 則,皆標示為 AI 生成並與原文分區\n" f"- 意見書白話解說:{n_op} / {sum(len(r['o']) for r in recs)} 篇\n" f"- OCR 補正:{n_ocr} 篇\n" f"- 仍無文字之意見書:{still} 篇\n" f"- 法條節點:{nlaw}\n" f"- 完整版網頁:{s1/1048576:.1f} MB(字元數)\n" f"- 輕量版網頁:{s2/1048576:.1f} MB(字元數)\n") rep.write_text(txt, encoding="utf-8") json.dump(recs, open(dbp, "w", encoding="utf-8"), ensure_ascii=False) print("=" * 60) print("完成。") print(" 完整版:", out1) print(" 輕量版:", out2) print(" 仍無文字之意見書:", still, "篇") print("=" * 60) if __name__ == "__main__": main()