MessageHandler / filters: refactor

filters are now functions instead of enum like objects.
their definitions were moved to messagehandler.py
This commit is contained in:
Noam Meltzer 2016-04-25 14:26:52 +03:00
parent 8ff8d57998
commit 3f28633e79
11 changed files with 89 additions and 77 deletions

View file

@ -371,9 +371,8 @@ Our bot is now up and running (go ahead and try it)! It's not doing anything yet
>>> def echo(bot, update): >>> def echo(bot, update):
... bot.sendMessage(chat_id=update.message.chat_id, text=update.message.text) ... bot.sendMessage(chat_id=update.message.chat_id, text=update.message.text)
... ...
>>> from telegram.ext import MessageHandler >>> from telegram.ext import MessageHandler, Filters
>>> from telegram.ext import filters >>> echo_handler = MessageHandler([Filters.text], echo)
>>> echo_handler = MessageHandler([filters.TEXT], echo)
>>> dispatcher.addHandler(echo_handler) >>> dispatcher.addHandler(echo_handler)
Our bot should now reply to all text messages that are not a command with a message that has the same content. Our bot should now reply to all text messages that are not a command with a message that has the same content.

View file

@ -1,7 +0,0 @@
telegram.ext.filters module
===========================
.. automodule:: telegram.ext.filters
:members:
:undoc-members:
:show-inheritance:

View file

@ -14,7 +14,6 @@ Submodules
telegram.ext.commandhandler telegram.ext.commandhandler
telegram.ext.inlinequeryhandler telegram.ext.inlinequeryhandler
telegram.ext.messagehandler telegram.ext.messagehandler
telegram.ext.filters
telegram.ext.regexhandler telegram.ext.regexhandler
telegram.ext.stringcommandhandler telegram.ext.stringcommandhandler
telegram.ext.stringregexhandler telegram.ext.stringregexhandler

View file

@ -19,7 +19,7 @@ Type 'stop' on the command line to stop the bot.
""" """
from telegram.ext import Updater, StringCommandHandler, StringRegexHandler, \ from telegram.ext import Updater, StringCommandHandler, StringRegexHandler, \
MessageHandler, CommandHandler, RegexHandler, filters MessageHandler, CommandHandler, RegexHandler, Filters
from telegram.ext.dispatcher import run_async from telegram.ext.dispatcher import run_async
from time import sleep from time import sleep
import logging import logging
@ -115,7 +115,7 @@ def main():
dp.addHandler(CommandHandler("start", start)) dp.addHandler(CommandHandler("start", start))
dp.addHandler(CommandHandler("help", help)) dp.addHandler(CommandHandler("help", help))
# Message handlers only receive updates that don't contain commands # Message handlers only receive updates that don't contain commands
dp.addHandler(MessageHandler([filters.TEXT], message)) dp.addHandler(MessageHandler([Filters.text], message))
# Regex handlers will receive all updates on which their regex matches, # Regex handlers will receive all updates on which their regex matches,
# but we have to add it in a separate group, since in one group, # but we have to add it in a separate group, since in one group,
# only one handler will be executed # only one handler will be executed

View file

@ -17,7 +17,7 @@ Press Ctrl-C on the command line or send a signal to the process to stop the
bot. bot.
""" """
from telegram.ext import Updater, CommandHandler, MessageHandler, filters from telegram.ext import Updater, CommandHandler, MessageHandler, Filters
import logging import logging
# Enable logging # Enable logging
@ -58,7 +58,7 @@ def main():
dp.addHandler(CommandHandler("help", help)) dp.addHandler(CommandHandler("help", help))
# on noncommand i.e message - echo the message on Telegram # on noncommand i.e message - echo the message on Telegram
dp.addHandler(MessageHandler([filters.TEXT], echo)) dp.addHandler(MessageHandler([Filters.text], echo))
# log all errors # log all errors
dp.addErrorHandler(error) dp.addErrorHandler(error)

View file

