diff --git a/bot/filters/modes.py b/bot/filters/modes.py new file mode 100644 index 0000000..fbc3248 --- /dev/null +++ b/bot/filters/modes.py @@ -0,0 +1,184 @@ +""" +Фильтры для проверки активных режимов бота (silence, conflict) +""" +from datetime import datetime +from typing import Optional + +from aiogram.filters import BaseFilter +from aiogram.types import Message + +from middleware.loggers import logger + +__all__ = ('IsSilenceActive', 'IsConflictModeActive') + + +class IsSilenceActive(BaseFilter): + """ + Проверяет, активен ли режим тишины (silence mode). + + В режиме тишины удаляются ВСЕ сообщения (кроме админов). + + Attributes: + silence_until: Время до которого активен режим (None = неактивен) + + Example: + ```python + # В handler-файле + silence_filter = IsSilenceActive() + + @router.message(silence_filter) + async def silence_mode_active(message: Message): + # Удаляем все сообщения в режиме тишины + await message.delete() + ``` + """ + + def __init__(self, silence_until: Optional[datetime] = None): + """ + Args: + silence_until: Datetime до которого активен режим + """ + self.silence_until = silence_until + + def update_silence_until(self, new_datetime: Optional[datetime]) -> None: + """ + Обновляет время окончания режима тишины. + + Args: + new_datetime: Новое время окончания или None для отключения + """ + self.silence_until = new_datetime + + if new_datetime: + logger.info( + f"Режим тишины активирован до {new_datetime.strftime('%H:%M:%S')}", + log_type='SILENCE' + ) + else: + logger.info("Режим тишины отключен", log_type='SILENCE') + + def is_active(self) -> bool: + """ + Проверяет, активен ли режим сейчас. + + Returns: + bool: True если режим активен + """ + if self.silence_until is None: + return False + + # Проверка истечения времени + if datetime.now() >= self.silence_until: + logger.info("Режим тишины автоматически завершен", log_type='SILENCE') + self.silence_until = None + return False + + return True + + async def __call__(self, event: Message) -> Optional[dict]: + """ + Проверка активности режима тишины. + + Returns: + dict или None: Информация о режиме если активен, иначе None + """ + if self.is_active(): + remaining = (self.silence_until - datetime.now()).total_seconds() + logger.debug( + f"Режим тишины активен (осталось {remaining:.0f}с)", + log_type='SILENCE', + message=event + ) + return { + 'is_active': True, + 'until': self.silence_until, + 'remaining_seconds': remaining + } + + return None + + +class IsConflictModeActive(BaseFilter): + """ + Проверяет, активен ли режим антиконфликта (conflict mode). + + В режиме антиконфликта удаляются сообщения с конфликтными словами. + + Attributes: + conflict_until: Время до которого активен режим (None = неактивен) + + Example: + ```python + conflict_filter = IsConflictModeActive() + + @router.message(conflict_filter) + async def conflict_mode_active(message: Message): + # Проверяем на конфликтные слова и удаляем + if has_conflict_words(message.text): + await message.delete() + ``` + """ + + def __init__(self, conflict_until: Optional[datetime] = None): + """ + Args: + conflict_until: Datetime до которого активен режим + """ + self.conflict_until = conflict_until + + def update_conflict_until(self, new_datetime: Optional[datetime]) -> None: + """ + Обновляет время окончания режима антиконфликта. + + Args: + new_datetime: Новое время окончания или None для отключения + """ + self.conflict_until = new_datetime + + if new_datetime: + logger.info( + f"Режим антиконфликта активирован до {new_datetime.strftime('%H:%M:%S')}", + log_type='CONFLICT' + ) + else: + logger.info("Режим антиконфликта отключен", log_type='CONFLICT') + + def is_active(self) -> bool: + """ + Проверяет, активен ли режим сейчас. + + Returns: + bool: True если режим активен + """ + if self.conflict_until is None: + return False + + # Проверка истечения времени + if datetime.now() >= self.conflict_until: + logger.info("Режим антиконфликта автоматически завершен", log_type='CONFLICT') + self.conflict_until = None + return False + + return True + + async def __call__(self, event: Message) -> Optional[dict]: + """ + Проверка активности режима антиконфликта. + + Returns: + dict или None: Информация о режиме если активен, иначе None + """ + if self.is_active(): + remaining = (self.conflict_until - datetime.now()).total_seconds() + logger.debug( + f"Режим антиконфликта активен (осталось {remaining:.0f}с)", + log_type='CONFLICT', + message=event + ) + return { + 'is_active': True, + 'until': self.conflict_until, + 'remaining_seconds': remaining + } + + return None