added utils.py #7

Merged
Muzifs merged 1 commits from devel into master 2025-07-28 18:24:50 +00:00
8 changed files with 692 additions and 492 deletions
Showing only changes of commit 853bfcdbb4 - Show all commits

View File

@ -68,9 +68,11 @@ COMMAND_MESSAGES = {
"<b>✅ Команда /unban</b>\n\n" "<b>✅ Команда /unban</b>\n\n"
"<i>Снимает бан с пользователя</i>\n\n" "<i>Снимает бан с пользователя</i>\n\n"
"<u>🎯 Способы использования:</u>\n" "<u>🎯 Способы использования:</u>\n"
"1. По тегу пользователя:\n" "1. Ответ на сообщение:\n"
" <code>/unban</code>\n"
"2. По тегу пользователя:\n"
" <code>/unban @username</code>\n" " <code>/unban @username</code>\n"
"2. По ID пользователя:\n" "3. По ID пользователя:\n"
" <code>/unban 123456789</code>\n\n" " <code>/unban 123456789</code>\n\n"
"<b>⚠️ Работает только для забаненных через /ban</b>\n" "<b>⚠️ Работает только для забаненных через /ban</b>\n"
"<i> Пользователь сможет снова присоединиться</i>" "<i> Пользователь сможет снова присоединиться</i>"
@ -87,6 +89,7 @@ COMMAND_MESSAGES = {
'unmuted': '✅ Пользователь размучен.', 'unmuted': '✅ Пользователь размучен.',
'banned': '✅ Пользователь успешно забанен.', 'banned': '✅ Пользователь успешно забанен.',
'unbanned': '✅ Пользователь успешно разбанен.', 'unbanned': '✅ Пользователь успешно разбанен.',
'error': '⚠️ Ошибка: {e}',
'general_error': '⚠️ Произошла непредвиденная ошибка.' 'general_error': '⚠️ Произошла непредвиденная ошибка.'
} }

View File

