| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263 |
- """Stopping a print on a user's behalf.
- Every place a user can stop a print goes through here, so none can send the
- stop without the "stopped by the user" mark: the printer card, the queue and
- the webhook routes call stop_print_by_user; the HMS error dialog's "Stop
- Printing" sends its own stop payload and calls mark_stopped_by_user. Without
- the mark the printer's resulting "failed"/"aborted" status is taken at face
- value: a "print failed" notification goes out, and on some printers the
- cancel sequence's own error is reported as a fault such as a layer shift.
- """
- import logging
- from backend.app.services.printer_manager import printer_manager
- logger = logging.getLogger(__name__)
- def mark_stopped_by_user(printer_id: int) -> None:
- """Record that the user stopped the print on this printer (see module docstring)."""
- try:
- from backend.app.main import mark_printer_stopped_by_user
- mark_printer_stopped_by_user(printer_id)
- except Exception as e:
- logger.warning("Failed to mark printer %s as user-stopped: %s", printer_id, e)
- def stop_print_by_user(printer_id: int, *, mark_when_unsent: bool = False) -> bool:
- """Send the stop command; returns whether it was sent.
- The printer is marked as stopped by the user when the command was sent
- and the printer is not known to be idle (nothing to stop), or always with
- ``mark_when_unsent`` (the queue, which closes the job even
- when the printer is offline, so a "failed" it reports later still reads
- as the user's cancel). Errors sending the command propagate to the caller.
- """
- try:
- sent = printer_manager.stop_print(printer_id)
- except Exception:
- if mark_when_unsent:
- mark_stopped_by_user(printer_id)
- raise
- if mark_when_unsent or (sent and not _known_idle(printer_id)):
- mark_stopped_by_user(printer_id)
- return sent
- def _known_idle(printer_id: int) -> bool:
- """The printer reports a state with no print loaded.
- A stop sent then stops nothing, and its mark would linger until the next
- print's start clears it -- which a new MQTT client that first sees that
- print mid-way never runs, so the print's later failure read as the user's
- cancel (USP/I4). An unknown state is not idle: the mark is the safe side.
- That includes "unknown", the state before the first report after a
- (re)connect.
- """
- status = printer_manager.get_status(printer_id)
- state = getattr(status, "state", None)
- if not state or state == "unknown":
- return False
- return state not in printer_manager.ACTIVE_PRINT_STATES
|