# 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")