mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-10 20:47:03 +01:00
consumables.py 279 -> 217. check_page_delivery and _snapshot_counters move to _page_delivery.py. The state-file primitives stay put: test_consumables.py patches _load_consumable_state, _save_consumable_state and CONSUMABLE_STATE_FILE on consumables, and moving them would have let a test write to the real ~/.config/brother_printer/state.json. Verified by mtime after the run, not just by a green suite. test_consumables_part2.py patches the same three primitives from both sides of the seam, so it gains a second MOD_PD applied per class rather than a blanket swap. Pass count is 402 before and after. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY
77 lines
2.7 KiB
Python
77 lines
2.7 KiB
Python
"""Dropped-page detection: CUPS's page log versus the printer's own counter.
|
|
|
|
Split out of :mod:`python_pkg.brother_printer.consumables` to keep it under
|
|
the 250-line cap. The state-file I/O stays in ``consumables`` because
|
|
``tests/test_consumables.py`` patches it there; it is imported here so
|
|
``tests/test_consumables_part2.py`` can patch it on this module for the two
|
|
functions that moved.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from python_pkg.brother_printer.constants import PAGE_DROP_WARN_THRESHOLD
|
|
from python_pkg.brother_printer.consumables import (
|
|
_get_cups_total_pages,
|
|
_load_consumable_state,
|
|
_save_consumable_state,
|
|
)
|
|
from python_pkg.brother_printer.data_classes import PageDeliveryCheck
|
|
|
|
|
|
def check_page_delivery(printer_total: int, *, queue_idle: bool) -> PageDeliveryCheck:
|
|
"""Compare pages CUPS logged against pages the printer actually counted.
|
|
|
|
Only meaningful between jobs: mid-job, CUPS has logged pages the printer has
|
|
not yet pulled off the wire, which would look identical to dropping them.
|
|
Records a fresh snapshot of both counters whenever it runs cleanly.
|
|
|
|
Args:
|
|
printer_total: Lifetime count from the printer's own counter.
|
|
queue_idle: False when a job is queued or printing, which makes any
|
|
comparison meaningless.
|
|
|
|
Returns:
|
|
The comparison. suspected is True only when CUPS claims materially more
|
|
pages than the printer recorded.
|
|
"""
|
|
check = PageDeliveryCheck()
|
|
if printer_total <= 0 or not queue_idle:
|
|
return check
|
|
state = _load_consumable_state()
|
|
cups_total = _get_cups_total_pages()
|
|
last_printer = state["last_printer_count"]
|
|
last_cups = state["last_cups_total"]
|
|
|
|
_snapshot_counters(state, printer_total, cups_total)
|
|
|
|
if last_printer <= 0 or last_cups <= 0:
|
|
# No baseline yet: this run establishes one.
|
|
return check
|
|
printer_delta = printer_total - last_printer
|
|
cups_delta = cups_total - last_cups
|
|
if printer_delta < 0 or cups_delta < 0:
|
|
# Counter reset or the page log rotated; nothing to conclude.
|
|
return check
|
|
check.cups_pages = cups_delta
|
|
check.printer_pages = printer_delta
|
|
check.dropped = cups_delta - printer_delta
|
|
check.suspected = check.dropped >= PAGE_DROP_WARN_THRESHOLD
|
|
return check
|
|
|
|
|
|
def _snapshot_counters(
|
|
state: dict[str, int],
|
|
printer_total: int,
|
|
cups_total: int,
|
|
) -> None:
|
|
"""Persist where both counters stood, for the next run to compare against."""
|
|
if (
|
|
state["last_printer_count"] == printer_total
|
|
and state["last_cups_total"] == cups_total
|
|
):
|
|
return
|
|
updated = dict(state)
|
|
updated["last_printer_count"] = printer_total
|
|
updated["last_cups_total"] = cups_total
|
|
_save_consumable_state(updated)
|