@ -9,7 +9,7 @@ import logging
from telegram import Emoji, ForceReply, InlineKeyboardButton, \ from telegram import Emoji, ForceReply, InlineKeyboardButton, \
InlineKeyboardMarkup InlineKeyboardMarkup
from telegram.ext import Updater, CommandHandler, MessageHandler, \ from telegram.ext import Updater, CommandHandler, MessageHandler, \
CallbackQueryHandler, filters CallbackQueryHandler, Filters
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - ' logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - '
'%(message)s', '%(message)s',
@ -105,7 +105,7 @@ updater = Updater("TOKEN")
# The command # The command
updater.dispatcher.addHandler(CommandHandler('set', set_value)) updater.dispatcher.addHandler(CommandHandler('set', set_value))
# The answer # The answer
updater.dispatcher.addHandler(MessageHandler([filters.TEXT], entered_value)) updater.dispatcher.addHandler(MessageHandler([Filters.text], entered_value))
# The confirmation # The confirmation
updater.dispatcher.addHandler(CallbackQueryHandler(confirm_value)) updater.dispatcher.addHandler(CallbackQueryHandler(confirm_value))
updater.dispatcher.addHandler(CommandHandler('start', help)) updater.dispatcher.addHandler(CommandHandler('start', help))

View file

@ -6,7 +6,7 @@
import logging import logging
from telegram import Emoji, ForceReply, ReplyKeyboardMarkup, KeyboardButton from telegram import Emoji, ForceReply, ReplyKeyboardMarkup, KeyboardButton
from telegram.ext import Updater, CommandHandler, MessageHandler, filters from telegram.ext import Updater, CommandHandler, MessageHandler, Filters
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - ' logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - '
'%(message)s', '%(message)s',
@ -93,7 +93,7 @@ updater = Updater("TOKEN")
# The command # The command
updater.dispatcher.addHandler(CommandHandler('set', set_value)) updater.dispatcher.addHandler(CommandHandler('set', set_value))
# The answer and confirmation # The answer and confirmation
updater.dispatcher.addHandler(MessageHandler([filters.TEXT], set_value)) updater.dispatcher.addHandler(MessageHandler([Filters.text], set_value))
updater.dispatcher.addHandler(CommandHandler('cancel', cancel)) updater.dispatcher.addHandler(CommandHandler('cancel', cancel))
updater.dispatcher.addHandler(CommandHandler('start', help)) updater.dispatcher.addHandler(CommandHandler('start', help))
updater.dispatcher.addHandler(CommandHandler('help', help)) updater.dispatcher.addHandler(CommandHandler('help', help))

View file

@ -27,7 +27,7 @@ from .choseninlineresulthandler import ChosenInlineResultHandler
from .commandhandler import CommandHandler from .commandhandler import CommandHandler
from .handler import Handler from .handler import Handler
from .inlinequeryhandler import InlineQueryHandler from .inlinequeryhandler import InlineQueryHandler
from .messagehandler import MessageHandler from .messagehandler import MessageHandler, Filters
from .regexhandler import RegexHandler from .regexhandler import RegexHandler
from .stringcommandhandler import StringCommandHandler from .stringcommandhandler import StringCommandHandler
from .stringregexhandler import StringRegexHandler from .stringregexhandler import StringRegexHandler
@ -35,5 +35,5 @@ from .typehandler import TypeHandler
__all__ = ('Dispatcher', 'JobQueue', 'Updater', 'CallbackQueryHandler', __all__ = ('Dispatcher', 'JobQueue', 'Updater', 'CallbackQueryHandler',
'ChosenInlineResultHandler', 'CommandHandler', 'Handler', 'ChosenInlineResultHandler', 'CommandHandler', 'Handler',
'InlineQueryHandler', 'MessageHandler', 'RegexHandler', 'InlineQueryHandler', 'MessageHandler', 'Filters', 'RegexHandler',
'StringCommandHandler', 'StringRegexHandler', 'TypeHandler') 'StringCommandHandler', 'StringRegexHandler', 'TypeHandler')

