From 3f2bcbd8d1160e8d910365d8340b5e32d9f173ba Mon Sep 17 00:00:00 2001 From: Alex Root Junior Date: Mon, 11 Oct 2021 01:27:07 +0300 Subject: [PATCH] Added MagicData filter --- aiogram/dispatcher/filters/__init__.py | 64 +++++++++++++++---- aiogram/dispatcher/filters/magic_data.py | 20 ++++++ .../test_filters/test_magic_data.py | 30 +++++++++ 3 files changed, 100 insertions(+), 14 deletions(-) create mode 100644 aiogram/dispatcher/filters/magic_data.py create mode 100644 tests/test_dispatcher/test_filters/test_magic_data.py diff --git a/aiogram/dispatcher/filters/__init__.py b/aiogram/dispatcher/filters/__init__.py index d0a28492..9795697a 100644 --- a/aiogram/dispatcher/filters/__init__.py +++ b/aiogram/dispatcher/filters/__init__.py @@ -4,6 +4,7 @@ from .base import BaseFilter from .command import Command, CommandObject from .content_types import ContentTypesFilter from .exception import ExceptionMessageFilter, ExceptionTypeFilter +from .magic_data import MagicData from .state import StateFilter from .text import Text @@ -17,45 +18,80 @@ __all__ = ( "ExceptionMessageFilter", "ExceptionTypeFilter", "StateFilter", + "MagicData", ) +_ALL_EVENTS_FILTERS: Tuple[Type[BaseFilter], ...] = (MagicData,) +_TELEGRAM_EVENTS_FILTERS: Tuple[Type[BaseFilter], ...] = (StateFilter,) + BUILTIN_FILTERS: Dict[str, Tuple[Type[BaseFilter], ...]] = { "message": ( Text, Command, ContentTypesFilter, - StateFilter, + *_ALL_EVENTS_FILTERS, + *_TELEGRAM_EVENTS_FILTERS, ), "edited_message": ( Text, Command, ContentTypesFilter, - StateFilter, + *_ALL_EVENTS_FILTERS, + *_TELEGRAM_EVENTS_FILTERS, ), "channel_post": ( Text, ContentTypesFilter, - StateFilter, + *_ALL_EVENTS_FILTERS, + *_TELEGRAM_EVENTS_FILTERS, ), "edited_channel_post": ( Text, ContentTypesFilter, - StateFilter, + *_ALL_EVENTS_FILTERS, + *_TELEGRAM_EVENTS_FILTERS, ), "inline_query": ( Text, - StateFilter, + *_ALL_EVENTS_FILTERS, + *_TELEGRAM_EVENTS_FILTERS, + ), + "chosen_inline_result": ( + *_ALL_EVENTS_FILTERS, + *_TELEGRAM_EVENTS_FILTERS, ), - "chosen_inline_result": (StateFilter,), "callback_query": ( Text, - StateFilter, + *_ALL_EVENTS_FILTERS, + *_TELEGRAM_EVENTS_FILTERS, + ), + "shipping_query": ( + *_ALL_EVENTS_FILTERS, + *_TELEGRAM_EVENTS_FILTERS, + ), + "pre_checkout_query": ( + *_ALL_EVENTS_FILTERS, + *_TELEGRAM_EVENTS_FILTERS, + ), + "poll": ( + *_ALL_EVENTS_FILTERS, + *_TELEGRAM_EVENTS_FILTERS, + ), + "poll_answer": ( + *_ALL_EVENTS_FILTERS, + *_TELEGRAM_EVENTS_FILTERS, + ), + "my_chat_member": ( + *_ALL_EVENTS_FILTERS, + *_TELEGRAM_EVENTS_FILTERS, + ), + "chat_member": ( + *_ALL_EVENTS_FILTERS, + *_TELEGRAM_EVENTS_FILTERS, + ), + "error": ( + ExceptionMessageFilter, + ExceptionTypeFilter, + *_ALL_EVENTS_FILTERS, ), - "shipping_query": (StateFilter,), - "pre_checkout_query": (StateFilter,), - "poll": (StateFilter,), - "poll_answer": (StateFilter,), - "my_chat_member": (StateFilter,), - "chat_member": (StateFilter,), - "error": (ExceptionMessageFilter, ExceptionTypeFilter), } diff --git a/aiogram/dispatcher/filters/magic_data.py b/aiogram/dispatcher/filters/magic_data.py new file mode 100644 index 00000000..2fa5f46a --- /dev/null +++ b/aiogram/dispatcher/filters/magic_data.py @@ -0,0 +1,20 @@ +from typing import Any + +from magic_filter import AttrDict, MagicFilter + +from aiogram.dispatcher.filters import BaseFilter +from aiogram.types import TelegramObject + + +class MagicData(BaseFilter): + magic_data: MagicFilter + + class Config: + arbitrary_types_allowed = True + + async def __call__(self, event: TelegramObject, *args: Any, **kwargs: Any) -> bool: + return bool( + self.magic_data.resolve( + AttrDict({"event": event, **{k: v for k, v in enumerate(args)}, **kwargs}) + ) + ) diff --git a/tests/test_dispatcher/test_filters/test_magic_data.py b/tests/test_dispatcher/test_filters/test_magic_data.py new file mode 100644 index 00000000..4a23f99a --- /dev/null +++ b/tests/test_dispatcher/test_filters/test_magic_data.py @@ -0,0 +1,30 @@ +import pytest +from magic_filter import AttrDict + +from aiogram import F +from aiogram.dispatcher.filters import MagicData +from aiogram.types import Update + + +class TestMagicDataFilter: + @pytest.mark.asyncio + async def test_call(self): + called = False + + def check(value): + nonlocal called + called = True + + assert isinstance(value, AttrDict) + assert value[0] == "foo" + assert value[1] == "bar" + assert value["spam"] is True + assert value.spam is True + return value + + f = MagicData(magic_data=F.func(check)) + result = await f(Update(update_id=123), "foo", "bar", spam=True) + + assert called + assert isinstance(result, bool) + assert result