This commit is contained in:
2026-01-04 01:20:00 +03:00
parent ad8eb5b5ee
commit 05dd721f60
10 changed files with 23 additions and 19 deletions
@@ -22,7 +22,7 @@ from trudex.infrastructure.database.repo.test_attempt import TestAttemptReposito
from trudex.infrastructure.utils.config import Config from trudex.infrastructure.utils.config import Config
from trudex.infrastructure.utils.qr_generator import generate_qr_bytes from trudex.infrastructure.utils.qr_generator import generate_qr_bytes
from trudex.infrastructure.utils.test_id_to_hash import encode_id from trudex.infrastructure.utils.test_id_to_hash import encode_id
from trudex.infrastructure.utils.timezone import MSK_TZ, to_msk from trudex.infrastructure.utils.timezone import to_msk
@inject @inject
@@ -379,7 +379,7 @@ async def on_date_selected_for_test(_callback, _widget, manager: DialogManager,
await _callback.answer("❌ Тест не найден") await _callback.answer("❌ Тест не найден")
return return
expires_at = datetime.combine(selected_date, time.min, tzinfo=MSK_TZ) expires_at = datetime.combine(selected_date, time.min)
await test_dao.update(test_id, expires_at=expires_at) await test_dao.update(test_id, expires_at=expires_at)
await _callback.answer("✅ Срок действия обновлен") await _callback.answer("✅ Срок действия обновлен")
await manager.switch_to(AdminTestsSG.test_detail) await manager.switch_to(AdminTestsSG.test_detail)
@@ -16,7 +16,7 @@ from trudex.infrastructure.database.dao.option import OptionDAO
from trudex.infrastructure.database.dao.question import QuestionDAO from trudex.infrastructure.database.dao.question import QuestionDAO
from trudex.infrastructure.database.dao.test import TestDAO from trudex.infrastructure.database.dao.test import TestDAO
from trudex.infrastructure.database.repo.test import TestRepository from trudex.infrastructure.database.repo.test import TestRepository
from trudex.infrastructure.utils.timezone import MSK_TZ, to_msk from trudex.infrastructure.utils.timezone import to_msk
async def on_title_input(message: Message, _widget: MessageInput, manager: DialogManager): async def on_title_input(message: Message, _widget: MessageInput, manager: DialogManager):
@@ -111,7 +111,7 @@ async def on_skip_attempts(_callback: CallbackQuery, _button: Button, manager: D
async def on_date_selected(_callback, _widget, manager: DialogManager, selected_date: date): async def on_date_selected(_callback, _widget, manager: DialogManager, selected_date: date):
manager.dialog_data["expires_at"] = datetime.combine(selected_date, time.min, tzinfo=MSK_TZ) manager.dialog_data["expires_at"] = datetime.combine(selected_date, time.min)
await manager.switch_to(CreateTestSG.input_for_group) await manager.switch_to(CreateTestSG.input_for_group)
@@ -537,7 +537,7 @@ create_test_dialog = Dialog(
getter=get_question_type_data, getter=get_question_type_data,
), ),
Window( Window(
Const("<b>✏️ Правильный ответ</b>\n\n💬 <b>Введите правильный ответ</b> (для проверки будет использоваться точное совпадение):\n<i>(максимум 255 символов)</i>"), Const("<b>✏️ Правильный ответ</b>\n\n💬 <b>Введите правильный ответ</b> (регистр и пробелы игнорируются):\n<i>(максимум 255 символов)</i>"),
MessageInput(on_correct_answer_input), MessageInput(on_correct_answer_input),
Button(Const("◀️ Назад"), id="back", on_click=on_cancel_question), Button(Const("◀️ Назад"), id="back", on_click=on_cancel_question),
state=CreateTestSG.input_correct_answer, state=CreateTestSG.input_correct_answer,
@@ -25,7 +25,7 @@ from trudex.infrastructure.database.repo.test_attempt import TestAttemptReposito
from trudex.infrastructure.utils.config import Config from trudex.infrastructure.utils.config import Config
from trudex.infrastructure.utils.qr_generator import generate_qr_bytes from trudex.infrastructure.utils.qr_generator import generate_qr_bytes
from trudex.infrastructure.utils.test_id_to_hash import encode_id from trudex.infrastructure.utils.test_id_to_hash import encode_id
from trudex.infrastructure.utils.timezone import MSK_TZ, to_msk from trudex.infrastructure.utils.timezone import to_msk
@inject @inject
@@ -383,7 +383,7 @@ async def on_date_selected_for_test(_callback, _widget, manager: DialogManager,
await _callback.answer("❌ Тест не найден") await _callback.answer("❌ Тест не найден")
return return
expires_at = datetime.combine(selected_date, time.min, tzinfo=MSK_TZ) expires_at = datetime.combine(selected_date, time.min)
await test_dao.update(test_id, expires_at=expires_at) await test_dao.update(test_id, expires_at=expires_at)
await _callback.answer("✅ Срок действия обновлен") await _callback.answer("✅ Срок действия обновлен")
await manager.switch_to(CreatorTestsSG.test_detail) await manager.switch_to(CreatorTestsSG.test_detail)
+2 -2
View File
@@ -17,7 +17,7 @@ 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.config import Config
from trudex.infrastructure.utils.test_id_to_hash import decode_id from trudex.infrastructure.utils.test_id_to_hash import decode_id
from trudex.infrastructure.utils.timezone import now_msk from trudex.infrastructure.utils.timezone import now_msk_naive
router = Router() router = Router()
@@ -92,7 +92,7 @@ async def validate_deeplink_test(
if not test.is_active: if not test.is_active:
return False, "❌ Тест деактивирован" return False, "❌ Тест деактивирован"
if test.expires_at and test.expires_at < now_msk(): if test.expires_at and test.expires_at < now_msk_naive():
return False, "❌ Срок действия теста истек" return False, "❌ Срок действия теста истек"
user = await user_dao.get_by_id(user_id) user = await user_dao.get_by_id(user_id)
@@ -20,7 +20,7 @@ from trudex.infrastructure.database.repo.test_attempt import TestAttemptReposito
from trudex.infrastructure.utils.config import Config from trudex.infrastructure.utils.config import Config
from trudex.infrastructure.utils.qr_generator import generate_qr_bytes from trudex.infrastructure.utils.qr_generator import generate_qr_bytes
from trudex.infrastructure.utils.test_id_to_hash import encode_id from trudex.infrastructure.utils.test_id_to_hash import encode_id
from trudex.infrastructure.utils.timezone import now_msk, to_msk from trudex.infrastructure.utils.timezone import now_msk, now_msk_naive, to_msk
from datetime import datetime from datetime import datetime
@@ -150,7 +150,7 @@ async def on_name_input(
result = await user_dao.update( result = await user_dao.update(
user_id=message.from_user.id, user_id=message.from_user.id,
name=name, name=name,
name_updated_at=now_msk(), name_updated_at=now_msk_naive(),
) )
if result: if result:
await message.answer("✅ Имя обновлено") await message.answer("✅ Имя обновлено")
@@ -177,7 +177,7 @@ async def on_group_selected(
result = await user_dao.update( result = await user_dao.update(
user_id=_callback.from_user.id, user_id=_callback.from_user.id,
group=int(item_id), group=int(item_id),
group_updated_at=now_msk(), group_updated_at=now_msk_naive(),
) )
if result: if result:
await _callback.answer("✅ Группа обновлена") await _callback.answer("✅ Группа обновлена")
@@ -12,7 +12,7 @@ from trudex.infrastructure.database.dao.user_answer import UserAnswerDAO
from trudex.infrastructure.database.models import QuestionType from trudex.infrastructure.database.models import QuestionType
from trudex.infrastructure.database.repo.test import TestRepository from trudex.infrastructure.database.repo.test import TestRepository
from trudex.infrastructure.database.repo.test_attempt import TestAttemptRepository from trudex.infrastructure.database.repo.test_attempt import TestAttemptRepository
from trudex.infrastructure.utils.timezone import now_msk from trudex.infrastructure.utils.timezone import now_msk_naive
async def get_state_for_question_type(question_type: str): async def get_state_for_question_type(question_type: str):
@@ -50,7 +50,7 @@ async def on_start_test(
await _callback.answer("❌ Тест деактивирован") await _callback.answer("❌ Тест деактивирован")
return return
if test.expires_at and test.expires_at < now_msk(): if test.expires_at and test.expires_at < now_msk_naive():
await _callback.answer("❌ Срок действия теста истек") await _callback.answer("❌ Срок действия теста истек")
return return
@@ -1 +0,0 @@
@@ -12,7 +12,7 @@ from trudex.infrastructure.database.dto.user_answer import UserAnswerDTO
from trudex.infrastructure.database.models import \ from trudex.infrastructure.database.models import \
TestAttempt as TestAttemptModel TestAttempt as TestAttemptModel
from trudex.infrastructure.database.models import UserAnswer as UserAnswerModel from trudex.infrastructure.database.models import UserAnswer as UserAnswerModel
from trudex.infrastructure.utils.timezone import now_msk from trudex.infrastructure.utils.timezone import now_msk_naive
@final @final
@@ -132,7 +132,7 @@ class TestAttemptRepository:
async def finish_attempt(self, attempt_id: int, score: int, is_passed: bool) -> TestAttempt | None: async def finish_attempt(self, attempt_id: int, score: int, is_passed: bool) -> TestAttempt | None:
return await self.attempt_dao.update( return await self.attempt_dao.update(
attempt_id=attempt_id, attempt_id=attempt_id,
finished_at=now_msk(), finished_at=now_msk_naive(),
score=score, score=score,
is_passed=is_passed is_passed=is_passed
) )
@@ -1,7 +1,7 @@
from dishka import AsyncContainer from dishka import AsyncContainer
from trudex.infrastructure.database.dao.test import TestDAO from trudex.infrastructure.database.dao.test import TestDAO
from trudex.infrastructure.utils.timezone import now_msk from trudex.infrastructure.utils.timezone import now_msk_naive
async def deactivate_expired_tests(container: AsyncContainer): async def deactivate_expired_tests(container: AsyncContainer):
@@ -11,5 +11,5 @@ async def deactivate_expired_tests(container: AsyncContainer):
tests = await test_dao.get_all() tests = await test_dao.get_all()
for test in tests: for test in tests:
if test.expires_at and test.expires_at < now_msk() and test.is_active: if test.expires_at and test.expires_at < now_msk_naive() and test.is_active:
await test_dao.update(test.id, is_active=False) await test_dao.update(test.id, is_active=False)
@@ -8,6 +8,11 @@ def now_msk() -> datetime:
return datetime.now(MSK_TZ) return datetime.now(MSK_TZ)
def now_msk_naive() -> datetime:
"""Возвращает текущее время в МСК без timezone info (для сохранения в БД)."""
return datetime.now(MSK_TZ).replace(tzinfo=None)
def to_msk(dt: datetime | None) -> datetime | None: def to_msk(dt: datetime | None) -> datetime | None:
if dt is None: if dt is None:
return None return None