Files
LGBot/src/modules/warn.py

244 lines
9.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from telebot.async_telebot import AsyncTeleBot
from telebot.types import Message, User, ChatPermissions
import logging
import time
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 register_handlers(bot: AsyncTeleBot):
# Обработчик команды /warn
@bot.message_handler(commands=['warn'])
async def _warn_command_wrapper(message: Message):
await warn_command(bot, message)
# Основная функция команды /warn
async def warn_command(bot: AsyncTeleBot, message: Message):
# Определяем целевого пользователя
target_user = None
# Определяем причину
reason = None
# Разбиваем текст сообщения на части
parts_msg = message.text.split()
# Команда /warn 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_warn'],
message_thread_id=message.message_thread_id,
)
# Удаляем сообщения через 30 секунд
await delete_messages(bot, message, time_sleep=30, number_message=2)
return
try:
# Проверяем, является ли отправитель администратором с правом ограничения
if await check_admin_status(bot, message) == 1:
return
# Если одно слово (/warn)
if len(parts_msg) == 1:
# Удаляем сообщение через 3 секунды
await delete_messages(bot, message, time_sleep=3, number_message=1)
return
# Команда через ответ на сообщение, если два или более слов (/warn причина)
if message.reply_to_message and (not message.is_topic_message or message.message_thread_id != message.reply_to_message.message_id):
# Собираем данные
target_user = message.reply_to_message.from_user
reason = ' '.join(parts_msg[1:]) if len(parts_msg) > 1 else 'отсутствует'
# Если второе слово это тег или ID
elif len(parts_msg) >= 2 and (parts_msg[1].strip().isdigit() or parts_msg[1].startswith('@')):
# Собираем данные
identifier = parts_msg[1].strip()
reason = ' '.join(parts_msg[2:]) if len(parts_msg) > 2 else 'отсутствует'
# Делаем поиск по ID
if identifier.isdigit():
# Ищем пользователя в базе данных
user_info = db.get_user(int(identifier))
# Если нашли пользователя
if user_info:
# Создаем объект пользователя
target_user = User(
id=user_info[0],
first_name=user_info[1],
username=user_info[2],
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],
username=user_info[2],
is_bot=False
)
# Если команда неправильная
else:
# Удаляем сообщение через 3 секунды
await delete_messages(bot, message, time_sleep=3, number_message=1)
return
# Если пользователь не найден в базе данных
if not target_user:
# Отправляем предупреждение
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, time_sleep=5, number_message=2)
return
# Проверяем статус целевого пользователя
if await check_target_status(bot, message, target_user) == 1:
return
# Добавляем предупреждение в БД
db.add_warning(
user_id=target_user.id,
chat_id=message.chat.id,
reason=reason,
admin_id=message.from_user.id
)
# Импортируем константы времени
from config import ONE_WEEK, TWO_WEEKS
# Проверяем количество предупреждений
warns_week = db.get_warnings_count(target_user.id, message.chat.id, ONE_WEEK)
warns_two_weeks = db.get_warnings_count(target_user.id, message.chat.id, TWO_WEEKS)
logger.info(f"Предупреждений за неделю: {warns_week}, за 2 недели: {warns_two_weeks}")
# Определяем, нужно ли применять мут
mute_applied = False
mute_duration = 0
mute_duration_text = ""
response_message = COMMAND_MESSAGES['warned']
# Если это уже 2+ предупреждение за неделю -> мут на неделю
if warns_week >= 2:
mute_duration = 604800 # 7 дней
mute_duration_text = "7 дней"
response_message = COMMAND_MESSAGES['warned_auto_mute_week']
mute_applied = True
logger.info(f"Применен мут на неделю (предупреждений за неделю: {warns_week})")
# Если это 2-е предупреждение за 2 недели (но не за неделю) -> мут на сутки
elif warns_two_weeks >= 2:
mute_duration = 86400 # 1 день
mute_duration_text = "1 день"
response_message = COMMAND_MESSAGES['warned_auto_mute_day']
mute_applied = True
logger.info(f"Применен мут на сутки (предупреждений за 2 недели: {warns_two_weeks})")
# Применяем мут если нужно
if mute_applied:
try:
# Вычисляем время окончания мута
until_date = int(time.time()) + mute_duration
# Устанавливаем ограничения (только чтение)
permissions = ChatPermissions(
can_send_messages=False,
can_send_media_messages=False,
can_send_polls=False,
can_send_other_messages=False,
can_add_web_page_previews=False,
can_change_info=False,
can_invite_users=False,
can_pin_messages=False,
)
# Выполняем мут
await bot.restrict_chat_member(
chat_id=message.chat.id,
user_id=target_user.id,
permissions=permissions,
until_date=until_date
)
logger.info(f"Пользователь {target_user.id} получил автомут на {mute_duration_text} после варна")
except Exception as e:
logger.error(f"Ошибка при применении мута после варна: {str(e)}")
# Отправляем сообщение-лог в админ-чат
await action_reporter.log_action(
action="ВАРН" if not mute_applied else f"ВАРН + МУТ ({mute_duration_text})",
user_id=target_user.id,
admin_id=message.from_user.id,
reason=reason,
duration=mute_duration_text if mute_applied else None,
)
# Отправляем сообщение в чат
await bot.send_message(
chat_id=message.chat.id,
text=response_message,
message_thread_id=message.message_thread_id,
)
# Записываем действие в логи
logger.info(f"Администратор {message.from_user.id} выдал предупреждение пользователю {target_user.id}. Причина: {reason}")
# Удаляем сообщения через 5 секунд
await delete_messages(bot, message, time_sleep=5, number_message=2)
except Exception as e:
# Отправляем ошибку
await bot.send_message(
chat_id=message.chat.id,
text=COMMAND_MESSAGES['general_error'],
message_thread_id=message.message_thread_id,
)
# Записываем ошибку в логи
logger.error(f"Общая ошибка в warn_command: {str(e)}")
# Удаляем сообщения через 5 секунд
await delete_messages(bot, message, time_sleep=5, number_message=2)