#!/usr/bin/env python3 """ Metro Warden — entry point. Usage: python main.py [--debug] [--log-file PATH] The application reads config/defaults.toml on startup and can be overridden via CLI flags. """ from __future__ import annotations import argparse import logging import sys from pathlib import Path def _configure_logging(level: str, log_file: str) -> None: fmt = "%(asctime)s %(levelname)-8s %(name)s %(message)s" handlers: list[logging.Handler] = [logging.StreamHandler(sys.stderr)] if log_file: handlers.append(logging.FileHandler(log_file)) logging.basicConfig(level=getattr(logging, level.upper(), logging.INFO), format=fmt, handlers=handlers) def _parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser( prog="metro-warden", description="Metro Warden — Industrial Dark Network Operations Centre", ) parser.add_argument( "--debug", action="store_true", help="Enable DEBUG log level", ) parser.add_argument( "--log-file", default="", metavar="PATH", help="Write logs to this file in addition to stderr", ) parser.add_argument( "--config", default="", metavar="PATH", help="Path to TOML config file (default: config/defaults.toml)", ) return parser.parse_args() def _load_config(path: str) -> dict: config_path = Path(path) if path else Path(__file__).parent / "config" / "defaults.toml" if not config_path.exists(): return {} try: import toml return toml.loads(config_path.read_text()) except Exception as exc: logging.warning("could not load config %s: %s", config_path, exc) return {} def main() -> None: args = _parse_args() log_level = "DEBUG" if args.debug else "INFO" _configure_logging(log_level, args.log_file) raw_config = _load_config(args.config) # Flatten config sections into state-key style for the app config: dict = {} polling = raw_config.get("polling", {}) display = raw_config.get("display", {}) for k, v in polling.items(): config[f"settings.{k}"] = v for k, v in display.items(): config[f"settings.{k}"] = v from core.app import MetroWarden app = MetroWarden(config=config) app.run() if __name__ == "__main__": main()