openspoolman/tools_3mf.py

71 lines
2.3 KiB
Python
Raw Normal View History

import requests
import zipfile
import tempfile
import xml.etree.ElementTree as ET
def getFilamentsUsageFrom3mf(url):
"""
Download a 3MF file from a URL, unzip it, and parse filament usage.
Args:
url (str): URL to the 3MF file.
Returns:
list[dict]: List of dictionaries with `tray_info_idx` and `used_g`.
"""
try:
# Create a temporary file
with tempfile.NamedTemporaryFile(delete=False, suffix=".3mf") as temp_file:
temp_file_name = temp_file.name
print("Downloading 3MF file...")
# Download the file and save it to the temporary file
response = requests.get(url)
response.raise_for_status()
temp_file.write(response.content)
print(f"3MF file downloaded and saved as {temp_file_name}.")
# Unzip the 3MF file
with zipfile.ZipFile(temp_file_name, 'r') as z:
# Check for the Metadata/slice_info.config file
slice_info_path = "Metadata/slice_info.config"
if slice_info_path in z.namelist():
with z.open(slice_info_path) as slice_info_file:
# Parse the XML content of the file
tree = ET.parse(slice_info_file)
root = tree.getroot()
# Extract id and used_g from each filament
result = []
for plate in root.findall(".//plate"):
for filament in plate.findall(".//filament"):
used_g = filament.attrib.get("used_g")
if used_g:
result.append(used_g)
else:
result.append('0.0')
return result
else:
print(f"File '{slice_info_path}' not found in the archive.")
return []
except requests.exceptions.RequestException as e:
print(f"Error downloading file: {e}")
return []
except zipfile.BadZipFile:
print("The downloaded file is not a valid 3MF archive.")
return []
except ET.ParseError:
print("Error parsing the XML file.")
return []
except Exception as e:
print(f"An unexpected error occurred: {e}")
return []
finally:
# Cleanup: Delete the temporary file
try:
import os
if os.path.exists(temp_file_name):
os.remove(temp_file_name)
except Exception as cleanup_error:
print(f"Error during cleanup: {cleanup_error}")