Filters refactoring and small improvement
- Removed `filters/__init__.py` (filters are to be imported from `mab` directly) - Renamed `Text` filters to `Body` filters - Fixed `base.py` filters not propagating **kwargs to base classes - Added `__init__` for BaseEventFilter so that keyword argument that remain unused by its children get logged using `logging.critical`
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
from . import bot
|
||||
from . import types
|
||||
|
||||
from .types import MatrixBotConfig
|
||||
from .types import MatrixBotConfig, RoomEventData, MessageType
|
||||
|
||||
from .bot import MatrixBot
|
||||
|
||||
from .filters.base import *
|
||||
from .filters.text import *
|
||||
from .filters.message import *
|
||||
from .filters.body import *
|
||||
|
||||
__all__ = [
|
||||
# module names
|
||||
@@ -15,18 +16,29 @@ __all__ = [
|
||||
|
||||
# .types
|
||||
"MatrixBotConfig",
|
||||
"RoomEventData",
|
||||
"MessageType",
|
||||
|
||||
# .bot
|
||||
"MatrixBot",
|
||||
|
||||
# .filters.base
|
||||
"BaseEventFilter",
|
||||
"EventTypeFilter",
|
||||
|
||||
# .filters.text
|
||||
"TextFilter",
|
||||
"FormattedTextFilter",
|
||||
"TextContainsFilter",
|
||||
"TextStartsWithFilter",
|
||||
"TextEndsWithFilter",
|
||||
"TextCommandFilter",
|
||||
# .filters.body
|
||||
"BodyExistsFilter",
|
||||
"BodyContainsFilter",
|
||||
"BodyStartsWithFilter",
|
||||
"BodyEndsWithFilter",
|
||||
"BodyCommandFilter",
|
||||
"BodyRegexFilter",
|
||||
|
||||
# .filters.message
|
||||
"MessageTypeFilter",
|
||||
"NewMessageFilter",
|
||||
"EditedMessageFilter",
|
||||
"RedactedMessageFilter",
|
||||
"SenderIsFilter",
|
||||
"SenderIsBotFilter",
|
||||
]
|
||||
@@ -1,28 +0,0 @@
|
||||
from .base import *
|
||||
from .message import *
|
||||
from .room import *
|
||||
from .text import *
|
||||
|
||||
__all__ = [
|
||||
# base.py
|
||||
"BaseEventFilter",
|
||||
"EventTypeFilter",
|
||||
|
||||
# message.py
|
||||
"NewMessageFilter",
|
||||
"EditedMessageFilter",
|
||||
"RedactedMessageFilter",
|
||||
"SenderIsFilter",
|
||||
"SenderIsBotFilter",
|
||||
|
||||
# room.py
|
||||
"RoomEncryptedFilter",
|
||||
|
||||
# text.py
|
||||
"TextFilter",
|
||||
"TextContainsFilter",
|
||||
"TextStartsWithFilter",
|
||||
"TextEndsWithFilter",
|
||||
"TextCommandFilter",
|
||||
"TextRegexFilter"
|
||||
]
|
||||
@@ -9,6 +9,10 @@ class BaseEventFilter(ABC):
|
||||
"""Base class for all message filters"""
|
||||
_logger = logging.Logger("EventFilter")
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
for a in kwargs:
|
||||
self._logger.critical(f"Unknown keyword argument for some filter is used: '{a}'={repr(kwargs[a])}")
|
||||
|
||||
# AND
|
||||
def __and__(self, other):
|
||||
if not isinstance(other, BaseEventFilter):
|
||||
@@ -80,7 +84,8 @@ class BaseEventFilter(ABC):
|
||||
|
||||
class EventTypeFilter(BaseEventFilter):
|
||||
"""Event filter that checks if the event is an instance of some class"""
|
||||
def __init__(self, type: Type):
|
||||
def __init__(self, type: Type, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self._type = type
|
||||
|
||||
async def __call__(self, room: MatrixRoom, event: Event, client: AsyncClient) -> bool:
|
||||
@@ -113,8 +118,8 @@ class CompoundEventFilter(BaseEventFilter):
|
||||
CompoundEventFilter.OPERATOR_INVERT: [1],
|
||||
}[op]
|
||||
|
||||
def __init__(self, operator: str, arguments: list[BaseEventFilter]):
|
||||
super().__init__()
|
||||
def __init__(self, operator: str, arguments: list[BaseEventFilter], **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
if not self._is_operator_valid(operator):
|
||||
raise RuntimeError(f"Invalid operator `{operator}`")
|
||||
if not self._is_elements_count_valid(operator, len(arguments)):
|
||||
|
||||
@@ -5,7 +5,7 @@ from .message import NewMessageFilter
|
||||
from nio import AsyncClient
|
||||
from nio import MatrixRoom, Event
|
||||
|
||||
class TextFilter(NewMessageFilter):
|
||||
class BodyExistsFilter(NewMessageFilter):
|
||||
"""
|
||||
This filter returns True if all conditions are met:
|
||||
1. `event` has attribute `body`
|
||||
@@ -18,12 +18,17 @@ class TextFilter(NewMessageFilter):
|
||||
If `event.body` value equals to `event.source["content"]["filename"]` (if it
|
||||
is present, of course) then this filter will not match it by default. You
|
||||
may disable `ignore_filename_in_body` to disable this feature.
|
||||
|
||||
This filter will match any message that has `body` in it, including images,
|
||||
videos, files, etc.
|
||||
"""
|
||||
def __init__(self, *, ignore_filename_in_body: bool = True, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self._ignore_filename_in_body = ignore_filename_in_body
|
||||
|
||||
async def __call__(self, room: MatrixRoom, event: Event, client: AsyncClient) -> bool:
|
||||
if not await super().__call__(room, event, client):
|
||||
return False
|
||||
if not hasattr(event, "body"):
|
||||
return False
|
||||
if not isinstance(event.body, str): # type: ignore
|
||||
@@ -36,7 +41,7 @@ class TextFilter(NewMessageFilter):
|
||||
return False
|
||||
return True
|
||||
|
||||
class TextContainsFilter(TextFilter):
|
||||
class BodyContainsFilter(BodyExistsFilter):
|
||||
"""
|
||||
This filter returns True if `event.body` contains `needle` substring (or any
|
||||
of neddle from the list). `event.body` will be converted to lower case if
|
||||
@@ -65,7 +70,7 @@ class TextContainsFilter(TextFilter):
|
||||
return True
|
||||
return False
|
||||
|
||||
class TextStartsWithFilter(TextFilter):
|
||||
class BodyStartsWithFilter(BodyExistsFilter):
|
||||
"""
|
||||
This filter returns True if `event.body` starts with `substring` (or any of
|
||||
substrings from the list). The check will be case insensetive if `any_case`
|
||||
@@ -94,7 +99,7 @@ class TextStartsWithFilter(TextFilter):
|
||||
return True
|
||||
return False
|
||||
|
||||
class TextEndsWithFilter(TextFilter):
|
||||
class BodyEndsWithFilter(BodyExistsFilter):
|
||||
"""
|
||||
This filter returns True if `event.body` ends with `substring` (or any of
|
||||
substrings from the list). The check will be case insensetive if `any_case`
|
||||
@@ -123,7 +128,7 @@ class TextEndsWithFilter(TextFilter):
|
||||
return True
|
||||
return False
|
||||
|
||||
class TextCommandFilter(TextFilter):
|
||||
class BodyCommandFilter(BodyExistsFilter):
|
||||
"""
|
||||
This filter returns True if all conditions are met:
|
||||
1. `event.body` contains at least `min_args + 1` words after split()
|
||||
@@ -171,7 +176,7 @@ class TextCommandFilter(TextFilter):
|
||||
return True
|
||||
return False
|
||||
|
||||
class TextRegexFilter(TextFilter):
|
||||
class BodyRegexFilter(BodyExistsFilter):
|
||||
"""
|
||||
This filter returns True if the `event.body` passes the regex.
|
||||
"""
|
||||
Reference in New Issue
Block a user