mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2026-06-19 23:55:29 +00:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 15268acb27 | |||
| 927502e588 | |||
| 0af5cc2db8 | |||
| 6005861f46 | |||
| 8406889179 | |||
| a4e78f6183 | |||
| 8c6cb44a85 | |||
| ac7cc7fe5e | |||
| a42b68933c | |||
| c2d91c752f | |||
| 5057825586 | |||
| 613175b2c4 | |||
| 1330696259 | |||
| 5898e1fe7a | |||
| b6dec118c1 |
@@ -41,9 +41,9 @@ If you already know what you'd like to work on, you can skip this section.
|
||||
|
||||
If you have an idea for something to do, first check if it's already been filed on the `issue tracker`_. If so, add a comment to the issue saying you'd like to work on it, and we'll help you get started! Otherwise, please file a new issue and assign yourself to it.
|
||||
|
||||
Another great way to start contributing is by writing tests. Tests are really important because they help prevent developers from accidentally breaking existing code, allowing them to build cool things faster. If you're interested in helping out, let the development team know by posting to the `developers' mailing list`_, and we'll help you get started.
|
||||
Another great way to start contributing is by writing tests. Tests are really important because they help prevent developers from accidentally breaking existing code, allowing them to build cool things faster. If you're interested in helping out, let the development team know by posting to the `Telegram group`_ (use `@admins` to mention the maintainers), and we'll help you get started.
|
||||
|
||||
That being said, we want to mention that we are very hesistant about adding new requirements to our projects. If you intend to do this, please state this in an issue and get a verification from one of the maintainers.
|
||||
That being said, we want to mention that we are very hesitant about adding new requirements to our projects. If you intend to do this, please state this in an issue and get a verification from one of the maintainers.
|
||||
|
||||
Instructions for making a code change
|
||||
#####################################
|
||||
@@ -245,7 +245,7 @@ break the API classes. For example:
|
||||
|
||||
.. _`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
|
||||
.. _`Telegram group`: https://telegram.me/pythontelegrambotgroup
|
||||
.. _`PEP 8 Style Guide`: https://www.python.org/dev/peps/pep-0008/
|
||||
.. _`sphinx`: http://sphinx-doc.org
|
||||
.. _`Google Python Style Guide`: http://google.github.io/styleguide/pyguide.html
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 5
|
||||
daysUntilStale: 3
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 2
|
||||
# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled)
|
||||
|
||||
+35
@@ -2,6 +2,41 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
Version 12.8
|
||||
============
|
||||
*Released 2020-06-22*
|
||||
|
||||
**Major Changes:**
|
||||
|
||||
- Remove Python 2 support (`#1715`_)
|
||||
- Bot API 4.9 support (`#1980`_)
|
||||
- IDs/Usernames of ``Filters.user`` and ``Filters.chat`` can now be updated (`#1757`_)
|
||||
|
||||
**Minor changes, CI improvements, doc fixes or bug fixes:**
|
||||
|
||||
- Update contribution guide and stale bot (`#1937`_)
|
||||
- Remove ``NullHandlers`` (`#1913`_)
|
||||
- Improve and expand examples (`#1943`_, `#1995`_, `#1983`_, `#1997`_)
|
||||
- Doc fixes (`#1940`_, `#1962`_)
|
||||
- Add ``User.send_poll()`` shortcut (`#1968`_)
|
||||
- Ignore private attributes en ``TelegramObject.to_dict()`` (`#1989`_)
|
||||
- Stabilize CI (`#2000`_)
|
||||
|
||||
.. _`#1937`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1937
|
||||
.. _`#1913`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1913
|
||||
.. _`#1943`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1943
|
||||
.. _`#1757`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1757
|
||||
.. _`#1940`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1940
|
||||
.. _`#1962`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1962
|
||||
.. _`#1968`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1968
|
||||
.. _`#1989`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1989
|
||||
.. _`#1995`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1995
|
||||
.. _`#1983`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1983
|
||||
.. _`#1715`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1715
|
||||
.. _`#2000`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2000
|
||||
.. _`#1997`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1997
|
||||
.. _`#1980`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1980
|
||||
|
||||
Version 12.7
|
||||
============
|
||||
*Released 2020-05-02*
|
||||
|
||||
@@ -15,7 +15,7 @@ Depends: ${python3:Depends}, ${misc:Depends}
|
||||
Description: We have made you a wrapper you can't refuse!
|
||||
The Python Telegram bot (Python 3)
|
||||
This library provides a pure Python interface for the Telegram Bot API.
|
||||
It's compatible with Python versions 2.7, 3.3+ and PyPy.
|
||||
It's compatible with Python versions 3.5+ and PyPy.
|
||||
.
|
||||
In addition to the pure API implementation, this library features
|
||||
a number of high-level
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
export PYBUILD_NAME=telegram
|
||||
|
||||
%:
|
||||
DEB_BUILD_OPTIONS=nocheck dh $@ --with python2,python3 --buildsystem=pybuild
|
||||
DEB_BUILD_OPTIONS=nocheck dh $@ --with python3 --buildsystem=pybuild
|
||||
|
||||
|
||||
# If you need to rebuild the Sphinx documentation
|
||||
|
||||
+2
-2
@@ -58,9 +58,9 @@ author = u'Leandro Toledo'
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '12.7' # telegram.__version__[:3]
|
||||
version = '12.8' # telegram.__version__[:3]
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '12.7' # telegram.__version__
|
||||
release = '12.8' # telegram.__version__
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
||||
+14
-2
@@ -19,20 +19,32 @@ A more complex example of a bot that uses the `ConversationHandler`. It is also
|
||||
### [`nestedconversationbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/nestedconversationbot.py)
|
||||
A even more complex example of a bot that uses the nested `ConversationHandler`s. While it's certainly not that complex that you couldn't built it without nested `ConversationHanldler`s, it gives a good impression on how to work with them. Of course, there is a [fancy state diagram](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/nestedconversationbot.png) for this example, too!
|
||||
|
||||
### [`persistentconversationbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/persistentconversationbot.py)
|
||||
A basic example of a bot store conversation state and user_data over multiple restarts.
|
||||
|
||||
### [`inlinekeyboard.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/inlinekeyboard.py)
|
||||
This example sheds some light on inline keyboards, callback queries and message editing.
|
||||
|
||||
### [`inlinekeyboard2.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/inlinekeyboard2.py)
|
||||
A more complex example about inline keyboards, callback queries and message editing. This example showcases how an interactive menu could be build using inline keyboards.
|
||||
|
||||
### [`deeplinking.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/deeplinking.py)
|
||||
A basic example on how to use deeplinking with inline keyboards.
|
||||
|
||||
### [`inlinebot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/inlinebot.py)
|
||||
A basic example of an [inline bot](https://core.telegram.org/bots/inline). Don't forget to enable inline mode with [@BotFather](https://telegram.me/BotFather).
|
||||
|
||||
### [`pollbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/pollbot.py)
|
||||
This example sheds some light on polls, poll answers and the corresponding handlers.
|
||||
|
||||
### [`passportbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/passportbot.py)
|
||||
A basic example of a bot that can accept passports. Use in combination with [`passportbot.html`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/passportbot.html). Don't forget to enable and configure payments with [@BotFather](https://telegram.me/BotFather). Check out this [guide](https://git.io/fAvYd) on Telegram passports in PTB.
|
||||
|
||||
### [`paymentbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/paymentbot.py)
|
||||
A basic example of a bot that can accept payments. Don't forget to enable and configure payments with [@BotFather](https://telegram.me/BotFather).
|
||||
|
||||
### [`persistentconversationbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/persistentconversationbot.py)
|
||||
A basic example of a bot store conversation state and user_data over multiple restarts.
|
||||
### [`errorhandlerbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/errorhandlerbot.py)
|
||||
A basic example on how to set up a costum error handler.
|
||||
|
||||
## Pure API
|
||||
The [`echobot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/echobot.py) example uses only the pure, "bare-metal" API wrapper.
|
||||
|
||||
@@ -108,11 +108,6 @@ def cancel(update, context):
|
||||
return ConversationHandler.END
|
||||
|
||||
|
||||
def error(update, context):
|
||||
"""Log Errors caused by Updates."""
|
||||
logger.warning('Update "%s" caused error "%s"', update, context.error)
|
||||
|
||||
|
||||
def main():
|
||||
# Create the Updater and pass it your bot's token.
|
||||
# Make sure to set use_context=True to use the new context based callbacks
|
||||
@@ -143,9 +138,6 @@ def main():
|
||||
|
||||
dp.add_handler(conv_handler)
|
||||
|
||||
# log all errors
|
||||
dp.add_error_handler(error)
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
|
||||
@@ -96,11 +96,6 @@ def done(update, context):
|
||||
return ConversationHandler.END
|
||||
|
||||
|
||||
def error(update, context):
|
||||
"""Log Errors caused by Updates."""
|
||||
logger.warning('Update "%s" caused error "%s"', update, context.error)
|
||||
|
||||
|
||||
def main():
|
||||
# Create the Updater and pass it your bot's token.
|
||||
# Make sure to set use_context=True to use the new context based callbacks
|
||||
@@ -135,9 +130,6 @@ def main():
|
||||
|
||||
dp.add_handler(conv_handler)
|
||||
|
||||
# log all errors
|
||||
dp.add_error_handler(error)
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
|
||||
+2
-10
@@ -61,7 +61,7 @@ def deep_linked_level_2(update, context):
|
||||
bot = context.bot
|
||||
url = helpers.create_deep_linked_url(bot.get_me().username, USING_ENTITIES)
|
||||
text = "You can also mask the deep-linked URLs as links: " \
|
||||
"[▶️ CLICK HERE]({0}).".format(url)
|
||||
"[▶️ CLICK HERE]({}).".format(url)
|
||||
update.message.reply_text(text, parse_mode=ParseMode.MARKDOWN, disable_web_page_preview=True)
|
||||
|
||||
|
||||
@@ -69,12 +69,7 @@ def deep_linked_level_3(update, context):
|
||||
"""Reached through the USING_ENTITIES payload"""
|
||||
payload = context.args
|
||||
update.message.reply_text("Congratulations! This is as deep as it gets 👏🏻\n\n"
|
||||
"The payload was: {0}".format(payload))
|
||||
|
||||
|
||||
def error(update, context):
|
||||
"""Log Errors caused by Updates."""
|
||||
logger.warning('Update "%s" caused error "%s"', update, context.error)
|
||||
"The payload was: {}".format(payload))
|
||||
|
||||
|
||||
def main():
|
||||
@@ -103,9 +98,6 @@ def main():
|
||||
# Make sure the deep-linking handlers occur *before* the normal /start handler.
|
||||
dp.add_handler(CommandHandler("start", start))
|
||||
|
||||
# log all errors
|
||||
dp.add_error_handler(error)
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
|
||||
+2
-10
@@ -33,7 +33,7 @@ def start(update, context):
|
||||
update.message.reply_text('Hi!')
|
||||
|
||||
|
||||
def help(update, context):
|
||||
def help_command(update, context):
|
||||
"""Send a message when the command /help is issued."""
|
||||
update.message.reply_text('Help!')
|
||||
|
||||
@@ -43,11 +43,6 @@ def echo(update, context):
|
||||
update.message.reply_text(update.message.text)
|
||||
|
||||
|
||||
def error(update, context):
|
||||
"""Log Errors caused by Updates."""
|
||||
logger.warning('Update "%s" caused error "%s"', update, context.error)
|
||||
|
||||
|
||||
def main():
|
||||
"""Start the bot."""
|
||||
# Create the Updater and pass it your bot's token.
|
||||
@@ -60,14 +55,11 @@ def main():
|
||||
|
||||
# on different commands - answer in Telegram
|
||||
dp.add_handler(CommandHandler("start", start))
|
||||
dp.add_handler(CommandHandler("help", help))
|
||||
dp.add_handler(CommandHandler("help", help_command))
|
||||
|
||||
# on noncommand i.e message - echo the message on Telegram
|
||||
dp.add_handler(MessageHandler(Filters.text, echo))
|
||||
|
||||
# log all errors
|
||||
dp.add_error_handler(error)
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
This is a very simple example on how one could implement a custom error handler
|
||||
"""
|
||||
import html
|
||||
import json
|
||||
import logging
|
||||
import traceback
|
||||
|
||||
from telegram import Update, ParseMode
|
||||
from telegram.ext import Updater, CallbackContext, CommandHandler
|
||||
|
||||
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
level=logging.INFO)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# The token you got from @botfather when you created the bot
|
||||
BOT_TOKEN = "TOKEN"
|
||||
|
||||
# This can be your own ID, or one for a developer group/channel.
|
||||
# You can use the /start command of this bot to see your chat id.
|
||||
DEVELOPER_CHAT_ID = 123456789
|
||||
|
||||
|
||||
def error_handler(update: Update, context: CallbackContext):
|
||||
"""Log the error and send a telegram message to notify the developer."""
|
||||
# Log the error before we do anything else, so we can see it even if something breaks.
|
||||
logger.error(msg="Exception while handling an update:", exc_info=context.error)
|
||||
|
||||
# traceback.format_exception returns the usual python message about an exception, but as a
|
||||
# list of strings rather than a single string, so we have to join them together.
|
||||
tb_list = traceback.format_exception(None, context.error, context.error.__traceback__)
|
||||
tb = ''.join(tb_list)
|
||||
|
||||
# Build the message with some markup and additional information about what happened.
|
||||
# You might need to add some logic to deal with messages longer than the 4096 character limit.
|
||||
message = (
|
||||
'An exception was raised while handling an update\n'
|
||||
'<pre>update = {}</pre>\n\n'
|
||||
'<pre>context.chat_data = {}</pre>\n\n'
|
||||
'<pre>context.user_data = {}</pre>\n\n'
|
||||
'<pre>{}</pre>'
|
||||
).format(
|
||||
html.escape(json.dumps(update.to_dict(), indent=2, ensure_ascii=False)),
|
||||
html.escape(str(context.chat_data)),
|
||||
html.escape(str(context.user_data)),
|
||||
html.escape(tb)
|
||||
)
|
||||
|
||||
# Finally, send the message
|
||||
context.bot.send_message(chat_id=DEVELOPER_CHAT_ID, text=message, parse_mode=ParseMode.HTML)
|
||||
|
||||
|
||||
def bad_command(update: Update, context: CallbackContext):
|
||||
"""Raise an error to trigger the error handler."""
|
||||
context.bot.wrong_method_name()
|
||||
|
||||
|
||||
def start(update: Update, context: CallbackContext):
|
||||
update.effective_message.reply_html('Use /bad_command to cause an error.\n'
|
||||
'Your chat id is <code>{}</code>.'
|
||||
.format(update.effective_chat.id))
|
||||
|
||||
|
||||
def main():
|
||||
# Create the Updater and pass it your bot's token.
|
||||
# Make sure to set use_context=True to use the new context based callbacks
|
||||
# Post version 12 this will no longer be necessary
|
||||
updater = Updater(BOT_TOKEN, use_context=True)
|
||||
|
||||
# Get the dispatcher to register handlers
|
||||
dp = updater.dispatcher
|
||||
|
||||
# Register the commands...
|
||||
dp.add_handler(CommandHandler('start', start))
|
||||
dp.add_handler(CommandHandler('bad_command', bad_command))
|
||||
|
||||
# ...and the error handler
|
||||
dp.add_error_handler(error_handler)
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
# Run the bot until you press Ctrl-C or the process receives SIGINT,
|
||||
# SIGTERM or SIGABRT. This should be used most of the time, since
|
||||
# start_polling() is non-blocking and will stop the bot gracefully.
|
||||
updater.idle()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
+2
-10
@@ -34,7 +34,7 @@ def start(update, context):
|
||||
update.message.reply_text('Hi!')
|
||||
|
||||
|
||||
def help(update, context):
|
||||
def help_command(update, context):
|
||||
"""Send a message when the command /help is issued."""
|
||||
update.message.reply_text('Help!')
|
||||
|
||||
@@ -64,11 +64,6 @@ def inlinequery(update, context):
|
||||
update.inline_query.answer(results)
|
||||
|
||||
|
||||
def error(update, context):
|
||||
"""Log Errors caused by Updates."""
|
||||
logger.warning('Update "%s" caused error "%s"', update, context.error)
|
||||
|
||||
|
||||
def main():
|
||||
# Create the Updater and pass it your bot's token.
|
||||
# Make sure to set use_context=True to use the new context based callbacks
|
||||
@@ -80,14 +75,11 @@ def main():
|
||||
|
||||
# on different commands - answer in Telegram
|
||||
dp.add_handler(CommandHandler("start", start))
|
||||
dp.add_handler(CommandHandler("help", help))
|
||||
dp.add_handler(CommandHandler("help", help_command))
|
||||
|
||||
# on noncommand i.e message - echo the message on Telegram
|
||||
dp.add_handler(InlineQueryHandler(inlinequery))
|
||||
|
||||
# log all errors
|
||||
dp.add_error_handler(error)
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
|
||||
@@ -36,15 +36,10 @@ def button(update, context):
|
||||
query.edit_message_text(text="Selected option: {}".format(query.data))
|
||||
|
||||
|
||||
def help(update, context):
|
||||
def help_command(update, context):
|
||||
update.message.reply_text("Use /start to test this bot.")
|
||||
|
||||
|
||||
def error(update, context):
|
||||
"""Log Errors caused by Updates."""
|
||||
logger.warning('Update "%s" caused error "%s"', update, context.error)
|
||||
|
||||
|
||||
def main():
|
||||
# Create the Updater and pass it your bot's token.
|
||||
# Make sure to set use_context=True to use the new context based callbacks
|
||||
@@ -53,8 +48,7 @@ def main():
|
||||
|
||||
updater.dispatcher.add_handler(CommandHandler('start', start))
|
||||
updater.dispatcher.add_handler(CallbackQueryHandler(button))
|
||||
updater.dispatcher.add_handler(CommandHandler('help', help))
|
||||
updater.dispatcher.add_error_handler(error)
|
||||
updater.dispatcher.add_handler(CommandHandler('help', help_command))
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
@@ -149,11 +149,6 @@ def end(update, context):
|
||||
return ConversationHandler.END
|
||||
|
||||
|
||||
def error(update, context):
|
||||
"""Log Errors caused by Updates."""
|
||||
logger.warning('Update "%s" caused error "%s"', update, context.error)
|
||||
|
||||
|
||||
def main():
|
||||
# Create the Updater and pass it your bot's token.
|
||||
updater = Updater("TOKEN", use_context=True)
|
||||
@@ -184,9 +179,6 @@ def main():
|
||||
# updates
|
||||
dp.add_handler(conv_handler)
|
||||
|
||||
# log all errors
|
||||
dp.add_error_handler(error)
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
|
||||
@@ -100,14 +100,14 @@ def show_data(update, context):
|
||||
text = ''
|
||||
if level == SELF:
|
||||
for person in user_data[level]:
|
||||
text += '\nName: {0}, Age: {1}'.format(person.get(NAME, '-'), person.get(AGE, '-'))
|
||||
text += '\nName: {}, Age: {}'.format(person.get(NAME, '-'), person.get(AGE, '-'))
|
||||
else:
|
||||
male, female = _name_switcher(level)
|
||||
|
||||
for person in user_data[level]:
|
||||
gender = female if person[GENDER] == FEMALE else male
|
||||
text += '\n{0}: Name: {1}, Age: {2}'.format(gender, person.get(NAME, '-'),
|
||||
person.get(AGE, '-'))
|
||||
text += '\n{}: Name: {}, Age: {}'.format(gender, person.get(NAME, '-'),
|
||||
person.get(AGE, '-'))
|
||||
return text
|
||||
|
||||
ud = context.user_data
|
||||
@@ -267,12 +267,6 @@ def stop_nested(update, context):
|
||||
return STOPPING
|
||||
|
||||
|
||||
# Error handler
|
||||
def error(update, context):
|
||||
"""Log Errors caused by Updates."""
|
||||
logger.warning('Update "%s" caused error "%s"', update, context.error)
|
||||
|
||||
|
||||
def main():
|
||||
# Create the Updater and pass it your bot's token.
|
||||
# Make sure to set use_context=True to use the new context based callbacks
|
||||
@@ -313,8 +307,8 @@ def main():
|
||||
|
||||
states={
|
||||
SELECTING_LEVEL: [CallbackQueryHandler(select_gender,
|
||||
pattern='^{0}$|^{1}$'.format(str(PARENTS),
|
||||
str(CHILDREN)))],
|
||||
pattern='^{}$|^{}$'.format(str(PARENTS),
|
||||
str(CHILDREN)))],
|
||||
SELECTING_GENDER: [description_conv]
|
||||
},
|
||||
|
||||
@@ -335,32 +329,30 @@ def main():
|
||||
)
|
||||
|
||||
# Set up top level ConversationHandler (selecting action)
|
||||
# Because the states of the third level conversation map to the ones of the econd level
|
||||
# conversation, we need to make sure the top level conversation can also handle them
|
||||
selection_handlers = [
|
||||
add_member_conv,
|
||||
CallbackQueryHandler(show_data, pattern='^' + str(SHOWING) + '$'),
|
||||
CallbackQueryHandler(adding_self, pattern='^' + str(ADDING_SELF) + '$'),
|
||||
CallbackQueryHandler(end, pattern='^' + str(END) + '$'),
|
||||
]
|
||||
conv_handler = ConversationHandler(
|
||||
entry_points=[CommandHandler('start', start)],
|
||||
|
||||
states={
|
||||
SHOWING: [CallbackQueryHandler(start, pattern='^' + str(END) + '$')],
|
||||
SELECTING_ACTION: [
|
||||
add_member_conv,
|
||||
CallbackQueryHandler(show_data, pattern='^' + str(SHOWING) + '$'),
|
||||
CallbackQueryHandler(adding_self, pattern='^' + str(ADDING_SELF) + '$'),
|
||||
CallbackQueryHandler(end, pattern='^' + str(END) + '$'),
|
||||
],
|
||||
SELECTING_ACTION: selection_handlers,
|
||||
SELECTING_LEVEL: selection_handlers,
|
||||
DESCRIBING_SELF: [description_conv],
|
||||
STOPPING: [CommandHandler('start', start)],
|
||||
},
|
||||
|
||||
fallbacks=[CommandHandler('stop', stop)],
|
||||
)
|
||||
# Because the states of the third level conversation map to the ones of the
|
||||
# second level conversation, we need to be a bit hacky about that:
|
||||
conv_handler.states[SELECTING_LEVEL] = conv_handler.states[SELECTING_ACTION]
|
||||
conv_handler.states[STOPPING] = conv_handler.entry_points
|
||||
|
||||
dp.add_handler(conv_handler)
|
||||
|
||||
# log all errors
|
||||
dp.add_error_handler(error)
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
|
||||
@@ -77,11 +77,6 @@ def msg(update, context):
|
||||
actual_file.download()
|
||||
|
||||
|
||||
def error(update, context):
|
||||
"""Log Errors caused by Updates."""
|
||||
logger.warning('Update "%s" caused error "%s"', update, context.error)
|
||||
|
||||
|
||||
def main():
|
||||
"""Start the bot."""
|
||||
# Create the Updater and pass it your token and private key
|
||||
@@ -93,9 +88,6 @@ def main():
|
||||
# On messages that include passport data call msg
|
||||
dp.add_handler(MessageHandler(Filters.passport_data, msg))
|
||||
|
||||
# log all errors
|
||||
dp.add_error_handler(error)
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
|
||||
@@ -19,11 +19,6 @@ logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def error(update, context):
|
||||
"""Log Errors caused by Updates."""
|
||||
logger.warning('Update "%s" caused error "%s"', update, context.error)
|
||||
|
||||
|
||||
def start_callback(update, context):
|
||||
msg = "Use /shipping to get an invoice for shipping-payment, "
|
||||
msg += "or /noshipping for an invoice without shipping."
|
||||
@@ -134,9 +129,6 @@ def main():
|
||||
# Success! Notify your user!
|
||||
dp.add_handler(MessageHandler(Filters.successful_payment, successful_payment_callback))
|
||||
|
||||
# log all errors
|
||||
dp.add_error_handler(error)
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
|
||||
@@ -107,11 +107,6 @@ def done(update, context):
|
||||
return ConversationHandler.END
|
||||
|
||||
|
||||
def error(update, context):
|
||||
"""Log Errors caused by Updates."""
|
||||
logger.warning('Update "%s" caused error "%s"', update, context.error)
|
||||
|
||||
|
||||
def main():
|
||||
# Create the Updater and pass it your bot's token.
|
||||
pp = PicklePersistence(filename='conversationbot')
|
||||
@@ -149,8 +144,6 @@ def main():
|
||||
|
||||
show_data_handler = CommandHandler('show_data', show_data)
|
||||
dp.add_handler(show_data_handler)
|
||||
# log all errors
|
||||
dp.add_error_handler(error)
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
@@ -77,11 +77,6 @@ def unset(update, context):
|
||||
update.message.reply_text('Timer successfully unset!')
|
||||
|
||||
|
||||
def error(update, context):
|
||||
"""Log Errors caused by Updates."""
|
||||
logger.warning('Update "%s" caused error "%s"', update, context.error)
|
||||
|
||||
|
||||
def main():
|
||||
"""Run bot."""
|
||||
# Create the Updater and pass it your bot's token.
|
||||
@@ -101,9 +96,6 @@ def main():
|
||||
pass_chat_data=True))
|
||||
dp.add_handler(CommandHandler("unset", unset, pass_chat_data=True))
|
||||
|
||||
# log all errors
|
||||
dp.add_error_handler(error)
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
future>=0.16.0
|
||||
certifi
|
||||
tornado>=5.1
|
||||
cryptography
|
||||
|
||||
@@ -20,7 +20,6 @@ import sys
|
||||
import subprocess
|
||||
|
||||
import certifi
|
||||
import future
|
||||
|
||||
|
||||
from . import __version__ as telegram_ver
|
||||
@@ -37,11 +36,10 @@ def _git_revision():
|
||||
|
||||
def print_ver_info():
|
||||
git_revision = _git_revision()
|
||||
print('python-telegram-bot {0}'.format(telegram_ver) + (' ({0})'.format(git_revision)
|
||||
if git_revision else ''))
|
||||
print('certifi {0}'.format(certifi.__version__))
|
||||
print('future {0}'.format(future.__version__))
|
||||
print('Python {0}'.format(sys.version.replace('\n', ' ')))
|
||||
print('python-telegram-bot {}'.format(telegram_ver) + (' ({})'.format(git_revision)
|
||||
if git_revision else ''))
|
||||
print('certifi {}'.format(certifi.__version__))
|
||||
print('Python {}'.format(sys.version.replace('\n', ' ')))
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
+4
-9
@@ -24,7 +24,7 @@ except ImportError:
|
||||
import json
|
||||
|
||||
|
||||
class TelegramObject(object):
|
||||
class TelegramObject:
|
||||
"""Base class for most telegram objects."""
|
||||
|
||||
_id_attrs = ()
|
||||
@@ -57,12 +57,7 @@ class TelegramObject(object):
|
||||
data = dict()
|
||||
|
||||
for key in iter(self.__dict__):
|
||||
if key in ('bot',
|
||||
'_id_attrs',
|
||||
'_credentials',
|
||||
'_decrypted_credentials',
|
||||
'_decrypted_data',
|
||||
'_decrypted_secret'):
|
||||
if key == 'bot' or key.startswith('_'):
|
||||
continue
|
||||
|
||||
value = self.__dict__[key]
|
||||
@@ -79,9 +74,9 @@ class TelegramObject(object):
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
return self._id_attrs == other._id_attrs
|
||||
return super(TelegramObject, self).__eq__(other) # pylint: disable=no-member
|
||||
return super().__eq__(other) # pylint: disable=no-member
|
||||
|
||||
def __hash__(self):
|
||||
if self._id_attrs:
|
||||
return hash((self.__class__, self._id_attrs)) # pylint: disable=no-member
|
||||
return super(TelegramObject, self).__hash__()
|
||||
return super().__hash__()
|
||||
|
||||
+96
-93
@@ -34,7 +34,6 @@ from datetime import datetime
|
||||
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from future.utils import string_types
|
||||
|
||||
from telegram import (User, Message, Update, Chat, ChatMember, UserProfilePhotos, File,
|
||||
ReplyMarkup, TelegramObject, WebhookInfo, GameHighScore, StickerSet,
|
||||
@@ -44,8 +43,6 @@ from telegram.error import InvalidToken, TelegramError
|
||||
from telegram.utils.helpers import to_timestamp, DEFAULT_NONE
|
||||
from telegram.utils.request import Request
|
||||
|
||||
logging.getLogger(__name__).addHandler(logging.NullHandler())
|
||||
|
||||
|
||||
def info(func):
|
||||
@functools.wraps(func)
|
||||
@@ -96,7 +93,7 @@ class Bot(TelegramObject):
|
||||
defaults = kwargs.get('defaults')
|
||||
|
||||
# Make an instance of the class
|
||||
instance = super(Bot, cls).__new__(cls)
|
||||
instance = super().__new__(cls)
|
||||
|
||||
if not defaults:
|
||||
return instance
|
||||
@@ -268,7 +265,7 @@ class Bot(TelegramObject):
|
||||
def name(self):
|
||||
""":obj:`str`: Bot's @username."""
|
||||
|
||||
return '@{0}'.format(self.username)
|
||||
return '@{}'.format(self.username)
|
||||
|
||||
@log
|
||||
def get_me(self, timeout=None, **kwargs):
|
||||
@@ -287,7 +284,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/getMe'.format(self.base_url)
|
||||
url = '{}/getMe'.format(self.base_url)
|
||||
|
||||
result = self._request.get(url, timeout=timeout)
|
||||
|
||||
@@ -337,7 +334,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/sendMessage'.format(self.base_url)
|
||||
url = '{}/sendMessage'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id, 'text': text}
|
||||
|
||||
@@ -382,7 +379,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/deleteMessage'.format(self.base_url)
|
||||
url = '{}/deleteMessage'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id, 'message_id': message_id}
|
||||
|
||||
@@ -420,7 +417,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/forwardMessage'.format(self.base_url)
|
||||
url = '{}/forwardMessage'.format(self.base_url)
|
||||
|
||||
data = {}
|
||||
|
||||
@@ -481,7 +478,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/sendPhoto'.format(self.base_url)
|
||||
url = '{}/sendPhoto'.format(self.base_url)
|
||||
|
||||
if isinstance(photo, PhotoSize):
|
||||
photo = photo.file_id
|
||||
@@ -551,9 +548,10 @@ class Bot(TelegramObject):
|
||||
JSON-serialized object for an inline keyboard, custom reply keyboard, instructions
|
||||
to remove reply keyboard or to force a reply from the user.
|
||||
thumb (`filelike object`, optional): Thumbnail of the file sent; can be ignored if
|
||||
thumbnail generation for the file is supported server-side. The thumbnail should
|
||||
be in JPEG format and less than 200 kB in size. A thumbnail's width and height
|
||||
should not exceed 320. Ignored if the file is not is passed as a string or file_id.
|
||||
thumbnail generation for the file is supported server-side. The thumbnail should be
|
||||
in JPEG format and less than 200 kB in size. A thumbnail's width and height should
|
||||
not exceed 320. Ignored if the file is not uploaded using multipart/form-data.
|
||||
Thumbnails can't be reused and can be only uploaded as a new file.
|
||||
timeout (:obj:`int` | :obj:`float`, optional): Send file timeout (default: 20 seconds).
|
||||
**kwargs (:obj:`dict`): Arbitrary keyword arguments.
|
||||
|
||||
@@ -564,7 +562,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/sendAudio'.format(self.base_url)
|
||||
url = '{}/sendAudio'.format(self.base_url)
|
||||
|
||||
if isinstance(audio, Audio):
|
||||
audio = audio.file_id
|
||||
@@ -638,9 +636,10 @@ class Bot(TelegramObject):
|
||||
JSON-serialized object for an inline keyboard, custom reply keyboard, instructions
|
||||
to remove reply keyboard or to force a reply from the user.
|
||||
thumb (`filelike object`, optional): Thumbnail of the file sent; can be ignored if
|
||||
thumbnail generation for the file is supported server-side. The thumbnail should
|
||||
be in JPEG format and less than 200 kB in size. A thumbnail's width and height
|
||||
should not exceed 320. Ignored if the file is not passed as a string or file_id.
|
||||
thumbnail generation for the file is supported server-side. The thumbnail should be
|
||||
in JPEG format and less than 200 kB in size. A thumbnail's width and height should
|
||||
not exceed 320. Ignored if the file is not uploaded using multipart/form-data.
|
||||
Thumbnails can't be reused and can be only uploaded as a new file.
|
||||
timeout (:obj:`int` | :obj:`float`, optional): Send file timeout (default: 20 seconds).
|
||||
**kwargs (:obj:`dict`): Arbitrary keyword arguments.
|
||||
|
||||
@@ -651,7 +650,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/sendDocument'.format(self.base_url)
|
||||
url = '{}/sendDocument'.format(self.base_url)
|
||||
|
||||
if isinstance(document, Document):
|
||||
document = document.file_id
|
||||
@@ -714,7 +713,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/sendSticker'.format(self.base_url)
|
||||
url = '{}/sendSticker'.format(self.base_url)
|
||||
|
||||
if isinstance(sticker, Sticker):
|
||||
sticker = sticker.file_id
|
||||
@@ -780,9 +779,10 @@ class Bot(TelegramObject):
|
||||
JSON-serialized object for an inline keyboard, custom reply keyboard, instructions
|
||||
to remove reply keyboard or to force a reply from the user.
|
||||
thumb (`filelike object`, optional): Thumbnail of the file sent; can be ignored if
|
||||
thumbnail generation for the file is supported server-side. The thumbnail should
|
||||
be in JPEG format and less than 200 kB in size. A thumbnail‘s width and height
|
||||
should not exceed 320. Ignored if the file is not is passed as a string or file_id.
|
||||
thumbnail generation for the file is supported server-side. The thumbnail should be
|
||||
in JPEG format and less than 200 kB in size. A thumbnail's width and height should
|
||||
not exceed 320. Ignored if the file is not uploaded using multipart/form-data.
|
||||
Thumbnails can't be reused and can be only uploaded as a new file.
|
||||
timeout (:obj:`int` | :obj:`float`, optional): Send file timeout (default: 20 seconds).
|
||||
**kwargs (:obj:`dict`): Arbitrary keyword arguments.
|
||||
|
||||
@@ -793,7 +793,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/sendVideo'.format(self.base_url)
|
||||
url = '{}/sendVideo'.format(self.base_url)
|
||||
|
||||
if isinstance(video, Video):
|
||||
video = video.file_id
|
||||
@@ -862,9 +862,10 @@ class Bot(TelegramObject):
|
||||
JSON-serialized object for an inline keyboard, custom reply keyboard,
|
||||
instructions to remove reply keyboard or to force a reply from the user.
|
||||
thumb (`filelike object`, optional): Thumbnail of the file sent; can be ignored if
|
||||
thumbnail generation for the file is supported server-side. The thumbnail should
|
||||
be in JPEG format and less than 200 kB in size. A thumbnail‘s width and height
|
||||
should not exceed 320. Ignored if the file is not is passed as a string or file_id.
|
||||
thumbnail generation for the file is supported server-side. The thumbnail should be
|
||||
in JPEG format and less than 200 kB in size. A thumbnail's width and height should
|
||||
not exceed 320. Ignored if the file is not uploaded using multipart/form-data.
|
||||
Thumbnails can't be reused and can be only uploaded as a new file.
|
||||
timeout (:obj:`int` | :obj:`float`, optional): Send file timeout (default: 20 seconds).
|
||||
**kwargs (:obj:`dict`): Arbitrary keyword arguments.
|
||||
|
||||
@@ -875,7 +876,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/sendVideoNote'.format(self.base_url)
|
||||
url = '{}/sendVideoNote'.format(self.base_url)
|
||||
|
||||
if isinstance(video_note, VideoNote):
|
||||
video_note = video_note.file_id
|
||||
@@ -929,9 +930,10 @@ class Bot(TelegramObject):
|
||||
width (:obj:`int`, optional): Animation width.
|
||||
height (:obj:`int`, optional): Animation height.
|
||||
thumb (`filelike object`, optional): Thumbnail of the file sent; can be ignored if
|
||||
thumbnail generation for the file is supported server-side. The thumbnail should
|
||||
be in JPEG format and less than 200 kB in size. A thumbnail‘s width and height
|
||||
should not exceed 320. Ignored if the file is not is passed as a string or file_id.
|
||||
thumbnail generation for the file is supported server-side. The thumbnail should be
|
||||
in JPEG format and less than 200 kB in size. A thumbnail's width and height should
|
||||
not exceed 320. Ignored if the file is not uploaded using multipart/form-data.
|
||||
Thumbnails can't be reused and can be only uploaded as a new file.
|
||||
caption (:obj:`str`, optional): Animation caption (may also be used when resending
|
||||
animations by file_id), 0-1024 characters after entities parsing.
|
||||
parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to
|
||||
@@ -954,7 +956,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/sendAnimation'.format(self.base_url)
|
||||
url = '{}/sendAnimation'.format(self.base_url)
|
||||
|
||||
if isinstance(animation, Animation):
|
||||
animation = animation.file_id
|
||||
@@ -1035,7 +1037,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/sendVoice'.format(self.base_url)
|
||||
url = '{}/sendVoice'.format(self.base_url)
|
||||
|
||||
if isinstance(voice, Voice):
|
||||
voice = voice.file_id
|
||||
@@ -1084,7 +1086,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
"""
|
||||
|
||||
url = '{0}/sendMediaGroup'.format(self.base_url)
|
||||
url = '{}/sendMediaGroup'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id, 'media': media}
|
||||
|
||||
@@ -1152,7 +1154,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/sendLocation'.format(self.base_url)
|
||||
url = '{}/sendLocation'.format(self.base_url)
|
||||
|
||||
if not ((latitude is not None and longitude is not None) or location):
|
||||
raise ValueError("Either location or latitude and longitude must be passed as"
|
||||
@@ -1215,7 +1217,7 @@ class Bot(TelegramObject):
|
||||
edited Message is returned, otherwise ``True`` is returned.
|
||||
"""
|
||||
|
||||
url = '{0}/editMessageLiveLocation'.format(self.base_url)
|
||||
url = '{}/editMessageLiveLocation'.format(self.base_url)
|
||||
|
||||
if not (all([latitude, longitude]) or location):
|
||||
raise ValueError("Either location or latitude and longitude must be passed as"
|
||||
@@ -1269,7 +1271,7 @@ class Bot(TelegramObject):
|
||||
edited Message is returned, otherwise ``True`` is returned.
|
||||
"""
|
||||
|
||||
url = '{0}/stopMessageLiveLocation'.format(self.base_url)
|
||||
url = '{}/stopMessageLiveLocation'.format(self.base_url)
|
||||
|
||||
data = {}
|
||||
|
||||
@@ -1335,7 +1337,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/sendVenue'.format(self.base_url)
|
||||
url = '{}/sendVenue'.format(self.base_url)
|
||||
|
||||
if not (venue or all([latitude, longitude, address, title])):
|
||||
raise ValueError("Either venue or latitude, longitude, address and title must be"
|
||||
@@ -1413,7 +1415,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/sendContact'.format(self.base_url)
|
||||
url = '{}/sendContact'.format(self.base_url)
|
||||
|
||||
if (not contact) and (not all([phone_number, first_name])):
|
||||
raise ValueError("Either contact or phone_number and first_name must be passed as"
|
||||
@@ -1471,7 +1473,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/sendGame'.format(self.base_url)
|
||||
url = '{}/sendGame'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id, 'game_short_name': game_short_name}
|
||||
|
||||
@@ -1505,7 +1507,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/sendChatAction'.format(self.base_url)
|
||||
url = '{}/sendChatAction'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id, 'action': action}
|
||||
data.update(kwargs)
|
||||
@@ -1569,7 +1571,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/answerInlineQuery'.format(self.base_url)
|
||||
url = '{}/answerInlineQuery'.format(self.base_url)
|
||||
|
||||
for res in results:
|
||||
if res._has_parse_mode and res.parse_mode == DEFAULT_NONE:
|
||||
@@ -1635,7 +1637,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/getUserProfilePhotos'.format(self.base_url)
|
||||
url = '{}/getUserProfilePhotos'.format(self.base_url)
|
||||
|
||||
data = {'user_id': user_id}
|
||||
|
||||
@@ -1683,7 +1685,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/getFile'.format(self.base_url)
|
||||
url = '{}/getFile'.format(self.base_url)
|
||||
|
||||
try:
|
||||
file_id = file_id.file_id
|
||||
@@ -1696,7 +1698,7 @@ class Bot(TelegramObject):
|
||||
result = self._request.post(url, data, timeout=timeout)
|
||||
|
||||
if result.get('file_path'):
|
||||
result['file_path'] = '%s/%s' % (self.base_file_url, result['file_path'])
|
||||
result['file_path'] = '{}/{}'.format(self.base_file_url, result['file_path'])
|
||||
|
||||
return File.de_json(result, self)
|
||||
|
||||
@@ -1727,7 +1729,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/kickChatMember'.format(self.base_url)
|
||||
url = '{}/kickChatMember'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id, 'user_id': user_id}
|
||||
data.update(kwargs)
|
||||
@@ -1764,7 +1766,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/unbanChatMember'.format(self.base_url)
|
||||
url = '{}/unbanChatMember'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id, 'user_id': user_id}
|
||||
data.update(kwargs)
|
||||
@@ -1816,7 +1818,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url_ = '{0}/answerCallbackQuery'.format(self.base_url)
|
||||
url_ = '{}/answerCallbackQuery'.format(self.base_url)
|
||||
|
||||
data = {'callback_query_id': callback_query_id}
|
||||
|
||||
@@ -1878,7 +1880,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/editMessageText'.format(self.base_url)
|
||||
url = '{}/editMessageText'.format(self.base_url)
|
||||
|
||||
data = {'text': text}
|
||||
|
||||
@@ -1942,7 +1944,7 @@ class Bot(TelegramObject):
|
||||
'edit_message_caption: Both chat_id and message_id are required when '
|
||||
'inline_message_id is not specified')
|
||||
|
||||
url = '{0}/editMessageCaption'.format(self.base_url)
|
||||
url = '{}/editMessageCaption'.format(self.base_url)
|
||||
|
||||
data = {}
|
||||
|
||||
@@ -2004,7 +2006,7 @@ class Bot(TelegramObject):
|
||||
'edit_message_media: Both chat_id and message_id are required when '
|
||||
'inline_message_id is not specified')
|
||||
|
||||
url = '{0}/editMessageMedia'.format(self.base_url)
|
||||
url = '{}/editMessageMedia'.format(self.base_url)
|
||||
|
||||
data = {'media': media}
|
||||
|
||||
@@ -2057,7 +2059,7 @@ class Bot(TelegramObject):
|
||||
'edit_message_reply_markup: Both chat_id and message_id are required when '
|
||||
'inline_message_id is not specified')
|
||||
|
||||
url = '{0}/editMessageReplyMarkup'.format(self.base_url)
|
||||
url = '{}/editMessageReplyMarkup'.format(self.base_url)
|
||||
|
||||
data = {}
|
||||
|
||||
@@ -2116,7 +2118,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/getUpdates'.format(self.base_url)
|
||||
url = '{}/getUpdates'.format(self.base_url)
|
||||
|
||||
data = {'timeout': timeout}
|
||||
|
||||
@@ -2210,7 +2212,7 @@ class Bot(TelegramObject):
|
||||
.. _`guide to Webhooks`: https://core.telegram.org/bots/webhooks
|
||||
|
||||
"""
|
||||
url_ = '{0}/setWebhook'.format(self.base_url)
|
||||
url_ = '{}/setWebhook'.format(self.base_url)
|
||||
|
||||
# Backwards-compatibility: 'url' used to be named 'webhook_url'
|
||||
if 'webhook_url' in kwargs: # pragma: no cover
|
||||
@@ -2260,7 +2262,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/deleteWebhook'.format(self.base_url)
|
||||
url = '{}/deleteWebhook'.format(self.base_url)
|
||||
|
||||
data = kwargs
|
||||
|
||||
@@ -2287,7 +2289,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/leaveChat'.format(self.base_url)
|
||||
url = '{}/leaveChat'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id}
|
||||
data.update(kwargs)
|
||||
@@ -2317,7 +2319,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/getChat'.format(self.base_url)
|
||||
url = '{}/getChat'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id}
|
||||
data.update(kwargs)
|
||||
@@ -2352,7 +2354,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/getChatAdministrators'.format(self.base_url)
|
||||
url = '{}/getChatAdministrators'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id}
|
||||
data.update(kwargs)
|
||||
@@ -2380,7 +2382,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/getChatMembersCount'.format(self.base_url)
|
||||
url = '{}/getChatMembersCount'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id}
|
||||
data.update(kwargs)
|
||||
@@ -2409,7 +2411,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/getChatMember'.format(self.base_url)
|
||||
url = '{}/getChatMember'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id, 'user_id': user_id}
|
||||
data.update(kwargs)
|
||||
@@ -2440,7 +2442,7 @@ class Bot(TelegramObject):
|
||||
:obj:`bool`: On success, ``True`` is returned.
|
||||
"""
|
||||
|
||||
url = '{0}/setChatStickerSet'.format(self.base_url)
|
||||
url = '{}/setChatStickerSet'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id, 'sticker_set_name': sticker_set_name}
|
||||
|
||||
@@ -2467,7 +2469,7 @@ class Bot(TelegramObject):
|
||||
:obj:`bool`: On success, ``True`` is returned.
|
||||
"""
|
||||
|
||||
url = '{0}/deleteChatStickerSet'.format(self.base_url)
|
||||
url = '{}/deleteChatStickerSet'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id}
|
||||
|
||||
@@ -2490,7 +2492,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.WebhookInfo`
|
||||
|
||||
"""
|
||||
url = '{0}/getWebhookInfo'.format(self.base_url)
|
||||
url = '{}/getWebhookInfo'.format(self.base_url)
|
||||
|
||||
data = kwargs
|
||||
|
||||
@@ -2539,7 +2541,7 @@ class Bot(TelegramObject):
|
||||
current score in the chat and force is False.
|
||||
|
||||
"""
|
||||
url = '{0}/setGameScore'.format(self.base_url)
|
||||
url = '{}/setGameScore'.format(self.base_url)
|
||||
|
||||
data = {'user_id': user_id, 'score': score}
|
||||
|
||||
@@ -2588,7 +2590,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/getGameHighScores'.format(self.base_url)
|
||||
url = '{}/getGameHighScores'.format(self.base_url)
|
||||
|
||||
data = {'user_id': user_id}
|
||||
|
||||
@@ -2689,7 +2691,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/sendInvoice'.format(self.base_url)
|
||||
url = '{}/sendInvoice'.format(self.base_url)
|
||||
|
||||
data = {
|
||||
'chat_id': chat_id,
|
||||
@@ -2702,7 +2704,7 @@ class Bot(TelegramObject):
|
||||
'prices': [p.to_dict() for p in prices]
|
||||
}
|
||||
if provider_data is not None:
|
||||
if isinstance(provider_data, string_types):
|
||||
if isinstance(provider_data, str):
|
||||
data['provider_data'] = provider_data
|
||||
else:
|
||||
data['provider_data'] = json.dumps(provider_data)
|
||||
@@ -2781,7 +2783,7 @@ class Bot(TelegramObject):
|
||||
'answerShippingQuery: If ok is False, error_message '
|
||||
'should not be empty and there should not be shipping_options')
|
||||
|
||||
url_ = '{0}/answerShippingQuery'.format(self.base_url)
|
||||
url_ = '{}/answerShippingQuery'.format(self.base_url)
|
||||
|
||||
data = {'shipping_query_id': shipping_query_id, 'ok': ok}
|
||||
|
||||
@@ -2836,7 +2838,7 @@ class Bot(TelegramObject):
|
||||
'not be error_message; if ok is False, error_message '
|
||||
'should not be empty')
|
||||
|
||||
url_ = '{0}/answerPreCheckoutQuery'.format(self.base_url)
|
||||
url_ = '{}/answerPreCheckoutQuery'.format(self.base_url)
|
||||
|
||||
data = {'pre_checkout_query_id': pre_checkout_query_id, 'ok': ok}
|
||||
|
||||
@@ -2881,7 +2883,7 @@ class Bot(TelegramObject):
|
||||
Raises:
|
||||
:class:`telegram.TelegramError`
|
||||
"""
|
||||
url = '{0}/restrictChatMember'.format(self.base_url)
|
||||
url = '{}/restrictChatMember'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id, 'user_id': user_id, 'permissions': permissions.to_dict()}
|
||||
|
||||
@@ -2940,7 +2942,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/promoteChatMember'.format(self.base_url)
|
||||
url = '{}/promoteChatMember'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id, 'user_id': user_id}
|
||||
|
||||
@@ -2989,7 +2991,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/setChatPermissions'.format(self.base_url)
|
||||
url = '{}/setChatPermissions'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id, 'permissions': permissions.to_dict()}
|
||||
data.update(kwargs)
|
||||
@@ -3027,7 +3029,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/setChatAdministratorCustomTitle'.format(self.base_url)
|
||||
url = '{}/setChatAdministratorCustomTitle'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id, 'user_id': user_id, 'custom_title': custom_title}
|
||||
data.update(kwargs)
|
||||
@@ -3058,7 +3060,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/exportChatInviteLink'.format(self.base_url)
|
||||
url = '{}/exportChatInviteLink'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id}
|
||||
data.update(kwargs)
|
||||
@@ -3090,7 +3092,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/setChatPhoto'.format(self.base_url)
|
||||
url = '{}/setChatPhoto'.format(self.base_url)
|
||||
|
||||
if InputFile.is_file(photo):
|
||||
photo = InputFile(photo)
|
||||
@@ -3124,7 +3126,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/deleteChatPhoto'.format(self.base_url)
|
||||
url = '{}/deleteChatPhoto'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id}
|
||||
data.update(kwargs)
|
||||
@@ -3156,7 +3158,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/setChatTitle'.format(self.base_url)
|
||||
url = '{}/setChatTitle'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id, 'title': title}
|
||||
data.update(kwargs)
|
||||
@@ -3188,7 +3190,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/setChatDescription'.format(self.base_url)
|
||||
url = '{}/setChatDescription'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id, 'description': description}
|
||||
data.update(kwargs)
|
||||
@@ -3225,7 +3227,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/pinChatMessage'.format(self.base_url)
|
||||
url = '{}/pinChatMessage'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id, 'message_id': message_id}
|
||||
|
||||
@@ -3260,7 +3262,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/unpinChatMessage'.format(self.base_url)
|
||||
url = '{}/unpinChatMessage'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id}
|
||||
data.update(kwargs)
|
||||
@@ -3287,7 +3289,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/getStickerSet'.format(self.base_url)
|
||||
url = '{}/getStickerSet'.format(self.base_url)
|
||||
|
||||
data = {'name': name}
|
||||
data.update(kwargs)
|
||||
@@ -3324,7 +3326,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/uploadStickerFile'.format(self.base_url)
|
||||
url = '{}/uploadStickerFile'.format(self.base_url)
|
||||
|
||||
if InputFile.is_file(png_sticker):
|
||||
png_sticker = InputFile(png_sticker)
|
||||
@@ -3389,7 +3391,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/createNewStickerSet'.format(self.base_url)
|
||||
url = '{}/createNewStickerSet'.format(self.base_url)
|
||||
|
||||
if InputFile.is_file(png_sticker):
|
||||
png_sticker = InputFile(png_sticker)
|
||||
@@ -3461,7 +3463,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/addStickerToSet'.format(self.base_url)
|
||||
url = '{}/addStickerToSet'.format(self.base_url)
|
||||
|
||||
if InputFile.is_file(png_sticker):
|
||||
png_sticker = InputFile(png_sticker)
|
||||
@@ -3504,7 +3506,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/setStickerPositionInSet'.format(self.base_url)
|
||||
url = '{}/setStickerPositionInSet'.format(self.base_url)
|
||||
|
||||
data = {'sticker': sticker, 'position': position}
|
||||
data.update(kwargs)
|
||||
@@ -3531,7 +3533,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/deleteStickerFromSet'.format(self.base_url)
|
||||
url = '{}/deleteStickerFromSet'.format(self.base_url)
|
||||
|
||||
data = {'sticker': sticker}
|
||||
data.update(kwargs)
|
||||
@@ -3610,7 +3612,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url_ = '{0}/setPassportDataErrors'.format(self.base_url)
|
||||
url_ = '{}/setPassportDataErrors'.format(self.base_url)
|
||||
|
||||
data = {'user_id': user_id, 'errors': [error.to_dict() for error in errors]}
|
||||
data.update(kwargs)
|
||||
@@ -3687,7 +3689,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/sendPoll'.format(self.base_url)
|
||||
url = '{}/sendPoll'.format(self.base_url)
|
||||
|
||||
data = {
|
||||
'chat_id': chat_id,
|
||||
@@ -3755,7 +3757,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/stopPoll'.format(self.base_url)
|
||||
url = '{}/stopPoll'.format(self.base_url)
|
||||
|
||||
data = {
|
||||
'chat_id': chat_id,
|
||||
@@ -3784,13 +3786,14 @@ class Bot(TelegramObject):
|
||||
emoji=None,
|
||||
**kwargs):
|
||||
"""
|
||||
Use this method to send a dice, which will have a random value from 1 to 6. On success, the
|
||||
Use this method to send an animated emoji, which will have a random value. On success, the
|
||||
sent Message is returned.
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): Unique identifier for the target private chat.
|
||||
emoji (:obj:`str`, optional): Emoji on which the dice throw animation is based.
|
||||
Currently, must be one of “🎲” or “🎯”. Defaults to “🎲”
|
||||
Currently, must be one of “🎲”, “🎯” or “🏀”. Dice can have values 1-6 for “🎲” and
|
||||
“🎯”, and values 1-5 for “🏀” . Defaults to “🎲”
|
||||
disable_notification (:obj:`bool`, optional): Sends the message silently. Users will
|
||||
receive a notification with no sound.
|
||||
reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the
|
||||
@@ -3810,7 +3813,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/sendDice'.format(self.base_url)
|
||||
url = '{}/sendDice'.format(self.base_url)
|
||||
|
||||
data = {
|
||||
'chat_id': chat_id,
|
||||
@@ -3841,7 +3844,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/getMyCommands'.format(self.base_url)
|
||||
url = '{}/getMyCommands'.format(self.base_url)
|
||||
|
||||
result = self._request.get(url, timeout=timeout)
|
||||
|
||||
@@ -3870,7 +3873,7 @@ class Bot(TelegramObject):
|
||||
:class:`telegram.TelegramError`
|
||||
|
||||
"""
|
||||
url = '{0}/setMyCommands'.format(self.base_url)
|
||||
url = '{}/setMyCommands'.format(self.base_url)
|
||||
|
||||
cmds = [c if isinstance(c, BotCommand) else BotCommand(c[0], c[1]) for c in commands]
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ class CallbackQuery(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(CallbackQuery, cls).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
|
||||
data['from_user'] = User.de_json(data.get('from'), bot)
|
||||
message = data.get('message')
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"""This module contains an object that represents a Telegram ChatAction."""
|
||||
|
||||
|
||||
class ChatAction(object):
|
||||
class ChatAction:
|
||||
"""Helper class to provide constants for different chatactions."""
|
||||
|
||||
FIND_LOCATION = 'find_location'
|
||||
|
||||
@@ -150,7 +150,7 @@ class ChatMember(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(ChatMember, cls).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
|
||||
data['user'] = User.de_json(data.get('user'), bot)
|
||||
data['until_date'] = from_timestamp(data.get('until_date', None))
|
||||
@@ -158,7 +158,7 @@ class ChatMember(TelegramObject):
|
||||
return cls(**data)
|
||||
|
||||
def to_dict(self):
|
||||
data = super(ChatMember, self).to_dict()
|
||||
data = super().to_dict()
|
||||
|
||||
data['until_date'] = to_timestamp(self.until_date)
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ class ChosenInlineResult(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(ChosenInlineResult, cls).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
# Required
|
||||
data['from_user'] = User.de_json(data.pop('from'), bot)
|
||||
# Optionals
|
||||
|
||||
+13
-7
@@ -23,21 +23,25 @@ from telegram import TelegramObject
|
||||
|
||||
class Dice(TelegramObject):
|
||||
"""
|
||||
This object represents a dice with random value from 1 to 6 for currently supported base eomji.
|
||||
(The singular form of "dice" is "die". However, PTB mimics the Telegram API, which uses the
|
||||
term "dice".)
|
||||
This object represents an animated emoji with a random value for currently supported base
|
||||
emoji. (The singular form of "dice" is "die". However, PTB mimics the Telegram API, which uses
|
||||
the term "dice".)
|
||||
|
||||
Note:
|
||||
If :attr:`emoji` is "🎯", a value of 6 currently represents a bullseye, while a value of 1
|
||||
indicates that the dartboard was missed. However, this behaviour is undocumented and might
|
||||
be changed by Telegram.
|
||||
|
||||
If :attr:`emoji` is "🏀", a value of 4 or 5 currently score a basket, while a value of 1 to
|
||||
3 indicates that the basket was missed. However, this behaviour is undocumented and might
|
||||
be changed by Telegram.
|
||||
|
||||
Attributes:
|
||||
value (:obj:`int`): Value of the dice.
|
||||
emoji (:obj:`str`): Emoji on which the dice throw animation is based.
|
||||
|
||||
Args:
|
||||
value (:obj:`int`): Value of the dice, 1-6.
|
||||
value (:obj:`int`): Value of the dice. 1-6 for dice and darts, 1-5 for basketball.
|
||||
emoji (:obj:`str`): Emoji on which the dice throw animation is based.
|
||||
"""
|
||||
def __init__(self, value, emoji, **kwargs):
|
||||
@@ -55,6 +59,8 @@ class Dice(TelegramObject):
|
||||
""":obj:`str`: '🎲'"""
|
||||
DARTS = '🎯'
|
||||
""":obj:`str`: '🎯'"""
|
||||
ALL_EMOJI = [DICE, DARTS]
|
||||
"""List[:obj:`str`]: List of all supported base emoji. Currently :attr:`DICE` and
|
||||
:attr:`DARTS`."""
|
||||
BASKETBALL = '🏀'
|
||||
""":obj:`str`: '🏀'"""
|
||||
ALL_EMOJI = [DICE, DARTS, BASKETBALL]
|
||||
"""List[:obj:`str`]: List of all supported base emoji. Currently :attr:`DICE`,
|
||||
:attr:`DARTS` and :attr:`BASKETBALL`."""
|
||||
|
||||
+6
-8
@@ -38,7 +38,7 @@ def _lstrip_str(in_s, lstr):
|
||||
|
||||
class TelegramError(Exception):
|
||||
def __init__(self, message):
|
||||
super(TelegramError, self).__init__()
|
||||
super().__init__()
|
||||
|
||||
msg = _lstrip_str(message, 'Error: ')
|
||||
msg = _lstrip_str(msg, '[Error]: ')
|
||||
@@ -58,7 +58,7 @@ class Unauthorized(TelegramError):
|
||||
|
||||
class InvalidToken(TelegramError):
|
||||
def __init__(self):
|
||||
super(InvalidToken, self).__init__('Invalid token')
|
||||
super().__init__('Invalid token')
|
||||
|
||||
|
||||
class NetworkError(TelegramError):
|
||||
@@ -71,7 +71,7 @@ class BadRequest(NetworkError):
|
||||
|
||||
class TimedOut(NetworkError):
|
||||
def __init__(self):
|
||||
super(TimedOut, self).__init__('Timed out')
|
||||
super().__init__('Timed out')
|
||||
|
||||
|
||||
class ChatMigrated(TelegramError):
|
||||
@@ -82,8 +82,7 @@ class ChatMigrated(TelegramError):
|
||||
"""
|
||||
|
||||
def __init__(self, new_chat_id):
|
||||
super(ChatMigrated,
|
||||
self).__init__('Group migrated to supergroup. New chat id: {}'.format(new_chat_id))
|
||||
super().__init__('Group migrated to supergroup. New chat id: {}'.format(new_chat_id))
|
||||
self.new_chat_id = new_chat_id
|
||||
|
||||
|
||||
@@ -95,8 +94,7 @@ class RetryAfter(TelegramError):
|
||||
"""
|
||||
|
||||
def __init__(self, retry_after):
|
||||
super(RetryAfter,
|
||||
self).__init__('Flood control exceeded. Retry in {} seconds'.format(retry_after))
|
||||
super().__init__('Flood control exceeded. Retry in {} seconds'.format(retry_after))
|
||||
self.retry_after = float(retry_after)
|
||||
|
||||
|
||||
@@ -110,4 +108,4 @@ class Conflict(TelegramError):
|
||||
"""
|
||||
|
||||
def __init__(self, msg):
|
||||
super(Conflict, self).__init__(msg)
|
||||
super().__init__(msg)
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
from telegram import Update
|
||||
|
||||
|
||||
class CallbackContext(object):
|
||||
class CallbackContext:
|
||||
"""
|
||||
This is a context object passed to the callback called by :class:`telegram.ext.Handler`
|
||||
or by the :class:`telegram.ext.Dispatcher` in an error handler added by
|
||||
@@ -43,9 +43,9 @@ class CallbackContext(object):
|
||||
that you think you added will not be present.
|
||||
|
||||
Attributes:
|
||||
bot_data (:obj:`dict`, optional): A dict that can be used to keep any data in. For each
|
||||
bot_data (:obj:`dict`): Optional. A dict that can be used to keep any data in. For each
|
||||
update it will be the same ``dict``.
|
||||
chat_data (:obj:`dict`, optional): A dict that can be used to keep any data in. For each
|
||||
chat_data (:obj:`dict`): Optional. A dict that can be used to keep any data in. For each
|
||||
update from the same chat id it will be the same ``dict``.
|
||||
|
||||
Warning:
|
||||
@@ -54,18 +54,18 @@ class CallbackContext(object):
|
||||
<https://github.com/python-telegram-bot/python-telegram-bot/wiki/
|
||||
Storing-user--and-chat-related-data#chat-migration>`_.
|
||||
|
||||
user_data (:obj:`dict`, optional): A dict that can be used to keep any data in. For each
|
||||
user_data (:obj:`dict`): Optional. A dict that can be used to keep any data in. For each
|
||||
update from the same user it will be the same ``dict``.
|
||||
matches (List[:obj:`re match object`], optional): If the associated update originated from
|
||||
matches (List[:obj:`re match object`]): Optional. If the associated update originated from
|
||||
a regex-supported handler or had a :class:`Filters.regex`, this will contain a list of
|
||||
match objects for every pattern where ``re.search(pattern, string)`` returned a match.
|
||||
Note that filters short circuit, so combined regex filters will not always
|
||||
be evaluated.
|
||||
args (List[:obj:`str`], optional): Arguments passed to a command if the associated update
|
||||
args (List[:obj:`str`]): Optional. Arguments passed to a command if the associated update
|
||||
is handled by :class:`telegram.ext.CommandHandler`, :class:`telegram.ext.PrefixHandler`
|
||||
or :class:`telegram.ext.StringCommandHandler`. It contains a list of the words in the
|
||||
text after the command, using any whitespace string as a delimiter.
|
||||
error (:class:`telegram.TelegramError`, optional): The Telegram error that was raised.
|
||||
error (:class:`telegram.TelegramError`): Optional. The Telegram error that was raised.
|
||||
Only present when passed to a error handler registered with
|
||||
:attr:`telegram.ext.Dispatcher.add_error_handler`.
|
||||
job (:class:`telegram.ext.Job`): The job that that originated this callback.
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
|
||||
import re
|
||||
|
||||
from future.utils import string_types
|
||||
|
||||
from telegram import Update
|
||||
from .handler import Handler
|
||||
|
||||
@@ -105,14 +103,14 @@ class CallbackQueryHandler(Handler):
|
||||
pass_groupdict=False,
|
||||
pass_user_data=False,
|
||||
pass_chat_data=False):
|
||||
super(CallbackQueryHandler, self).__init__(
|
||||
super().__init__(
|
||||
callback,
|
||||
pass_update_queue=pass_update_queue,
|
||||
pass_job_queue=pass_job_queue,
|
||||
pass_user_data=pass_user_data,
|
||||
pass_chat_data=pass_chat_data)
|
||||
|
||||
if isinstance(pattern, string_types):
|
||||
if isinstance(pattern, str):
|
||||
pattern = re.compile(pattern)
|
||||
|
||||
self.pattern = pattern
|
||||
@@ -139,9 +137,7 @@ class CallbackQueryHandler(Handler):
|
||||
return True
|
||||
|
||||
def collect_optional_args(self, dispatcher, update=None, check_result=None):
|
||||
optional_args = super(CallbackQueryHandler, self).collect_optional_args(dispatcher,
|
||||
update,
|
||||
check_result)
|
||||
optional_args = super().collect_optional_args(dispatcher, update, check_result)
|
||||
if self.pattern:
|
||||
if self.pass_groups:
|
||||
optional_args['groups'] = check_result.groups()
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
import re
|
||||
import warnings
|
||||
|
||||
from future.utils import string_types
|
||||
|
||||
from telegram.ext import Filters
|
||||
from telegram.utils.deprecate import TelegramDeprecationWarning
|
||||
|
||||
@@ -125,14 +123,14 @@ class CommandHandler(Handler):
|
||||
pass_job_queue=False,
|
||||
pass_user_data=False,
|
||||
pass_chat_data=False):
|
||||
super(CommandHandler, self).__init__(
|
||||
super().__init__(
|
||||
callback,
|
||||
pass_update_queue=pass_update_queue,
|
||||
pass_job_queue=pass_job_queue,
|
||||
pass_user_data=pass_user_data,
|
||||
pass_chat_data=pass_chat_data)
|
||||
|
||||
if isinstance(command, string_types):
|
||||
if isinstance(command, str):
|
||||
self.command = [command.lower()]
|
||||
else:
|
||||
self.command = [x.lower() for x in command]
|
||||
@@ -184,7 +182,7 @@ class CommandHandler(Handler):
|
||||
return False
|
||||
|
||||
def collect_optional_args(self, dispatcher, update=None, check_result=None):
|
||||
optional_args = super(CommandHandler, self).collect_optional_args(dispatcher, update)
|
||||
optional_args = super().collect_optional_args(dispatcher, update)
|
||||
if self.pass_args:
|
||||
optional_args['args'] = check_result[0]
|
||||
return optional_args
|
||||
@@ -306,7 +304,7 @@ class PrefixHandler(CommandHandler):
|
||||
self._command = list()
|
||||
self._commands = list()
|
||||
|
||||
super(PrefixHandler, self).__init__(
|
||||
super().__init__(
|
||||
'nocommand', callback, filters=filters, allow_edited=None, pass_args=pass_args,
|
||||
pass_update_queue=pass_update_queue,
|
||||
pass_job_queue=pass_job_queue,
|
||||
@@ -323,7 +321,7 @@ class PrefixHandler(CommandHandler):
|
||||
|
||||
@prefix.setter
|
||||
def prefix(self, prefix):
|
||||
if isinstance(prefix, string_types):
|
||||
if isinstance(prefix, str):
|
||||
self._prefix = [prefix.lower()]
|
||||
else:
|
||||
self._prefix = prefix
|
||||
@@ -335,7 +333,7 @@ class PrefixHandler(CommandHandler):
|
||||
|
||||
@command.setter
|
||||
def command(self, command):
|
||||
if isinstance(command, string_types):
|
||||
if isinstance(command, str):
|
||||
self._command = [command.lower()]
|
||||
else:
|
||||
self._command = command
|
||||
|
||||
@@ -28,7 +28,7 @@ from telegram.ext import (Handler, CallbackQueryHandler, InlineQueryHandler,
|
||||
from telegram.utils.promise import Promise
|
||||
|
||||
|
||||
class _ConversationTimeoutContext(object):
|
||||
class _ConversationTimeoutContext:
|
||||
def __init__(self, conversation_key, update, dispatcher, callback_context):
|
||||
self.conversation_key = conversation_key
|
||||
self.update = update
|
||||
@@ -404,7 +404,7 @@ class ConversationHandler(Handler):
|
||||
return key, handler, check
|
||||
return None
|
||||
|
||||
self.logger.debug('selecting conversation %s with state %s' % (str(key), str(state)))
|
||||
self.logger.debug('selecting conversation {} with state {}'.format(str(key), str(state)))
|
||||
|
||||
handler = None
|
||||
|
||||
|
||||
@@ -66,9 +66,9 @@ class DictPersistence(BasePersistence):
|
||||
chat_data_json='',
|
||||
bot_data_json='',
|
||||
conversations_json=''):
|
||||
super(DictPersistence, self).__init__(store_user_data=store_user_data,
|
||||
store_chat_data=store_chat_data,
|
||||
store_bot_data=store_bot_data)
|
||||
super().__init__(store_user_data=store_user_data,
|
||||
store_chat_data=store_chat_data,
|
||||
store_bot_data=store_bot_data)
|
||||
self._user_data = None
|
||||
self._chat_data = None
|
||||
self._bot_data = None
|
||||
|
||||
@@ -29,8 +29,6 @@ from collections import defaultdict
|
||||
|
||||
from queue import Queue, Empty
|
||||
|
||||
from future.builtins import range
|
||||
|
||||
from telegram import TelegramError, Update
|
||||
from telegram.ext.handler import Handler
|
||||
from telegram.ext.callbackcontext import CallbackContext
|
||||
@@ -38,7 +36,6 @@ from telegram.utils.deprecate import TelegramDeprecationWarning
|
||||
from telegram.utils.promise import Promise
|
||||
from telegram.ext import BasePersistence
|
||||
|
||||
logging.getLogger(__name__).addHandler(logging.NullHandler())
|
||||
DEFAULT_GROUP = 0
|
||||
|
||||
|
||||
@@ -67,7 +64,7 @@ class DispatcherHandlerStop(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class Dispatcher(object):
|
||||
class Dispatcher:
|
||||
"""This class dispatches all kinds of updates to its registered handlers.
|
||||
|
||||
Attributes:
|
||||
@@ -305,10 +302,10 @@ class Dispatcher(object):
|
||||
self.__async_queue.put(None)
|
||||
|
||||
for i, thr in enumerate(threads):
|
||||
self.logger.debug('Waiting for async thread {0}/{1} to end'.format(i + 1, total))
|
||||
self.logger.debug('Waiting for async thread {}/{} to end'.format(i + 1, total))
|
||||
thr.join()
|
||||
self.__async_threads.remove(thr)
|
||||
self.logger.debug('async thread {0}/{1} has ended'.format(i + 1, total))
|
||||
self.logger.debug('async thread {}/{} has ended'.format(i + 1, total))
|
||||
|
||||
@property
|
||||
def has_running_threads(self):
|
||||
@@ -392,7 +389,7 @@ class Dispatcher(object):
|
||||
from .conversationhandler import ConversationHandler
|
||||
|
||||
if not isinstance(handler, Handler):
|
||||
raise TypeError('handler is not an instance of {0}'.format(Handler.__name__))
|
||||
raise TypeError('handler is not an instance of {}'.format(Handler.__name__))
|
||||
if not isinstance(group, int):
|
||||
raise TypeError('group is not int')
|
||||
if isinstance(handler, ConversationHandler) and handler.persistent:
|
||||
|
||||
+306
-46
@@ -20,8 +20,8 @@
|
||||
|
||||
import re
|
||||
|
||||
from future.utils import string_types
|
||||
from abc import ABC, abstractmethod
|
||||
from threading import Lock
|
||||
|
||||
from telegram import Chat, Update, MessageEntity
|
||||
|
||||
@@ -247,7 +247,7 @@ class _DiceEmoji(BaseFilter):
|
||||
return True
|
||||
|
||||
|
||||
class Filters(object):
|
||||
class Filters:
|
||||
"""Predefined filters for use as the `filter` argument of :class:`telegram.ext.MessageHandler`.
|
||||
|
||||
Examples:
|
||||
@@ -425,7 +425,7 @@ class Filters(object):
|
||||
data_filter = True
|
||||
|
||||
def __init__(self, pattern):
|
||||
if isinstance(pattern, string_types):
|
||||
if isinstance(pattern, str):
|
||||
pattern = re.compile(pattern)
|
||||
self.pattern = pattern
|
||||
self.name = 'Filters.regex({})'.format(self.pattern)
|
||||
@@ -892,38 +892,166 @@ officedocument.wordprocessingml.document")``-
|
||||
Examples:
|
||||
``MessageHandler(Filters.user(1234), callback_method)``
|
||||
|
||||
Warning:
|
||||
:attr:`user_ids` will give a *copy* of the saved user ids as :class:`frozenset`. This
|
||||
is to ensure thread safety. To add/remove a user, you should use :meth:`add_usernames`,
|
||||
:meth:`add_user_ids`, :meth:`remove_usernames` and :meth:`remove_user_ids`. Only update
|
||||
the entire set by ``filter.user_ids/usernames = new_set``, if you are entirely sure
|
||||
that it is not causing race conditions, as this will complete replace the current set
|
||||
of allowed users.
|
||||
|
||||
Attributes:
|
||||
user_ids(set(:obj:`int`), optional): Which user ID(s) to allow through.
|
||||
usernames(set(:obj:`str`), optional): Which username(s) (without leading '@') to allow
|
||||
through.
|
||||
allow_empty(:obj:`bool`, optional): Whether updates should be processed, if no user
|
||||
is specified in :attr:`user_ids` and :attr:`usernames`.
|
||||
|
||||
Args:
|
||||
user_id(:obj:`int` | List[:obj:`int`], optional): Which user ID(s) to allow through.
|
||||
username(:obj:`str` | List[:obj:`str`], optional): Which username(s) to allow through.
|
||||
If username starts with '@' symbol, it will be ignored.
|
||||
user_id(:obj:`int` | List[:obj:`int`], optional): Which user ID(s) to allow
|
||||
through.
|
||||
username(:obj:`str` | List[:obj:`str`], optional): Which username(s) to allow
|
||||
through. Leading '@'s in usernames will be discarded.
|
||||
allow_empty(:obj:`bool`, optional): Whether updates should be processed, if no user
|
||||
is specified in :attr:`user_ids` and :attr:`usernames`. Defaults to :obj:`False`
|
||||
|
||||
Raises:
|
||||
ValueError: If chat_id and username are both present, or neither is.
|
||||
RuntimeError: If user_id and username are both present.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, user_id=None, username=None):
|
||||
if not (bool(user_id) ^ bool(username)):
|
||||
raise ValueError('One and only one of user_id or username must be used')
|
||||
if user_id is not None and isinstance(user_id, int):
|
||||
self.user_ids = [user_id]
|
||||
else:
|
||||
self.user_ids = user_id
|
||||
def __init__(self, user_id=None, username=None, allow_empty=False):
|
||||
self.allow_empty = allow_empty
|
||||
self.__lock = Lock()
|
||||
|
||||
self._user_ids = set()
|
||||
self._usernames = set()
|
||||
|
||||
self._set_user_ids(user_id)
|
||||
self._set_usernames(username)
|
||||
|
||||
@staticmethod
|
||||
def _parse_user_id(user_id):
|
||||
if user_id is None:
|
||||
return set()
|
||||
if isinstance(user_id, int):
|
||||
return {user_id}
|
||||
return set(user_id)
|
||||
|
||||
@staticmethod
|
||||
def _parse_username(username):
|
||||
if username is None:
|
||||
self.usernames = username
|
||||
elif isinstance(username, string_types):
|
||||
self.usernames = [username.replace('@', '')]
|
||||
else:
|
||||
self.usernames = [user.replace('@', '') for user in username]
|
||||
return set()
|
||||
if isinstance(username, str):
|
||||
return {username[1:] if username.startswith('@') else username}
|
||||
return {user[1:] if user.startswith('@') else user for user in username}
|
||||
|
||||
def _set_user_ids(self, user_id):
|
||||
with self.__lock:
|
||||
if user_id and self._usernames:
|
||||
raise RuntimeError("Can't set user_id in conjunction with (already set) "
|
||||
"usernames.")
|
||||
self._user_ids = self._parse_user_id(user_id)
|
||||
|
||||
def _set_usernames(self, username):
|
||||
with self.__lock:
|
||||
if username and self._user_ids:
|
||||
raise RuntimeError("Can't set username in conjunction with (already set) "
|
||||
"user_ids.")
|
||||
self._usernames = self._parse_username(username)
|
||||
|
||||
@property
|
||||
def user_ids(self):
|
||||
with self.__lock:
|
||||
return frozenset(self._user_ids)
|
||||
|
||||
@user_ids.setter
|
||||
def user_ids(self, user_id):
|
||||
self._set_user_ids(user_id)
|
||||
|
||||
@property
|
||||
def usernames(self):
|
||||
with self.__lock:
|
||||
return frozenset(self._usernames)
|
||||
|
||||
@usernames.setter
|
||||
def usernames(self, username):
|
||||
self._set_usernames(username)
|
||||
|
||||
def add_usernames(self, username):
|
||||
"""
|
||||
Add one or more users to the allowed usernames.
|
||||
|
||||
Args:
|
||||
username(:obj:`str` | List[:obj:`str`], optional): Which username(s) to allow
|
||||
through. Leading '@'s in usernames will be discarded.
|
||||
"""
|
||||
with self.__lock:
|
||||
if self._user_ids:
|
||||
raise RuntimeError("Can't set username in conjunction with (already set) "
|
||||
"user_ids.")
|
||||
|
||||
username = self._parse_username(username)
|
||||
self._usernames |= username
|
||||
|
||||
def add_user_ids(self, user_id):
|
||||
"""
|
||||
Add one or more users to the allowed user ids.
|
||||
|
||||
Args:
|
||||
user_id(:obj:`int` | List[:obj:`int`], optional): Which user ID(s) to allow
|
||||
through.
|
||||
"""
|
||||
with self.__lock:
|
||||
if self._usernames:
|
||||
raise RuntimeError("Can't set user_id in conjunction with (already set) "
|
||||
"usernames.")
|
||||
|
||||
user_id = self._parse_user_id(user_id)
|
||||
|
||||
self._user_ids |= user_id
|
||||
|
||||
def remove_usernames(self, username):
|
||||
"""
|
||||
Remove one or more users from allowed usernames.
|
||||
|
||||
Args:
|
||||
username(:obj:`str` | List[:obj:`str`], optional): Which username(s) to disallow
|
||||
through. Leading '@'s in usernames will be discarded.
|
||||
"""
|
||||
with self.__lock:
|
||||
if self._user_ids:
|
||||
raise RuntimeError("Can't set username in conjunction with (already set) "
|
||||
"user_ids.")
|
||||
|
||||
username = self._parse_username(username)
|
||||
self._usernames -= username
|
||||
|
||||
def remove_user_ids(self, user_id):
|
||||
"""
|
||||
Remove one or more users from allowed user ids.
|
||||
|
||||
Args:
|
||||
user_id(:obj:`int` | List[:obj:`int`], optional): Which user ID(s) to disallow
|
||||
through.
|
||||
"""
|
||||
with self.__lock:
|
||||
if self._usernames:
|
||||
raise RuntimeError("Can't set user_id in conjunction with (already set) "
|
||||
"usernames.")
|
||||
user_id = self._parse_user_id(user_id)
|
||||
self._user_ids -= user_id
|
||||
|
||||
def filter(self, message):
|
||||
"""""" # remove method from docs
|
||||
if self.user_ids is not None:
|
||||
return bool(message.from_user and message.from_user.id in self.user_ids)
|
||||
else:
|
||||
# self.usernames is not None
|
||||
return bool(message.from_user and message.from_user.username
|
||||
if message.from_user:
|
||||
if self.user_ids:
|
||||
return message.from_user.id in self.user_ids
|
||||
if self.usernames:
|
||||
return (message.from_user.username
|
||||
and message.from_user.username in self.usernames)
|
||||
return self.allow_empty
|
||||
return False
|
||||
|
||||
class chat(BaseFilter):
|
||||
"""Filters messages to allow only those which are from specified chat ID.
|
||||
@@ -931,37 +1059,166 @@ officedocument.wordprocessingml.document")``-
|
||||
Examples:
|
||||
``MessageHandler(Filters.chat(-1234), callback_method)``
|
||||
|
||||
Warning:
|
||||
:attr:`chat_ids` will give a *copy* of the saved chat ids as :class:`frozenset`. This
|
||||
is to ensure thread safety. To add/remove a chat, you should use :meth:`add_usernames`,
|
||||
:meth:`add_chat_ids`, :meth:`remove_usernames` and :meth:`remove_chat_ids`. Only update
|
||||
the entire set by ``filter.chat_ids/usernames = new_set``, if you are entirely sure
|
||||
that it is not causing race conditions, as this will complete replace the current set
|
||||
of allowed chats.
|
||||
|
||||
Attributes:
|
||||
chat_ids(set(:obj:`int`), optional): Which chat ID(s) to allow through.
|
||||
usernames(set(:obj:`str`), optional): Which username(s) (without leading '@') to allow
|
||||
through.
|
||||
allow_empty(:obj:`bool`, optional): Whether updates should be processed, if no chat
|
||||
is specified in :attr:`chat_ids` and :attr:`usernames`.
|
||||
|
||||
Args:
|
||||
chat_id(:obj:`int` | List[:obj:`int`], optional): Which chat ID(s) to allow through.
|
||||
username(:obj:`str` | List[:obj:`str`], optional): Which username(s) to allow through.
|
||||
If username start swith '@' symbol, it will be ignored.
|
||||
chat_id(:obj:`int` | List[:obj:`int`], optional): Which chat ID(s) to allow
|
||||
through.
|
||||
username(:obj:`str` | List[:obj:`str`], optional): Which username(s) to allow
|
||||
through. Leading '@'s in usernames will be discarded.
|
||||
allow_empty(:obj:`bool`, optional): Whether updates should be processed, if no chat
|
||||
is specified in :attr:`chat_ids` and :attr:`usernames`. Defaults to :obj:`False`
|
||||
|
||||
Raises:
|
||||
ValueError: If chat_id and username are both present, or neither is.
|
||||
RuntimeError: If chat_id and username are both present.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, chat_id=None, username=None):
|
||||
if not (bool(chat_id) ^ bool(username)):
|
||||
raise ValueError('One and only one of chat_id or username must be used')
|
||||
if chat_id is not None and isinstance(chat_id, int):
|
||||
self.chat_ids = [chat_id]
|
||||
else:
|
||||
self.chat_ids = chat_id
|
||||
def __init__(self, chat_id=None, username=None, allow_empty=False):
|
||||
self.allow_empty = allow_empty
|
||||
self.__lock = Lock()
|
||||
|
||||
self._chat_ids = set()
|
||||
self._usernames = set()
|
||||
|
||||
self._set_chat_ids(chat_id)
|
||||
self._set_usernames(username)
|
||||
|
||||
@staticmethod
|
||||
def _parse_chat_id(chat_id):
|
||||
if chat_id is None:
|
||||
return set()
|
||||
if isinstance(chat_id, int):
|
||||
return {chat_id}
|
||||
return set(chat_id)
|
||||
|
||||
@staticmethod
|
||||
def _parse_username(username):
|
||||
if username is None:
|
||||
self.usernames = username
|
||||
elif isinstance(username, string_types):
|
||||
self.usernames = [username.replace('@', '')]
|
||||
else:
|
||||
self.usernames = [chat.replace('@', '') for chat in username]
|
||||
return set()
|
||||
if isinstance(username, str):
|
||||
return {username[1:] if username.startswith('@') else username}
|
||||
return {chat[1:] if chat.startswith('@') else chat for chat in username}
|
||||
|
||||
def _set_chat_ids(self, chat_id):
|
||||
with self.__lock:
|
||||
if chat_id and self._usernames:
|
||||
raise RuntimeError("Can't set chat_id in conjunction with (already set) "
|
||||
"usernames.")
|
||||
self._chat_ids = self._parse_chat_id(chat_id)
|
||||
|
||||
def _set_usernames(self, username):
|
||||
with self.__lock:
|
||||
if username and self._chat_ids:
|
||||
raise RuntimeError("Can't set username in conjunction with (already set) "
|
||||
"chat_ids.")
|
||||
self._usernames = self._parse_username(username)
|
||||
|
||||
@property
|
||||
def chat_ids(self):
|
||||
with self.__lock:
|
||||
return frozenset(self._chat_ids)
|
||||
|
||||
@chat_ids.setter
|
||||
def chat_ids(self, chat_id):
|
||||
self._set_chat_ids(chat_id)
|
||||
|
||||
@property
|
||||
def usernames(self):
|
||||
with self.__lock:
|
||||
return frozenset(self._usernames)
|
||||
|
||||
@usernames.setter
|
||||
def usernames(self, username):
|
||||
self._set_usernames(username)
|
||||
|
||||
def add_usernames(self, username):
|
||||
"""
|
||||
Add one or more chats to the allowed usernames.
|
||||
|
||||
Args:
|
||||
username(:obj:`str` | List[:obj:`str`], optional): Which username(s) to allow
|
||||
through. Leading '@'s in usernames will be discarded.
|
||||
"""
|
||||
with self.__lock:
|
||||
if self._chat_ids:
|
||||
raise RuntimeError("Can't set username in conjunction with (already set) "
|
||||
"chat_ids.")
|
||||
|
||||
username = self._parse_username(username)
|
||||
self._usernames |= username
|
||||
|
||||
def add_chat_ids(self, chat_id):
|
||||
"""
|
||||
Add one or more chats to the allowed chat ids.
|
||||
|
||||
Args:
|
||||
chat_id(:obj:`int` | List[:obj:`int`], optional): Which chat ID(s) to allow
|
||||
through.
|
||||
"""
|
||||
with self.__lock:
|
||||
if self._usernames:
|
||||
raise RuntimeError("Can't set chat_id in conjunction with (already set) "
|
||||
"usernames.")
|
||||
|
||||
chat_id = self._parse_chat_id(chat_id)
|
||||
|
||||
self._chat_ids |= chat_id
|
||||
|
||||
def remove_usernames(self, username):
|
||||
"""
|
||||
Remove one or more chats from allowed usernames.
|
||||
|
||||
Args:
|
||||
username(:obj:`str` | List[:obj:`str`], optional): Which username(s) to disallow
|
||||
through. Leading '@'s in usernames will be discarded.
|
||||
"""
|
||||
with self.__lock:
|
||||
if self._chat_ids:
|
||||
raise RuntimeError("Can't set username in conjunction with (already set) "
|
||||
"chat_ids.")
|
||||
|
||||
username = self._parse_username(username)
|
||||
self._usernames -= username
|
||||
|
||||
def remove_chat_ids(self, chat_id):
|
||||
"""
|
||||
Remove one or more chats from allowed chat ids.
|
||||
|
||||
Args:
|
||||
chat_id(:obj:`int` | List[:obj:`int`], optional): Which chat ID(s) to disallow
|
||||
through.
|
||||
"""
|
||||
with self.__lock:
|
||||
if self._usernames:
|
||||
raise RuntimeError("Can't set chat_id in conjunction with (already set) "
|
||||
"usernames.")
|
||||
chat_id = self._parse_chat_id(chat_id)
|
||||
self._chat_ids -= chat_id
|
||||
|
||||
def filter(self, message):
|
||||
"""""" # remove method from docs
|
||||
if self.chat_ids is not None:
|
||||
return bool(message.chat_id in self.chat_ids)
|
||||
else:
|
||||
# self.usernames is not None
|
||||
return bool(message.chat.username and message.chat.username in self.usernames)
|
||||
if message.chat:
|
||||
if self.chat_ids:
|
||||
return message.chat.id in self.chat_ids
|
||||
if self.usernames:
|
||||
return (message.chat.username
|
||||
and message.chat.username in self.usernames)
|
||||
return self.allow_empty
|
||||
return False
|
||||
|
||||
class _Invoice(BaseFilter):
|
||||
name = 'Filters.invoice'
|
||||
@@ -1002,6 +1259,7 @@ officedocument.wordprocessingml.document")``-
|
||||
class _Dice(_DiceEmoji):
|
||||
dice = _DiceEmoji('🎲', 'dice')
|
||||
darts = _DiceEmoji('🎯', 'darts')
|
||||
basketball = _DiceEmoji('🏀', 'basketball')
|
||||
|
||||
dice = _Dice()
|
||||
"""Dice Messages. If an integer or a list of integers is passed, it filters messages to only
|
||||
@@ -1028,6 +1286,8 @@ officedocument.wordprocessingml.document")``-
|
||||
:attr:`Filters.dice`.
|
||||
darts: Dice messages with the emoji 🎯. Passing a list of integers is supported just as for
|
||||
:attr:`Filters.dice`.
|
||||
basketball: Dice messages with the emoji 🏀. Passing a list of integers is supported just
|
||||
as for :attr:`Filters.dice`.
|
||||
"""
|
||||
|
||||
class language(BaseFilter):
|
||||
@@ -1048,7 +1308,7 @@ officedocument.wordprocessingml.document")``-
|
||||
"""
|
||||
|
||||
def __init__(self, lang):
|
||||
if isinstance(lang, string_types):
|
||||
if isinstance(lang, str):
|
||||
self.lang = [lang]
|
||||
else:
|
||||
self.lang = lang
|
||||
|
||||
@@ -19,9 +19,8 @@
|
||||
""" This module contains the InlineQueryHandler class """
|
||||
import re
|
||||
|
||||
from future.utils import string_types
|
||||
|
||||
from telegram import Update
|
||||
|
||||
from .handler import Handler
|
||||
|
||||
|
||||
@@ -104,14 +103,14 @@ class InlineQueryHandler(Handler):
|
||||
pass_groupdict=False,
|
||||
pass_user_data=False,
|
||||
pass_chat_data=False):
|
||||
super(InlineQueryHandler, self).__init__(
|
||||
super().__init__(
|
||||
callback,
|
||||
pass_update_queue=pass_update_queue,
|
||||
pass_job_queue=pass_job_queue,
|
||||
pass_user_data=pass_user_data,
|
||||
pass_chat_data=pass_chat_data)
|
||||
|
||||
if isinstance(pattern, string_types):
|
||||
if isinstance(pattern, str):
|
||||
pattern = re.compile(pattern)
|
||||
|
||||
self.pattern = pattern
|
||||
@@ -140,8 +139,7 @@ class InlineQueryHandler(Handler):
|
||||
return True
|
||||
|
||||
def collect_optional_args(self, dispatcher, update=None, check_result=None):
|
||||
optional_args = super(InlineQueryHandler, self).collect_optional_args(dispatcher,
|
||||
update, check_result)
|
||||
optional_args = super().collect_optional_args(dispatcher, update, check_result)
|
||||
if self.pattern:
|
||||
if self.pass_groups:
|
||||
optional_args['groups'] = check_result.groups()
|
||||
|
||||
@@ -33,12 +33,12 @@ from telegram.utils.deprecate import TelegramDeprecationWarning
|
||||
from telegram.utils.helpers import to_float_timestamp
|
||||
|
||||
|
||||
class Days(object):
|
||||
class Days:
|
||||
MON, TUE, WED, THU, FRI, SAT, SUN = range(7)
|
||||
EVERY_DAY = tuple(range(7))
|
||||
|
||||
|
||||
class JobQueue(object):
|
||||
class JobQueue:
|
||||
"""This class allows you to periodically perform tasks with the bot.
|
||||
|
||||
Attributes:
|
||||
@@ -54,7 +54,7 @@ class JobQueue(object):
|
||||
warnings.warn("Passing bot to jobqueue is deprecated. Please use set_dispatcher "
|
||||
"instead!", TelegramDeprecationWarning, stacklevel=2)
|
||||
|
||||
class MockDispatcher(object):
|
||||
class MockDispatcher:
|
||||
def __init__(self):
|
||||
self.bot = bot
|
||||
self.use_context = False
|
||||
@@ -492,7 +492,7 @@ class JobQueue(object):
|
||||
return tuple(job[1] for job in self._queue.queue if job and job[1].name == name)
|
||||
|
||||
|
||||
class Job(object):
|
||||
class Job:
|
||||
"""This class encapsulates a Job.
|
||||
|
||||
Attributes:
|
||||
|
||||
@@ -117,7 +117,7 @@ class MessageHandler(Handler):
|
||||
channel_post_updates=None,
|
||||
edited_updates=None):
|
||||
|
||||
super(MessageHandler, self).__init__(
|
||||
super().__init__(
|
||||
callback,
|
||||
pass_update_queue=pass_update_queue,
|
||||
pass_job_queue=pass_job_queue,
|
||||
|
||||
@@ -23,24 +23,9 @@
|
||||
from telegram.utils import promise
|
||||
|
||||
import functools
|
||||
import sys
|
||||
import time
|
||||
import threading
|
||||
if sys.version_info.major > 2:
|
||||
import queue as q
|
||||
else:
|
||||
import Queue as q
|
||||
|
||||
# We need to count < 1s intervals, so the most accurate timer is needed
|
||||
# Starting from Python 3.3 we have time.perf_counter which is the clock
|
||||
# with the highest resolution available to the system, so let's use it there.
|
||||
# In Python 2.7, there's no perf_counter yet, so fallback on what we have:
|
||||
# on Windows, the best available is time.clock while time.time is on
|
||||
# another platforms (M. Lutz, "Learning Python," 4ed, p.630-634)
|
||||
if sys.version_info.major == 3 and sys.version_info.minor >= 3:
|
||||
curtime = time.perf_counter # pylint: disable=E1101
|
||||
else:
|
||||
curtime = time.clock if sys.platform[:3] == 'win' else time.time
|
||||
import queue as q
|
||||
|
||||
|
||||
class DelayQueueError(RuntimeError):
|
||||
@@ -95,11 +80,11 @@ class DelayQueue(threading.Thread):
|
||||
self.__exit_req = False # flag to gently exit thread
|
||||
self.__class__._instcnt += 1
|
||||
if name is None:
|
||||
name = '%s-%s' % (self.__class__.__name__, self.__class__._instcnt)
|
||||
super(DelayQueue, self).__init__(name=name)
|
||||
name = '{}-{}'.format(self.__class__.__name__, self.__class__._instcnt)
|
||||
super().__init__(name=name)
|
||||
self.daemon = False
|
||||
if autostart: # immediately start processing
|
||||
super(DelayQueue, self).start()
|
||||
super().start()
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
@@ -114,7 +99,7 @@ class DelayQueue(threading.Thread):
|
||||
if self.__exit_req:
|
||||
return # shutdown thread
|
||||
# delay routine
|
||||
now = curtime()
|
||||
now = time.perf_counter()
|
||||
t_delta = now - self.time_limit # calculate early to improve perf.
|
||||
if times and t_delta > times[-1]:
|
||||
# if last call was before the limit time-window
|
||||
@@ -146,7 +131,7 @@ class DelayQueue(threading.Thread):
|
||||
|
||||
self.__exit_req = True # gently request
|
||||
self._queue.put(None) # put something to unfreeze if frozen
|
||||
super(DelayQueue, self).join(timeout=timeout)
|
||||
super().join(timeout=timeout)
|
||||
|
||||
@staticmethod
|
||||
def _default_exception_handler(exc):
|
||||
@@ -180,7 +165,7 @@ class DelayQueue(threading.Thread):
|
||||
# msg --> group delay if group msg, else no delay --> normal msg delay --> out
|
||||
# This way OS threading scheduler cares of timings accuracy.
|
||||
# (see time.time, time.clock, time.perf_counter, time.sleep @ docs.python.org)
|
||||
class MessageQueue(object):
|
||||
class MessageQueue:
|
||||
"""
|
||||
Implements callback processing with proper delays to avoid hitting Telegram's message limits.
|
||||
Contains two ``DelayQueue``, for group and for all messages, interconnected in delay chain.
|
||||
|
||||
@@ -66,9 +66,9 @@ class PicklePersistence(BasePersistence):
|
||||
store_bot_data=True,
|
||||
single_file=True,
|
||||
on_flush=False):
|
||||
super(PicklePersistence, self).__init__(store_user_data=store_user_data,
|
||||
store_chat_data=store_chat_data,
|
||||
store_bot_data=store_bot_data)
|
||||
super().__init__(store_user_data=store_user_data,
|
||||
store_chat_data=store_chat_data,
|
||||
store_bot_data=store_bot_data)
|
||||
self.filename = filename
|
||||
self.single_file = single_file
|
||||
self.on_flush = on_flush
|
||||
|
||||
@@ -110,21 +110,20 @@ class RegexHandler(MessageHandler):
|
||||
warnings.warn('RegexHandler is deprecated. See https://git.io/fxJuV for more info',
|
||||
TelegramDeprecationWarning,
|
||||
stacklevel=2)
|
||||
super(RegexHandler, self).__init__(Filters.regex(pattern),
|
||||
callback,
|
||||
pass_update_queue=pass_update_queue,
|
||||
pass_job_queue=pass_job_queue,
|
||||
pass_user_data=pass_user_data,
|
||||
pass_chat_data=pass_chat_data,
|
||||
message_updates=message_updates,
|
||||
channel_post_updates=channel_post_updates,
|
||||
edited_updates=edited_updates)
|
||||
super().__init__(Filters.regex(pattern),
|
||||
callback,
|
||||
pass_update_queue=pass_update_queue,
|
||||
pass_job_queue=pass_job_queue,
|
||||
pass_user_data=pass_user_data,
|
||||
pass_chat_data=pass_chat_data,
|
||||
message_updates=message_updates,
|
||||
channel_post_updates=channel_post_updates,
|
||||
edited_updates=edited_updates)
|
||||
self.pass_groups = pass_groups
|
||||
self.pass_groupdict = pass_groupdict
|
||||
|
||||
def collect_optional_args(self, dispatcher, update=None, check_result=None):
|
||||
optional_args = super(RegexHandler, self).collect_optional_args(dispatcher, update,
|
||||
check_result)
|
||||
optional_args = super().collect_optional_args(dispatcher, update, check_result)
|
||||
if self.pass_groups:
|
||||
optional_args['groups'] = check_result['matches'][0].groups()
|
||||
if self.pass_groupdict:
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the StringCommandHandler class."""
|
||||
|
||||
from future.utils import string_types
|
||||
|
||||
from .handler import Handler
|
||||
|
||||
|
||||
@@ -73,7 +71,7 @@ class StringCommandHandler(Handler):
|
||||
pass_args=False,
|
||||
pass_update_queue=False,
|
||||
pass_job_queue=False):
|
||||
super(StringCommandHandler, self).__init__(
|
||||
super().__init__(
|
||||
callback,
|
||||
pass_update_queue=pass_update_queue,
|
||||
pass_job_queue=pass_job_queue)
|
||||
@@ -90,15 +88,13 @@ class StringCommandHandler(Handler):
|
||||
:obj:`bool`
|
||||
|
||||
"""
|
||||
if isinstance(update, string_types) and update.startswith('/'):
|
||||
if isinstance(update, str) and update.startswith('/'):
|
||||
args = update[1:].split(' ')
|
||||
if args[0] == self.command:
|
||||
return args[1:]
|
||||
|
||||
def collect_optional_args(self, dispatcher, update=None, check_result=None):
|
||||
optional_args = super(StringCommandHandler, self).collect_optional_args(dispatcher,
|
||||
update,
|
||||
check_result)
|
||||
optional_args = super().collect_optional_args(dispatcher, update, check_result)
|
||||
if self.pass_args:
|
||||
optional_args['args'] = check_result
|
||||
return optional_args
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
|
||||
import re
|
||||
|
||||
from future.utils import string_types
|
||||
|
||||
from .handler import Handler
|
||||
|
||||
|
||||
@@ -85,12 +83,12 @@ class StringRegexHandler(Handler):
|
||||
pass_groupdict=False,
|
||||
pass_update_queue=False,
|
||||
pass_job_queue=False):
|
||||
super(StringRegexHandler, self).__init__(
|
||||
super().__init__(
|
||||
callback,
|
||||
pass_update_queue=pass_update_queue,
|
||||
pass_job_queue=pass_job_queue)
|
||||
|
||||
if isinstance(pattern, string_types):
|
||||
if isinstance(pattern, str):
|
||||
pattern = re.compile(pattern)
|
||||
|
||||
self.pattern = pattern
|
||||
@@ -107,14 +105,13 @@ class StringRegexHandler(Handler):
|
||||
:obj:`bool`
|
||||
|
||||
"""
|
||||
if isinstance(update, string_types):
|
||||
if isinstance(update, str):
|
||||
match = re.match(self.pattern, update)
|
||||
if match:
|
||||
return match
|
||||
|
||||
def collect_optional_args(self, dispatcher, update=None, check_result=None):
|
||||
optional_args = super(StringRegexHandler, self).collect_optional_args(dispatcher,
|
||||
update, check_result)
|
||||
optional_args = super().collect_optional_args(dispatcher, update, check_result)
|
||||
if self.pattern:
|
||||
if self.pass_groups:
|
||||
optional_args['groups'] = check_result.groups()
|
||||
|
||||
@@ -65,7 +65,7 @@ class TypeHandler(Handler):
|
||||
strict=False,
|
||||
pass_update_queue=False,
|
||||
pass_job_queue=False):
|
||||
super(TypeHandler, self).__init__(
|
||||
super().__init__(
|
||||
callback,
|
||||
pass_update_queue=pass_update_queue,
|
||||
pass_job_queue=pass_job_queue)
|
||||
|
||||
+9
-10
@@ -32,10 +32,8 @@ from telegram.utils.helpers import get_signal_name
|
||||
from telegram.utils.request import Request
|
||||
from telegram.utils.webhookhandler import (WebhookServer, WebhookAppClass)
|
||||
|
||||
logging.getLogger(__name__).addHandler(logging.NullHandler())
|
||||
|
||||
|
||||
class Updater(object):
|
||||
class Updater:
|
||||
"""
|
||||
This class, which employs the :class:`telegram.ext.Dispatcher`, provides a frontend to
|
||||
:class:`telegram.Bot` to the programmer, so they can focus on coding the bot. Its purpose is to
|
||||
@@ -49,7 +47,8 @@ class Updater(object):
|
||||
|
||||
Attributes:
|
||||
bot (:class:`telegram.Bot`): The bot used with this Updater.
|
||||
user_sig_handler (:obj:`signal`): signals the updater will respond to.
|
||||
user_sig_handler (:obj:`function`): Optional. Function to be called when a signal is
|
||||
received.
|
||||
update_queue (:obj:`Queue`): Queue for the updates.
|
||||
job_queue (:class:`telegram.ext.JobQueue`): Jobqueue for the updater.
|
||||
dispatcher (:class:`telegram.ext.Dispatcher`): Dispatcher that handles the updates and
|
||||
@@ -57,7 +56,7 @@ class Updater(object):
|
||||
running (:obj:`bool`): Indicates if the updater is running.
|
||||
persistence (:class:`telegram.ext.BasePersistence`): Optional. The persistence class to
|
||||
store data that should be persistent over restarts.
|
||||
use_context (:obj:`bool`, optional): ``True`` if using context based callbacks.
|
||||
use_context (:obj:`bool`): Optional. ``True`` if using context based callbacks.
|
||||
|
||||
Args:
|
||||
token (:obj:`str`, optional): The bot's token given by the @BotFather.
|
||||
@@ -211,14 +210,14 @@ class Updater(object):
|
||||
|
||||
def _thread_wrapper(self, target, *args, **kwargs):
|
||||
thr_name = current_thread().name
|
||||
self.logger.debug('{0} - started'.format(thr_name))
|
||||
self.logger.debug('{} - started'.format(thr_name))
|
||||
try:
|
||||
target(*args, **kwargs)
|
||||
except Exception:
|
||||
self.__exception_event.set()
|
||||
self.logger.exception('unhandled exception in %s', thr_name)
|
||||
raise
|
||||
self.logger.debug('{0} - ended'.format(thr_name))
|
||||
self.logger.debug('{} - ended'.format(thr_name))
|
||||
|
||||
def start_polling(self,
|
||||
poll_interval=0.0,
|
||||
@@ -415,7 +414,7 @@ class Updater(object):
|
||||
self.logger.debug('Updater thread started (webhook)')
|
||||
use_ssl = cert is not None and key is not None
|
||||
if not url_path.startswith('/'):
|
||||
url_path = '/{0}'.format(url_path)
|
||||
url_path = '/{}'.format(url_path)
|
||||
|
||||
# Create Tornado app instance
|
||||
app = WebhookAppClass(url_path, self.bot, self.update_queue,
|
||||
@@ -544,9 +543,9 @@ class Updater(object):
|
||||
|
||||
def _join_threads(self):
|
||||
for thr in self.__threads:
|
||||
self.logger.debug('Waiting for {0} thread to end'.format(thr.name))
|
||||
self.logger.debug('Waiting for {} thread to end'.format(thr.name))
|
||||
thr.join()
|
||||
self.logger.debug('{0} thread has ended'.format(thr.name))
|
||||
self.logger.debug('{} thread has ended'.format(thr.name))
|
||||
self.__threads = []
|
||||
|
||||
def signal_handler(self, signum, frame):
|
||||
|
||||
@@ -88,7 +88,7 @@ class Animation(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(Animation, cls).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
|
||||
data['thumb'] = PhotoSize.de_json(data.get('thumb'), bot)
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ class Document(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(Document, cls).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
|
||||
data['thumb'] = PhotoSize.de_json(data.get('thumb'), bot)
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ from base64 import b64decode
|
||||
from os.path import basename
|
||||
import os
|
||||
|
||||
from future.backports.urllib import parse as urllib_parse
|
||||
import urllib.parse as urllib_parse
|
||||
|
||||
from telegram import TelegramObject
|
||||
from telegram.passport.credentials import decrypt
|
||||
|
||||
@@ -29,7 +29,7 @@ from telegram import TelegramError
|
||||
DEFAULT_MIME_TYPE = 'application/octet-stream'
|
||||
|
||||
|
||||
class InputFile(object):
|
||||
class InputFile:
|
||||
"""This object represents a Telegram InputFile.
|
||||
|
||||
Attributes:
|
||||
@@ -55,11 +55,7 @@ class InputFile(object):
|
||||
|
||||
if filename:
|
||||
self.filename = filename
|
||||
elif (hasattr(obj, 'name')
|
||||
and not isinstance(obj.name, int) # py3
|
||||
and obj.name != '<fdopen>'): # py2
|
||||
# on py2.7, pylint fails to understand this properly
|
||||
# pylint: disable=E1101
|
||||
elif (hasattr(obj, 'name') and not isinstance(obj.name, int)):
|
||||
self.filename = os.path.basename(obj.name)
|
||||
|
||||
try:
|
||||
|
||||
@@ -38,33 +38,25 @@ class InputMediaAnimation(InputMedia):
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): ``animation``.
|
||||
media (:obj:`str` | `filelike object` | :class:`telegram.Animation`): Animation to
|
||||
send. Pass a file_id as String to send an animation that exists on the Telegram
|
||||
servers (recommended), pass an HTTP URL as a String for Telegram to get an
|
||||
animation from the Internet, or upload a new animation using multipart/form-data.
|
||||
Lastly you can pass an existing :class:`telegram.Animation` object to send.
|
||||
thumb (`filelike object`): Optional. Thumbnail of the
|
||||
file sent. The thumbnail should be in JPEG format and less than 200 kB in size.
|
||||
A thumbnail's width and height should not exceed 320. Ignored if the file is not
|
||||
is passed as a string or file_id.
|
||||
caption (:obj:`str`): Optional. Caption of the animation to be sent, 0-1024 characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. Send Markdown or HTML, if you want Telegram apps to show
|
||||
bold, italic, fixed-width text or inline URLs in the media caption. See the constants
|
||||
in :class:`telegram.ParseMode` for the available modes.
|
||||
media (:obj:`str` | :class:`telegram.InputFile`): Animation to send.
|
||||
caption (:obj:`str`): Optional. Caption of the document to be sent.
|
||||
parse_mode (:obj:`str`): Optional. The parse mode to use for text formatting.
|
||||
thumb (:class:`telegram.InputFile`): Optional. Thumbnail of the file to send.
|
||||
width (:obj:`int`): Optional. Animation width.
|
||||
height (:obj:`int`): Optional. Animation height.
|
||||
duration (:obj:`int`): Optional. Animation duration.
|
||||
|
||||
|
||||
Args:
|
||||
media (:obj:`str`): File to send. Pass a file_id to send a file that exists on the Telegram
|
||||
servers (recommended), pass an HTTP URL for Telegram to get a file from the Internet.
|
||||
Lastly you can pass an existing :class:`telegram.Animation` object to send.
|
||||
thumb (`filelike object`, optional): Thumbnail of the
|
||||
file sent. The thumbnail should be in JPEG format and less than 200 kB in size.
|
||||
A thumbnail's width and height should not exceed 320. Ignored if the file is not
|
||||
is passed as a string or file_id.
|
||||
media (:obj:`str` | `filelike object` | :class:`telegram.Animation`): File to send. Pass a
|
||||
file_id to send a file that exists on the Telegram servers (recommended), pass an HTTP
|
||||
URL for Telegram to get a file from the Internet. Lastly you can pass an existing
|
||||
:class:`telegram.Animation` object to send.
|
||||
thumb (`filelike object`, optional): Thumbnail of the file sent; can be ignored if
|
||||
thumbnail generation for the file is supported server-side. The thumbnail should be
|
||||
in JPEG format and less than 200 kB in size. A thumbnail's width and height should
|
||||
not exceed 320. Ignored if the file is not uploaded using multipart/form-data.
|
||||
Thumbnails can't be reused and can be only uploaded as a new file.
|
||||
caption (:obj:`str`, optional): Caption of the animation to be sent, 0-1024 characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show
|
||||
@@ -121,21 +113,15 @@ class InputMediaPhoto(InputMedia):
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): ``photo``.
|
||||
media (:obj:`str` | `filelike object` | :class:`telegram.PhotoSize`): Photo to send.
|
||||
Pass a file_id as String to send a photo that exists on the Telegram servers
|
||||
(recommended), pass an HTTP URL as a String for Telegram to get a photo from the
|
||||
Internet, or upload a new photo using multipart/form-data. Lastly you can pass
|
||||
an existing :class:`telegram.PhotoSize` object to send.
|
||||
caption (:obj:`str`): Optional. Caption of the photo to be sent, 0-1024 characters after
|
||||
entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. Send Markdown or HTML, if you want Telegram apps to show
|
||||
bold, italic, fixed-width text or inline URLs in the media caption. See the constants
|
||||
in :class:`telegram.ParseMode` for the available modes.
|
||||
media (:obj:`str` | :class:`telegram.InputFile`): Photo to send.
|
||||
caption (:obj:`str`): Optional. Caption of the document to be sent.
|
||||
parse_mode (:obj:`str`): Optional. The parse mode to use for text formatting.
|
||||
|
||||
Args:
|
||||
media (:obj:`str`): File to send. Pass a file_id to send a file that exists on the
|
||||
Telegram servers (recommended), pass an HTTP URL for Telegram to get a file from the
|
||||
Internet. Lastly you can pass an existing :class:`telegram.PhotoSize` object to send.
|
||||
media (:obj:`str` | `filelike object` | :class:`telegram.PhotoSize`): File to send. Pass a
|
||||
file_id to send a file that exists on the Telegram servers (recommended), pass an HTTP
|
||||
URL for Telegram to get a file from the Internet. Lastly you can pass an existing
|
||||
:class:`telegram.PhotoSize` object to send.
|
||||
caption (:obj:`str`, optional ): Caption of the photo to be sent, 0-1024 characters after
|
||||
entities parsing.
|
||||
parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show
|
||||
@@ -163,30 +149,21 @@ class InputMediaVideo(InputMedia):
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): ``video``.
|
||||
media (:obj:`str` | `filelike object` | :class:`telegram.Video`): Video file to send.
|
||||
Pass a file_id as String to send an video file that exists on the Telegram servers
|
||||
(recommended), pass an HTTP URL as a String for Telegram to get an video file from
|
||||
the Internet, or upload a new one using multipart/form-data. Lastly you can pass
|
||||
an existing :class:`telegram.Video` object to send.
|
||||
caption (:obj:`str`): Optional. Caption of the video to be sent, 0-1024 characters after
|
||||
entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. Send Markdown or HTML, if you want Telegram apps to show
|
||||
bold, italic, fixed-width text or inline URLs in the media caption. See the constants
|
||||
in :class:`telegram.ParseMode` for the available modes.
|
||||
media (:obj:`str` | :class:`telegram.InputFile`): Video file to send.
|
||||
caption (:obj:`str`): Optional. Caption of the document to be sent.
|
||||
parse_mode (:obj:`str`): Optional. The parse mode to use for text formatting.
|
||||
width (:obj:`int`): Optional. Video width.
|
||||
height (:obj:`int`): Optional. Video height.
|
||||
duration (:obj:`int`): Optional. Video duration.
|
||||
supports_streaming (:obj:`bool`): Optional. Pass True, if the uploaded video is suitable
|
||||
for streaming.
|
||||
thumb (`filelike object`): Optional. Thumbnail of the
|
||||
file sent. The thumbnail should be in JPEG format and less than 200 kB in size.
|
||||
A thumbnail's width and height should not exceed 320. Ignored if the file is not
|
||||
is passed as a string or file_id.
|
||||
thumb (:class:`telegram.InputFile`): Optional. Thumbnail of the file to send.
|
||||
|
||||
Args:
|
||||
media (:obj:`str`): File to send. Pass a file_id to send a file that exists on the Telegram
|
||||
servers (recommended), pass an HTTP URL for Telegram to get a file from the Internet.
|
||||
Lastly you can pass an existing :class:`telegram.Video` object to send.
|
||||
media (:obj:`str` | `filelike object` | :class:`telegram.Video`): File to send. Pass a
|
||||
file_id to send a file that exists on the Telegram servers (recommended), pass an HTTP
|
||||
URL for Telegram to get a file from the Internet. Lastly you can pass an existing
|
||||
:class:`telegram.Video` object to send.
|
||||
caption (:obj:`str`, optional): Caption of the video to be sent, 0-1024 characters after
|
||||
entities parsing.
|
||||
parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show
|
||||
@@ -197,10 +174,11 @@ class InputMediaVideo(InputMedia):
|
||||
duration (:obj:`int`, optional): Video duration.
|
||||
supports_streaming (:obj:`bool`, optional): Pass True, if the uploaded video is suitable
|
||||
for streaming.
|
||||
thumb (`filelike object`, optional): Thumbnail of the
|
||||
file sent. The thumbnail should be in JPEG format and less than 200 kB in size.
|
||||
A thumbnail's width and height should not exceed 320. Ignored if the file is not
|
||||
is passed as a string or file_id.
|
||||
thumb (`filelike object`, optional): Thumbnail of the file sent; can be ignored if
|
||||
thumbnail generation for the file is supported server-side. The thumbnail should be
|
||||
in JPEG format and less than 200 kB in size. A thumbnail's width and height should
|
||||
not exceed 320. Ignored if the file is not uploaded using multipart/form-data.
|
||||
Thumbnails can't be reused and can be only uploaded as a new file.
|
||||
|
||||
Note:
|
||||
When using a :class:`telegram.Video` for the :attr:`media` attribute. It will take the
|
||||
@@ -245,29 +223,20 @@ class InputMediaAudio(InputMedia):
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): ``audio``.
|
||||
media (:obj:`str` | `filelike object` | :class:`telegram.Audio`): Audio file to send.
|
||||
Pass a file_id as String to send an audio file that exists on the Telegram servers
|
||||
(recommended), pass an HTTP URL as a String for Telegram to get an audio file from
|
||||
the Internet, or upload a new one using multipart/form-data. Lastly you can pass
|
||||
an existing :class:`telegram.Audio` object to send.
|
||||
caption (:obj:`str`): Optional. Caption of the audio to be sent, 0-1024 characters after
|
||||
entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. Send Markdown or HTML, if you want Telegram apps to show
|
||||
bold, italic, fixed-width text or inline URLs in the media caption. See the constants
|
||||
in :class:`telegram.ParseMode` for the available modes.
|
||||
media (:obj:`str` | :class:`telegram.InputFile`): Audio file to send.
|
||||
caption (:obj:`str`): Optional. Caption of the document to be sent.
|
||||
parse_mode (:obj:`str`): Optional. The parse mode to use for text formatting.
|
||||
duration (:obj:`int`): Duration of the audio in seconds.
|
||||
performer (:obj:`str`): Optional. Performer of the audio as defined by sender or by audio
|
||||
tags.
|
||||
title (:obj:`str`): Optional. Title of the audio as defined by sender or by audio tags.
|
||||
thumb (`filelike object`): Optional. Thumbnail of the
|
||||
file sent. The thumbnail should be in JPEG format and less than 200 kB in size.
|
||||
A thumbnail's width and height should not exceed 320. Ignored if the file is not
|
||||
is passed as a string or file_id.
|
||||
thumb (:class:`telegram.InputFile`): Optional. Thumbnail of the file to send.
|
||||
|
||||
Args:
|
||||
media (:obj:`str`): File to send. Pass a file_id to send a file that exists on the Telegram
|
||||
servers (recommended), pass an HTTP URL for Telegram to get a file from the Internet.
|
||||
Lastly you can pass an existing :class:`telegram.Document` object to send.
|
||||
media (:obj:`str` | `filelike object` | :class:`telegram.Audio`): File to send. Pass a
|
||||
file_id to send a file that exists on the Telegram servers (recommended), pass an HTTP
|
||||
URL for Telegram to get a file from the Internet. Lastly you can pass an existing
|
||||
:class:`telegram.Document` object to send.
|
||||
caption (:obj:`str`, optional): Caption of the audio to be sent, 0-1024 characters after
|
||||
entities parsing.
|
||||
parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show
|
||||
@@ -277,10 +246,11 @@ class InputMediaAudio(InputMedia):
|
||||
performer (:obj:`str`, optional): Performer of the audio as defined by sender or by audio
|
||||
tags.
|
||||
title (:obj:`str`, optional): Title of the audio as defined by sender or by audio tags.
|
||||
thumb (`filelike object`, optional): Thumbnail of the
|
||||
file sent. The thumbnail should be in JPEG format and less than 200 kB in size.
|
||||
A thumbnail's width and height should not exceed 320. Ignored if the file is not
|
||||
is passed as a string or file_id.
|
||||
thumb (`filelike object`, optional): Thumbnail of the file sent; can be ignored if
|
||||
thumbnail generation for the file is supported server-side. The thumbnail should be
|
||||
in JPEG format and less than 200 kB in size. A thumbnail's width and height should
|
||||
not exceed 320. Ignored if the file is not uploaded using multipart/form-data.
|
||||
Thumbnails can't be reused and can be only uploaded as a new file.
|
||||
|
||||
Note:
|
||||
When using a :class:`telegram.Audio` for the :attr:`media` attribute. It will take the
|
||||
@@ -323,34 +293,26 @@ class InputMediaDocument(InputMedia):
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): ``document``.
|
||||
media (:obj:`str` | `filelike object` | :class:`telegram.Document`): File to send.
|
||||
Pass a file_id as String to send a file that exists on the Telegram servers
|
||||
(recommended), pass an HTTP URL as a String for Telegram to get a file from the
|
||||
Internet, or upload a new one using multipart/form-data. Lastly you can pass
|
||||
an existing :class:`telegram.Document` object to send.
|
||||
caption (:obj:`str`): Optional. Caption of the document to be sent, 0-1024 characters after
|
||||
entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. Send Markdown or HTML, if you want Telegram apps to show
|
||||
bold, italic, fixed-width text or inline URLs in the media caption. See the constants
|
||||
in :class:`telegram.ParseMode` for the available modes.
|
||||
thumb (`filelike object`): Optional. Thumbnail of the
|
||||
file sent. The thumbnail should be in JPEG format and less than 200 kB in size.
|
||||
A thumbnail's width and height should not exceed 320. Ignored if the file is not
|
||||
is passed as a string or file_id.
|
||||
media (:obj:`str` | :class:`telegram.InputFile`): File to send.
|
||||
caption (:obj:`str`): Optional. Caption of the document to be sent.
|
||||
parse_mode (:obj:`str`): Optional. The parse mode to use for text formatting.
|
||||
thumb (:class:`telegram.InputFile`): Optional. Thumbnail of the file to send.
|
||||
|
||||
Args:
|
||||
media (:obj:`str`): File to send. Pass a file_id to send a file that exists on the Telegram
|
||||
servers (recommended), pass an HTTP URL for Telegram to get a file from the Internet.
|
||||
Lastly you can pass an existing :class:`telegram.Document` object to send.
|
||||
media (:obj:`str` | `filelike object` | :class:`telegram.Document`): File to send. Pass a
|
||||
file_id to send a file that exists on the Telegram servers (recommended), pass an HTTP
|
||||
URL for Telegram to get a file from the Internet. Lastly you can pass an existing
|
||||
:class:`telegram.Document` object to send.
|
||||
caption (:obj:`str`, optional): Caption of the document to be sent, 0-1024 characters after
|
||||
entities parsing.
|
||||
parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show
|
||||
bold, italic, fixed-width text or inline URLs in the media caption. See the constants
|
||||
in :class:`telegram.ParseMode` for the available modes.
|
||||
thumb (`filelike object`, optional): Thumbnail of the
|
||||
file sent. The thumbnail should be in JPEG format and less than 200 kB in size.
|
||||
A thumbnail's width and height should not exceed 320. Ignored if the file is not
|
||||
is passed as a string or file_id.
|
||||
thumb (`filelike object`, optional): Thumbnail of the file sent; can be ignored if
|
||||
thumbnail generation for the file is supported server-side. The thumbnail should be
|
||||
in JPEG format and less than 200 kB in size. A thumbnail's width and height should
|
||||
not exceed 320. Ignored if the file is not uploaded using multipart/form-data.
|
||||
Thumbnails can't be reused and can be only uploaded as a new file.
|
||||
"""
|
||||
|
||||
def __init__(self, media, thumb=None, caption=None, parse_mode=DEFAULT_NONE):
|
||||
|
||||
@@ -96,7 +96,7 @@ class Sticker(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(Sticker, cls).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
|
||||
data['thumb'] = PhotoSize.de_json(data.get('thumb'), bot)
|
||||
data['mask_position'] = MaskPosition.de_json(data.get('mask_position'), bot)
|
||||
@@ -164,20 +164,20 @@ class StickerSet(TelegramObject):
|
||||
|
||||
self._id_attrs = (self.name,)
|
||||
|
||||
@staticmethod
|
||||
def de_json(data, bot):
|
||||
@classmethod
|
||||
def de_json(cls, data, bot):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(StickerSet, StickerSet).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
|
||||
data['thumb'] = PhotoSize.de_json(data.get('thumb'), bot)
|
||||
data['stickers'] = Sticker.de_list(data.get('stickers'), bot)
|
||||
|
||||
return StickerSet(bot=bot, **data)
|
||||
return cls(bot=bot, **data)
|
||||
|
||||
def to_dict(self):
|
||||
data = super(StickerSet, self).to_dict()
|
||||
data = super().to_dict()
|
||||
|
||||
data['stickers'] = [s.to_dict() for s in data.get('stickers')]
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ class Venue(TelegramObject):
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data, bot):
|
||||
data = super(Venue, cls).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
@@ -83,7 +83,7 @@ class Video(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(Video, cls).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
|
||||
data['thumb'] = PhotoSize.de_json(data.get('thumb'), bot)
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ class VideoNote(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(VideoNote, cls).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
|
||||
data['thumb'] = PhotoSize.de_json(data.get('thumb'), bot)
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ class Voice(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(Voice, cls).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
|
||||
return cls(bot=bot, **data)
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ class Game(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(Game, cls).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
|
||||
data['photo'] = PhotoSize.de_list(data.get('photo'), bot)
|
||||
data['text_entities'] = MessageEntity.de_list(data.get('text_entities'), bot)
|
||||
@@ -86,7 +86,7 @@ class Game(TelegramObject):
|
||||
return cls(**data)
|
||||
|
||||
def to_dict(self):
|
||||
data = super(Game, self).to_dict()
|
||||
data = super().to_dict()
|
||||
|
||||
data['photo'] = [p.to_dict() for p in self.photo]
|
||||
if self.text_entities:
|
||||
|
||||
@@ -46,7 +46,7 @@ class GameHighScore(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(GameHighScore, cls).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
|
||||
data['user'] = User.de_json(data.get('user'), bot)
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ class InlineKeyboardMarkup(ReplyMarkup):
|
||||
self.inline_keyboard = inline_keyboard
|
||||
|
||||
def to_dict(self):
|
||||
data = super(InlineKeyboardMarkup, self).to_dict()
|
||||
data = super().to_dict()
|
||||
|
||||
data['inline_keyboard'] = []
|
||||
for inline_keyboard in self.inline_keyboard:
|
||||
|
||||
@@ -65,7 +65,7 @@ class InlineQuery(TelegramObject):
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data, bot):
|
||||
data = super(InlineQuery, cls).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
@@ -72,7 +72,7 @@ class InlineQueryResultArticle(InlineQueryResult):
|
||||
**kwargs):
|
||||
|
||||
# Required
|
||||
super(InlineQueryResultArticle, self).__init__('article', id)
|
||||
super().__init__('article', id)
|
||||
self.title = title
|
||||
self.input_message_content = input_message_content
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ class InlineQueryResultAudio(InlineQueryResult):
|
||||
**kwargs):
|
||||
|
||||
# Required
|
||||
super(InlineQueryResultAudio, self).__init__('audio', id)
|
||||
super().__init__('audio', id)
|
||||
self.audio_url = audio_url
|
||||
self.title = title
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ class InlineQueryResultCachedAudio(InlineQueryResult):
|
||||
parse_mode=DEFAULT_NONE,
|
||||
**kwargs):
|
||||
# Required
|
||||
super(InlineQueryResultCachedAudio, self).__init__('audio', id)
|
||||
super().__init__('audio', id)
|
||||
self.audio_file_id = audio_file_id
|
||||
|
||||
# Optionals
|
||||
|
||||
@@ -73,7 +73,7 @@ class InlineQueryResultCachedDocument(InlineQueryResult):
|
||||
parse_mode=DEFAULT_NONE,
|
||||
**kwargs):
|
||||
# Required
|
||||
super(InlineQueryResultCachedDocument, self).__init__('document', id)
|
||||
super().__init__('document', id)
|
||||
self.title = title
|
||||
self.document_file_id = document_file_id
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ class InlineQueryResultCachedGif(InlineQueryResult):
|
||||
parse_mode=DEFAULT_NONE,
|
||||
**kwargs):
|
||||
# Required
|
||||
super(InlineQueryResultCachedGif, self).__init__('gif', id)
|
||||
super().__init__('gif', id)
|
||||
self.gif_file_id = gif_file_id
|
||||
|
||||
# Optionals
|
||||
|
||||
@@ -71,7 +71,7 @@ class InlineQueryResultCachedMpeg4Gif(InlineQueryResult):
|
||||
parse_mode=DEFAULT_NONE,
|
||||
**kwargs):
|
||||
# Required
|
||||
super(InlineQueryResultCachedMpeg4Gif, self).__init__('mpeg4_gif', id)
|
||||
super().__init__('mpeg4_gif', id)
|
||||
self.mpeg4_file_id = mpeg4_file_id
|
||||
|
||||
# Optionals
|
||||
|
||||
@@ -74,7 +74,7 @@ class InlineQueryResultCachedPhoto(InlineQueryResult):
|
||||
parse_mode=DEFAULT_NONE,
|
||||
**kwargs):
|
||||
# Required
|
||||
super(InlineQueryResultCachedPhoto, self).__init__('photo', id)
|
||||
super().__init__('photo', id)
|
||||
self.photo_file_id = photo_file_id
|
||||
|
||||
# Optionals
|
||||
|
||||
@@ -54,7 +54,7 @@ class InlineQueryResultCachedSticker(InlineQueryResult):
|
||||
input_message_content=None,
|
||||
**kwargs):
|
||||
# Required
|
||||
super(InlineQueryResultCachedSticker, self).__init__('sticker', id)
|
||||
super().__init__('sticker', id)
|
||||
self.sticker_file_id = sticker_file_id
|
||||
|
||||
# Optionals
|
||||
|
||||
@@ -74,7 +74,7 @@ class InlineQueryResultCachedVideo(InlineQueryResult):
|
||||
parse_mode=DEFAULT_NONE,
|
||||
**kwargs):
|
||||
# Required
|
||||
super(InlineQueryResultCachedVideo, self).__init__('video', id)
|
||||
super().__init__('video', id)
|
||||
self.video_file_id = video_file_id
|
||||
self.title = title
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ class InlineQueryResultCachedVoice(InlineQueryResult):
|
||||
parse_mode=DEFAULT_NONE,
|
||||
**kwargs):
|
||||
# Required
|
||||
super(InlineQueryResultCachedVoice, self).__init__('voice', id)
|
||||
super().__init__('voice', id)
|
||||
self.voice_file_id = voice_file_id
|
||||
self.title = title
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ class InlineQueryResultContact(InlineQueryResult):
|
||||
vcard=None,
|
||||
**kwargs):
|
||||
# Required
|
||||
super(InlineQueryResultContact, self).__init__('contact', id)
|
||||
super().__init__('contact', id)
|
||||
self.phone_number = phone_number
|
||||
self.first_name = first_name
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ class InlineQueryResultDocument(InlineQueryResult):
|
||||
parse_mode=DEFAULT_NONE,
|
||||
**kwargs):
|
||||
# Required
|
||||
super(InlineQueryResultDocument, self).__init__('document', id)
|
||||
super().__init__('document', id)
|
||||
self.document_url = document_url
|
||||
self.title = title
|
||||
self.mime_type = mime_type
|
||||
|
||||
@@ -42,7 +42,7 @@ class InlineQueryResultGame(InlineQueryResult):
|
||||
|
||||
def __init__(self, id, game_short_name, reply_markup=None, **kwargs):
|
||||
# Required
|
||||
super(InlineQueryResultGame, self).__init__('game', id)
|
||||
super().__init__('game', id)
|
||||
self.id = id
|
||||
self.game_short_name = game_short_name
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ class InlineQueryResultGif(InlineQueryResult):
|
||||
gif_height (:obj:`int`): Optional. Height of the GIF.
|
||||
gif_duration (:obj:`int`): Optional. Duration of the GIF.
|
||||
thumb_url (:obj:`str`): URL of the static thumbnail for the result (jpeg or gif).
|
||||
thumb_mime_type (:obj:`str`): Optional. MIME type of the thumbnail.
|
||||
title (:obj:`str`): Optional. Title for the result.
|
||||
caption (:obj:`str`): Optional. Caption of the GIF file to be sent, 0-1024 characters
|
||||
after entities parsing.
|
||||
@@ -54,6 +55,8 @@ class InlineQueryResultGif(InlineQueryResult):
|
||||
gif_height (:obj:`int`, optional): Height of the GIF.
|
||||
gif_duration (:obj:`int`, optional): Duration of the GIF
|
||||
thumb_url (:obj:`str`): URL of the static thumbnail for the result (jpeg or gif).
|
||||
thumb_mime_type (:obj:`str`): Optional. MIME type of the thumbnail, must be one of
|
||||
“image/jpeg”, “image/gif”, or “video/mp4”. Defaults to “image/jpeg”.
|
||||
title (:obj:`str`, optional): Title for the result.
|
||||
caption (:obj:`str`, optional): Caption of the GIF file to be sent, 0-1024 characters
|
||||
after entities parsing.
|
||||
@@ -80,10 +83,11 @@ class InlineQueryResultGif(InlineQueryResult):
|
||||
input_message_content=None,
|
||||
gif_duration=None,
|
||||
parse_mode=DEFAULT_NONE,
|
||||
thumb_mime_type=None,
|
||||
**kwargs):
|
||||
|
||||
# Required
|
||||
super(InlineQueryResultGif, self).__init__('gif', id)
|
||||
super().__init__('gif', id)
|
||||
self.gif_url = gif_url
|
||||
self.thumb_url = thumb_url
|
||||
|
||||
@@ -96,3 +100,4 @@ class InlineQueryResultGif(InlineQueryResult):
|
||||
self.parse_mode = parse_mode
|
||||
self.reply_markup = reply_markup
|
||||
self.input_message_content = input_message_content
|
||||
self.thumb_mime_type = thumb_mime_type
|
||||
|
||||
@@ -74,7 +74,7 @@ class InlineQueryResultLocation(InlineQueryResult):
|
||||
thumb_height=None,
|
||||
**kwargs):
|
||||
# Required
|
||||
super(InlineQueryResultLocation, self).__init__('location', id)
|
||||
super().__init__('location', id)
|
||||
self.latitude = latitude
|
||||
self.longitude = longitude
|
||||
self.title = title
|
||||
|
||||
@@ -37,6 +37,7 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult):
|
||||
mpeg4_height (:obj:`int`): Optional. Video height.
|
||||
mpeg4_duration (:obj:`int`): Optional. Video duration.
|
||||
thumb_url (:obj:`str`): URL of the static thumbnail (jpeg or gif) for the result.
|
||||
thumb_mime_type (:obj:`str`): Optional. MIME type of the thumbnail.
|
||||
title (:obj:`str`): Optional. Title for the result.
|
||||
caption (:obj:`str`): Optional. Caption of the MPEG-4 file to be sent, 0-1024 characters
|
||||
after entities parsing.
|
||||
@@ -55,6 +56,8 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult):
|
||||
mpeg4_height (:obj:`int`, optional): Video height.
|
||||
mpeg4_duration (:obj:`int`, optional): Video duration.
|
||||
thumb_url (:obj:`str`): URL of the static thumbnail (jpeg or gif) for the result.
|
||||
thumb_mime_type (:obj:`str`): Optional. MIME type of the thumbnail, must be one of
|
||||
“image/jpeg”, “image/gif”, or “video/mp4”. Defaults to “image/jpeg”.
|
||||
title (:obj:`str`, optional): Title for the result.
|
||||
caption (:obj:`str`, optional): Caption of the MPEG-4 file to be sent, 0-1024 characters
|
||||
after entities parsing.
|
||||
@@ -81,10 +84,11 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult):
|
||||
input_message_content=None,
|
||||
mpeg4_duration=None,
|
||||
parse_mode=DEFAULT_NONE,
|
||||
thumb_mime_type=None,
|
||||
**kwargs):
|
||||
|
||||
# Required
|
||||
super(InlineQueryResultMpeg4Gif, self).__init__('mpeg4_gif', id)
|
||||
super().__init__('mpeg4_gif', id)
|
||||
self.mpeg4_url = mpeg4_url
|
||||
self.thumb_url = thumb_url
|
||||
|
||||
@@ -97,3 +101,4 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult):
|
||||
self.parse_mode = parse_mode
|
||||
self.reply_markup = reply_markup
|
||||
self.input_message_content = input_message_content
|
||||
self.thumb_mime_type = thumb_mime_type
|
||||
|
||||
@@ -84,7 +84,7 @@ class InlineQueryResultPhoto(InlineQueryResult):
|
||||
parse_mode=DEFAULT_NONE,
|
||||
**kwargs):
|
||||
# Required
|
||||
super(InlineQueryResultPhoto, self).__init__('photo', id)
|
||||
super().__init__('photo', id)
|
||||
self.photo_url = photo_url
|
||||
self.thumb_url = thumb_url
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ class InlineQueryResultVenue(InlineQueryResult):
|
||||
**kwargs):
|
||||
|
||||
# Required
|
||||
super(InlineQueryResultVenue, self).__init__('venue', id)
|
||||
super().__init__('venue', id)
|
||||
self.latitude = latitude
|
||||
self.longitude = longitude
|
||||
self.title = title
|
||||
|
||||
@@ -97,7 +97,7 @@ class InlineQueryResultVideo(InlineQueryResult):
|
||||
**kwargs):
|
||||
|
||||
# Required
|
||||
super(InlineQueryResultVideo, self).__init__('video', id)
|
||||
super().__init__('video', id)
|
||||
self.video_url = video_url
|
||||
self.mime_type = mime_type
|
||||
self.thumb_url = thumb_url
|
||||
|
||||
@@ -73,7 +73,7 @@ class InlineQueryResultVoice(InlineQueryResult):
|
||||
**kwargs):
|
||||
|
||||
# Required
|
||||
super(InlineQueryResultVoice, self).__init__('voice', id)
|
||||
super().__init__('voice', id)
|
||||
self.voice_url = voice_url
|
||||
self.title = title
|
||||
|
||||
|
||||
+28
-23
@@ -107,6 +107,7 @@ class Message(TelegramObject):
|
||||
poll (:class:`telegram.Poll`): Optional. Message is a native poll,
|
||||
information about the poll.
|
||||
dice (:class:`telegram.Dice`): Optional. Message is a dice.
|
||||
via_bot (:class:`telegram.User`): Optional. Bot through which the message was sent.
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached
|
||||
to the message.
|
||||
bot (:class:`telegram.Bot`): Optional. The Bot to use for instance methods.
|
||||
@@ -216,6 +217,7 @@ class Message(TelegramObject):
|
||||
poll (:class:`telegram.Poll`, optional): Message is a native poll,
|
||||
information about the poll.
|
||||
dice (:class:`telegram.Dice`, optional): Message is a dice with random value from 1 to 6.
|
||||
via_bot (:class:`telegram.User`, optional): Message was sent through an inline bot.
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached
|
||||
to the message. login_url buttons are represented as ordinary url buttons.
|
||||
default_quote (:obj:`bool`, optional): Default setting for the `quote` parameter of the
|
||||
@@ -285,6 +287,7 @@ class Message(TelegramObject):
|
||||
bot=None,
|
||||
default_quote=None,
|
||||
dice=None,
|
||||
via_bot=None,
|
||||
**kwargs):
|
||||
# Required
|
||||
self.message_id = int(message_id)
|
||||
@@ -335,6 +338,7 @@ class Message(TelegramObject):
|
||||
self.passport_data = passport_data
|
||||
self.poll = poll
|
||||
self.dice = dice
|
||||
self.via_bot = via_bot
|
||||
self.reply_markup = reply_markup
|
||||
self.bot = bot
|
||||
self.default_quote = default_quote
|
||||
@@ -364,7 +368,7 @@ class Message(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(Message, cls).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
|
||||
data['from_user'] = User.de_json(data.get('from'), bot)
|
||||
data['date'] = from_timestamp(data['date'])
|
||||
@@ -409,6 +413,7 @@ class Message(TelegramObject):
|
||||
data['passport_data'] = PassportData.de_json(data.get('passport_data'), bot)
|
||||
data['poll'] = Poll.de_json(data.get('poll'), bot)
|
||||
data['dice'] = Dice.de_json(data.get('dice'), bot)
|
||||
data['via_bot'] = User.de_json(data.get('via_bot'), bot)
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(data.get('reply_markup'), bot)
|
||||
|
||||
return cls(bot=bot, **data)
|
||||
@@ -452,7 +457,7 @@ class Message(TelegramObject):
|
||||
return self.chat.id
|
||||
|
||||
def to_dict(self):
|
||||
data = super(Message, self).to_dict()
|
||||
data = super().to_dict()
|
||||
|
||||
# Required
|
||||
data['date'] = to_timestamp(self.date)
|
||||
@@ -859,9 +864,9 @@ class Message(TelegramObject):
|
||||
**kwargs)
|
||||
|
||||
Note:
|
||||
You can only edit messages that the bot sent itself,
|
||||
therefore this method can only be used on the
|
||||
return value of the ``bot.send_*`` family of methods.
|
||||
You can only edit messages that the bot sent itself (i.e. of the ``bot.send_*`` family
|
||||
of methods) or channel posts, if the bot is an admin in that channel. However, this
|
||||
behaviour is undocumented and might be changed by Telegram.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the edited message.
|
||||
@@ -879,9 +884,9 @@ class Message(TelegramObject):
|
||||
**kwargs)
|
||||
|
||||
Note:
|
||||
You can only edit messages that the bot sent itself,
|
||||
therefore this method can only be used on the
|
||||
return value of the ``bot.send_*`` family of methods.
|
||||
You can only edit messages that the bot sent itself (i.e. of the ``bot.send_*`` family
|
||||
of methods) or channel posts, if the bot is an admin in that channel. However, this
|
||||
behaviour is undocumented and might be changed by Telegram.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the edited message.
|
||||
@@ -893,21 +898,21 @@ class Message(TelegramObject):
|
||||
def edit_media(self, media, *args, **kwargs):
|
||||
"""Shortcut for::
|
||||
|
||||
bot.edit_message_media(chat_id=message.chat_id,
|
||||
message_id=message.message_id,
|
||||
*args,
|
||||
**kwargs)
|
||||
bot.edit_message_media(chat_id=message.chat_id,
|
||||
message_id=message.message_id,
|
||||
*args,
|
||||
**kwargs)
|
||||
|
||||
Note:
|
||||
You can only edit messages that the bot sent itself,
|
||||
therefore this method can only be used on the
|
||||
return value of the ``bot.send_*`` family of methods.
|
||||
Note:
|
||||
You can only edit messages that the bot sent itself (i.e. of the ``bot.send_*`` family
|
||||
of methods) or channel posts, if the bot is an admin in that channel. However, this
|
||||
behaviour is undocumented and might be changed by Telegram.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the edited
|
||||
message.
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the edited
|
||||
message.
|
||||
|
||||
"""
|
||||
"""
|
||||
return self.bot.edit_message_media(
|
||||
chat_id=self.chat_id, message_id=self.message_id, media=media, *args, **kwargs)
|
||||
|
||||
@@ -920,9 +925,9 @@ class Message(TelegramObject):
|
||||
**kwargs)
|
||||
|
||||
Note:
|
||||
You can only edit messages that the bot sent itself,
|
||||
therefore this method can only be used on the
|
||||
return value of the ``bot.send_*`` family of methods.
|
||||
You can only edit messages that the bot sent itself (i.e. of the ``bot.send_*`` family
|
||||
of methods) or channel posts, if the bot is an admin in that channel. However, this
|
||||
behaviour is undocumented and might be changed by Telegram.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the edited message.
|
||||
|
||||
@@ -65,7 +65,7 @@ class MessageEntity(TelegramObject):
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data, bot):
|
||||
data = super(MessageEntity, cls).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"""This module contains an object that represents a Telegram Message Parse Modes."""
|
||||
|
||||
|
||||
class ParseMode(object):
|
||||
class ParseMode:
|
||||
"""This object represents a Telegram Message Parse Modes."""
|
||||
|
||||
MARKDOWN = 'Markdown'
|
||||
|
||||
@@ -28,7 +28,6 @@ from cryptography.hazmat.primitives.ciphers import Cipher
|
||||
from cryptography.hazmat.primitives.ciphers.algorithms import AES
|
||||
from cryptography.hazmat.primitives.ciphers.modes import CBC
|
||||
from cryptography.hazmat.primitives.hashes import SHA512, SHA256, Hash, SHA1
|
||||
from future.utils import bord
|
||||
|
||||
from telegram import TelegramObject, TelegramError
|
||||
|
||||
@@ -39,8 +38,7 @@ class TelegramDecryptionError(TelegramError):
|
||||
"""
|
||||
|
||||
def __init__(self, message):
|
||||
super(TelegramDecryptionError, self).__init__("TelegramDecryptionError: "
|
||||
"{}".format(message))
|
||||
super().__init__("TelegramDecryptionError: {}".format(message))
|
||||
|
||||
|
||||
def decrypt(secret, hash, data):
|
||||
@@ -83,7 +81,7 @@ def decrypt(secret, hash, data):
|
||||
# Raise a error that is caught inside telegram.PassportData and transformed into a warning
|
||||
raise TelegramDecryptionError("Hashes are not equal! {} != {}".format(data_hash, hash))
|
||||
# Return data without padding
|
||||
return data[bord(data[0]):]
|
||||
return data[data[0]:]
|
||||
|
||||
|
||||
def decrypt_json(secret, hash, data):
|
||||
@@ -134,7 +132,7 @@ class EncryptedCredentials(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(EncryptedCredentials, cls).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
|
||||
return cls(bot=bot, **data)
|
||||
|
||||
@@ -347,7 +345,7 @@ class SecureValue(TelegramObject):
|
||||
return cls(bot=bot, **data)
|
||||
|
||||
def to_dict(self):
|
||||
data = super(SecureValue, self).to_dict()
|
||||
data = super().to_dict()
|
||||
|
||||
data['files'] = [p.to_dict() for p in self.files]
|
||||
data['translation'] = [p.to_dict() for p in self.translation]
|
||||
@@ -402,10 +400,10 @@ class DataCredentials(_CredentialsBase):
|
||||
"""
|
||||
|
||||
def __init__(self, data_hash, secret, **kwargs):
|
||||
super(DataCredentials, self).__init__(data_hash, secret, **kwargs)
|
||||
super().__init__(data_hash, secret, **kwargs)
|
||||
|
||||
def to_dict(self):
|
||||
data = super(DataCredentials, self).to_dict()
|
||||
data = super().to_dict()
|
||||
|
||||
del data['file_hash']
|
||||
del data['hash']
|
||||
@@ -428,10 +426,10 @@ class FileCredentials(_CredentialsBase):
|
||||
"""
|
||||
|
||||
def __init__(self, file_hash, secret, **kwargs):
|
||||
super(FileCredentials, self).__init__(file_hash, secret, **kwargs)
|
||||
super().__init__(file_hash, secret, **kwargs)
|
||||
|
||||
def to_dict(self):
|
||||
data = super(FileCredentials, self).to_dict()
|
||||
data = super().to_dict()
|
||||
|
||||
del data['data_hash']
|
||||
del data['hash']
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
"""This module contains an object that represents a Telegram EncryptedPassportElement."""
|
||||
from base64 import b64decode
|
||||
|
||||
from telegram import (TelegramObject, PassportFile, PersonalDetails, IdDocumentData,
|
||||
ResidentialAddress)
|
||||
from telegram import (IdDocumentData, PassportFile, PersonalDetails,
|
||||
ResidentialAddress, TelegramObject)
|
||||
from telegram.passport.credentials import decrypt_json
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ class EncryptedPassportElement(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(EncryptedPassportElement, cls).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
|
||||
data['files'] = PassportFile.de_list(data.get('files'), bot) or None
|
||||
data['front_side'] = PassportFile.de_json(data.get('front_side'), bot)
|
||||
@@ -153,7 +153,7 @@ class EncryptedPassportElement(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(EncryptedPassportElement, cls).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
|
||||
if data['type'] not in ('phone_number', 'email'):
|
||||
secure_data = getattr(credentials.secure_data, data['type'])
|
||||
@@ -197,7 +197,7 @@ class EncryptedPassportElement(TelegramObject):
|
||||
return encrypted_passport_elements
|
||||
|
||||
def to_dict(self):
|
||||
data = super(EncryptedPassportElement, self).to_dict()
|
||||
data = super().to_dict()
|
||||
|
||||
if self.files:
|
||||
data['files'] = [p.to_dict() for p in self.files]
|
||||
|
||||
@@ -58,7 +58,7 @@ class PassportData(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(PassportData, cls).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
|
||||
data['data'] = EncryptedPassportElement.de_list(data.get('data'), bot)
|
||||
data['credentials'] = EncryptedCredentials.de_json(data.get('credentials'), bot)
|
||||
@@ -66,7 +66,7 @@ class PassportData(TelegramObject):
|
||||
return cls(bot=bot, **data)
|
||||
|
||||
def to_dict(self):
|
||||
data = super(PassportData, self).to_dict()
|
||||
data = super().to_dict()
|
||||
|
||||
data['data'] = [e.to_dict() for e in self.data]
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ class PassportElementErrorDataField(PassportElementError):
|
||||
message,
|
||||
**kwargs):
|
||||
# Required
|
||||
super(PassportElementErrorDataField, self).__init__('data', type, message)
|
||||
super().__init__('data', type, message)
|
||||
self.field_name = field_name
|
||||
self.data_hash = data_hash
|
||||
|
||||
@@ -111,7 +111,7 @@ class PassportElementErrorFile(PassportElementError):
|
||||
message,
|
||||
**kwargs):
|
||||
# Required
|
||||
super(PassportElementErrorFile, self).__init__('file', type, message)
|
||||
super().__init__('file', type, message)
|
||||
self.file_hash = file_hash
|
||||
|
||||
self._id_attrs = (self.source, self.type, self.file_hash, self.message)
|
||||
@@ -145,7 +145,7 @@ class PassportElementErrorFiles(PassportElementError):
|
||||
message,
|
||||
**kwargs):
|
||||
# Required
|
||||
super(PassportElementErrorFiles, self).__init__('files', type, message)
|
||||
super().__init__('files', type, message)
|
||||
self.file_hashes = file_hashes
|
||||
|
||||
self._id_attrs = ((self.source, self.type, self.message)
|
||||
@@ -180,7 +180,7 @@ class PassportElementErrorFrontSide(PassportElementError):
|
||||
message,
|
||||
**kwargs):
|
||||
# Required
|
||||
super(PassportElementErrorFrontSide, self).__init__('front_side', type, message)
|
||||
super().__init__('front_side', type, message)
|
||||
self.file_hash = file_hash
|
||||
|
||||
self._id_attrs = (self.source, self.type, self.file_hash, self.message)
|
||||
@@ -214,7 +214,7 @@ class PassportElementErrorReverseSide(PassportElementError):
|
||||
message,
|
||||
**kwargs):
|
||||
# Required
|
||||
super(PassportElementErrorReverseSide, self).__init__('reverse_side', type, message)
|
||||
super().__init__('reverse_side', type, message)
|
||||
self.file_hash = file_hash
|
||||
|
||||
self._id_attrs = (self.source, self.type, self.file_hash, self.message)
|
||||
@@ -246,7 +246,7 @@ class PassportElementErrorSelfie(PassportElementError):
|
||||
message,
|
||||
**kwargs):
|
||||
# Required
|
||||
super(PassportElementErrorSelfie, self).__init__('selfie', type, message)
|
||||
super().__init__('selfie', type, message)
|
||||
self.file_hash = file_hash
|
||||
|
||||
self._id_attrs = (self.source, self.type, self.file_hash, self.message)
|
||||
@@ -282,8 +282,7 @@ class PassportElementErrorTranslationFile(PassportElementError):
|
||||
message,
|
||||
**kwargs):
|
||||
# Required
|
||||
super(PassportElementErrorTranslationFile, self).__init__('translation_file',
|
||||
type, message)
|
||||
super().__init__('translation_file', type, message)
|
||||
self.file_hash = file_hash
|
||||
|
||||
self._id_attrs = (self.source, self.type, self.file_hash, self.message)
|
||||
@@ -319,8 +318,7 @@ class PassportElementErrorTranslationFiles(PassportElementError):
|
||||
message,
|
||||
**kwargs):
|
||||
# Required
|
||||
super(PassportElementErrorTranslationFiles, self).__init__('translation_files',
|
||||
type, message)
|
||||
super().__init__('translation_files', type, message)
|
||||
self.file_hashes = file_hashes
|
||||
|
||||
self._id_attrs = ((self.source, self.type, self.message)
|
||||
@@ -351,7 +349,7 @@ class PassportElementErrorUnspecified(PassportElementError):
|
||||
message,
|
||||
**kwargs):
|
||||
# Required
|
||||
super(PassportElementErrorUnspecified, self).__init__('unspecified', type, message)
|
||||
super().__init__('unspecified', type, message)
|
||||
self.element_hash = element_hash
|
||||
|
||||
self._id_attrs = (self.source, self.type, self.element_hash, self.message)
|
||||
|
||||
@@ -71,7 +71,7 @@ class PassportFile(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(PassportFile, cls).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
|
||||
return cls(bot=bot, **data)
|
||||
|
||||
@@ -80,7 +80,7 @@ class PassportFile(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(PassportFile, cls).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
|
||||
data['credentials'] = credentials
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ class OrderInfo(TelegramObject):
|
||||
if not data:
|
||||
return cls()
|
||||
|
||||
data = super(OrderInfo, cls).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
|
||||
data['shipping_address'] = ShippingAddress.de_json(data.get('shipping_address'), bot)
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ class PreCheckoutQuery(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(PreCheckoutQuery, cls).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
|
||||
data['from_user'] = User.de_json(data.pop('from'), bot)
|
||||
data['order_info'] = OrderInfo.de_json(data.get('order_info'), bot)
|
||||
|
||||
@@ -45,7 +45,7 @@ class ShippingOption(TelegramObject):
|
||||
self._id_attrs = (self.id,)
|
||||
|
||||
def to_dict(self):
|
||||
data = super(ShippingOption, self).to_dict()
|
||||
data = super().to_dict()
|
||||
|
||||
data['prices'] = [p.to_dict() for p in self.prices]
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ class ShippingQuery(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(ShippingQuery, cls).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
|
||||
data['from_user'] = User.de_json(data.pop('from'), bot)
|
||||
data['shipping_address'] = ShippingAddress.de_json(data.get('shipping_address'), bot)
|
||||
|
||||
@@ -74,7 +74,7 @@ class SuccessfulPayment(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(SuccessfulPayment, cls).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
data['order_info'] = OrderInfo.de_json(data.get('order_info'), bot)
|
||||
|
||||
return cls(**data)
|
||||
|
||||
+2
-2
@@ -165,7 +165,7 @@ class Poll(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(Poll, cls).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
|
||||
data['options'] = [PollOption.de_json(option, bot) for option in data['options']]
|
||||
data['explanation_entities'] = MessageEntity.de_list(data.get('explanation_entities'), bot)
|
||||
@@ -174,7 +174,7 @@ class Poll(TelegramObject):
|
||||
return cls(**data)
|
||||
|
||||
def to_dict(self):
|
||||
data = super(Poll, self).to_dict()
|
||||
data = super().to_dict()
|
||||
|
||||
data['options'] = [x.to_dict() for x in self.options]
|
||||
if self.explanation_entities:
|
||||
|
||||
@@ -73,7 +73,7 @@ class ReplyKeyboardMarkup(ReplyMarkup):
|
||||
self.selective = bool(selective)
|
||||
|
||||
def to_dict(self):
|
||||
data = super(ReplyKeyboardMarkup, self).to_dict()
|
||||
data = super().to_dict()
|
||||
|
||||
data['keyboard'] = []
|
||||
for row in self.keyboard:
|
||||
|
||||
+1
-1
@@ -223,7 +223,7 @@ class Update(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(Update, cls).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
|
||||
message = data.get('message')
|
||||
if message:
|
||||
|
||||
+14
-1
@@ -116,7 +116,7 @@ class User(TelegramObject):
|
||||
def de_json(cls, data, bot):
|
||||
if not data:
|
||||
return None
|
||||
data = super(User, cls).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
|
||||
return cls(bot=bot, **data)
|
||||
|
||||
@@ -296,3 +296,16 @@ class User(TelegramObject):
|
||||
|
||||
"""
|
||||
return self.bot.send_voice(self.id, *args, **kwargs)
|
||||
|
||||
def send_poll(self, *args, **kwargs):
|
||||
"""Shortcut for::
|
||||
|
||||
bot.send_poll(User.id, *args, **kwargs)
|
||||
|
||||
Where User is the current instance.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
||||
|
||||
"""
|
||||
return self.bot.send_poll(self.id, *args, **kwargs)
|
||||
|
||||
@@ -45,14 +45,14 @@ class UserProfilePhotos(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(UserProfilePhotos, cls).de_json(data, bot)
|
||||
data = super().de_json(data, bot)
|
||||
|
||||
data['photos'] = [PhotoSize.de_list(photo, bot) for photo in data['photos']]
|
||||
|
||||
return cls(**data)
|
||||
|
||||
def to_dict(self):
|
||||
data = super(UserProfilePhotos, self).to_dict()
|
||||
data = super().to_dict()
|
||||
|
||||
data['photos'] = []
|
||||
for photo in self.photos:
|
||||
|
||||
@@ -30,7 +30,7 @@ class TelegramDeprecationWarning(Warning):
|
||||
|
||||
def warn_deprecate_obj(old, new, stacklevel=3):
|
||||
warnings.warn(
|
||||
'{0} is being deprecated, please use {1} from now on.'.format(old, new),
|
||||
'{} is being deprecated, please use {} from now on.'.format(old, new),
|
||||
category=TelegramDeprecationWarning,
|
||||
stacklevel=stacklevel)
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user