2 Commits

Author SHA1 Message Date
159a43ebe6 Fixed _callbacks.py did not reraise CancelledError 2026-09-09 18:19:52 +03:00
9f4cd4948a Text filters update and stability
- **kwargs are propagated to base classes in text filters from now on
- `_callbacks.py` prints filter exceptions from now on
2026-09-09 18:18:07 +03:00
2 changed files with 30 additions and 14 deletions

View File

@@ -51,8 +51,14 @@ class Callbacks:
for callback_info in self._filters:
if not isinstance(callback_info, self._FilterBasedCallback):
continue
try:
if not await callback_info.filter(room, event, self._client):
continue
except asyncio.CancelledError:
raise
except:
self._logger.error(traceback.format_exc())
continue
event_data = RoomEventData(
room=room,
event=event,

View File

@@ -14,9 +14,14 @@ class TextFilter(BaseEventFilter):
If this filter matches, you can access `event.body` and it stores
unformatted text of the message.
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.
"""
def __init__(self):
super().__init__()
def __init__(self, *, ignore_filename_in_body: bool = True, **kwargs):
super().__init__(**kwargs)
self._ignore_filename_in_body = ignore_filename_in_body
def __repr__(self) -> str:
return "TextFilter()"
@@ -28,6 +33,10 @@ class TextFilter(BaseEventFilter):
return False
if not event.body.strip(): # type: ignore
return False
if self._ignore_filename_in_body:
content = event.source["content"]
if "filename" in content and content["filename"] == event.body: # type: ignore
return False
return True
class FormattedTextFilter(BaseEventFilter):
@@ -40,8 +49,8 @@ class FormattedTextFilter(BaseEventFilter):
If this filter matches, you can access `event.formatted_body` and it stores
formatted text of the message.
"""
def __init__(self):
super().__init__()
def __init__(self, **kwargs):
super().__init__(**kwargs)
def __repr__(self):
return "FormattedTextFilter()"
@@ -68,8 +77,8 @@ class TextContainsFilter(TextFilter):
is True. That means you must ensure that `needle` is lower case. The filter
will never match otherwise.
"""
def __init__(self, needle: str | list[str], *, any_case: bool = True):
super().__init__()
def __init__(self, needle: str | list[str], *, any_case: bool = True, **kwargs):
super().__init__(**kwargs)
if type(needle) is str:
needle = [needle]
self._any_case = any_case
@@ -100,8 +109,8 @@ class TextStartsWithFilter(TextFilter):
is True. That means you must ensure that `needle` is lower case. The filter
will never match otherwise.
"""
def __init__(self, substring: str | list[str], *, any_case: bool = True):
super().__init__()
def __init__(self, substring: str | list[str], *, any_case: bool = True, **kwargs):
super().__init__(**kwargs)
if type(substring) is str:
substring = [substring]
self._any_case = any_case
@@ -132,8 +141,8 @@ class TextEndsWithFilter(TextFilter):
is True. That means you must ensure that `needle` is lower case. The filter
will never match otherwise.
"""
def __init__(self, substring: str | list[str], *, any_case: bool = True):
super().__init__()
def __init__(self, substring: str | list[str], *, any_case: bool = True, **kwargs):
super().__init__(**kwargs)
if type(substring) is str:
substring = [substring]
self._any_case = any_case
@@ -172,8 +181,8 @@ class TextCommandFilter(TextFilter):
`event.command_args: list[str]`. You may use this attribute in your callback
for this event.
"""
def __init__(self, verbs: str | list[str], min_args: int = 0, max_args: int | None = None, prefix: str = "!"):
super().__init__()
def __init__(self, verbs: str | list[str], min_args: int = 0, max_args: int | None = None, prefix: str = "!", **kwargs):
super().__init__(**kwargs)
if type(verbs) is str:
verbs = [verbs]
self._verbs = verbs
@@ -206,7 +215,8 @@ class TextRegexFilter(TextFilter):
"""
This filter returns True if the `event.body` passes the regex.
"""
def __init__(self, regex: re.Pattern | str):
def __init__(self, regex: re.Pattern | str, **kwargs):
super().__init__(**kwargs)
if isinstance(regex, str):
regex = re.compile(regex)
self._regex = regex