From bc1606a4d0b0f94fa5456b3ac9dcaa659ff76d79 Mon Sep 17 00:00:00 2001 From: Tommaso Bianchi Date: Sun, 23 Aug 2026 02:19:30 +0200 Subject: [PATCH] Port from snaporca ab22482e40: say why a sheet was skipped, and stop calling an encrypted PDF an engine failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Over the whole 977-sheet corpus: 767 graded, 767 fully clean, 0 failures. The 210 skips are sheets whose part outline is not a closed stroked path at all (largest loop 5 to 132 mm2, measured), and one of them — MPD133 — is password-protected, which was being reported as an engine ERROR. Both now say what they are. snaporca-j6sr --- scripts/ladder-corpus.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/scripts/ladder-corpus.py b/scripts/ladder-corpus.py index 725f37a95c..e39b77103e 100644 --- a/scripts/ladder-corpus.py +++ b/scripts/ladder-corpus.py @@ -245,7 +245,12 @@ def grade(pdf, name, report): voids = [r for r in loops[2:] if shoelace(r) > 1.0 and point_in(r[0], outer)] if shoelace(outer) < 100.0: - report(name, "SKIP", "outline too small to grade") + # Not a defect and not a near miss: on these sheets the part outline is not a closed + # stroked path at all, so the only loops extraction recovers are glyph counters and + # arrowheads. Measured on MPD12/30/31/60: the LARGEST loop on the sheet is 5 to 132 mm2. + # Say the number, so nobody has to re-measure to know which kind of skip this is. + report(name, "SKIP", f"no part outline on this sheet — largest loop is only " + f"{shoelace(outer):.1f} mm2") return None # Feed the drawing's own geometry to the engine, as lines only. @@ -392,6 +397,12 @@ def grade_scale(pdf, name, report, budget): return ok +def _pdf_error(path): + """What poppler says about a file it refused, so a refusal can be classified.""" + r = subprocess.run(["pdfinfo", path], capture_output=True, text=True) + return (r.stderr or "") + (r.stdout or "") + + def main(): ap = argparse.ArgumentParser() ap.add_argument("--corpus", default=os.path.expanduser("~/studycadcam")) @@ -454,7 +465,13 @@ def main(): if r is not None: results.append((name, r)) except Exception as e: # noqa: BLE001 - report(name, "ERROR", str(e)[:120], False) + # An unreadable SOURCE file is not a grading failure. MPD133 of this corpus is + # password-protected, and pdftocairo says so on stderr while exiting non-zero; + # reporting that as ERROR made one encrypted sheet look like an engine defect. + if "password" in _pdf_error(f).lower(): + report(name, "SKIP", "the PDF is password-protected — nothing to extract") + else: + report(name, "ERROR", str(e)[:120], False) graded = len(results) passed = sum(1 for _, r in results if r)