mirror of
https://github.com/koloideal/Quizzi.git
synced 2026-06-10 18:35:28 +03:00
commit
This commit is contained in:
@@ -35,6 +35,7 @@ from trudex.application.bot.middlewares.reject_not_admin import \
|
|||||||
RejectNotAdminMiddleware
|
RejectNotAdminMiddleware
|
||||||
from trudex.application.bot.middlewares.reject_not_creator import \
|
from trudex.application.bot.middlewares.reject_not_creator import \
|
||||||
RejectNotCreatorMiddleware
|
RejectNotCreatorMiddleware
|
||||||
|
from trudex.application.bot.user_dialogs.deeplink import deeplink_dialog
|
||||||
from trudex.application.bot.user_dialogs.main_menu import user_menu_dialog
|
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
|
||||||
@@ -65,6 +66,7 @@ async def main() -> None:
|
|||||||
user_menu_dialog,
|
user_menu_dialog,
|
||||||
take_test_dialog,
|
take_test_dialog,
|
||||||
registration_dialog,
|
registration_dialog,
|
||||||
|
deeplink_dialog,
|
||||||
admin_menu_dialog,
|
admin_menu_dialog,
|
||||||
admin_users_dialog,
|
admin_users_dialog,
|
||||||
admin_tests_dialog,
|
admin_tests_dialog,
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
|
||||||
from aiogram import Router
|
from aiogram import Router
|
||||||
from aiogram.filters import Command, CommandStart
|
from aiogram.filters import Command, CommandStart, CommandObject
|
||||||
from aiogram.types import ErrorEvent, Message
|
from aiogram.types import ErrorEvent, Message
|
||||||
from aiogram_dialog import DialogManager, StartMode
|
from aiogram_dialog import DialogManager, StartMode
|
||||||
from aiogram_dialog.api.exceptions import OutdatedIntent, UnknownIntent
|
from aiogram_dialog.api.exceptions import OutdatedIntent, UnknownIntent
|
||||||
@@ -7,14 +9,150 @@ from dishka.integrations.aiogram import FromDishka
|
|||||||
|
|
||||||
from trudex.application.bot.admin_dialogs.states import AdminMenuSG
|
from trudex.application.bot.admin_dialogs.states import AdminMenuSG
|
||||||
from trudex.application.bot.creator_dialogs.states import CreatorMenuSG
|
from trudex.application.bot.creator_dialogs.states import CreatorMenuSG
|
||||||
from trudex.application.bot.user_dialogs.states import (UserMenuSG,
|
from trudex.application.bot.user_dialogs.states import (
|
||||||
UserRegistrationSG)
|
UserDeeplinkSG,
|
||||||
|
UserMenuSG,
|
||||||
|
UserRegistrationSG,
|
||||||
|
)
|
||||||
from trudex.infrastructure.database.dao.group import GroupDAO
|
from trudex.infrastructure.database.dao.group import GroupDAO
|
||||||
|
from trudex.infrastructure.database.dao.test import TestDAO
|
||||||
from trudex.infrastructure.database.dao.user import UserDAO
|
from trudex.infrastructure.database.dao.user import UserDAO
|
||||||
|
from trudex.infrastructure.utils.config import Config
|
||||||
|
from trudex.infrastructure.utils.test_id_to_hash import decode_id
|
||||||
|
|
||||||
router = Router()
|
router = Router()
|
||||||
|
|
||||||
|
|
||||||
|
async def ensure_user_registered(
|
||||||
|
user_dao: UserDAO,
|
||||||
|
group_dao: GroupDAO,
|
||||||
|
message: Message,
|
||||||
|
dialog_manager: DialogManager,
|
||||||
|
pending_test_id: int | None = None,
|
||||||
|
) -> bool:
|
||||||
|
assert message.from_user is not None
|
||||||
|
|
||||||
|
existing_user = await user_dao.get_by_id(message.from_user.id)
|
||||||
|
groups = await group_dao.get_all()
|
||||||
|
|
||||||
|
start_data = {"user_id": message.from_user.id}
|
||||||
|
if pending_test_id:
|
||||||
|
start_data["pending_test_id"] = pending_test_id
|
||||||
|
|
||||||
|
if existing_user is None:
|
||||||
|
await user_dao.create(
|
||||||
|
user_id=message.from_user.id,
|
||||||
|
first_name=message.from_user.first_name,
|
||||||
|
username=message.from_user.username,
|
||||||
|
last_name=message.from_user.last_name,
|
||||||
|
)
|
||||||
|
if len(groups) > 0:
|
||||||
|
await dialog_manager.start(
|
||||||
|
UserRegistrationSG.input_name,
|
||||||
|
mode=StartMode.RESET_STACK,
|
||||||
|
data=start_data
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
if len(groups) > 0 and (existing_user.name is None or existing_user.group is None):
|
||||||
|
if existing_user.name is None:
|
||||||
|
await dialog_manager.start(
|
||||||
|
UserRegistrationSG.input_name,
|
||||||
|
mode=StartMode.RESET_STACK,
|
||||||
|
data=start_data
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
await dialog_manager.start(
|
||||||
|
UserRegistrationSG.select_group,
|
||||||
|
mode=StartMode.RESET_STACK,
|
||||||
|
data=start_data
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
|
||||||
|
await user_dao.upsert(
|
||||||
|
user_id=message.from_user.id,
|
||||||
|
first_name=message.from_user.first_name,
|
||||||
|
username=message.from_user.username,
|
||||||
|
last_name=message.from_user.last_name,
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
async def validate_deeplink_test(
|
||||||
|
test_dao: TestDAO,
|
||||||
|
user_dao: UserDAO,
|
||||||
|
test_id: int,
|
||||||
|
user_id: int,
|
||||||
|
) -> tuple[bool, str]:
|
||||||
|
test = await test_dao.get_by_id(test_id)
|
||||||
|
|
||||||
|
if not test:
|
||||||
|
return False, "❌ Тест не найден"
|
||||||
|
|
||||||
|
if not test.is_active:
|
||||||
|
return False, "❌ Тест деактивирован"
|
||||||
|
|
||||||
|
if test.expires_at and test.expires_at < datetime.utcnow():
|
||||||
|
return False, "❌ Срок действия теста истек"
|
||||||
|
|
||||||
|
user = await user_dao.get_by_id(user_id)
|
||||||
|
if test.for_group and user and user.group != test.for_group:
|
||||||
|
return False, f"❌ Тест доступен только для группы {test.for_group}"
|
||||||
|
|
||||||
|
return True, ""
|
||||||
|
|
||||||
|
|
||||||
|
@router.message(CommandStart(deep_link=True))
|
||||||
|
async def start_with_deeplink(
|
||||||
|
message: Message,
|
||||||
|
command: CommandObject,
|
||||||
|
user_dao: FromDishka[UserDAO],
|
||||||
|
group_dao: FromDishka[GroupDAO],
|
||||||
|
test_dao: FromDishka[TestDAO],
|
||||||
|
config: FromDishka[Config],
|
||||||
|
dialog_manager: DialogManager,
|
||||||
|
) -> None:
|
||||||
|
assert message.from_user is not None
|
||||||
|
|
||||||
|
deeplink = command.args
|
||||||
|
if not deeplink:
|
||||||
|
await start_handler(message, user_dao, group_dao, dialog_manager)
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
test_id = decode_id(deeplink, config.security.encode_key)
|
||||||
|
except (ValueError, IndexError):
|
||||||
|
await message.answer("❌ Неверная ссылка на тест")
|
||||||
|
await start_handler(message, user_dao, group_dao, dialog_manager)
|
||||||
|
return
|
||||||
|
|
||||||
|
is_registered = await ensure_user_registered(
|
||||||
|
user_dao, group_dao, message, dialog_manager, pending_test_id=test_id
|
||||||
|
)
|
||||||
|
|
||||||
|
if not is_registered:
|
||||||
|
return
|
||||||
|
|
||||||
|
is_valid, error = await validate_deeplink_test(
|
||||||
|
test_dao, user_dao, test_id, message.from_user.id
|
||||||
|
)
|
||||||
|
|
||||||
|
if not is_valid:
|
||||||
|
await dialog_manager.start(
|
||||||
|
UserDeeplinkSG.test_preview,
|
||||||
|
mode=StartMode.RESET_STACK,
|
||||||
|
data={"test_id": test_id, "error": error}
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
await dialog_manager.start(
|
||||||
|
UserDeeplinkSG.test_preview,
|
||||||
|
mode=StartMode.RESET_STACK,
|
||||||
|
data={"test_id": test_id}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@router.message(CommandStart())
|
@router.message(CommandStart())
|
||||||
async def start_handler(
|
async def start_handler(
|
||||||
message: Message,
|
message: Message,
|
||||||
@@ -22,56 +160,11 @@ async def start_handler(
|
|||||||
group_dao: FromDishka[GroupDAO],
|
group_dao: FromDishka[GroupDAO],
|
||||||
dialog_manager: DialogManager
|
dialog_manager: DialogManager
|
||||||
) -> None:
|
) -> None:
|
||||||
assert message.from_user is not None
|
is_registered = await ensure_user_registered(
|
||||||
|
user_dao, group_dao, message, dialog_manager
|
||||||
|
)
|
||||||
|
|
||||||
existing_user = await user_dao.get_by_id(message.from_user.id)
|
if is_registered:
|
||||||
|
|
||||||
if existing_user is None:
|
|
||||||
groups = await group_dao.get_all()
|
|
||||||
|
|
||||||
if len(groups) > 0:
|
|
||||||
await user_dao.create(
|
|
||||||
user_id=message.from_user.id,
|
|
||||||
first_name=message.from_user.first_name,
|
|
||||||
username=message.from_user.username,
|
|
||||||
last_name=message.from_user.last_name,
|
|
||||||
)
|
|
||||||
await dialog_manager.start(
|
|
||||||
UserRegistrationSG.input_name,
|
|
||||||
mode=StartMode.RESET_STACK,
|
|
||||||
data={"user_id": message.from_user.id}
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
await user_dao.create(
|
|
||||||
user_id=message.from_user.id,
|
|
||||||
first_name=message.from_user.first_name,
|
|
||||||
username=message.from_user.username,
|
|
||||||
last_name=message.from_user.last_name,
|
|
||||||
)
|
|
||||||
await dialog_manager.start(UserMenuSG.main, mode=StartMode.RESET_STACK)
|
|
||||||
else:
|
|
||||||
groups = await group_dao.get_all()
|
|
||||||
|
|
||||||
if len(groups) > 0 and (existing_user.name is None or existing_user.group is None):
|
|
||||||
if existing_user.name is None:
|
|
||||||
await dialog_manager.start(
|
|
||||||
UserRegistrationSG.input_name,
|
|
||||||
mode=StartMode.RESET_STACK,
|
|
||||||
data={"user_id": message.from_user.id}
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
await dialog_manager.start(
|
|
||||||
UserRegistrationSG.select_group,
|
|
||||||
mode=StartMode.RESET_STACK,
|
|
||||||
data={"user_id": message.from_user.id}
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
await user_dao.upsert(
|
|
||||||
user_id=message.from_user.id,
|
|
||||||
first_name=message.from_user.first_name,
|
|
||||||
username=message.from_user.username,
|
|
||||||
last_name=message.from_user.last_name,
|
|
||||||
)
|
|
||||||
await dialog_manager.start(UserMenuSG.main, mode=StartMode.RESET_STACK)
|
await dialog_manager.start(UserMenuSG.main, mode=StartMode.RESET_STACK)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,204 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
from aiogram.types import CallbackQuery, Message
|
||||||
|
from aiogram_dialog import Dialog, DialogManager, StartMode, Window
|
||||||
|
from aiogram_dialog.widgets.input import MessageInput
|
||||||
|
from aiogram_dialog.widgets.kbd import Button
|
||||||
|
from aiogram_dialog.widgets.text import Const, Format
|
||||||
|
from dishka import FromDishka
|
||||||
|
from dishka.integrations.aiogram_dialog import inject
|
||||||
|
|
||||||
|
from trudex.application.bot.user_dialogs.states import UserDeeplinkSG, UserMenuSG, UserTestSG
|
||||||
|
from trudex.domain.schemas import Test, User
|
||||||
|
from trudex.infrastructure.database.dao.test import TestDAO
|
||||||
|
from trudex.infrastructure.database.models import QuestionType
|
||||||
|
from trudex.infrastructure.database.repo.test import TestRepository
|
||||||
|
from trudex.infrastructure.database.repo.test_attempt import TestAttemptRepository
|
||||||
|
|
||||||
|
|
||||||
|
async def validate_test_access(test: Test | None, user: User | None) -> tuple[bool, str]:
|
||||||
|
if not test:
|
||||||
|
return False, "❌ Тест не найден"
|
||||||
|
|
||||||
|
if not test.is_active:
|
||||||
|
return False, "❌ Тест деактивирован"
|
||||||
|
|
||||||
|
if test.expires_at and test.expires_at < datetime.utcnow():
|
||||||
|
return False, "❌ Срок действия теста истек"
|
||||||
|
|
||||||
|
if test.for_group and user and user.group != test.for_group:
|
||||||
|
return False, f"❌ Тест доступен только для группы {test.for_group}"
|
||||||
|
|
||||||
|
return True, ""
|
||||||
|
|
||||||
|
|
||||||
|
@inject
|
||||||
|
async def get_deeplink_test_data(
|
||||||
|
dialog_manager: DialogManager,
|
||||||
|
test_dao: FromDishka[TestDAO],
|
||||||
|
test_repo: FromDishka[TestRepository],
|
||||||
|
**_kwargs
|
||||||
|
):
|
||||||
|
test_id = dialog_manager.start_data.get("test_id") if dialog_manager.start_data else None
|
||||||
|
error = dialog_manager.start_data.get("error") if dialog_manager.start_data else None
|
||||||
|
|
||||||
|
if error:
|
||||||
|
return {"test_info": error, "can_start": False}
|
||||||
|
|
||||||
|
if not test_id:
|
||||||
|
return {"test_info": "❌ Тест не найден", "can_start": False}
|
||||||
|
|
||||||
|
test = await test_dao.get_by_id(test_id)
|
||||||
|
|
||||||
|
if not test:
|
||||||
|
return {"test_info": "❌ Тест не найден", "can_start": False}
|
||||||
|
|
||||||
|
questions_count = await test_repo.count_questions_in_test(test_id)
|
||||||
|
|
||||||
|
password_str = "🔒 Требуется пароль" if test.password else "🔓 Без пароля"
|
||||||
|
attempts_str = f"🔄 Попыток: {test.attempts}" if test.attempts else "🔄 Попыток: ♾️"
|
||||||
|
|
||||||
|
test_info = (
|
||||||
|
f"<b>📝 {test.title}</b>\n\n"
|
||||||
|
f"<blockquote>{test.description or '—'}</blockquote>\n\n"
|
||||||
|
f"<b>Вопросов:</b> {questions_count}\n"
|
||||||
|
f"{password_str}\n"
|
||||||
|
f"{attempts_str}"
|
||||||
|
)
|
||||||
|
|
||||||
|
return {"test_info": test_info, "can_start": True, "has_password": bool(test.password)}
|
||||||
|
|
||||||
|
|
||||||
|
@inject
|
||||||
|
async def on_start_deeplink_test(
|
||||||
|
_callback: CallbackQuery,
|
||||||
|
_button: Button,
|
||||||
|
manager: DialogManager,
|
||||||
|
test_dao: FromDishka[TestDAO],
|
||||||
|
test_repo: FromDishka[TestRepository],
|
||||||
|
attempt_repo: FromDishka[TestAttemptRepository],
|
||||||
|
):
|
||||||
|
start_data = manager.start_data or {}
|
||||||
|
test_id = start_data.get("test_id")
|
||||||
|
user_id = _callback.from_user.id
|
||||||
|
|
||||||
|
if not test_id:
|
||||||
|
await _callback.answer("❌ Тест не найден")
|
||||||
|
return
|
||||||
|
|
||||||
|
test = await test_dao.get_by_id(test_id)
|
||||||
|
if not test:
|
||||||
|
await _callback.answer("❌ Тест не найден")
|
||||||
|
return
|
||||||
|
|
||||||
|
if test.attempts:
|
||||||
|
attempts = await attempt_repo.get_user_test_attempts(user_id, test_id)
|
||||||
|
finished_attempts = [a for a in attempts if a.finished_at]
|
||||||
|
if len(finished_attempts) >= test.attempts:
|
||||||
|
await _callback.answer("❌ Вы исчерпали все попытки")
|
||||||
|
return
|
||||||
|
|
||||||
|
active_attempt = await attempt_repo.get_active_attempt(user_id, test_id)
|
||||||
|
if active_attempt:
|
||||||
|
await attempt_repo.attempt_dao.delete(active_attempt.id)
|
||||||
|
|
||||||
|
if test.password:
|
||||||
|
await manager.switch_to(UserDeeplinkSG.password_input)
|
||||||
|
else:
|
||||||
|
await start_test_without_password(manager, test_repo, attempt_repo, test_id, user_id)
|
||||||
|
|
||||||
|
|
||||||
|
async def start_test_without_password(
|
||||||
|
manager: DialogManager,
|
||||||
|
test_repo: TestRepository,
|
||||||
|
attempt_repo: TestAttemptRepository,
|
||||||
|
test_id: int,
|
||||||
|
user_id: int,
|
||||||
|
):
|
||||||
|
_, questions = await test_repo.get_test_with_questions(test_id)
|
||||||
|
|
||||||
|
if not questions:
|
||||||
|
return
|
||||||
|
|
||||||
|
attempt = await attempt_repo.attempt_dao.create(user_id=user_id, test_id=test_id)
|
||||||
|
|
||||||
|
first_question, _ = await test_repo.get_question_with_options(questions[0].id)
|
||||||
|
|
||||||
|
if first_question:
|
||||||
|
if first_question.question_type == QuestionType.SINGLE:
|
||||||
|
first_state = UserTestSG.question_single
|
||||||
|
elif first_question.question_type == QuestionType.MULTIPLE:
|
||||||
|
first_state = UserTestSG.question_multiple
|
||||||
|
else:
|
||||||
|
first_state = UserTestSG.question_input
|
||||||
|
else:
|
||||||
|
first_state = UserTestSG.question_single
|
||||||
|
|
||||||
|
await manager.start(
|
||||||
|
first_state,
|
||||||
|
mode=StartMode.RESET_STACK,
|
||||||
|
data={
|
||||||
|
"test_id": test_id,
|
||||||
|
"attempt_id": attempt.id,
|
||||||
|
"questions": [q.id for q in questions],
|
||||||
|
"current_question_index": 0,
|
||||||
|
"user_answers": {},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@inject
|
||||||
|
async def on_deeplink_password_input(
|
||||||
|
message: Message,
|
||||||
|
_widget: MessageInput,
|
||||||
|
manager: DialogManager,
|
||||||
|
test_dao: FromDishka[TestDAO],
|
||||||
|
test_repo: FromDishka[TestRepository],
|
||||||
|
attempt_repo: FromDishka[TestAttemptRepository],
|
||||||
|
):
|
||||||
|
start_data = manager.start_data or {}
|
||||||
|
test_id = start_data.get("test_id")
|
||||||
|
|
||||||
|
if not test_id:
|
||||||
|
await message.answer("❌ Тест не найден")
|
||||||
|
return
|
||||||
|
|
||||||
|
test = await test_dao.get_by_id(test_id)
|
||||||
|
|
||||||
|
if not test or not test.password:
|
||||||
|
await message.answer("❌ Ошибка проверки пароля")
|
||||||
|
return
|
||||||
|
|
||||||
|
if message.text and message.text.strip() == test.password:
|
||||||
|
await message.answer("✅ Пароль верный")
|
||||||
|
await start_test_without_password(
|
||||||
|
manager, test_repo, attempt_repo, test_id, message.from_user.id
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
await message.answer("❌ Неверный пароль")
|
||||||
|
|
||||||
|
|
||||||
|
async def on_back_to_menu(_callback: CallbackQuery, _button: Button, manager: DialogManager):
|
||||||
|
await manager.start(UserMenuSG.main, mode=StartMode.RESET_STACK)
|
||||||
|
|
||||||
|
|
||||||
|
deeplink_dialog = Dialog(
|
||||||
|
Window(
|
||||||
|
Format("{test_info}"),
|
||||||
|
Button(
|
||||||
|
Const("▶️ Пройти тест"),
|
||||||
|
id="start_test",
|
||||||
|
on_click=on_start_deeplink_test,
|
||||||
|
when="can_start"
|
||||||
|
),
|
||||||
|
Button(Const("◀️ В главное меню"), id="back", on_click=on_back_to_menu),
|
||||||
|
state=UserDeeplinkSG.test_preview,
|
||||||
|
getter=get_deeplink_test_data,
|
||||||
|
),
|
||||||
|
Window(
|
||||||
|
Const("<b>🔑 Введите пароль для доступа к тесту:</b>"),
|
||||||
|
MessageInput(on_deeplink_password_input),
|
||||||
|
Button(Const("◀️ Назад"), id="back", on_click=on_back_to_menu),
|
||||||
|
state=UserDeeplinkSG.password_input,
|
||||||
|
),
|
||||||
|
)
|
||||||
@@ -6,8 +6,11 @@ from aiogram_dialog.widgets.text import Const, Format
|
|||||||
from dishka import FromDishka
|
from dishka import FromDishka
|
||||||
from dishka.integrations.aiogram_dialog import inject
|
from dishka.integrations.aiogram_dialog import inject
|
||||||
|
|
||||||
from trudex.application.bot.user_dialogs.states import (UserMenuSG,
|
from trudex.application.bot.user_dialogs.states import (
|
||||||
UserRegistrationSG)
|
UserDeeplinkSG,
|
||||||
|
UserMenuSG,
|
||||||
|
UserRegistrationSG,
|
||||||
|
)
|
||||||
from trudex.infrastructure.database.dao.group import GroupDAO
|
from trudex.infrastructure.database.dao.group import GroupDAO
|
||||||
from trudex.infrastructure.database.dao.user import UserDAO
|
from trudex.infrastructure.database.dao.user import UserDAO
|
||||||
|
|
||||||
@@ -27,7 +30,8 @@ async def on_name_input(message: Message, _widget: MessageInput, manager: Dialog
|
|||||||
await message.answer("❌ Имя и фамилия слишком длинные (максимум 128 символов)")
|
await message.answer("❌ Имя и фамилия слишком длинные (максимум 128 символов)")
|
||||||
return
|
return
|
||||||
|
|
||||||
user_id = manager.start_data.get("user_id")
|
start_data = manager.start_data or {}
|
||||||
|
user_id = start_data.get("user_id")
|
||||||
await user_dao.update(user_id=user_id, name=name)
|
await user_dao.update(user_id=user_id, name=name)
|
||||||
|
|
||||||
manager.dialog_data["name"] = name
|
manager.dialog_data["name"] = name
|
||||||
@@ -35,7 +39,7 @@ async def on_name_input(message: Message, _widget: MessageInput, manager: Dialog
|
|||||||
|
|
||||||
|
|
||||||
@inject
|
@inject
|
||||||
async def get_groups_for_registration(dialog_manager: DialogManager, group_dao: FromDishka[GroupDAO], **_kwargs):
|
async def get_groups_for_registration(group_dao: FromDishka[GroupDAO], **_kwargs):
|
||||||
groups = await group_dao.get_all()
|
groups = await group_dao.get_all()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -45,8 +49,19 @@ async def get_groups_for_registration(dialog_manager: DialogManager, group_dao:
|
|||||||
|
|
||||||
@inject
|
@inject
|
||||||
async def on_group_selected(_callback: CallbackQuery, _widget, manager: DialogManager, item_id: str, user_dao: FromDishka[UserDAO]):
|
async def on_group_selected(_callback: CallbackQuery, _widget, manager: DialogManager, item_id: str, user_dao: FromDishka[UserDAO]):
|
||||||
user_id = manager.start_data.get("user_id")
|
start_data = manager.start_data or {}
|
||||||
|
user_id = start_data.get("user_id")
|
||||||
|
pending_test_id = start_data.get("pending_test_id")
|
||||||
|
|
||||||
await user_dao.update(user_id=user_id, group=int(item_id))
|
await user_dao.update(user_id=user_id, group=int(item_id))
|
||||||
|
|
||||||
|
if pending_test_id:
|
||||||
|
await manager.start(
|
||||||
|
UserDeeplinkSG.test_preview,
|
||||||
|
mode=StartMode.RESET_STACK,
|
||||||
|
data={"test_id": pending_test_id}
|
||||||
|
)
|
||||||
|
else:
|
||||||
await manager.start(UserMenuSG.main, mode=StartMode.RESET_STACK)
|
await manager.start(UserMenuSG.main, mode=StartMode.RESET_STACK)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,11 @@ class UserTestSG(StatesGroup):
|
|||||||
detailed_results = State()
|
detailed_results = State()
|
||||||
|
|
||||||
|
|
||||||
|
class UserDeeplinkSG(StatesGroup):
|
||||||
|
test_preview = State()
|
||||||
|
password_input = State()
|
||||||
|
|
||||||
|
|
||||||
class UserRegistrationSG(StatesGroup):
|
class UserRegistrationSG(StatesGroup):
|
||||||
input_name = State()
|
input_name = State()
|
||||||
select_group = State()
|
select_group = State()
|
||||||
|
|||||||
Reference in New Issue
Block a user