Add tray status model

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Luna 2026-06-30 06:01:53 -07:00
parent 826daa3ab7
commit 715db9ec36
3 changed files with 94 additions and 0 deletions

View file

@ -0,0 +1,2 @@
# SPDX-License-Identifier: GPL-3.0-or-later
"""Optional desktop tray applet. GUI deps live behind the [tray] extra."""

View file

@ -0,0 +1,49 @@
# SPDX-License-Identifier: GPL-3.0-or-later
"""Pure status model for the tray applet. No GUI or subprocess imports."""
from __future__ import annotations
from dataclasses import dataclass
@dataclass(frozen=True)
class TrayState:
running: bool
total_alerts: int
high_alerts: int
last_alert: str | None
color: str # "green" | "amber" | "grey"
summary: str
@property
def tooltip(self) -> str:
return f"Enodia Sentinel — {self.summary}"
def _high_count(counts: dict) -> int:
# Severity keys are stringified Severity names ("HIGH"/"CRITICAL"); be
# tolerant of case in case a producer lowercases them.
total = 0
for key, value in counts.items():
if str(key).upper() in ("HIGH", "CRITICAL"):
total += int(value)
return total
def parse_status(status: dict | None) -> TrayState:
if not status:
return TrayState(False, 0, 0, None, "grey", "Unknown")
running = bool(status.get("running"))
total = int(status.get("total_alerts", 0))
high = _high_count(status.get("counts") or {})
last = status.get("last_alert")
if not running:
return TrayState(False, total, high, last, "grey", "Stopped")
if high:
return TrayState(
True, total, high, last, "amber",
f"Running — {high} high/critical of {total} alerts",
)
if total:
return TrayState(True, total, high, last, "green",
f"Running — {total} alerts")
return TrayState(True, total, high, last, "green", "Running — no alerts")