reminder-bot/bot/main.py

109 lines
2.5 KiB
Python

"""Main entry point for the reminder bot."""
import asyncio
import signal
import sys
from aiogram import Bot, Dispatcher
from bot.config import get_config
from bot.logging_config import setup_logging, get_logger
from bot.db.base import init_db, create_tables, close_db
from bot.core.bot import create_bot, create_dispatcher
from bot.core.scheduler import create_scheduler, start_scheduler, stop_scheduler
# Global instances
bot: Bot = None
dp: Dispatcher = None
async def on_startup() -> None:
"""Execute actions on bot startup."""
logger = get_logger(__name__)
logger.info("Starting reminder bot...")
# Load config
config = get_config()
# Initialize database
init_db(config.db_url)
await create_tables()
logger.info("Bot startup completed")
async def on_shutdown() -> None:
"""Execute actions on bot shutdown."""
logger = get_logger(__name__)
logger.info("Shutting down reminder bot...")
# Stop scheduler
stop_scheduler()
# Close database
await close_db()
# Close bot session
if bot:
await bot.session.close()
logger.info("Bot shutdown completed")
async def main() -> None:
"""Main function to run the bot."""
global bot, dp
# Load configuration
config = get_config()
# Setup logging
setup_logging(config.log_level)
logger = get_logger(__name__)
try:
# Execute startup
await on_startup()
# Create bot and dispatcher
bot = create_bot(config.bot_token)
dp = create_dispatcher()
# Create and start scheduler
scheduler = create_scheduler(bot)
start_scheduler()
# Start polling
logger.info("Starting polling...")
await dp.start_polling(
bot,
skip_updates=config.polling_skip_updates,
)
except KeyboardInterrupt:
logger.info("Received keyboard interrupt")
except Exception as e:
logger.error(f"Fatal error: {e}", exc_info=True)
raise
finally:
await on_shutdown()
def handle_signal(signum, frame):
"""Handle termination signals."""
logger = get_logger(__name__)
logger.info(f"Received signal {signum}")
sys.exit(0)
if __name__ == "__main__":
# Setup signal handlers for graceful shutdown
signal.signal(signal.SIGINT, handle_signal)
signal.signal(signal.SIGTERM, handle_signal)
# Run the bot
try:
asyncio.run(main())
except (KeyboardInterrupt, SystemExit):
pass