initial commit for dispatcher rework. deleted updatequeue.py as it is not needed. added handler base class, messagehandler, commandhandler, regexhandler. adjusted dispatcher for new system

This commit is contained in:
Jannes Höke 2016-04-14 23:57:40 +02:00
parent 8b95f9cbeb
commit 1e19084a0d
9 changed files with 329 additions and 573 deletions

View file

@ -22,5 +22,10 @@
from .dispatcher import Dispatcher
from .jobqueue import JobQueue
from .updater import Updater
from .handler import Handler
from .commandhandler import CommandHandler
from .messagehandler import MessageHandler
from .regexhandler import RegexHandler
__all__ = ('Dispatcher', 'JobQueue', 'Updater')
__all__ = ('Dispatcher', 'JobQueue', 'Updater', 'Handler', 'CommandHandler',
'MessageHandler', 'RegexHandler')

View file

@ -0,0 +1,49 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2016
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
""" This module contains the base class for handlers as used by the
Dispatcher """
from .handler import Handler
from telegram import Update
class CommandHandler(Handler):
def __init__(self, command, callback, pass_args=False,
pass_update_queue=False):
super(Handler).__init__(callback, pass_update_queue)
self.command = command
self.pass_args = pass_args
def checkUpdate(self, update):
return (isinstance(update, Update) and
update.message and
update.message.text and
update.message.text.startswith('/') and
update.message.text[1:].split(' ')[0].split('@')[0] ==
self.command)
def handleUpdate(self, update, dispatcher):
optional_args = self.collectOptionalArgs(dispatcher)
if self.pass_args:
optional_args['args'] = update.message.text.split(' ')[1:]
self.callback(dispatcher.bot, update, **optional_args)

View file

