Add print time extraction from 3MF files to print queue response

This commit is contained in:
MisterBeardy
2026-02-05 11:02:03 -05:00
parent 8b3ea0602c
commit 671685a4e2
+65
View File
@@ -98,6 +98,58 @@ def _extract_filament_types_from_3mf(file_path: Path, plate_id: int | None = Non
return sorted(types)
def _extract_print_time_from_3mf(file_path: Path, plate_id: int | None = None) -> int | None:
"""Extract print time (prediction) from a 3MF file.
Args:
file_path: Path to the 3MF file
plate_id: Optional plate index to filter for (for multi-plate files)
Returns:
Print time in seconds, or None if not found
"""
try:
with zipfile.ZipFile(file_path, "r") as zf:
if "Metadata/slice_info.config" not in zf.namelist():
return None
content = zf.read("Metadata/slice_info.config").decode()
root = ET.fromstring(content)
if plate_id is not None:
for plate_elem in root.findall(".//plate"):
plate_index = None
for meta in plate_elem.findall("metadata"):
if meta.get("key") == "index":
try:
plate_index = int(meta.get("value", "0"))
except ValueError:
pass
break
if plate_index == plate_id:
for meta in plate_elem.findall("metadata"):
if meta.get("key") == "prediction":
try:
return int(meta.get("value", "0"))
except ValueError:
return None
break
else:
plate_elem = root.find(".//plate")
if plate_elem is not None:
for meta in plate_elem.findall("metadata"):
if meta.get("key") == "prediction":
try:
return int(meta.get("value", "0"))
except ValueError:
return None
except Exception as e:
logger.warning(f"Failed to extract print time from {file_path}: {e}")
return None
def _enrich_response(item: PrintQueueItem) -> PrintQueueItemResponse:
"""Add nested archive/printer/library_file info to response."""
# Parse ams_mapping from JSON string BEFORE model_validate
@@ -153,6 +205,12 @@ def _enrich_response(item: PrintQueueItem) -> PrintQueueItemResponse:
response.archive_name = item.archive.print_name or item.archive.filename
response.archive_thumbnail = item.archive.thumbnail_path
response.print_time_seconds = item.archive.print_time_seconds
if item.plate_id:
archive_path = settings.base_dir / item.archive.file_path
if archive_path.exists():
plate_time = _extract_print_time_from_3mf(archive_path, item.plate_id)
if plate_time is not None:
response.print_time_seconds = plate_time
if item.library_file:
response.library_file_name = (
item.library_file.file_metadata.get("print_name") if item.library_file.file_metadata else None
@@ -163,6 +221,13 @@ def _enrich_response(item: PrintQueueItem) -> PrintQueueItemResponse:
# Get print time from library file metadata if no archive
if not item.archive and item.library_file.file_metadata:
response.print_time_seconds = item.library_file.file_metadata.get("print_time_seconds")
if item.plate_id:
lib_path = Path(item.library_file.file_path)
library_file_path = lib_path if lib_path.is_absolute() else settings.base_dir / item.library_file.file_path
if library_file_path.exists():
plate_time = _extract_print_time_from_3mf(library_file_path, item.plate_id)
if plate_time is not None:
response.print_time_seconds = plate_time
if item.printer:
response.printer_name = item.printer.name
return response