Files
MCM/main.py

112 lines
3.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""MCM MultiCustomerMessenger
Entry Point: Startet FastAPI (Uvicorn) und Textual TUI im selben asyncio-Event-Loop.
Für den systemd-Dienst (ohne TUI) siehe main_api_only.py.
"""
from __future__ import annotations
import asyncio
import logging
import sys
import uvicorn
from api.app import app as fastapi_app
from api.routes import channels as channels_router
from channels.sms_channel import SmsChannel
from channels.telegram_channel import TelegramChannel
from channels.whatsapp_channel import WhatsAppChannel
from config import settings
from db.database import init_db
from services import message_service
from tasks.receiver import build_scheduler
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
)
logger = logging.getLogger("mcm")
async def _run_api() -> None:
"""Uvicorn als Task in der bestehenden Event-Loop."""
config = uvicorn.Config(
fastapi_app,
host=settings.host,
port=settings.port,
log_level="warning",
access_log=False,
)
server = uvicorn.Server(config)
await server.serve()
async def main(with_tui: bool = True) -> None:
logger.info("MCM starting…")
# 1. Datenbank initialisieren
init_db()
# 2. Kanäle instanziieren
telegram = TelegramChannel()
whatsapp = WhatsAppChannel()
sms = SmsChannel()
# 3. Inbound-Callback setzen
telegram.set_inbound_callback(message_service.handle_inbound)
whatsapp.set_inbound_callback(message_service.handle_inbound)
sms.set_inbound_callback(message_service.handle_inbound)
# 4. Channel-Referenzen in Services/Routes registrieren
message_service.register_channels(telegram, whatsapp, sms)
channels_router.register(telegram, whatsapp, sms)
# 5. Kanäle starten
await telegram.start()
await whatsapp.start()
await sms.start()
# 6. Hintergrund-Tasks starten (WhatsApp-Polling etc.)
scheduler = build_scheduler(whatsapp)
scheduler.start()
# 7. Uvicorn als Hintergrund-Task starten
api_task = asyncio.create_task(_run_api(), name="mcm-api")
logger.info("API running on http://%s:%d", settings.host, settings.port)
try:
if with_tui:
# 8a. TUI starten (blockiert bis der Nutzer beendet)
from tui.app import MCMApp
tui = MCMApp()
await tui.run_async()
else:
# 8b. Nur API wartet auf Ctrl-C / SIGTERM
logger.info("Running in API-only mode (no TUI)")
try:
await api_task
except asyncio.CancelledError:
pass
finally:
logger.info("MCM shutting down…")
scheduler.shutdown(wait=False)
api_task.cancel()
try:
await api_task
except asyncio.CancelledError:
pass
await telegram.stop()
await whatsapp.stop()
await sms.stop()
logger.info("MCM stopped.")
if __name__ == "__main__":
no_tui = "--no-tui" in sys.argv
try:
asyncio.run(main(with_tui=not no_tui))
except KeyboardInterrupt:
pass