Browse Source

Fix finish photo not captured when archive has no source 3MF (#484)

When the 3MF source file wasn't downloaded from the printer (e.g. FTP
failure on P2S), archive.file_path was null. The finish photo capture
silently skipped because it derived the save directory from file_path.

Now falls back to archive/{id}/ directory and logs a warning.
maziggy 3 months ago
parent
commit
7232ddb5a6
2 changed files with 7 additions and 2 deletions
  1. 1 0
      CHANGELOG.md
  2. 6 2
      backend/app/main.py

+ 1 - 0
CHANGELOG.md

@@ -7,6 +7,7 @@ All notable changes to Bambuddy will be documented in this file.
 ### Fixed
 - **Developer Mode Detection Always Reports Null** — The MQTT `fun` field is an integer in the JSON payload, but the parser used `int(value, 16)` which requires a string argument. This raised `TypeError` on every message, silently caught by the exception handler, so `developer_mode` was never set. Now handles both integer and hex string formats.
 - **File Manager Rename Doesn't Update Displayed Name** ([#460](https://github.com/maziggy/bambuddy/issues/460)) — Renaming a file in the File Manager updated the `filename` field but not `file_metadata.print_name`, which the UI uses as the primary display name. Since `print_name` is extracted from inside the 3MF at upload time, it always took precedence over the renamed `filename`. The rename endpoint now also updates `print_name` in the file metadata when present.
+- **Finish Photo Not Captured When Archive Has No Source 3MF** ([#484](https://github.com/maziggy/bambuddy/issues/484)) — When a print completed but the 3MF source file wasn't downloaded from the printer (e.g. FTP download failure), the archive's `file_path` was null. The finish photo capture silently skipped because it derived the save directory from `file_path`. Now falls back to `archive/{id}/` so the photo is captured regardless.
 
 ## [0.2.1b2] - 2026-02-21
 

+ 6 - 2
backend/app/main.py

@@ -2499,12 +2499,16 @@ async def on_print_complete(printer_id: int, data: dict):
                         result = await db.execute(select(PrintArchive).where(PrintArchive.id == archive_id))
                         archive = result.scalar_one_or_none()
 
-                        if archive and archive.file_path:
+                        if archive:
                             import uuid
                             from datetime import datetime
                             from pathlib import Path
 
-                            archive_dir = app_settings.base_dir / Path(archive.file_path).parent
+                            if archive.file_path:
+                                archive_dir = app_settings.base_dir / Path(archive.file_path).parent
+                            else:
+                                logger.warning("[PHOTO-BG] Archive %s has no file_path, using fallback dir", archive_id)
+                                archive_dir = app_settings.archive_dir / str(archive.id)
                             photo_filename = None
 
                             # Check for external camera first