Skip to content

Commit 9fd298a

Browse files
authored
Merge pull request python-telegram-bot#307 from python-telegram-bot/jobqueue-rework
Make job queue API similar to the dispatcher, add new functionality
2 parents ecbc268 + 3107310 commit 9fd298a

17 files changed

+471
-199
lines changed

examples/timerbot.py

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@
1717
bot.
1818
"""
1919

20-
from telegram.ext import Updater, CommandHandler
20+
from telegram.ext import Updater, CommandHandler, Job
2121
import logging
2222

2323
# Enable logging
2424
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
25-
level=logging.INFO)
25+
level=logging.DEBUG)
2626

2727
logger = logging.getLogger(__name__)
28-
job_queue = None
28+
timers = dict()
2929

3030

3131
# Define a few command handlers. These usually take the two arguments bot and
@@ -34,46 +34,58 @@ def start(bot, update):
3434
bot.sendMessage(update.message.chat_id, text='Hi! Use /set <seconds> to ' 'set a timer')
3535

3636

37-
def set(bot, update, args):
38-
""" Adds a job to the queue """
37+
def set(bot, update, args, job_queue):
38+
"""Adds a job to the queue"""
3939
chat_id = update.message.chat_id
4040
try:
4141
# args[0] should contain the time for the timer in seconds
4242
due = int(args[0])
4343
if due < 0:
4444
bot.sendMessage(chat_id, text='Sorry we can not go back to future!')
4545

46-
def alarm(bot):
47-
""" Inner function to send the alarm message """
46+
def alarm(bot, job):
47+
"""Inner function to send the alarm message"""
4848
bot.sendMessage(chat_id, text='Beep!')
4949

5050
# Add job to queue
51-
job_queue.put(alarm, due, repeat=False)
51+
job = Job(alarm, due, repeat=False)
52+
timers[chat_id] = job
53+
job_queue.put(job)
54+
5255
bot.sendMessage(chat_id, text='Timer successfully set!')
5356

54-
except IndexError:
55-
bot.sendMessage(chat_id, text='Usage: /set <seconds>')
56-
except ValueError:
57+
except (IndexError, ValueError):
5758
bot.sendMessage(chat_id, text='Usage: /set <seconds>')
5859

5960

61+
def unset(bot, update):
62+
"""Removes the job if the user changed their mind"""
63+
chat_id = update.message.chat_id
64+
65+
if chat_id not in timers:
66+
bot.sendMessage(chat_id, text='You have no active timer')
67+
return
68+
69+
job = timers[chat_id]
70+
job.schedule_removal()
71+
bot.sendMessage(chat_id, text='Timer successfully unset!')
72+
73+
6074
def error(bot, update, error):
6175
logger.warn('Update "%s" caused error "%s"' % (update, error))
6276

6377

6478
def main():
65-
global job_queue
66-
6779
updater = Updater("TOKEN")
68-
job_queue = updater.job_queue
6980

7081
# Get the dispatcher to register handlers
7182
dp = updater.dispatcher
7283

7384
# on different commands - answer in Telegram
7485
dp.add_handler(CommandHandler("start", start))
7586
dp.add_handler(CommandHandler("help", start))
76-
dp.add_handler(CommandHandler("set", set, pass_args=True))
87+
dp.add_handler(CommandHandler("set", set, pass_args=True, pass_job_queue=True))
88+
dp.add_handler(CommandHandler("unset", unset))
7789

7890
# log all errors
7991
dp.add_error_handler(error)

telegram/ext/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"""Extensions over the Telegram Bot API to facilitate bot making"""
2020

2121
from .dispatcher import Dispatcher
22-
from .jobqueue import JobQueue
22+
from .jobqueue import JobQueue, Job
2323
from .updater import Updater
2424
from .callbackqueryhandler import CallbackQueryHandler
2525
from .choseninlineresulthandler import ChosenInlineResultHandler
@@ -32,7 +32,7 @@
3232
from .stringregexhandler import StringRegexHandler
3333
from .typehandler import TypeHandler
3434

35-
__all__ = ('Dispatcher', 'JobQueue', 'Updater', 'CallbackQueryHandler',
35+
__all__ = ('Dispatcher', 'JobQueue', 'Job', 'Updater', 'CallbackQueryHandler',
3636
'ChosenInlineResultHandler', 'CommandHandler', 'Handler', 'InlineQueryHandler',
3737
'MessageHandler', 'Filters', 'RegexHandler', 'StringCommandHandler',
3838
'StringRegexHandler', 'TypeHandler')

telegram/ext/callbackqueryhandler.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,20 @@ class CallbackQueryHandler(Handler):
3131
callback (function): A function that takes ``bot, update`` as
3232
positional arguments. It will be called when the ``check_update``
3333
has determined that an update should be processed by this handler.
34-
pass_update_queue (optional[bool]): If the handler should be passed the
35-
update queue as a keyword argument called ``update_queue``. It can
36-
be used to insert updates. Default is ``False``
34+
pass_update_queue (optional[bool]): If set to ``True``, a keyword argument called
35+
``update_queue`` will be passed to the callback function. It will be the ``Queue``
36+
instance used by the ``Updater`` and ``Dispatcher`` that contains new updates which can
37+
be used to insert updates. Default is ``False``.
38+
pass_job_queue (optional[bool]): If set to ``True``, a keyword argument called
39+
``job_queue`` will be passed to the callback function. It will be a ``JobQueue``
40+
instance created by the ``Updater`` which can be used to schedule new jobs.
41+
Default is ``False``.
3742
"""
3843

