Добавлен BaseFilter

This commit is contained in:
Денис Семёнов 2025-08-03 13:56:56 +03:00
parent 3855f93862
commit cb2226eee5
3 changed files with 93 additions and 10 deletions

View File

@ -3,11 +3,12 @@ from __future__ import annotations
import asyncio import asyncio
import functools import functools
from typing import Any, Awaitable, Callable, Dict, List, TYPE_CHECKING, Optional from typing import Any, Awaitable, Callable, Dict, List, TYPE_CHECKING, Literal, Optional
from asyncio.exceptions import TimeoutError as AsyncioTimeoutError from asyncio.exceptions import TimeoutError as AsyncioTimeoutError
from aiohttp import ClientConnectorError from aiohttp import ClientConnectorError
from .filters.filter import BaseFilter
from .filters.middleware import BaseMiddleware from .filters.middleware import BaseMiddleware
from .filters.handler import Handler from .filters.handler import Handler
@ -70,6 +71,7 @@ class Dispatcher:
self.contexts: List[MemoryContext] = [] self.contexts: List[MemoryContext] = []
self.routers: List[Router | Dispatcher] = [] self.routers: List[Router | Dispatcher] = []
self.filters: List[MagicFilter] = [] self.filters: List[MagicFilter] = []
self.base_filters: List[BaseFilter] = []
self.middlewares: List[BaseMiddleware] = [] self.middlewares: List[BaseMiddleware] = []
self.bot: Optional[Bot] = None self.bot: Optional[Bot] = None
@ -144,6 +146,36 @@ class Dispatcher:
""" """
self.routers += [r for r in routers] self.routers += [r for r in routers]
def outer_middleware(self, middleware: BaseMiddleware) -> None:
"""
Добавляет Middleware на первое место в списке
:param: middleware: Middleware
"""
self.middlewares.insert(0, middleware)
def middleware(self, middleware: BaseMiddleware) -> None:
"""
Добавляет Middleware в список
:param middleware: Middleware
"""
self.middlewares.append(middleware)
def filter(self, base_filter: BaseFilter) -> None:
"""
Добавляет фильтр в список
:param base_filter: Фильтр
"""
self.base_filters.append(base_filter)
async def __ready(self, bot: Bot): async def __ready(self, bot: Bot):
@ -205,6 +237,24 @@ class Dispatcher:
else: else:
await handler.func_event(event_object) await handler.func_event(event_object)
async def process_base_filters(
self,
event: UpdateUnion,
filters: List[BaseFilter]
) -> Optional[Dict[str, Any]] | Literal[False]:
data = {}
for _filter in filters:
result = await _filter(event)
if isinstance(result, dict):
data.update(result)
elif not result:
return result
return data
async def handle(self, event_object: UpdateUnion): async def handle(self, event_object: UpdateUnion):
@ -236,6 +286,17 @@ class Dispatcher:
if not filter_attrs(event_object, *router.filters): if not filter_attrs(event_object, *router.filters):
continue continue
result_router_filter = await self.process_base_filters(
event=event_object,
filters=router.base_filters
)
if isinstance(result_router_filter, dict):
kwargs.update(result_router_filter)
elif not result_router_filter:
continue
for handler in router.event_handlers: for handler in router.event_handlers:
if not handler.update_type == event_object.update_type: if not handler.update_type == event_object.update_type:
@ -248,9 +309,21 @@ class Dispatcher:
if handler.states: if handler.states:
if current_state not in handler.states: if current_state not in handler.states:
continue continue
func_args = handler.func_event.__annotations__.keys() func_args = handler.func_event.__annotations__.keys()
if handler.base_filters:
result_filter = await self.process_base_filters(
event=event_object,
filters=handler.base_filters
)
if isinstance(result_filter, dict):
kwargs.update(result_filter)
elif not result_filter:
continue
if isinstance(router, Router): if isinstance(router, Router):
full_middlewares = self.middlewares + router.middlewares + handler.middlewares full_middlewares = self.middlewares + router.middlewares + handler.middlewares
elif isinstance(router, Dispatcher): elif isinstance(router, Dispatcher):
@ -260,7 +333,7 @@ class Dispatcher:
full_middlewares, full_middlewares,
functools.partial(self.call_handler, handler) functools.partial(self.call_handler, handler)
) )
kwargs_filtered = {k: v for k, v in kwargs.items() if k in func_args} kwargs_filtered = {k: v for k, v in kwargs.items() if k in func_args}
await handler_chain(event_object, kwargs_filtered) await handler_chain(event_object, kwargs_filtered)

10
maxapi/filters/filter.py Normal file
View File

@ -0,0 +1,10 @@
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from ..types.updates import UpdateUnion
class BaseFilter:
async def __call__(self, event: UpdateUnion) -> bool | dict:
return True

View File

@ -1,11 +1,10 @@
from typing import Callable, List, Optional from typing import Callable, List, Optional
from magic_filter import F, MagicFilter from magic_filter import MagicFilter
from ..filters.filter import BaseFilter
from ..filters.middleware import BaseMiddleware from ..filters.middleware import BaseMiddleware
from ..types.command import Command, CommandStart
from ..context.state_machine import State from ..context.state_machine import State
from ..enums.update import UpdateType from ..enums.update import UpdateType
@ -43,7 +42,8 @@ class Handler:
self.func_event: Callable = func_event self.func_event: Callable = func_event
self.update_type: UpdateType = update_type self.update_type: UpdateType = update_type
self.filters = [] self.filters: Optional[List[MagicFilter]] = []
self.base_filters: Optional[List[BaseFilter]] = []
self.states: Optional[List[State]] = [] self.states: Optional[List[State]] = []
self.middlewares: List[BaseMiddleware] = [] self.middlewares: List[BaseMiddleware] = []
@ -52,10 +52,10 @@ class Handler:
self.filters.append(arg) self.filters.append(arg)
elif isinstance(arg, State): elif isinstance(arg, State):
self.states.append(arg) self.states.append(arg)
elif isinstance(arg, (Command, CommandStart)):
self.filters.insert(0, F.message.body.text.split()[0] == arg.command)
elif isinstance(arg, BaseMiddleware): elif isinstance(arg, BaseMiddleware):
self.middlewares.append(arg) self.middlewares.append(arg)
elif isinstance(arg, BaseFilter):
self.base_filters.append(arg)
else: else:
logger_dp.info(f'Обнаружен неизвестный фильтр `{arg}` при ' logger_dp.info(f'Обнаружен неизвестный фильтр `{arg}` при '
f'регистрации функции `{func_event.__name__}`') f'регистрации функции `{func_event.__name__}`')