aufträge und „Alle aktualisieren“: beendete lassen sich ausblenden
User 25.09.: Die Karten waren „immer da“ und ließen sich weder bestätigen noch wegklicken. Beendete Aufträge der KI-Box und das letzte „Alle aktualisieren“ im Homelab haben jetzt einen Knopf „Ausblenden“ (quittiert wird auf dem Server, gilt also auf allen Geräten; das Protokoll behält alles). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
0df593c05a
commit
54a3649d5e
@@ -126,6 +126,13 @@ def sammellauf_stand() -> dict:
|
||||
return {"sammellauf": sammellauf.aktueller()}
|
||||
|
||||
|
||||
@router.post("/sammellauf/{sl_id}/quittieren")
|
||||
def sammellauf_quittieren(sl_id: str) -> dict:
|
||||
"""Beendetes „Alle aktualisieren“ als gesehen markieren (die Update-Seite blendet es aus)."""
|
||||
from services.homelab import sammellauf
|
||||
return {"ok": sammellauf.quittieren(sl_id)}
|
||||
|
||||
|
||||
@router.get("/protokoll")
|
||||
def protokoll_lesen(grenze: int = 200, berichte: bool = False) -> dict:
|
||||
from services.homelab import protokoll
|
||||
|
||||
@@ -155,6 +155,12 @@ def cancel(job_id: str) -> dict:
|
||||
return {"ok": jobengine.cancel_job(job_id)}
|
||||
|
||||
|
||||
@router.post("/jobs/{job_id}/quittieren")
|
||||
def quittieren(job_id: str) -> dict:
|
||||
"""Beendeten Auftrag als gesehen markieren (die Oberfläche blendet ihn aus)."""
|
||||
return {"ok": jobengine.quittieren(job_id)}
|
||||
|
||||
|
||||
class RoleReq(BaseModel):
|
||||
role: str | None = None
|
||||
|
||||
|
||||
@@ -89,9 +89,24 @@ def liste() -> list[dict]:
|
||||
|
||||
|
||||
def aktueller() -> dict | None:
|
||||
"""Der laufende oder, wenn keiner läuft, der letzte Sammellauf."""
|
||||
"""Der laufende oder, wenn keiner läuft, der letzte Sammellauf — solange ihn niemand quittiert hat (seit
|
||||
25.09.2026: vorher stand der letzte für immer auf der Update-Seite)."""
|
||||
alle = _alle()
|
||||
return oeffentlich(next((x for x in reversed(alle) if x.get("status") == "laeuft"), alle[-1] if alle else None))
|
||||
if laufend := next((x for x in reversed(alle) if x.get("status") == "laeuft"), None):
|
||||
return oeffentlich(laufend)
|
||||
letzter = alle[-1] if alle else None
|
||||
return None if not letzter or letzter.get("quittiert") else oeffentlich(letzter)
|
||||
|
||||
|
||||
def quittieren(sl_id: str) -> bool:
|
||||
"""Einen beendeten Sammellauf als gesehen markieren; das Protokoll behält ihn."""
|
||||
with _lock:
|
||||
sl = next((x for x in _alle() if x["id"] == sl_id), None)
|
||||
if not sl or sl.get("status") == "laeuft":
|
||||
return False
|
||||
sl["quittiert"] = True
|
||||
_merken(sl)
|
||||
return True
|
||||
|
||||
|
||||
def laeuft() -> bool:
|
||||
|
||||
@@ -567,6 +567,19 @@ def cancel_job(job_id: str) -> bool:
|
||||
return True
|
||||
|
||||
|
||||
def quittieren(job_id: str) -> bool:
|
||||
"""Einen beendeten Auftrag als gesehen markieren — die Oberfläche blendet ihn dann aus (seit 25.09.2026;
|
||||
vorher blieben beendete Aufträge 24 Stunden stehen, ohne dass man sie wegklicken konnte)."""
|
||||
with _LOCK:
|
||||
_laden()
|
||||
job = JOBS.get(job_id)
|
||||
if not job or job["state"] not in _ENDE:
|
||||
return False
|
||||
job["quittiert"] = True
|
||||
_speichern(job)
|
||||
return True
|
||||
|
||||
|
||||
def public_jobs(mit_log: bool = True) -> list[dict]:
|
||||
"""Aufträge ohne interne Felder für die API; das Protokoll kommt aus der Datei (Ende)."""
|
||||
with _LOCK:
|
||||
|
||||
@@ -386,3 +386,14 @@ def test_schnittstellen(homelab):
|
||||
fertig = c.get("/api/homelab/sammellauf").json()["sammellauf"]
|
||||
assert fertig["status"] == "fertig" and fertig["id"] == antwort.json()["sammellauf"]["id"]
|
||||
assert "meldung" not in fertig and "dringend" not in fertig
|
||||
|
||||
|
||||
def test_quittiert_verschwindet_von_der_update_seite(homelab):
|
||||
"""25.09.2026: Das fertige „Alle aktualisieren“ ließ sich nicht wegklicken."""
|
||||
antwort = sammellauf.starten()
|
||||
assert sammellauf.quittieren(antwort["sammellauf"]["id"]) is False # läuft noch
|
||||
sl = _auf_ende()
|
||||
assert sammellauf.aktueller()["id"] == sl["id"]
|
||||
assert sammellauf.quittieren(sl["id"]) is True
|
||||
assert sammellauf.aktueller() is None
|
||||
assert sammellauf.liste()[0]["quittiert"] is True # das Protokoll behält ihn
|
||||
|
||||
@@ -194,3 +194,16 @@ def test_systemd_start_scheitert_sauber(motor, monkeypatch):
|
||||
def test_zeilen_aus_ueberschreibt_mit_wagenruecklauf():
|
||||
assert jobengine.zeilen_aus("a\n 1%\r 50%\r100%\nb\r\n") == ["a", "100%", "b"]
|
||||
assert jobengine.zeilen_aus("läuft\r 7%") == [" 7%"]
|
||||
|
||||
|
||||
def test_quittieren_nur_wenn_beendet(motor):
|
||||
"""25.09.2026: Beendete Aufträge standen 24 Stunden auf der Update-Seite, ohne dass man sie wegklicken konnte."""
|
||||
job_id = jobengine.start_job([PY, "-c", "import time; time.sleep(30)"], "Lang")
|
||||
time.sleep(0.2)
|
||||
assert jobengine.quittieren(job_id) is False # läuft noch
|
||||
jobengine.cancel_job(job_id)
|
||||
_warte(job_id)
|
||||
assert jobengine.quittieren(job_id) is True and _oeffentlich(job_id)["quittiert"] is True
|
||||
akte = json.loads((motor / f"{job_id}.json").read_text(encoding="utf-8"))
|
||||
assert akte["quittiert"] is True
|
||||
assert jobengine.quittieren("gibt-es-nicht") is False
|
||||
|
||||
Reference in New Issue
Block a user