From 853bfcdbb480af3cba01f0d6f88d2c0d75f43bed Mon Sep 17 00:00:00 2001 From: Muzifs Date: Mon, 28 Jul 2025 21:03:28 +0300 Subject: [PATCH] added utils.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Добавил message_thread_id для всех команд, убрав костыль, который отвечал за корректную отправку сообщений в топик. 2. Функции (определение администратора, удаление сообщений) вынес в utils.py, от куда они будут вызываться в командах. Модули стали более читаемы из-за уменьшения количества строк кода в них. 3. Дописал manual_unban и добавил error в config.py 4. Оптимизация --- src/config.py | 7 +- src/modules/ban.py | 234 ++++++++++++++-------------- src/modules/help.py | 38 +++-- src/modules/mute.py | 343 ++++++++++++++++++------------------------ src/modules/start.py | 38 +++-- src/modules/unban.py | 176 ++++++++++++---------- src/modules/unmute.py | 171 ++++++++++++--------- src/utils.py | 177 ++++++++++++++++++++++ 8 files changed, 692 insertions(+), 492 deletions(-) create mode 100644 src/utils.py diff --git a/src/config.py b/src/config.py index 046c895..d7be4b7 100644 --- a/src/config.py +++ b/src/config.py @@ -68,9 +68,11 @@ COMMAND_MESSAGES = { "✅ Команда /unban\n\n" "Снимает бан с пользователя\n\n" "🎯 Способы использования:\n" - "1. По тегу пользователя:\n" + "1. Ответ на сообщение:\n" + " /unban\n" + "2. По тегу пользователя:\n" " /unban @username\n" - "2. По ID пользователя:\n" + "3. По ID пользователя:\n" " /unban 123456789\n\n" "⚠️ Работает только для забаненных через /ban\n" "ℹ️ Пользователь сможет снова присоединиться" @@ -87,6 +89,7 @@ COMMAND_MESSAGES = { 'unmuted': '✅ Пользователь размучен.', 'banned': '✅ Пользователь успешно забанен.', 'unbanned': '✅ Пользователь успешно разбанен.', + 'error': '⚠️ Ошибка: {e}', 'general_error': '⚠️ Произошла непредвиденная ошибка.' } \ No newline at end of file diff --git a/src/modules/ban.py b/src/modules/ban.py index d6d51e1..5e0bfee 100644 --- a/src/modules/ban.py +++ b/src/modules/ban.py @@ -5,27 +5,16 @@ import logging from database import db from action_reporter import action_reporter +from utils import ( + delete_messages, + check_admin_status, + check_target_status, +) from config import COMMAND_MESSAGES logger = logging.getLogger(__name__) # Получаем логгер для текущего модуля -# Возвращает причину бана -def extract_reason(words: str) -> str: - - if words == []: - reason = 'отсутствует' - else: - reason = ' '.join(words) - - return reason - -# Удаляет два последних сообщения -async def delete_messages(bot: AsyncTeleBot, message: Message, time_sleep: int): - await asyncio.sleep(time_sleep) - await bot.delete_message(message.chat.id, message.message_id) - await bot.delete_message(message.chat.id, message.message_id+1) - # Регистрирует все обработчики команд def register_handlers(bot: AsyncTeleBot): @@ -37,10 +26,6 @@ def register_handlers(bot: AsyncTeleBot): # Основная функция команды /ban async def ban_command(bot: AsyncTeleBot, message: Message, photo_path: str = None): - # Отправка сообщения в тему или обычный чат - send_message = bot.reply_to if message.is_topic_message else bot.send_message - chat_id = message if message.is_topic_message else message.chat.id - # Определяем целевого пользователя target_user = None @@ -50,91 +35,81 @@ async def ban_command(bot: AsyncTeleBot, message: Message, photo_path: str = Non # Разбиваем текст сообщения на части parts_msg = message.text.split() - # Выводим помощь (/ban help) - if len(parts_msg) == 2 and parts_msg[1].strip() in ['help', 'помощь']: - await send_message(chat_id, COMMAND_MESSAGES['manual_ban']) + # Команда /ban help + if len(parts_msg) == 2 and parts_msg[1].strip() in ('help', 'помощь'): + + # Отправляем инструкцию + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['manual_ban'], + message_thread_id=message.message_thread_id, + ) # Удаляем сообщения через 30 секунд - await delete_messages(bot, message, 30) - + await delete_messages(bot, message, time_sleep=30, number_message=2) return try: + # Проверяем, является ли отправитель администратором - try: - admin_status = await bot.get_chat_member(message.chat.id, message.from_user.id) - - # Проверяем статус администратора (создателя) - if admin_status.status not in ['administrator', 'creator']: - await send_message(chat_id, COMMAND_MESSAGES['no_admin_rights']) - - # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) - - return - - # Проверяем право администратора на бан - if admin_status.status == 'administrator' and not admin_status.can_restrict_members: - await send_message(chat_id, COMMAND_MESSAGES['no_restrict_rights']) - - # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) - - return - - except Exception as e: - await send_message(chat_id, f"⚠️ Ошибка: {str(e)}") - logger.error(f"Ошибка при получении статуса администратора: {str(e)}") - - # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) - + if await check_admin_status(bot, message) == 1: return - # Если одно слово, то ответом на сообщение + # Команда через ответ на сообщение, если одно слово (/ban) if len(parts_msg) == 1: - # Если это тема + # Если это топик if message.is_topic_message: - # Если без ответа на сообщение, ошибка + # Если без ответа на сообщение if message.message_thread_id == message.reply_to_message.message_id: - await asyncio.sleep(3) - await bot.delete_message(message.chat.id, message.message_id) + + # Удаляем сообщение через 3 секунды + await delete_messages(bot, message, time_sleep=3, number_message=1) return # Если с ответом на сообщение else: - target_user = message.reply_to_message.from_user - reason = extract_reason(parts_msg[1:]) - # Если это обычный чат + # Собираем данные + target_user = message.reply_to_message.from_user + reason = 'отсутствует' + + # Если это General (обычный чат) elif message.reply_to_message and message.is_topic_message is None: + + # Собираем данные target_user = message.reply_to_message.from_user - reason = extract_reason(parts_msg[1:]) + reason = 'отсутствует' + message.message_thread_id = None - # Удаляем сообщение, если команда неправильная + # Если команда неправильная else: - await asyncio.sleep(3) - await bot.delete_message(message.chat.id, message.message_id) + + # Удаляем сообщение через 3 секунды + await delete_messages(bot, message, time_sleep=3, number_message=1) return + # В сообщении больше одного слова else: # Если второе слово это тег или ID if parts_msg[1].strip().isdigit() or parts_msg[1].startswith('@'): - - identifier = parts_msg[1].strip() - reason = extract_reason(parts_msg[2:]) - # Поиск по ID + # Собираем данные + identifier = parts_msg[1].strip() + reason = ' '.join(parts_msg[2:]) if parts_msg[2:] != [] else 'отсутствует' + + # Делаем поиск по ID if identifier.isdigit(): - # Делаем в int и ищем + # Ищем пользователя в базе данных user_info = db.get_user(int(identifier)) + # Если нашли пользователя if user_info: - # Создаем объект пользователя из данных базы + + # Создаем объект пользователя target_user = User( id=user_info[0], first_name=user_info[1], @@ -142,14 +117,16 @@ async def ban_command(bot: AsyncTeleBot, message: Message, photo_path: str = Non is_bot=False ) - # Поиск по тэгу + # Делаем поиск по тегу elif identifier.startswith('@'): - # Убираем @ и ищем + # Ищем пользователя в базе данных (убрали @) user_info = db.get_user_by_username(identifier[1:]) + # Если нашли пользователя if user_info: - # Создаем объект пользователя из данных базы + + # Создаем объект пользователя target_user = User( id=user_info[0], first_name=user_info[1], @@ -157,67 +134,66 @@ async def ban_command(bot: AsyncTeleBot, message: Message, photo_path: str = Non is_bot=False ) + # Команда через ответ на сообщение с указанием причины else: - # Если это тема + # Если это топик if message.is_topic_message: - # Если без ответа на сообщение, ошибка + # Если без ответа на сообщение if message.message_thread_id == message.reply_to_message.message_id: - await asyncio.sleep(3) - await bot.delete_message(message.chat.id, message.message_id) + + # Удаляем сообщение через 3 секунды + await delete_messages(bot, message, time_sleep=3, number_message=1) return # Если с ответом на сообщение else: - target_user = message.reply_to_message.from_user - reason = extract_reason(parts_msg[1:]) - # Если это обычный чат + # Собираем данные + target_user = message.reply_to_message.from_user + reason = ' '.join(parts_msg[1:]) + + # Если это General (обычный чат) elif message.reply_to_message and message.is_topic_message is None: + + # Собираем данные target_user = message.reply_to_message.from_user - reason = extract_reason(parts_msg[1:]) + reason = ' '.join(parts_msg[1:]) + message.message_thread_id = None - # Удаляем сообщение, если команда неправильная + # Если команда неправильная else: - await asyncio.sleep(3) - await bot.delete_message(message.chat.id, message.message_id) + + # Удаляем сообщение через 3 секунды + await delete_messages(bot, message, time_sleep=3, number_message=1) return - # Если пользователь не найден + # Если пользователь не найден в базе данных if not target_user: - await send_message(chat_id, COMMAND_MESSAGES['user_not_found']) + + # Отправляем предупреждение + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['user_not_found'], + message_thread_id=message.message_thread_id, + ) # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) - + await delete_messages(bot, message, time_sleep=5, number_message=2) return # Проверяем статус целевого пользователя - try: - target_status = await bot.get_chat_member(message.chat.id, target_user.id) - - # Проверяем, является ли цель администратором или создателем - if target_status.status in ['administrator', 'creator']: - await send_message(chat_id, COMMAND_MESSAGES['cant_ban_admin']) - - # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) - - return - - except Exception as e: - await send_message(chat_id, f"⚠️ Ошибка: {str(e)}") - logger.error(f"Ошибка при получении статуса пользователя: {str(e)}") - - # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) - + if await check_target_status(bot, message, target_user) == 1: return - # Выполняем бан try: - await bot.ban_chat_member(message.chat.id, target_user.id) + + # Выполняем бан + await bot.ban_chat_member( + chat_id=message.chat.id, + user_id=target_user.id, + ) # Отправляем лог в админ-чат await action_reporter.log_action( @@ -226,28 +202,48 @@ async def ban_command(bot: AsyncTeleBot, message: Message, photo_path: str = Non admin_id=message.from_user.id, reason=reason, duration=None, - photo_path=photo_path + photo_path=photo_path, ) # Отправляем сообщения, что пользователь получил бан - await send_message(chat_id, COMMAND_MESSAGES['banned']) + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['banned'], + message_thread_id=message.message_thread_id, + ) + + # Записываем действие в логи logger.info(f"Пользователь {target_user.id} забанен администратором {message.from_user.id}.") # Удаляем сообщения через 5 секунд - await asyncio.sleep(5) - await bot.delete_message(message.chat.id, message.message_id) - await bot.delete_message(message.chat.id, message.message_id+2) + await delete_messages(bot, message, time_sleep=5, number_message=2) except Exception as e: - await send_message(chat_id, f"⚠️ Ошибка: {str(e)}") + + # Отправляем ошибку + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['error'].format(e=str(e)), + message_thread_id=message.message_thread_id, + ) + + # Записываем ошибку в логи logger.error(f"Ошибка бана: {str(e)}") # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) + await delete_messages(bot, message, time_sleep=5, number_message=2) except Exception as e: - await send_message(chat_id, COMMAND_MESSAGES['general_error']) + + # Отправляем ошибку + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['general_error'], + message_thread_id=message.message_thread_id, + ) + + # Записываем ошибку в логи logger.error(f"Общая ошибка в ban_command: {str(e)}") # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) \ No newline at end of file + await delete_messages(bot, message, time_sleep=5, number_message=2) \ No newline at end of file diff --git a/src/modules/help.py b/src/modules/help.py index 939a5c3..726c714 100644 --- a/src/modules/help.py +++ b/src/modules/help.py @@ -3,32 +3,46 @@ from telebot.types import Message import asyncio import logging +from utils import delete_messages + from config import COMMAND_MESSAGES -logger = logging.getLogger(__name__) # Получаем логгер для текущего модуля +# Получаем логгер для текущего модуля +logger = logging.getLogger(__name__) -def register_handlers(bot: AsyncTeleBot): # Регистрирует все обработчики команд +# Регистрирует все обработчики команд +def register_handlers(bot: AsyncTeleBot): - @bot.message_handler(commands=['help']) # Обработчик команды /help + # Обработчик команды /help + @bot.message_handler(commands=['help']) async def help_command(message: Message): - # Отправка сообщения в тему или обычный чат - send_message = bot.reply_to if message.is_topic_message else bot.send_message - chat_id = message if message.is_topic_message else message.chat.id - try: # Отправляем сообщение - await send_message(chat_id, COMMAND_MESSAGES['help']) + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['help'], + message_thread_id=message.message_thread_id, + ) + + # Записываем действие в логи logger.info(f"Пользователь {message.from_user.id} запустил /help.") # Если пользователь писал в чат if message.chat.id != message.from_user.id: # Удаляем сообщения через 30 секунд - await asyncio.sleep(30) - await bot.delete_message(message.chat.id, message.message_id) - await bot.delete_message(message.chat.id, message.message_id+1) + await delete_messages(bot, message, time_sleep=30, number_message=2) except Exception as e: - logger.error(f"Пользователь {message.from_user.id} запустил /help: {str(e)}") \ No newline at end of file + + # Отправляем ошибку + await send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['general_error'], + message_thread_id=message.message_thread_id, + ) + + # Записываем ошибку в логи + logger.error(f"Общая ошибка в help_command: {str(e)}") \ No newline at end of file diff --git a/src/modules/mute.py b/src/modules/mute.py index 0105915..37b5727 100644 --- a/src/modules/mute.py +++ b/src/modules/mute.py @@ -6,90 +6,18 @@ import time from database import db from action_reporter import action_reporter +from utils import ( + delete_messages, + check_admin_status, + check_target_status, + parse_mute_time, + format_mute_time, +) from config import COMMAND_MESSAGES -logger = logging.getLogger(__name__) # Получаем логгер для текущего модуля - -# Возвращает количество секунд -def parse_mute_time(time_str: str) -> int: - - # Парсим строку времени - time_str = time_str.strip().lower() - - # Минуты - if time_str.endswith('m') or time_str.endswith('м'): - try: - minutes = int(time_str[:-1]) - return abs(minutes) * 60 - except: - return None - - # Часы - elif time_str.endswith('h') or time_str.endswith('ч'): - try: - hours = int(time_str[:-1]) - return abs(hours) * 3600 - except: - return None - - # Дни - elif time_str.endswith('d') or time_str.endswith('д'): - try: - days = int(time_str[:-1]) - return abs(days) * 86400 - except: - return None - - return None - -# Возвращает причину мута -def extract_reason(words: str) -> str: - - if words == []: - reason = 'отсутствует' - else: - reason = ' '.join(words) - - return reason - -# Форматирует время в нормальный вид -def format_time(seconds: int) -> str: - - # Для минут - minutes = seconds // 60 - if minutes < 60: - if minutes % 10 == 1 and minutes % 100 != 11: - return f"{minutes} минута" - elif 2 <= minutes % 10 <= 4 and minutes % 100 not in (12, 13, 14): - return f"{minutes} минуты" - else: - return f"{minutes} минут" - - # Для часов - hours = minutes // 60 - if hours < 24: - if hours % 10 == 1 and hours % 100 != 11: - return f"{hours} час" - elif 2 <= hours % 10 <= 4 and hours % 100 not in (12, 13, 14): - return f"{hours} часа" - else: - return f"{hours} часов" - - # Для дней - days = hours // 24 - if days % 10 == 1 and days % 100 != 11: - return f"{days} день" - elif 2 <= days % 10 <= 4 and days % 100 not in (12, 13, 14): - return f"{days} дня" - else: - return f"{days} дней" - -# Удаляет два последних сообщения -async def delete_messages(bot: AsyncTeleBot, message: Message, time_sleep: int): - await asyncio.sleep(time_sleep) - await bot.delete_message(message.chat.id, message.message_id) - await bot.delete_message(message.chat.id, message.message_id+1) +# Получаем логгер для текущего модуля +logger = logging.getLogger(__name__) # Регистрирует все обработчики команд def register_handlers(bot: AsyncTeleBot): @@ -102,10 +30,6 @@ def register_handlers(bot: AsyncTeleBot): # Основная функция команды /mute async def mute_command(bot: AsyncTeleBot, message: Message, photo_path: str = None): - # Отправка сообщения в тему или обычный чат - send_message = bot.reply_to if message.is_topic_message else bot.send_message - chat_id = message if message.is_topic_message else message.chat.id - # Определяем целевого пользователя target_user = None @@ -118,100 +42,91 @@ async def mute_command(bot: AsyncTeleBot, message: Message, photo_path: str = No # Разбиваем текст сообщения на части parts_msg = message.text.split() - # Выводим помощь - if len(parts_msg) == 2 and parts_msg[1].strip() in ['help', 'помощь']: - await send_message(chat_id, COMMAND_MESSAGES['manual_mute']) + # Команда /mute help + if len(parts_msg) == 2 and parts_msg[1].strip() in ('help', 'помощь'): + + # Отправляем инструкцию + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['manual_mute'], + message_thread_id=message.message_thread_id, + ) # Удаляем сообщения через 30 секунд - await delete_messages(bot, message, 30) - + await delete_messages(bot, message, time_sleep=30, number_message=2) return try: + # Проверяем, является ли отправитель администратором - try: - admin_status = await bot.get_chat_member(message.chat.id, message.from_user.id) - - # Проверяем статус администратора (создателя) - if admin_status.status not in ['administrator', 'creator']: - await send_message(chat_id, COMMAND_MESSAGES['no_admin_rights']) - - # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) - - return - - # Проверяем право администратора на мут - if admin_status.status == 'administrator' and not admin_status.can_restrict_members: - await send_message(chat_id, COMMAND_MESSAGES['no_restrict_rights']) - - # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) - - return - - except Exception as e: - await send_message(chat_id, f"⚠️ Ошибка: {str(e)}") - logger.error(f"Ошибка при получении статуса администратора: {str(e)}") - - # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) - + if await check_admin_status(bot, message) == 1: return - # Если одно слово, то удаляем сообщение. Ошибка + # Если одно слово (/mute) if len(parts_msg) == 1: - await asyncio.sleep(3) - await bot.delete_message(message.chat.id, message.message_id) + + # Удаляем сообщение через 3 секунды + await delete_messages(bot, message, time_sleep=3, number_message=1) return - # Если два слово, то ответом на сообщение + # Команда через ответ на сообщение, если два слова (/mute 2m) elif len(parts_msg) == 2: - # Если это тема + # Если это топик if message.is_topic_message: - # Если без ответа на сообщение, ошибка + # Если без ответа на сообщение if message.message_thread_id == message.reply_to_message.message_id: - await asyncio.sleep(3) - await bot.delete_message(message.chat.id, message.message_id) + + # Удаляем сообщение через 3 секунды + await delete_messages(bot, message, time_sleep=3, number_message=1) return # Если с ответом на сообщение else: + + # Собираем данные target_user = message.reply_to_message.from_user time_arg = parts_msg[1] - reason = extract_reason(parts_msg[2:]) + reason = 'отсутствует' - # Если это обычный чат + # Если это General (обычный чат) elif message.reply_to_message and message.is_topic_message is None: + + # Собираем данные target_user = message.reply_to_message.from_user time_arg = parts_msg[1] - reason = extract_reason(parts_msg[2:]) + reason = 'отсутствует' + message.message_thread_id = None - # Удаляем сообщение, если команда неправильная + # Если команда неправильная else: - await asyncio.sleep(3) - await bot.delete_message(message.chat.id, message.message_id) + + # Удаляем сообщение через 3 секунды + await delete_messages(bot, message, time_sleep=3, number_message=1) return + # В сообщении больше двух слов else: # Если второе слово это тег или ID if parts_msg[1].strip().isdigit() or parts_msg[1].startswith('@'): - + + # Собираем данные identifier = parts_msg[1].strip() time_arg = parts_msg[2] - reason = extract_reason(parts_msg[3:]) + reason = ' '.join(parts_msg[3:]) if parts_msg[3:] != [] else 'отсутствует' - # Поиск по ID + # Делаем поиск по ID if identifier.isdigit(): - # Делаем в int и ищем + # Ищем пользователя в базе данных user_info = db.get_user(int(identifier)) + # Если нашли пользователя if user_info: - # Создаем объект пользователя из данных базы + + # Создаем объект пользователя target_user = User( id=user_info[0], first_name=user_info[1], @@ -219,14 +134,16 @@ async def mute_command(bot: AsyncTeleBot, message: Message, photo_path: str = No is_bot=False ) - # Поиск по тегу + # Делаем поиск по тегу elif identifier.startswith('@'): - # Убираем @ и ищем + # Ищем пользователя в базе данных (убрали @) user_info = db.get_user_by_username(identifier[1:]) + # Если нашли пользователя if user_info: - # Создаем объект пользователя из данных базы + + # Создаем объект пользователя target_user = User( id=user_info[0], first_name=user_info[1], @@ -234,95 +151,106 @@ async def mute_command(bot: AsyncTeleBot, message: Message, photo_path: str = No is_bot=False ) + # Команда через ответ на сообщение с указанием причины else: - # Если это тема + # Если это топик if message.is_topic_message: - # Если без ответа на сообщение, ошибка + # Если без ответа на сообщение if message.message_thread_id == message.reply_to_message.message_id: - await asyncio.sleep(3) - await bot.delete_message(message.chat.id, message.message_id) + + # Удаляем сообщение через 3 секунды + await delete_messages(bot, message, time_sleep=3, number_message=1) return # Если с ответом на сообщение else: + + # Собираем данные target_user = message.reply_to_message.from_user time_arg = parts_msg[1] - reason = extract_reason(parts_msg[2:]) + reason = ' '.join(parts_msg[2:]) - # Если это обычный чат + # Если это General (обычный чат) elif message.reply_to_message and message.is_topic_message is None: + + # Собираем данные target_user = message.reply_to_message.from_user time_arg = parts_msg[1] - reason = extract_reason(parts_msg[2:]) + reason = ' '.join(parts_msg[2:]) + message.message_thread_id = None - # Удаляем сообщение, если команда неправильная + # Если команда неправильная else: - await asyncio.sleep(3) - await bot.delete_message(message.chat.id, message.message_id) + + # Удаляем сообщение через 3 секунды + await delete_messages(bot, message, time_sleep=3, number_message=1) return - # Если пользователь не найден + # Если пользователь не найден в базе данных if not target_user: - await send_message(chat_id, COMMAND_MESSAGES['user_not_found']) + + # Отправляем предупреждение + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['user_not_found'], + message_thread_id=message.message_thread_id, + ) # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) - + await delete_messages(bot, message, time_sleep=5, number_message=2) return # Парсинг времени мута mute_seconds = parse_mute_time(time_arg) + + # Если не указали время if mute_seconds is None: - await send_message(chat_id, COMMAND_MESSAGES['incorrect_time_format']) + + # Отправляем предупреждение + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['incorrect_time_format'], + message_thread_id=message.message_thread_id, + ) # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) - + await delete_messages(bot, message, time_sleep=5, number_message=2) return - # Минимальный мут 1 минута (60 секунд) + # Минимальное время мута - 1 минута (60 секунд) if mute_seconds < 60: - await send_message(chat_id, COMMAND_MESSAGES['min_mute']) + + # Отправляем предупреждение + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['min_mute'], + message_thread_id=message.message_thread_id, + ) # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) - + await delete_messages(bot, message, time_sleep=5, number_message=2) return - # Максимальный мут 30 дней (2592000 секунд) + # Максимальное время мута - 30 дней (2592000 секунд) if mute_seconds > 2592000: - await send_message(chat_id, COMMAND_MESSAGES['max_mute']) + + # Отправляем предупреждение + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['max_mute'], + message_thread_id=message.message_thread_id, + ) # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) - + await delete_messages(bot, message, time_sleep=5, number_message=2) return # Проверяем статус целевого пользователя - try: - target_status = await bot.get_chat_member(message.chat.id, target_user.id) - - # Проверяем, является ли цель администратором или создателем - if target_status.status in ['administrator', 'creator']: - await send_message(chat_id, COMMAND_MESSAGES['cant_mute_admin']) - - # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) - - return - - except Exception as e: - await send_message(chat_id, f"⚠️ Ошибка: {str(e)}") - logger.error(f"Ошибка при получении статуса пользователя: {str(e)}") - - # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) - + if await check_target_status(bot, message, target_user) == 1: return - # Выполняем мут try: # Вычисляем время окончания мута @@ -340,6 +268,7 @@ async def mute_command(bot: AsyncTeleBot, message: Message, photo_path: str = No can_pin_messages=False, ) + # Выполняем мут await bot.restrict_chat_member( chat_id=message.chat.id, user_id=target_user.id, @@ -347,36 +276,58 @@ async def mute_command(bot: AsyncTeleBot, message: Message, photo_path: str = No until_date=until_date ) - # Форматирование времени - time_display = format_time(mute_seconds) + # Форматируем время в удобный формат + time_display = format_mute_time(mute_seconds) - # Отправляем лог в админ-чат + # Отправляем сообщение-лог в админ-чат await action_reporter.log_action( action="МУТ", user_id=target_user.id, admin_id=message.from_user.id, reason=reason, duration=time_display, - photo_path=photo_path + photo_path=photo_path, ) - # Отправляем сообщения, что пользователь получил мут - await send_message(chat_id, COMMAND_MESSAGES['muted'].format(time_display=time_display)) + # Отправляем сообщение, что пользователь получил мут + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['muted'].format(time_display=time_display), + message_thread_id=message.message_thread_id, + ) + + # Записываем действие в логи logger.info(f"Пользователь {target_user.id} получил мут на {time_display} от администратора {message.from_user.id}.") # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) + await delete_messages(bot, message, time_sleep=5, number_message=2) except Exception as e: - await send_message(chat_id, f"⚠️ Ошибка: {str(e)}") + + # Отправляем ошибку + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['error'].format(e=str(e)), + message_thread_id=message.message_thread_id, + ) + + # Записываем ошибку в логи logger.error(f"Ошибка мута: {str(e)}") # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) + await delete_messages(bot, message, time_sleep=5, number_message=2) except Exception as e: - await send_message(chat_id, COMMAND_MESSAGES['general_error']) + + # Отправляем ошибку + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['general_error'], + message_thread_id=message.message_thread_id, + ) + + # Записываем ошибку в логи logger.error(f"Общая ошибка в mute_command: {str(e)}") # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) \ No newline at end of file + await delete_messages(bot, message, time_sleep=5, number_message=2) \ No newline at end of file diff --git a/src/modules/start.py b/src/modules/start.py index e398784..1ad4123 100644 --- a/src/modules/start.py +++ b/src/modules/start.py @@ -3,32 +3,46 @@ from telebot.types import Message import asyncio import logging +from utils import delete_messages + from config import COMMAND_MESSAGES -logger = logging.getLogger(__name__) # Получаем логгер для текущего модуля +# Получаем логгер для текущего модуля +logger = logging.getLogger(__name__) -def register_handlers(bot: AsyncTeleBot): # Регистрирует все обработчики команд +# Регистрирует все обработчики команд +def register_handlers(bot: AsyncTeleBot): - @bot.message_handler(commands=['start']) # Обработчик команды /start + # Обработчик команды /start + @bot.message_handler(commands=['start']) async def start_command(message: Message): - # Отправка сообщения в тему или обычный чат - send_message = bot.reply_to if message.is_topic_message else bot.send_message - chat_id = message if message.is_topic_message else message.chat.id - try: # Отправляем сообщение - await send_message(chat_id, COMMAND_MESSAGES['start']) + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['start'], + message_thread_id=message.message_thread_id, + ) + + # Записываем действие в логи logger.info(f"Пользователь {message.from_user.id} запустил /start.") # Если пользователь писал в чат if message.chat.id != message.from_user.id: # Удаляем сообщения через 5 секунд - await asyncio.sleep(5) - await bot.delete_message(message.chat.id, message.message_id) - await bot.delete_message(message.chat.id, message.message_id+1) + await delete_messages(bot, message, time_sleep=5, number_message=2) except Exception as e: - logger.error(f"Пользователь {message.from_user.id} запустил /start: {str(e)}") \ No newline at end of file + + # Отправляем ошибку + await send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['general_error'], + message_thread_id=message.message_thread_id, + ) + + # Записываем ошибку в логи + logger.error(f"Общая ошибка в start_command: {str(e)}") \ No newline at end of file diff --git a/src/modules/unban.py b/src/modules/unban.py index 30ecb0c..946a350 100644 --- a/src/modules/unban.py +++ b/src/modules/unban.py @@ -1,116 +1,103 @@ from telebot.async_telebot import AsyncTeleBot -from telebot.types import Message, User +from telebot.types import Message, User, ChatPermissions import asyncio import logging from database import db from action_reporter import action_reporter +from utils import ( + delete_messages, + check_admin_status, + check_target_status, +) from config import COMMAND_MESSAGES -logger = logging.getLogger(__name__) # Получаем логгер для текущего модуля +# Получаем логгер для текущего модуля +logger = logging.getLogger(__name__) -# Удаляет два последних сообщения -async def delete_messages(bot: AsyncTeleBot, message: Message, time_sleep: int): - await asyncio.sleep(time_sleep) - await bot.delete_message(message.chat.id, message.message_id) - await bot.delete_message(message.chat.id, message.message_id+1) +# Регистрирует все обработчики команд +def register_handlers(bot: AsyncTeleBot): -def register_handlers(bot: AsyncTeleBot): # Регистрирует все обработчики команд - - @bot.message_handler(commands=['unban']) # Обработчик команды /unban + # Обработчик команды /unban + @bot.message_handler(commands=['unban']) async def unban_command(message: Message): - # Отправка сообщения в тему или обычный чат - send_message = bot.reply_to if message.is_topic_message else bot.send_message - chat_id = message if message.is_topic_message else message.chat.id - # Определяем целевого пользователя target_user = None # Разбиваем текст сообщения на части parts_msg = message.text.split() - # Выводим помощь (/unban help) - if len(parts_msg) == 2 and parts_msg[1].strip() in ['help', 'помощь']: - await send_message(chat_id, COMMAND_MESSAGES['manual_unban']) + # Команда /unban help + if len(parts_msg) == 2 and parts_msg[1].strip() in ('help', 'помощь'): + + # Отправляем инструкцию + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['manual_unban'], + message_thread_id=message.message_thread_id, + ) # Удаляем сообщения через 30 секунд - await delete_messages(bot, message, 30) - + await delete_messages(bot, message, time_sleep=30, number_message=2) return try: + # Проверяем, является ли отправитель администратором - try: - admin_status = await bot.get_chat_member(message.chat.id, message.from_user.id) - - # Проверяем статус администратора (создателя) - if admin_status.status not in ['administrator', 'creator']: - await send_message(chat_id, COMMAND_MESSAGES['no_admin_rights']) - - # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) - - return - - # Проверяем право администратора на разбан - if admin_status.status == 'administrator' and not admin_status.can_restrict_members: - await send_message(chat_id, COMMAND_MESSAGES['no_restrict_rights']) - - # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) - - return - - except Exception as e: - await send_message(chat_id, f"⚠️ Ошибка: {str(e)}") - logger.error(f"Ошибка при получении статуса администратора: {str(e)}") - - # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) - + if await check_admin_status(bot, message) == 1: return - # Если одно слово, то ответом на сообщение + # Команда через ответ на сообщение, если одно слово (/unban) if len(parts_msg) == 1: - # Если это тема + # Если это топик if message.is_topic_message: - # Если без ответа на сообщение, ошибка + # Если без ответа на сообщение if message.message_thread_id == message.reply_to_message.message_id: - await asyncio.sleep(3) - await bot.delete_message(message.chat.id, message.message_id) + + # Удаляем сообщение через 3 секунды + await delete_messages(bot, message, time_sleep=3, number_message=1) return # Если с ответом на сообщение else: + + # Собираем данные target_user = message.reply_to_message.from_user - # Если это обычный чат + # Если это General (обычный чат) elif message.reply_to_message and message.is_topic_message is None: + + # Собираем данные target_user = message.reply_to_message.from_user + message.message_thread_id = None # Удаляем сообщение, если команда неправильная else: - await asyncio.sleep(3) - await bot.delete_message(message.chat.id, message.message_id) + + # Удаляем сообщение через 3 секунды + await delete_messages(bot, message, time_sleep=3, number_message=1) return - # Если два, то через тег или ID + # Команда через тег или ID, если два слова elif len(parts_msg) == 2: + # Собираем данные identifier = parts_msg[1].strip() - # Поиск по ID + # Делаем поиск по ID if identifier.isdigit(): - # Делаем в int и ищем + # Ищем пользователя в базе данных user_info = db.get_user(int(identifier)) + # Если нашли пользователя if user_info: - # Создаем объект пользователя из данных базы + + # Создаем объект пользователя target_user = User( id=user_info[0], first_name=user_info[1], @@ -118,14 +105,16 @@ def register_handlers(bot: AsyncTeleBot): # Регистрирует все об is_bot=False ) - # Поиск по тегу + # Делаем поиск по тегу elif identifier.startswith('@'): - # Убираем @ и ищем + # Ищем пользователя в базе данных user_info = db.get_user_by_username(identifier[1:]) + # Если нашли пользователя if user_info: - # Создаем объект пользователя из данных базы + + # Создаем объект пользователя target_user = User( id=user_info[0], first_name=user_info[1], @@ -133,18 +122,31 @@ def register_handlers(bot: AsyncTeleBot): # Регистрирует все об is_bot=False ) - # Если пользователь не найден + # Если пользователь не найден в базе данных if not target_user: - await send_message(chat_id, COMMAND_MESSAGES['user_not_found']) + + # Отправляем предупреждение + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['user_not_found'], + message_thread_id=message.message_thread_id, + ) # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) - + await delete_messages(bot, message, time_sleep=5, number_message=2) + return + + # Проверяем статус целевого пользователя + if await check_target_status(bot, message, target_user) == 1: return - # Выполняем разбан try: - await bot.unban_chat_member(message.chat.id, target_user.id) + + # Выполняем разбан + await bot.unban_chat_member( + chat_id=message.chat.id, + user_id=target_user.id, + ) # Отправляем лог в админ-чат await action_reporter.log_action( @@ -153,26 +155,48 @@ def register_handlers(bot: AsyncTeleBot): # Регистрирует все об admin_id=message.from_user.id, reason=None, duration=None, - photo_path=None + photo_path=None, ) # Отправляем сообщения, что пользователь получил разбан - await send_message(chat_id, COMMAND_MESSAGES['unbanned']) + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['unbanned'], + message_thread_id=message.message_thread_id, + ) + + # Записываем действие в логи logger.info(f"Пользователь {target_user.id} разбанен администратором {message.from_user.id}.") # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) + await delete_messages(bot, message, time_sleep=5, number_message=2) except Exception as e: - await send_message(chat_id, f"⚠️ Ошибка: {str(e)}") - logger.error(f"Ошибка разбана: {str(e)}") + + # Отправляем ошибку + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['error'].format(e=str(e)), + message_thread_id=message.message_thread_id, + ) + + # Записываем ошибку в логи + logger.error(f"Ошибка размута: {str(e)}") # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) + await delete_messages(bot, message, time_sleep=5, number_message=2) except Exception as e: - await send_message(chat_id, COMMAND_MESSAGES['general_error']) + + # Отправляем ошибку + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['general_error'], + message_thread_id=message.message_thread_id, + ) + + # Записываем ошибку в логи logger.error(f"Общая ошибка в unban_command: {str(e)}") # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) \ No newline at end of file + await delete_messages(bot, message, time_sleep=5, number_message=2) \ No newline at end of file diff --git a/src/modules/unmute.py b/src/modules/unmute.py index f449717..9ee4588 100644 --- a/src/modules/unmute.py +++ b/src/modules/unmute.py @@ -5,112 +5,99 @@ import logging from database import db from action_reporter import action_reporter +from utils import ( + delete_messages, + check_admin_status, + check_target_status, +) from config import COMMAND_MESSAGES -logger = logging.getLogger(__name__) # Получаем логгер для текущего модуля +# Получаем логгер для текущего модуля +logger = logging.getLogger(__name__) -# Удаляет два последних сообщения -async def delete_messages(bot: AsyncTeleBot, message: Message, time_sleep: int): - await asyncio.sleep(time_sleep) - await bot.delete_message(message.chat.id, message.message_id) - await bot.delete_message(message.chat.id, message.message_id+1) +# Регистрирует все обработчики команд +def register_handlers(bot: AsyncTeleBot): -def register_handlers(bot: AsyncTeleBot): # Регистрирует все обработчики команд - - @bot.message_handler(commands=['unmute']) # Обработчик команды /unmute + # Обработчик команды /unmute + @bot.message_handler(commands=['unmute']) async def unmute_command(message: Message): - # Отправка сообщения в тему или обычный чат - send_message = bot.reply_to if message.is_topic_message else bot.send_message - chat_id = message if message.is_topic_message else message.chat.id - # Определяем целевого пользователя target_user = None # Разбиваем текст сообщения на части parts_msg = message.text.split() - # Выводим помощь (/unmute help) - if len(parts_msg) == 2 and parts_msg[1].strip() in ['help', 'помощь']: - await send_message(chat_id, COMMAND_MESSAGES['manual_unmute']) + # Команда /unmute help + if len(parts_msg) == 2 and parts_msg[1].strip() in ('help', 'помощь'): + + # Отправляем инструкцию + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['manual_unmute'], + message_thread_id=message.message_thread_id, + ) # Удаляем сообщения через 30 секунд - await delete_messages(bot, message, 30) - + await delete_messages(bot, message, time_sleep=30, number_message=2) return try: + # Проверяем, является ли отправитель администратором - try: - admin_status = await bot.get_chat_member(message.chat.id, message.from_user.id) - - # Проверяем статус администратора (создателя) - if admin_status.status not in ['administrator', 'creator']: - await send_message(chat_id, COMMAND_MESSAGES['no_admin_rights']) - - # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) - - return - - # Проверяем право администратора на разбан - if admin_status.status == 'administrator' and not admin_status.can_restrict_members: - await send_message(chat_id, COMMAND_MESSAGES['no_restrict_rights']) - - # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) - - return - - except Exception as e: - await send_message(chat_id, f"⚠️ Ошибка: {str(e)}") - logger.error(f"Ошибка при получении статуса администратора: {str(e)}") - - # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) - + if await check_admin_status(bot, message) == 1: return - # Если одно слово, то ответом на сообщение + # Команда через ответ на сообщение, если одно слово (/unmute) if len(parts_msg) == 1: - # Если это тема + # Если это топик if message.is_topic_message: - # Если без ответа на сообщение, ошибка + # Если без ответа на сообщение if message.message_thread_id == message.reply_to_message.message_id: - await asyncio.sleep(3) - await bot.delete_message(message.chat.id, message.message_id) + + # Удаляем сообщение через 3 секунды + await delete_messages(bot, message, time_sleep=3, number_message=1) return # Если с ответом на сообщение else: + + # Собираем данные target_user = message.reply_to_message.from_user - # Если это обычный чат + # Если это General (обычный чат) elif message.reply_to_message and message.is_topic_message is None: + + # Собираем данные target_user = message.reply_to_message.from_user + message.message_thread_id = None # Удаляем сообщение, если команда неправильная else: - await asyncio.sleep(3) - await bot.delete_message(message.chat.id, message.message_id) + + # Удаляем сообщение через 3 секунды + await delete_messages(bot, message, time_sleep=3, number_message=1) return - # Если два, то через тег или ID + # Команда через тег или ID, если два слова elif len(parts_msg) == 2: + # Собираем данные identifier = parts_msg[1].strip() - # Поиск по ID + # Делаем поиск по ID if identifier.isdigit(): - # Делаем в int и ищем + # Ищем пользователя в базе данных user_info = db.get_user(int(identifier)) + # Если нашли пользователя if user_info: - # Создаем объект пользователя из данных базы + + # Создаем объект пользователя target_user = User( id=user_info[0], first_name=user_info[1], @@ -118,14 +105,16 @@ def register_handlers(bot: AsyncTeleBot): # Регистрирует все об is_bot=False ) - # Поиск по тегу + # Делаем поиск по тегу elif identifier.startswith('@'): - # Убираем @ и ищем + # Ищем пользователя в базе данных user_info = db.get_user_by_username(identifier[1:]) + # Если нашли пользователя if user_info: - # Создаем объект пользователя из данных базы + + # Создаем объект пользователя target_user = User( id=user_info[0], first_name=user_info[1], @@ -133,17 +122,26 @@ def register_handlers(bot: AsyncTeleBot): # Регистрирует все об is_bot=False ) - # Если пользователь не найден + # Если пользователь не найден в базе данных if not target_user: - await send_message(chat_id, COMMAND_MESSAGES['user_not_found']) + + # Отправляем предупреждение + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['user_not_found'], + message_thread_id=message.message_thread_id, + ) # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) - + await delete_messages(bot, message, time_sleep=5, number_message=2) + return + + # Проверяем статус целевого пользователя + if await check_target_status(bot, message, target_user) == 1: return - # Выполняем размут try: + # Убираем ограничения (можно писать в чат) permissions = ChatPermissions( can_send_messages=True, @@ -153,13 +151,14 @@ def register_handlers(bot: AsyncTeleBot): # Регистрирует все об can_add_web_page_previews=True, can_change_info=False, can_invite_users=True, - can_pin_messages=False, + can_pin_messages=False ) + # Выполняем размут await bot.restrict_chat_member( chat_id=message.chat.id, user_id=target_user.id, - permissions=permissions + permissions=permissions, ) # Отправляем лог в админ-чат @@ -169,26 +168,48 @@ def register_handlers(bot: AsyncTeleBot): # Регистрирует все об admin_id=message.from_user.id, reason=None, duration=None, - photo_path=None + photo_path=None, ) # Отправляем сообщения, что пользователь получил размут - await send_message(chat_id, COMMAND_MESSAGES['unmuted']) + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['unmuted'], + message_thread_id=message.message_thread_id, + ) + + # Записываем действие в логи logger.info(f"Пользователь {target_user.id} получил размут от администратора {message.from_user.id}.") # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) + await delete_messages(bot, message, time_sleep=5, number_message=2) except Exception as e: - await send_message(chat_id, f"⚠️ Ошибка: {str(e)}") + + # Отправляем ошибку + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['error'].format(e=str(e)), + message_thread_id=message.message_thread_id, + ) + + # Записываем ошибку в логи logger.error(f"Ошибка размута: {str(e)}") # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) + await delete_messages(bot, message, time_sleep=5, number_message=2) except Exception as e: - await send_message(chat_id, COMMAND_MESSAGES['general_error']) + + # Отправляем ошибку + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['general_error'], + message_thread_id=message.message_thread_id, + ) + + # Записываем ошибку в логи logger.error(f"Общая ошибка в unmute_command: {str(e)}") # Удаляем сообщения через 5 секунд - await delete_messages(bot, message, 5) \ No newline at end of file + await delete_messages(bot, message, time_sleep=5, number_message=2) \ No newline at end of file diff --git a/src/utils.py b/src/utils.py new file mode 100644 index 0000000..681d47f --- /dev/null +++ b/src/utils.py @@ -0,0 +1,177 @@ +from telebot.async_telebot import AsyncTeleBot +from telebot.types import Message +import asyncio +import logging + +# Получаем логгер для текущего модуля +logger = logging.getLogger(__name__) + +# Удаляет определённое количество сообщения +async def delete_messages(bot: AsyncTeleBot, message: Message, time_sleep: int, number_message: int): + await asyncio.sleep(time_sleep) + for i in range(number_message): + await bot.delete_message(message.chat.id, message.message_id+i) + +# Проверяет, является ли отправитель администратором +async def check_admin_status(bot: AsyncTeleBot, message: Message): + + if message.reply_to_message and message.is_topic_message is None: + message.message_thread_id = None + + try: + + # Получаем статус отправителя + admin_status = await bot.get_chat_member(message.chat.id, message.from_user.id) + + # Проверка наличия прав администратора/создателя + if admin_status.status not in ('administrator', 'creator'): + + # Отправляем предупреждение + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['no_admin_rights'], + message_thread_id=message.message_thread_id, + ) + + # Удаляем сообщения через 5 секунд + await delete_messages(bot, message, time_sleep=5, number_message=2) + return 1 + + # Проверка права на ограничение участников + if admin_status.status == 'administrator' and not admin_status.can_restrict_members: + + # Отправляем предупреждение + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['no_restrict_rights'], + message_thread_id=message.message_thread_id, + ) + + # Удаляем сообщения через 5 секунд + await delete_messages(bot, message, time_sleep=5, number_message=2) + return 1 + + except Exception as e: + + # Отправляем ошибку + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['error'].format(e=str(e)), + message_thread_id=message.message_thread_id, + ) + + # Записываем ошибку в логи + logger.error(f"Ошибка при получении статуса администратора: {str(e)}") + + # Удаляем сообщения через 5 секунд + await delete_messages(bot, message, time_sleep=5, number_message=2) + return 1 + +# Проверяет статус целевого пользователя +async def check_target_status(bot: AsyncTeleBot, message: Message, target_user): + + if message.reply_to_message and message.is_topic_message is None: + message.message_thread_id = None + + try: + + # Получаем статус пользователя + target_status = await bot.get_chat_member( + chat_id=message.chat.id, + user_id=target_user.id, + ) + + # Проверяем, является ли цель администратором или создателем + if target_status.status in ('administrator', 'creator'): + + # Отправляем предупреждение + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['cant_mute_admin'], + message_thread_id=message.message_thread_id, + ) + + # Удаляем сообщения через 5 секунд + await delete_messages(bot, message, time_sleep=5, number_message=2) + return + + except Exception as e: + + # Отправляем ошибку + await bot.send_message( + chat_id=message.chat.id, + text=COMMAND_MESSAGES['error'].format(e=str(e)), + message_thread_id=message.message_thread_id, + ) + + # Записываем ошибку в логи + logger.error(f"Ошибка при получении статуса пользователя: {str(e)}") + + # Удаляем сообщения через 5 секунд + await delete_messages(bot, message, time_sleep=5, number_message=2) + return + +# Возвращает количество секунд +def parse_mute_time(time_str: str) -> int | None: + + # Нормализация входной строки + normalized = time_str.strip().lower() + + # Словарь для конвертации единиц времени в секунды + time_units = { + 'm': 60, 'м': 60, # минуты + 'h': 3600, 'ч': 3600, # часы + 'd': 86400, 'д': 86400 # дни + } + + # Проверям, существует ли строка + if not normalized: + return None + + # Проверяем последний символ (единица измерения) + unit = normalized[-1] + if unit not in time_units: + return None + + # Парсим числовую часть + try: + value = int(normalized[:-1]) + if value <= 0: + return None + + return value * time_units[unit] + + except (ValueError, TypeError): + return None + +# Форматирует время в нормальный вид +def format_mute_time(seconds: int) -> str: + + # Обработка минут + minutes = seconds // 60 + if minutes < 60: + if minutes % 10 == 1 and minutes % 100 != 11: + return f"{minutes} минуту" + elif 2 <= minutes % 10 <= 4 and (minutes % 100 < 10 or minutes % 100 >= 20): + return f"{minutes} минуты" + else: + return f"{minutes} минут" + + # Обработка часов + hours = minutes // 60 + if hours < 24: + if hours % 10 == 1 and hours % 100 != 11: + return f"{hours} час" + elif 2 <= hours % 10 <= 4 and (hours % 100 < 10 or hours % 100 >= 20): + return f"{hours} часа" + else: + return f"{hours} часов" + + # Обработка дней + days = hours // 24 + if days % 10 == 1 and days % 100 != 11: + return f"{days} день" + elif 2 <= days % 10 <= 4 and (days % 100 < 10 or days % 100 >= 20): + return f"{days} дня" + else: + return f"{days} дней" \ No newline at end of file -- 2.49.0