mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2024-11-22 09:26:37 +03:00
Minor improvement to updates handling
Now the updates thread won't start unless you add, at least, one updates handler. Also, if the TcpClient was receiving (i.e., from an update), it will let the update to be received first instead of crashing
This commit is contained in:
parent
c11795f294
commit
cdb1674a27
|
@ -36,8 +36,22 @@ class MtProtoSender:
|
|||
def add_update_handler(self, handler):
|
||||
"""Adds an update handler (a method with one argument, the received
|
||||
TLObject) that is fired when there are updates available"""
|
||||
|
||||
first_handler = not self.on_update_handlers
|
||||
self.on_update_handlers.append(handler)
|
||||
|
||||
# If this is the first added handler,
|
||||
# we must start the thread to receive updates
|
||||
if first_handler:
|
||||
self.set_listen_for_updates(enabled=True)
|
||||
|
||||
def remove_update_handler(self, handler):
|
||||
self.on_update_handlers.remove(handler)
|
||||
|
||||
# If there are no more update handlers, stop the thread
|
||||
if not self.on_update_handlers:
|
||||
self.set_listen_for_updates(False)
|
||||
|
||||
def generate_sequence(self, confirmed):
|
||||
"""Generates the next sequence number, based on whether it
|
||||
was confirmed yet or not"""
|
||||
|
|
|
@ -45,7 +45,12 @@ class TcpClient:
|
|||
self.cancelled = False
|
||||
|
||||
with BinaryWriter() as writer:
|
||||
while writer.written_count < buffer_size and not self.cancelled:
|
||||
while writer.written_count < buffer_size:
|
||||
# Only do cancel if no data was read yet
|
||||
# Otherwise, carry on reading and finish
|
||||
if self.cancelled and writer.written_count == 0:
|
||||
raise ReadCancelledError()
|
||||
|
||||
try:
|
||||
# When receiving from the socket, we may not receive all the data at once
|
||||
# This is why we need to keep checking to make sure that we receive it all
|
||||
|
@ -57,20 +62,10 @@ class TcpClient:
|
|||
# There was no data available for us to read. Sleep a bit
|
||||
time.sleep(self.delay)
|
||||
|
||||
# If the operation was cancelled *but* data was read,
|
||||
# this will result on data loss so raise an exception
|
||||
# TODO this could be solved by using an internal FIFO buffer (first in, first out)
|
||||
if self.cancelled:
|
||||
if writer.written_count == 0:
|
||||
raise ReadCancelledError()
|
||||
else:
|
||||
raise NotImplementedError('The read operation was cancelled when some data '
|
||||
'was already read. This has not yet implemented '
|
||||
'an internal buffer, so cannot continue.')
|
||||
|
||||
# If everything went fine, return the read bytes
|
||||
return writer.get_bytes()
|
||||
|
||||
def cancel_read(self):
|
||||
"""Cancels the read operation raising a ReadCancelledError"""
|
||||
"""Cancels the read operation IF it hasn't yet
|
||||
started, raising a ReadCancelledError"""
|
||||
self.cancelled = True
|
||||
|
|
|
@ -123,9 +123,8 @@ def parse_message_entities(msg):
|
|||
# Second case, both inside: so*me_th*in_g.
|
||||
# In this case, the current entity length is decreased by one,
|
||||
# and all the subentities offset and length decrease 1
|
||||
elif (subentity.offset > entity.offset and
|
||||
subentity.offset < entity.offset + entity.length and
|
||||
subentity.offset + subentity.length > entity.offset + entity.length):
|
||||
elif (entity.offset < subentity.offset < entity.offset + entity.length and
|
||||
subentity.offset + subentity.length > entity.offset + entity.length):
|
||||
entity.length -= 1
|
||||
subentity.offset -= 1
|
||||
subentity.length -= 1
|
||||
|
|
|
@ -18,9 +18,6 @@ from tl.functions.help import GetConfigRequest
|
|||
from tl.functions.auth import SendCodeRequest, SignInRequest
|
||||
from tl.functions.messages import GetDialogsRequest, GetHistoryRequest, SendMessageRequest
|
||||
|
||||
# For working with updates
|
||||
from tl.types import UpdateShortMessage
|
||||
|
||||
|
||||
class TelegramClient:
|
||||
|
||||
|
@ -59,7 +56,6 @@ class TelegramClient:
|
|||
self.session.save()
|
||||
|
||||
self.sender = MtProtoSender(self.transport, self.session)
|
||||
self.sender.add_update_handler(self.on_update)
|
||||
|
||||
# Now it's time to send an InitConnectionRequest
|
||||
# This must always be invoked with the layer we'll be using
|
||||
|
@ -72,10 +68,6 @@ class TelegramClient:
|
|||
|
||||
result = self.invoke(InvokeWithLayerRequest(layer=self.layer, query=query))
|
||||
|
||||
# Only listen for updates if we're authorized
|
||||
if self.is_user_authorized():
|
||||
self.sender.set_listen_for_updates(True)
|
||||
|
||||
# We're only interested in the DC options,
|
||||
# although many other options are available!
|
||||
self.dc_options = result.dc_options
|
||||
|
@ -260,21 +252,18 @@ class TelegramClient:
|
|||
return InputPeerChannel(channel.id, channel.access_hash)
|
||||
|
||||
except StopIteration:
|
||||
pass
|
||||
|
||||
return None
|
||||
return None
|
||||
|
||||
# endregion
|
||||
|
||||
# region Updates handling
|
||||
|
||||
def on_update(self, tlobject):
|
||||
"""This method is fired when there are updates from Telegram.
|
||||
Add your own implementation below, or simply override it!"""
|
||||
def add_update_handler(self, handler):
|
||||
"""Adds an update handler (a function which takes a TLObject,
|
||||
an update, as its parameter) and listens for updates"""
|
||||
self.sender.add_update_handler(handler)
|
||||
|
||||
# Only show incoming messages
|
||||
if type(tlobject) is UpdateShortMessage:
|
||||
if not tlobject.out:
|
||||
print('> User with ID {} said "{}"'.format(tlobject.user_id, tlobject.message))
|
||||
def remove_update_handler(self, handler):
|
||||
self.sender.remove_update_handler(handler)
|
||||
|
||||
# endregion
|
||||
|
|
Loading…
Reference in New Issue
Block a user