@ -21,12 +21,11 @@
import logging
from functools import wraps
from inspect import getargspec
from threading import Thread, BoundedSemaphore, Lock, Event, current_thread
from re import match, split
from time import sleep
from telegram import (TelegramError, Update, NullHandler)
from telegram import (TelegramError, NullHandler)
from telegram.ext.handler import Handler
from telegram.utils.updatequeue import Empty
logging.getLogger(__name__).addHandler(NullHandler())
@ -35,13 +34,12 @@ semaphore = None
async_threads = set()
""":type: set[Thread]"""
async_lock = Lock()
DEFAULT_GROUP = 0
def run_async(func):
"""
Function decorator that will run the function in a new thread. A function
decorated with this will have to include **kwargs in their parameter list,
which will contain all optional parameters.
Function decorator that will run the function in a new thread.
Args:
func (function): The function to run in the thread.
@ -82,52 +80,6 @@ def run_async(func):
class Dispatcher:
"""
This class dispatches all kinds of updates to its registered handlers.
A handler is a function that usually takes the following parameters
bot:
The telegram.Bot instance that received the message
update:
The update that should be handled by the handler
Error handlers take an additional parameter
error:
The TelegramError instance that was raised during processing the
update
All handlers, except error handlers, can also request more information by
appending one or more of the following arguments in their argument list for
convenience
update_queue:
The Queue instance which contains all new updates and is
processed by the Dispatcher. Be careful with this - you might
create an infinite loop.
args:
If the update is an instance str or telegram.Update, this will be
a list that contains the content of the message split on spaces,
except the first word (usually the command).
Example: '/add item1 item2 item3' -> ['item1', 'item2', 'item3']
For updates that contain inline queries, they will contain the
whole query split on spaces.
For other updates, args will be None
In some cases handlers may need some context data to process the update. To
procedure just queue in update_queue.put(update, context=context) or
processUpdate(update,context=context).
context:
Extra data for handling updates.
For regex-based handlers, you can also request information about the match.
For all other handlers, these will be None
groups:
A tuple that contains the result of
re.match(matcher, ...).groups()
groupdict:
A dictionary that contains the result of
re.match(matcher, ...).groupdict()
Args:
bot (telegram.Bot): The bot object that should be passed to the
@ -138,16 +90,10 @@ class Dispatcher:
def __init__(self, bot, update_queue, workers=4, exception_event=None):
self.bot = bot
self.update_queue = update_queue
self.telegram_message_handlers = []
self.telegram_inline_handlers = []
self.telegram_command_handlers = {}
self.telegram_regex_handlers = {}
self.string_regex_handlers = {}
self.string_command_handlers = {}
self.type_handlers = {}
self.unknown_telegram_command_handlers = []
self.unknown_string_command_handlers = []
self.handlers = {}
self.error_handlers = []
self.logger = logging.getLogger(__name__)
self.running = False
self.__stop_event = Event()
@ -177,10 +123,10 @@ class Dispatcher:
self.running = True
self.logger.debug('Dispatcher started')
while 1:
while True:
try:
# Pop update from update queue.
update, context = self.update_queue.get(True, 1, True)
update = self.update_queue.get(True, 1)
except Empty:
if self.__stop_event.is_set():
self.logger.debug('orderly stopping')
@ -191,26 +137,8 @@ class Dispatcher:
break
continue
try:
self.processUpdate(update, context)
self.logger.debug('Processed Update: %s with context %s'
% (update, context))
# Dispatch any errors
except TelegramError as te:
self.logger.warn("Error was raised while processing Update.")
try:
self.dispatchError(update, te)
# Log errors in error handlers
except:
self.logger.exception("An uncaught error was raised while "
"handling the error")
# All other errors should not stop the thread, just print them
except:
self.logger.exception("An uncaught error was raised while "
"processing an update")
self.logger.debug('Processing Update: %s' % update)
self.processUpdate(update)
self.running = False
self.logger.debug('Dispatcher thread stopped')
@ -225,7 +153,7 @@ class Dispatcher:
sleep(0.1)
self.__stop_event.clear()
def processUpdate(self, update, context=None):
def processUpdate(self, update):
"""
Processes a single update.
@ -233,164 +161,77 @@ class Dispatcher:
update (any):
"""
handled = False
# Custom type handlers
for t in self.type_handlers:
if isinstance(update, t):
self.dispatchType(update, context)
handled = True
# string update
if type(update) is str and update.startswith('/'):
self.dispatchStringCommand(update, context)
handled = True
elif type(update) is str:
self.dispatchRegex(update, context)
handled = True
# An error happened while polling
if isinstance(update, TelegramError):
self.dispatchError(None, update)
handled = True
# Telegram update (regex)
if isinstance(update, Update) and update.message is not None:
self.dispatchRegex(update, context)
handled = True
else:
for group in self.handlers.values():
handler_triggered = False
# Telegram update (command)
if update.message.text.startswith('/'):
self.dispatchTelegramCommand(update, context)
for handler in group:
try:
if handler.checkUpdate(update):
handler_triggered = True
handler.handleUpdate(update, self)
# Dispatch any errors
except TelegramError as te:
self.logger.warn(
'Error was raised while processing Update.')
# Telegram update (message)
else:
self.dispatchTelegramMessage(update, context)
handled = True
elif isinstance(update, Update) and \
(update.inline_query is not None or
update.chosen_inline_result is not None):
self.dispatchTelegramInline(update, context)
handled = True
# Update not recognized
if not handled:
self.dispatchError(update, TelegramError(
"Received update of unknown type %s" % type(update)))
try:
self.dispatchError(update, te)
except:
self.logger.exception(
'An uncaught error was raised while '
'handling the error')
# Add Handlers
def addTelegramMessageHandler(self, handler):
# Errors should not stop the thread
except:
self.logger.exception(
'An uncaught error was raised while '
'processing the update')
finally:
if handler_triggered:
break
def addHandler(self, handler, group=DEFAULT_GROUP):
"""
Registers a message handler in the Dispatcher.
Register a handler. A handler must be an instance of a subclass of
telegram.ext.Handler. All handlers are organized in groups, the default
group is int(0), but any object can identify a group. Every update will
be tested against each handler in each group from first-added to last-
added. If the update has been handled in one group, it will not be
tested against other handlers in that group. That means an update can
only be handled 0 or 1 times per group, but multiple times across all
groups.
Args:
handler (function): A function that takes (Bot, Update, *args) as
arguments.
handler (Handler): A Handler instance
group (object): The group identifier
"""
self.telegram_message_handlers.append(handler)
if not isinstance(handler, Handler):
raise TypeError('Handler is no instance of telegram.ext.Handler')
def addTelegramInlineHandler(self, handler):
if group not in self.handlers:
self.handlers[group] = list()
self.handlers[group].append(handler)
def removeHandler(self, handler, group=DEFAULT_GROUP):
"""
Registers an inline query handler in the Dispatcher.
Remove a handler from the specified group
Args:
handler (function): A function that takes (Bot, Update, *args) as
arguments.
handler (Handler): A Handler instance
group (object): The group identifier
"""
if handler in self.handlers[group]:
self.handlers[group].remove(handler)
self.telegram_inline_handlers.append(handler)
def addTelegramCommandHandler(self, command, handler):
"""
Registers a command handler in the Dispatcher.
Args:
command (str): The command keyword that this handler should be
listening to.
handler (function): A function that takes (Bot, Update, *args) as
arguments.
"""
if command not in self.telegram_command_handlers:
self.telegram_command_handlers[command] = []
self.telegram_command_handlers[command].append(handler)
def addTelegramRegexHandler(self, matcher, handler):
"""
Registers a regex handler in the Dispatcher. If handlers will be
called if re.match(matcher, update.message.text) is True.
Args:
matcher (str/__Regex): A regex string or compiled regex object that
matches on messages that handler should be listening to
handler (function): A function that takes (Bot, Update, *args) as
arguments.
"""
if matcher not in self.telegram_regex_handlers:
self.telegram_regex_handlers[matcher] = []
self.telegram_regex_handlers[matcher].append(handler)
def addStringCommandHandler(self, command, handler):
"""
Registers a string-command handler in the Dispatcher.
Args:
command (str): The command keyword that this handler should be
listening to.
handler (function): A function that takes (Bot, str, *args) as
arguments.
"""
if command not in self.string_command_handlers:
self.string_command_handlers[command] = []
self.string_command_handlers[command].append(handler)
def addStringRegexHandler(self, matcher, handler):
"""
Registers a regex handler in the Dispatcher. If handlers will be
called if re.match(matcher, string) is True.
Args:
matcher (str/__Regex): A regex string or compiled regex object that
matches on the string input that handler should be listening to
handler (function): A function that takes (Bot, Update, *args) as
arguments.
"""
if matcher not in self.string_regex_handlers:
self.string_regex_handlers[matcher] = []
self.string_regex_handlers[matcher].append(handler)
def addUnknownTelegramCommandHandler(self, handler):
"""
Registers a command handler in the Dispatcher, that will receive all
commands that have no associated handler.
Args:
handler (function): A function that takes (Bot, Update, *args) as
arguments.
"""
self.unknown_telegram_command_handlers.append(handler)
def addUnknownStringCommandHandler(self, handler):
"""
Registers a string-command handler in the Dispatcher, that will
receive all commands that have no associated handler.
Args:
handler (function): A function that takes (Bot, str, *args) as
arguments.
"""
self.unknown_string_command_handlers.append(handler)
def addErrorHandler(self, handler):
def addErrorHandler(self, callback):
"""
Registers an error handler in the Dispatcher.
@ -399,122 +240,9 @@ class Dispatcher:
arguments.
"""
self.error_handlers.append(handler)
self.error_handlers.append(callback)
def addTypeHandler(self, the_type, handler):
"""
Registers a type handler in the Dispatcher. This allows you to send
any type of object into the update queue.
Args:
the_type (type): The type this handler should listen to
handler (function): A function that takes (Bot, type, *args) as
arguments.
"""
if the_type not in self.type_handlers:
self.type_handlers[the_type] = []
self.type_handlers[the_type].append(handler)
# Remove Handlers
def removeTelegramMessageHandler(self, handler):
"""
De-registers a message handler.
Args:
handler (any):
"""
if handler in self.telegram_message_handlers:
self.telegram_message_handlers.remove(handler)
def removeTelegramInlineHandler(self, handler):
"""
De-registers an inline query handler.
Args:
handler (any):
"""
if handler in self.telegram_inline_handlers:
self.telegram_inline_handlers.remove(handler)
def removeTelegramCommandHandler(self, command, handler):
"""
De-registers a command handler.
Args:
command (str): The command
handler (any):
"""
if command in self.telegram_command_handlers \
and handler in self.telegram_command_handlers[command]:
self.telegram_command_handlers[command].remove(handler)
def removeTelegramRegexHandler(self, matcher, handler):
"""
De-registers a regex handler.
Args:
matcher (str/__Regex): The regex matcher object or string
handler (any):
"""
if matcher in self.telegram_regex_handlers \
and handler in self.telegram_regex_handlers[matcher]:
self.telegram_regex_handlers[matcher].remove(handler)
def removeStringCommandHandler(self, command, handler):
"""
De-registers a string-command handler.
Args:
command (str): The command
handler (any):
"""
if command in self.string_command_handlers \
and handler in self.string_command_handlers[command]:
self.string_command_handlers[command].remove(handler)
def removeStringRegexHandler(self, matcher, handler):
"""
De-registers a regex handler.
Args:
matcher (str/__Regex): The regex matcher object or string
handler (any):
"""
if matcher in self.string_regex_handlers \
and handler in self.string_regex_handlers[matcher]:
self.string_regex_handlers[matcher].remove(handler)
def removeUnknownTelegramCommandHandler(self, handler):
"""
De-registers an unknown-command handler.
Args:
handler (any):
"""
if handler in self.unknown_telegram_command_handlers:
self.unknown_telegram_command_handlers.remove(handler)
def removeUnknownStringCommandHandler(self, handler):
"""
De-registers an unknown-command handler.
Args:
handler (any):
"""
if handler in self.unknown_string_command_handlers:
self.unknown_string_command_handlers.remove(handler)
def removeErrorHandler(self, handler):
def removeErrorHandler(self, callback):
"""
De-registers an error handler.
@ -522,117 +250,8 @@ class Dispatcher:
handler (any):
"""
if handler in self.error_handlers:
self.error_handlers.remove(handler)
def removeTypeHandler(self, the_type, handler):
"""
De-registers a type handler.
Args:
handler (any):
"""
if the_type in self.type_handlers \
and handler in self.type_handlers[the_type]:
self.type_handlers[the_type].remove(handler)
def dispatchTelegramCommand(self, update, context=None):
"""
Dispatches an update that contains a command.
Args:
command (str): The command keyword
update (telegram.Update): The Telegram update that contains the
command
"""
command = split('\W', update.message.text[1:])[0]
if command in self.telegram_command_handlers:
self.dispatchTo(self.telegram_command_handlers[command], update,
context=context)
else:
self.dispatchTo(self.unknown_telegram_command_handlers, update,
context=context)
def dispatchRegex(self, update, context=None):
"""
Dispatches an update to all string or telegram regex handlers that
match the string/message content.
Args:
update (str, Update): The update that should be checked for matches
"""
if isinstance(update, Update):
handlers = self.telegram_regex_handlers
to_match = update.message.text
elif isinstance(update, str):
handlers = self.string_regex_handlers
to_match = update
for matcher in handlers:
m = match(matcher, to_match)
if m:
for handler in handlers[matcher]:
self.call_handler(handler,
update,
groups=m.groups(),
groupdict=m.groupdict(),
context=context)
def dispatchStringCommand(self, update, context=None):
"""
Dispatches a string-update that contains a command.
Args:
update (str): The string input
"""
command = update.split(' ')[0][1:]
if command in self.string_command_handlers:
self.dispatchTo(self.string_command_handlers[command], update,
context=context)
else:
self.dispatchTo(self.unknown_string_command_handlers, update,
context=context)
def dispatchType(self, update, context=None):
"""
Dispatches an update of any type.
Args:
update (any): The update
"""
for t in self.type_handlers:
if isinstance(update, t):
self.dispatchTo(self.type_handlers[t], update, context=context)
def dispatchTelegramMessage(self, update, context=None):
"""
Dispatches an update that contains a regular message.
Args:
update (telegram.Update): The Telegram update that contains the
message.
"""
self.dispatchTo(self.telegram_message_handlers, update,
context=context)
def dispatchTelegramInline(self, update, context=None):
"""
Dispatches an update that contains an inline update.
Args:
update (telegram.Update): The Telegram update that contains the
message.
"""
self.dispatchTo(self.telegram_inline_handlers, update, context=None)
if callback in self.error_handlers:
self.error_handlers.remove(callback)
def dispatchError(self, update, error):
"""
@ -643,63 +262,5 @@ class Dispatcher:
error (telegram.TelegramError): The Telegram error that was raised.
"""
for handler in self.error_handlers:
handler(self.bot, update, error)
def dispatchTo(self, handlers, update, **kwargs):
"""
Dispatches an update to a list of handlers.
Args:
handlers (list): A list of handler-functions.
update (any): The update to be dispatched
"""
for handler in handlers:
self.call_handler(handler, update, **kwargs)
def call_handler(self, handler, update, **kwargs):
"""
Calls an update handler. Checks the handler for keyword arguments and
fills them, if possible.
Args:
handler (function): An update handler function
update (any): An update
"""
target_kwargs = {}
fargs = getargspec(handler).args
'''
async handlers will receive all optional arguments, since we can't
their argument list.
'''
is_async = 'pargs' == getargspec(handler).varargs
if is_async or 'update_queue' in fargs:
target_kwargs['update_queue'] = self.update_queue
if is_async or 'args' in fargs:
if isinstance(update, Update) and update.message:
args = update.message.text.split(' ')[1:]
elif isinstance(update, Update) and update.inline_query:
args = update.inline_query.query.split(' ')
elif isinstance(update, str):
args = update.split(' ')[1:]
else:
args = None
target_kwargs['args'] = args
if is_async or 'groups' in fargs:
target_kwargs['groups'] = kwargs.get('groups', None)
if is_async or 'groupdict' in fargs:
target_kwargs['groupdict'] = kwargs.get('groupdict', None)
if is_async or 'context' in fargs:
target_kwargs['context'] = kwargs.get('context', None)
handler(self.bot, update, **target_kwargs)
for callback in self.error_handlers:
callback(self.bot, update, error)

