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):
... bot.sendMessage(chat_id=update.message.chat_id, text=update.message.text)
...
>>> from telegram.ext import MessageHandler
>>> from telegram.ext import filters
>>> echo_handler = MessageHandler([filters.TEXT], echo)
>>> from telegram.ext import MessageHandler, Filters
>>> echo_handler = MessageHandler([Filters.text], echo)
>>> 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.

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.inlinequeryhandler
telegram.ext.messagehandler
telegram.ext.filters
telegram.ext.regexhandler
telegram.ext.stringcommandhandler
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, \
MessageHandler, CommandHandler, RegexHandler, filters
MessageHandler, CommandHandler, RegexHandler, Filters
from telegram.ext.dispatcher import run_async
from time import sleep
import logging
@ -115,7 +115,7 @@ def main():
dp.addHandler(CommandHandler("start", start))
dp.addHandler(CommandHandler("help", help))
# 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,
# but we have to add it in a separate group, since in one group,
# 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.
"""
from telegram.ext import Updater, CommandHandler, MessageHandler, filters
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters
import logging
# Enable logging
@ -58,7 +58,7 @@ def main():
dp.addHandler(CommandHandler("help", help))
# 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
dp.addErrorHandler(error)

View file

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

View file

@ -6,7 +6,7 @@
import logging
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 - '
'%(message)s',
@ -93,7 +93,7 @@ updater = Updater("TOKEN")
# The command
updater.dispatcher.addHandler(CommandHandler('set', set_value))
# 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('start', help))
updater.dispatcher.addHandler(CommandHandler('help', help))

View file

@ -27,7 +27,7 @@ from .choseninlineresulthandler import ChosenInlineResultHandler
from .commandhandler import CommandHandler
from .handler import Handler
from .inlinequeryhandler import InlineQueryHandler
from .messagehandler import MessageHandler
from .messagehandler import MessageHandler, Filters
from .regexhandler import RegexHandler
from .stringcommandhandler import StringCommandHandler
from .stringregexhandler import StringRegexHandler
@ -35,5 +35,5 @@ from .typehandler import TypeHandler
__all__ = ('Dispatcher', 'JobQueue', 'Updater', 'CallbackQueryHandler',
'ChosenInlineResultHandler', 'CommandHandler', 'Handler',
'InlineQueryHandler', 'MessageHandler', 'RegexHandler',
'InlineQueryHandler', 'MessageHandler', 'Filters', 'RegexHandler',
'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 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):
@ -32,8 +96,10 @@ class MessageHandler(Handler):
updates.
Args:
filters (list): A list of filters defined in ``telegram.ext.filters``.
All messages that match at least one of those filters will be
filters (list[function]): A list of filter functions. Standard filters
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
not filtered.
callback (function): A function that takes ``bot, update`` as
@ -49,36 +115,14 @@ class MessageHandler(Handler):
self.filters = filters
def checkUpdate(self, update):
filters = self.filters
if isinstance(update, Update) and update.message:
message = update.message
return (not filters or # If filters is empty, accept all messages
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)
)
if not self.filters:
res = True
else:
res = any(func(update) for func in self.filters)
else:
return False
res = False
return res
def handleUpdate(self, update, dispatcher):
optional_args = self.collectOptionalArgs(dispatcher)

View file

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