"""Evaluator-side office helpers (controller): recalculate spreadsheet formulas with LibreOffice headless so that cached values exist whatever tool produced the workbook (openpyxl writes formulas without cached values). Arm-neutral: applied to every run's deliverables before deterministic evaluation and before judging; the raw archive is never modified.""" from __future__ import annotations import os, shutil, subprocess, tempfile SOFFICE = "/Applications/LibreOffice.app/Contents/MacOS/soffice" def recalc_xlsx(path: str, timeout=120) -> bool: """Replace `path` by a LibreOffice-recalculated copy. Returns True if it succeeded.""" if not os.path.isfile(SOFFICE) or not path.lower().endswith((".xlsx", ".xlsm")): return False try: with open(path, "rb") as f: if f.read(2) != b"PK": return False # not an OOXML zip (e.g. a text file named .xlsx): leave it as is, the evaluator must see garbage as garbage except OSError: return False with tempfile.TemporaryDirectory() as td, tempfile.TemporaryDirectory() as profile: try: r = subprocess.run([SOFFICE, f"-env:UserInstallation=file://{profile}", "--headless", "--calc", "--convert-to", "xlsx:Calc MS Excel 2007 XML", "--outdir", td, path], capture_output=True, text=True, timeout=timeout) out = os.path.join(td, os.path.basename(path)) if r.returncode == 0 and os.path.isfile(out) and os.path.getsize(out) > 0: shutil.copy2(out, path); return True except Exception: # noqa: BLE001 pass return False def recalc_tree(root: str) -> dict: res = {} for dp, _, fns in os.walk(root): for fn in fns: if fn.lower().endswith((".xlsx", ".xlsm")): res[os.path.relpath(os.path.join(dp, fn), root)] = recalc_xlsx(os.path.join(dp, fn)) return res