|
@@ -488,24 +488,37 @@ async def get_printer_cover(
|
|
|
if cache_key in _cover_cache[printer_id]:
|
|
if cache_key in _cover_cache[printer_id]:
|
|
|
return Response(content=_cover_cache[printer_id][cache_key], media_type="image/png")
|
|
return Response(content=_cover_cache[printer_id][cache_key], media_type="image/png")
|
|
|
|
|
|
|
|
- # Build 3MF filename from subtask_name
|
|
|
|
|
- # Bambu printers store files as "name.gcode.3mf"
|
|
|
|
|
- filename = subtask_name
|
|
|
|
|
- if not filename.endswith(".3mf"):
|
|
|
|
|
- filename = filename + ".gcode.3mf"
|
|
|
|
|
-
|
|
|
|
|
- # Try to download the 3MF file from printer
|
|
|
|
|
- temp_path = settings.archive_dir / "temp" / f"cover_{printer_id}_{filename}"
|
|
|
|
|
- temp_path.parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
|
|
|
+ # Build possible 3MF filenames from subtask_name
|
|
|
|
|
+ # Bambu printers may store files as "name.gcode.3mf" (sliced via Bambu Studio)
|
|
|
|
|
+ # or just "name.3mf" (uploaded directly)
|
|
|
|
|
+ possible_filenames = []
|
|
|
|
|
+ if subtask_name.endswith(".3mf"):
|
|
|
|
|
+ possible_filenames.append(subtask_name)
|
|
|
|
|
+ else:
|
|
|
|
|
+ # Try both naming patterns
|
|
|
|
|
+ possible_filenames.append(f"{subtask_name}.gcode.3mf")
|
|
|
|
|
+ possible_filenames.append(f"{subtask_name}.3mf")
|
|
|
|
|
+
|
|
|
|
|
+ # Build list of all remote paths to try
|
|
|
|
|
+ remote_paths = []
|
|
|
|
|
+ for filename in possible_filenames:
|
|
|
|
|
+ remote_paths.extend(
|
|
|
|
|
+ [
|
|
|
|
|
+ f"/{filename}", # Root directory (most common)
|
|
|
|
|
+ f"/cache/{filename}",
|
|
|
|
|
+ f"/model/{filename}",
|
|
|
|
|
+ f"/data/{filename}",
|
|
|
|
|
+ ]
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
- remote_paths = [
|
|
|
|
|
- f"/{filename}", # Root directory (most common)
|
|
|
|
|
- f"/cache/{filename}",
|
|
|
|
|
- f"/model/{filename}",
|
|
|
|
|
- f"/data/{filename}",
|
|
|
|
|
- ]
|
|
|
|
|
|
|
+ # Use first filename for temp path (will be reused)
|
|
|
|
|
+ temp_filename = possible_filenames[0]
|
|
|
|
|
+ temp_path = settings.archive_dir / "temp" / f"cover_{printer_id}_{temp_filename}"
|
|
|
|
|
+ temp_path.parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
|
|
|
|
- logger.info(f"Trying to download cover for '{filename}' from {printer.ip_address}")
|
|
|
|
|
|
|
+ logger.info(
|
|
|
|
|
+ f"Trying to download cover for '{subtask_name}' from {printer.ip_address} (trying {len(remote_paths)} paths)"
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
# Retry logic for transient FTP failures
|
|
# Retry logic for transient FTP failures
|
|
|
max_retries = 2
|
|
max_retries = 2
|
|
@@ -535,7 +548,8 @@ async def get_printer_cover(
|
|
|
|
|
|
|
|
if not downloaded:
|
|
if not downloaded:
|
|
|
raise HTTPException(
|
|
raise HTTPException(
|
|
|
- 404, f"Could not download 3MF file '{filename}' from printer {printer.ip_address}. Tried: {remote_paths}"
|
|
|
|
|
|
|
+ 404,
|
|
|
|
|
+ f"Could not download 3MF file for '{subtask_name}' from printer {printer.ip_address}. Tried: {possible_filenames}",
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
# Verify file actually exists and has content
|
|
# Verify file actually exists and has content
|
|
@@ -547,7 +561,7 @@ async def get_printer_cover(
|
|
|
|
|
|
|
|
if file_size == 0:
|
|
if file_size == 0:
|
|
|
temp_path.unlink()
|
|
temp_path.unlink()
|
|
|
- raise HTTPException(500, f"Downloaded file is empty: {filename}")
|
|
|
|
|
|
|
+ raise HTTPException(500, f"Downloaded file is empty for '{subtask_name}'")
|
|
|
|
|
|
|
|
try:
|
|
try:
|
|
|
# Extract thumbnail from 3MF (which is a ZIP file)
|
|
# Extract thumbnail from 3MF (which is a ZIP file)
|
|
@@ -1207,16 +1221,22 @@ async def get_printable_objects(
|
|
|
from backend.app.services.archive import extract_printable_objects_from_3mf
|
|
from backend.app.services.archive import extract_printable_objects_from_3mf
|
|
|
from backend.app.services.bambu_ftp import download_file_try_paths_async
|
|
from backend.app.services.bambu_ftp import download_file_try_paths_async
|
|
|
|
|
|
|
|
- # Build 3MF filename
|
|
|
|
|
- filename = subtask_name
|
|
|
|
|
- if not filename.endswith(".3mf"):
|
|
|
|
|
- filename = filename + ".gcode.3mf"
|
|
|
|
|
|
|
+ # Build possible 3MF filenames (try both .gcode.3mf and .3mf)
|
|
|
|
|
+ possible_filenames = []
|
|
|
|
|
+ if subtask_name.endswith(".3mf"):
|
|
|
|
|
+ possible_filenames.append(subtask_name)
|
|
|
|
|
+ else:
|
|
|
|
|
+ possible_filenames.append(f"{subtask_name}.gcode.3mf")
|
|
|
|
|
+ possible_filenames.append(f"{subtask_name}.3mf")
|
|
|
|
|
|
|
|
# Download 3MF from printer
|
|
# Download 3MF from printer
|
|
|
- temp_path = settings.archive_dir / "temp" / f"objects_{printer_id}_{filename}"
|
|
|
|
|
|
|
+ temp_path = settings.archive_dir / "temp" / f"objects_{printer_id}_{possible_filenames[0]}"
|
|
|
temp_path.parent.mkdir(parents=True, exist_ok=True)
|
|
temp_path.parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
|
|
|
|
- remote_paths = [f"/{filename}", f"/cache/{filename}", f"/model/{filename}"]
|
|
|
|
|
|
|
+ # Build list of all remote paths to try
|
|
|
|
|
+ remote_paths = []
|
|
|
|
|
+ for filename in possible_filenames:
|
|
|
|
|
+ remote_paths.extend([f"/{filename}", f"/cache/{filename}", f"/model/{filename}"])
|
|
|
|
|
|
|
|
try:
|
|
try:
|
|
|
downloaded = await download_file_try_paths_async(
|
|
downloaded = await download_file_try_paths_async(
|