-
Anruf-Übersicht · {html.escape(kategorien.PROFIL_NAME)}
+
Anruf-Übersicht
{len(anrufe)} Anrufe · {zusammenfassung or '—'} · lokal erzeugt aus der Ablage
{karten}
"""
diff --git a/pipe/deck.py b/pipe/deck.py
index c1b117e..394e302 100644
--- a/pipe/deck.py
+++ b/pipe/deck.py
@@ -18,15 +18,24 @@ import urllib.error
import urllib.request
from functools import lru_cache
-from . import config, kategorien
+from . import config
_API = "/index.php/apps/deck/api/v1.1"
-# Farben je Dringlichkeit - siehe pipe/kategorien.py.
-DRINGLICHKEIT_FARBE = kategorien.DRINGLICHKEIT_FARBE
+# Farben (6-stelliges Hex ohne #) je Dringlichkeit.
+DRINGLICHKEIT_FARBE = {
+ "niedrig": "31CC7C", # grün
+ "normal": "F1DB50", # gelb
+ "hoch": "E0A339", # orange
+ "notfall": "E9322D", # rot
+}
# Lesbare Namen der Kategorien für den Kartentitel - der Stapel sagt jetzt,
# wie weit die Bearbeitung ist, nicht mehr worum es geht.
-KATEGORIE_LABEL = kategorien.KATEGORIE_LABEL
+KATEGORIE_LABEL = {
+ "termin": "Termin", "rezept": "Rezept", "ueberweisung": "Überweisung",
+ "befund": "Befund", "verwaltung": "Verwaltung", "beschwerden": "Beschwerden", "notfall": "Notfall",
+ "rueckruf": "Rückruf", "sonstiges": "Sonstiges",
+}
@lru_cache(maxsize=1)
diff --git a/pipe/dienste.py b/pipe/dienste.py
deleted file mode 100644
index c17342f..0000000
--- a/pipe/dienste.py
+++ /dev/null
@@ -1,96 +0,0 @@
-"""Zustand der beteiligten Dienste (Telefon, Verarbeitung, Spracherkennung,
-Nextcloud) — geteilt zwischen Leitstand (pipe.server) und Störungswache
-(pipe.monitor), damit beide dieselbe Sicht auf "läuft/steht" haben.
-"""
-from __future__ import annotations
-
-import subprocess
-import time
-import urllib.error
-import urllib.request
-from datetime import datetime
-
-from . import config, store
-
-# Statusabfragen sind teuer (Netz, Unterprozesse) - kurz zwischenspeichern,
-# damit haeufiges Nachfragen den Rechner nicht belastet.
-_CACHE: dict[str, tuple[float, dict]] = {}
-CACHE_S = 4.0
-
-
-def _laeuft(muster: str) -> bool:
- try:
- return subprocess.run(["pgrep", "-f", muster], capture_output=True).returncode == 0
- except Exception:
- return False
-
-
-def _http_ok(url: str, timeout: float = 5.0) -> bool:
- """Erreichbarkeitstest. Mit eigenem User-Agent - ein WAF vor Nextcloud
- blockt den Standardnamen von urllib und meldete fälschlich 'nicht
- erreichbar'."""
- req = urllib.request.Request(url, headers={"User-Agent": "praxis-telefon-agent/1.0"})
- try:
- with urllib.request.urlopen(req, timeout=timeout, context=store._ssl_kontext()):
- return True
- except urllib.error.HTTPError:
- return True # antwortet - reicht als Lebenszeichen
- except Exception:
- return False
-
-
-def _trunk() -> tuple[str, str]:
- """(zustand, text) des SIP-Trunks."""
- if not _laeuft("[f]reeswitch"):
- return "aus", "FreeSWITCH läuft nicht"
- try:
- roh = subprocess.run(
- ["fs_cli", "-P", config.FS_PORT, "-x", "sofia status gateway plusnet"],
- capture_output=True, text=True, timeout=8).stdout
- for zeile in roh.splitlines():
- if zeile.startswith("Status"):
- wert = zeile.split()[-1]
- return ("gut", "registriert") if wert == "UP" else ("schlecht", f"Trunk {wert}")
- return "unklar", "Gateway unbekannt"
- except Exception:
- return "unklar", "fs_cli nicht erreichbar"
-
-
-def status() -> dict:
- jetzt = time.time()
- gepuffert = _CACHE.get("status")
- if gepuffert and jetzt - gepuffert[0] < CACHE_S:
- return gepuffert[1]
-
- trunk_zustand, trunk_text = _trunk()
- watcher = _laeuft("[p]ipe.watch")
- ollama = _http_ok(f"{config.OLLAMA_URL}/api/version")
- nextcloud = (_http_ok(f"{config.NEXTCLOUD_URL}/status.php")
- if config.nextcloud_aktiv() else None)
-
- offen = 0
- if config.TELEFON_EINGANG.is_dir():
- offen = sum(1 for d in config.TELEFON_EINGANG.iterdir()
- if d.is_file() and not d.name.startswith("."))
- fehler = 0
- if config.TELEFON_FEHLER.is_dir():
- fehler = sum(1 for d in config.TELEFON_FEHLER.iterdir() if d.is_file())
-
- daten = {
- "dienste": [
- {"name": "Telefon", "zustand": trunk_zustand, "text": trunk_text},
- {"name": "Verarbeitung", "zustand": "gut" if watcher else "aus",
- "text": "beobachtet Eingang" if watcher else "Watcher läuft nicht"},
- {"name": "Spracherkennung", "zustand": "gut" if ollama else "schlecht",
- "text": "Ollama bereit" if ollama else "Ollama nicht erreichbar"},
- {"name": "Nextcloud", "zustand": "unklar" if nextcloud is None
- else ("gut" if nextcloud else "schlecht"),
- "text": "nicht konfiguriert" if nextcloud is None
- else ("erreichbar" if nextcloud else "nicht erreichbar")},
- ],
- "eingang_offen": offen,
- "fehler": fehler,
- "stand": datetime.now().strftime("%H:%M:%S"),
- }
- _CACHE["status"] = (jetzt, daten)
- return daten
diff --git a/pipe/kategorien.py b/pipe/kategorien.py
deleted file mode 100644
index 4365a04..0000000
--- a/pipe/kategorien.py
+++ /dev/null
@@ -1,48 +0,0 @@
-"""Kategorien-Schema des aktiven Branchen-Profils (profile/