Merge branch 'master' of github.com:python-telegram-bot/python-telegram-bot

This commit is contained in:
Leandro Toledo 2016-05-23 19:44:34 -03:00
commit 7c84516d2b
17 changed files with 120 additions and 100 deletions

View file

@ -1,8 +1,8 @@
- repo: git://github.com/pre-commit/mirrors-yapf
sha: d79d3113a991229b8f9d329e8e97b615abad91ba
sha: 316b795b2f32cbe80047aff7e842b72368d5a2c1
hooks:
- id: yapf
files: ^(telegram|tests)/.*\.py$
files: ^(examples|telegram|tests)/.*\.py$
- repo: git://github.com/pre-commit/pre-commit-hooks
sha: adbb569fe9a64ad9bce3b53a77f1bc39ef31f682
hooks:

View file

@ -131,6 +131,52 @@ Here's how to make a one-off code change.
7. **Celebrate.** Congratulations, you have contributed to ``python-telegram-bot``!
Style commandments
==================
Specific commandments
---------------------
- Avoid using "double quotes" where you can reasonably use 'single quotes'.
AssertEqual argument order
--------------------------
assertEqual method's arguments should be in ('actual', 'expected') order.
Properly calling callables
--------------------------
Methods, functions and classes can specify optional parameters (with default
values) using Python's keyword arg syntax. When providing a value to such a
callable we prefer that the call also uses keyword arg syntax. For example::
# GOOD
f(0, optional=True)
# BAD
f(0, True)
This gives us the flexibility to re-order arguments and more importantly
to add new required arguments. It's also more explicit and easier to read.
Properly defining optional arguments
------------------------------------
It's always good to not initialize optional arguments at class creation,
instead use ``**kwargs`` to get them. It's well known Telegram API can
change without notice, in that case if a new argument is added it won't
break the API classes. For example::
# GOOD
def __init__(self, id, name, **kwargs):
self.last_name = kwargs.get('last_name', '')
# BAD
def __init__(self, id, name, last_name=''):
self.last_name = last_name
.. _`Code of Conduct`: https://www.python.org/psf/codeofconduct/
.. _`issue tracker`: https://github.com/python-telegram-bot/python-telegram-bot/issues
.. _`developers' mailing list`: mailto:devs@python-telegram-bot.org

View file

@ -3,7 +3,6 @@
#
# 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.
@ -27,9 +26,8 @@ import logging
from future.builtins import input
# Enable Logging
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.INFO)
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.INFO)
logger = logging.getLogger(__name__)
@ -58,9 +56,7 @@ def any_message(bot, update):
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))
(update.message.from_user, update.message.chat_id, update.message.text))
@run_async
@ -72,8 +68,7 @@ def message(bot, update):
"""
sleep(2) # IO-heavy operation here
bot.sendMessage(update.message.chat_id, text='Echo: %s' %
update.message.text)
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
@ -126,8 +121,7 @@ def main():
# 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))
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.
@ -135,7 +129,6 @@ def main():
# Start the Bot and store the update Queue, so we can insert updates
update_queue = updater.start_polling(timeout=10)
'''
# Alternatively, run with webhook:
@ -166,5 +159,6 @@ def main():
elif len(text) > 0:
update_queue.put(text)
if __name__ == '__main__':
main()

View file

@ -3,7 +3,6 @@
#
# Simple Bot to reply to Telegram messages
# This program is dedicated to the public domain under the CC0 license.
"""
This Bot uses the Updater class to handle the bot.
@ -21,9 +20,8 @@ from telegram.ext import Updater, CommandHandler, MessageHandler, Filters
import logging
# Enable logging
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.INFO)
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.INFO)
logger = logging.getLogger(__name__)
@ -71,5 +69,6 @@ def main():
# start_polling() is non-blocking and will stop the bot gracefully.
updater.idle()
if __name__ == '__main__':
main()

View file