2
telegram/ext/filters.py Normal file
View file

@ -0,0 +1,2 @@
TEXT, AUDIO, DOCUMENT, PHOTO, STICKER, VIDEO, VOICE, CONTACT, LOCATION, \
VENUE, STATUS_UPDATE = range(11)

65
telegram/ext/handler.py Normal file
View file

@ -0,0 +1,65 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2016
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
""" This module contains the base class for handlers as used by the
Dispatcher """
class Handler(object):
def __init__(self, callback, pass_update_queue=False):
self.callback = callback
self.pass_update_queue = pass_update_queue
def checkUpdate(self, update):
"""
This method is called to determine if an update should be handled by
this handler instance. It should always be overridden.
Args:
update (object): The update to be tested
"""
raise NotImplementedError
def handleUpdate(self, update, dispatcher):
"""
This method is called if it was determined that an update should indeed
be handled by this instance. It should also be overridden, but in most
cases call self.callback(dispatcher.bot, update), possibly along with
optional arguments.
Args:
update (object): The update to be handled
"""
raise NotImplementedError
def collectOptionalArgs(self, dispatcher):
"""
Prepares the optional arguments that are the same for all types of
handlers
Args:
dispatcher (Dispatcher):
"""
optional_args = dict()
if self.pass_update_queue:
optional_args['update_queue'] = dispatcher.update_queue
return optional_args

