sten.wtf / Unstable Instance

open-autosecure — Unstable Instance. May not even function properly but you are free to help improvise it.

bot/__init__.py

from __future__ import annotations

import subprocess
import sys

from config import ROOT, prepare_runtime, resolve_db_path

VERSION = "0.1.0"
prepare_runtime()


def load_version() -> tuple[str, str]:
    kwargs = {
        "capture_output": True,
        "text": True,
        "check": True,
        "cwd": str(ROOT),
        "encoding": "utf-8",
        "errors": "replace",
    }
    if sys.platform == "win32":
        kwargs["creationflags"] = getattr(subprocess, "CREATE_NO_WINDOW", 0)
    try:
        commit = subprocess.run(["git", "rev-parse", "--short", "HEAD"], **kwargs).stdout.strip()
        commit = commit or "unknown"
    except Exception:
        commit = "unknown"
    return VERSION, commit


async def main() -> None:
    import asyncio
    import os

    import aiohttp

    import config
    from bot.client import build_bot
    from db import store
    from telemetry import meta_server, reporter

    version, commit = load_version()

    db = await store.connect(resolve_db_path(os.environ.get("OAS_DB_PATH")))
    try:
        cfg = config.resolve(await store.get_instance_config(db), os.environ)
        instance_id = cfg.instance_id or version or "unknown"

        meta_app = meta_server.build_meta_app(instance_id, version, commit)
        runner = await meta_server.start_meta_server(meta_app, cfg.meta_host, cfg.meta_port)
        try:
            async with aiohttp.ClientSession() as http:
                payload = reporter.build_payload(instance_id, version, "startup", {})
                await reporter.report(cfg.telemetry_enabled, cfg.telemetry_url, payload, http)

            bots = await store.list_bots(db)
            clients = [build_bot(db, cfg) for _ in bots]
            try:
                await asyncio.gather(
                    *(client.start(b["token"]) for client, b in zip(clients, bots))
                )
            except (KeyboardInterrupt, asyncio.CancelledError):
                pass
            finally:
                await asyncio.gather(*(client.close() for client in clients))
        finally:
            await runner.cleanup()
    finally:
        await db.close()