@ -3,7 +3,6 @@
#
# Simple Bot to reply to Telegram messages
# This program is dedicated to the public domain under the CC0 license.
"""
This Bot uses the Updater class to handle the bot.
@ -26,9 +25,8 @@ from telegram.ext import Updater, InlineQueryHandler, CommandHandler
import logging
# Enable logging
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.INFO)
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.INFO)
logger = logging.getLogger(__name__)
@ -53,24 +51,22 @@ def inlinequery(bot, update):
query = update.inline_query.query
results = list()
results.append(InlineQueryResultArticle(
id=uuid4(),
title="Caps",
input_message_content=InputTextMessageContent(query.upper())))
results.append(InlineQueryResultArticle(id=uuid4(),
title="Caps",
input_message_content=InputTextMessageContent(
query.upper())))
results.append(InlineQueryResultArticle(
id=uuid4(),
title="Bold",
input_message_content=InputTextMessageContent(
"*%s*" % escape_markdown(query),
parse_mode=ParseMode.MARKDOWN)))
results.append(InlineQueryResultArticle(id=uuid4(),
title="Bold",
input_message_content=InputTextMessageContent(
"*%s*" % escape_markdown(query),
parse_mode=ParseMode.MARKDOWN)))
results.append(InlineQueryResultArticle(
id=uuid4(),
title="Italic",
input_message_content=InputTextMessageContent(
"_%s_" % escape_markdown(query),
parse_mode=ParseMode.MARKDOWN)))
results.append(InlineQueryResultArticle(id=uuid4(),
title="Italic",
input_message_content=InputTextMessageContent(
"_%s_" % escape_markdown(query),
parse_mode=ParseMode.MARKDOWN)))
bot.answerInlineQuery(update.inline_query.id, results=results)
@ -104,5 +100,6 @@ def main():
# start_polling() is non-blocking and will stop the bot gracefully.
updater.idle()
if __name__ == '__main__':
main()

View file

@ -11,8 +11,7 @@ from telegram import Emoji, ForceReply, InlineKeyboardButton, \
from telegram.ext import Updater, CommandHandler, MessageHandler, \
CallbackQueryHandler, Filters
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - '
'%(message)s',
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.DEBUG)
# Define the different states a chat can be in
@ -20,8 +19,7 @@ MENU, AWAIT_CONFIRMATION, AWAIT_INPUT = range(3)
# Python 2 and 3 unicode differences
try:
YES, NO = (Emoji.THUMBS_UP_SIGN.decode('utf-8'),
Emoji.THUMBS_DOWN_SIGN.decode('utf-8'))
YES, NO = (Emoji.THUMBS_UP_SIGN.decode('utf-8'), Emoji.THUMBS_DOWN_SIGN.decode('utf-8'))
except AttributeError:
YES, NO = (Emoji.THUMBS_UP_SIGN, Emoji.THUMBS_DOWN_SIGN)
@ -58,11 +56,9 @@ def entered_value(bot, update):
# Save the user id and the answer to context
context[user_id] = update.message.text
reply_markup = InlineKeyboardMarkup(
[[InlineKeyboardButton(YES, callback_data=YES),
InlineKeyboardButton(NO, callback_data=NO)]])
bot.sendMessage(chat_id, text="Are you sure?",
reply_markup=reply_markup)
reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton(YES, callback_data=YES),
InlineKeyboardButton(NO, callback_data=NO)]])
bot.sendMessage(chat_id, text="Are you sure?", reply_markup=reply_markup)
def confirm_value(bot, update):
@ -82,14 +78,12 @@ def confirm_value(bot, update):
values[user_id] = user_context
bot.editMessageText(text="Changed value to %s." % values[user_id],
chat_id=chat_id,
message_id=
query.message.message_id)
message_id=query.message.message_id)
else:
bot.editMessageText(text="Alright, value is still %s."
% values.get(user_id, 'not set'),
bot.editMessageText(text="Alright, value is still %s." %
values.get(user_id, 'not set'),
chat_id=chat_id,
message_id=
query.message.message_id)
message_id=query.message.message_id)
def help(bot, update):

View file

@ -21,8 +21,7 @@ def main():
except IndexError:
update_id = None
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
while True:
try:
@ -45,8 +44,7 @@ def echo(bot, update_id):
if message:
# Reply to the message
bot.sendMessage(chat_id=chat_id,
text=message)
bot.sendMessage(chat_id=chat_id, text=message)
return update_id

View file

@ -10,8 +10,7 @@ import urllib
def main():
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
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
@ -34,5 +33,6 @@ def ed(text):
return data.strip()
if __name__ == '__main__':
main()

View file

@ -8,8 +8,7 @@ import logging
from telegram import Emoji, ForceReply, ReplyKeyboardMarkup, KeyboardButton
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - '
'%(message)s',
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.INFO)
# Define the different states a chat can be in
@ -17,8 +16,7 @@ MENU, AWAIT_CONFIRMATION, AWAIT_INPUT = range(3)
# Python 2 and 3 unicode differences
try:
YES, NO = (Emoji.THUMBS_UP_SIGN.decode('utf-8'),
Emoji.THUMBS_DOWN_SIGN.decode('utf-8'))
YES, NO = (Emoji.THUMBS_UP_SIGN.decode('utf-8'), Emoji.THUMBS_DOWN_SIGN.decode('utf-8'))
except AttributeError:
YES, NO = (Emoji.THUMBS_UP_SIGN, Emoji.THUMBS_DOWN_SIGN)
@ -46,7 +44,7 @@ def set_value(bot, update):
context[chat_id] = user_id # save the user id to context
bot.sendMessage(chat_id,
text="Please enter your settings value or send "
"/cancel to abort",
"/cancel to abort",
reply_markup=ForceReply())
# If we are waiting for input and the right user answered
@ -58,8 +56,7 @@ def set_value(bot, update):
reply_markup = ReplyKeyboardMarkup(
[[KeyboardButton(YES), KeyboardButton(NO)]],
one_time_keyboard=True)
bot.sendMessage(chat_id, text="Are you sure?",
reply_markup=reply_markup)
bot.sendMessage(chat_id, text="Are you sure?", reply_markup=reply_markup)
# If we are waiting for confirmation and the right user answered
elif chat_state == AWAIT_CONFIRMATION and chat_context[0] == user_id:
@ -67,12 +64,10 @@ def set_value(bot, update):
del context[chat_id]
if text == YES:
values[chat_id] = chat_context[1]
bot.sendMessage(chat_id,
text="Changed value to %s." % values[chat_id])
bot.sendMessage(chat_id, text="Changed value to %s." % values[chat_id])
else:
bot.sendMessage(chat_id,
text="Value not changed: %s."
% values.get(chat_id, '<not set>'))
text="Value not changed: %s." % values.get(chat_id, '<not set>'))
# Handler for the /cancel command.
@ -86,7 +81,6 @@ def cancel(bot, update):
def help(bot, update):
bot.sendMessage(update.message.chat_id, text="Use /set to test this bot.")
# Create the Updater and pass it your bot's token.
updater = Updater("TOKEN")

View file

@ -3,7 +3,6 @@
#
# Simple Bot to send timed Telegram messages
# This program is dedicated to the public domain under the CC0 license.
"""
This Bot uses the Updater class to handle the bot and the JobQueue to send
timed messages.
@ -22,9 +21,8 @@ from telegram.ext import Updater, CommandHandler
import logging
# Enable logging
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.INFO)
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.INFO)
logger = logging.getLogger(__name__)
job_queue = None
@ -33,8 +31,7 @@ job_queue = None
# Define a few command handlers. These usually take the two arguments bot and
# update. Error handlers also receive the raised TelegramError object in error.
def start(bot, update):
bot.sendMessage(update.message.chat_id, text='Hi! Use /set <seconds> to '
'set a timer')
bot.sendMessage(update.message.chat_id, text='Hi! Use /set <seconds> to ' 'set a timer')
def set(bot, update, args):
@ -44,7 +41,8 @@ def set(bot, update, args):
# args[0] should contain the time for the timer in seconds
due = int(args[0])
if due < 0:
bot.sendMessage(chat_id, text='Sorry we can not go back to future!')
bot.sendMessage(chat_id, text='Sorry we can not go back to future!')
def alarm(bot):
""" Inner function to send the alarm message """
bot.sendMessage(chat_id, text='Beep!')
@ -88,5 +86,6 @@ def main():
# start_polling() is non-blocking and will stop the bot gracefully.
updater.idle()
if __name__ == '__main__':
main()

