diff --git a/telethon/telegram_bare_client.py b/telethon/telegram_bare_client.py index 31a3f7d9..23fd4ee4 100644 --- a/telethon/telegram_bare_client.py +++ b/telethon/telegram_bare_client.py @@ -1,7 +1,6 @@ import logging import os import threading -import warnings from datetime import timedelta, datetime from signal import signal, SIGINT, SIGTERM, SIGABRT from threading import Lock @@ -589,24 +588,6 @@ class TelegramBareClient: self.updates.process(self(GetStateRequest())) self._last_state = datetime.now() - 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""" - if self.updates.workers is None: - warnings.warn( - "You have not setup any workers, so you won't receive updates." - " Pass update_workers=4 when creating the TelegramClient," - " or set client.self.updates.workers = 4" - ) - - self.updates.handlers.append(handler) - - def remove_update_handler(self, handler): - self.updates.handlers.remove(handler) - - def list_update_handlers(self): - return self.updates.handlers[:] - # endregion # region Constant read diff --git a/telethon/telegram_client.py b/telethon/telegram_client.py index e81171d4..118f1f53 100644 --- a/telethon/telegram_client.py +++ b/telethon/telegram_client.py @@ -7,6 +7,7 @@ import os import re import sys import time +import warnings from collections import OrderedDict, UserList from datetime import datetime, timedelta from io import BytesIO @@ -32,7 +33,7 @@ except ImportError: hachoir = None from . import TelegramBareClient -from . import helpers, utils +from . import helpers, utils, events from .errors import ( RPCError, UnauthorizedError, PhoneCodeEmptyError, PhoneCodeExpiredError, PhoneCodeHashEmptyError, PhoneCodeInvalidError, LocationInvalidError, @@ -1760,26 +1761,17 @@ class TelegramClient(TelegramBareClient): def on(self, event): """ - - Turns the given entity into a valid Telegram user or chat. + Decorator helper method around add_event_handler(). Args: event (:obj:`_EventBuilder` | :obj:`type`): The event builder class or instance to be used, for instance ``events.NewMessage``. """ - if isinstance(event, type): - event = event() - - event.resolve(self) - def decorator(f): - self._event_builders.append((event, f)) + self.add_event_handler(f, event) return f - if self._on_handler not in self.updates.handlers: - self.add_update_handler(self._on_handler) - return decorator def _on_handler(self, update): @@ -1789,6 +1781,49 @@ class TelegramClient(TelegramBareClient): event._client = self callback(event) + def add_event_handler(self, callback, event): + """ + Registers the given callback to be called on the specified event. + + Args: + callback (:obj:`callable`): + The callable function accepting one parameter to be used. + + event (:obj:`_EventBuilder` | :obj:`type`): + The event builder class or instance to be used, + for instance ``events.NewMessage``. + """ + if self.updates.workers is None: + warnings.warn( + "You have not setup any workers, so you won't receive updates." + " Pass update_workers=1 when creating the TelegramClient," + " or set client.self.updates.workers = 1" + ) + + self.updates.handler = self._on_handler + if isinstance(event, type): + event = event() + + event.resolve(self) + self._event_builders.append((event, callback)) + + 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""" + warnings.warn( + 'add_update_handler is deprecated, use the @client.on syntax ' + 'or add_event_handler(callback, events.Raw) instead (see ' + 'https://telethon.rtfd.io/en/latest/extra/basic/working-' + 'with-updates.html)' + ) + self.add_event_handler(handler, events.Raw) + + def remove_update_handler(self, handler): + pass + + def list_update_handlers(self): + return [] + # endregion # region Small utilities to make users' life easier diff --git a/telethon/update_state.py b/telethon/update_state.py index f98c0c04..6fa0b12a 100644 --- a/telethon/update_state.py +++ b/telethon/update_state.py @@ -22,12 +22,12 @@ class UpdateState: workers is None: Updates will *not* be stored on self. workers = 0: Another thread is responsible for calling self.poll() workers > 0: 'workers' background threads will be spawned, any - any of them will invoke all the self.handlers. + any of them will invoke the self.handler. """ self._workers = workers self._worker_threads = [] - self.handlers = [] + self.handler = None self._updates_lock = RLock() self._updates = Queue() @@ -106,10 +106,8 @@ class UpdateState: while True: try: update = self.poll(timeout=UpdateState.WORKER_POLL_TIMEOUT) - # TODO Maybe people can add different handlers per update type - if update: - for handler in self.handlers: - handler(update) + if update and self.handler: + self.handler(update) except StopIteration: break except: