Dual-nozzle H2D/H2D Pro: filament matching now respects nozzle assignments
from the 3MF file. Each AMS unit feeds a specific nozzle (L/R), and the
scheduler/frontend constrain matching to only trays on the correct nozzle.
Falls back to unfiltered matching when no trays exist on the target nozzle.
L/R badges shown in the filament mapping UI. Translated in en/de/ja/it.
Fix AMS slot config overwritten on startup: on_ams_change unconditionally
unlinked BL spool assignments on every MQTT pushall, then re-assigned them
sending ams_filament_setting without setting_id — clearing the printer's
filament preset. Now compares spool RFID identifiers before unlinking.
Fix BL spool detection false positives: removed tray_info_idx from detection
logic in both backend is_bambu_lab_spool() and frontend isBambuLabSpool().
Third-party spools using Bambu generic presets had GF-prefixed tray_info_idx
values, causing misidentification. Now uses only tray_uuid and tag_uid.
SQLite WAL mode with 5s busy timeout reduces "database is locked" errors.
The CodeQL cleanup in "Housekeeping" (2b11efd) bulk-narrowed except
clauses across 50+ files, breaking FTP uploads on ALL printer models.
ftplib.error_perm (550 errors) is not a subclass of ftplib.error_reply,
so diagnose_storage() CWD failures escaped the handler and prevented
STOR from ever executing — causing 100% upload failure and HTTP 500s
on /api/v1/archives/{id}/reprint and /api/v1/library/files/{id}/print.
FTP fixes:
- Remove diagnose_storage() from upload hot path
- Change all except (OSError, ftplib.error_reply) to
except (OSError, ftplib.Error) across bambu_ftp.py
Exception handling reverts (9 files):
- Revert narrowed except clauses back to except Exception in route
handlers and service code where broad catches are intentional
defensive programming (archive parsing, HTTP clients, 3MF/ZIP
processing, Home Assistant, firmware checks)
- Keep narrow exceptions only where safe (single-op blocks like
int(), file.unlink(), socket.close())
- Remove unused XMLParseError imports from archive.py, threemf_tools.py
Closes#287
These modules were already imported at the top of each file.
Removes re-imports of re, json, zipfile, and logging from
inside functions in archive.py, library.py, main.py,
printers.py, support.py, and test_library_api.py.
Resolves all 30 CodeQL py/repeated-import findings.
Security scan (Bandit) identified vulnerable XML parsing in 3MF file
processing. The standard xml.etree.ElementTree is vulnerable to XXE
(XML External Entity) attacks.
Changes:
- Add defusedxml>=0.7.0 to requirements.txt
- Replace all xml.etree.ElementTree imports with defusedxml.ElementTree
in production code (6 files)
Affected files:
- backend/app/services/archive.py
- backend/app/services/print_scheduler.py
- backend/app/api/routes/print_queue.py
- backend/app/api/routes/library.py
- backend/app/api/routes/printers.py
- backend/app/api/routes/archives.py
Test files intentionally left unchanged (test XML is trusted).
When multiple AMS trays have the same filament type and color, Bambuddy
now uses the tray_info_idx attribute from the 3MF file to identify the
exact spool selected during slicing. This ensures the correct tray is
used rather than just picking the first match.
Matching priority: tray_info_idx > exact color > similar color > type-only
Closes#245
- Added query to fetch library file details in PrintModal
- Updated backend FileResponse schema to include metadata fields (print_name, print_time_seconds, filament_used_grams, sliced_for_model)
- Updated backend get_file endpoint to extract and return metadata fields
- Updated frontend LibraryFile interface to include metadata fields
- Now slicedForModel is properly extracted from both archives and library files
Co-authored-by: cadtoolbox <12723486+cadtoolbox@users.noreply.github.com>
The File Manager (Library) backend had no permission enforcement - endpoints were returning data to any authenticated user regardless of their group permissions.
Closes#224
The fix for A1/P1S FTP uploads (commit 82a6025) was accidentally broken in
commit 9969005 which removed the skip_session_reuse parameter from the
ImplicitFTP_TLS constructor. This caused P2S (and other models in
SKIP_SESSION_REUSE_MODELS) to still use SSL on the data channel, resulting
in "426 Failure reading network stream" errors.
The fix was implemented in commit b96ecfa on test/issue_174 branch but
never merged to main. This cherry-picks that fix.
Also includes:
- Storage diagnostics for debugging upload issues
- Better FTP error logging with specific error codes (553, 550, 552)
- Improved error messages in print scheduler
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Backend:
- Split update/delete permissions into *_own and *_all variants:
- queue:update_own/all, queue:delete_own/all
- archives:update_own/all, archives:delete_own/all, archives:reprint_own/all
- library:update_own/all, library:delete_own/all
- Add require_ownership_permission dependency factory in auth.py
- Enforce ownership checks on all relevant API endpoints:
- archives.py: PATCH, DELETE, POST /reprint
- print_queue.py: PATCH, DELETE, POST /cancel, PATCH /bulk
- library.py: PUT /files, DELETE /files, POST /bulk-delete, DELETE /folders
- Add user items count endpoint: GET /users/{id}/items-count
- Add delete_items parameter to DELETE /users/{id}
- Explicitly set created_by_id to NULL on user deletion for DB portability
- Add permission migration for existing groups in database.py
- Add require_permission_if_auth_enabled for folder delete
Frontend:
- Add canModify helper to AuthContext for ownership-based checks
- Update ArchivesPage: use canModify for edit/delete/reprint buttons
- Update QueuePage: use canModify for edit/delete/cancel buttons
- Update FileManagerPage: use canModify for edit/delete buttons
- Update SettingsPage: add user deletion modal with item handling options
- Update StatsPage: use archives:update_all for recalculate costs
- Update Permission type with new ownership permissions
- Add getUserItemsCount and update deleteUser API methods
Tests:
- Add test_ownership_permissions.py with 28 comprehensive tests
- Test admin *_all permissions, operator *_own permissions
- Test bulk operations skip non-owned items
- Test auth disabled allows all operations
- Test user deletion with/without items
Closes#205
Track and display who performs key actions in Bambuddy:
- Archives: who uploaded each archive file
- Library: who uploaded each file in File Manager
- Queue: who added each print job to the queue
- Printers: who started the current print (reprint tracking)
Backend changes:
- Add created_by_id column to print_archives, library_files, print_queue tables
- Add database migrations for new columns (auto-run on startup)
- Update archive, library, and queue routes to capture current user
- Add current-print-user endpoint for printer reprint tracking
- Track reprint user in PrinterManager in-memory state
- Fix file uploads not sending auth headers (FormData requires explicit headers)
Frontend changes:
- Display username on archive cards, library files, queue items
- Show "Started by" on printer cards during active prints
- Add auth headers to all 12 FormData upload functions
- Update TypeScript types for user tracking fields
Tests:
- Add unit tests for PrinterManager user tracking methods (7 tests)
- Add integration tests for current-print-user endpoint (3 tests)
- Add integration tests for library file user tracking (3 tests)
Works when authentication is enabled; gracefully hidden when disabled.
Closes#206
Library files now store paths relative to base_dir instead of absolute
paths. This ensures thumbnails and files work correctly after restoring
a backup on a different system or with a different data directory.
Changes:
- Add to_relative_path() and to_absolute_path() helper functions
- Update file upload, ZIP extraction, and STL thumbnail generation
to store relative paths
- Update download, thumbnail, gcode, and delete endpoints to resolve
relative paths when accessing files
- Add database migration to convert existing absolute paths to relative
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The code is ready for testing. After pushing to the remote host:
1. The migration will run automatically on startup, converting any existing absolute paths
2. New files will be stored with relative paths
3. Thumbnails should display correctly after backup/restore
- Implemented batch STL thumbnail generation API endpoint.
- Added Pydantic schemas for batch thumbnail requests and responses.
- Created service for generating thumbnails from STL files using trimesh and matplotlib.
- Updated file upload and ZIP extraction endpoints to include thumbnail generation option.
- Enhanced frontend to support STL thumbnail generation during file uploads and ZIP extractions.
- Added integration and unit tests for the new thumbnail generation features.
- Updated requirements to include necessary libraries for STL processing.
- Add trimesh and matplotlib dependencies for software-based 3D rendering
- Create stl_thumbnail service with generate_stl_thumbnail() function
- Handle mesh simplification for large files (>100k vertices)
- Auto-generate thumbnails during STL file upload and ZIP extraction
- Add POST /library/files/{id}/regenerate-thumbnail endpoint
- Add POST /library/generate-stl-thumbnails batch endpoint
- Add "Generate Thumbnails" button to file manager toolbar
- Add "Regenerate Thumbnail" option to file context menu
- Add unit and integration tests for new functionality
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
File Manager improvements (#121):
- New option to create folder from ZIP filename (e.g., MyProject.zip → MyProject/)
- Upload modal now accepts all file types, not just ZIP files
- Updated drop zone text to clarify all files are supported
- Both options can be combined: create folder + preserve internal structure
Camera zoom/pan improvements (#132):
- Pan range now based on actual container size instead of fixed pixels
- Users can pan across the entire zoomed image at any zoom level
- Added pinch-to-zoom gesture for mobile (two fingers)
- Added single finger pan when zoomed in on touch devices
- Pan while pinching to reposition zoom focus
- Both EmbeddedCameraViewer and standalone CameraPage updated
Features:
- ZIP file support in File Manager (Issue #121): Upload ZIP files to
automatically extract contents with option to preserve folder structure
- Delete operation loading indicator: Shows progress during folder/file
deletion operations
Fixed:
- Print time stats using actual elapsed time instead of slicer estimates
(Issue #137)
- Skip objects modal overflow with scrollable list for many objects
(Issue #134)
Removed:
- Duplicate badge feature from File Manager (per user request)
Tests:
- Added ZIP extraction backend tests (5 tests)
- Added ConfirmModal loading state frontend tests (5 tests)
- New RenameModal component with validation
- Backend endpoint supports filename updates (rejects path separators)
- Context menu "Rename" option in grid and list views
- Inline rename button in list view actions
- Add Print button to multi-selection toolbar:
- Appears when exactly one sliced file is selected
- Opens full PrintModal with plate selection and options
- Add to Queue button now uses Clock icon for clarity
- Improve mobile/PWA accessibility:
- Three-dot menu button always visible on mobile (md:opacity-0)
- Selection checkbox always visible on touch devices
- Better experience for PWA users on tablets and phones
Closes#94
- Print from File Manager with plate selection, AMS mapping, and print options. Closes#94
- Add to queue without creating archive (reduces clutter)
- Queue displays library file name, thumbnail, and print time
Fixes:
Queue items from File Manager now reference library files directly instead of
creating archives upfront. Archives are created automatically when prints start.