MeshDD-Bot/main.py
ppfeiffer fd9eb99b6a feat(db): Initialen Admin-User beim ersten Start anlegen
Wenn beim Start keine User in der Datenbank vorhanden sind, wird
automatisch ein verifizierter Admin angelegt:
  E-Mail: admin@localhost
  Passwort: changeme

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 22:03:19 +01:00

108 lines
2.9 KiB
Python

import asyncio
import logging
import signal
import threading
from meshbot import config
from meshbot.auth import hash_password
from meshbot.database import Database
from meshbot.bot import MeshBot
from meshbot.nina import NinaBot
from meshbot.scheduler import Scheduler
from meshbot.webserver import WebServer, WebSocketManager
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
)
logger = logging.getLogger(__name__)
async def main():
logger.info("Starting %s v%s", config.get("bot.name"), config.get("version"))
# Database
db = Database(config.get("database.path", "data/meshdd.db"))
await db.connect()
# Seed initial admin if no users exist
if not await db.get_all_users():
await db.create_user(
email="admin@localhost",
password=hash_password("changeme"),
name="Administrator",
role="admin",
is_verified=1,
)
logger.info("Initial admin created: admin@localhost / changeme <- bitte Passwort aendern!")
# WebSocket Manager
ws_manager = WebSocketManager()
# Bot
loop = asyncio.get_event_loop()
bot = MeshBot(db, loop)
bot.ws_manager = ws_manager
# Scheduler
scheduler = Scheduler(bot, ws_manager)
# NINA
nina = NinaBot(bot.send_message, ws_manager)
# Webserver
webserver = WebServer(db, ws_manager, bot, scheduler, nina)
runner = await webserver.start(config.get("web.host", "0.0.0.0"), config.get("web.port", 8080))
# Connect Meshtastic in a thread (blocking call)
connect_thread = threading.Thread(target=bot.connect, daemon=True)
connect_thread.start()
# Watch config for changes
asyncio.create_task(config.watch())
# Scheduler tasks
asyncio.create_task(scheduler.watch())
asyncio.create_task(scheduler.run())
# NINA tasks
asyncio.create_task(nina.watch())
await nina.start()
# Wait for shutdown
stop_event = asyncio.Event()
def _signal_handler():
logger.info("Shutdown signal received")
stop_event.set()
for sig in (signal.SIGINT, signal.SIGTERM):
loop.add_signal_handler(sig, _signal_handler)
try:
await stop_event.wait()
finally:
logger.info("Shutting down...")
try:
await nina.stop()
except Exception:
logger.exception("Error stopping NINA")
try:
bot.disconnect()
except Exception:
logger.exception("Error disconnecting bot")
try:
await ws_manager.close_all()
except Exception:
logger.exception("Error closing WebSocket connections")
try:
await runner.cleanup()
except Exception:
logger.exception("Error cleaning up web runner")
await db.close()
logger.info("Shutdown complete")
if __name__ == "__main__":
asyncio.run(main())