#!/usr/bin/env python3 """Render or grade a phone-monitoring report produced by ``monitor.sh``. Two modes, selected by ``argv[1]``: * ``summary`` — print a human-readable status summary to stdout (always exit 0). * ``severity`` — exit 1 if any check is ``fatal``/``error``, else exit 0 (no output). ``argv[2]`` is the path to the ``report.json`` snapshot. Kept as a standalone module (not inline ``python < list[object]: """Return the ``checks`` array from the report, or [] if absent/malformed.""" data: object = json.loads(report_path.read_text(encoding="utf-8")) if not isinstance(data, dict): return [] checks: object = data.get("checks", []) return checks if isinstance(checks, list) else [] def _field(check: object, key: str, default: str) -> str: """Read a string field from a check object, falling back to ``default``.""" if isinstance(check, dict): value = check.get(key, default) if isinstance(value, str): return value return default def _render_summary(checks: list[object]) -> str: """Build the multi-line monitoring summary string for the given checks.""" counts = dict.fromkeys(_COUNT_KEYS, 0) issues: list[tuple[str, str, str]] = [] for check in checks: status = _field(check, "status", "warn") counts[status] = counts.get(status, 0) + 1 if status in _ISSUE_STATUSES: issues.append( ( status, _field(check, "check", "unknown"), _field(check, "message", ""), ), ) lines = [ "", "=== Monitoring Summary ===", f" ok={counts.get('ok', 0):<3} warn={counts.get('warn', 0):<3} " f"error={counts.get('error', 0):<3} fatal={counts.get('fatal', 0):<3}", ] if issues: lines.append("") lines.append("Issues found:") lines.extend( f" [{status}] {name}: {message}" for status, name, message in issues ) lines.append("==========================") lines.append("") return "\n".join(lines) + "\n" def _has_severe(checks: list[object]) -> bool: """Return True if any check has a fatal/error status.""" return any(_field(check, "status", "warn") in _SEVERE_STATUSES for check in checks) def main() -> int: """Dispatch on ``argv[1]`` (summary|severity) and ``argv[2]`` (report path).""" args = sys.argv[1:] expected_args = 2 if len(args) != expected_args or args[0] not in {"summary", "severity"}: sys.stderr.write("usage: monitor_report.py {summary|severity} \n") return 2 mode, report_path = args[0], Path(args[1]) checks = _load_checks(report_path) if mode == "summary": sys.stdout.write(_render_summary(checks)) return 0 return 1 if _has_severe(checks) else 0 if __name__ == "__main__": sys.exit(main())