# Система управления бранными словами # Список слов хранится в JSON файле для возможности управления через команды import json import os import logging logger = logging.getLogger(__name__) # Путь к файлу с бранными словами BAD_WORDS_FILE = os.path.join(os.path.dirname(__file__), 'data', 'bad_words.json') # Кэш для загруженных слов _bad_words_cache = None _exceptions_cache = None def load_bad_words(): """ Загружает список бранных слов из JSON файла. Returns: tuple: (список бранных слов, список исключений) """ global _bad_words_cache, _exceptions_cache try: with open(BAD_WORDS_FILE, 'r', encoding='utf-8') as f: data = json.load(f) _bad_words_cache = data.get('bad_words', []) _exceptions_cache = data.get('exceptions', []) logger.info(f"Загружено {len(_bad_words_cache)} бранных слов и {len(_exceptions_cache)} исключений") return _bad_words_cache, _exceptions_cache except FileNotFoundError: logger.error(f"Файл {BAD_WORDS_FILE} не найден") return [], [] except json.JSONDecodeError as e: logger.error(f"Ошибка чтения JSON: {e}") return [], [] def save_bad_words(bad_words: list, exceptions: list): """ Сохраняет список бранных слов в JSON файл. Args: bad_words: Список бранных слов exceptions: Список исключений Returns: bool: True если успешно, иначе False """ global _bad_words_cache, _exceptions_cache try: # Создаем директорию, если её нет os.makedirs(os.path.dirname(BAD_WORDS_FILE), exist_ok=True) data = { 'bad_words': sorted(list(set(bad_words))), # Убираем дубликаты и сортируем 'exceptions': sorted(list(set(exceptions))) } with open(BAD_WORDS_FILE, 'w', encoding='utf-8') as f: json.dump(data, f, ensure_ascii=False, indent=2) # Обновляем кэш _bad_words_cache = data['bad_words'] _exceptions_cache = data['exceptions'] logger.info(f"Сохранено {len(_bad_words_cache)} бранных слов и {len(_exceptions_cache)} исключений") return True except Exception as e: logger.error(f"Ошибка сохранения: {e}") return False def get_bad_words(): """Возвращает список бранных слов (с кэшированием)""" global _bad_words_cache if _bad_words_cache is None: load_bad_words() return _bad_words_cache or [] def get_exceptions(): """Возвращает список исключений (с кэшированием)""" global _exceptions_cache if _exceptions_cache is None: load_bad_words() return _exceptions_cache or [] def reload_words(): """Перезагружает списки из файла (сбрасывает кэш)""" global _bad_words_cache, _exceptions_cache _bad_words_cache = None _exceptions_cache = None return load_bad_words() # Загружаем слова при импорте модуля BAD_WORDS, EXCEPTIONS = load_bad_words() def contains_bad_word(text: str) -> bool: """ Проверяет, содержит ли текст бранные слова. Args: text: Текст для проверки Returns: True, если найдено бранное слово, иначе False """ if not text: return False # Приводим к нижнему регистру для проверки text_lower = text.lower() # Получаем актуальные списки из кэша bad_words = get_bad_words() exceptions = get_exceptions() # Проверяем исключения for exception in exceptions: if exception in text_lower: text_lower = text_lower.replace(exception, '') # Проверяем бранные слова for bad_word in bad_words: if bad_word in text_lower: return True return False def get_bad_words_from_text(text: str) -> list: """ Возвращает список найденных бранных слов в тексте. Args: text: Текст для проверки Returns: Список найденных бранных слов """ if not text: return [] text_lower = text.lower() found_words = [] # Получаем актуальные списки из кэша bad_words = get_bad_words() exceptions = get_exceptions() # Проверяем исключения for exception in exceptions: if exception in text_lower: text_lower = text_lower.replace(exception, '') # Ищем бранные слова for bad_word in bad_words: if bad_word in text_lower: found_words.append(bad_word) return found_words