diff --git a/.env.example b/.env.example index 5849c63..2d6bf66 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,3 @@ BOT_TOKEN = "..." # Токен бота получать у @BotFather ADMIN_CHAT_ID = -1001111111111 # ID админ-чата получать у @username_to_id_bot -LOG_THREAD_ID = 2 # ID топика, брать из ссылки сообщения -ADMIN_IDS = "11111,22222" # ID администраторов получать у @username_to_id_bot \ No newline at end of file +LOG_THREAD_ID = 2 # ID топика, брать из ссылки сообщения \ No newline at end of file diff --git a/.gigaide/gigaide.properties b/.gigaide/gigaide.properties index da0696a..064b3d2 100644 --- a/.gigaide/gigaide.properties +++ b/.gigaide/gigaide.properties @@ -1,5 +1,5 @@ -## changed at Sun Oct 12 15:29:33 MSK 2025 -#Sun Oct 12 15:29:33 MSK 2025 +## changed at Sat Oct 18 12:59:47 MSK 2025 +#Sat Oct 18 12:59:47 MSK 2025 com.gigaide.elements.ext.marker.solution.BeanMarkedPsi.shouldMark=true com.gigaide.elements.ext.marker.solution.ConfigMarkedPsi.shouldMark=true com.gigaide.elements.ext.marker.solution.DataMarkedPsi.shouldMark=true diff --git a/requirements.txt b/requirements.txt index 8b5c218..10f0dd3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,7 +5,6 @@ asyncio==3.4.3 attrs==25.3.0 certifi==2025.6.15 charset-normalizer==3.4.2 -dotenv==0.9.9 frozenlist==1.7.0 idna==3.10 multidict==6.6.3 diff --git a/src/action_reporter.py b/src/action_reporter.py index 1614223..0811318 100644 --- a/src/action_reporter.py +++ b/src/action_reporter.py @@ -26,11 +26,18 @@ class ActionReporter: if tag: text += f"• Tag: @{tag}\n" text += f"• ID: {user_id}" + else: + # Пользователь не найден в БД + text = f"👤 Пользователь:\n• ID: {user_id}" return text # Получает информацию об администраторе - async def _get_admin_info(self, admin_id: int) -> str: + async def _get_admin_info(self, admin_id: int | None) -> str: + # Если админ не указан (автоматическое действие) + if admin_id is None: + return "🤖 Администратор: Автоматическое действие" + admin_info = db.get_user(admin_id) if admin_info: @@ -44,11 +51,14 @@ class ActionReporter: if tag: text += f"• Tag: @{tag}\n" text += f"• ID: {admin_id}" + else: + # Администратор не найден в БД + text = f"🛡 Администратор:\n• ID: {admin_id}" return text # Отправляет лог действия в админ-чат - async def log_action(self, action: str, user_id: int, admin_id: int, reason: str, duration: str, photo_path: str = None): + async def log_action(self, action: str, user_id: int, admin_id: int | None, reason: str, duration: str, photo_path: str = None): try: # Получаем информацию о пользователе и администраторе diff --git a/src/bad_words.py b/src/bad_words.py index b718e38..9684429 100644 --- a/src/bad_words.py +++ b/src/bad_words.py @@ -93,8 +93,8 @@ def reload_words(): _exceptions_cache = None return load_bad_words() -# Загружаем слова при импорте модуля -BAD_WORDS, EXCEPTIONS = load_bad_words() +# Предзагружаем слова при импорте модуля в кэш +load_bad_words() def contains_bad_word(text: str) -> bool: """ diff --git a/src/main.py b/src/main.py index 98c0290..fe04c32 100644 --- a/src/main.py +++ b/src/main.py @@ -18,6 +18,32 @@ from config import MODULES_DIR # Загружаем токен бота из .env load_dotenv() + +# Валидация переменных окружения +def validate_env_vars(): + """Проверяет наличие всех необходимых переменных окружения""" + required_vars = { + "BOT_TOKEN": "Токен бота", + "ADMIN_CHAT_ID": "ID админ-чата", + "LOG_THREAD_ID": "ID топика для логов" + } + + missing_vars = [] + for var_name, description in required_vars.items(): + value = os.getenv(var_name) + if not value or value.strip() == "" or value == "...": + missing_vars.append(f"{var_name} ({description})") + + if missing_vars: + print("\n❌ ОШИБКА: Не заполнены необходимые переменные окружения в файле .env:") + for var in missing_vars: + print(f" • {var}") + print("\nПожалуйста, заполните файл .env на основе .env.example") + sys.exit(1) + +# Проверяем переменные окружения +validate_env_vars() + bot = AsyncTeleBot(os.getenv("BOT_TOKEN"), parse_mode="html") # Загружаем ID админ-чата из .env и инициализируемся для логов в чат @@ -67,10 +93,6 @@ bot.setup_middleware(UserUpdateMiddleware(db)) # Загружает все модули из директории /modules async def load_modules(): - - # Инициализация логирования - setup_logging() - # Переменная для подсчёта модулей loaded_count = 0 @@ -116,7 +138,7 @@ async def setup_bot_commands(): from telebot.types import BotCommand commands = [ - BotCommand("start", "Начало работы сботом"), + BotCommand("start", "Начало работы с ботом"), BotCommand("help", "Справка по всем командам"), BotCommand("log", "Инструкция по созданию лога ошибки"), BotCommand("ban", "Забанить пользователя. Использование: /ban help"), @@ -132,6 +154,8 @@ async def setup_bot_commands(): logger.info("Команды бота успешно установлены.") async def main(): + # Инициализация логирования (должна быть первой) + setup_logging() # Очищаем терминал os.system('clear') diff --git a/src/modules/auto_mute.py b/src/modules/auto_mute.py index 0829b35..f03c2a5 100644 --- a/src/modules/auto_mute.py +++ b/src/modules/auto_mute.py @@ -28,7 +28,7 @@ MUTE_LEVELS = [ 259200, # 11. 3 дня 432000, # 12. 5 дней 604800, # 13. 7 дней - None, # 16. Перманентный мут (режим только чтения навсегда) + None, # 14. Перманентный мут (режим только чтения навсегда) ] # Период для подсчета нарушений (30 дней в секундах) diff --git a/src/modules/ban.py b/src/modules/ban.py index 768c929..e1f2234 100644 --- a/src/modules/ban.py +++ b/src/modules/ban.py @@ -62,7 +62,7 @@ async def ban_command(bot: AsyncTeleBot, message: Message, photo_path: str = Non if message.is_topic_message: # Если без ответа на сообщение - if message.message_thread_id == message.reply_to_message.message_id: + if not message.reply_to_message or message.message_thread_id == message.reply_to_message.message_id: # Удаляем сообщение через 3 секунды await delete_messages(bot, message, time_sleep=3, number_message=1) @@ -141,7 +141,7 @@ async def ban_command(bot: AsyncTeleBot, message: Message, photo_path: str = Non if message.is_topic_message: # Если без ответа на сообщение - if message.message_thread_id == message.reply_to_message.message_id: + if not message.reply_to_message or message.message_thread_id == message.reply_to_message.message_id: # Удаляем сообщение через 3 секунды await delete_messages(bot, message, time_sleep=3, number_message=1) diff --git a/src/modules/mute.py b/src/modules/mute.py index b794c46..da72c01 100644 --- a/src/modules/mute.py +++ b/src/modules/mute.py @@ -76,7 +76,7 @@ async def mute_command(bot: AsyncTeleBot, message: Message, photo_path: str = No if message.is_topic_message: # Если без ответа на сообщение - if message.message_thread_id == message.reply_to_message.message_id: + if not message.reply_to_message or message.message_thread_id == message.reply_to_message.message_id: # Удаляем сообщение через 3 секунды await delete_messages(bot, message, time_sleep=3, number_message=1) @@ -158,7 +158,7 @@ async def mute_command(bot: AsyncTeleBot, message: Message, photo_path: str = No if message.is_topic_message: # Если без ответа на сообщение - if message.message_thread_id == message.reply_to_message.message_id: + if not message.reply_to_message or message.message_thread_id == message.reply_to_message.message_id: # Удаляем сообщение через 3 секунды await delete_messages(bot, message, time_sleep=3, number_message=1)