From 45fc51397d92c2ec72a48b7bf2c6446434419683 Mon Sep 17 00:00:00 2001 From: kitiketov Date: Sat, 13 Dec 2025 13:10:59 +0500 Subject: [PATCH 1/2] =?UTF-8?q?-=20=D0=B0=D0=B4=D0=BC=D0=B8=D0=BD=20=D0=B8?= =?UTF-8?q?=D0=B7=D0=BD=D0=B0=D1=87=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=20=D0=BD?= =?UTF-8?q?=D0=B5=20=D1=83=D1=87=D0=B0=D1=81=D1=82=D0=BD=D0=B8=D0=BA=20?= =?UTF-8?q?=D0=B1=D0=BE=D0=BB=D0=B5=D0=B5=20=D0=BE=D1=87=D0=B5=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/handlers/room_admin.py | 149 +++++++++++++++++++++++++++++---- src/keyboards/room_admin_kb.py | 34 ++++++++ src/texts/callback_actions.py | 2 + src/texts/messages.py | 7 ++ 4 files changed, 174 insertions(+), 18 deletions(-) diff --git a/src/handlers/room_admin.py b/src/handlers/room_admin.py index 7d24720..1a1d1c5 100644 --- a/src/handlers/room_admin.py +++ b/src/handlers/room_admin.py @@ -20,6 +20,47 @@ async def get_room_name(room_iden): router = Router(name=__name__) +async def _perform_start_event(call, room_iden, room_name: str, include_admin: bool): + status = await db.isStarted(room_iden) + if status: + await call.message.edit_text( + messages.event_already_started(room_name), + reply_markup=await room_admin_kb.room_admin_kb(room_iden), + ) + return + + members, admin, isAdminMember = await db.get_members_list(room_iden) + if isAdminMember: + members.append(admin) + elif include_admin: + members.append(admin) + + members = [member[0] for member in members] + if len(members) < 2: + await call.message.edit_text( + messages.event_not_enough_members(room_name), + reply_markup=await room_admin_kb.room_admin_kb(room_iden), + ) + return + + await db.start_event(room_iden) + pairs = utils.randomize_members(members) + await db.write_pairs(pairs, room_iden) + await call.message.edit_text( + messages.event_started(room_name), + reply_markup=await room_admin_kb.room_admin_kb(room_iden), + ) + await notification.broadcast( + call.bot, + members, + text=messages.event_started_notify(room_name), + reply_markup=await common_kb.ok_kb("None", asAdmin=False), + delay=RATE_LIMIT_DELAY, + message_effect_id=EFFECT_IDS["🎉"], + ) + await call.answer("Уведомление о начале события отправлено") + + @router.callback_query(CallbackFactory.filter(F.action == CallbackAction.DELETE_ROOM)) async def delete_room( call: CallbackQuery, callback_data: CallbackFactory, state: FSMContext @@ -124,6 +165,21 @@ async def start_event( ) return + room_admin_id = await db.get_room_admin(callback_data.room_iden) + if room_admin_id != call.from_user.id: + await call.message.edit_text( + messages.not_a_member(room_name), + reply_markup=await common_kb.ok_kb("None", asAdmin=False), + ) + return + + if isMemberOrAdmin == "MEMBER NOT EXISTS": + await call.message.edit_text( + messages.not_a_member(room_name), + reply_markup=await common_kb.ok_kb("None", asAdmin=False), + ) + return + status = await db.isStarted(callback_data.room_iden) if status: await call.message.edit_text( @@ -133,31 +189,88 @@ async def start_event( return members, admin, isAdminMember = await db.get_members_list(callback_data.room_iden) - if isAdminMember: - members.append(admin) + if isMemberOrAdmin == "IS ADMIN" and not isAdminMember: + kb = await room_admin_kb.start_event_confirm_kb(callback_data.room_iden) + await call.message.edit_text( + messages.admin_not_member_start(room_name), + reply_markup=kb, + ) + return - members = [member[0] for member in members] - if len(members) < 2: + await _perform_start_event( + call, + callback_data.room_iden, + room_name, + include_admin=isAdminMember, + ) + + +@router.callback_query( + CallbackFactory.filter(F.action == CallbackAction.START_EVENT_JOIN_ADMIN) +) +async def start_event_join_admin( + call: CallbackQuery, callback_data: CallbackFactory, state: FSMContext +): + room_name = await get_room_name(callback_data.room_iden) + room_admin_id = await db.get_room_admin(callback_data.room_iden) + if room_admin_id != call.from_user.id: await call.message.edit_text( - messages.event_not_enough_members(room_name), + messages.not_a_member(room_name), + reply_markup=await common_kb.ok_kb("None", asAdmin=False), + ) + return + + status = await db.isStarted(callback_data.room_iden) + if status: + await call.message.edit_text( + messages.event_already_started(room_name), reply_markup=await room_admin_kb.room_admin_kb(callback_data.room_iden), ) return - await db.start_event(callback_data.room_iden) - pairs = utils.randomize_members(members) - await db.write_pairs(pairs, callback_data.room_iden) - await call.message.edit_text( - messages.event_started(room_name), - reply_markup=await room_admin_kb.room_admin_kb(callback_data.room_iden), + join_status = await db.connect2room(room_name, call.from_user.id) + if join_status == "room_error": + await call.message.edit_text( + messages.room_not_exists(room_name), + reply_markup=await common_kb.ok_kb("None", asAdmin=False), + ) + return + if join_status == "joined late": + await call.message.edit_text( + messages.event_already_started(room_name), + reply_markup=await room_admin_kb.room_admin_kb(callback_data.room_iden), + ) + return + + await _perform_start_event( + call, + callback_data.room_iden, + room_name, + include_admin=True, + ) + + +@router.callback_query( + CallbackFactory.filter(F.action == CallbackAction.START_EVENT_SKIP_ADMIN) +) +async def start_event_skip_admin( + call: CallbackQuery, callback_data: CallbackFactory, state: FSMContext +): + room_name = await get_room_name(callback_data.room_iden) + room_admin_id = await db.get_room_admin(callback_data.room_iden) + if room_admin_id != call.from_user.id: + await call.message.edit_text( + messages.not_a_member(room_name), + reply_markup=await common_kb.ok_kb("None", asAdmin=False), + ) + return + + await _perform_start_event( + call, + callback_data.room_iden, + room_name, + include_admin=False, ) - await notification.broadcast(call.bot, members, - text=messages.event_started_notify(room_name), - reply_markup=await common_kb.ok_kb("None", asAdmin=False), - delay=RATE_LIMIT_DELAY, - message_effect_id=EFFECT_IDS["🎉"] - ) - await call.answer("Уведомление о начале события отправлено") @router.callback_query(CallbackFactory.filter(F.action == CallbackAction.REMIND_ABOUT_EVENT)) diff --git a/src/keyboards/room_admin_kb.py b/src/keyboards/room_admin_kb.py index a98dce7..c6bb685 100644 --- a/src/keyboards/room_admin_kb.py +++ b/src/keyboards/room_admin_kb.py @@ -105,6 +105,40 @@ async def room_admin_kb(room_iden): return InlineKeyboardMarkup(inline_keyboard=room_kb) +async def start_event_confirm_kb(room_iden): + kb = [ + [ + InlineKeyboardButton( + text="👥Добавить меня и начать", + callback_data=states.CallbackFactory( + action=CallbackAction.START_EVENT_JOIN_ADMIN, + room_iden=room_iden, + asAdmin=True, + ).pack(), + ) + ], + [ + InlineKeyboardButton( + text="▶️Начать без меня", + callback_data=states.CallbackFactory( + action=CallbackAction.START_EVENT_SKIP_ADMIN, + room_iden=room_iden, + asAdmin=True, + ).pack(), + ) + ], + [ + InlineKeyboardButton( + text="🚫Отмена", + callback_data=states.CallbackFactory( + action=CallbackAction.CANCEL, room_iden=room_iden, asAdmin=True + ).pack(), + ) + ], + ] + return InlineKeyboardMarkup(inline_keyboard=kb) + + async def confirm_kb(room_iden, asAdmin): confirm_kb = [ [ diff --git a/src/texts/callback_actions.py b/src/texts/callback_actions.py index 7f8c995..fc54da3 100644 --- a/src/texts/callback_actions.py +++ b/src/texts/callback_actions.py @@ -23,6 +23,8 @@ class CallbackAction: CUSTOM_INVITATION = "custom_invitation" START_EVENT = "start_event" + START_EVENT_JOIN_ADMIN = "start_event_join_admin" + START_EVENT_SKIP_ADMIN = "start_event_skip_admin" DELETE_ROOM = "delete_room" CONFIRM_DELETE = "confirm_delete" REMOVE_MEMBER = "remove_member" diff --git a/src/texts/messages.py b/src/texts/messages.py index f999ae8..637ac06 100644 --- a/src/texts/messages.py +++ b/src/texts/messages.py @@ -48,6 +48,13 @@ def event_not_started(room_name: str) -> str: return f"Событие в комнате {room_name} ещё не началось " +def admin_not_member_start(room_name: str) -> str: + return ( + f"Вы пока не участник комнаты {room_name}.\n" + "Добавить себя и участвовать в обмене или начать без вас?" + ) + + def event_started_before_join(room_name: str) -> str: return ( f"Событие в комнате {room_name} началось раньше вашего присоединения\n" From 1b248110740b135fb11dc453cf3a1ac323a0683b Mon Sep 17 00:00:00 2001 From: kitiketov Date: Sat, 13 Dec 2025 13:44:41 +0500 Subject: [PATCH 2/2] =?UTF-8?q?-=20=D1=83=D0=B1=D1=80=D0=B0=D0=BD=D0=BE=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=BE=D0=B5=20=D1=83?= =?UTF-8?q?=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/handlers/common.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/handlers/common.py b/src/handlers/common.py index 0d797d6..84365f4 100644 --- a/src/handlers/common.py +++ b/src/handlers/common.py @@ -1,4 +1,5 @@ from aiogram import F, Router +from aiogram.exceptions import TelegramBadRequest from aiogram.fsm.context import FSMContext from aiogram.types import Message, CallbackQuery, ReactionTypeEmoji @@ -38,13 +39,24 @@ async def get_room_name(room_iden): router = Router(name=__name__) +async def _delete_message_if_exists(message: Message) -> None: + if not message: + return + + try: + await message.delete() + except TelegramBadRequest as exc: + if "message to delete not found" not in exc.message.lower(): + raise + + @router.callback_query(CallbackFactory.filter(F.action == CallbackAction.CANCEL)) async def cancel( call: CallbackQuery, callback_data: CallbackFactory, state: FSMContext ): if callback_data.room_iden == "None": await state.clear() - await call.message.delete() + await _delete_message_if_exists(call.message) @router.message(F.text == "◀️Вернуться в меню")