Spool page for NFC links, bridge address; vendor-first new spool form
CI / test (push) Successful in 2m29s
CI / image (push) Successful in 39s

- /s/<id> shows a spool: rest in Spoolman and CC2 Control, where it is,
  last booking, history, links to Spoolman and the tag generator.
- Setting "Adresse der Bridge"; the tag generator can put <address>/s/<id>
  on the tag, so an iPhone held to the roll opens that page.
- New spool: vendor and material chosen from Spoolman, the vendor's
  filaments offered, values taken from similar filaments, duplicates
  pointed out and never created twice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014GcEk5tkfFSYD6NTF66NkC
This commit is contained in:
Jonas MenzelandClaude Opus 5.5 committed 2026-10-25 21:52:23 +01:00
1 parent b37cd64909
commit 64ea91d107
10 files changed
+304 -49

No files matched your search

+24
View File
@@ -1224,6 +1224,30 @@ class Bridge:
self.spool_cache[smid] = (self.clock(), sm)
return sm
def spool_whereabouts(self, smid: int) -> dict:
"""Where a Spoolman spool is as the bridge sees it, for the spool page."""
with self.lock:
slot = None
for pid, n, m in self.mappings():
if m["spool"] == smid:
w = self.workers.get(pid)
slot = {"printer": w.name if w else pid, "printer_id": pid, "slot": n + 1,
"since": m.get("since"), "assigned": bool(m.get("assigned"))}
copies, last = [], None
for w in self.workers.values():
st = w.st
for t in st["takeout"]:
if t["spool"] == smid and t["until"] is None and slot is None:
slot = {"printer": w.name, "printer_id": w.id, "slot": t["slot"] + 1, "takeout": True}
for sp in (w.cc2_data or {}).get("spools") or []:
if spoolman_id_of(sp) == smid:
copies.append({"printer": w.name, "remaining": _num(sp.get("remaining"), None),
"archived": bool(sp.get("archived"))})
for b in st["booked"].values():
if b.get("spoolman") == smid and b.get("last") and (last is None or b["last"]["time"] > last["time"]):
last = {**b["last"], "printer": w.name}
return {"slot": slot, "copies": copies, "last_booking": last}
def _name(self, smid: int) -> str:
cached = self.spool_cache.get(smid)
return label(cached[1]) if cached else f"Spoolman-Spule {smid}"