@ -5,27 +5,16 @@ import logging
from database import db from database import db
from action_reporter import action_reporter from action_reporter import action_reporter
from utils import (
delete_messages,
check_admin_status,
check_target_status,
)
from config import COMMAND_MESSAGES from config import COMMAND_MESSAGES
logger = logging.getLogger(__name__) # Получаем логгер для текущего модуля 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): def register_handlers(bot: AsyncTeleBot):
@ -37,10 +26,6 @@ def register_handlers(bot: AsyncTeleBot):
# Основная функция команды /ban # Основная функция команды /ban
async def ban_command(bot: AsyncTeleBot, message: Message, photo_path: str = None): 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 target_user = None
@ -50,91 +35,81 @@ async def ban_command(bot: AsyncTeleBot, message: Message, photo_path: str = Non
# Разбиваем текст сообщения на части # Разбиваем текст сообщения на части
parts_msg = message.text.split() parts_msg = message.text.split()
# Выводим помощь (/ban help) # Команда /ban help
if len(parts_msg) == 2 and parts_msg[1].strip() in ['help', 'помощь']: if len(parts_msg) == 2 and parts_msg[1].strip() in ('help', 'помощь'):
await send_message(chat_id, COMMAND_MESSAGES['manual_ban'])
# Отправляем инструкцию
await bot.send_message(
chat_id=message.chat.id,
text=COMMAND_MESSAGES['manual_ban'],
message_thread_id=message.message_thread_id,
)
# Удаляем сообщения через 30 секунд # Удаляем сообщения через 30 секунд
await delete_messages(bot, message, 30) await delete_messages(bot, message, time_sleep=30, number_message=2)
return return
try: try:
# Проверяем, является ли отправитель администратором # Проверяем, является ли отправитель администратором
try: if await check_admin_status(bot, message) == 1:
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)
return return
# Если одно слово, то ответом на сообщение # Команда через ответ на сообщение, если одно слово (/ban)
if len(parts_msg) == 1: if len(parts_msg) == 1:
# Если это тема # Если это топик
if message.is_topic_message: if message.is_topic_message:
# Если без ответа на сообщение, ошибка # Если без ответа на сообщение
if message.message_thread_id == message.reply_to_message.message_id: 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 return
# Если с ответом на сообщение # Если с ответом на сообщение
else: 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: elif message.reply_to_message and message.is_topic_message is None:
# Собираем данные
target_user = message.reply_to_message.from_user target_user = message.reply_to_message.from_user
reason = extract_reason(parts_msg[1:]) reason = 'отсутствует'
message.message_thread_id = None
# Удаляем сообщение, если команда неправильная # Если команда неправильная
else: 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 return
# В сообщении больше одного слова
else: else:
# Если второе слово это тег или ID # Если второе слово это тег или ID
if parts_msg[1].strip().isdigit() or parts_msg[1].startswith('@'): 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(): if identifier.isdigit():
# Делаем в int и ищем # Ищем пользователя в базе данных
user_info = db.get_user(int(identifier)) user_info = db.get_user(int(identifier))
# Если нашли пользователя
if user_info: if user_info:
# Создаем объект пользователя из данных базы
# Создаем объект пользователя
target_user = User( target_user = User(
id=user_info[0], id=user_info[0],
first_name=user_info[1], first_name=user_info[1],
@ -142,14 +117,16 @@ async def ban_command(bot: AsyncTeleBot, message: Message, photo_path: str = Non
is_bot=False is_bot=False
) )
# Поиск по тэгу # Делаем поиск по тегу
elif identifier.startswith('@'): elif identifier.startswith('@'):
# Убираем @ и ищем # Ищем пользователя в базе данных (убрали @)
user_info = db.get_user_by_username(identifier[1:]) user_info = db.get_user_by_username(identifier[1:])
# Если нашли пользователя
if user_info: if user_info:
# Создаем объект пользователя из данных базы
# Создаем объект пользователя
target_user = User( target_user = User(
id=user_info[0], id=user_info[0],
first_name=user_info[1], first_name=user_info[1],
@ -157,67 +134,66 @@ async def ban_command(bot: AsyncTeleBot, message: Message, photo_path: str = Non
is_bot=False is_bot=False
) )
# Команда через ответ на сообщение с указанием причины
else: else:
# Если это тема # Если это топик
if message.is_topic_message: if message.is_topic_message:
# Если без ответа на сообщение, ошибка # Если без ответа на сообщение
if message.message_thread_id == message.reply_to_message.message_id: 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 return
# Если с ответом на сообщение # Если с ответом на сообщение
else: 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: elif message.reply_to_message and message.is_topic_message is None:
# Собираем данные
target_user = message.reply_to_message.from_user 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: 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 return
# Если пользователь не найден # Если пользователь не найден в базе данных
if not target_user: 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 секунд # Удаляем сообщения через 5 секунд
await delete_messages(bot, message, 5) await delete_messages(bot, message, time_sleep=5, number_message=2)
return return
# Проверяем статус целевого пользователя # Проверяем статус целевого пользователя
try: if await check_target_status(bot, message, target_user) == 1:
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)
return return
# Выполняем бан
try: 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( 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, admin_id=message.from_user.id,
reason=reason, reason=reason,
duration=None, 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}.") logger.info(f"Пользователь {target_user.id} забанен администратором {message.from_user.id}.")
# Удаляем сообщения через 5 секунд # Удаляем сообщения через 5 секунд
await asyncio.sleep(5) await delete_messages(bot, message, time_sleep=5, number_message=2)
await bot.delete_message(message.chat.id, message.message_id)
await bot.delete_message(message.chat.id, message.message_id+2)
except Exception as e: 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)}") logger.error(f"Ошибка бана: {str(e)}")
# Удаляем сообщения через 5 секунд # Удаляем сообщения через 5 секунд
await delete_messages(bot, message, 5) await delete_messages(bot, message, time_sleep=5, number_message=2)
except Exception as e: 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)}") logger.error(f"Общая ошибка в ban_command: {str(e)}")
# Удаляем сообщения через 5 секунд # Удаляем сообщения через 5 секунд
await delete_messages(bot, message, 5) await delete_messages(bot, message, time_sleep=5, number_message=2)

