fix: resolve printer model server-side for "Any Model" queue items (#435)

The previous fix passed target_model from the frontend, but this relied
on printer.model being set on the client. When a printer was added
without selecting a model (the field is optional), the frontend sent no
target_model parameter, causing the OR logic to be bypassed entirely —
the widget only queried printer_id=X and missed unassigned model-based
items.

The backend now looks up the printer's model from the database when
target_model isn't provided by the client, ensuring "Clear Plate &
Start Next" appears for model-based queue jobs regardless of how the
printer was configured.
This commit is contained in:
maziggy
2026-02-20 08:26:23 +01:00
parent d71e56c3e6
commit 732ff634fa
2 changed files with 24 additions and 13 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ All notable changes to Bambuddy will be documented in this file.
## [0.2.1b2] - Unreleased
### Fixed
- **Queue Stuck on "Busy" for "Any Model" Jobs** ([#435](https://github.com/maziggy/bambuddy/issues/435)) — When a print was queued with "Any [Model]" (e.g., "Any P1S"), it was created with `printer_id=NULL` and `target_model="P1S"`. After the assigned printer finished, the queue widget queried only for items matching `printer_id=X`, missing the next pending model-based item (`printer_id IS NULL`). With no next item found, the "Clear Plate & Start Next" button never appeared, leaving the scheduler stuck reporting "Busy". The queue API now accepts an optional `target_model` parameter; when combined with `printer_id`, it uses OR logic to also return unassigned items whose `target_model` matches the printer's model. The frontend passes the printer's model through to this query.
- **Queue Stuck on "Busy" for "Any Model" Jobs** ([#435](https://github.com/maziggy/bambuddy/issues/435)) — When a print was queued with "Any [Model]" (e.g., "Any P1S"), it was created with `printer_id=NULL` and `target_model="P1S"`. After the assigned printer finished, the queue widget queried only for items matching `printer_id=X`, missing the next pending model-based item (`printer_id IS NULL`). With no next item found, the "Clear Plate & Start Next" button never appeared, leaving the scheduler stuck reporting "Busy". The queue API now accepts an optional `target_model` parameter; when combined with `printer_id`, it uses OR logic to also return unassigned items whose `target_model` matches the printer's model. The frontend passes the printer's model through to this query. Additionally, the backend now resolves the printer's model server-side from the database when the frontend doesn't provide `target_model` (e.g., when the printer was added without selecting a model), ensuring the OR logic works regardless of whether the client knows the printer's model.
### New Features
- **Include Beta Updates Setting** — New toggle in Settings → Updates to opt in to beta/prerelease update notifications. Default: off (stable only). The update checker now fetches `/releases` instead of `/releases/latest` and filters by `parse_version()` prerelease detection (not GitHub's `prerelease` flag, which may not be set correctly). Users on the Docker `latest` tag will no longer see notifications for beta releases they can't install.
+23 -12
View File
@@ -270,19 +270,30 @@ async def list_queue(
if printer_id == -1:
# Special value: filter for unassigned items
query = query.where(PrintQueueItem.printer_id.is_(None))
elif target_model:
# Include both printer-specific items AND model-based (unassigned) items
query = query.where(
or_(
PrintQueueItem.printer_id == printer_id,
and_(
PrintQueueItem.printer_id.is_(None),
func.lower(PrintQueueItem.target_model) == target_model.lower(),
),
)
)
else:
query = query.where(PrintQueueItem.printer_id == printer_id)
# Resolve effective model: prefer explicit param, fall back to printer's DB model.
# This ensures model-based "Any X" items are returned even when the frontend
# doesn't send target_model (e.g. printer.model is NULL on the client side).
effective_model = target_model
if not effective_model:
printer_row = (
await db.execute(select(Printer.model).where(Printer.id == printer_id))
).scalar_one_or_none()
effective_model = printer_row
if effective_model:
# Include both printer-specific items AND model-based (unassigned) items
query = query.where(
or_(
PrintQueueItem.printer_id == printer_id,
and_(
PrintQueueItem.printer_id.is_(None),
func.lower(PrintQueueItem.target_model) == effective_model.lower(),
),
)
)
else:
query = query.where(PrintQueueItem.printer_id == printer_id)
elif target_model:
query = query.where(func.lower(PrintQueueItem.target_model) == target_model.lower())
if status: