Add source

This commit is contained in:
2025-12-04 00:12:56 +03:00
parent b75875df5e
commit 0cb7045e7a
75 changed files with 9055 additions and 0 deletions

145
main.py Normal file
View File

@@ -0,0 +1,145 @@
"""
Unified entry point for bot and web interface
"""
import asyncio
import logging
from pyrogram import Client
from shared.config import settings
from shared.database.session import init_db
from bot.modules.message_handler.commands import register_commands
from bot.modules.message_handler.callbacks import register_callbacks
from bot.modules.access_control.middleware import setup_middleware
from bot.modules.task_scheduler.executor import task_executor, set_app_client
from bot.modules.task_scheduler.queue import task_queue
from bot.utils.logger import setup_logger
from web.app import app as web_app
import uvicorn
# Setup logging
setup_logger()
logger = logging.getLogger(__name__)
async def run_web_server():
"""Run web server in the same event loop"""
config = uvicorn.Config(
app=web_app,
host=settings.WEB_HOST,
port=settings.WEB_PORT,
log_level="info",
loop="asyncio"
)
server = uvicorn.Server(config)
logger.info(f"Starting web server on {settings.WEB_HOST}:{settings.WEB_PORT}")
await server.serve()
async def run_bot():
"""Run Telegram bot"""
logger.info("Starting Telegram bot...")
# Initialize database
await init_db()
logger.info("Database initialized")
# Initialize task queue
await task_queue.initialize()
logger.info("Task queue initialized")
# Create Pyrogram client
app = Client(
"tgloader_bot",
api_id=settings.TELEGRAM_API_ID,
api_hash=settings.TELEGRAM_API_HASH,
bot_token=settings.BOT_TOKEN,
)
# Setup middleware for access control
setup_middleware(app)
# Set client for task executor
set_app_client(app)
# Register handlers
register_commands(app)
register_callbacks(app)
logger.info("Bot ready")
# Start bot
await app.start()
logger.info(f"Bot started. Owner ID: {settings.OWNER_ID}")
# Start task executor AFTER bot is started
await task_executor.start()
logger.info("Task executor started")
# Start background task for cleaning old files
from bot.utils.file_cleanup import cleanup_files_periodically
cleanup_task = asyncio.create_task(cleanup_files_periodically())
logger.info("File cleanup task started")
# Start background task for updating user information
from bot.utils.user_info_updater import update_users_without_info_periodically
user_info_task = asyncio.create_task(update_users_without_info_periodically())
logger.info("User info update task started")
return app
async def main():
"""Main startup function"""
logger.info("=" * 50)
logger.info("Starting TGLoader (Bot + Web Interface)")
logger.info("=" * 50)
# Start bot
bot_app = await run_bot()
# Start web server in the same event loop
web_task = asyncio.create_task(run_web_server())
logger.info("Web server started in the same event loop")
# Wait for completion (running in parallel)
try:
# Wait for web server to complete (runs indefinitely)
await web_task
except KeyboardInterrupt:
logger.info("Received stop signal (Ctrl+C)")
except asyncio.CancelledError:
logger.info("Received cancellation signal")
finally:
logger.info("Starting graceful shutdown...")
# Stop web server
web_task.cancel()
try:
await web_task
except asyncio.CancelledError:
pass
# Stop task executor
try:
await task_executor.stop()
logger.info("Task executor stopped")
except Exception as e:
logger.error(f"Error stopping executor: {e}")
# Stop bot
try:
await bot_app.stop()
logger.info("Bot stopped")
except Exception as e:
logger.error(f"Error stopping bot: {e}")
logger.info("Application terminated")
if __name__ == "__main__":
try:
asyncio.run(main())
except KeyboardInterrupt:
logger.info("Получен сигнал остановки (KeyboardInterrupt)")
except Exception as e:
logger.error(f"Критическая ошибка: {e}", exc_info=True)