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