View File

@ -3,32 +3,46 @@ from telebot.types import Message
import asyncio import asyncio
import logging import logging
from utils import delete_messages
from config import COMMAND_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): 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: 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.") logger.info(f"Пользователь {message.from_user.id} запустил /help.")
# Если пользователь писал в чат # Если пользователь писал в чат
if message.chat.id != message.from_user.id: if message.chat.id != message.from_user.id:
# Удаляем сообщения через 30 секунд # Удаляем сообщения через 30 секунд
await asyncio.sleep(30) await delete_messages(bot, message, time_sleep=30, number_message=2)
await bot.delete_message(message.chat.id, message.message_id)
await bot.delete_message(message.chat.id, message.message_id+1)
except Exception as e: except Exception as e:
logger.error(f"Пользователь {message.from_user.id} запустил /help: {str(e)}")
# Отправляем ошибку
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)}")

View File

@ -6,90 +6,18 @@ import time
from database import db from database import db
from action_reporter import action_reporter 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 from config import COMMAND_MESSAGES
logger = logging.getLogger(__name__) # Получаем логгер для текущего модуля # Получаем логгер для текущего модуля
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)
# Регистрирует все обработчики команд # Регистрирует все обработчики команд
def register_handlers(bot: AsyncTeleBot): def register_handlers(bot: AsyncTeleBot):
@ -102,10 +30,6 @@ def register_handlers(bot: AsyncTeleBot):
# Основная функция команды /mute # Основная функция команды /mute
async def mute_command(bot: AsyncTeleBot, message: Message, photo_path: str = None): 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 target_user = None
@ -118,100 +42,91 @@ async def mute_command(bot: AsyncTeleBot, message: Message, photo_path: str = No
# Разбиваем текст сообщения на части # Разбиваем текст сообщения на части
parts_msg = message.text.split() parts_msg = message.text.split()
# Выводим помощь # Команда /mute help
if len(parts_msg) == 2 and parts_msg[1].strip() in ['help', 'помощь']: if len(parts_msg) == 2 and parts_msg[1].strip() in ('help', 'помощь'):
await send_message(chat_id, COMMAND_MESSAGES['manual_mute'])
# Отправляем инструкцию
await bot.send_message(
chat_id=message.chat.id,
text=COMMAND_MESSAGES['manual_mute'],
message_thread_id=message.message_thread_id,
)
# Удаляем сообщения через 30 секунд # Удаляем сообщения через 30 секунд
await delete_messages(bot, message, 30) await delete_messages(bot, message, time_sleep=30, number_message=2)
return return
try: try:
# Проверяем, является ли отправитель администратором # Проверяем, является ли отправитель администратором
try: if await check_admin_status(bot, message) == 1:
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)
return return
# Если одно слово, то удаляем сообщение. Ошибка # Если одно слово (/mute)
if len(parts_msg) == 1: 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 return
# Если два слово, то ответом на сообщение # Команда через ответ на сообщение, если два слова (/mute 2m)
elif len(parts_msg) == 2: elif len(parts_msg) == 2:
# Если это тема # Если это топик
if message.is_topic_message: if message.is_topic_message:
# Если без ответа на сообщение, ошибка # Если без ответа на сообщение
if message.message_thread_id == message.reply_to_message.message_id: 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 return
# Если с ответом на сообщение # Если с ответом на сообщение
else: else:
# Собираем данные
target_user = message.reply_to_message.from_user target_user = message.reply_to_message.from_user
time_arg = parts_msg[1] 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: elif message.reply_to_message and message.is_topic_message is None:
# Собираем данные
target_user = message.reply_to_message.from_user target_user = message.reply_to_message.from_user
time_arg = parts_msg[1] time_arg = parts_msg[1]
reason = extract_reason(parts_msg[2:]) reason = 'отсутствует'
message.message_thread_id = None
# Удаляем сообщение, если команда неправильная # Если команда неправильная
else: 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 return
# В сообщении больше двух слов
else: else:
# Если второе слово это тег или ID # Если второе слово это тег или ID
if parts_msg[1].strip().isdigit() or parts_msg[1].startswith('@'): if parts_msg[1].strip().isdigit() or parts_msg[1].startswith('@'):
# Собираем данные
identifier = parts_msg[1].strip() identifier = parts_msg[1].strip()
time_arg = parts_msg[2] 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(): if identifier.isdigit():
# Делаем в int и ищем # Ищем пользователя в базе данных
user_info = db.get_user(int(identifier)) user_info = db.get_user(int(identifier))
# Если нашли пользователя
if user_info: if user_info:
# Создаем объект пользователя из данных базы
# Создаем объект пользователя
target_user = User( target_user = User(
id=user_info[0], id=user_info[0],
first_name=user_info[1], first_name=user_info[1],
@ -219,14 +134,16 @@ async def mute_command(bot: AsyncTeleBot, message: Message, photo_path: str = No
is_bot=False is_bot=False
) )
# Поиск по тегу # Делаем поиск по тегу
elif identifier.startswith('@'): elif identifier.startswith('@'):
# Убираем @ и ищем # Ищем пользователя в базе данных (убрали @)
user_info = db.get_user_by_username(identifier[1:]) user_info = db.get_user_by_username(identifier[1:])
# Если нашли пользователя
if user_info: if user_info:
# Создаем объект пользователя из данных базы
# Создаем объект пользователя
target_user = User( target_user = User(
id=user_info[0], id=user_info[0],
first_name=user_info[1], first_name=user_info[1],
@ -234,95 +151,106 @@ async def mute_command(bot: AsyncTeleBot, message: Message, photo_path: str = No
is_bot=False is_bot=False
) )
# Команда через ответ на сообщение с указанием причины
else: else:
# Если это тема # Если это топик
if message.is_topic_message: if message.is_topic_message:
# Если без ответа на сообщение, ошибка # Если без ответа на сообщение
if message.message_thread_id == message.reply_to_message.message_id: 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 return
# Если с ответом на сообщение # Если с ответом на сообщение
else: else:
# Собираем данные
target_user = message.reply_to_message.from_user target_user = message.reply_to_message.from_user
time_arg = parts_msg[1] 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: elif message.reply_to_message and message.is_topic_message is None:
# Собираем данные
target_user = message.reply_to_message.from_user target_user = message.reply_to_message.from_user
time_arg = parts_msg[1] time_arg = parts_msg[1]
reason = extract_reason(parts_msg[2:]) reason = ' '.join(parts_msg[2:])
message.message_thread_id = None
# Удаляем сообщение, если команда неправильная # Если команда неправильная
else: 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 return
# Если пользователь не найден # Если пользователь не найден в базе данных
if not target_user: 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 секунд # Удаляем сообщения через 5 секунд
await delete_messages(bot, message, 5) await delete_messages(bot, message, time_sleep=5, number_message=2)
return return
# Парсинг времени мута # Парсинг времени мута
mute_seconds = parse_mute_time(time_arg) mute_seconds = parse_mute_time(time_arg)
# Если не указали время
if mute_seconds is None: 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 секунд # Удаляем сообщения через 5 секунд
await delete_messages(bot, message, 5) await delete_messages(bot, message, time_sleep=5, number_message=2)
return return
# Минимальный мут 1 минута (60 секунд) # Минимальное время мута - 1 минута (60 секунд)
if mute_seconds < 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 секунд # Удаляем сообщения через 5 секунд
await delete_messages(bot, message, 5) await delete_messages(bot, message, time_sleep=5, number_message=2)
return return
# Максимальный мут 30 дней (2592000 секунд) # Максимальное время мута - 30 дней (2592000 секунд)
if mute_seconds > 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 секунд # Удаляем сообщения через 5 секунд
await delete_messages(bot, message, 5) await delete_messages(bot, message, time_sleep=5, number_message=2)
return return
# Проверяем статус целевого пользователя # Проверяем статус целевого пользователя
try: if await check_target_status(bot, message, target_user) == 1:
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)
return return
# Выполняем мут
try: try:
# Вычисляем время окончания мута # Вычисляем время окончания мута
@ -340,6 +268,7 @@ async def mute_command(bot: AsyncTeleBot, message: Message, photo_path: str = No
can_pin_messages=False, can_pin_messages=False,
) )
# Выполняем мут
await bot.restrict_chat_member( await bot.restrict_chat_member(
chat_id=message.chat.id, chat_id=message.chat.id,
user_id=target_user.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 until_date=until_date
) )
# Форматирование времени # Форматируем время в удобный формат
time_display = format_time(mute_seconds) time_display = format_mute_time(mute_seconds)
# Отправляем лог в админ-чат # Отправляем сообщение-лог в админ-чат
await action_reporter.log_action( await action_reporter.log_action(
action="МУТ", action="МУТ",
user_id=target_user.id, user_id=target_user.id,
admin_id=message.from_user.id, admin_id=message.from_user.id,
reason=reason, reason=reason,
duration=time_display, 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}.") logger.info(f"Пользователь {target_user.id} получил мут на {time_display} от администратора {message.from_user.id}.")
# Удаляем сообщения через 5 секунд # Удаляем сообщения через 5 секунд
await delete_messages(bot, message, 5) await delete_messages(bot, message, time_sleep=5, number_message=2)
except Exception as e: 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)}") logger.error(f"Ошибка мута: {str(e)}")
# Удаляем сообщения через 5 секунд # Удаляем сообщения через 5 секунд
await delete_messages(bot, message, 5) await delete_messages(bot, message, time_sleep=5, number_message=2)
except Exception as e: 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)}") logger.error(f"Общая ошибка в mute_command: {str(e)}")
# Удаляем сообщения через 5 секунд # Удаляем сообщения через 5 секунд
await delete_messages(bot, message, 5) await delete_messages(bot, message, time_sleep=5, number_message=2)

