Merge remote-tracking branch 'origin/master' into urllib3

This commit is contained in:
Noam Meltzer 2016-06-17 17:54:04 +03:00
commit cb6ddfded5
10 changed files with 38 additions and 232 deletions

View file

@ -1,3 +1,10 @@
**2016-06-10**
*Released 4.2.1*
- Fix ``CallbackQuery.to_dict()`` bug (thanks to @jlmadurga)
- Fix ``editMessageText`` exception when receiving a ``CallbackQuery``
**2016-05-28** **2016-05-28**
*Released 4.2* *Released 4.2*

View file

@ -129,13 +129,7 @@ code and building on top of it.
- `timerbot <https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/timerbot.py>`_ uses the ``JobQueue`` to send timed messages. - `timerbot <https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/timerbot.py>`_ uses the ``JobQueue`` to send timed messages.
- `clibot <https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/clibot.py>`_ has a command line interface. - `echobot <https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/legacy/echobot.py>`_ uses only the pure API to echo messages.
Examples using only the pure API:
- `echobot <https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/legacy/echobot.py>`_ replies back messages.
- `roboed <https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/legacy/roboed.py>`_ talks to `Robô Ed <http://www.ed.conpet.gov.br/br/converse.php>`_.
Look at the examples on the `wiki <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Examples>`_ to see other bots the community has built. Look at the examples on the `wiki <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Examples>`_ to see other bots the community has built.

View file