View file

@ -0,0 +1,68 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2016
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
""" This module contains the base class for handlers as used by the
Dispatcher """
from .handler import Handler
from telegram import Update
from .filters import *
class MessageHandler(Handler):
def __init__(self, filters, callback, pass_update_queue=False):
super(Handler).__init__(callback, pass_update_queue)
self.filters = filters
def checkUpdate(self, update):
filters = self.filters
if isinstance(update, Update) and update.message:
message = update.message
return (TEXT in filters and message.text and
not message.text.startswith('/') or
AUDIO in filters and message.audio or
DOCUMENT in filters and message.document or
PHOTO in filters and message.photo or
STICKER in filters and message.sticker or
VIDEO in filters and message.video or
VOICE in filters and message.voice or
CONTACT in filters and message.contact or
LOCATION in filters and message.location or
VENUE in filters and message.venue or
STATUS_UPDATE in filters and (
message.new_chat_member or
message.left_chat_member or
message.new_chat_title or
message.new_chat_photo or
message.delete_chat_photo or
message.group_chat_created or
message.supergroup_chat_created or
message.channel_chat_created or
message.migrate_to_chat_id or
message.migrate_from_chat_id or
message.pinned_message)
)
else:
return False
def handleUpdate(self, update, dispatcher):
optional_args = self.collectOptionalArgs(dispatcher)
self.callback(dispatcher.bot, update, **optional_args)