View File

@ -3,32 +3,46 @@ from telebot.types import Message
import asyncio import asyncio
import logging import logging
from utils import delete_messages
from config import COMMAND_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): 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: 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.") logger.info(f"Пользователь {message.from_user.id} запустил /start.")
# Если пользователь писал в чат # Если пользователь писал в чат
if message.chat.id != message.from_user.id: if message.chat.id != message.from_user.id:
# Удаляем сообщения через 5 секунд # Удаляем сообщения через 5 секунд
await asyncio.sleep(5) await delete_messages(bot, message, time_sleep=5, number_message=2)
await bot.delete_message(message.chat.id, message.message_id)
await bot.delete_message(message.chat.id, message.message_id+1)
except Exception as e: except Exception as e:
logger.error(f"Пользователь {message.from_user.id} запустил /start: {str(e)}")
# Отправляем ошибку
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)}")

View File

@ -1,116 +1,103 @@
from telebot.async_telebot import AsyncTeleBot from telebot.async_telebot import AsyncTeleBot
from telebot.types import Message, User from telebot.types import Message, User, ChatPermissions
import asyncio import asyncio
import logging import logging
from database import db from database import db
from action_reporter import action_reporter from action_reporter import action_reporter
from utils import (
delete_messages,
check_admin_status,
check_target_status,
)
from config import COMMAND_MESSAGES from config import COMMAND_MESSAGES
logger = logging.getLogger(__name__) # Получаем логгер для текущего модуля # Получаем логгер для текущего модуля
logger = logging.getLogger(__name__)
# Удаляет два последних сообщения # Регистрирует все обработчики команд
async def delete_messages(bot: AsyncTeleBot, message: Message, time_sleep: int): def register_handlers(bot: AsyncTeleBot):
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): # Регистрирует все обработчики команд # Обработчик команды /unban
@bot.message_handler(commands=['unban'])
@bot.message_handler(commands=['unban']) # Обработчик команды /unban
async def unban_command(message: Message): 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 target_user = None
# Разбиваем текст сообщения на части # Разбиваем текст сообщения на части
parts_msg = message.text.split() parts_msg = message.text.split()
# Выводим помощь (/unban help) # Команда /unban help
if len(parts_msg) == 2 and parts_msg[1].strip() in ['help', 'помощь']: if len(parts_msg) == 2 and parts_msg[1].strip() in ('help', 'помощь'):
await send_message(chat_id, COMMAND_MESSAGES['manual_unban'])
# Отправляем инструкцию
await bot.send_message(
chat_id=message.chat.id,
text=COMMAND_MESSAGES['manual_unban'],
message_thread_id=message.message_thread_id,
)
# Удаляем сообщения через 30 секунд # Удаляем сообщения через 30 секунд
await delete_messages(bot, message, 30) await delete_messages(bot, message, time_sleep=30, number_message=2)
return return
try: try:
# Проверяем, является ли отправитель администратором # Проверяем, является ли отправитель администратором
try: if await check_admin_status(bot, message) == 1:
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)
return return
# Если одно слово, то ответом на сообщение # Команда через ответ на сообщение, если одно слово (/unban)
if len(parts_msg) == 1: if len(parts_msg) == 1:
# Если это тема # Если это топик
if message.is_topic_message: if message.is_topic_message:
# Если без ответа на сообщение, ошибка # Если без ответа на сообщение
if message.message_thread_id == message.reply_to_message.message_id: 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 return
# Если с ответом на сообщение # Если с ответом на сообщение
else: else:
# Собираем данные
target_user = message.reply_to_message.from_user target_user = message.reply_to_message.from_user
# Если это обычный чат # Если это General (обычный чат)
elif message.reply_to_message and message.is_topic_message is None: elif message.reply_to_message and message.is_topic_message is None:
# Собираем данные
target_user = message.reply_to_message.from_user target_user = message.reply_to_message.from_user
message.message_thread_id = None
# Удаляем сообщение, если команда неправильная # Удаляем сообщение, если команда неправильная
else: 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 return
# Если два, то через тег или ID # Команда через тег или ID, если два слова
elif len(parts_msg) == 2: elif len(parts_msg) == 2:
# Собираем данные
identifier = parts_msg[1].strip() identifier = parts_msg[1].strip()
# Поиск по ID # Делаем поиск по ID
if identifier.isdigit(): if identifier.isdigit():
# Делаем в int и ищем # Ищем пользователя в базе данных
user_info = db.get_user(int(identifier)) user_info = db.get_user(int(identifier))
# Если нашли пользователя
if user_info: if user_info:
# Создаем объект пользователя из данных базы
# Создаем объект пользователя
target_user = User( target_user = User(
id=user_info[0], id=user_info[0],
first_name=user_info[1], first_name=user_info[1],
@ -118,14 +105,16 @@ def register_handlers(bot: AsyncTeleBot): # Регистрирует все об
is_bot=False is_bot=False
) )
# Поиск по тегу # Делаем поиск по тегу
elif identifier.startswith('@'): elif identifier.startswith('@'):
# Убираем @ и ищем # Ищем пользователя в базе данных
user_info = db.get_user_by_username(identifier[1:]) user_info = db.get_user_by_username(identifier[1:])
# Если нашли пользователя
if user_info: if user_info:
# Создаем объект пользователя из данных базы
# Создаем объект пользователя
target_user = User( target_user = User(
id=user_info[0], id=user_info[0],
first_name=user_info[1], first_name=user_info[1],
@ -133,18 +122,31 @@ def register_handlers(bot: AsyncTeleBot): # Регистрирует все об
is_bot=False is_bot=False
) )
# Если пользователь не найден # Если пользователь не найден в базе данных
if not target_user: 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 секунд # Удаляем сообщения через 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 return
# Выполняем разбан
try: 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( await action_reporter.log_action(
@ -153,26 +155,48 @@ def register_handlers(bot: AsyncTeleBot): # Регистрирует все об
admin_id=message.from_user.id, admin_id=message.from_user.id,
reason=None, reason=None,
duration=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}.") logger.info(f"Пользователь {target_user.id} разбанен администратором {message.from_user.id}.")
# Удаляем сообщения через 5 секунд # Удаляем сообщения через 5 секунд
await delete_messages(bot, message, 5) await delete_messages(bot, message, time_sleep=5, number_message=2)
except Exception as e: 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 секунд # Удаляем сообщения через 5 секунд
await delete_messages(bot, message, 5) await delete_messages(bot, message, time_sleep=5, number_message=2)
except Exception as e: 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)}") logger.error(f"Общая ошибка в unban_command: {str(e)}")
# Удаляем сообщения через 5 секунд # Удаляем сообщения через 5 секунд
await delete_messages(bot, message, 5) await delete_messages(bot, message, time_sleep=5, number_message=2)

