Dispatch updates to event handlers

This commit is contained in:
Lonami Exo 2018-06-13 16:20:15 +02:00
parent a91109c9fa
commit 3ce8b17193
4 changed files with 22 additions and 19 deletions

View File

@ -12,7 +12,6 @@ from ..network.mtprotostate import MTProtoState
from ..sessions import Session, SQLiteSession from ..sessions import Session, SQLiteSession
from ..tl import TLObject, functions from ..tl import TLObject, functions
from ..tl.all_tlobjects import LAYER from ..tl.all_tlobjects import LAYER
from ..update_state import UpdateState
DEFAULT_DC_ID = 4 DEFAULT_DC_ID = 4
DEFAULT_IPV4_IP = '149.154.167.51' DEFAULT_IPV4_IP = '149.154.167.51'
@ -171,17 +170,14 @@ class TelegramBaseClient(abc.ABC):
self._connection = connection self._connection = connection
self._sender = MTProtoSender( self._sender = MTProtoSender(
state, connection, state, connection,
first_query=self._init_with(functions.help.GetConfigRequest()) first_query=self._init_with(functions.help.GetConfigRequest()),
update_callback=self._handle_update
) )
# Cache :tl:`ExportedAuthorization` as ``dc_id: MTProtoState`` # Cache :tl:`ExportedAuthorization` as ``dc_id: MTProtoState``
# to easily import them when getting an exported sender. # to easily import them when getting an exported sender.
self._exported_auths = {} self._exported_auths = {}
# This member will process updates if enabled.
# One may change self.updates.enabled at any later point.
self.updates = UpdateState()
# Save whether the user is authorized here (a.k.a. logged in) # Save whether the user is authorized here (a.k.a. logged in)
self._authorized = None # None = We don't know yet self._authorized = None # None = We don't know yet
@ -367,4 +363,8 @@ class TelegramBaseClient(abc.ABC):
'use client(...) instead') 'use client(...) instead')
return await self(*args, **kwargs) return await self(*args, **kwargs)
@abc.abstractmethod
def _handle_update(self, update):
raise NotImplementedError
# endregion # endregion

View File

@ -1,10 +1,10 @@
import asyncio
import logging
import warnings import warnings
from .users import UserMethods from .users import UserMethods
from .. import events, utils
from ..tl import types, functions from ..tl import types, functions
from .. import events
import logging
__log__ = logging.getLogger(__name__) __log__ = logging.getLogger(__name__)
@ -44,7 +44,6 @@ class UpdateMethods(UserMethods):
:tl:`Update` objects with no further processing) will :tl:`Update` objects with no further processing) will
be passed instead. be passed instead.
""" """
self.updates.handler = self._on_handler
if isinstance(event, type): if isinstance(event, type):
event = event() event = event()
elif not event: elif not event:
@ -124,7 +123,7 @@ class UpdateMethods(UserMethods):
# infinite loop here (so check against old pts to stop) # infinite loop here (so check against old pts to stop)
break break
self.updates.process(types.Updates( self._handle_update(types.Updates(
users=d.users, users=d.users,
chats=d.chats, chats=d.chats,
date=state.date, date=state.date,
@ -144,8 +143,12 @@ class UpdateMethods(UserMethods):
# region Private methods # region Private methods
async def _on_handler(self, update): def _handle_update(self, update):
asyncio.ensure_future(self._dispatch_update(update))
async def _dispatch_update(self, update):
if self._events_pending_resolve: if self._events_pending_resolve:
# TODO Add lock not to resolve them twice
for event in self._events_pending_resolve: for event in self._events_pending_resolve:
await event.resolve(self) await event.resolve(self)
self._events_pending_resolve.clear() self._events_pending_resolve.clear()

View File

@ -7,7 +7,7 @@ from ..errors import RPCError
from ..tl import TLObject, types, functions from ..tl import TLObject, types, functions
def _into_id_set(client, chats): async def _into_id_set(client, chats):
"""Helper util to turn the input chat or chats into a set of IDs.""" """Helper util to turn the input chat or chats into a set of IDs."""
if chats is None: if chats is None:
return None return None
@ -30,9 +30,9 @@ def _into_id_set(client, chats):
# 0x2d45687 == crc32(b'Peer') # 0x2d45687 == crc32(b'Peer')
result.add(utils.get_peer_id(chat)) result.add(utils.get_peer_id(chat))
else: else:
chat = client.get_input_entity(chat) chat = await client.get_input_entity(chat)
if isinstance(chat, types.InputPeerSelf): if isinstance(chat, types.InputPeerSelf):
chat = client.get_me(input_peer=True) chat = await client.get_me(input_peer=True)
result.add(utils.get_peer_id(chat)) result.add(utils.get_peer_id(chat))
return result return result
@ -62,10 +62,10 @@ class EventBuilder(abc.ABC):
def build(self, update): def build(self, update):
"""Builds an event for the given update if possible, or returns None""" """Builds an event for the given update if possible, or returns None"""
def resolve(self, client): async def resolve(self, client):
"""Helper method to allow event builders to be resolved before usage""" """Helper method to allow event builders to be resolved before usage"""
self.chats = _into_id_set(client, self.chats) self.chats = await _into_id_set(client, self.chats)
self._self_id = client.get_me(input_peer=True).user_id self._self_id = await client.get_me(input_peer=True).user_id
def _filter_event(self, event): def _filter_event(self, event):
""" """

View File

@ -22,7 +22,7 @@ class Raw(EventBuilder):
assert all(isinstance(x, type) for x in types) assert all(isinstance(x, type) for x in types)
self.types = tuple(types) self.types = tuple(types)
def resolve(self, client): async def resolve(self, client):
pass pass
def build(self, update): def build(self, update):