@ -1,164 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Example Bot to show some of the functionality of the library
# This program is dedicated to the public domain under the CC0 license.
"""
This Bot uses the Updater class to handle the bot.
First, a few handler functions are defined. Then, those functions are passed to
the Dispatcher and registered at their respective places.
Then, the bot is started and the CLI-Loop is entered, where all text inputs are
inserted into the update queue for the bot to handle.
Usage:
Repeats messages with a delay.
Reply to last chat from the command line by typing "/reply <text>"
Type 'stop' on the command line to stop the bot.
"""
from telegram.ext import Updater, StringCommandHandler, StringRegexHandler, \
MessageHandler, CommandHandler, RegexHandler, Filters
from telegram.ext.dispatcher import run_async
from time import sleep
import logging
from future.builtins import input
# Enable Logging
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.INFO)
logger = logging.getLogger(__name__)
# We use this var to save the last chat id, so we can reply to it
last_chat_id = 0
# Define a few (command) handler callback functions. These usually take the
# two arguments bot and update. Error handlers also receive the raised
# TelegramError object in error.
def start(bot, update):
""" Answer in Telegram """
bot.sendMessage(update.message.chat_id, text='Hi!')
def help(bot, update):
""" Answer in Telegram """
bot.sendMessage(update.message.chat_id, text='Help!')
def any_message(bot, update):
""" Print to console """
# Save last chat_id to use in reply handler
global last_chat_id
last_chat_id = update.message.chat_id
logger.info("New message\nFrom: %s\nchat_id: %d\nText: %s" %
(update.message.from_user, update.message.chat_id, update.message.text))
@run_async
def message(bot, update):
"""
Example for an asynchronous handler. It's not guaranteed that replies will
be in order when using @run_async. Also, you have to include **kwargs in
your parameter list. The kwargs contain all optional parameters that are
"""
sleep(2) # IO-heavy operation here
bot.sendMessage(update.message.chat_id, text='Echo: %s' % update.message.text)
# These handlers are for updates of type str. We use them to react to inputs
# on the command line interface
def cli_reply(bot, update, args):
"""
For any update of type telegram.Update or str that contains a command, you
can get the argument list by appending args to the function parameters.
Here, we reply to the last active chat with the text after the command.
"""
if last_chat_id is not 0:
bot.sendMessage(chat_id=last_chat_id, text=' '.join(args))
def cli_noncommand(bot, update, update_queue):
"""
You can also get the update queue as an argument in any handler by
appending it to the argument list. Be careful with this though.
Here, we put the input string back into the queue, but as a command.
To learn more about those optional handler parameters, read the
documentation of the Handler classes.
"""
update_queue.put('/%s' % update)
def error(bot, update, error):
""" Print error to console """
logger.warn('Update %s caused error %s' % (update, error))
def main():
# Create the EventHandler and pass it your bot's token.
token = 'TOKEN'
updater = Updater(token, workers=10)
# Get the dispatcher to register handlers
dp = updater.dispatcher
# This is how we add handlers for Telegram messages
dp.add_handler(CommandHandler("start", start))
dp.add_handler(CommandHandler("help", help))
# Message handlers only receive updates that don't contain commands
dp.add_handler(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
dp.add_handler(RegexHandler('.*', any_message), group=1)
# String handlers work pretty much the same. Note that we have to tell
# the handler to pass the args or update_queue parameter
dp.add_handler(StringCommandHandler('reply', cli_reply, pass_args=True))
dp.add_handler(StringRegexHandler('[^/].*', cli_noncommand, pass_update_queue=True))
# All TelegramErrors are caught for you and delivered to the error
# handler(s). Other types of Errors are not caught.
dp.add_error_handler(error)
# Start the Bot and store the update Queue, so we can insert updates
update_queue = updater.start_polling(timeout=10)
'''
# Alternatively, run with webhook:
update_queue = updater.start_webhook('0.0.0.0',
443,
url_path=token,
cert='cert.pem',
key='key.key',
webhook_url='https://example.com/%s'
% token)
# Or, if SSL is handled by a reverse proxy, the webhook URL is already set
# and the reverse proxy is configured to deliver directly to port 6000:
update_queue = updater.start_webhook('0.0.0.0', 6000)
'''
# Start CLI-Loop
while True:
text = input()
# Gracefully stop the event handler
if text == 'stop':
updater.stop()
break
# else, put the text into the update queue to be handled by our handlers
elif len(text) > 0:
update_queue.put(text)
if __name__ == '__main__':
main()

View file

@ -1,16 +1,19 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
# Simple Bot to reply to Telegram messages # Simple Bot to reply to Telegram messages. This is built on the API wrapper, see
# echobot2.py to see the same example built on the telegram.ext bot framework.
# This program is dedicated to the public domain under the CC0 license. # This program is dedicated to the public domain under the CC0 license.
import logging import logging
import telegram import telegram
from telegram.error import NetworkError, Unauthorized from telegram.error import NetworkError, Unauthorized
from time import sleep from time import sleep
update_id = None
def main(): def main():
global update_id
# Telegram Bot Authorization Token # Telegram Bot Authorization Token
bot = telegram.Bot('TOKEN') bot = telegram.Bot('TOKEN')
@ -25,7 +28,7 @@ def main():
while True: while True:
try: try:
update_id = echo(bot, update_id) echo(bot)
except NetworkError: except NetworkError:
sleep(1) sleep(1)
except Unauthorized: except Unauthorized:
@ -33,20 +36,17 @@ def main():
update_id += 1 update_id += 1
def echo(bot, update_id): def echo(bot):
global update_id
# Request updates after the last update_id # Request updates after the last update_id
for update in bot.getUpdates(offset=update_id, timeout=10): for update in bot.getUpdates(offset=update_id, timeout=10):
# chat_id is required to reply to any message # chat_id is required to reply to any message
chat_id = update.message.chat_id chat_id = update.message.chat_id
update_id = update.update_id + 1 update_id = update.update_id + 1
message = update.message.text
if message: if update.message: # your bot can receive updates without messages
# Reply to the message # Reply to the message
bot.sendMessage(chat_id=chat_id, text=message) bot.sendMessage(chat_id=chat_id, text=update.message.text)
return update_id
if __name__ == '__main__': if __name__ == '__main__':

View file

@ -1,38 +0,0 @@
#!/usr/bin/env python
# encoding: utf-8
#
# Robô Ed Telegram Bot
# This program is dedicated to the public domain under the CC0 license.
import logging
import telegram
import urllib
def main():
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
bot = telegram.Bot('TOKEN') # Telegram Bot Authorization Token
LAST_UPDATE_ID = bot.getUpdates()[-1].update_id # Get lastest update
while True:
for update in bot.getUpdates(offset=LAST_UPDATE_ID, timeout=10):
text = update.message.text
chat_id = update.message.chat.id
update_id = update.update_id
if text:
roboed = ed(text) # Ask something to Robô Ed
bot.sendMessage(chat_id=chat_id, text=roboed)
LAST_UPDATE_ID = update_id + 1
def ed(text):
url = 'http://www.ed.conpet.gov.br/mod_perl/bot_gateway.cgi?server=0.0.0.0%3A8085&charset_post=utf-8&charset=utf-8&pure=1&js=0&tst=1&msg=' + text
data = urllib.urlopen(url).read()
return data.strip()
if __name__ == '__main__':
main()

View file

@ -82,7 +82,7 @@ from .update import Update
from .bot import Bot from .bot import Bot
__author__ = 'devs@python-telegram-bot.org' __author__ = 'devs@python-telegram-bot.org'
__version__ = '4.2.0' __version__ = '4.2.1'
__all__ = ['Audio', 'Bot', 'Chat', 'ChatMember', 'ChatAction', 'ChosenInlineResult', __all__ = ['Audio', 'Bot', 'Chat', 'ChatMember', 'ChatAction', 'ChosenInlineResult',
'CallbackQuery', 'Contact', 'Document', 'Emoji', 'File', 'ForceReply', 'CallbackQuery', 'Contact', 'Document', 'Emoji', 'File', 'ForceReply',
'InlineKeyboardButton', 'InlineKeyboardMarkup', 'InlineQuery', 'InlineQueryResult', 'InlineKeyboardButton', 'InlineKeyboardMarkup', 'InlineQuery', 'InlineQueryResult',

View file

@ -1009,6 +1009,7 @@ class Bot(TelegramObject):
return result return result
@log @log
@message
def editMessageText(self, def editMessageText(self,
text, text,
chat_id=None, chat_id=None,
@ -1016,7 +1017,6 @@ class Bot(TelegramObject):
inline_message_id=None, inline_message_id=None,
parse_mode=None, parse_mode=None,
disable_web_page_preview=None, disable_web_page_preview=None,
reply_markup=None,
**kwargs): **kwargs):
"""Use this method to edit text messages sent by the bot or via the bot """Use this method to edit text messages sent by the bot or via the bot
(for inline bots). (for inline bots).
@ -1043,6 +1043,10 @@ class Bot(TelegramObject):
A JSON-serialized object for an inline keyboard. A JSON-serialized object for an inline keyboard.
Keyword Args: Keyword Args:
reply_markup (Optional[:class:`telegram.ReplyMarkup`]): Additional
interface options. A JSON-serialized object for an inline
keyboard, custom reply keyboard, instructions to hide reply
keyboard or to force a reply from the user.
timeout (Optional[float]): If this value is specified, use it as timeout (Optional[float]): If this value is specified, use it as
the definitive timeout (in seconds) for urlopen() operations. the definitive timeout (in seconds) for urlopen() operations.
@ -1070,15 +1074,8 @@ class Bot(TelegramObject):
data['parse_mode'] = parse_mode data['parse_mode'] = parse_mode
if disable_web_page_preview: if disable_web_page_preview:
data['disable_web_page_preview'] = disable_web_page_preview data['disable_web_page_preview'] = disable_web_page_preview
if reply_markup:
if isinstance(reply_markup, ReplyMarkup):
data['reply_markup'] = reply_markup.to_json()
else:
data['reply_markup'] = reply_markup
result = request.post(url, data, timeout=kwargs.get('timeout')) return url, data
return Message.de_json(result)
@log @log
@message @message

View file

@ -43,3 +43,14 @@ class CallbackQuery(TelegramObject):
data['message'] = Message.de_json(data.get('message')) data['message'] = Message.de_json(data.get('message'))
return CallbackQuery(**data) return CallbackQuery(**data)
def to_dict(self):
"""
Returns:
dict:
"""
data = super(CallbackQuery, self).to_dict()
# Required
data['from'] = data.pop('from_user', None)
return data

View file

@ -35,15 +35,14 @@ class PhotoTest(BaseTest, unittest.TestCase):
def setUp(self): def setUp(self):
self.photo_file = open('tests/data/telegram.jpg', 'rb') self.photo_file = open('tests/data/telegram.jpg', 'rb')
self.photo_file_id = 'AgADAQADvb8xGx8j9QcpZDKxYoFK3bfX1i8ABFX_dgMWoKDuQugAAgI' self.photo_file_id = 'AgADAQADgEsyGx8j9QfmDMmwkPBrFcKRzy8ABHW8ul9nW7FoNHYBAAEC'
self.photo_file_url = 'https://raw.githubusercontent.com/python-telegram-bot/python-telegram-bot/master/tests/data/telegram.jpg' self.photo_file_url = 'https://raw.githubusercontent.com/python-telegram-bot/python-telegram-bot/master/tests/data/telegram.jpg'
self.width = 300 self.width = 300
self.height = 300 self.height = 300
self.thumb = { self.thumb = {
'width': 90, 'width': 90,
'height': 90, 'height': 90,
'file_id': 'file_id': 'AgADAQADgEsyGx8j9QfmDMmwkPBrFcKRzy8ABD64nkFkjujeNXYBAAEC',
'AgADAQADvb8xGx8j9QcpZDKxYoFK3bfX1i8ABBxRLXFhLnhIQ-gAAgI',
'file_size': 1478 'file_size': 1478
} }
self.file_size = 10209 self.file_size = 10209