from __future__ import annotations import argparse import asyncio import logging import sys from app.collectors import import_all_sources from app.config import get_settings from app.db import get_engine, get_session_factory, init_db from app.db.queries import prune_probe_results from app.probes import probe_due_batch def _setup() -> None: logging.basicConfig(level=logging.INFO, format="%(levelname)s %(message)s") get_settings() get_engine() async def cmd_import_sources() -> int: _setup() await init_db() factory = get_session_factory() async with factory() as session: results = await import_all_sources(session) for name, stats in results.items(): print(f"{name}: {stats}") return 0 async def cmd_probe_once() -> int: _setup() await init_db() settings = get_settings() factory = get_session_factory() async with factory() as session: count = await probe_due_batch(session, settings) print(f"probed {count} trackers") return 0 async def cmd_prune() -> int: _setup() await init_db() settings = get_settings() factory = get_session_factory() async with factory() as session: removed = await prune_probe_results(session, settings.raw_result_retention_days) print(f"removed {removed} probe results") return 0 def main(argv: list[str] | None = None) -> int: parser = argparse.ArgumentParser(prog="python -m app.cli") sub = parser.add_subparsers(dest="command", required=True) sub.add_parser("import-sources", help="Import tracker sources once") sub.add_parser("probe-once", help="Probe due trackers once") sub.add_parser("prune", help="Prune expired raw probe results") args = parser.parse_args(argv) if args.command == "import-sources": return asyncio.run(cmd_import_sources()) if args.command == "probe-once": return asyncio.run(cmd_probe_once()) if args.command == "prune": return asyncio.run(cmd_prune()) parser.error("unknown command") return 2 if __name__ == "__main__": sys.exit(main())