Nolikumi-as-Code 0.1.0: 93 iestāžu nolikumi kā teksts un XML
Shēma nolikums-0.1, katalogs nolikumi.yaml, datu līgums B05. Teksts — likumi.lv konsolidētās redakcijas 2026-10-11 (sources/), dati (data/), datnes nosaukums <VPK ID>-<saīsinājums>. Pārbaude: 0 kļūdas; 92/93 teksti sakrīt ar likumi.lv lapu, 19-0458 — 2 cipari informatīvajā atsaucē. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016679RwmHsuTFfxt26wP6rk
This commit is contained in:
53
tools/verify_html.py
Normal file
53
tools/verify_html.py
Normal file
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Teksta datnes salīdzināšana ar likumi.lv lapu (lai pārliecinātos, ka teksts nav zaudēts vai pārveidots).
|
||||
|
||||
python3 tools/verify_html.py <html kešs>
|
||||
|
||||
Salīdzina burtu un ciparu secību: teksta datne pret lapas redzamo dokumenta tekstu no virsraksta līdz pēdējam
|
||||
parakstītājam (bez tiesību akta pases, saitēm un izvēlnēm). Lapu nolasa ar lxml text_content — citādi nekā convert.py.
|
||||
"""
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
import lxml.html
|
||||
import yaml
|
||||
|
||||
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
|
||||
def norm(s):
|
||||
return re.sub(r"[^0-9a-zāčēģīķļņšūž⁰¹²³⁴⁵⁶⁷⁸⁹]", "", s.lower().replace("", ""))
|
||||
|
||||
|
||||
def page_text(path):
|
||||
r = lxml.html.fromstring(open(path, encoding="utf-8").read())
|
||||
body = r.xpath("//div[contains(concat(' ', normalize-space(@class), ' '), ' TV207 ')]")[0].getparent()
|
||||
for s in body.iter("sup"):
|
||||
s.text = (s.text or "").translate(str.maketrans("0123456789", "⁰¹²³⁴⁵⁶⁷⁸⁹"))
|
||||
parts = []
|
||||
for el in body:
|
||||
c = (el.get("class") or "").split()
|
||||
if c and c[0].startswith("TV") and el.tag != "style":
|
||||
for junk in el.xpath(".//*[contains(@class,'info-icon-wrapper') or contains(@class,'panta-doc-npk')]"):
|
||||
junk.getparent().remove(junk)
|
||||
parts.append(el.text_content())
|
||||
return norm(" ".join(parts))
|
||||
|
||||
|
||||
def main(cache):
|
||||
cat = yaml.safe_load(open(os.path.join(ROOT, "nolikumi.yaml"), encoding="utf-8"))
|
||||
bad = 0
|
||||
for e in cat["nolikumi"]:
|
||||
stem = os.path.basename(e["file"])[:-4]
|
||||
t = norm(open(os.path.join(ROOT, "sources", stem + ".txt"), encoding="utf-8").read())
|
||||
h = page_text(os.path.join(cache, f"{e['likumi_id']}.html"))
|
||||
if t != h:
|
||||
bad += 1
|
||||
i = next((k for k in range(min(len(t), len(h))) if t[k] != h[k]), min(len(t), len(h)))
|
||||
print(f"ATŠĶIRAS {stem}: teksts {len(t)}, lapa {len(h)}; no {i}: '{t[i:i+60]}' / '{h[i:i+60]}'")
|
||||
print(f"pārbaudīti {len(cat['nolikumi'])}, atšķiras {bad}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv[1])
|
||||
Reference in New Issue
Block a user