- Add "Schedule" button next to "Reprint" on archive cards for quick
access to print queue functionality
- Button respects queue:create permission for restricted users
- Previously only accessible via context menu (right-click)
Closes#208
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
Replace the complex JSON-based backup system (~2000 lines) with a simple
approach that copies the SQLite database and all data directories into a
single ZIP file.
Backend changes:
- Add close_all_connections() and reinitialize_database() helpers to database.py
- New GET /backup endpoint: creates complete ZIP with bambuddy.db and all
data directories (archive, virtual_printer, plate_calibration, icons, projects)
- New POST /restore endpoint: extracts ZIP, replaces database and directories,
requires restart after restore
- Move legacy endpoints to /backup-legacy and /restore-legacy for transition
Frontend changes:
- Simplify api.exportBackup() - no longer takes category parameters
- Simplify api.importBackup() - no longer takes overwrite parameter
- Remove BackupModal and RestoreModal components from GitHubBackupSettings
- Add simple Download/Restore buttons with inline logic
- Add blocking modal overlay during backup/restore operations
- Add beforeunload handler to prevent accidental navigation
- Show operation status messages during backup/restore
Benefits:
- ~100 lines vs ~2000 lines of backup/restore code
- Complete by definition - SQLite database contains ALL data
- No code changes needed when schema changes
- No ID remapping required - IDs stay the same
- Faster - file copy vs querying all tables
- Add ?fps=N parameter to control camera frame rate (1-30, default 15)
- Add ?camera=false parameter for status-only overlay without camera feed
- Increase default camera FPS from 10 to 15 across all camera views
- Add comprehensive tests for new overlay parameters
Resolves user request on Issue #164 for higher FPS and status-only option.
Add --no-cache and --pull flags to ensure clean builds every time.
Remove registry cache arguments that could cause stale layers.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
These columns were added in 0.1.6 beta but migrations were missing:
- nozzle_count: Integer DEFAULT 1 (for dual-extruder detection)
- print_hours_offset: Float DEFAULT 0.0 (baseline hours adjustment)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add migration for target_model, required_filament_types, and waiting_reason
columns in print_queue table. These columns were added to the model for the
model-based queue assignment feature but the migration was missing.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add _sanitize_camera_url() that returns reconstructed URL from
validated and parsed components, breaking CodeQL's taint tracking
- Update _capture_mjpeg_frame, _capture_snapshot, _stream_mjpeg to
use sanitized URLs instead of original user input
- Keep _validate_camera_url as legacy wrapper for backwards compat
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Block access to cloud metadata services and dangerous destinations:
- AWS/GCP/Azure metadata endpoint (169.254.169.254)
- GCP internal metadata hostnames
- localhost and loopback addresses
- All link-local addresses (169.254.x.x)
Local network IPs (192.168.x.x, 10.x.x.x) are still allowed since
cameras are typically on the same LAN as the server.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Path traversal: Convert device number to integer to break taint chain,
use strict /dev/videoN validation with range limit
- SSRF: Add documentation explaining intentional SSRF for user-configured
external camera URLs, add lgtm suppression comments
- Info exposure: Don't expose exception messages in plate calibration
errors, only expose error type name
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Resolved conflicts:
- CHANGELOG.md: Kept both HA Script Support and STL Thumbnail features
- database.py: Kept both migration sets (UNIQUE constraint removal + queue columns)
- SmartPlugCard.tsx: Merged script UI support with base styling
- static/: Rebuilt frontend with merged changes
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The print scheduler was hardcoded to use Tasmota service when powering
on printers for queued prints. Home Assistant plugs were not checked,
causing "Tasmota device not found" errors.
Changes:
- Make get_service_for_plug() public in smart_plug_manager
- Update print_scheduler to use smart_plug_manager.get_service_for_plug()
instead of tasmota_service directly
- Fixes both _power_on_and_wait() and _power_off_if_needed() methods
Closes#200
Implement a full permissions system replacing simple admin/user roles:
Backend:
- Add Group model with many-to-many user relationship
- Add 50+ granular permissions (resource:action pattern)
- Create default groups: Administrators, Operators, Viewers
- Add permission-checking dependencies for route protection
- Add groups API endpoints (CRUD, user assignment)
- Add change password endpoint for users
- Update backup/restore to include groups
- Migrate existing users to groups on startup
Frontend:
- Add GroupsPage for managing groups and permissions
- Add permission helpers to AuthContext (hasPermission, hasAnyPermission)
- Add PermissionRoute component for protected routes
- Disable buttons/features based on permissions (with tooltips)
- Add change password modal in sidebar for all users
- Add forgot password info modal on login page
- Show user groups in UsersPage with group assignment
Testing:
- Add integration tests for groups API
- Add tests for user-group assignments
- Add tests for change password endpoint
- Seed default groups in test fixtures
Closes#28#161
When using "Any [Model]" queue assignment, the scheduler now computes
AMS mapping after a printer is assigned, instead of requiring it upfront.
This fixes H2D Pro (and other printers) failing at filament loading when
queued via model-based assignment. The issue was that no AMS mapping was
sent to the printer because the specific printer wasn't known at queue time.
Closes#192
Implement centralized tag management for print archives:
- GET /archives/tags endpoint to list all tags with usage counts
- PUT /archives/tags/{name} endpoint to rename tags across archives
- DELETE /archives/tags/{name} endpoint to delete tags from archives
- TagManagementModal component with search, sort, rename, and delete
- Gear icon button next to tag filter dropdown on Archives page
- Fix tag autocompletion in EditArchiveModal using dedicated getTags API
Closes#183
- Path is now optional for power, energy, and state topics
- When path is empty, raw MQTT payload value is used directly
- Energy and state topics no longer fall back to power topic
- Added helper text in UI explaining path is optional
- Fixes energy monitoring not working with separate topics
Closes 173
- Add H2D Pro option to printer model dropdowns (add/edit modals)
- Support both O1E and O2D internal codes for H2D Pro compatibility
- Add O2D to RTSP-capable and chamber temp supported models
- Add H2DPRO variant to firmware check mapping
- Add H2D Pro and X1E to bug report issue template
Closes#192
- 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 separate MQTT topics for power, energy, and state monitoring
- mqtt_power_topic, mqtt_power_path, mqtt_power_multiplier
- mqtt_energy_topic, mqtt_energy_path, mqtt_energy_multiplier
- mqtt_state_topic, mqtt_state_path, mqtt_state_on_value
- Support different MQTT topics per data type (e.g., Zigbee2MQTT with
separate power/energy/state topics)
- Individual multipliers for power and energy (e.g., mW→W, Wh→kWh)
- Configurable ON value for state monitoring (e.g., "ON", "true", "1")
- Maintain backward compatibility with legacy mqtt_topic/mqtt_multiplier
- Database migration auto-copies legacy fields to new fields
- Update backup/restore to handle new MQTT fields
- Add backend tests for new MQTT configurations
- Update frontend form with organized Power/Energy/State sections
Closes#173