39-
def __init__(self, callback, pass_update_queue=False):
40-
super(CallbackQueryHandler, self).__init__(callback, pass_update_queue)
44+
def __init__(self, callback, pass_update_queue=False, pass_job_queue=False):
45+
super(CallbackQueryHandler, self).__init__(callback,
46+
pass_update_queue=pass_update_queue,
47+
pass_job_queue=pass_job_queue)
4148

4249
def check_update(self, update):
4350
return isinstance(update, Update) and update.callback_query

telegram/ext/choseninlineresulthandler.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,20 @@ class ChosenInlineResultHandler(Handler):
3232
callback (function): A function that takes ``bot, update`` as
3333
positional arguments. It will be called when the ``check_update``
3434
has determined that an update should be processed by this handler.
35-
pass_update_queue (optional[bool]): If the handler should be passed the
36-
update queue as a keyword argument called ``update_queue``. It can
37-
be used to insert updates. Default is ``False``
35+
pass_update_queue (optional[bool]): If set to ``True``, a keyword argument called
36+
``update_queue`` will be passed to the callback function. It will be the ``Queue``
37+
instance used by the ``Updater`` and ``Dispatcher`` that contains new updates which can
38+
be used to insert updates. Default is ``False``.
39+
pass_job_queue (optional[bool]): If set to ``True``, a keyword argument called
40+
``job_queue`` will be passed to the callback function. It will be a ``JobQueue``
41+
instance created by the ``Updater`` which can be used to schedule new jobs.
42+
Default is ``False``.
3843
"""
3944

40-
def __init__(self, callback, pass_update_queue=False):
41-
super(ChosenInlineResultHandler, self).__init__(callback, pass_update_queue)
45+
def __init__(self, callback, pass_update_queue=False, pass_job_queue=False):
46+
super(ChosenInlineResultHandler, self).__init__(callback,
47+
pass_update_queue=pass_update_queue,
48+
pass_job_queue=pass_job_queue)
4249

4350
def check_update(self, update):
4451
return isinstance(update, Update) and update.chosen_inline_result

telegram/ext/commandhandler.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,26 @@ class CommandHandler(Handler):
4040
arguments passed to the command as a keyword argument called `
4141
``args``. It will contain a list of strings, which is the text
4242
following the command split on spaces. Default is ``False``
43-
pass_update_queue (optional[bool]): If the handler should be passed the
44-
update queue as a keyword argument called ``update_queue``. It can
45-
be used to insert updates. Default is ``False``
43+
pass_update_queue (optional[bool]): If set to ``True``, a keyword argument called
44+
``update_queue`` will be passed to the callback function. It will be the ``Queue``
45+
instance used by the ``Updater`` and ``Dispatcher`` that contains new updates which can
46+
be used to insert updates. Default is ``False``.
47+
pass_job_queue (optional[bool]): If set to ``True``, a keyword argument called
48+
``job_queue`` will be passed to the callback function. It will be a ``JobQueue``
49+
instance created by the ``Updater`` which can be used to schedule new jobs.
50+
Default is ``False``.
4651
"""
4752

