diff --git a/src/config.py b/src/config.py
index 5ec5140..0d7df63 100644
--- a/src/config.py
+++ b/src/config.py
@@ -123,6 +123,18 @@ COMMAND_MESSAGES = {
"Прочее:\n"
"• /badwords reload
- Перезагрузить из файла\n\n"
"💡 Все изменения применяются немедленно"
+ ),
+ 'reset_violations_help': (
+ "🔄 Команда /reset_violations\n\n"
+ "Сбрасывает счётчик нарушений пользователя\n\n"
+ "🎯 Способы использования:\n"
+ "1. Ответ на сообщение:\n"
+ " /reset_violations
\n"
+ "2. По тегу пользователя:\n"
+ " /reset_violations @username
\n"
+ "3. По ID пользователя:\n"
+ " /reset_violations 123456789
\n\n"
+ "ℹ️ Сбрасывает все записи об автомутах пользователя"
)
}
\ No newline at end of file
diff --git a/src/database.py b/src/database.py
index 9cd2169..6c21a18 100644
--- a/src/database.py
+++ b/src/database.py
@@ -143,5 +143,18 @@ class Database: # Инициализация класса
logger.info(f"Удалено старых нарушений: {deleted_count}")
return deleted_count
+ # Сбрасывает все нарушения пользователя в чате
+ def reset_user_violations(self, user_id: int, chat_id: int):
+ with self._get_connection() as connect:
+ cursor = connect.cursor()
+ cursor.execute('''
+ DELETE FROM violations
+ WHERE user_id = ? AND chat_id = ?
+ ''', (user_id, chat_id))
+ deleted_count = cursor.rowcount
+ connect.commit()
+ logger.info(f"Сброшено {deleted_count} нарушений пользователя {user_id} в чате {chat_id}")
+ return deleted_count
+
# Создаем экземпляр базы данных для импорта в других модулях
db = Database()
\ No newline at end of file
diff --git a/src/main.py b/src/main.py
index 02e2914..98c0290 100644
--- a/src/main.py
+++ b/src/main.py
@@ -124,6 +124,7 @@ async def setup_bot_commands():
BotCommand("mute", "Замутить пользователя. Использование: /mute help"),
BotCommand("unmute", "Размутить пользователя. Использование: /unmute help"),
BotCommand("badwords", "Управление списком бранных слов. /badwords help"),
+ BotCommand("reset_violations", "Сбросить счётчик нарушений пользователя"),
BotCommand("botdata", "Получить данные бота (только для админов)"),
]
diff --git a/src/modules/auto_mute.py b/src/modules/auto_mute.py
index e6e904e..0829b35 100644
--- a/src/modules/auto_mute.py
+++ b/src/modules/auto_mute.py
@@ -56,7 +56,7 @@ def get_mute_duration(violations_count: int) -> int:
return MUTE_LEVELS[level_index]
-async def apply_mute(bot: AsyncTeleBot, message: Message, user_id: int, duration: int, violations_count: int):
+async def apply_mute(bot: AsyncTeleBot, message: Message, user_id: int, duration: int, violations_count: int, bad_words_found: list = None):
"""
Применяет мут к пользователю.
@@ -66,6 +66,7 @@ async def apply_mute(bot: AsyncTeleBot, message: Message, user_id: int, duration
user_id: ID пользователя
duration: Длительность мута в секундах (None для перманентного)
violations_count: Количество нарушений
+ bad_words_found: Список найденных плохих слов
"""
try:
# Устанавливаем ограничения (только чтение)
@@ -97,6 +98,14 @@ async def apply_mute(bot: AsyncTeleBot, message: Message, user_id: int, duration
except Exception as e:
logger.warning(f"Не удалось удалить сообщение: {e}")
+ # Формируем информацию о найденных словах
+ words_info = ""
+ if bad_words_found:
+ words_list = ", ".join([f"«{word}»" for word in bad_words_found])
+ words_info = f"Найдено слов: {words_list}"
+ else:
+ words_info = "Использование нецензурной лексики"
+
# Формируем сообщение о муте
if duration is None:
time_display = "навсегда"
@@ -127,7 +136,7 @@ async def apply_mute(bot: AsyncTeleBot, message: Message, user_id: int, duration
action="АВТОМУТ",
user_id=user_id,
admin_id=None, # Автоматическое действие
- reason=f"Использование нецензурной лексики (нарушение #{violations_count})",
+ reason=f"{words_info} (нарушение #{violations_count})",
duration=time_display,
)
@@ -160,6 +169,9 @@ async def check_message_for_profanity(bot: AsyncTeleBot, message: Message):
if not contains_bad_word(message.text):
return
+ # Получаем список найденных плохих слов
+ bad_words_found = get_bad_words_from_text(message.text)
+
# Получаем ID пользователя и чата
user_id = message.from_user.id
chat_id = message.chat.id
@@ -184,7 +196,7 @@ async def check_message_for_profanity(bot: AsyncTeleBot, message: Message):
mute_duration = get_mute_duration(violations_count)
# Применяем мут
- await apply_mute(bot, message, user_id, mute_duration, violations_count)
+ await apply_mute(bot, message, user_id, mute_duration, violations_count, bad_words_found)
def register_handlers(bot: AsyncTeleBot):
"""
diff --git a/src/modules/reset_violations.py b/src/modules/reset_violations.py
new file mode 100644
index 0000000..c160204
--- /dev/null
+++ b/src/modules/reset_violations.py
@@ -0,0 +1,120 @@
+from telebot.async_telebot import AsyncTeleBot
+from telebot.types import Message
+import logging
+
+from database import db
+from utils import check_admin_status, delete_messages
+from config import COMMAND_MESSAGES
+
+logger = logging.getLogger(__name__)
+
+def register_handlers(bot: AsyncTeleBot):
+ """Регистрирует обработчик команды сброса нарушений"""
+
+ @bot.message_handler(commands=['reset_violations'])
+ async def reset_violations_command(message: Message):
+ """Команда для сброса счётчика нарушений пользователя"""
+
+ logger.info(f"Команда /reset_violations получена от пользователя {message.from_user.id}")
+
+ # Проверяем права администратора
+ admin_check = await check_admin_status(bot, message)
+ if admin_check == 1:
+ logger.info(f"Пользователь {message.from_user.id} не является администратором")
+ return
+
+ logger.info(f"Пользователь {message.from_user.id} прошел проверку прав администратора")
+
+ # Определяем целевого пользователя
+ target_user = None
+ target_user_id = None
+
+ # Обработка ответа на сообщение
+ if message.reply_to_message:
+ target_user = message.reply_to_message.from_user
+ target_user_id = target_user.id
+
+ # Обработка по username или ID
+ else:
+ parts = message.text.split(maxsplit=1)
+
+ if len(parts) < 2:
+ await send_temp_message(
+ bot,
+ message,
+ COMMAND_MESSAGES['reset_violations_help']
+ )
+ return
+
+ identifier = parts[1].strip()
+
+ # Попытка получить по username
+ if identifier.startswith('@'):
+ username = identifier[1:]
+ user_data = db.get_user_by_username(username)
+ if user_data:
+ target_user_id = user_data[0]
+ else:
+ await send_temp_message(
+ bot,
+ message,
+ COMMAND_MESSAGES['user_not_found']
+ )
+ return
+
+ # Попытка получить по ID
+ else:
+ try:
+ target_user_id = int(identifier)
+ except ValueError:
+ await send_temp_message(
+ bot,
+ message,
+ COMMAND_MESSAGES['user_not_found']
+ )
+ return
+
+ # Проверяем, что нашли пользователя
+ if not target_user_id:
+ await send_temp_message(
+ bot,
+ message,
+ COMMAND_MESSAGES['user_not_found']
+ )
+ return
+
+ # Получаем информацию о пользователе из базы
+ user_info = db.get_user(target_user_id)
+
+ # Получаем текущее количество нарушений
+ violations_count = db.get_violations_count(target_user_id, message.chat.id)
+
+ # Сбрасываем нарушения
+ deleted_count = db.reset_user_violations(target_user_id, message.chat.id)
+
+ # Формируем сообщение
+ if user_info:
+ _, nickname, tag = user_info
+ user_display = f"{nickname}"
+ if tag:
+ user_display += f" (@{tag})"
+ else:
+ user_display = f"{target_user_id}
"
+
+ response = (
+ f"✅ Счётчик нарушений сброшен\n\n"
+ f"👤 Пользователь: {user_display}\n"
+ f"📊 Удалено нарушений: {deleted_count}"
+ )
+
+ await send_temp_message(bot, message, response, time_sleep=30)
+ logger.info(f"Администратор {message.from_user.id} сбросил счётчик нарушений пользователя {target_user_id}")
+
+async def send_temp_message(bot: AsyncTeleBot, message: Message, text: str, time_sleep: int = 10):
+ """Отправляет временное сообщение, которое удаляется через указанное время"""
+ await bot.send_message(
+ chat_id=message.chat.id,
+ text=text,
+ message_thread_id=message.message_thread_id,
+ )
+ await delete_messages(bot, message, time_sleep=time_sleep, number_message=2)
\ No newline at end of file