From 02c91c0c58efe6213392735df89a271386459d40 Mon Sep 17 00:00:00 2001 From: DLANSAMA Date: Wed, 26 Aug 2026 09:06:02 -0400 Subject: [PATCH 1/2] perf: single-pass 3MF scan and early-exit gcode header parse Keep the 10 MB slice_info cap from #128. Drop the .jules/bolt.md file from #129. --- bambu_cli/slicer/estimate.py | 39 +++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/bambu_cli/slicer/estimate.py b/bambu_cli/slicer/estimate.py index 8965fee..48e5c2d 100644 --- a/bambu_cli/slicer/estimate.py +++ b/bambu_cli/slicer/estimate.py @@ -89,6 +89,8 @@ def _parse_gcode_header(gcode_bytes: bytes) -> tuple[int | None, float | None]: grams = v except (ValueError, TypeError): pass + if seconds is not None and grams is not None: + break return seconds, grams @@ -106,12 +108,18 @@ def read_3mf_estimate(path: str) -> Estimate: # Primary: Metadata/slice_info.config slice_info_name: str | None = None + gcode_members: list[str] = [] + for n in names: - normalised = n.replace("\\", "/") - parts = normalised.split("/") - if len(parts) == 2 and parts[0] == "Metadata" and parts[1] == "slice_info.config": + norm = n.replace("\\", "/") + if norm == "Metadata/slice_info.config": slice_info_name = n - break + elif ( + norm.startswith("Metadata/") + and norm.endswith(".gcode") + and norm.count("/") == 1 + ): + gcode_members.append(n) if slice_info_name is not None: info = zf.getinfo(slice_info_name) @@ -131,20 +139,15 @@ def read_3mf_estimate(path: str) -> Estimate: # Fallback: gcode members under Metadata/, in plate order. Keep # trying later plates if an earlier one carries no usable header. - gcode_members = sorted( - n - for n in names - if len(n.replace("\\", "/").split("/")) == 2 - and n.replace("\\", "/").split("/")[0] == "Metadata" - and n.replace("\\", "/").split("/")[1].endswith(".gcode") - ) - for n in gcode_members: - # Read only the header window; a real plate gcode can be tens of MB. - with zf.open(n) as fh: - gcode_bytes = fh.read(GCODE_READ_BYTES) - seconds, grams = _parse_gcode_header(gcode_bytes) - if seconds is not None or grams is not None: - return Estimate(seconds, grams) + if gcode_members: + gcode_members.sort() + for n in gcode_members: + # Read only the header window; a real plate gcode can be tens of MB. + with zf.open(n) as fh: + gcode_bytes = fh.read(GCODE_READ_BYTES) + seconds, grams = _parse_gcode_header(gcode_bytes) + if seconds is not None or grams is not None: + return Estimate(seconds, grams) except Exception: # noqa: BLE001 — never raise, degrade gracefully pass From ef55ea96aac9cd793583d33a209430f5cf61f416 Mon Sep 17 00:00:00 2001 From: DLANSAMA Date: Wed, 26 Aug 2026 09:07:23 -0400 Subject: [PATCH 2/2] style: keep the gcode-member match on one line for ruff format --- bambu_cli/slicer/estimate.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/bambu_cli/slicer/estimate.py b/bambu_cli/slicer/estimate.py index 48e5c2d..3db9947 100644 --- a/bambu_cli/slicer/estimate.py +++ b/bambu_cli/slicer/estimate.py @@ -114,11 +114,7 @@ def read_3mf_estimate(path: str) -> Estimate: norm = n.replace("\\", "/") if norm == "Metadata/slice_info.config": slice_info_name = n - elif ( - norm.startswith("Metadata/") - and norm.endswith(".gcode") - and norm.count("/") == 1 - ): + elif norm.startswith("Metadata/") and norm.endswith(".gcode") and norm.count("/") == 1: gcode_members.append(n) if slice_info_name is not None: