From a5a856064089fccba2267f421f608c5cf75edca8 Mon Sep 17 00:00:00 2001 From: Zakhar Izmaylov Date: Sat, 9 Nov 2024 15:49:05 +0300 Subject: [PATCH] Refactoring notifications.py and commands.py --- handlers/commands.py | 146 ++++++++++++++++++-------------------- handlers/notifications.py | 28 +++++--- 2 files changed, 88 insertions(+), 86 deletions(-) diff --git a/handlers/commands.py b/handlers/commands.py index e656a1bb..c4715fbb 100644 --- a/handlers/commands.py +++ b/handlers/commands.py @@ -29,16 +29,13 @@ class Form(StatesGroup): @router.message(Command("backup")) -async def backup_command(message: Message): - if message.from_user.id != ADMIN_ID: - await message.answer("У вас нет прав для выполнения этой команды.") - return +async def backup_command(message: Message, is_admin: bool): + if is_admin: + from backup import backup_database - from backup import backup_database - - await message.answer("Запускаю бэкап базы данных...") - await backup_database() - await message.answer("Бэкап завершен и отправлен админу.") + await message.answer("Запускаю бэкап базы данных...") + await backup_database() + await message.answer("Бэкап завершен и отправлен админу.") @router.message(Command("start")) @@ -57,89 +54,88 @@ async def handle_menu(message: types.Message, state: FSMContext): @router.message(Command("send_trial")) -async def handle_send_trial_command(message: types.Message, state: FSMContext): - # Проверка на администратора - if message.from_user.id != ADMIN_ID: - await message.reply("У вас нет доступа к этой команде.") - return - - try: - conn = await asyncpg.connect(DATABASE_URL) +async def handle_send_trial_command( + message: types.Message, state: FSMContext, is_admin: bool +): + if is_admin: try: - records = await conn.fetch( + conn = await asyncpg.connect(DATABASE_URL) + try: + records = await conn.fetch( + """ + SELECT tg_id FROM connections WHERE trial = 0 """ - SELECT tg_id FROM connections WHERE trial = 0 - """ - ) - - if records: - for record in records: - tg_id = record["tg_id"] - trial_message = TRIAL - try: - await bot.send_message(chat_id=tg_id, text=trial_message) - except Exception as e: - if "Forbidden: bot was blocked by the user" in str(e): - logger.info( - f"Бот заблокирован пользователем с tg_id: {tg_id}" - ) - else: - logger.error( - f"Ошибка при отправке сообщения пользователю {tg_id}: {e}" - ) - - await message.answer( - "Сообщения о пробном периоде отправлены всем пользователям с не использованным ключом." - ) - else: - await message.answer( - "Нет пользователей с не использованными пробными ключами." ) - finally: - await conn.close() + if records: + for record in records: + tg_id = record["tg_id"] + trial_message = TRIAL + try: + await bot.send_message(chat_id=tg_id, text=trial_message) + except Exception as e: + if "Forbidden: bot was blocked by the user" in str(e): + logger.info( + f"Бот заблокирован пользователем с tg_id: {tg_id}" + ) + else: + logger.error( + f"Ошибка при отправке сообщения пользователю {tg_id}: {e}" + ) - except Exception as e: - await message.answer(f"Ошибка при отправке сообщений: {e}") + await message.answer( + "Сообщения о пробном периоде отправлены всем пользователям с не использованным ключом." + ) + else: + await message.answer( + "Нет пользователей с не использованными пробными ключами." + ) + + finally: + await conn.close() + + except Exception as e: + await message.answer(f"Ошибка при отправке сообщений: {e}") @router.message(Command("send_to_all")) async def send_message_to_all_clients( - message: types.Message, state: FSMContext, from_panel=False + message: types.Message, state: FSMContext, is_admin: bool, from_panel=False ): - if not from_panel and message.from_user.id != ADMIN_ID: - await message.answer("У вас нет прав для выполнения этой команды.") - return + if from_panel and is_admin: - await message.answer( - "Введите текст сообщения, который вы хотите отправить всем клиентам:" - ) - await state.set_state(Form.waiting_for_message) + await message.answer( + "Введите текст сообщения, который вы хотите отправить всем клиентам:" + ) + await state.set_state(Form.waiting_for_message) @router.message(Form.waiting_for_message) -async def process_message_to_all(message: types.Message, state: FSMContext): - text_message = message.text +async def process_message_to_all( + message: types.Message, state: FSMContext, is_admin: bool +): + if is_admin: + text_message = message.text - try: - conn = await asyncpg.connect(DATABASE_URL) - tg_ids = await conn.fetch("SELECT tg_id FROM connections") + try: + conn = await asyncpg.connect(DATABASE_URL) + tg_ids = await conn.fetch("SELECT tg_id FROM connections") - for record in tg_ids: - tg_id = record["tg_id"] - try: - await bot.send_message(chat_id=tg_id, text=text_message) - except Exception as e: - logger.error( - f"Ошибка при отправке сообщения пользователю {tg_id}: {e}. Пропускаем этого пользователя." - ) + for record in tg_ids: + tg_id = record["tg_id"] + try: + await bot.send_message(chat_id=tg_id, text=text_message) + except Exception as e: + logger.error( + f"Ошибка при отправке сообщения пользователю {tg_id}: {e}. Пропускаем этого пользователя." + ) - await message.answer("Сообщение было отправлено всем клиентам.") - except Exception as e: - logger.error(f"Ошибка при подключении к базе данных: {e}") - await message.answer("Произошла ошибка при отправке сообщения.") - finally: - await conn.close() + await message.answer("Сообщение было отправлено всем клиентам.") + except Exception as e: + logger.error(f"Ошибка при подключении к базе данных: {e}") + await message.answer("Произошла ошибка при отправке сообщения.") + finally: + await conn.close() await state.clear() diff --git a/handlers/notifications.py b/handlers/notifications.py index b5401556..bdc594c1 100644 --- a/handlers/notifications.py +++ b/handlers/notifications.py @@ -21,10 +21,6 @@ from handlers.texts import ( router = Router() -class NotificationStates(StatesGroup): - waiting_for_notification_text = State() - - async def notify_expiring_keys(bot: Bot): conn = None try: @@ -39,11 +35,13 @@ async def notify_expiring_keys(bot: Bot): logger.info("Начало обработки уведомлений.") - await notify_10h_keys(bot, conn, current_time, threshold_time_10h) - await asyncio.sleep(1) - await notify_24h_keys(bot, conn, current_time, threshold_time_24h) - await asyncio.sleep(1) - await handle_expired_keys(bot, conn, current_time) + notification_tasks = [ + notify_10h_keys(bot, conn, current_time, threshold_time_10h), + notify_24h_keys(bot, conn, current_time, threshold_time_24h), + handle_expired_keys(bot, conn, current_time), + ] + + await asyncio.gather(*notification_tasks) except Exception as e: logger.error(f"Ошибка при отправке уведомлений: {e}") @@ -55,10 +53,18 @@ async def notify_expiring_keys(bot: Bot): async def is_bot_blocked(bot: Bot, chat_id: int) -> bool: try: + # Проверка статуса бота в чате с пользователем member = await bot.get_chat_member(chat_id, bot.id) - return member.status == "left" + blocked = member.status == "left" + logger.info( + f"Статус бота для пользователя {chat_id}: {'заблокирован' if blocked else 'активен'}" + ) + return blocked except Exception as e: - logger.error(f"Ошибка при проверке статуса бота у пользователя {chat_id}: {e}") + # Обработка ошибок при проверке статуса + logger.warning( + f"Не удалось проверить статус бота для пользователя {chat_id}: {e}" + ) return False