Skip to content

Commit

Permalink
Merge pull request #5 from OCCCAS/dev
Browse files Browse the repository at this point in the history
TelegramObservHandler HOT FIX
  • Loading branch information
OCCASS authored Oct 25, 2022
2 parents 32650d8 + d1087e4 commit f0d096d
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 149 deletions.
2 changes: 0 additions & 2 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,5 @@ aiogram = ">=3.0.0"
pytest = "*"
pytest-asyncio = "*"

[dev-packages]

[requires]
python_version = "3.9"
143 changes: 0 additions & 143 deletions aiogram_tests/handler.py

This file was deleted.

4 changes: 4 additions & 0 deletions aiogram_tests/handler/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from .handler import CallbackQueryHandler
from .handler import MessageHandler

__all__ = ["MessageHandler", "CallbackQueryHandler"]
70 changes: 70 additions & 0 deletions aiogram_tests/handler/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
from typing import Iterable
from typing import List

from aiogram import Bot
from aiogram import Dispatcher
from aiogram.dispatcher.event.telegram import TelegramEventObserver
from aiogram.fsm.storage.memory import MemoryStorage
from aiogram.types import Chat
from aiogram.types import User

from aiogram_tests.mocked_bot import MockedBot
from aiogram_tests.types.dataset import CHAT
from aiogram_tests.types.dataset import USER


class RequestHandler:
def __init__(
self,
dp_middlewares: Iterable = None,
dp_filters: Iterable = None,
exclude_observer_methods: Iterable = None,
**kwargs,
):
self.bot = MockedBot()
self.dp = Dispatcher(storage=MemoryStorage())

if dp_middlewares is None:
dp_middlewares = ()

if dp_filters is None:
dp_filters = ()

if exclude_observer_methods is None:
exclude_observer_methods = []

dispatcher_methods = self._get_dispatcher_event_observers()
available_methods = tuple(set(dispatcher_methods) - set(exclude_observer_methods))
self._register_middlewares(available_methods, tuple(dp_middlewares))
self._register_filters(available_methods, tuple(dp_filters))

Bot.set_current(self.bot)
User.set_current(USER.as_object())
Chat.set_current(CHAT.as_object())

def _get_dispatcher_event_observers(self) -> List[str]:
"""
Returns a names for bot event observers, like message, callback_query etc.
"""

result = []
for name in dir(self.bot):
if isinstance(getattr(self.bot, name), TelegramEventObserver):
result.append(name)

return result

def _register_middlewares(self, event_observer: Iterable, middlewares: Iterable) -> None:
for eo_name in event_observer:
for m in middlewares:
eo_obj = getattr(self.bot, eo_name)
eo_obj.middleware.register(m)

def _register_filters(self, event_observer: Iterable, filters: Iterable) -> None:
for eo_name in event_observer:
for f in filters:
eo_obj = getattr(self.bot, eo_name)
eo_obj.middleware.register(f)

async def __call__(self, *args, **kwargs):
raise NotImplementedError
83 changes: 83 additions & 0 deletions aiogram_tests/handler/handler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
from typing import Callable
from typing import Dict
from typing import Iterable
from typing import List
from typing import Union

from aiogram import types
from aiogram.filters import Filter
from aiogram.filters import StateFilter
from aiogram.fsm.state import State

from .base import RequestHandler


class TelegramEventObserverHandler(RequestHandler):
def __init__(
self,
callback: Callable,
*filters: Filter,
state: Union[State, str, None] = None,
state_data: Dict = None,
dp_middlewares: Iterable = None,
exclude_observer_methods: Iterable = None,
**kwargs,
):
super().__init__(dp_middlewares, (), exclude_observer_methods)

self._callback = callback
self._filters: List = list(filters)
self._state: Union[State, str, None] = state
self._state_data: Dict = state_data

if self._state_data is None:
self._state_data = {}

if self._filters is None:
self._filters = []

if not isinstance(self._state_data, dict):
raise ValueError("state_data is not a dict")

async def __call__(self, *args, **kwargs):
if self._state:
self._filters.append(StateFilter(self._state))

self.register_handler()

if self._state:
state = self.dp.fsm.get_context(self.bot, user_id=12345678, chat_id=12345678)
await state.set_state(self._state)
await state.update_data(**self._state_data)

await self.feed_update(*args, **kwargs)

def register_handler(self) -> None:
"""
Register TelegramEventObserver in dispatcher
"""

raise NotImplementedError

async def feed_update(self, *args, **kwargs) -> None:
"""
Feed dispatcher updates
"""

raise NotImplementedError


class MessageHandler(TelegramEventObserverHandler):
def register_handler(self) -> None:
self.dp.message.register(self._callback, *self._filters)

async def feed_update(self, message: types.Message, *args, **kwargs) -> None:
await self.dp.feed_update(self.bot, types.Update(update_id=12345678, message=message))


class CallbackQueryHandler(TelegramEventObserverHandler):
def register_handler(self) -> None:
self.dp.callback_query.register(self._callback, *self._filters)

async def feed_update(self, callback_query: types.CallbackQuery, *args, **kwargs) -> None:
await self.dp.feed_update(self.bot, types.Update(update_id=12345678, callback_query=callback_query))
7 changes: 4 additions & 3 deletions aiogram_tests/requester.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from aiogram.utils.helper import Item

from .exceptions import MethodIsNotCalledError
from .handler import RequestHandler
from .handler.base import RequestHandler
from .utils import camel_case2snake_case


Expand Down Expand Up @@ -146,13 +146,14 @@ def __getattr__(self, item):
return getattr(self, item)
else:
raise MethodIsNotCalledError(
"method '{}' is not called.\nTry to use: {}".format(item, ", ".join(self._get_attributes()))
"method '%s' is not called by bot, so you cant to get this attribute. Called methods: %s"
% (item, self._get_attributes())
)


class Requester:
def __init__(self, *, request_handler: RequestHandler):
self._handler = request_handler
self._handler: RequestHandler = request_handler

async def query(self, *args, **kwargs) -> Calls:
await self._handler(*args, **kwargs)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ requires = ["aiogram ~= 3.0.0b5", "setuptools"]

[project]
name = "aiogram_tests"
version = "1.0.0"
version = "1.0.1"
authors = [
{ name = "Timur", email = "[email protected]" }
]
Expand Down

0 comments on commit f0d096d

Please sign in to comment.