maziggy
29a81520d9
feat(external-links): an app can show a count on its sidebar link (PUT /external-links/badge with "Send notifications"; Bambuddy Orders shows its To do count), the count disappears when not updated for ten minutes
2026-10-21 17:51:18 +02:00
maziggy
ee2d6e69aa
test: close the coroutines that mocked create_task, wait_for, run_coroutine_threadsafe, spawn_background_task and AsyncMock sessions left unawaited (reported as unraisable warnings in unrelated later tests); the Spoolman recovery tests archive under their own tmp_path instead of the shared archive/
2026-10-21 13:18:54 +02:00
maziggy
9f2d15f70f
Merge perf/farm-fanout: batched printer-card reads (/api/v1/bulk) and server-paged queue history
...
Brought in line with dev: bulk card plugs shaped per caller (REST URLs only for plug editors), bulk archive folders keep to the caller's printers, queue delete and Clear History share dev's end time and grouping refresh, Clear History with an API key keeps to its owner's read-own limit, type fixes, Queue page wiring tests on the paged history, watchdog duration test tolerant of a slow run.
2026-10-21 12:00:02 +02:00
maziggy
833a096da6
test/chore: Bandit findings on PR #3350 marked with reasons (ftplib in tests, migration SQL built from module constants), a misplaced nosec moved to its SQL line; layer timelapse tests use tmp_path instead of a shared /tmp/test_bambuddy
2026-10-21 10:51:10 +02:00
maziggy
2443cea174
feat: USB cameras are picked from a list of detected devices (refresh, not-found marking, manual fallback, Docker hint; device listing off the event loop, /dev/video0-99 only); fix: timelapse editor saves as a background job with progress and cancel (ffmpeg stopped on cancel, no overwrite of a timelapse removed or replaced meanwhile, ffprobe/thumbnail timeouts), and the music volume is applied
2026-10-21 08:56:46 +02:00
maziggy
460c11ca30
chore: remove dead code (audit step 4): unused backend helpers and schema classes, 51 unused API client wrappers, test-only components (BackupModal, RestoreModal, VirtualPrinterSettings, TagDetectedModal, WeightDisplay, useLongPress) and their translations; removed POST /printers/test, the two printer debug routes and the SpoolBuddy update-status channel; legacy virtual printer settings fields removed from the settings API; first-run setup redirect tested
2026-10-21 08:12:17 +02:00
maziggy
770c6bfdf9
fix: firmware upload only for idle printers (dialog, server, re-check after download, queue waits during upload); AMS Reset Slot asks first and is refused while printing; confirms for shopping list Clear all, Git history Clear and SSO unlink (last SSO link of an account without password stays); LDAP/SMTP test use the form's values; emptying a user's email removes it; local backup delete errors are shown; removed the unreachable printer-card Spoolman link/unlink
2026-10-20 21:35:41 +02:00
maziggy
57ed8253ea
Security hardening (maziggy/bambuddy-security #N)
2026-10-20 21:35:14 +02:00
maziggy
6cdf4eb2d0
Tests: 21 in the new test_api_key_own_rows.py. Before the change, 8 of them failed; the rest pass either way because they check refusals and unchanged behaviour. All 7 mutations were killed. In the #3256 tests (test_api_key_queue_acts_as_owner.py), I tightened the bulk assertion and fixed the outdated docstring. The wiki's API keys page had documented the old refusal; that block is rewritten.
2026-10-20 17:08:09 +02:00
maziggy
c6598afec8
test: library/queue probe files get unique names, so parallel workers no longer delete each other's files ("File not found on disk" flake)
2026-10-20 15:35:54 +02:00
maziggy
bd692ac3c7
fix(stats): date filters use calendar days in the browser's time zone instead of UTC days; the Statistics page sends its zone, and the date-filtered archive, statistics and inventory-statistics endpoints take an optional tz (Bambuddy's own TZ when omitted)
2026-10-20 15:20:10 +02:00
maziggy
ac4806f029
fix: a failed first run no longer leaves the archive at its partial cost (built-in inventory); completion stops the start cost estimate before writing the real cost; 2FA/SSO logins report LDAP/OIDC users' auth source; a fault in both print_error and HMS is listed once; a refused H2D load's tray target expires; refused K-profile re-applies are logged; the cloud filament-name map is fetched once per account without holding a DB connection; the library edit route refuses folder changes across the external boundary; a slow slice-progress answer is not reported as an unreachable sidecar
2026-10-20 14:29:08 +02:00
maziggy
27003de368
fix(ftp): a slow folder listing is reported as slow instead of "printer unavailable", and a refresh joins the listing still running instead of starting another; printer file times without a year are dated against UTC, so evening files on hosts behind UTC are not dated a year back
2026-10-20 12:30:27 +02:00
maziggy
ba93abdb9d
fix(spoolbuddy): writing a sticker no longer replaces a Bambu spool's AMS link in Spoolman (refused with the reason on Spoolman before 0.27, and such spools are not listed as untagged); the colour-name warning only appears when the name is really missing; an update stops when installing dependencies times out instead of restarting the daemon and reporting success
2026-10-20 12:04:38 +02:00
maziggy
b9b62f739f
fix(virtual-printer): a late slicer update leaves a queue job the scheduler already claimed alone (its archive still keeps the slicer's AMS pick); a backup restore really stops the virtual printers; the legacy PUT /settings/virtual-printer refuses the settings it no longer applies and is no longer blocked by stale legacy values
2026-10-20 11:39:38 +02:00
maziggy
175758d25a
fix(maintenance): a printer's time offline is not counted as print time; duplicate maintenance items are merged on upgrade and prevented by a unique index; the "performed" response honours the item's own interval type
2026-10-20 10:37:17 +02:00
maziggy
dad7fea37b
fix(notifications): the daily digest goes out during quiet hours and a failed one keeps its events for the next (dropped after two days); a deleted queued archive no longer leaves its creator to be named on a later print; a print closed at reconnect reports no actual duration; the template editor knows the print outcome confirmation and names every event
2026-10-20 10:07:53 +02:00
maziggy
ab5ccc1082
fix(printers): a Stop on an idle printer no longer marks it as user-stopped, so a later failed print is not reported as cancelled; Configure Slot warns when a manual K value could not be sent; Skip Objects and the connection diagnostic release their DB connection before talking to the printer
2026-10-20 09:41:21 +02:00
maziggy
cf0ba31f19
fix(camera): the plate check holds the chamber light like other camera uses, so a live view opened meanwhile keeps it; captures use the live frame of a watched single-client external camera; a reconnecting X1C live view is not ended by the cleanup; camera test/diagnose/plate routes release their DB connection before capturing
2026-10-20 09:16:41 +02:00
maziggy
07d99f3383
fix(queue): GET /queue?status= takes several comma-separated statuses, as documented; remove the archive rescan and project attachment routes that had no UI (cover images keep their storage)
2026-10-20 08:39:48 +02:00
maziggy
51610b9f19
fix(ui): one toast and one close when saving an edited queue item; a failed Unassign on the printer card shows its error; the OBS overlay applies live status updates; bulk upload shows each same-named file its own result; queue timeline and history rows show the queued plate's thumbnail; remove the Inventory "Full" column that nothing fills
2026-10-20 08:15:03 +02:00
maziggy
fcc20cb62c
fix(spoolman): AMS syncs write only the slots whose spool they changed and keep a spool assigned meanwhile; the Sync buttons announce slot changes and update the slot preset; a new Spoolman spool is not seeded from leftover built-in assignments
2026-10-19 21:49:18 +02:00
maziggy
c2bc41a5ef
fix(spoolman): a location delete is refused while Spoolman can't be read; labels print for archived spools; archived spools are not assigned or linked to slots; slot requests outside the AMS ranges are refused before Spoolman is written; bulk counter resets report the spools that failed
2026-10-19 21:22:29 +02:00
maziggy
5afb485c12
fix(inventory): a finished print is not charged a second time by an AMS update while its usage is booked; a completion reported without any file name closes the print session instead of keeping the AMS weight sync off until the next print
2026-10-19 17:36:53 +02:00
maziggy
5b34997dfa
fix(inventory): hand assign, unassign and add-from-slot wait for the printer's slot lock; the AMS remain sync and a print's usage no longer overwrite a weight set by hand or weighed meanwhile; a spool deleted while a print is charged is skipped
2026-10-19 16:10:02 +02:00
maziggy
5edbe7586d
fix(inventory): deleting a spool frees and announces its slots; scale, AMS and manual weight syncs and a finished print's usage refresh other tabs and the printer cards; a deleted printer's spool assignments go with it on SQLite; a pre-assigned slot the printer could not be told about is retried; CSV last_used is stored in UTC
2026-10-19 15:23:41 +02:00
maziggy
a6a4b7648c
fix(queue): an override counts an equivalent filament type in its colour; preheat and keep-warm heat the bed for the plate the job prints; queue colour names and the colour name saved with an override follow the filament's product line
2026-10-19 14:46:26 +02:00
maziggy
2b5cd87c7f
fix(queue): pipeline cancel stops the preheat and frees the budget; an offline stop frees the budget; the SD cleanup at a print's end is bounded to 45 s; a refused print start is logged and retried at once without a reconnect
2026-10-19 13:58:55 +02:00
maziggy
918aa26ffa
fix(queue): models matched without regard to case when adding jobs and in pipelines, stored in the printers' spelling; webhook reprints reuse the slicer's AMS slots; a multi-plate file queued without a plate stores the plate that prints
2026-10-19 13:35:13 +02:00
maziggy
abc971a718
fix(queue): a job edited during a scheduler round waits for the next one instead of being dispatched or mapped from the stale copy; the claim requires the selected printer; bulk edit rechecks the claim; no transaction held through a power-on wait
2026-10-19 13:09:44 +02:00
maziggy
3b7c287f68
fix(queue): a print is charged with its own plate and AMS mapping (a fresh dispatch replaces a never-started one's, a failed send leaves a running plate's, completion drains the mapping)
2026-10-19 12:44:10 +02:00
maziggy
b342124f0e
fix(timelapse): a video goes to the run it belongs to (scan stops on a newer run, claimed videos left out of matching, camera video replaces the printer's without orphaning it); every timelapse change refreshes open Archives pages
2026-10-19 12:11:47 +02:00
maziggy
461c3f045d
fix(archives): a cost set through the API or by Recalculate reaches the run that had it; edits during a reprint leave the previous run alone; archive cost bounded; a 422 survives Infinity/NaN
2026-10-19 11:27:38 +02:00
maziggy
879acdbf1f
fix(archives): archives made without their 3MF store #RRGGBB colours (existing ones repaired at startup), find AMS-HT filament and are priced from their spools once the 3MF arrives; nozzle temperature of the printed plate
2026-10-19 10:58:15 +02:00
maziggy
bb0bf03f68
fix(archives): an offline stop is logged and its real end replaces it; one log entry per run; untracked completions and print start find the print's own archive and 3MF
2026-10-19 10:29:01 +02:00
maziggy
44a5c7a7f5
test(queue,billing,vp): pin dispatch failures, creator scope and busy-printer holds, aborted-print usage fallbacks, end-to-end print completion and billing, VP MQTT pre-login and rate-limit guards; test schema loads every model
2026-10-19 09:50:39 +02:00
maziggy
69c2ff1b44
test(auth): pin disabled keys, ended sessions on every gate, own-only key owners, long-lived token scope, model targets of limited keys; stricter route-auth backstop
2026-10-19 09:22:10 +02:00
maziggy
c9c13b6440
fix(archives): the A1/A1 Mini/P1/A2L built-in calibration is not archived as a print
2026-10-18 16:41:47 +02:00
maziggy
e05a917445
fix(notifications,drying): printer-limited channels get only their printer's events; blocking mode pre-dries for scheduled jobs; model jobs say "(drying)"; remove dead load-tray state
2026-10-18 16:25:16 +02:00
maziggy
92d299bf20
Security hardening (maziggy/bambuddy-security #43 )
2026-10-18 16:04:37 +02:00
maziggy
26e9a05707
fix(queue): a plate printed from the external spool keeps the AMS off on multi-plate files; slot reuse respects the finish; any-model VPs keep the AMS on; cloud filament id read from the preset too
2026-10-18 14:21:05 +02:00
maziggy
f45cc599f3
fix(kprofiles): an AMS change leaves the K-profile to the lost-selection check; command answers no longer change the nozzle; unconfirmed writes say so and edits read back; skip refusals are logged; stop-drying toast says sent
2026-10-18 13:57:24 +02:00
maziggy
cacaaf4dae
fix(printers): live status carries nozzles, firmware, developer mode and the print's AMS mapping; run-out hint narrows by nozzle; AMS-HT is its unit id; rotate check sees loaded slots
2026-10-18 13:27:23 +02:00
maziggy
ac976e0003
fix(archives): kill-switch stops archive as cancelled; offline queue stop stores a reason key; SpoolBuddy config save offers a daemon restart
2026-10-18 12:39:38 +02:00
maziggy
3c2ab99635
fix(archives): re-sliced archives read as not printed with a cost; restore checks its numbers; prints are bound under one set of names
...
- A re-sliced archive is "archived" (Not printed) and priced like any
archive with grams (estimate_filament_cost, shared with archive_print).
- A reprint deletes a timelapse with no plate on record when the 3MF has
exactly one plate.
- on_print_start binds every print through _bind_active_print, so a
resumed print keeps its #3240 plate-restore binding.
- A model job's own nozzle_mapping is cleared on assignment to a nozzle-rack
printer (not on H2D, not for variants).
- GitHub restore: grams, costs, energy, print times and usage weights must be
finite numbers >= 0 (grams <= 100000, ints <= 2^31-1), else left empty
with a note; quantity 0..10000 is kept.
2026-10-18 12:13:46 +02:00
maziggy
f7bd06641a
fix(inventory): a used weight entered for a new spool is kept; Spoolman last_used means print use; the slot K picker accounts for nozzle flow
...
- Create, Add copies and CSV import lock a used weight above 0 (an
explicit weight_locked wins); a negative used weight is refused on create
and edit, more than the label is still taken.
- update_spool no longer stamps last_used: syncs, location changes and
weighing are not use. Print usage goes through Spoolman's /use, which sets it.
- ConfigureAmsSlotModal matches K-profiles to the fitted nozzle's flow
(others under Other) and labels each [HF] / [S]; the spool form uses the
same flowApplies helper.
2026-10-18 11:35:56 +02:00
maziggy
741539a740
chore(api): remove dead firmware WS progress, the delete-all plate calibration route and unused client wrappers
...
- Firmware upload progress was broadcast over WebSocket with no listener;
the page polls the upload status. Broadcast removed, docstrings fixed.
- DELETE /printers/{id}/camera/plate-detection/calibrate (delete every
reference at once) had no caller; references are deleted one at a time.
- 12 unused frontend API wrappers removed; the routes stay as API.
- /spoolbuddy/calibration redirects to the SpoolBuddy settings page, where
calibration lives; the dead page is gone.
2026-10-18 11:04:10 +02:00
maziggy
5fec296d72
chore(virtual-printer): log K-profile, filament and load commands from the slicer in full
...
The publish log line stops at 100 characters, which cut every K-profile
command off before its tray_id, the field that says how BambuStudio numbers
an A2L or AMS-HT tray. Those commands carry no credentials and are now
logged whole, so a support bundle settles it.
--------------
Security hardening (maziggy/bambuddy-security #42 )
2026-10-18 10:36:18 +02:00
maziggy
5a9415e2e1
fix(ams): Load and Unload work on an AMS-HT
...
The printer card sent unit*4+slot for an AMS-HT slot (512 for HT-A), which
the load route refused, and the commands turned the AMS-HT into ams_id 32.
An AMS-HT tray is now addressed by its unit id (128-135), as tray_now
reports it and as BambuStudio sends it (ams_id = target = unit, slot 0);
the A2L AMS-Lite load target is its unit 16, as BambuStudio sends. Unload
from an AMS-HT slot names that slot, a load behind a Filament Track Switch
asks which nozzle for an AMS-HT too, and the dual-nozzle load confirmation
resolves AMS-HT B-H to their unit instead of AMS 0.
2026-10-18 09:52:42 +02:00
maziggy
3542005110
test: register sqlite_only and docker marks in pytest.ini, drop redundant asyncio marks
...
The suite reads backend/tests/pytest.ini, not pyproject.toml, so every
sqlite_only use warned "Unknown pytest.mark". Two modules marked their sync
tests asyncio; asyncio_mode is auto, so the mark was redundant.
2026-10-17 17:01:32 +02:00