View file

@ -11,7 +11,9 @@ upload-dir = docs/build/html
[flake8]
max-line-length = 99
ignore = W503
[yapf]
based_on_style = google
split_before_logical_operator = True
column_limit = 99

View file

@ -49,9 +49,9 @@ class CommandHandler(Handler):
self.pass_args = pass_args
def check_update(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)
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 handle_update(self, update, dispatcher):
optional_args = self.collect_optional_args(dispatcher)

View file

@ -75,15 +75,12 @@ class Filters(object):
@staticmethod
def status_update(update):
# yapf: disable
# https://github.com/google/yapf/issues/252
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)
# yapf: enable
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):

View file

@ -47,8 +47,8 @@ class StringCommandHandler(Handler):
self.pass_args = pass_args
def check_update(self, update):
return (isinstance(update, str) and update.startswith('/') and
update[1:].split(' ')[0] == self.command)
return (isinstance(update, str) and update.startswith('/')
and update[1:].split(' ')[0] == self.command)
def handle_update(self, update, dispatcher):
optional_args = self.collect_optional_args(dispatcher)

View file

@ -318,8 +318,8 @@ class Updater(object):
except (Unauthorized, InvalidToken):
raise
except TelegramError:
msg = 'error in bootstrap phase; try={0} max_retries={1}'\
.format(retries, max_retries)
msg = 'error in bootstrap phase; try={0} max_retries={1}'.format(retries,
max_retries)
if max_retries < 0 or retries < max_retries:
self.logger.warning(msg)
retries += 1

