Initial commit

This commit is contained in:
2026-01-03 16:38:00 +03:00
parent 94ca600d3a
commit 39c99c4165
3 changed files with 50 additions and 3 deletions
+12 -2
View File
@@ -5,6 +5,7 @@ from aiogram import Bot, Dispatcher
from aiogram.client.default import DefaultBotProperties from aiogram.client.default import DefaultBotProperties
from aiogram.enums import ParseMode from aiogram.enums import ParseMode
from aiogram_dialog import setup_dialogs from aiogram_dialog import setup_dialogs
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from dishka import make_async_container from dishka import make_async_container
from dishka.integrations.aiogram import setup_dishka from dishka.integrations.aiogram import setup_dishka
@@ -38,7 +39,7 @@ from trudex.application.bot.user_dialogs.main_menu import user_menu_dialog
from trudex.application.bot.user_dialogs.registration import \ from trudex.application.bot.user_dialogs.registration import \
registration_dialog registration_dialog
from trudex.infrastructure.database.repo.user import UserRepository from trudex.infrastructure.database.repo.user import UserRepository
from trudex.infrastructure.di import DatabaseProvider from trudex.infrastructure.di import DatabaseProvider, SchedulerProvider
from trudex.infrastructure.utils.bot_commands import setup_bot_commands from trudex.infrastructure.utils.bot_commands import setup_bot_commands
from trudex.infrastructure.utils.config import Config from trudex.infrastructure.utils.config import Config
@@ -78,7 +79,11 @@ async def main() -> None:
router.message.middleware(RejectNotAdminMiddleware()) router.message.middleware(RejectNotAdminMiddleware())
router.message.middleware(RejectNotCreatorMiddleware()) router.message.middleware(RejectNotCreatorMiddleware())
container = make_async_container(DatabaseProvider(), context={Bot: bot, Config: config}) container = make_async_container(
DatabaseProvider(),
SchedulerProvider(),
context={Bot: bot, Config: config}
)
setup_dialogs(dp) setup_dialogs(dp)
setup_dishka(container, dp, auto_inject=True) setup_dishka(container, dp, auto_inject=True)
@@ -88,13 +93,18 @@ async def main() -> None:
user_repo = await request_container.get(UserRepository) user_repo = await request_container.get(UserRepository)
await setup_bot_commands(bot, config, user_repo) await setup_bot_commands(bot, config, user_repo)
scheduler = await container.get(AsyncIOScheduler)
scheduler.start()
await bot.delete_webhook(drop_pending_updates=True) await bot.delete_webhook(drop_pending_updates=True)
logging.info("Бот запущен") logging.info("Бот запущен")
logging.info("Планировщик задач запущен")
try: try:
await dp.start_polling(bot) await dp.start_polling(bot)
finally: finally:
scheduler.shutdown()
await bot.session.close() await bot.session.close()
+21 -1
View File
@@ -1,6 +1,8 @@
from collections.abc import AsyncIterable from collections.abc import AsyncIterable
import logging
from dishka import Provider, Scope, provide from apscheduler.schedulers.asyncio import AsyncIOScheduler
from dishka import AsyncContainer, Provider, Scope, provide
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
from trudex.infrastructure.database.config import new_session_maker from trudex.infrastructure.database.config import new_session_maker
@@ -15,6 +17,7 @@ from trudex.infrastructure.database.repo.test import TestRepository
from trudex.infrastructure.database.repo.test_attempt import \ from trudex.infrastructure.database.repo.test_attempt import \
TestAttemptRepository TestAttemptRepository
from trudex.infrastructure.database.repo.user import UserRepository from trudex.infrastructure.database.repo.user import UserRepository
from trudex.infrastructure.scheduling.tasks import deactivate_expired_tests
from trudex.infrastructure.utils.config import Config from trudex.infrastructure.utils.config import Config
@@ -70,3 +73,20 @@ class DatabaseProvider(Provider):
@provide(scope=Scope.REQUEST) @provide(scope=Scope.REQUEST)
def get_test_attempt_repository(self, session: AsyncSession) -> TestAttemptRepository: def get_test_attempt_repository(self, session: AsyncSession) -> TestAttemptRepository:
return TestAttemptRepository(session) return TestAttemptRepository(session)
class SchedulerProvider(Provider):
@provide(scope = Scope.APP)
def get_scheduler(self, container: AsyncContainer) -> AsyncIOScheduler:
logging.getLogger('apscheduler').setLevel(logging.WARNING)
scheduler = AsyncIOScheduler()
scheduler.add_job(
deactivate_expired_tests,
'interval',
minutes=5,
args=[container],
id='deactivate_expired_tests',
)
return scheduler
@@ -0,0 +1,17 @@
from datetime import datetime
from dishka import AsyncContainer
from trudex.infrastructure.database.dao.test import TestDAO
from trudex.infrastructure.database.models import Test
async def deactivate_expired_tests(container: AsyncContainer):
async with container() as request_container:
test_dao = await request_container.get(TestDAO)
tests = await test_dao.get_all()
for test in tests:
if test.expires_at and test.expires_at < datetime.utcnow() and test.is_active:
await test_dao.update(test.id, is_active=False)