From 2b9e819944764083798d4b2e85f2b6fac34f5acb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=B2=D0=B3=D0=B5=D0=BD=D0=B8=D0=B9=20=D0=A5=D1=80?= =?UTF-8?q?=D0=B0=D0=BC=D0=BE=D0=B2?= Date: Sun, 19 Oct 2025 14:14:35 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BA=D0=BE=D0=BC=D0=B0=D0=BD=D0=B4=D1=8B?= =?UTF-8?q?=20=D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BA=D0=B8=20?= =?UTF-8?q?=D0=BA=D0=B0=D1=80=D0=BC=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/config.py | 16 ++++ src/database.py | 25 +++++ src/main.py | 9 +- src/modules/setkarma.py | 198 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 244 insertions(+), 4 deletions(-) create mode 100644 src/modules/setkarma.py diff --git a/src/config.py b/src/config.py index 8546b7c..de72405 100644 --- a/src/config.py +++ b/src/config.py @@ -211,6 +211,22 @@ COMMAND_MESSAGES = { "🎯 Использование:\n" " /top\n\n" "💡 Система кармы поощряет активных и полезных участников чата!" + ), + 'setkarma_help': ( + "🎚 Команда /setkarma\n\n" + "Устанавливает карму пользователя в указанное значение (только для администраторов)\n\n" + "🎯 Способы использования:\n" + "1. Ответ на сообщение:\n" + " /setkarma 100\n" + "2. По тегу пользователя:\n" + " /setkarma @username 50\n" + "3. По ID пользователя:\n" + " /setkarma 123456789 -10\n\n" + "💡 Примеры:\n" + "• Установить карму на 0: /setkarma @user 0\n" + "• Установить отрицательную карму: /setkarma @user -50\n" + "• Установить высокую карму: /setkarma @user 1000\n\n" + "⚠️ Команда доступна только администраторам с правами ограничения" ) } \ No newline at end of file diff --git a/src/database.py b/src/database.py index 6fb4837..3e6f287 100644 --- a/src/database.py +++ b/src/database.py @@ -287,6 +287,31 @@ class Database: # Инициализация класса connect.commit() logger.info(f"Пользователю {user_id} добавлено {amount} кармы в чате {chat_id}") + # Устанавливает карму пользователя в указанное значение + def set_karma(self, user_id: int, chat_id: int, karma_value: int): + with self._get_connection() as connect: + cursor = connect.cursor() + # Проверяем существование записи + cursor.execute('SELECT karma_points FROM karma WHERE user_id = ? AND chat_id = ?', (user_id, chat_id)) + result = cursor.fetchone() + + if result: + # Обновляем существующую карму + cursor.execute(''' + UPDATE karma + SET karma_points = ? + WHERE user_id = ? AND chat_id = ? + ''', (karma_value, user_id, chat_id)) + else: + # Создаем новую запись + cursor.execute(''' + INSERT INTO karma (user_id, chat_id, karma_points) + VALUES (?, ?, ?) + ''', (user_id, chat_id, karma_value)) + + connect.commit() + logger.info(f"Карма пользователя {user_id} установлена на {karma_value} в чате {chat_id}") + # Получает карму пользователя def get_karma(self, user_id: int, chat_id: int) -> int: with self._get_connection() as connect: diff --git a/src/main.py b/src/main.py index 2ddf807..941e21a 100644 --- a/src/main.py +++ b/src/main.py @@ -77,11 +77,11 @@ class UserUpdateMiddleware(BaseMiddleware): ) # ВАЖНО: Кэшируем сообщение для обработки реакций - # Импортируем функцию кэширования из karma_tracker + # Импортируем функцию кэширования из 0_karma_tracker try: - from modules import karma_tracker - if hasattr(karma_tracker, '_cache_message') and message.chat.type in ['group', 'supergroup']: - karma_tracker._cache_message(message.chat.id, message.message_id, message.from_user.id) + karma_module = importlib.import_module("modules.0_karma_tracker") + if message.chat.type in ['group', 'supergroup']: + karma_module._cache_message(message.chat.id, message.message_id, message.from_user.id) logger.info(f"[CACHE] Сообщение {message.message_id} от {message.from_user.id} добавлено в кэш, chat_id={message.chat.id}") except Exception as e: logger.error(f"Ошибка кэширования сообщения: {e}", exc_info=True) @@ -260,6 +260,7 @@ async def setup_bot_commands(): BotCommand("botdata", "Получить данные бота (только для админов)"), BotCommand("karma", "Просмотр кармы пользователя"), BotCommand("top", "Топ-10 пользователей по карме"), + BotCommand("setkarma", "Установить карму пользователя. Использование: /setkarma help"), ] await bot.set_my_commands(commands) diff --git a/src/modules/setkarma.py b/src/modules/setkarma.py new file mode 100644 index 0000000..11629bf --- /dev/null +++ b/src/modules/setkarma.py @@ -0,0 +1,198 @@ +from telebot.async_telebot import AsyncTeleBot +from telebot.types import Message, User +import logging + +from database import db +from action_reporter import action_reporter +from utils import delete_messages, check_admin_status + +from config import COMMAND_MESSAGES + +# Получаем логгер для текущего модуля +logger = logging.getLogger(__name__) + +# Регистрирует обработчик команды +def register_handlers(bot: AsyncTeleBot): + + # Обработчик команды /setkarma + @bot.message_handler(commands=['setkarma']) + async def _setkarma_command_wrapper(message: Message): + await setkarma_command(bot, message) + +# Основная функция команды /setkarma +async def setkarma_command(bot: AsyncTeleBot, message: Message): + """Устанавливает карму пользователя в указанное значение""" + + # Определяем целевого пользователя + target_user = None + + # Определяем новое значение кармы + new_karma_value = None + + # Разбиваем текст сообщения на части + parts_msg = message.text.split() + + # Команда /setkarma 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['setkarma_help'], + 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 + + # Проверяем, что это групповой чат + if message.chat.type not in ['group', 'supergroup']: + await bot.send_message( + chat_id=message.chat.id, + text="❌ Эта команда работает только в групповых чатах.", + message_thread_id=message.message_thread_id, + ) + await delete_messages(bot, message, time_sleep=5, number_message=2) + return + + # Если недостаточно аргументов + if len(parts_msg) < 2: + await delete_messages(bot, message, time_sleep=3, number_message=1) + return + + # Команда через ответ на сообщение: /setkarma 100 + if message.reply_to_message and (not message.is_topic_message or message.message_thread_id != message.reply_to_message.message_id): + if len(parts_msg) >= 2: + target_user = message.reply_to_message.from_user + try: + new_karma_value = int(parts_msg[1]) + except ValueError: + await bot.send_message( + chat_id=message.chat.id, + text="❌ Неверный формат кармы. Укажите целое число.", + message_thread_id=message.message_thread_id, + ) + await delete_messages(bot, message, time_sleep=5, number_message=2) + return + + # Команда с указанием пользователя: /setkarma @username 100 или /setkarma 123456789 100 + elif len(parts_msg) >= 3 and (parts_msg[1].strip().isdigit() or parts_msg[1].startswith('@')): + identifier = parts_msg[1].strip() + try: + new_karma_value = int(parts_msg[2]) + except ValueError: + await bot.send_message( + chat_id=message.chat.id, + text="❌ Неверный формат кармы. Укажите целое число.", + message_thread_id=message.message_thread_id, + ) + await delete_messages(bot, message, time_sleep=5, number_message=2) + return + + # Поиск по 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: + 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, + ) + await delete_messages(bot, message, time_sleep=5, number_message=2) + return + + # Проверяем, не пытается ли установить карму себе + if message.from_user.id == target_user.id: + await bot.send_message( + chat_id=message.chat.id, + text="❌ Нельзя устанавливать карму самому себе.", + message_thread_id=message.message_thread_id, + ) + await delete_messages(bot, message, time_sleep=5, number_message=2) + return + + # Получаем текущую карму + old_karma = db.get_karma(target_user.id, message.chat.id) + + # Устанавливаем новую карму + db.set_karma(target_user.id, message.chat.id, new_karma_value) + + # Формируем имя пользователя для отображения + target_user_display = f"@{target_user.username}" if target_user.username else target_user.first_name + + # Вычисляем разницу + karma_diff = new_karma_value - old_karma + diff_sign = "+" if karma_diff > 0 else "" + + # Отправляем сообщение-лог в админ-чат + await action_reporter.log_action( + action="УСТАНОВКА КАРМЫ", + user_id=target_user.id, + admin_id=message.from_user.id, + reason=f"Карма изменена: {old_karma} → {new_karma_value} ({diff_sign}{karma_diff})", + duration=None, + ) + + # Отправляем сообщение в чат + response = ( + f"✅ Карма пользователя {target_user_display} установлена на {new_karma_value}\n" + f"Было: {old_karma} → Стало: {new_karma_value} ({diff_sign}{karma_diff})" + ) + await bot.send_message( + chat_id=message.chat.id, + text=response, + message_thread_id=message.message_thread_id, + ) + + # Записываем действие в логи + logger.info( + f"Администратор {message.from_user.id} установил карму пользователя {target_user.id} " + f"на {new_karma_value} (было {old_karma})" + ) + + # Удаляем сообщения через 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"Общая ошибка в setkarma_command: {str(e)}") + + # Удаляем сообщения через 5 секунд + await delete_messages(bot, message, time_sleep=5, number_message=2) \ No newline at end of file