Workflow-App/Workflow/scripts/_compare_doc_text.py
sjcoetzeesj-coder 11d0178ab1 feat: commit Workflow app source; move CIPC credentials to env
Adds the full Next.js app (app/, components/, lib/, scripts/, assets/,
docs/, Dockerfile, compose, configs) to version control.

Security:
- CIPC BizPortal customer-code logins (Login 1 + Login 3) now read
  CIPC_LOGIN1_CODE / CIPC_LOGIN1_PASSWORD / CIPC_LOGIN3_CODE /
  CIPC_LOGIN3_PASSWORD from .env.local instead of source.
- BizPortal personal login in apply-bizportal route reads
  BIZPORTAL_ID_NO / BIZPORTAL_PASSWORD.
- Added .env.example as the committed template.

.gitignore excludes .env*, node_modules, .next, logs, sqlite, Playwright
storage_state.json (live CIPC cookies), scratch dirs, client PDFs and
debug screenshots.
2026-10-18 15:21:45 +02:00

80 lines
No EOL
2.9 KiB
Python

"""Byte hashes already proved the stored files are all distinct. This compares
their TEXT so we can say whether the stored resignation letter is simply an
older render of the same letter the user just attached.
"""
import io
import urllib.parse
import urllib.request
from pathlib import Path
from pypdf import PdfReader
JEI = Path(r"C:\Users\SJ\.minimax-agent\projects\JEI")
env = {}
for line in (JEI / ".env.local").read_text(encoding="utf-8").splitlines():
line = line.strip()
if line and not line.startswith("#") and "=" in line:
k, v = line.split("=", 1)
env[k.strip()] = v.strip().strip('"').strip("'")
PB = env.get("NEXT_PUBLIC_PB_URL") or env["PB_URL"]
TOK = env["PB_TOKEN"]
LOCAL = {
"LOCAL: UFC - Shareholders Resolution Director Sune Resigned.pdf":
r"C:\Users\SJ\.minimax\v2\assets\2026\10\12\13-41-56-012-asset_20261012-134156-012_a0299b3ae338_88b7c484-UFC - Shareholders Resolution Director Sune Resigned.pdf",
"LOCAL: UFC - Sune Resignation Letter.pdf":
r"C:\Users\SJ\.minimax\v2\assets\2026\10\12\13-41-56-017-asset_20261012-134156-017_9aec1b4380ba_261a3e6b-UFC - Sune Resignation Letter.pdf",
}
STORED = [
("STORED resolution.signed_letter", "pbc_266170881", "e0dbxprazb70rqx", "corrected_v2_avwpnq7o93.pdf"),
("STORED resignation.letter", "ysterbaard_director_resignations", "8cfie18uhgy0n0o",
"resignation_letter_the_ultimate_fuel_company_1jk8t34nf3.pdf"),
("STORED resignation.signature", "ysterbaard_director_resignations", "8cfie18uhgy0n0o",
"tbde1evt2m6_8mz8kutpki.pdf"),
]
def text_of(b: bytes) -> str:
try:
r = PdfReader(io.BytesIO(b))
return "\n".join((p.extract_text() or "") for p in r.pages)
except Exception as e:
return f"<<unreadable: {e}>>"
def norm(s: str) -> str:
return " ".join(s.split()).lower()
texts = {}
for label, path in LOCAL.items():
b = Path(path).read_bytes()
texts[label] = (norm(text_of(b)), len(b))
print(f"{label}\n {len(b):>8} B chars={len(texts[label][0])}")
print()
for label, col, rid, fname in STORED:
url = f"{PB}/api/files/{col}/{rid}/{urllib.parse.quote(fname)}"
req = urllib.request.Request(url, headers={"Authorization": TOK})
with urllib.request.urlopen(req, timeout=120) as r:
b = r.read()
texts[label] = (norm(text_of(b)), len(b))
print(f"{label}\n {len(b):>8} B chars={len(texts[label][0])}")
print("\n=== TEXT SIMILARITY (fraction of the shorter text found in the longer) ===")
import difflib
labels = list(texts)
for i in range(len(labels)):
for j in range(i + 1, len(labels)):
a, b = texts[labels[i]][0], texts[labels[j]][0]
if not a or not b:
continue
ratio = difflib.SequenceMatcher(None, a, b).ratio()
print(f" {ratio * 100:5.1f}% {labels[i]} <-> {labels[j]}")
print("\n=== FIRST 400 CHARS OF EACH ===")
for label in labels:
t = texts[label][0]
print(f"\n--- {label}\n{t[:400]}")