View file

@ -1,23 +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 filters used by the MessageHandler class """
TEXT, AUDIO, DOCUMENT, PHOTO, STICKER, VIDEO, VOICE, CONTACT, LOCATION, \
VENUE, STATUS_UPDATE = range(11)

View file

@ -22,7 +22,71 @@
from .handler import Handler from .handler import Handler
from telegram import Update from telegram import Update
from .filters import * # flake8: noqa
class Filters(object):
"""
Convenient namespace (class) & methods for the filter funcs of the
MessageHandler class.
"""
@staticmethod
def text(update):
return update.message.text and not update.message.text.startswith('/')
@staticmethod
def command(update):
return update.message.text and update.message.text.startswith('/')
@staticmethod
def audio(update):
return bool(update.message.audio)
@staticmethod
def document(update):
return bool(update.message.document)
@staticmethod
def photo(update):
return bool(update.message.photo)
@staticmethod
def sticker(update):
return bool(update.message.sticker)
@staticmethod
def video(update):
return bool(update.message.video)
@staticmethod
def voice(update):
return bool(update.message.voice)
@staticmethod
def contact(update):
return bool(update.message.contact)
@staticmethod
def location(update):
return bool(update.message.location)
@staticmethod
def venue(update):
return bool(update.message.venue)
@staticmethod
def status_update(update):
return bool(
update.message.new_chat_member or
update.message.left_chat_member or
update.message.new_chat_title or
update.message.new_chat_photo or
update.message.delete_chat_photo or
update.message.group_chat_created or
update.message.supergroup_chat_created or
update.message.channel_chat_created or
update.message.migrate_to_chat_id or
update.message.migrate_from_chat_id or
update.message.pinned_message)
class MessageHandler(Handler): class MessageHandler(Handler):
@ -32,8 +96,10 @@ class MessageHandler(Handler):
updates. updates.
Args: Args:
filters (list): A list of filters defined in ``telegram.ext.filters``. filters (list[function]): A list of filter functions. Standard filters
All messages that match at least one of those filters will be can be found in the Filters class above.
| Each `function` takes ``Update`` as arg and returns ``bool``.
| All messages that match at least one of those filters will be
accepted. If ``bool(filters)`` evaluates to ``False``, messages are accepted. If ``bool(filters)`` evaluates to ``False``, messages are
not filtered. not filtered.
callback (function): A function that takes ``bot, update`` as callback (function): A function that takes ``bot, update`` as
@ -49,36 +115,14 @@ class MessageHandler(Handler):
self.filters = filters self.filters = filters
def checkUpdate(self, update): def checkUpdate(self, update):
filters = self.filters
if isinstance(update, Update) and update.message: if isinstance(update, Update) and update.message:
message = update.message if not self.filters:
return (not filters or # If filters is empty, accept all messages res = True
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: else:
return False res = any(func(update) for func in self.filters)
else:
res = False
return res
def handleUpdate(self, update, dispatcher): def handleUpdate(self, update, dispatcher):
optional_args = self.collectOptionalArgs(dispatcher) optional_args = self.collectOptionalArgs(dispatcher)

View file

@ -144,8 +144,8 @@ class UpdaterTest(BaseTest, unittest.TestCase):
def test_addRemoveTelegramMessageHandler(self): def test_addRemoveTelegramMessageHandler(self):
self._setup_updater('Test') self._setup_updater('Test')
d = self.updater.dispatcher d = self.updater.dispatcher
from telegram.ext import filters from telegram.ext import Filters
handler = MessageHandler([filters.TEXT], self.telegramHandlerTest) handler = MessageHandler([Filters.text], self.telegramHandlerTest)
d.addHandler(handler) d.addHandler(handler)
self.updater.start_polling(0.01) self.updater.start_polling(0.01)
sleep(.1) sleep(.1)