Files
max-server/src/main.py
2026-05-08 15:27:05 +03:00

152 lines
4.5 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.
# Импортирование библиотек
import asyncio
import logging
import signal
import ssl
import sys
import traceback
from common.config import ServerConfig
from common.push import PushService
from common.sqlite import SQLitePoolCompat
from oneme.controller import OnemeController
from tamtam.controller import TTController
from telegrambot.controller import TelegramBotController
# Конфиг сервера
server_config = ServerConfig()
async def init_db():
"""Инициализация базы данных"""
db = {}
if server_config.db_type == "mysql":
import aiomysql
db = await aiomysql.create_pool(
host=server_config.db_host,
port=server_config.db_port,
user=server_config.db_user,
password=server_config.db_password,
db=server_config.db_name,
cursorclass=aiomysql.DictCursor,
autocommit=True,
)
elif server_config.db_type == "sqlite":
import aiosqlite
raw_db = await aiosqlite.connect(server_config.db_file, isolation_level=None)
raw_db.row_factory = aiosqlite.Row
db = SQLitePoolCompat(raw_db)
# Возвращаем
return db
def init_ssl():
"""Создание контекста SSL"""
# Создаем контекст SSL
ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ssl_context.load_cert_chain(server_config.certfile, server_config.keyfile)
# Возвращаем
return ssl_context
def set_logging():
"""Настройка уровня логирования"""
# Настройка уровня логирования
log_level = server_config.log_level
if log_level == "debug":
logging.basicConfig(level=logging.DEBUG)
elif log_level == "info":
logging.basicConfig(level=logging.INFO)
else:
logging.basicConfig(level=None)
async def main():
"""Запуск сервера"""
set_logging()
db = await init_db()
ssl_context = init_ssl()
clients = {}
push_service = PushService(server_config.firebase_credentials_path)
async def api_event(target, eventData):
target_clients = api.get("clients", {}).get(target, {}).get("clients", [])
for client in target_clients:
await controllers[client["protocol"]].event(target, client, eventData)
# Если у пользователя нет активных подключений
# и это новое сообщение - отсылаем пуш
if not target_clients and eventData.get("eventType") == "new_msg":
message = eventData.get("message", {})
sender_id = message.get("sender")
text = message.get("text", "")
chat_id = eventData.get("chatId", "")
msg_id = message.get("id", 0)
await push_service.send_to_user(
db, target,
sender_id=sender_id,
msg_id=msg_id,
chat_id=chat_id,
text=text,
)
api = {
"db": db,
"ssl": ssl_context,
"clients": clients,
"event": api_event,
"origins": server_config.origins,
}
controllers = {
"oneme": OnemeController(),
"tamtam": TTController(),
"telegrambot": TelegramBotController(),
}
api["telegram_bot"] = controllers["telegrambot"]
loop = asyncio.get_running_loop()
running_tasks = []
def _shutdown(sig):
logging.info(f"Получен сигнал {sig}, завершаем все задачи...")
for task in running_tasks:
task.cancel()
if sys.platform != "win32":
for sig in (signal.SIGTERM, signal.SIGINT):
loop.add_signal_handler(sig, _shutdown, sig)
coros = [controller.launch(api) for controller in controllers.values()]
running_tasks.extend(asyncio.create_task(coro) for coro in coros)
# Запускаем контроллеры
try:
await asyncio.gather(*running_tasks)
except asyncio.CancelledError:
logging.info("Все задачи завершены")
except Exception as e:
logging.error(
f"Произошла неизвестная ошибка: {e}"
)
traceback.print_exc()
finally:
if hasattr(db, 'close'):
db.close()
await db.wait_closed()
elif hasattr(db, 'connection') and hasattr(db.connection, 'close'):
await db.connection.close()
if __name__ == "__main__":
asyncio.run(main())