View file

@ -51,8 +51,8 @@ class PhotoSize(TelegramObject):
def __eq__(self, other):
if not isinstance(other, self.__class__):
return False
return (self.file_id == other.file_id and self.width == other.width and
self.height == other.height and self.file_size == other.file_size)
return (self.file_id == other.file_id and self.width == other.width
and self.height == other.height and self.file_size == other.file_size)
@staticmethod
def de_json(data):

View file

@ -60,8 +60,8 @@ class InlineKeyboardMarkupTest(BaseTest, unittest.TestCase):
inline_keyboard_markup = telegram.InlineKeyboardMarkup.de_json(self.json_dict)
self.assertTrue(isinstance(inline_keyboard_markup.inline_keyboard, list))
self.assertTrue(isinstance(inline_keyboard_markup.inline_keyboard[0][
0], telegram.InlineKeyboardButton))
self.assertTrue(isinstance(inline_keyboard_markup.inline_keyboard[0][0],
telegram.InlineKeyboardButton))
def test_inline_keyboard_markup_to_json(self):
inline_keyboard_markup = telegram.InlineKeyboardMarkup.de_json(self.json_dict)
@ -72,8 +72,8 @@ class InlineKeyboardMarkupTest(BaseTest, unittest.TestCase):
inline_keyboard_markup = telegram.InlineKeyboardMarkup.de_json(self.json_dict)
self.assertTrue(isinstance(inline_keyboard_markup.inline_keyboard, list))
self.assertTrue(isinstance(inline_keyboard_markup.inline_keyboard[0][
0], telegram.InlineKeyboardButton))
self.assertTrue(isinstance(inline_keyboard_markup.inline_keyboard[0][0],
telegram.InlineKeyboardButton))
if __name__ == '__main__':