185 lines
6.3 KiB
Python
185 lines
6.3 KiB
Python
"""
|
||
Фильтры для проверки активных режимов бота (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
|