View File

@ -5,112 +5,99 @@ import logging
from database import db from database import db
from action_reporter import action_reporter from action_reporter import action_reporter
from utils import (
delete_messages,
check_admin_status,
check_target_status,
)
from config import COMMAND_MESSAGES from config import COMMAND_MESSAGES
logger = logging.getLogger(__name__) # Получаем логгер для текущего модуля # Получаем логгер для текущего модуля
logger = logging.getLogger(__name__)
# Удаляет два последних сообщения # Регистрирует все обработчики команд
async def delete_messages(bot: AsyncTeleBot, message: Message, time_sleep: int): def register_handlers(bot: AsyncTeleBot):
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): # Регистрирует все обработчики команд # Обработчик команды /unmute
@bot.message_handler(commands=['unmute'])
@bot.message_handler(commands=['unmute']) # Обработчик команды /unmute
async def unmute_command(message: Message): 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 target_user = None
# Разбиваем текст сообщения на части # Разбиваем текст сообщения на части
parts_msg = message.text.split() parts_msg = message.text.split()
# Выводим помощь (/unmute help) # Команда /unmute help
if len(parts_msg) == 2 and parts_msg[1].strip() in ['help', 'помощь']: if len(parts_msg) == 2 and parts_msg[1].strip() in ('help', 'помощь'):
await send_message(chat_id, COMMAND_MESSAGES['manual_unmute'])
# Отправляем инструкцию
await bot.send_message(
chat_id=message.chat.id,
text=COMMAND_MESSAGES['manual_unmute'],
message_thread_id=message.message_thread_id,
)
# Удаляем сообщения через 30 секунд # Удаляем сообщения через 30 секунд
await delete_messages(bot, message, 30) await delete_messages(bot, message, time_sleep=30, number_message=2)
return return
try: try:
# Проверяем, является ли отправитель администратором # Проверяем, является ли отправитель администратором
try: if await check_admin_status(bot, message) == 1:
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)
return return
# Если одно слово, то ответом на сообщение # Команда через ответ на сообщение, если одно слово (/unmute)
if len(parts_msg) == 1: if len(parts_msg) == 1:
# Если это тема # Если это топик
if message.is_topic_message: if message.is_topic_message:
# Если без ответа на сообщение, ошибка # Если без ответа на сообщение
if message.message_thread_id == message.reply_to_message.message_id: 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 return
# Если с ответом на сообщение # Если с ответом на сообщение
else: else:
# Собираем данные
target_user = message.reply_to_message.from_user target_user = message.reply_to_message.from_user
# Если это обычный чат # Если это General (обычный чат)
elif message.reply_to_message and message.is_topic_message is None: elif message.reply_to_message and message.is_topic_message is None:
# Собираем данные
target_user = message.reply_to_message.from_user target_user = message.reply_to_message.from_user
message.message_thread_id = None
# Удаляем сообщение, если команда неправильная # Удаляем сообщение, если команда неправильная
else: 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 return
# Если два, то через тег или ID # Команда через тег или ID, если два слова
elif len(parts_msg) == 2: elif len(parts_msg) == 2:
# Собираем данные
identifier = parts_msg[1].strip() identifier = parts_msg[1].strip()
# Поиск по ID # Делаем поиск по ID
if identifier.isdigit(): if identifier.isdigit():
# Делаем в int и ищем # Ищем пользователя в базе данных
user_info = db.get_user(int(identifier)) user_info = db.get_user(int(identifier))
# Если нашли пользователя
if user_info: if user_info:
# Создаем объект пользователя из данных базы
# Создаем объект пользователя
target_user = User( target_user = User(
id=user_info[0], id=user_info[0],
first_name=user_info[1], first_name=user_info[1],
@ -118,14 +105,16 @@ def register_handlers(bot: AsyncTeleBot): # Регистрирует все об
is_bot=False is_bot=False
) )
# Поиск по тегу # Делаем поиск по тегу
elif identifier.startswith('@'): elif identifier.startswith('@'):
# Убираем @ и ищем # Ищем пользователя в базе данных
user_info = db.get_user_by_username(identifier[1:]) user_info = db.get_user_by_username(identifier[1:])
# Если нашли пользователя
if user_info: if user_info:
# Создаем объект пользователя из данных базы
# Создаем объект пользователя
target_user = User( target_user = User(
id=user_info[0], id=user_info[0],
first_name=user_info[1], first_name=user_info[1],
@ -133,17 +122,26 @@ def register_handlers(bot: AsyncTeleBot): # Регистрирует все об
is_bot=False is_bot=False
) )
# Если пользователь не найден # Если пользователь не найден в базе данных
if not target_user: 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 секунд # Удаляем сообщения через 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 return
# Выполняем размут
try: try:
# Убираем ограничения (можно писать в чат) # Убираем ограничения (можно писать в чат)
permissions = ChatPermissions( permissions = ChatPermissions(
can_send_messages=True, can_send_messages=True,
@ -153,13 +151,14 @@ def register_handlers(bot: AsyncTeleBot): # Регистрирует все об
can_add_web_page_previews=True, can_add_web_page_previews=True,
can_change_info=False, can_change_info=False,
can_invite_users=True, can_invite_users=True,
can_pin_messages=False, can_pin_messages=False
) )
# Выполняем размут
await bot.restrict_chat_member( await bot.restrict_chat_member(
chat_id=message.chat.id, chat_id=message.chat.id,
user_id=target_user.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, admin_id=message.from_user.id,
reason=None, reason=None,
duration=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}.") logger.info(f"Пользователь {target_user.id} получил размут от администратора {message.from_user.id}.")
# Удаляем сообщения через 5 секунд # Удаляем сообщения через 5 секунд
await delete_messages(bot, message, 5) await delete_messages(bot, message, time_sleep=5, number_message=2)
except Exception as e: 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)}") logger.error(f"Ошибка размута: {str(e)}")
# Удаляем сообщения через 5 секунд # Удаляем сообщения через 5 секунд
await delete_messages(bot, message, 5) await delete_messages(bot, message, time_sleep=5, number_message=2)
except Exception as e: 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)}") logger.error(f"Общая ошибка в unmute_command: {str(e)}")
# Удаляем сообщения через 5 секунд # Удаляем сообщения через 5 секунд
await delete_messages(bot, message, 5) await delete_messages(bot, message, time_sleep=5, number_message=2)

177
src/utils.py Normal file
View File

@ -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} дней"