View file

@ -0,0 +1,60 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2016
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
""" This module contains the base class for handlers as used by the
Dispatcher """
import re
from .handler import Handler
from telegram import Update
class RegexHandler(Handler):
def __init__(self, pattern, callback, pass_groups=False,
pass_groupdict=False, pass_update_queue=False):
super(Handler).__init__(callback, pass_update_queue)
if isinstance(pattern, str):
pattern = re.compile(pattern)
self.pattern = pattern
self.pass_groups = pass_groups
self.pass_groupdict = pass_groupdict
def checkUpdate(self, update):
if (isinstance(update, Update) and
update.message and
update.message.text):
match = re.match(self.pattern, update.message.text)
return bool(match)
else:
return False
def handleUpdate(self, update, dispatcher):
optional_args = self.collectOptionalArgs(dispatcher)
match = re.match(self.pattern, update.message.text)
if self.pass_groups:
optional_args['groups'] = match.groups()
if self.pass_groupdict:
optional_args['groupdict'] = match.groupdict()
self.callback(dispatcher.bot, update, **optional_args)

View file

@ -28,10 +28,16 @@ from threading import Thread, Lock, current_thread, Event
from time import sleep
import subprocess
from signal import signal, SIGINT, SIGTERM, SIGABRT
# Adjust for differences in Python versions
try:
from queue import Queue # flake8: noqa
except ImportError:
from Queue import Queue # flake8: noqa
from telegram import Bot, TelegramError, NullHandler
from telegram.ext import dispatcher, Dispatcher, JobQueue
from telegram.error import Unauthorized, InvalidToken
from telegram.utils.updatequeue import UpdateQueue
from telegram.utils.webhookhandler import (WebhookServer, WebhookHandler)
logging.getLogger(__name__).addHandler(NullHandler())
@ -81,7 +87,7 @@ class Updater:
self.bot = bot
else:
self.bot = Bot(token, base_url)
self.update_queue = UpdateQueue()
self.update_queue = Queue()
self.job_queue = JobQueue(self.bot, job_queue_tick_interval)
self.__exception_event = Event()
self.dispatcher = Dispatcher(self.bot, self.update_queue, workers,

View file

@ -1,60 +0,0 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2016
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the class UpdateQueue to override standard
Queue."""
# Adjust for differences in Python versions
try:
# loading Empty here so it can be imported by users of updatequeue
from queue import Queue, Empty # flake8: noqa
except ImportError:
from Queue import Queue, Empty # flake8: noqa
class UpdateQueue(Queue):
"""
This class overrides standard Queues. Allows you to de/queue context
data apart from the handled `update`
"""
def put(self, item, block=True, timeout=None, context=None):
"""
Put an item into the queue with context data if provided as a
tuple (item, context). Overrides standard Queue.put method.
Args:
update (any): handled by the dispatcher
context (any): extra data to use in handlers
"""
Queue.put(self, (item, context), block, timeout)
def get(self, block=True, timeout=None, context=False):
"""
Remove and return an item from the queue. A tuple of
(update, context) if requested. Overrides standard Queue.get
method.
Args:
context (boolean): set true to get (update, context)
"""
if not context:
return Queue.get(self, block, timeout)[0]
return Queue.get(self, block, timeout)