4853
def __init__(self,
4954
command,
5055
callback,
5156
allow_edited=False,
5257
pass_args=False,
53-
pass_update_queue=False):
54-
super(CommandHandler, self).__init__(callback, pass_update_queue)
58+
pass_update_queue=False,
59+
pass_job_queue=False):
60+
super(CommandHandler, self).__init__(callback,
61+
pass_update_queue=pass_update_queue,
62+
pass_job_queue=pass_job_queue)
5563
self.command = command
5664
self.allow_edited = allow_edited
5765
self.pass_args = pass_args

telegram/ext/dispatcher.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,16 @@ class Dispatcher(object):
9494
handlers
9595
update_queue (Queue): The synchronized queue that will contain the
9696
updates.
97+
job_queue (Optional[telegram.ext.JobQueue]): The ``JobQueue`` instance to pass onto handler
98+
callbacks
99+
workers (Optional[int]): Number of maximum concurrent worker threads for the ``@run_async``
100+
decorator
97101
"""
98102

99-
def __init__(self, bot, update_queue, workers=4, exception_event=None):
103+
def __init__(self, bot, update_queue, workers=4, exception_event=None, job_queue=None):
100104
self.bot = bot
101105
self.update_queue = update_queue
106+
self.job_queue = job_queue
102107

103108
self.handlers = {}
104109
""":type: dict[int, list[Handler]"""

telegram/ext/handler.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,20 @@ class Handler(object):
3131
callback (function): A function that takes ``bot, update`` as
3232
positional arguments. It will be called when the ``check_update``
3333
has determined that an update should be processed by this handler.
34-
pass_update_queue (optional[bool]): If the callback should be passed
35-
the update queue as a keyword argument called ``update_queue``. It
36-
can be used to insert updates. Default is ``False``
34+
pass_update_queue (optional[bool]): If set to ``True``, a keyword argument called
35+
``update_queue`` will be passed to the callback function. It will be the ``Queue``
36+
instance used by the ``Updater`` and ``Dispatcher`` that contains new updates which can
37+
be used to insert updates. Default is ``False``.
38+
pass_job_queue (optional[bool]): If set to ``True``, a keyword argument called
39+
``job_queue`` will be passed to the callback function. It will be a ``JobQueue``
40+
instance created by the ``Updater`` which can be used to schedule new jobs.
41+
Default is ``False``.
3742
"""
3843

39-
def __init__(self, callback, pass_update_queue=False):
44+
def __init__(self, callback, pass_update_queue=False, pass_job_queue=False):
4045
self.callback = callback
4146
self.pass_update_queue = pass_update_queue
47+
self.pass_job_queue = pass_job_queue
4248

4349
def check_update(self, update):
4450
"""
@@ -77,6 +83,8 @@ def collect_optional_args(self, dispatcher):
7783
optional_args = dict()
7884
if self.pass_update_queue:
7985
optional_args['update_queue'] = dispatcher.update_queue
86+
if self.pass_job_queue:
87+
optional_args['job_queue'] = dispatcher.job_queue
8088

8189
return optional_args
8290

telegram/ext/inlinequeryhandler.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,20 @@ class InlineQueryHandler(Handler):
3131
callback (function): A function that takes ``bot, update`` as
3232
positional arguments. It will be called when the ``check_update``
3333
has determined that an update should be processed by this handler.
34-
pass_update_queue (optional[bool]): If the handler should be passed the
35-
update queue as a keyword argument called ``update_queue``. It can
36-
be used to insert updates. Default is ``False``
34+
pass_update_queue (optional[bool]): If set to ``True``, a keyword argument called
35+
``update_queue`` will be passed to the callback function. It will be the ``Queue``
36+
instance used by the ``Updater`` and ``Dispatcher`` that contains new updates which can
37+
be used to insert updates. Default is ``False``.
38+
pass_job_queue (optional[bool]): If set to ``True``, a keyword argument called
39+
``job_queue`` will be passed to the callback function. It will be a ``JobQueue``
40+
instance created by the ``Updater`` which can be used to schedule new jobs.
41+
Default is ``False``.
3742
"""
3843

39-
def __init__(self, callback, pass_update_queue=False):
40-
super(InlineQueryHandler, self).__init__(callback, pass_update_queue)
44+
def __init__(self, callback, pass_update_queue=False, pass_job_queue=False):
45+
super(InlineQueryHandler, self).__init__(callback,
46+
pass_update_queue=pass_update_queue,
47+
pass_job_queue=pass_job_queue)
4148

4249
def check_update(self, update):
4350
return isinstance(update, Update) and update.inline_query

0 commit comments

Comments
 (0)