mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2026-06-19 23:55:29 +00:00
Compare commits
62 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ac55ba007e | |||
| 6bdca1e4f8 | |||
| fd7b571e92 | |||
| 9243cd3507 | |||
| 1b09738191 | |||
| 836c50965a | |||
| 1d9d0fc764 | |||
| e57e6dd645 | |||
| 49122d6a99 | |||
| d445d35ceb | |||
| 703b8d1301 | |||
| 46993d5f2d | |||
| 880746baed | |||
| 8ad1f330ea | |||
| 56b1d4f5ce | |||
| df16846d80 | |||
| 3ac9a1cd71 | |||
| 4d8174edc3 | |||
| 235bb72702 | |||
| 9a5ccb1c2d | |||
| a18640a8d3 | |||
| fdc3ac0cc5 | |||
| d881fa6a5f | |||
| c551d71735 | |||
| bee3d881d1 | |||
| 6ec81dd552 | |||
| 6e9f30ca6e | |||
| 252cafb04c | |||
| d4f7b7165c | |||
| 0ed5e8e1a3 | |||
| 335813a11a | |||
| 10a98211f8 | |||
| b5570ddfa5 | |||
| 99c9544a27 | |||
| 0e0611767a | |||
| 4ba5fbf4f5 | |||
| 4b0be65a76 | |||
| 5971cb35f8 | |||
| 6e5302c089 | |||
| 5aab4525c2 | |||
| 62c651d167 | |||
| 41e457f5ed | |||
| 4ce0ab53d0 | |||
| d940afa718 | |||
| a327e9d6ff | |||
| 5e5510d42b | |||
| 73c60ee817 | |||
| 474d5f0c9f | |||
| 74a2baf03d | |||
| 0612385233 | |||
| c0489db17c | |||
| 592352c849 | |||
| 9d367e9f2c | |||
| d86ca30601 | |||
| ec15e866be | |||
| 998040da92 | |||
| 0c74b3cfb9 | |||
| 0ca3ef7a38 | |||
| e160355190 | |||
| d80e0b4b8c | |||
| 96d98084c7 | |||
| a686db2c6f |
@@ -0,0 +1,17 @@
|
||||
- repo: git://github.com/pre-commit/mirrors-yapf
|
||||
sha: 'v0.7.1'
|
||||
hooks:
|
||||
- id: yapf
|
||||
args: ['-i']
|
||||
|
||||
- repo: git://github.com/pre-commit/pre-commit-hooks
|
||||
sha: 'v0.5.0'
|
||||
hooks:
|
||||
- id: flake8
|
||||
args: ['telegram']
|
||||
|
||||
- repo: git://github.com/pre-commit/mirrors-pylint
|
||||
sha: 'v1.5.5'
|
||||
hooks:
|
||||
- id: pylint
|
||||
args: ['--errors-only', '--disable=no-name-in-module,import-error', 'telegram']
|
||||
+2
-1
@@ -13,7 +13,8 @@ install:
|
||||
- pip install -r requirements-dev.txt
|
||||
script:
|
||||
- nosetests -v --with-flaky --no-flaky-report --with-coverage --cover-package=telegram/
|
||||
- 'if [ $TRAVIS_PYTHON_VERSION != 2.6 ] && [ $TRAVIS_PYTHON_VERSION != 3.3 ] && [ $TRAVIS_PYTHON_VERSION != pypy3 ]; then yapf -r telegram; fi'
|
||||
- flake8 telegram
|
||||
- 'if [[ $TRAVIS_PYTHON_VERSION != 2.6 ]]; then pylint -E telegram --disable=no-name-in-module,import-error; fi'
|
||||
- 'if [ $TRAVIS_PYTHON_VERSION != 2.6 ]; then pylint -E telegram --disable=no-name-in-module,import-error; fi'
|
||||
after_success:
|
||||
coveralls
|
||||
|
||||
+13
@@ -1,3 +1,16 @@
|
||||
**2016-05-01**
|
||||
|
||||
*Released 4.0.3*
|
||||
|
||||
- Add missing attribute ``location`` to ``InlineQuery``
|
||||
|
||||
**2016-04-29**
|
||||
|
||||
*Released 4.0.2*
|
||||
|
||||
- Bugfixes
|
||||
- ``KeyboardReplyMarkup`` now accepts ``str`` again
|
||||
|
||||
**2016-04-27**
|
||||
|
||||
*Released 4.0.1*
|
||||
|
||||
+15
-7
@@ -20,9 +20,12 @@ Setting things up
|
||||
|
||||
4. Install dependencies:
|
||||
|
||||
``$ pip install -r requirements.txt``
|
||||
``$ pip install -r requirements.txt -r requirements-dev.txt``
|
||||
|
||||
``$ pip install -r requirements-dev.txt``
|
||||
|
||||
5. Install pre-commit hooks:
|
||||
|
||||
``$ pre-commit install``
|
||||
|
||||
Finding something to do
|
||||
-----------------------
|
||||
@@ -56,6 +59,8 @@ Here's how to make a one-off code change.
|
||||
|
||||
- You can refer to relevant issues in the commit message by writing, e.g., "#105".
|
||||
|
||||
- Your code should adhere to the `PEP 8 Style Guide`_, with the exception that we have a maximum line length of 99.
|
||||
|
||||
- For consistency, please conform to `Google Python Style Guide`_ and `Google Python Style Docstrings`_. In addition, code should be formatted consistently with other code around it.
|
||||
|
||||
- The following exceptions to the above (Google's) style guides applies:
|
||||
@@ -68,18 +73,20 @@ Here's how to make a one-off code change.
|
||||
|
||||
- Add yourself to the AUTHORS.rst_ file in an alphabetical fashion.
|
||||
|
||||
- Before making a commit ensure that all automated tests, pep8 & lint validations still pass:
|
||||
- Before making a commit ensure that all automated tests still pass:
|
||||
|
||||
``$ make test``
|
||||
|
||||
``$ make pep8``
|
||||
- To actually make the commit (this will trigger tests for yapf, lint and pep8 automatically):
|
||||
|
||||
``$ make lint``
|
||||
``$ git add your-file-changed.py``
|
||||
|
||||
- To actually make the commit and push it to your GitHub fork, run:
|
||||
- yapf may change code formatting, make sure to re-add them to your commit.
|
||||
|
||||
``$ git commit -a -m "your-commit-message-here"``
|
||||
|
||||
- Finally, push it to your GitHub fork, run:
|
||||
|
||||
``$ git push origin your-branch-name``
|
||||
|
||||
4. **When your feature is ready to merge, create a pull request.**
|
||||
@@ -116,7 +123,7 @@ Here's how to make a one-off code change.
|
||||
|
||||
- At the end, the reviewer will merge the pull request.
|
||||
|
||||
6. **Tidy up!** Delete the feature branch from your both your local clone and the GitHub repository:
|
||||
6. **Tidy up!** Delete the feature branch from both your local clone and the GitHub repository:
|
||||
|
||||
``$ git branch -D your-branch-name``
|
||||
|
||||
@@ -127,6 +134,7 @@ Here's how to make a one-off code change.
|
||||
.. _`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
|
||||
.. _`PEP 8 Style Guide`: https://www.python.org/dev/peps/pep-0008/
|
||||
.. _`Google Python Style Guide`: https://google-styleguide.googlecode.com/svn/trunk/pyguide.html
|
||||
.. _`Google Python Style Docstrings`: http://sphinx-doc.org/latest/ext/example_google.html
|
||||
.. _AUTHORS.rst: https://github.com/python-telegram-bot/python-telegram-bot/blob/master/AUTHORS.rst
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
.DEFAULT_GOAL := help
|
||||
.PHONY: clean pep8 lint test install
|
||||
.PHONY: clean pep257 pep8 yapf lint test install
|
||||
|
||||
PYLINT := pylint
|
||||
NOSETESTS := nosetests
|
||||
PEP257 := pep257
|
||||
PEP8 := flake8
|
||||
YAPF := yapf
|
||||
PIP := pip
|
||||
|
||||
clean:
|
||||
@@ -19,7 +20,10 @@ pep257:
|
||||
$(PEP257) telegram
|
||||
|
||||
pep8:
|
||||
$(PEP8) telegram
|
||||
$(PEP8) telegram
|
||||
|
||||
yapf:
|
||||
$(YAPF) -r telegram
|
||||
|
||||
lint:
|
||||
$(PYLINT) -E telegram --disable=no-name-in-module,import-error
|
||||
@@ -28,7 +32,7 @@ test:
|
||||
$(NOSETESTS) -v
|
||||
|
||||
install:
|
||||
$(PIP) install -r requirements.txt
|
||||
$(PIP) install -r requirements.txt -r requirements-dev.txt
|
||||
|
||||
help:
|
||||
@echo "Available targets:"
|
||||
@@ -36,6 +40,7 @@ help:
|
||||
@echo "- pep257 Check docstring style with pep257"
|
||||
@echo "- pep8 Check style with flake8"
|
||||
@echo "- lint Check style with pylint"
|
||||
@echo "- yapf Check style with yapf"
|
||||
@echo "- test Run tests"
|
||||
@echo
|
||||
@echo "Available variables:"
|
||||
@@ -43,4 +48,5 @@ help:
|
||||
@echo "- NOSETESTS default: $(NOSETESTS)"
|
||||
@echo "- PEP257 default: $(PEP257)"
|
||||
@echo "- PEP8 default: $(PEP8)"
|
||||
@echo "- YAPF default: $(YAPF)"
|
||||
@echo "- PIP default: $(PIP)"
|
||||
|
||||
+7
-12
@@ -15,10 +15,6 @@ Not **just** a Python wrapper around the Telegram Bot API
|
||||
:target: https://pypi.python.org/pypi/python-telegram-bot
|
||||
:alt: Supported python versions
|
||||
|
||||
.. image:: https://img.shields.io/pypi/dm/python-telegram-bot.svg
|
||||
:target: https://pypi.python.org/pypi/python-telegram-bot
|
||||
:alt: PyPi Package Monthly Download
|
||||
|
||||
.. image:: https://readthedocs.org/projects/python-telegram-bot/badge/?version=latest
|
||||
:target: https://readthedocs.org/projects/python-telegram-bot/?badge=latest
|
||||
:alt: Documentation Status
|
||||
@@ -110,7 +106,6 @@ answerCallbackQuery Yes
|
||||
editMessageText Yes
|
||||
editMessageCaption Yes
|
||||
editMessageReplyMarkup Yes
|
||||
answerCallbackQuery Yes
|
||||
========================= ============
|
||||
|
||||
=============
|
||||
@@ -121,7 +116,7 @@ You can install or upgrade python-telegram-bot with:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
$ pip install python-telegram-bot==4.0rc1 --upgrade
|
||||
$ pip install python-telegram-bot --upgrade
|
||||
|
||||
===================
|
||||
_`Getting the code`
|
||||
@@ -202,7 +197,7 @@ _`API`
|
||||
|
||||
Note: Using the ``Bot`` class directly is the 'old' method, we have an easier way to make bots described in the next section. All of this is however still important information, even if you're using the ``telegram.ext`` submodule!
|
||||
|
||||
The API is exposed via the ``telegram.Bot`` class.
|
||||
The API is exposed via the ``telegram.Bot`` class. The methods have names as described in the official `Telegram Bot API <https://core.telegram.org/bots/api>`_, but equivalent snake_case methods are available for `PEP8 <https://www.python.org/dev/peps/pep-0008/>`_ enthusiasts. So for example `telegram.Bot.send_message` is the same as `telegram.Bot.sendMessage`.
|
||||
|
||||
To generate an Access Token you have to talk to `BotFather <https://telegram.me/botfather>`_ and follow a few simple steps (described `here <https://core.telegram.org/bots#6-botfather>`_).
|
||||
|
||||
@@ -356,7 +351,7 @@ We want this function to be called on a Telegram message that contains the ``/st
|
||||
|
||||
>>> from telegram.ext import CommandHandler
|
||||
>>> start_handler = CommandHandler('start', start)
|
||||
>>> dispatcher.addHandler(start_handler)
|
||||
>>> dispatcher.add_handler(start_handler)
|
||||
|
||||
The last step is to tell the ``Updater`` to start working:
|
||||
|
||||
@@ -373,7 +368,7 @@ Our bot is now up and running (go ahead and try it)! It's not doing anything yet
|
||||
...
|
||||
>>> from telegram.ext import MessageHandler, Filters
|
||||
>>> echo_handler = MessageHandler([Filters.text], echo)
|
||||
>>> dispatcher.addHandler(echo_handler)
|
||||
>>> dispatcher.add_handler(echo_handler)
|
||||
|
||||
Our bot should now reply to all text messages that are not a command with a message that has the same content.
|
||||
|
||||
@@ -386,7 +381,7 @@ Let's add some functionality to our bot. We want to add the ``/caps`` command, t
|
||||
... bot.sendMessage(chat_id=update.message.chat_id, text=text_caps)
|
||||
...
|
||||
>>> caps_handler = CommandHandler('caps', caps, pass_args=True)
|
||||
>>> dispatcher.addHandler(caps_handler)
|
||||
>>> dispatcher.add_handler(caps_handler)
|
||||
|
||||
To enable our bot to respond to inline queries, we can add the following (you will also have to talk to BotFather):
|
||||
|
||||
@@ -401,7 +396,7 @@ To enable our bot to respond to inline queries, we can add the following (you wi
|
||||
...
|
||||
>>> from telegram.ext import InlineQueryHandler
|
||||
>>> inline_caps_handler = InlineQueryHandler(inline_caps)
|
||||
>>> dispatcher.addHandler(inline_caps_handler)
|
||||
>>> dispatcher.add_handler(inline_caps_handler)
|
||||
|
||||
People might try to send commands to the bot that it doesn't understand, so we can use a ``RegexHandler`` to recognize all commands that were not recognized by the previous handlers. **Note:** This handler has to be added last, else it will be triggered before the ``CommandHandlers`` had a chance to look at the update:
|
||||
|
||||
@@ -412,7 +407,7 @@ People might try to send commands to the bot that it doesn't understand, so we c
|
||||
...
|
||||
>>> from telegram.ext import RegexHandler
|
||||
>>> unknown_handler = RegexHandler(r'/.*', unknown)
|
||||
>>> dispatcher.addHandler(unknown_handler)
|
||||
>>> dispatcher.add_handler(unknown_handler)
|
||||
|
||||
If you're done playing around, stop the bot with this:
|
||||
|
||||
|
||||
+2
-2
@@ -58,9 +58,9 @@ author = u'Leandro Toledo'
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '4.0'
|
||||
version = '4.1'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '4.0.1'
|
||||
release = '4.1'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
||||
+11
-12
@@ -24,6 +24,8 @@ from telegram.ext.dispatcher import run_async
|
||||
from time import sleep
|
||||
import logging
|
||||
|
||||
from future.builtins import input
|
||||
|
||||
# Enable Logging
|
||||
logging.basicConfig(
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
@@ -112,24 +114,24 @@ def main():
|
||||
dp = updater.dispatcher
|
||||
|
||||
# This is how we add handlers for Telegram messages
|
||||
dp.addHandler(CommandHandler("start", start))
|
||||
dp.addHandler(CommandHandler("help", help))
|
||||
dp.add_handler(CommandHandler("start", start))
|
||||
dp.add_handler(CommandHandler("help", help))
|
||||
# Message handlers only receive updates that don't contain commands
|
||||
dp.addHandler(MessageHandler([Filters.text], message))
|
||||
dp.add_handler(MessageHandler([Filters.text], message))
|
||||
# Regex handlers will receive all updates on which their regex matches,
|
||||
# but we have to add it in a separate group, since in one group,
|
||||
# only one handler will be executed
|
||||
dp.addHandler(RegexHandler('.*', any_message), group='log')
|
||||
dp.add_handler(RegexHandler('.*', any_message), group=1)
|
||||
|
||||
# String handlers work pretty much the same. Note that we have to tell
|
||||
# the handler to pass the args or update_queue parameter
|
||||
dp.addHandler(StringCommandHandler('reply', cli_reply, pass_args=True))
|
||||
dp.addHandler(StringRegexHandler('[^/].*', cli_noncommand,
|
||||
pass_update_queue=True))
|
||||
dp.add_handler(StringCommandHandler('reply', cli_reply, pass_args=True))
|
||||
dp.add_handler(StringRegexHandler('[^/].*', cli_noncommand,
|
||||
pass_update_queue=True))
|
||||
|
||||
# All TelegramErrors are caught for you and delivered to the error
|
||||
# handler(s). Other types of Errors are not caught.
|
||||
dp.addErrorHandler(error)
|
||||
dp.add_error_handler(error)
|
||||
|
||||
# Start the Bot and store the update Queue, so we can insert updates
|
||||
update_queue = updater.start_polling(timeout=10)
|
||||
@@ -153,10 +155,7 @@ def main():
|
||||
|
||||
# Start CLI-Loop
|
||||
while True:
|
||||
try:
|
||||
text = raw_input()
|
||||
except NameError:
|
||||
text = input()
|
||||
text = input()
|
||||
|
||||
# Gracefully stop the event handler
|
||||
if text == 'stop':
|
||||
|
||||
@@ -54,14 +54,14 @@ def main():
|
||||
dp = updater.dispatcher
|
||||
|
||||
# on different commands - answer in Telegram
|
||||
dp.addHandler(CommandHandler("start", start))
|
||||
dp.addHandler(CommandHandler("help", help))
|
||||
dp.add_handler(CommandHandler("start", start))
|
||||
dp.add_handler(CommandHandler("help", help))
|
||||
|
||||
# on noncommand i.e message - echo the message on Telegram
|
||||
dp.addHandler(MessageHandler([Filters.text], echo))
|
||||
dp.add_handler(MessageHandler([Filters.text], echo))
|
||||
|
||||
# log all errors
|
||||
dp.addErrorHandler(error)
|
||||
dp.add_error_handler(error)
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
@@ -87,14 +87,14 @@ def main():
|
||||
dp = updater.dispatcher
|
||||
|
||||
# on different commands - answer in Telegram
|
||||
dp.addHandler(CommandHandler("start", start))
|
||||
dp.addHandler(CommandHandler("help", help))
|
||||
dp.add_handler(CommandHandler("start", start))
|
||||
dp.add_handler(CommandHandler("help", help))
|
||||
|
||||
# on noncommand i.e message - echo the message on Telegram
|
||||
dp.addHandler(InlineQueryHandler(inlinequery))
|
||||
dp.add_handler(InlineQueryHandler(inlinequery))
|
||||
|
||||
# log all errors
|
||||
dp.addErrorHandler(error)
|
||||
dp.add_error_handler(error)
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
@@ -105,12 +105,12 @@ updater = Updater("TOKEN")
|
||||
# The command
|
||||
updater.dispatcher.addHandler(CommandHandler('set', set_value))
|
||||
# The answer
|
||||
updater.dispatcher.addHandler(MessageHandler([Filters.text], entered_value))
|
||||
updater.dispatcher.add_handler(MessageHandler([Filters.text], entered_value))
|
||||
# The confirmation
|
||||
updater.dispatcher.addHandler(CallbackQueryHandler(confirm_value))
|
||||
updater.dispatcher.addHandler(CommandHandler('start', help))
|
||||
updater.dispatcher.addHandler(CommandHandler('help', help))
|
||||
updater.dispatcher.addErrorHandler(error)
|
||||
updater.dispatcher.add_handler(CallbackQueryHandler(confirm_value))
|
||||
updater.dispatcher.add_handler(CommandHandler('start', help))
|
||||
updater.dispatcher.add_handler(CommandHandler('help', help))
|
||||
updater.dispatcher.add_error_handler(error)
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
@@ -91,12 +91,12 @@ def help(bot, update):
|
||||
updater = Updater("TOKEN")
|
||||
|
||||
# The command
|
||||
updater.dispatcher.addHandler(CommandHandler('set', set_value))
|
||||
updater.dispatcher.add_handler(CommandHandler('set', set_value))
|
||||
# The answer and confirmation
|
||||
updater.dispatcher.addHandler(MessageHandler([Filters.text], set_value))
|
||||
updater.dispatcher.addHandler(CommandHandler('cancel', cancel))
|
||||
updater.dispatcher.addHandler(CommandHandler('start', help))
|
||||
updater.dispatcher.addHandler(CommandHandler('help', help))
|
||||
updater.dispatcher.add_handler(MessageHandler([Filters.text], set_value))
|
||||
updater.dispatcher.add_handler(CommandHandler('cancel', cancel))
|
||||
updater.dispatcher.add_handler(CommandHandler('start', help))
|
||||
updater.dispatcher.add_handler(CommandHandler('help', help))
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
@@ -73,12 +73,12 @@ def main():
|
||||
dp = updater.dispatcher
|
||||
|
||||
# on different commands - answer in Telegram
|
||||
dp.addHandler(CommandHandler("start", start))
|
||||
dp.addHandler(CommandHandler("help", start))
|
||||
dp.addHandler(CommandHandler("set", set))
|
||||
dp.add_handler(CommandHandler("start", start))
|
||||
dp.add_handler(CommandHandler("help", start))
|
||||
dp.add_handler(CommandHandler("set", set, pass_args=True))
|
||||
|
||||
# log all errors
|
||||
dp.addErrorHandler(error)
|
||||
dp.add_error_handler(error)
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
@@ -3,4 +3,7 @@ nose
|
||||
pep257
|
||||
pylint
|
||||
unittest2
|
||||
flaky
|
||||
flaky
|
||||
yapf
|
||||
pre-commit
|
||||
pre-commit-hooks
|
||||
|
||||
@@ -8,3 +8,10 @@ all_files = 1
|
||||
|
||||
[upload_sphinx]
|
||||
upload-dir = docs/build/html
|
||||
|
||||
[flake8]
|
||||
max-line-length = 99
|
||||
|
||||
[yapf]
|
||||
based_on_style = google
|
||||
column_limit = 99
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
'''The setup and build script for the python-telegram-bot library.'''
|
||||
|
||||
import os
|
||||
@@ -24,34 +23,32 @@ def requirements():
|
||||
return requirements_list
|
||||
|
||||
|
||||
setup(
|
||||
name='python-telegram-bot',
|
||||
version='4.0.1',
|
||||
author='Leandro Toledo',
|
||||
author_email='devs@python-telegram-bot.org',
|
||||
license='LGPLv3',
|
||||
url='https://github.com/python-telegram-bot/python-telegram-bot',
|
||||
keywords='python telegram bot api wrapper',
|
||||
description='A Python wrapper around the Telegram Bot API',
|
||||
long_description=(read('README.rst')),
|
||||
packages=find_packages(exclude=['tests*']),
|
||||
install_requires=requirements(),
|
||||
include_package_data=True,
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Intended Audience :: Developers',
|
||||
'License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)',
|
||||
'Operating System :: OS Independent',
|
||||
'Topic :: Software Development :: Libraries :: Python Modules',
|
||||
'Topic :: Communications :: Chat',
|
||||
'Topic :: Internet',
|
||||
'Programming Language :: Python',
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.6',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
],
|
||||
)
|
||||
setup(name='python-telegram-bot',
|
||||
version='4.1',
|
||||
author='Leandro Toledo',
|
||||
author_email='devs@python-telegram-bot.org',
|
||||
license='LGPLv3',
|
||||
url='https://github.com/python-telegram-bot/python-telegram-bot',
|
||||
keywords='python telegram bot api wrapper',
|
||||
description='A Python wrapper around the Telegram Bot API',
|
||||
long_description=(read('README.rst')),
|
||||
packages=find_packages(exclude=['tests*']),
|
||||
install_requires=requirements(),
|
||||
include_package_data=True,
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Intended Audience :: Developers',
|
||||
'License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)',
|
||||
'Operating System :: OS Independent',
|
||||
'Topic :: Software Development :: Libraries :: Python Modules',
|
||||
'Topic :: Communications :: Chat',
|
||||
'Topic :: Internet',
|
||||
'Programming Language :: Python',
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.6',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
],)
|
||||
|
||||
+24
-63
@@ -16,9 +16,10 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""A library that provides a Python interface to the Telegram Bot API"""
|
||||
|
||||
from sys import version_info
|
||||
|
||||
from .base import TelegramObject
|
||||
from .user import User
|
||||
from .chat import Chat
|
||||
@@ -79,66 +80,26 @@ from .inputcontactmessagecontent import InputContactMessageContent
|
||||
from .update import Update
|
||||
from .bot import Bot
|
||||
|
||||
|
||||
__author__ = 'devs@python-telegram-bot.org'
|
||||
__version__ = '4.0.1'
|
||||
__all__ = ['Audio',
|
||||
'Bot',
|
||||
'Chat',
|
||||
'ChatAction',
|
||||
'ChosenInlineResult',
|
||||
'CallbackQuery',
|
||||
'Contact',
|
||||
'Document',
|
||||
'Emoji',
|
||||
'File',
|
||||
'ForceReply',
|
||||
'InlineKeyboardButton',
|
||||
'InlineKeyboardMarkup',
|
||||
'InlineQuery',
|
||||
'InlineQueryResult',
|
||||
'InlineQueryResult',
|
||||
'InlineQueryResultArticle',
|
||||
'InlineQueryResultAudio',
|
||||
'InlineQueryResultCachedAudio',
|
||||
'InlineQueryResultCachedDocument',
|
||||
'InlineQueryResultCachedGif',
|
||||
'InlineQueryResultCachedMpeg4Gif',
|
||||
'InlineQueryResultCachedPhoto',
|
||||
'InlineQueryResultCachedSticker',
|
||||
'InlineQueryResultCachedVideo',
|
||||
'InlineQueryResultCachedVoice',
|
||||
'InlineQueryResultContact',
|
||||
'InlineQueryResultDocument',
|
||||
'InlineQueryResultGif',
|
||||
'InlineQueryResultLocation',
|
||||
'InlineQueryResultMpeg4Gif',
|
||||
'InlineQueryResultPhoto',
|
||||
'InlineQueryResultVenue',
|
||||
'InlineQueryResultVideo',
|
||||
'InlineQueryResultVoice',
|
||||
'InputContactMessageContent',
|
||||
'InputFile',
|
||||
'InputLocationMessageContent',
|
||||
'InputMessageContent',
|
||||
'InputTextMessageContent',
|
||||
'InputVenueMessageContent',
|
||||
'KeyboardButton',
|
||||
'Location',
|
||||
'Message',
|
||||
'MessageEntity',
|
||||
'NullHandler',
|
||||
'ParseMode',
|
||||
'PhotoSize',
|
||||
'ReplyKeyboardHide',
|
||||
'ReplyKeyboardMarkup',
|
||||
'ReplyMarkup',
|
||||
'Sticker',
|
||||
'TelegramError',
|
||||
'TelegramObject',
|
||||
'Update',
|
||||
'User',
|
||||
'UserProfilePhotos',
|
||||
'Venue',
|
||||
'Video',
|
||||
'Voice']
|
||||
__version__ = '4.1'
|
||||
__all__ = ['Audio', 'Bot', 'Chat', 'ChatAction', 'ChosenInlineResult', 'CallbackQuery', 'Contact',
|
||||
'Document', 'Emoji', 'File', 'ForceReply', 'InlineKeyboardButton',
|
||||
'InlineKeyboardMarkup', 'InlineQuery', 'InlineQueryResult', 'InlineQueryResult',
|
||||
'InlineQueryResultArticle', 'InlineQueryResultAudio', 'InlineQueryResultCachedAudio',
|
||||
'InlineQueryResultCachedDocument', 'InlineQueryResultCachedGif',
|
||||
'InlineQueryResultCachedMpeg4Gif', 'InlineQueryResultCachedPhoto',
|
||||
'InlineQueryResultCachedSticker', 'InlineQueryResultCachedVideo',
|
||||
'InlineQueryResultCachedVoice', 'InlineQueryResultContact', 'InlineQueryResultDocument',
|
||||
'InlineQueryResultGif', 'InlineQueryResultLocation', 'InlineQueryResultMpeg4Gif',
|
||||
'InlineQueryResultPhoto', 'InlineQueryResultVenue', 'InlineQueryResultVideo',
|
||||
'InlineQueryResultVoice', 'InputContactMessageContent', 'InputFile',
|
||||
'InputLocationMessageContent', 'InputMessageContent', 'InputTextMessageContent',
|
||||
'InputVenueMessageContent', 'KeyboardButton', 'Location', 'Message', 'MessageEntity',
|
||||
'NullHandler', 'ParseMode', 'PhotoSize', 'ReplyKeyboardHide', 'ReplyKeyboardMarkup',
|
||||
'ReplyMarkup', 'Sticker', 'TelegramError', 'TelegramObject', 'Update', 'User',
|
||||
'UserProfilePhotos', 'Venue', 'Video', 'Voice']
|
||||
|
||||
if version_info < (2, 7):
|
||||
from warnings import warn
|
||||
warn("python-telegram-bot will stop supporting Python 2.6 in a future release. "
|
||||
"Please upgrade your Python!")
|
||||
|
||||
+1
-5
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a Telegram Audio."""
|
||||
|
||||
from telegram import TelegramObject
|
||||
@@ -45,10 +44,7 @@ class Audio(TelegramObject):
|
||||
file_size (Optional[int]):
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
file_id,
|
||||
duration,
|
||||
**kwargs):
|
||||
def __init__(self, file_id, duration, **kwargs):
|
||||
# Required
|
||||
self.file_id = str(file_id)
|
||||
self.duration = int(duration)
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""Base class for Telegram Objects."""
|
||||
|
||||
import json
|
||||
|
||||
+114
-277
@@ -17,14 +17,13 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a Telegram Bot."""
|
||||
|
||||
import logging
|
||||
import functools
|
||||
|
||||
from telegram import User, Message, Update, UserProfilePhotos, File, \
|
||||
ReplyMarkup, TelegramObject, NullHandler
|
||||
from telegram import (User, Message, Update, UserProfilePhotos, File, ReplyMarkup, TelegramObject,
|
||||
NullHandler)
|
||||
from telegram.utils import request
|
||||
from telegram.utils.validate import validate_token
|
||||
|
||||
@@ -43,28 +42,21 @@ class Bot(TelegramObject):
|
||||
|
||||
Args:
|
||||
token (str): Bot's unique authentication.
|
||||
**kwargs: Arbitrary keyword arguments.
|
||||
|
||||
Keyword Args:
|
||||
base_url (Optional[str]): Telegram Bot API service URL.
|
||||
base_file_url (Optional[str]): Telegram Bot API file URL.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
token,
|
||||
base_url=None,
|
||||
base_file_url=None):
|
||||
def __init__(self, token, base_url=None, base_file_url=None):
|
||||
self.token = validate_token(token)
|
||||
|
||||
if not base_url:
|
||||
self.base_url = 'https://api.telegram.org/bot{0}'.format(
|
||||
self.token)
|
||||
self.base_url = 'https://api.telegram.org/bot{0}'.format(self.token)
|
||||
else:
|
||||
self.base_url = base_url + self.token
|
||||
|
||||
if not base_file_url:
|
||||
self.base_file_url = 'https://api.telegram.org/file/bot{0}'.format(
|
||||
self.token)
|
||||
self.base_file_url = 'https://api.telegram.org/file/bot{0}'.format(self.token)
|
||||
else:
|
||||
self.base_file_url = base_file_url + self.token
|
||||
|
||||
@@ -73,6 +65,7 @@ class Bot(TelegramObject):
|
||||
self.logger = logging.getLogger(__name__)
|
||||
|
||||
def info(func):
|
||||
|
||||
@functools.wraps(func)
|
||||
def decorator(self, *args, **kwargs):
|
||||
if not self.bot:
|
||||
@@ -121,17 +114,16 @@ class Bot(TelegramObject):
|
||||
return decorator
|
||||
|
||||
def message(func):
|
||||
|
||||
@functools.wraps(func)
|
||||
def decorator(self, *args, **kwargs):
|
||||
url, data = func(self, *args, **kwargs)
|
||||
|
||||
if kwargs.get('reply_to_message_id'):
|
||||
data['reply_to_message_id'] = \
|
||||
kwargs.get('reply_to_message_id')
|
||||
data['reply_to_message_id'] = kwargs.get('reply_to_message_id')
|
||||
|
||||
if kwargs.get('disable_notification'):
|
||||
data['disable_notification'] = \
|
||||
kwargs.get('disable_notification')
|
||||
data['disable_notification'] = kwargs.get('disable_notification')
|
||||
|
||||
if kwargs.get('reply_markup'):
|
||||
reply_markup = kwargs.get('reply_markup')
|
||||
@@ -140,9 +132,7 @@ class Bot(TelegramObject):
|
||||
else:
|
||||
data['reply_markup'] = reply_markup
|
||||
|
||||
result = request.post(url, data,
|
||||
timeout=kwargs.get('timeout'),
|
||||
network_delay=kwargs.get('network_delay'))
|
||||
result = request.post(url, data, timeout=kwargs.get('timeout'))
|
||||
|
||||
if result is True:
|
||||
return result
|
||||
@@ -175,12 +165,7 @@ class Bot(TelegramObject):
|
||||
|
||||
@log
|
||||
@message
|
||||
def sendMessage(self,
|
||||
chat_id,
|
||||
text,
|
||||
parse_mode=None,
|
||||
disable_web_page_preview=None,
|
||||
**kwargs):
|
||||
def sendMessage(self, chat_id, text, parse_mode=None, disable_web_page_preview=None, **kwargs):
|
||||
"""Use this method to send text messages.
|
||||
|
||||
Args:
|
||||
@@ -208,10 +193,6 @@ class Bot(TelegramObject):
|
||||
keyboard or to force a reply from the user.
|
||||
timeout (Optional[float]): If this value is specified, use it as
|
||||
the definitive timeout (in seconds) for urlopen() operations.
|
||||
network_delay (Optional[float]): If using the timeout (which is
|
||||
a `timeout` for the Telegram servers operation),
|
||||
then `network_delay` as an extra delay (in seconds) to
|
||||
compensate for network latency. Defaults to 2.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, the sent message is
|
||||
@@ -224,8 +205,7 @@ class Bot(TelegramObject):
|
||||
|
||||
url = '{0}/sendMessage'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id,
|
||||
'text': text}
|
||||
data = {'chat_id': chat_id, 'text': text}
|
||||
|
||||
if parse_mode:
|
||||
data['parse_mode'] = parse_mode
|
||||
@@ -236,11 +216,7 @@ class Bot(TelegramObject):
|
||||
|
||||
@log
|
||||
@message
|
||||
def forwardMessage(self,
|
||||
chat_id,
|
||||
from_chat_id,
|
||||
message_id,
|
||||
**kwargs):
|
||||
def forwardMessage(self, chat_id, from_chat_id, message_id, **kwargs):
|
||||
"""Use this method to forward messages of any kind.
|
||||
|
||||
Args:
|
||||
@@ -258,10 +234,6 @@ class Bot(TelegramObject):
|
||||
receive a notification with no sound.
|
||||
timeout (Optional[float]): If this value is specified, use it as
|
||||
the definitive timeout (in seconds) for urlopen() operations.
|
||||
network_delay (Optional[float]): If using the timeout (which is
|
||||
a `timeout` for the Telegram servers operation),
|
||||
then `network_delay` as an extra delay (in seconds) to
|
||||
compensate for network latency. Defaults to 2.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the
|
||||
@@ -287,11 +259,7 @@ class Bot(TelegramObject):
|
||||
|
||||
@log
|
||||
@message
|
||||
def sendPhoto(self,
|
||||
chat_id,
|
||||
photo,
|
||||
caption=None,
|
||||
**kwargs):
|
||||
def sendPhoto(self, chat_id, photo, caption=None, **kwargs):
|
||||
"""Use this method to send photos.
|
||||
|
||||
Args:
|
||||
@@ -317,10 +285,6 @@ class Bot(TelegramObject):
|
||||
keyboard or to force a reply from the user.
|
||||
timeout (Optional[float]): If this value is specified, use it as
|
||||
the definitive timeout (in seconds) for urlopen() operations.
|
||||
network_delay (Optional[float]): If using the timeout (which is
|
||||
a `timeout` for the Telegram servers operation),
|
||||
then `network_delay` as an extra delay (in seconds) to
|
||||
compensate for network latency. Defaults to 2.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the
|
||||
@@ -333,8 +297,7 @@ class Bot(TelegramObject):
|
||||
|
||||
url = '{0}/sendPhoto'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id,
|
||||
'photo': photo}
|
||||
data = {'chat_id': chat_id, 'photo': photo}
|
||||
|
||||
if caption:
|
||||
data['caption'] = caption
|
||||
@@ -343,13 +306,7 @@ class Bot(TelegramObject):
|
||||
|
||||
@log
|
||||
@message
|
||||
def sendAudio(self,
|
||||
chat_id,
|
||||
audio,
|
||||
duration=None,
|
||||
performer=None,
|
||||
title=None,
|
||||
**kwargs):
|
||||
def sendAudio(self, chat_id, audio, duration=None, performer=None, title=None, **kwargs):
|
||||
"""Use this method to send audio files, if you want Telegram clients to
|
||||
display them in the music player. Your audio must be in an .mp3 format.
|
||||
On success, the sent Message is returned. Bots can currently send audio
|
||||
@@ -387,10 +344,6 @@ class Bot(TelegramObject):
|
||||
keyboard or to force a reply from the user.
|
||||
timeout (Optional[float]): If this value is specified, use it as
|
||||
the definitive timeout (in seconds) for urlopen() operations.
|
||||
network_delay (Optional[float]): If using the timeout (which is
|
||||
a `timeout` for the Telegram servers operation),
|
||||
then `network_delay` as an extra delay (in seconds) to
|
||||
compensate for network latency. Defaults to 2.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the
|
||||
@@ -403,8 +356,7 @@ class Bot(TelegramObject):
|
||||
|
||||
url = '{0}/sendAudio'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id,
|
||||
'audio': audio}
|
||||
data = {'chat_id': chat_id, 'audio': audio}
|
||||
|
||||
if duration:
|
||||
data['duration'] = duration
|
||||
@@ -417,12 +369,7 @@ class Bot(TelegramObject):
|
||||
|
||||
@log
|
||||
@message
|
||||
def sendDocument(self,
|
||||
chat_id,
|
||||
document,
|
||||
filename=None,
|
||||
caption=None,
|
||||
**kwargs):
|
||||
def sendDocument(self, chat_id, document, filename=None, caption=None, **kwargs):
|
||||
"""Use this method to send general files.
|
||||
|
||||
Args:
|
||||
@@ -451,10 +398,6 @@ class Bot(TelegramObject):
|
||||
keyboard or to force a reply from the user.
|
||||
timeout (Optional[float]): If this value is specified, use it as
|
||||
the definitive timeout (in seconds) for urlopen() operations.
|
||||
network_delay (Optional[float]): If using the timeout (which is
|
||||
a `timeout` for the Telegram servers operation),
|
||||
then `network_delay` as an extra delay (in seconds) to
|
||||
compensate for network latency. Defaults to 2.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the
|
||||
@@ -467,8 +410,7 @@ class Bot(TelegramObject):
|
||||
|
||||
url = '{0}/sendDocument'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id,
|
||||
'document': document}
|
||||
data = {'chat_id': chat_id, 'document': document}
|
||||
|
||||
if filename:
|
||||
data['filename'] = filename
|
||||
@@ -479,10 +421,7 @@ class Bot(TelegramObject):
|
||||
|
||||
@log
|
||||
@message
|
||||
def sendSticker(self,
|
||||
chat_id,
|
||||
sticker,
|
||||
**kwargs):
|
||||
def sendSticker(self, chat_id, sticker, **kwargs):
|
||||
"""Use this method to send .webp stickers.
|
||||
|
||||
Args:
|
||||
@@ -505,10 +444,6 @@ class Bot(TelegramObject):
|
||||
keyboard or to force a reply from the user.
|
||||
timeout (Optional[float]): If this value is specified, use it as
|
||||
the definitive timeout (in seconds) for urlopen() operations.
|
||||
network_delay (Optional[float]): If using the timeout (which is
|
||||
a `timeout` for the Telegram servers operation),
|
||||
then `network_delay` as an extra delay (in seconds) to
|
||||
compensate for network latency. Defaults to 2.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the
|
||||
@@ -521,19 +456,13 @@ class Bot(TelegramObject):
|
||||
|
||||
url = '{0}/sendSticker'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id,
|
||||
'sticker': sticker}
|
||||
data = {'chat_id': chat_id, 'sticker': sticker}
|
||||
|
||||
return url, data
|
||||
|
||||
@log
|
||||
@message
|
||||
def sendVideo(self,
|
||||
chat_id,
|
||||
video,
|
||||
duration=None,
|
||||
caption=None,
|
||||
**kwargs):
|
||||
def sendVideo(self, chat_id, video, duration=None, caption=None, **kwargs):
|
||||
"""Use this method to send video files, Telegram clients support mp4
|
||||
videos (other formats may be sent as telegram.Document).
|
||||
|
||||
@@ -562,10 +491,6 @@ class Bot(TelegramObject):
|
||||
keyboard or to force a reply from the user.
|
||||
timeout (Optional[float]): If this value is specified, use it as
|
||||
the definitive timeout (in seconds) for urlopen() operations.
|
||||
network_delay (Optional[float]): If using the timeout (which is
|
||||
a `timeout` for the Telegram servers operation),
|
||||
then `network_delay` as an extra delay (in seconds) to
|
||||
compensate for network latency. Defaults to 2.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the
|
||||
@@ -578,8 +503,7 @@ class Bot(TelegramObject):
|
||||
|
||||
url = '{0}/sendVideo'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id,
|
||||
'video': video}
|
||||
data = {'chat_id': chat_id, 'video': video}
|
||||
|
||||
if duration:
|
||||
data['duration'] = duration
|
||||
@@ -590,11 +514,7 @@ class Bot(TelegramObject):
|
||||
|
||||
@log
|
||||
@message
|
||||
def sendVoice(self,
|
||||
chat_id,
|
||||
voice,
|
||||
duration=None,
|
||||
**kwargs):
|
||||
def sendVoice(self, chat_id, voice, duration=None, **kwargs):
|
||||
"""Use this method to send audio files, if you want Telegram clients to
|
||||
display the file as a playable voice message. For this to work, your
|
||||
audio must be in an .ogg file encoded with OPUS (other formats may be
|
||||
@@ -624,10 +544,6 @@ class Bot(TelegramObject):
|
||||
keyboard or to force a reply from the user.
|
||||
timeout (Optional[float]): If this value is specified, use it as
|
||||
the definitive timeout (in seconds) for urlopen() operations.
|
||||
network_delay (Optional[float]): If using the timeout (which is
|
||||
a `timeout` for the Telegram servers operation),
|
||||
then `network_delay` as an extra delay (in seconds) to
|
||||
compensate for network latency. Defaults to 2.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the
|
||||
@@ -640,8 +556,7 @@ class Bot(TelegramObject):
|
||||
|
||||
url = '{0}/sendVoice'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id,
|
||||
'voice': voice}
|
||||
data = {'chat_id': chat_id, 'voice': voice}
|
||||
|
||||
if duration:
|
||||
data['duration'] = duration
|
||||
@@ -650,11 +565,7 @@ class Bot(TelegramObject):
|
||||
|
||||
@log
|
||||
@message
|
||||
def sendLocation(self,
|
||||
chat_id,
|
||||
latitude,
|
||||
longitude,
|
||||
**kwargs):
|
||||
def sendLocation(self, chat_id, latitude, longitude, **kwargs):
|
||||
"""Use this method to send point on the map.
|
||||
|
||||
Args:
|
||||
@@ -677,10 +588,6 @@ class Bot(TelegramObject):
|
||||
keyboard or to force a reply from the user.
|
||||
timeout (Optional[float]): If this value is specified, use it as
|
||||
the definitive timeout (in seconds) for urlopen() operations.
|
||||
network_delay (Optional[float]): If using the timeout (which is
|
||||
a `timeout` for the Telegram servers operation),
|
||||
then `network_delay` as an extra delay (in seconds) to
|
||||
compensate for network latency. Defaults to 2.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the
|
||||
@@ -693,22 +600,19 @@ class Bot(TelegramObject):
|
||||
|
||||
url = '{0}/sendLocation'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id,
|
||||
'latitude': latitude,
|
||||
'longitude': longitude}
|
||||
data = {'chat_id': chat_id, 'latitude': latitude, 'longitude': longitude}
|
||||
|
||||
return url, data
|
||||
|
||||
@log
|
||||
@message
|
||||
def sendVenue(self,
|
||||
chat_id,
|
||||
latitude,
|
||||
longitude,
|
||||
title,
|
||||
address,
|
||||
foursquare_id=None,
|
||||
**kwargs):
|
||||
def sendVenue(
|
||||
self, chat_id,
|
||||
latitude,
|
||||
longitude,
|
||||
title, address,
|
||||
foursquare_id=None,
|
||||
**kwargs):
|
||||
"""
|
||||
Use this method to send information about a venue.
|
||||
|
||||
@@ -739,10 +643,6 @@ class Bot(TelegramObject):
|
||||
keyboard or to force a reply from the user.
|
||||
timeout (Optional[float]): If this value is specified, use it as
|
||||
the definitive timeout (in seconds) for urlopen() operations.
|
||||
network_delay (Optional[float]): If using the timeout (which is
|
||||
a `timeout` for the Telegram servers operation),
|
||||
then `network_delay` as an extra delay (in seconds) to
|
||||
compensate for network latency. Defaults to 2.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the
|
||||
@@ -768,12 +668,7 @@ class Bot(TelegramObject):
|
||||
|
||||
@log
|
||||
@message
|
||||
def sendContact(self,
|
||||
chat_id,
|
||||
phone_number,
|
||||
first_name,
|
||||
last_name=None,
|
||||
**kwargs):
|
||||
def sendContact(self, chat_id, phone_number, first_name, last_name=None, **kwargs):
|
||||
"""
|
||||
Use this method to send phone contacts.
|
||||
|
||||
@@ -800,10 +695,6 @@ class Bot(TelegramObject):
|
||||
keyboard or to force a reply from the user.
|
||||
timeout (Optional[float]): If this value is specified, use it as
|
||||
the definitive timeout (in seconds) for urlopen() operations.
|
||||
network_delay (Optional[float]): If using the timeout (which is
|
||||
a `timeout` for the Telegram servers operation),
|
||||
then `network_delay` as an extra delay (in seconds) to
|
||||
compensate for network latency. Defaults to 2.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the
|
||||
@@ -816,9 +707,7 @@ class Bot(TelegramObject):
|
||||
|
||||
url = '{0}/sendContact'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id,
|
||||
'phone_number': phone_number,
|
||||
'first_name': first_name}
|
||||
data = {'chat_id': chat_id, 'phone_number': phone_number, 'first_name': first_name}
|
||||
|
||||
if last_name:
|
||||
data['last_name'] = last_name
|
||||
@@ -827,10 +716,7 @@ class Bot(TelegramObject):
|
||||
|
||||
@log
|
||||
@message
|
||||
def sendChatAction(self,
|
||||
chat_id,
|
||||
action,
|
||||
**kwargs):
|
||||
def sendChatAction(self, chat_id, action, **kwargs):
|
||||
"""Use this method when you need to tell the user that something is
|
||||
happening on the bot's side. The status is set for 5 seconds or less
|
||||
(when a message arrives from your bot, Telegram clients clear its
|
||||
@@ -852,8 +738,7 @@ class Bot(TelegramObject):
|
||||
|
||||
url = '{0}/sendChatAction'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id,
|
||||
'action': action}
|
||||
data = {'chat_id': chat_id, 'action': action}
|
||||
|
||||
return url, data
|
||||
|
||||
@@ -895,10 +780,6 @@ class Bot(TelegramObject):
|
||||
Keyword Args:
|
||||
timeout (Optional[float]): If this value is specified, use it as
|
||||
the definitive timeout (in seconds) for urlopen() operations.
|
||||
network_delay (Optional[float]): If using the timeout (which is
|
||||
a `timeout` for the Telegram servers operation),
|
||||
then `network_delay` as an extra delay (in seconds) to
|
||||
compensate for network latency. Defaults to 2.
|
||||
|
||||
Returns:
|
||||
bool: On success, `True` is returned.
|
||||
@@ -912,8 +793,7 @@ class Bot(TelegramObject):
|
||||
|
||||
results = [res.to_dict() for res in results]
|
||||
|
||||
data = {'inline_query_id': inline_query_id,
|
||||
'results': results}
|
||||
data = {'inline_query_id': inline_query_id, 'results': results}
|
||||
|
||||
if cache_time or cache_time == 0:
|
||||
data['cache_time'] = cache_time
|
||||
@@ -926,18 +806,12 @@ class Bot(TelegramObject):
|
||||
if switch_pm_parameter:
|
||||
data['switch_pm_parameter'] = switch_pm_parameter
|
||||
|
||||
result = request.post(url, data,
|
||||
timeout=kwargs.get('timeout'),
|
||||
network_delay=kwargs.get('network_delay'))
|
||||
result = request.post(url, data, timeout=kwargs.get('timeout'))
|
||||
|
||||
return result
|
||||
|
||||
@log
|
||||
def getUserProfilePhotos(self,
|
||||
user_id,
|
||||
offset=None,
|
||||
limit=100,
|
||||
**kwargs):
|
||||
def getUserProfilePhotos(self, user_id, offset=None, limit=100, **kwargs):
|
||||
"""Use this method to get a list of profile pictures for a user.
|
||||
|
||||
Args:
|
||||
@@ -953,10 +827,6 @@ class Bot(TelegramObject):
|
||||
Keyword Args:
|
||||
timeout (Optional[float]): If this value is specified, use it as
|
||||
the definitive timeout (in seconds) for urlopen() operations.
|
||||
network_delay (Optional[float]): If using the timeout (which is
|
||||
a `timeout` for the Telegram servers operation),
|
||||
then `network_delay` as an extra delay (in seconds) to
|
||||
compensate for network latency. Defaults to 2.
|
||||
|
||||
Returns:
|
||||
list[:class:`telegram.UserProfilePhotos`]: A list of
|
||||
@@ -976,16 +846,12 @@ class Bot(TelegramObject):
|
||||
if limit:
|
||||
data['limit'] = limit
|
||||
|
||||
result = request.post(url, data,
|
||||
timeout=kwargs.get('timeout'),
|
||||
network_delay=kwargs.get('network_delay'))
|
||||
result = request.post(url, data, timeout=kwargs.get('timeout'))
|
||||
|
||||
return UserProfilePhotos.de_json(result)
|
||||
|
||||
@log
|
||||
def getFile(self,
|
||||
file_id,
|
||||
**kwargs):
|
||||
def getFile(self, file_id, **kwargs):
|
||||
"""Use this method to get basic info about a file and prepare it for
|
||||
downloading. For the moment, bots can download files of up to 20MB in
|
||||
size.
|
||||
@@ -997,10 +863,6 @@ class Bot(TelegramObject):
|
||||
Keyword Args:
|
||||
timeout (Optional[float]): If this value is specified, use it as
|
||||
the definitive timeout (in seconds) for urlopen() operations.
|
||||
network_delay (Optional[float]): If using the timeout (which is
|
||||
a `timeout` for the Telegram servers operation),
|
||||
then `network_delay` as an extra delay (in seconds) to
|
||||
compensate for network latency. Defaults to 2.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.File`: On success, a :class:`telegram.File`
|
||||
@@ -1015,21 +877,15 @@ class Bot(TelegramObject):
|
||||
|
||||
data = {'file_id': file_id}
|
||||
|
||||
result = request.post(url, data,
|
||||
timeout=kwargs.get('timeout'),
|
||||
network_delay=kwargs.get('network_delay'))
|
||||
result = request.post(url, data, timeout=kwargs.get('timeout'))
|
||||
|
||||
if result.get('file_path'):
|
||||
result['file_path'] = '%s/%s' % (self.base_file_url,
|
||||
result['file_path'])
|
||||
result['file_path'] = '%s/%s' % (self.base_file_url, result['file_path'])
|
||||
|
||||
return File.de_json(result)
|
||||
|
||||
@log
|
||||
def kickChatMember(self,
|
||||
chat_id,
|
||||
user_id,
|
||||
**kwargs):
|
||||
def kickChatMember(self, chat_id, user_id, **kwargs):
|
||||
"""Use this method to kick a user from a group or a supergroup. In the
|
||||
case of supergroups, the user will not be able to return to the group
|
||||
on their own using invite links, etc., unless unbanned first. The bot
|
||||
@@ -1045,10 +901,6 @@ class Bot(TelegramObject):
|
||||
Keyword Args:
|
||||
timeout (Optional[float]): If this value is specified, use it as
|
||||
the definitive timeout (in seconds) for urlopen() operations.
|
||||
network_delay (Optional[float]): If using the timeout (which is
|
||||
a `timeout` for the Telegram servers operation),
|
||||
then `network_delay` as an extra delay (in seconds) to
|
||||
compensate for network latency. Defaults to 2.
|
||||
|
||||
Returns:
|
||||
bool: On success, `True` is returned.
|
||||
@@ -1060,20 +912,14 @@ class Bot(TelegramObject):
|
||||
|
||||
url = '{0}/kickChatMember'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id,
|
||||
'user_id': user_id}
|
||||
data = {'chat_id': chat_id, 'user_id': user_id}
|
||||
|
||||
result = request.post(url, data,
|
||||
timeout=kwargs.get('timeout'),
|
||||
network_delay=kwargs.get('network_delay'))
|
||||
result = request.post(url, data, timeout=kwargs.get('timeout'))
|
||||
|
||||
return result
|
||||
|
||||
@log
|
||||
def unbanChatMember(self,
|
||||
chat_id,
|
||||
user_id,
|
||||
**kwargs):
|
||||
def unbanChatMember(self, chat_id, user_id, **kwargs):
|
||||
"""Use this method to unban a previously kicked user in a supergroup.
|
||||
The user will not return to the group automatically, but will be able
|
||||
to join via link, etc. The bot must be an administrator in the group
|
||||
@@ -1089,10 +935,6 @@ class Bot(TelegramObject):
|
||||
Keyword Args:
|
||||
timeout (Optional[float]): If this value is specified, use it as
|
||||
the definitive timeout (in seconds) for urlopen() operations.
|
||||
network_delay (Optional[float]): If using the timeout (which is
|
||||
a `timeout` for the Telegram servers operation),
|
||||
then `network_delay` as an extra delay (in seconds) to
|
||||
compensate for network latency. Defaults to 2.
|
||||
|
||||
Returns:
|
||||
bool: On success, `True` is returned.
|
||||
@@ -1104,21 +946,14 @@ class Bot(TelegramObject):
|
||||
|
||||
url = '{0}/unbanChatMember'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id,
|
||||
'user_id': user_id}
|
||||
data = {'chat_id': chat_id, 'user_id': user_id}
|
||||
|
||||
result = request.post(url, data,
|
||||
timeout=kwargs.get('timeout'),
|
||||
network_delay=kwargs.get('network_delay'))
|
||||
result = request.post(url, data, timeout=kwargs.get('timeout'))
|
||||
|
||||
return result
|
||||
|
||||
@log
|
||||
def answerCallbackQuery(self,
|
||||
callback_query_id,
|
||||
text=None,
|
||||
show_alert=False,
|
||||
**kwargs):
|
||||
def answerCallbackQuery(self, callback_query_id, text=None, show_alert=False, **kwargs):
|
||||
"""Use this method to send answers to callback queries sent from
|
||||
inline keyboards. The answer will be displayed to the user as a
|
||||
notification at the top of the chat screen or as an alert.
|
||||
@@ -1157,14 +992,11 @@ class Bot(TelegramObject):
|
||||
if show_alert:
|
||||
data['show_alert'] = show_alert
|
||||
|
||||
result = request.post(url, data,
|
||||
timeout=kwargs.get('timeout'),
|
||||
network_delay=kwargs.get('network_delay'))
|
||||
result = request.post(url, data, timeout=kwargs.get('timeout'))
|
||||
|
||||
return result
|
||||
|
||||
@log
|
||||
@message
|
||||
def editMessageText(self,
|
||||
text,
|
||||
chat_id=None,
|
||||
@@ -1172,6 +1004,7 @@ class Bot(TelegramObject):
|
||||
inline_message_id=None,
|
||||
parse_mode=None,
|
||||
disable_web_page_preview=None,
|
||||
reply_markup=None,
|
||||
**kwargs):
|
||||
"""Use this method to edit text messages sent by the bot or via the bot
|
||||
(for inline bots).
|
||||
@@ -1194,16 +1027,12 @@ class Bot(TelegramObject):
|
||||
italic, fixed-width text or inline URLs in your bot's message.
|
||||
disable_web_page_preview:
|
||||
Disables link previews for links in this message.
|
||||
reply_markup:
|
||||
A JSON-serialized object for an inline keyboard.
|
||||
|
||||
Keyword Args:
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]):
|
||||
A JSON-serialized object for an inline keyboard.
|
||||
timeout (Optional[float]): If this value is specified, use it as
|
||||
the definitive timeout (in seconds) for urlopen() operations.
|
||||
network_delay (Optional[float]): If using the timeout (which is
|
||||
a `timeout` for the Telegram servers operation),
|
||||
then `network_delay` as an extra delay (in seconds) to
|
||||
compensate for network latency. Defaults to 2.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, if edited message is sent by
|
||||
@@ -1229,8 +1058,15 @@ class Bot(TelegramObject):
|
||||
data['parse_mode'] = parse_mode
|
||||
if disable_web_page_preview:
|
||||
data['disable_web_page_preview'] = disable_web_page_preview
|
||||
if reply_markup:
|
||||
if isinstance(reply_markup, ReplyMarkup):
|
||||
data['reply_markup'] = reply_markup.to_json()
|
||||
else:
|
||||
data['reply_markup'] = reply_markup
|
||||
|
||||
return url, data
|
||||
result = request.post(url, data, timeout=kwargs.get('timeout'))
|
||||
|
||||
return Message.de_json(result)
|
||||
|
||||
@log
|
||||
@message
|
||||
@@ -1259,10 +1095,6 @@ class Bot(TelegramObject):
|
||||
A JSON-serialized object for an inline keyboard.
|
||||
timeout (Optional[float]): If this value is specified, use it as
|
||||
the definitive timeout (in seconds) for urlopen() operations.
|
||||
network_delay (Optional[float]): If using the timeout (which is
|
||||
a `timeout` for the Telegram servers operation),
|
||||
then `network_delay` as an extra delay (in seconds) to
|
||||
compensate for network latency. Defaults to 2.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, if edited message is sent by
|
||||
@@ -1291,11 +1123,10 @@ class Bot(TelegramObject):
|
||||
|
||||
@log
|
||||
@message
|
||||
def editMessageReplyMarkup(self,
|
||||
chat_id=None,
|
||||
message_id=None,
|
||||
inline_message_id=None,
|
||||
**kwargs):
|
||||
def editMessageReplyMarkup(
|
||||
self, chat_id=None,
|
||||
message_id=None, inline_message_id=None,
|
||||
**kwargs):
|
||||
"""Use this method to edit only the reply markup of messages sent by
|
||||
the bot or via the bot (for inline bots).
|
||||
|
||||
@@ -1314,10 +1145,6 @@ class Bot(TelegramObject):
|
||||
A JSON-serialized object for an inline keyboard.
|
||||
timeout (Optional[float]): If this value is specified, use it as
|
||||
the definitive timeout (in seconds) for urlopen() operations.
|
||||
network_delay (Optional[float]): If using the timeout (which is
|
||||
a `timeout` for the Telegram servers operation),
|
||||
then `network_delay` as an extra delay (in seconds) to
|
||||
compensate for network latency. Defaults to 2.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, if edited message is sent by
|
||||
@@ -1343,10 +1170,7 @@ class Bot(TelegramObject):
|
||||
return url, data
|
||||
|
||||
@log
|
||||
def getUpdates(self,
|
||||
offset=None,
|
||||
limit=100,
|
||||
**kwargs):
|
||||
def getUpdates(self, offset=None, limit=100, timeout=0, network_delay=.2):
|
||||
"""Use this method to receive incoming updates using long polling.
|
||||
|
||||
Args:
|
||||
@@ -1359,17 +1183,17 @@ class Bot(TelegramObject):
|
||||
limit:
|
||||
Limits the number of updates to be retrieved. Values between 1-100
|
||||
are accepted. Defaults to 100.
|
||||
|
||||
Keyword Args:
|
||||
timeout (Optional[float]): If this value is specified, use it as
|
||||
the definitive timeout (in seconds) for urlopen() operations.
|
||||
network_delay (Optional[float]): If using the timeout (which is
|
||||
a `timeout` for the Telegram servers operation),
|
||||
then `network_delay` as an extra delay (in seconds) to
|
||||
compensate for network latency. Defaults to 2.
|
||||
timeout:
|
||||
Timeout in seconds for long polling. Defaults to 0, i.e. usual
|
||||
short polling.
|
||||
network_delay:
|
||||
Additional timeout in seconds to allow the response from Telegram
|
||||
to take some time when using long polling. Defaults to 2, which
|
||||
should be enough for most connections. Increase it if it takes very
|
||||
long for data to be transmitted from and to the Telegram servers.
|
||||
|
||||
Returns:
|
||||
list[:class:`telegram.Message`]: A list of :class:`telegram.Update`
|
||||
list[:class:`telegram.Update`]: A list of :class:`telegram.Update`
|
||||
objects are returned.
|
||||
|
||||
Raises:
|
||||
@@ -1379,30 +1203,26 @@ class Bot(TelegramObject):
|
||||
|
||||
url = '{0}/getUpdates'.format(self.base_url)
|
||||
|
||||
data = {}
|
||||
data = {'timeout': timeout}
|
||||
|
||||
if offset:
|
||||
data['offset'] = offset
|
||||
if limit:
|
||||
data['limit'] = limit
|
||||
|
||||
result = request.post(url, data,
|
||||
timeout=kwargs.get('timeout'),
|
||||
network_delay=kwargs.get('network_delay'))
|
||||
urlopen_timeout = timeout + network_delay
|
||||
|
||||
result = request.post(url, data, timeout=urlopen_timeout)
|
||||
|
||||
if result:
|
||||
self.logger.debug(
|
||||
'Getting updates: %s', [u['update_id'] for u in result])
|
||||
self.logger.debug('Getting updates: %s', [u['update_id'] for u in result])
|
||||
else:
|
||||
self.logger.debug('No new updates found.')
|
||||
|
||||
return [Update.de_json(x) for x in result]
|
||||
|
||||
@log
|
||||
def setWebhook(self,
|
||||
webhook_url=None,
|
||||
certificate=None,
|
||||
**kwargs):
|
||||
def setWebhook(self, webhook_url=None, certificate=None, **kwargs):
|
||||
"""Use this method to specify a url and receive incoming updates via an
|
||||
outgoing webhook. Whenever there is an update for the bot, we will send
|
||||
an HTTPS POST request to the specified url, containing a
|
||||
@@ -1417,10 +1237,6 @@ class Bot(TelegramObject):
|
||||
Keyword Args:
|
||||
timeout (Optional[float]): If this value is specified, use it as
|
||||
the definitive timeout (in seconds) for urlopen() operations.
|
||||
network_delay (Optional[float]): If using the timeout (which is
|
||||
a `timeout` for the Telegram servers operation),
|
||||
then `network_delay` as an extra delay (in seconds) to
|
||||
compensate for network latency. Defaults to 2.
|
||||
|
||||
Returns:
|
||||
bool: On success, `True` is returned.
|
||||
@@ -1439,9 +1255,7 @@ class Bot(TelegramObject):
|
||||
if certificate:
|
||||
data['certificate'] = certificate
|
||||
|
||||
result = request.post(url, data,
|
||||
timeout=kwargs.get('timeout'),
|
||||
network_delay=kwargs.get('network_delay'))
|
||||
result = request.post(url, data, timeout=kwargs.get('timeout'))
|
||||
|
||||
return result
|
||||
|
||||
@@ -1452,9 +1266,7 @@ class Bot(TelegramObject):
|
||||
return Bot(**data)
|
||||
|
||||
def to_dict(self):
|
||||
data = {'id': self.id,
|
||||
'username': self.username,
|
||||
'first_name': self.username}
|
||||
data = {'id': self.id, 'username': self.username, 'first_name': self.username}
|
||||
|
||||
if self.last_name:
|
||||
data['last_name'] = self.last_name
|
||||
@@ -1462,6 +1274,31 @@ class Bot(TelegramObject):
|
||||
return data
|
||||
|
||||
def __reduce__(self):
|
||||
return (self.__class__, (self.token,
|
||||
self.base_url.replace(self.token, ''),
|
||||
return (self.__class__, (self.token, self.base_url.replace(self.token, ''),
|
||||
self.base_file_url.replace(self.token, '')))
|
||||
|
||||
# snake_case (PEP8) aliases
|
||||
get_me = getMe
|
||||
send_message = sendMessage
|
||||
forward_message = forwardMessage
|
||||
send_photo = sendPhoto
|
||||
send_audio = sendAudio
|
||||
send_document = sendDocument
|
||||
send_sticker = sendSticker
|
||||
send_video = sendVideo
|
||||
send_voice = sendVoice
|
||||
send_location = sendLocation
|
||||
send_venue = sendVenue
|
||||
send_contact = sendContact
|
||||
send_chat_action = sendChatAction
|
||||
answer_inline_query = answerInlineQuery
|
||||
get_user_profile_photos = getUserProfilePhotos
|
||||
get_file = getFile
|
||||
kick_chat_member = kickChatMember
|
||||
unban_chat_member = unbanChatMember
|
||||
answer_callback_query = answerCallbackQuery
|
||||
edit_message_text = editMessageText
|
||||
edit_message_caption = editMessageCaption
|
||||
edit_message_reply_markup = editMessageReplyMarkup
|
||||
get_updates = getUpdates
|
||||
set_webhook = setWebhook
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a Telegram
|
||||
CallbackQuery"""
|
||||
|
||||
@@ -26,11 +25,7 @@ from telegram import TelegramObject, Message, User
|
||||
class CallbackQuery(TelegramObject):
|
||||
"""This object represents a Telegram CallbackQuery."""
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
from_user,
|
||||
data,
|
||||
**kwargs):
|
||||
def __init__(self, id, from_user, data, **kwargs):
|
||||
# Required
|
||||
self.id = id
|
||||
self.from_user = from_user
|
||||
|
||||
+1
-5
@@ -17,7 +17,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a Telegram Chat."""
|
||||
|
||||
from telegram import TelegramObject
|
||||
@@ -43,10 +42,7 @@ class Chat(TelegramObject):
|
||||
type (Optional[str]):
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
type,
|
||||
**kwargs):
|
||||
def __init__(self, id, type, **kwargs):
|
||||
# Required
|
||||
self.id = int(id)
|
||||
self.type = type
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a Telegram ChatAction."""
|
||||
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""
|
||||
This module contains a object that represents a Telegram ChosenInlineResult
|
||||
"""
|
||||
@@ -42,12 +41,7 @@ class ChosenInlineResult(TelegramObject):
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
result_id,
|
||||
from_user,
|
||||
query,
|
||||
location=None,
|
||||
inline_message_id=None):
|
||||
def __init__(self, result_id, from_user, query, location=None, inline_message_id=None):
|
||||
# Required
|
||||
self.result_id = result_id
|
||||
self.from_user = from_user
|
||||
|
||||
+1
-5
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a Telegram Contact."""
|
||||
|
||||
from telegram import TelegramObject
|
||||
@@ -41,10 +40,7 @@ class Contact(TelegramObject):
|
||||
user_id (Optional[int]):
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
phone_number,
|
||||
first_name,
|
||||
**kwargs):
|
||||
def __init__(self, phone_number, first_name, **kwargs):
|
||||
# Required
|
||||
self.phone_number = str(phone_number)
|
||||
self.first_name = first_name
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a Telegram Document."""
|
||||
|
||||
from telegram import PhotoSize, TelegramObject
|
||||
@@ -43,9 +42,7 @@ class Document(TelegramObject):
|
||||
file_size (Optional[int]):
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
file_id,
|
||||
**kwargs):
|
||||
def __init__(self, file_id, **kwargs):
|
||||
# Required
|
||||
self.file_id = str(file_id)
|
||||
# Optionals
|
||||
|
||||
+23
-23
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python
|
||||
# flake8: noqa
|
||||
# pylint: disable=C0103,C0301,R0903
|
||||
# pylint: disable=C0103,R0903
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2016
|
||||
@@ -18,7 +18,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents an Emoji."""
|
||||
|
||||
from future.utils import bytes_to_native_str as n
|
||||
@@ -163,26 +162,26 @@ class Emoji(object):
|
||||
SQUARED_SOS = n(b'\xF0\x9F\x86\x98')
|
||||
SQUARED_UP_WITH_EXCLAMATION_MARK = n(b'\xF0\x9F\x86\x99')
|
||||
SQUARED_VS = n(b'\xF0\x9F\x86\x9A')
|
||||
REGIONAL_INDICATOR_SYMBOL_LETTER_D_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_E \
|
||||
= n(b'\xF0\x9F\x87\xA9\xF0\x9F\x87\xAA')
|
||||
REGIONAL_INDICATOR_SYMBOL_LETTER_G_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_B \
|
||||
= n(b'\xF0\x9F\x87\xAC\xF0\x9F\x87\xA7')
|
||||
REGIONAL_INDICATOR_SYMBOL_LETTER_C_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_N \
|
||||
= n(b'\xF0\x9F\x87\xA8\xF0\x9F\x87\xB3')
|
||||
REGIONAL_INDICATOR_SYMBOL_LETTER_J_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_P \
|
||||
= n(b'\xF0\x9F\x87\xAF\xF0\x9F\x87\xB5')
|
||||
REGIONAL_INDICATOR_SYMBOL_LETTER_K_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_R \
|
||||
= n(b'\xF0\x9F\x87\xB0\xF0\x9F\x87\xB7')
|
||||
REGIONAL_INDICATOR_SYMBOL_LETTER_F_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_R \
|
||||
= n(b'\xF0\x9F\x87\xAB\xF0\x9F\x87\xB7')
|
||||
REGIONAL_INDICATOR_SYMBOL_LETTER_E_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_S \
|
||||
= n(b'\xF0\x9F\x87\xAA\xF0\x9F\x87\xB8')
|
||||
REGIONAL_INDICATOR_SYMBOL_LETTER_I_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_T \
|
||||
= n(b'\xF0\x9F\x87\xAE\xF0\x9F\x87\xB9')
|
||||
REGIONAL_INDICATOR_SYMBOL_LETTER_U_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_S \
|
||||
= n(b'\xF0\x9F\x87\xBA\xF0\x9F\x87\xB8')
|
||||
REGIONAL_INDICATOR_SYMBOL_LETTER_R_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_U \
|
||||
= n(b'\xF0\x9F\x87\xB7\xF0\x9F\x87\xBA')
|
||||
REGIONAL_INDICATOR_SYMBOL_LETTER_D_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_E = n(
|
||||
b'\xF0\x9F\x87\xA9\xF0\x9F\x87\xAA')
|
||||
REGIONAL_INDICATOR_SYMBOL_LETTER_G_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_B = n(
|
||||
b'\xF0\x9F\x87\xAC\xF0\x9F\x87\xA7')
|
||||
REGIONAL_INDICATOR_SYMBOL_LETTER_C_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_N = n(
|
||||
b'\xF0\x9F\x87\xA8\xF0\x9F\x87\xB3')
|
||||
REGIONAL_INDICATOR_SYMBOL_LETTER_J_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_P = n(
|
||||
b'\xF0\x9F\x87\xAF\xF0\x9F\x87\xB5')
|
||||
REGIONAL_INDICATOR_SYMBOL_LETTER_K_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_R = n(
|
||||
b'\xF0\x9F\x87\xB0\xF0\x9F\x87\xB7')
|
||||
REGIONAL_INDICATOR_SYMBOL_LETTER_F_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_R = n(
|
||||
b'\xF0\x9F\x87\xAB\xF0\x9F\x87\xB7')
|
||||
REGIONAL_INDICATOR_SYMBOL_LETTER_E_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_S = n(
|
||||
b'\xF0\x9F\x87\xAA\xF0\x9F\x87\xB8')
|
||||
REGIONAL_INDICATOR_SYMBOL_LETTER_I_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_T = n(
|
||||
b'\xF0\x9F\x87\xAE\xF0\x9F\x87\xB9')
|
||||
REGIONAL_INDICATOR_SYMBOL_LETTER_U_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_S = n(
|
||||
b'\xF0\x9F\x87\xBA\xF0\x9F\x87\xB8')
|
||||
REGIONAL_INDICATOR_SYMBOL_LETTER_R_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_U = n(
|
||||
b'\xF0\x9F\x87\xB7\xF0\x9F\x87\xBA')
|
||||
SQUARED_KATAKANA_KOKO = n(b'\xF0\x9F\x88\x81')
|
||||
SQUARED_KATAKANA_SA = n(b'\xF0\x9F\x88\x82')
|
||||
SQUARED_CJK_UNIFIED_IDEOGRAPH_7121 = n(b'\xF0\x9F\x88\x9A')
|
||||
@@ -858,7 +857,8 @@ class Emoji(object):
|
||||
NO_MOBILE_PHONES = n(b'\xF0\x9F\x93\xB5')
|
||||
TWISTED_RIGHTWARDS_ARROWS = n(b'\xF0\x9F\x94\x80')
|
||||
CLOCKWISE_RIGHTWARDS_AND_LEFTWARDS_OPEN_CIRCLE_ARROWS = n(b'\xF0\x9F\x94\x81')
|
||||
CLOCKWISE_RIGHTWARDS_AND_LEFTWARDS_OPEN_CIRCLE_ARROWS_WITH_CIRCLED_ONE_OVERLAY = n(b'\xF0\x9F\x94\x82')
|
||||
CLOCKWISE_RIGHTWARDS_AND_LEFTWARDS_OPEN_CIRCLE_ARROWS_WITH_CIRCLED_ONE_OVERLAY = n(
|
||||
b'\xF0\x9F\x94\x82')
|
||||
ANTICLOCKWISE_DOWNWARDS_AND_UPWARDS_OPEN_CIRCLE_ARROWS = n(b'\xF0\x9F\x94\x84')
|
||||
LOW_BRIGHTNESS_SYMBOL = n(b'\xF0\x9F\x94\x85')
|
||||
HIGH_BRIGHTNESS_SYMBOL = n(b'\xF0\x9F\x94\x86')
|
||||
|
||||
+3
-1
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a Telegram Error."""
|
||||
|
||||
|
||||
@@ -62,11 +61,13 @@ class TelegramError(Exception):
|
||||
|
||||
|
||||
class Unauthorized(TelegramError):
|
||||
|
||||
def __init__(self):
|
||||
super(Unauthorized, self).__init__('Unauthorized')
|
||||
|
||||
|
||||
class InvalidToken(TelegramError):
|
||||
|
||||
def __init__(self):
|
||||
super(InvalidToken, self).__init__('Invalid token')
|
||||
|
||||
@@ -76,5 +77,6 @@ class NetworkError(TelegramError):
|
||||
|
||||
|
||||
class TimedOut(NetworkError):
|
||||
|
||||
def __init__(self):
|
||||
super(TimedOut, self).__init__('Timed out')
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""Extensions over the Telegram Bot API to facilitate bot making"""
|
||||
|
||||
from .dispatcher import Dispatcher
|
||||
@@ -34,6 +33,6 @@ from .stringregexhandler import StringRegexHandler
|
||||
from .typehandler import TypeHandler
|
||||
|
||||
__all__ = ('Dispatcher', 'JobQueue', 'Updater', 'CallbackQueryHandler',
|
||||
'ChosenInlineResultHandler', 'CommandHandler', 'Handler',
|
||||
'InlineQueryHandler', 'MessageHandler', 'Filters', 'RegexHandler',
|
||||
'StringCommandHandler', 'StringRegexHandler', 'TypeHandler')
|
||||
'ChosenInlineResultHandler', 'CommandHandler', 'Handler', 'InlineQueryHandler',
|
||||
'MessageHandler', 'Filters', 'RegexHandler', 'StringCommandHandler',
|
||||
'StringRegexHandler', 'TypeHandler')
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
""" This module contains the CallbackQueryHandler class """
|
||||
|
||||
from .handler import Handler
|
||||
from telegram import Update
|
||||
from telegram.utils.deprecate import deprecate
|
||||
|
||||
|
||||
class CallbackQueryHandler(Handler):
|
||||
@@ -29,7 +29,7 @@ class CallbackQueryHandler(Handler):
|
||||
|
||||
Args:
|
||||
callback (function): A function that takes ``bot, update`` as
|
||||
positional arguments. It will be called when the ``checkUpdate``
|
||||
positional arguments. It will be called when the ``check_update``
|
||||
has determined that an update should be processed by this handler.
|
||||
pass_update_queue (optional[bool]): If the handler should be passed the
|
||||
update queue as a keyword argument called ``update_queue``. It can
|
||||
@@ -39,10 +39,15 @@ class CallbackQueryHandler(Handler):
|
||||
def __init__(self, callback, pass_update_queue=False):
|
||||
super(CallbackQueryHandler, self).__init__(callback, pass_update_queue)
|
||||
|
||||
def checkUpdate(self, update):
|
||||
def check_update(self, update):
|
||||
return isinstance(update, Update) and update.callback_query
|
||||
|
||||
def handleUpdate(self, update, dispatcher):
|
||||
optional_args = self.collectOptionalArgs(dispatcher)
|
||||
def handle_update(self, update, dispatcher):
|
||||
optional_args = self.collect_optional_args(dispatcher)
|
||||
|
||||
self.callback(dispatcher.bot, update, **optional_args)
|
||||
|
||||
# old non-PEP8 Handler methods
|
||||
m = "telegram.CallbackQueryHandler."
|
||||
checkUpdate = deprecate(check_update, m + "checkUpdate", m + "check_update")
|
||||
handleUpdate = deprecate(handle_update, m + "handleUpdate", m + "handle_update")
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
""" This module contains the ChosenInlineResultHandler class """
|
||||
|
||||
from .handler import Handler
|
||||
from telegram import Update
|
||||
from telegram.utils.deprecate import deprecate
|
||||
|
||||
|
||||
class ChosenInlineResultHandler(Handler):
|
||||
@@ -30,7 +30,7 @@ class ChosenInlineResultHandler(Handler):
|
||||
|
||||
Args:
|
||||
callback (function): A function that takes ``bot, update`` as
|
||||
positional arguments. It will be called when the ``checkUpdate``
|
||||
positional arguments. It will be called when the ``check_update``
|
||||
has determined that an update should be processed by this handler.
|
||||
pass_update_queue (optional[bool]): If the handler should be passed the
|
||||
update queue as a keyword argument called ``update_queue``. It can
|
||||
@@ -38,13 +38,17 @@ class ChosenInlineResultHandler(Handler):
|
||||
"""
|
||||
|
||||
def __init__(self, callback, pass_update_queue=False):
|
||||
super(ChosenInlineResultHandler, self).__init__(callback,
|
||||
pass_update_queue)
|
||||
super(ChosenInlineResultHandler, self).__init__(callback, pass_update_queue)
|
||||
|
||||
def checkUpdate(self, update):
|
||||
def check_update(self, update):
|
||||
return isinstance(update, Update) and update.chosen_inline_result
|
||||
|
||||
def handleUpdate(self, update, dispatcher):
|
||||
optional_args = self.collectOptionalArgs(dispatcher)
|
||||
def handle_update(self, update, dispatcher):
|
||||
optional_args = self.collect_optional_args(dispatcher)
|
||||
|
||||
self.callback(dispatcher.bot, update, **optional_args)
|
||||
|
||||
# old non-PEP8 Handler methods
|
||||
m = "telegram.ChosenInlineResultHandler."
|
||||
checkUpdate = deprecate(check_update, m + "checkUpdate", m + "check_update")
|
||||
handleUpdate = deprecate(handle_update, m + "handleUpdate", m + "handle_update")
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
""" This module contains the CommandHandler class """
|
||||
|
||||
from .handler import Handler
|
||||
from telegram import Update
|
||||
from telegram.utils.deprecate import deprecate
|
||||
|
||||
|
||||
class CommandHandler(Handler):
|
||||
@@ -32,7 +32,7 @@ class CommandHandler(Handler):
|
||||
Args:
|
||||
command (str): The name of the command this handler should listen for.
|
||||
callback (function): A function that takes ``bot, update`` as
|
||||
positional arguments. It will be called when the ``checkUpdate``
|
||||
positional arguments. It will be called when the ``check_update``
|
||||
has determined that an update should be processed by this handler.
|
||||
pass_args (optional[bool]): If the handler should be passed the
|
||||
arguments passed to the command as a keyword argument called `
|
||||
@@ -43,24 +43,25 @@ class CommandHandler(Handler):
|
||||
be used to insert updates. Default is ``False``
|
||||
"""
|
||||
|
||||
def __init__(self, command, callback, pass_args=False,
|
||||
pass_update_queue=False):
|
||||
def __init__(self, command, callback, pass_args=False, pass_update_queue=False):
|
||||
super(CommandHandler, self).__init__(callback, pass_update_queue)
|
||||
self.command = command
|
||||
self.pass_args = pass_args
|
||||
|
||||
def checkUpdate(self, update):
|
||||
return (isinstance(update, Update) and
|
||||
update.message and
|
||||
update.message.text and
|
||||
def check_update(self, update):
|
||||
return (isinstance(update, Update) and update.message and update.message.text and
|
||||
update.message.text.startswith('/') and
|
||||
update.message.text[1:].split(' ')[0].split('@')[0] ==
|
||||
self.command)
|
||||
update.message.text[1:].split(' ')[0].split('@')[0] == self.command)
|
||||
|
||||
def handleUpdate(self, update, dispatcher):
|
||||
optional_args = self.collectOptionalArgs(dispatcher)
|
||||
def handle_update(self, update, dispatcher):
|
||||
optional_args = self.collect_optional_args(dispatcher)
|
||||
|
||||
if self.pass_args:
|
||||
optional_args['args'] = update.message.text.split(' ')[1:]
|
||||
|
||||
self.callback(dispatcher.bot, update, **optional_args)
|
||||
|
||||
# old non-PEP8 Handler methods
|
||||
m = "telegram.CommandHandler."
|
||||
checkUpdate = deprecate(check_update, m + "checkUpdate", m + "check_update")
|
||||
handleUpdate = deprecate(handle_update, m + "handleUpdate", m + "handle_update")
|
||||
|
||||
+22
-18
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains the Dispatcher class."""
|
||||
|
||||
import logging
|
||||
@@ -28,6 +27,7 @@ from queue import Empty
|
||||
|
||||
from telegram import (TelegramError, NullHandler)
|
||||
from telegram.ext.handler import Handler
|
||||
from telegram.utils.deprecate import deprecate
|
||||
|
||||
logging.getLogger(__name__).addHandler(NullHandler())
|
||||
|
||||
@@ -91,6 +91,7 @@ class Dispatcher(object):
|
||||
update_queue (Queue): The synchronized queue that will contain the
|
||||
updates.
|
||||
"""
|
||||
|
||||
def __init__(self, bot, update_queue, workers=4, exception_event=None):
|
||||
self.bot = bot
|
||||
self.update_queue = update_queue
|
||||
@@ -139,8 +140,7 @@ class Dispatcher(object):
|
||||
self.logger.debug('orderly stopping')
|
||||
break
|
||||
elif self.__exception_event.is_set():
|
||||
self.logger.critical(
|
||||
'stopping due to exception in another thread')
|
||||
self.logger.critical('stopping due to exception in another thread')
|
||||
break
|
||||
continue
|
||||
|
||||
@@ -181,27 +181,24 @@ class Dispatcher(object):
|
||||
break
|
||||
# Dispatch any errors
|
||||
except TelegramError as te:
|
||||
self.logger.warn(
|
||||
'A TelegramError was raised while processing the '
|
||||
'Update.')
|
||||
self.logger.warn('A TelegramError was raised while processing the '
|
||||
'Update.')
|
||||
|
||||
try:
|
||||
self.dispatchError(update, te)
|
||||
except Exception:
|
||||
self.logger.exception(
|
||||
'An uncaught error was raised while '
|
||||
'handling the error')
|
||||
self.logger.exception('An uncaught error was raised while '
|
||||
'handling the error')
|
||||
finally:
|
||||
break
|
||||
|
||||
# Errors should not stop the thread
|
||||
except Exception:
|
||||
self.logger.exception(
|
||||
'An uncaught error was raised while '
|
||||
'processing the update')
|
||||
self.logger.exception('An uncaught error was raised while '
|
||||
'processing the update')
|
||||
break
|
||||
|
||||
def addHandler(self, handler, group=DEFAULT_GROUP):
|
||||
def add_handler(self, handler, group=DEFAULT_GROUP):
|
||||
"""
|
||||
Register a handler.
|
||||
|
||||
@@ -227,8 +224,7 @@ class Dispatcher(object):
|
||||
"""
|
||||
|
||||
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 {0}'.format(Handler.__name__))
|
||||
if not isinstance(group, int):
|
||||
raise TypeError('group is not int')
|
||||
|
||||
@@ -239,7 +235,7 @@ class Dispatcher(object):
|
||||
|
||||
self.handlers[group].append(handler)
|
||||
|
||||
def removeHandler(self, handler, group=DEFAULT_GROUP):
|
||||
def remove_handler(self, handler, group=DEFAULT_GROUP):
|
||||
"""
|
||||
Remove a handler from the specified group
|
||||
|
||||
@@ -253,7 +249,7 @@ class Dispatcher(object):
|
||||
del self.handlers[group]
|
||||
self.groups.remove(group)
|
||||
|
||||
def addErrorHandler(self, callback):
|
||||
def add_error_handler(self, callback):
|
||||
"""
|
||||
Registers an error handler in the Dispatcher.
|
||||
|
||||
@@ -264,7 +260,7 @@ class Dispatcher(object):
|
||||
|
||||
self.error_handlers.append(callback)
|
||||
|
||||
def removeErrorHandler(self, callback):
|
||||
def remove_error_handler(self, callback):
|
||||
"""
|
||||
De-registers an error handler.
|
||||
|
||||
@@ -286,3 +282,11 @@ class Dispatcher(object):
|
||||
|
||||
for callback in self.error_handlers:
|
||||
callback(self.bot, update, error)
|
||||
|
||||
# old non-PEP8 Dispatcher methods
|
||||
m = "telegram.dispatcher."
|
||||
addHandler = deprecate(add_handler, m + "AddHandler", m + "add_handler")
|
||||
removeHandler = deprecate(remove_handler, m + "removeHandler", m + "remove_handler")
|
||||
addErrorHandler = deprecate(add_error_handler, m + "addErrorHandler", m + "add_error_handler")
|
||||
removeErrorHandler = deprecate(remove_error_handler, m + "removeErrorHandler",
|
||||
m + "remove_error_handler")
|
||||
|
||||
+13
-5
@@ -16,10 +16,11 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
""" This module contains the base class for handlers as used by the
|
||||
Dispatcher """
|
||||
|
||||
from telegram.utils.deprecate import deprecate
|
||||
|
||||
|
||||
class Handler(object):
|
||||
"""
|
||||
@@ -28,7 +29,7 @@ class Handler(object):
|
||||
|
||||
Args:
|
||||
callback (function): A function that takes ``bot, update`` as
|
||||
positional arguments. It will be called when the ``checkUpdate``
|
||||
positional arguments. It will be called when the ``check_update``
|
||||
has determined that an update should be processed by this handler.
|
||||
pass_update_queue (optional[bool]): If the callback should be passed
|
||||
the update queue as a keyword argument called ``update_queue``. It
|
||||
@@ -39,7 +40,7 @@ class Handler(object):
|
||||
self.callback = callback
|
||||
self.pass_update_queue = pass_update_queue
|
||||
|
||||
def checkUpdate(self, update):
|
||||
def check_update(self, update):
|
||||
"""
|
||||
This method is called to determine if an update should be handled by
|
||||
this handler instance. It should always be overridden.
|
||||
@@ -52,7 +53,7 @@ class Handler(object):
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def handleUpdate(self, update, dispatcher):
|
||||
def handle_update(self, update, dispatcher):
|
||||
"""
|
||||
This method is called if it was determined that an update should indeed
|
||||
be handled by this instance. It should also be overridden, but in most
|
||||
@@ -65,7 +66,7 @@ class Handler(object):
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def collectOptionalArgs(self, dispatcher):
|
||||
def collect_optional_args(self, dispatcher):
|
||||
"""
|
||||
Prepares the optional arguments that are the same for all types of
|
||||
handlers
|
||||
@@ -78,3 +79,10 @@ class Handler(object):
|
||||
optional_args['update_queue'] = dispatcher.update_queue
|
||||
|
||||
return optional_args
|
||||
|
||||
# old non-PEP8 Handler methods
|
||||
m = "telegram.Handler."
|
||||
checkUpdate = deprecate(check_update, m + "checkUpdate", m + "check_update")
|
||||
handleUpdate = deprecate(handle_update, m + "handleUpdate", m + "handle_update")
|
||||
collectOptionalArgs = deprecate(collect_optional_args, m + "collectOptionalArgs",
|
||||
m + "collect_optional_args")
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
""" This module contains the InlineQueryHandler class """
|
||||
|
||||
from .handler import Handler
|
||||
from telegram import Update
|
||||
from telegram.utils.deprecate import deprecate
|
||||
|
||||
|
||||
class InlineQueryHandler(Handler):
|
||||
@@ -29,7 +29,7 @@ class InlineQueryHandler(Handler):
|
||||
|
||||
Args:
|
||||
callback (function): A function that takes ``bot, update`` as
|
||||
positional arguments. It will be called when the ``checkUpdate``
|
||||
positional arguments. It will be called when the ``check_update``
|
||||
has determined that an update should be processed by this handler.
|
||||
pass_update_queue (optional[bool]): If the handler should be passed the
|
||||
update queue as a keyword argument called ``update_queue``. It can
|
||||
@@ -39,10 +39,15 @@ class InlineQueryHandler(Handler):
|
||||
def __init__(self, callback, pass_update_queue=False):
|
||||
super(InlineQueryHandler, self).__init__(callback, pass_update_queue)
|
||||
|
||||
def checkUpdate(self, update):
|
||||
def check_update(self, update):
|
||||
return isinstance(update, Update) and update.inline_query
|
||||
|
||||
def handleUpdate(self, update, dispatcher):
|
||||
optional_args = self.collectOptionalArgs(dispatcher)
|
||||
def handle_update(self, update, dispatcher):
|
||||
optional_args = self.collect_optional_args(dispatcher)
|
||||
|
||||
self.callback(dispatcher.bot, update, **optional_args)
|
||||
|
||||
# old non-PEP8 Handler methods
|
||||
m = "telegram.InlineQueryHandler."
|
||||
checkUpdate = deprecate(check_update, m + "checkUpdate", m + "check_update")
|
||||
handleUpdate = deprecate(handle_update, m + "handleUpdate", m + "handle_update")
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains the class JobQueue."""
|
||||
|
||||
import logging
|
||||
@@ -50,12 +49,7 @@ class JobQueue(object):
|
||||
self.__lock = Lock()
|
||||
self.running = False
|
||||
|
||||
def put(self,
|
||||
run,
|
||||
interval,
|
||||
repeat=True,
|
||||
next_t=None,
|
||||
prevent_autostart=False):
|
||||
def put(self, run, interval, repeat=True, next_t=None, prevent_autostart=False):
|
||||
"""
|
||||
Queue a new job. If the JobQueue is not running, it will be started.
|
||||
|
||||
@@ -123,8 +117,7 @@ class JobQueue(object):
|
||||
if not self.running:
|
||||
self.running = True
|
||||
self.__lock.release()
|
||||
job_queue_thread = Thread(target=self._start,
|
||||
name="job_queue")
|
||||
job_queue_thread = Thread(target=self._start, name="job_queue")
|
||||
job_queue_thread.start()
|
||||
self.logger.debug('Job Queue thread started')
|
||||
else:
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
""" This module contains the MessageHandler class """
|
||||
|
||||
from .handler import Handler
|
||||
from telegram import Update
|
||||
from telegram.utils.deprecate import deprecate
|
||||
|
||||
|
||||
class Filters(object):
|
||||
@@ -75,18 +75,15 @@ class Filters(object):
|
||||
|
||||
@staticmethod
|
||||
def status_update(update):
|
||||
return bool(
|
||||
update.message.new_chat_member or
|
||||
update.message.left_chat_member or
|
||||
update.message.new_chat_title or
|
||||
update.message.new_chat_photo or
|
||||
update.message.delete_chat_photo or
|
||||
update.message.group_chat_created or
|
||||
update.message.supergroup_chat_created or
|
||||
update.message.channel_chat_created or
|
||||
update.message.migrate_to_chat_id or
|
||||
update.message.migrate_from_chat_id or
|
||||
update.message.pinned_message)
|
||||
# yapf: disable
|
||||
# https://github.com/google/yapf/issues/252
|
||||
return bool(update.message.new_chat_member or update.message.left_chat_member or
|
||||
update.message.new_chat_title or update.message.new_chat_photo or
|
||||
update.message.delete_chat_photo or update.message.group_chat_created or
|
||||
update.message.supergroup_chat_created or
|
||||
update.message.channel_chat_created or update.message.migrate_to_chat_id or
|
||||
update.message.migrate_from_chat_id or update.message.pinned_message)
|
||||
# yapf: enable
|
||||
|
||||
|
||||
class MessageHandler(Handler):
|
||||
@@ -103,7 +100,7 @@ class MessageHandler(Handler):
|
||||
accepted. If ``bool(filters)`` evaluates to ``False``, messages are
|
||||
not filtered.
|
||||
callback (function): A function that takes ``bot, update`` as
|
||||
positional arguments. It will be called when the ``checkUpdate``
|
||||
positional arguments. It will be called when the ``check_update``
|
||||
has determined that an update should be processed by this handler.
|
||||
pass_update_queue (optional[bool]): If the handler should be passed the
|
||||
update queue as a keyword argument called ``update_queue``. It can
|
||||
@@ -114,7 +111,7 @@ class MessageHandler(Handler):
|
||||
super(MessageHandler, self).__init__(callback, pass_update_queue)
|
||||
self.filters = filters
|
||||
|
||||
def checkUpdate(self, update):
|
||||
def check_update(self, update):
|
||||
if isinstance(update, Update) and update.message:
|
||||
if not self.filters:
|
||||
res = True
|
||||
@@ -124,7 +121,12 @@ class MessageHandler(Handler):
|
||||
res = False
|
||||
return res
|
||||
|
||||
def handleUpdate(self, update, dispatcher):
|
||||
optional_args = self.collectOptionalArgs(dispatcher)
|
||||
def handle_update(self, update, dispatcher):
|
||||
optional_args = self.collect_optional_args(dispatcher)
|
||||
|
||||
self.callback(dispatcher.bot, update, **optional_args)
|
||||
|
||||
# old non-PEP8 Handler methods
|
||||
m = "telegram.MessageHandler."
|
||||
checkUpdate = deprecate(check_update, m + "checkUpdate", m + "check_update")
|
||||
handleUpdate = deprecate(handle_update, m + "handleUpdate", m + "handle_update")
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
""" This module contains the RegexHandler class """
|
||||
|
||||
import re
|
||||
@@ -25,6 +24,7 @@ from future.utils import string_types
|
||||
|
||||
from .handler import Handler
|
||||
from telegram import Update
|
||||
from telegram.utils.deprecate import deprecate
|
||||
|
||||
|
||||
class RegexHandler(Handler):
|
||||
@@ -37,7 +37,7 @@ class RegexHandler(Handler):
|
||||
Args:
|
||||
pattern (str or Pattern): The regex pattern.
|
||||
callback (function): A function that takes ``bot, update`` as
|
||||
positional arguments. It will be called when the ``checkUpdate``
|
||||
positional arguments. It will be called when the ``check_update``
|
||||
has determined that an update should be processed by this handler.
|
||||
pass_groups (optional[bool]): If the callback should be passed the
|
||||
result of ``re.match(pattern, text).groups()`` as a keyword
|
||||
@@ -50,8 +50,12 @@ class RegexHandler(Handler):
|
||||
be used to insert updates. Default is ``False``
|
||||
"""
|
||||
|
||||
def __init__(self, pattern, callback, pass_groups=False,
|
||||
pass_groupdict=False, pass_update_queue=False):
|
||||
def __init__(self,
|
||||
pattern,
|
||||
callback,
|
||||
pass_groups=False,
|
||||
pass_groupdict=False,
|
||||
pass_update_queue=False):
|
||||
super(RegexHandler, self).__init__(callback, pass_update_queue)
|
||||
|
||||
if isinstance(pattern, string_types):
|
||||
@@ -61,17 +65,15 @@ class RegexHandler(Handler):
|
||||
self.pass_groups = pass_groups
|
||||
self.pass_groupdict = pass_groupdict
|
||||
|
||||
def checkUpdate(self, update):
|
||||
if (isinstance(update, Update) and
|
||||
update.message and
|
||||
update.message.text):
|
||||
def check_update(self, update):
|
||||
if (isinstance(update, Update) and update.message and update.message.text):
|
||||
match = re.match(self.pattern, update.message.text)
|
||||
return bool(match)
|
||||
else:
|
||||
return False
|
||||
|
||||
def handleUpdate(self, update, dispatcher):
|
||||
optional_args = self.collectOptionalArgs(dispatcher)
|
||||
def handle_update(self, update, dispatcher):
|
||||
optional_args = self.collect_optional_args(dispatcher)
|
||||
match = re.match(self.pattern, update.message.text)
|
||||
|
||||
if self.pass_groups:
|
||||
@@ -80,3 +82,8 @@ class RegexHandler(Handler):
|
||||
optional_args['groupdict'] = match.groupdict()
|
||||
|
||||
self.callback(dispatcher.bot, update, **optional_args)
|
||||
|
||||
# old non-PEP8 Handler methods
|
||||
m = "telegram.RegexHandler."
|
||||
checkUpdate = deprecate(check_update, m + "checkUpdate", m + "check_update")
|
||||
handleUpdate = deprecate(handle_update, m + "handleUpdate", m + "handle_update")
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
""" This module contains the StringCommandHandler class """
|
||||
|
||||
from .handler import Handler
|
||||
from telegram.utils.deprecate import deprecate
|
||||
|
||||
|
||||
class StringCommandHandler(Handler):
|
||||
@@ -30,7 +30,7 @@ class StringCommandHandler(Handler):
|
||||
Args:
|
||||
command (str): The name of the command this handler should listen for.
|
||||
callback (function): A function that takes ``bot, update`` as
|
||||
positional arguments. It will be called when the ``checkUpdate``
|
||||
positional arguments. It will be called when the ``check_update``
|
||||
has determined that an update should be processed by this handler.
|
||||
pass_args (optional[bool]): If the handler should be passed the
|
||||
arguments passed to the command as a keyword argument called `
|
||||
@@ -41,21 +41,24 @@ class StringCommandHandler(Handler):
|
||||
be used to insert updates. Default is ``False``
|
||||
"""
|
||||
|
||||
def __init__(self, command, callback, pass_args=False,
|
||||
pass_update_queue=False):
|
||||
def __init__(self, command, callback, pass_args=False, pass_update_queue=False):
|
||||
super(StringCommandHandler, self).__init__(callback, pass_update_queue)
|
||||
self.command = command
|
||||
self.pass_args = pass_args
|
||||
|
||||
def checkUpdate(self, update):
|
||||
return (isinstance(update, str) and
|
||||
update.startswith('/') and
|
||||
def check_update(self, update):
|
||||
return (isinstance(update, str) and update.startswith('/') and
|
||||
update[1:].split(' ')[0] == self.command)
|
||||
|
||||
def handleUpdate(self, update, dispatcher):
|
||||
optional_args = self.collectOptionalArgs(dispatcher)
|
||||
def handle_update(self, update, dispatcher):
|
||||
optional_args = self.collect_optional_args(dispatcher)
|
||||
|
||||
if self.pass_args:
|
||||
optional_args['args'] = update.split(' ')[1:]
|
||||
|
||||
self.callback(dispatcher.bot, update, **optional_args)
|
||||
|
||||
# old non-PEP8 Handler methods
|
||||
m = "telegram.StringCommandHandler."
|
||||
checkUpdate = deprecate(check_update, m + "checkUpdate", m + "check_update")
|
||||
handleUpdate = deprecate(handle_update, m + "handleUpdate", m + "handle_update")
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
""" This module contains the StringRegexHandler class """
|
||||
|
||||
import re
|
||||
@@ -24,6 +23,7 @@ import re
|
||||
from future.utils import string_types
|
||||
|
||||
from .handler import Handler
|
||||
from telegram.utils.deprecate import deprecate
|
||||
|
||||
|
||||
class StringRegexHandler(Handler):
|
||||
@@ -36,7 +36,7 @@ class StringRegexHandler(Handler):
|
||||
Args:
|
||||
pattern (str or Pattern): The regex pattern.
|
||||
callback (function): A function that takes ``bot, update`` as
|
||||
positional arguments. It will be called when the ``checkUpdate``
|
||||
positional arguments. It will be called when the ``check_update``
|
||||
has determined that an update should be processed by this handler.
|
||||
pass_groups (optional[bool]): If the callback should be passed the
|
||||
result of ``re.match(pattern, update).groups()`` as a keyword
|
||||
@@ -49,8 +49,12 @@ class StringRegexHandler(Handler):
|
||||
be used to insert updates. Default is ``False``
|
||||
"""
|
||||
|
||||
def __init__(self, pattern, callback, pass_groups=False,
|
||||
pass_groupdict=False, pass_update_queue=False):
|
||||
def __init__(self,
|
||||
pattern,
|
||||
callback,
|
||||
pass_groups=False,
|
||||
pass_groupdict=False,
|
||||
pass_update_queue=False):
|
||||
super(StringRegexHandler, self).__init__(callback, pass_update_queue)
|
||||
|
||||
if isinstance(pattern, string_types):
|
||||
@@ -60,12 +64,11 @@ class StringRegexHandler(Handler):
|
||||
self.pass_groups = pass_groups
|
||||
self.pass_groupdict = pass_groupdict
|
||||
|
||||
def checkUpdate(self, update):
|
||||
return isinstance(update, string_types) and bool(
|
||||
re.match(self.pattern, update))
|
||||
def check_update(self, update):
|
||||
return isinstance(update, string_types) and bool(re.match(self.pattern, update))
|
||||
|
||||
def handleUpdate(self, update, dispatcher):
|
||||
optional_args = self.collectOptionalArgs(dispatcher)
|
||||
def handle_update(self, update, dispatcher):
|
||||
optional_args = self.collect_optional_args(dispatcher)
|
||||
match = re.match(self.pattern, update)
|
||||
|
||||
if self.pass_groups:
|
||||
@@ -74,3 +77,8 @@ class StringRegexHandler(Handler):
|
||||
optional_args['groupdict'] = match.groupdict()
|
||||
|
||||
self.callback(dispatcher.bot, update, **optional_args)
|
||||
|
||||
# old non-PEP8 Handler methods
|
||||
m = "telegram.StringRegexHandler."
|
||||
checkUpdate = deprecate(check_update, m + "checkUpdate", m + "check_update")
|
||||
handleUpdate = deprecate(handle_update, m + "handleUpdate", m + "handle_update")
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
""" This module contains the TypeHandler class """
|
||||
|
||||
from .handler import Handler
|
||||
from telegram.utils.deprecate import deprecate
|
||||
|
||||
|
||||
class TypeHandler(Handler):
|
||||
@@ -30,7 +30,7 @@ class TypeHandler(Handler):
|
||||
type (type): The ``type`` of updates this handler should process, as
|
||||
determined by ``isinstance``
|
||||
callback (function): A function that takes ``bot, update`` as
|
||||
positional arguments. It will be called when the ``checkUpdate``
|
||||
positional arguments. It will be called when the ``check_update``
|
||||
has determined that an update should be processed by this handler.
|
||||
strict (optional[bool]): Use ``type`` instead of ``isinstance``.
|
||||
Default is ``False``
|
||||
@@ -44,13 +44,18 @@ class TypeHandler(Handler):
|
||||
self.type = type
|
||||
self.strict = strict
|
||||
|
||||
def checkUpdate(self, update):
|
||||
def check_update(self, update):
|
||||
if not self.strict:
|
||||
return isinstance(update, self.type)
|
||||
else:
|
||||
return type(update) is self.type
|
||||
|
||||
def handleUpdate(self, update, dispatcher):
|
||||
optional_args = self.collectOptionalArgs(dispatcher)
|
||||
def handle_update(self, update, dispatcher):
|
||||
optional_args = self.collect_optional_args(dispatcher)
|
||||
|
||||
self.callback(dispatcher.bot, update, **optional_args)
|
||||
|
||||
# old non-PEP8 Handler methods
|
||||
m = "telegram.TypeHandler."
|
||||
checkUpdate = deprecate(check_update, m + "checkUpdate", m + "check_update")
|
||||
handleUpdate = deprecate(handle_update, m + "handleUpdate", m + "handle_update")
|
||||
|
||||
+79
-85
@@ -16,8 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
|
||||
"""This module contains the class Updater, which tries to make creating
|
||||
Telegram bots intuitive."""
|
||||
|
||||
@@ -85,8 +83,7 @@ class Updater(object):
|
||||
self.update_queue = Queue()
|
||||
self.job_queue = JobQueue(self.bot, job_queue_tick_interval)
|
||||
self.__exception_event = Event()
|
||||
self.dispatcher = Dispatcher(self.bot, self.update_queue, workers,
|
||||
self.__exception_event)
|
||||
self.dispatcher = Dispatcher(self.bot, self.update_queue, workers, self.__exception_event)
|
||||
self.last_update_id = 0
|
||||
self.logger = logging.getLogger(__name__)
|
||||
self.running = False
|
||||
@@ -96,8 +93,28 @@ class Updater(object):
|
||||
self.__threads = []
|
||||
""":type: list[Thread]"""
|
||||
|
||||
def start_polling(self, poll_interval=0.0, timeout=10, network_delay=2,
|
||||
clean=False, bootstrap_retries=0):
|
||||
def _init_thread(self, target, name, *args, **kwargs):
|
||||
thr = Thread(target=self._thread_wrapper, name=name, args=(target,) + args, kwargs=kwargs)
|
||||
thr.start()
|
||||
self.__threads.append(thr)
|
||||
|
||||
def _thread_wrapper(self, target, *args, **kwargs):
|
||||
thr_name = current_thread().name
|
||||
self.logger.debug('{0} - started'.format(thr_name))
|
||||
try:
|
||||
target(*args, **kwargs)
|
||||
except Exception:
|
||||
self.__exception_event.set()
|
||||
self.logger.exception('unhandled exception')
|
||||
raise
|
||||
self.logger.debug('{0} - ended'.format(thr_name))
|
||||
|
||||
def start_polling(self,
|
||||
poll_interval=0.0,
|
||||
timeout=10,
|
||||
network_delay=2,
|
||||
clean=False,
|
||||
bootstrap_retries=0):
|
||||
"""
|
||||
Starts polling updates from Telegram.
|
||||
|
||||
@@ -123,35 +140,15 @@ class Updater(object):
|
||||
with self.__lock:
|
||||
if not self.running:
|
||||
self.running = True
|
||||
if clean:
|
||||
self._clean_updates()
|
||||
|
||||
# Create & start threads
|
||||
self._init_thread(self.dispatcher.start, "dispatcher")
|
||||
self._init_thread(self._start_polling, "updater",
|
||||
poll_interval, timeout, network_delay,
|
||||
bootstrap_retries)
|
||||
self._init_thread(self._start_polling, "updater", poll_interval, timeout,
|
||||
network_delay, bootstrap_retries, clean)
|
||||
|
||||
# Return the update queue so the main thread can insert updates
|
||||
return self.update_queue
|
||||
|
||||
def _init_thread(self, target, name, *args, **kwargs):
|
||||
thr = Thread(target=self._thread_wrapper, name=name,
|
||||
args=(target,) + args, kwargs=kwargs)
|
||||
thr.start()
|
||||
self.__threads.append(thr)
|
||||
|
||||
def _thread_wrapper(self, target, *args, **kwargs):
|
||||
thr_name = current_thread().name
|
||||
self.logger.debug('{0} - started'.format(thr_name))
|
||||
try:
|
||||
target(*args, **kwargs)
|
||||
except Exception:
|
||||
self.__exception_event.set()
|
||||
self.logger.exception('unhandled exception')
|
||||
raise
|
||||
self.logger.debug('{0} - ended'.format(thr_name))
|
||||
|
||||
def start_webhook(self,
|
||||
listen='127.0.0.1',
|
||||
port=80,
|
||||
@@ -194,20 +191,16 @@ class Updater(object):
|
||||
with self.__lock:
|
||||
if not self.running:
|
||||
self.running = True
|
||||
if clean:
|
||||
self._clean_updates()
|
||||
|
||||
# Create & start threads
|
||||
self._init_thread(self.dispatcher.start, "dispatcher"),
|
||||
self._init_thread(self._start_webhook, "updater", listen,
|
||||
port, url_path, cert, key, bootstrap_retries,
|
||||
webhook_url)
|
||||
self._init_thread(self._start_webhook, "updater", listen, port, url_path, cert,
|
||||
key, bootstrap_retries, clean, webhook_url)
|
||||
|
||||
# Return the update queue so the main thread can insert updates
|
||||
return self.update_queue
|
||||
|
||||
def _start_polling(self, poll_interval, timeout, network_delay,
|
||||
bootstrap_retries):
|
||||
def _start_polling(self, poll_interval, timeout, network_delay, bootstrap_retries, clean):
|
||||
"""
|
||||
Thread target of thread 'updater'. Runs in background, pulls
|
||||
updates from Telegram and inserts them in the update queue of the
|
||||
@@ -217,7 +210,7 @@ class Updater(object):
|
||||
cur_interval = poll_interval
|
||||
self.logger.debug('Updater thread started')
|
||||
|
||||
self._set_webhook(None, bootstrap_retries, None)
|
||||
self._bootstrap(bootstrap_retries, clean=clean, webhook_url='')
|
||||
|
||||
while self.running:
|
||||
try:
|
||||
@@ -225,8 +218,7 @@ class Updater(object):
|
||||
timeout=timeout,
|
||||
network_delay=network_delay)
|
||||
except TelegramError as te:
|
||||
self.logger.error(
|
||||
"Error while getting Updates: {0}".format(te))
|
||||
self.logger.error("Error while getting Updates: {0}".format(te))
|
||||
|
||||
# Put the error into the update queue and let the Dispatcher
|
||||
# broadcast it
|
||||
@@ -249,28 +241,6 @@ class Updater(object):
|
||||
|
||||
sleep(cur_interval)
|
||||
|
||||
def _set_webhook(self, webhook_url, max_retries, cert):
|
||||
retries = 0
|
||||
while 1:
|
||||
try:
|
||||
# Remove webhook
|
||||
self.bot.setWebhook(webhook_url=webhook_url,
|
||||
certificate=cert)
|
||||
except (Unauthorized, InvalidToken):
|
||||
raise
|
||||
except TelegramError:
|
||||
msg = 'failed to set webhook; try={0} max_retries={1}'.format(
|
||||
retries, max_retries)
|
||||
if max_retries < 0 or retries < max_retries:
|
||||
self.logger.info(msg)
|
||||
retries += 1
|
||||
else:
|
||||
self.logger.exception(msg)
|
||||
raise
|
||||
else:
|
||||
break
|
||||
sleep(1)
|
||||
|
||||
@staticmethod
|
||||
def _increase_poll_interval(current_interval):
|
||||
# increase waiting times on subsequent errors up to 30secs
|
||||
@@ -282,16 +252,15 @@ class Updater(object):
|
||||
current_interval = 30
|
||||
return current_interval
|
||||
|
||||
def _start_webhook(self, listen, port, url_path, cert, key,
|
||||
bootstrap_retries, webhook_url):
|
||||
def _start_webhook(self, listen, port, url_path, cert, key, bootstrap_retries, clean,
|
||||
webhook_url):
|
||||
self.logger.debug('Updater thread started')
|
||||
use_ssl = cert is not None and key is not None
|
||||
if not url_path.startswith('/'):
|
||||
url_path = '/{0}'.format(url_path)
|
||||
|
||||
# Create and start server
|
||||
self.httpd = WebhookServer((listen, port), WebhookHandler,
|
||||
self.update_queue, url_path)
|
||||
self.httpd = WebhookServer((listen, port), WebhookHandler, self.update_queue, url_path)
|
||||
|
||||
if use_ssl:
|
||||
self._check_ssl_cert(cert, key)
|
||||
@@ -300,18 +269,23 @@ class Updater(object):
|
||||
if not webhook_url:
|
||||
webhook_url = self._gen_webhook_url(listen, port, url_path)
|
||||
|
||||
self._set_webhook(webhook_url, bootstrap_retries,
|
||||
open(cert, 'rb'))
|
||||
self._bootstrap(max_retries=bootstrap_retries,
|
||||
clean=clean,
|
||||
webhook_url=webhook_url,
|
||||
cert=open(cert, 'rb'))
|
||||
elif clean:
|
||||
self.logger.warning("cleaning updates is not supported if "
|
||||
"SSL-termination happens elsewhere; skipping")
|
||||
|
||||
self.httpd.serve_forever(poll_interval=1)
|
||||
|
||||
def _check_ssl_cert(self, cert, key):
|
||||
# Check SSL-Certificate with openssl, if possible
|
||||
try:
|
||||
exit_code = subprocess.call(["openssl", "x509", "-text",
|
||||
"-noout", "-in", cert],
|
||||
stdout=open(os.devnull, 'wb'),
|
||||
stderr=subprocess.STDOUT)
|
||||
exit_code = subprocess.call(
|
||||
["openssl", "x509", "-text", "-noout", "-in", cert],
|
||||
stdout=open(os.devnull, 'wb'),
|
||||
stderr=subprocess.STDOUT)
|
||||
except OSError:
|
||||
exit_code = 0
|
||||
if exit_code is 0:
|
||||
@@ -326,11 +300,35 @@ class Updater(object):
|
||||
else:
|
||||
raise TelegramError('SSL Certificate invalid')
|
||||
|
||||
def _gen_webhook_url(self, listen, port, url_path):
|
||||
return 'https://{listen}:{port}{path}'.format(
|
||||
listen=listen,
|
||||
port=port,
|
||||
path=url_path)
|
||||
@staticmethod
|
||||
def _gen_webhook_url(listen, port, url_path):
|
||||
return 'https://{listen}:{port}{path}'.format(listen=listen, port=port, path=url_path)
|
||||
|
||||
def _bootstrap(self, max_retries, clean, webhook_url, cert=None):
|
||||
retries = 0
|
||||
while True:
|
||||
|
||||
try:
|
||||
if clean:
|
||||
# Disable webhook for cleaning
|
||||
self.bot.setWebhook(webhook_url='')
|
||||
self._clean_updates()
|
||||
|
||||
self.bot.setWebhook(webhook_url=webhook_url, certificate=cert)
|
||||
except (Unauthorized, InvalidToken):
|
||||
raise
|
||||
except TelegramError:
|
||||
msg = 'error in bootstrap phase; try={0} max_retries={1}'\
|
||||
.format(retries, max_retries)
|
||||
if max_retries < 0 or retries < max_retries:
|
||||
self.logger.warning(msg)
|
||||
retries += 1
|
||||
else:
|
||||
self.logger.exception(msg)
|
||||
raise
|
||||
else:
|
||||
break
|
||||
sleep(1)
|
||||
|
||||
def _clean_updates(self):
|
||||
self.logger.debug('Cleaning updates from Telegram server')
|
||||
@@ -360,10 +358,9 @@ class Updater(object):
|
||||
|
||||
def _stop_httpd(self):
|
||||
if self.httpd:
|
||||
self.logger.debug(
|
||||
'Waiting for current webhook connection to be '
|
||||
'closed... Send a Telegram message to the bot to exit '
|
||||
'immediately.')
|
||||
self.logger.debug('Waiting for current webhook connection to be '
|
||||
'closed... Send a Telegram message to the bot to exit '
|
||||
'immediately.')
|
||||
self.httpd.shutdown()
|
||||
self.httpd = None
|
||||
|
||||
@@ -376,16 +373,13 @@ class Updater(object):
|
||||
threads = list(dispatcher.async_threads)
|
||||
total = len(threads)
|
||||
for i, thr in enumerate(threads):
|
||||
self.logger.debug(
|
||||
'Waiting for async thread {0}/{1} to end'.format(i, total))
|
||||
self.logger.debug('Waiting for async thread {0}/{1} to end'.format(i, total))
|
||||
thr.join()
|
||||
self.logger.debug(
|
||||
'async thread {0}/{1} has ended'.format(i, total))
|
||||
self.logger.debug('async thread {0}/{1} has ended'.format(i, total))
|
||||
|
||||
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 {0} thread to end'.format(thr.name))
|
||||
thr.join()
|
||||
self.logger.debug('{0} thread has ended'.format(thr.name))
|
||||
self.__threads = []
|
||||
|
||||
+2
-6
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a Telegram File."""
|
||||
|
||||
from os.path import basename
|
||||
@@ -42,9 +41,7 @@ class File(TelegramObject):
|
||||
file_path (Optional[str]):
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
file_id,
|
||||
**kwargs):
|
||||
def __init__(self, file_id, **kwargs):
|
||||
# Required
|
||||
self.file_id = str(file_id)
|
||||
# Optionals
|
||||
@@ -65,8 +62,7 @@ class File(TelegramObject):
|
||||
|
||||
return File(**data)
|
||||
|
||||
def download(self,
|
||||
custom_path=None):
|
||||
def download(self, custom_path=None):
|
||||
"""
|
||||
Args:
|
||||
custom_path (str):
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a Telegram ForceReply."""
|
||||
|
||||
from telegram import ReplyMarkup
|
||||
@@ -37,9 +36,7 @@ class ForceReply(ReplyMarkup):
|
||||
selective (Optional[bool]):
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
force_reply=True,
|
||||
**kwargs):
|
||||
def __init__(self, force_reply=True, **kwargs):
|
||||
# Required
|
||||
self.force_reply = bool(force_reply)
|
||||
# Optionals
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a Telegram
|
||||
InlineKeyboardButton"""
|
||||
|
||||
@@ -43,9 +42,7 @@ class InlineKeyboardButton(TelegramObject):
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
text,
|
||||
**kwargs):
|
||||
def __init__(self, text, **kwargs):
|
||||
# Required
|
||||
self.text = text
|
||||
|
||||
@@ -70,7 +67,6 @@ class InlineKeyboardButton(TelegramObject):
|
||||
|
||||
inline_keyboards = list()
|
||||
for inline_keyboard in data:
|
||||
inline_keyboards.append(InlineKeyboardButton.
|
||||
de_json(inline_keyboard))
|
||||
inline_keyboards.append(InlineKeyboardButton.de_json(inline_keyboard))
|
||||
|
||||
return inline_keyboards
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a Telegram
|
||||
InlineKeyboardMarkup"""
|
||||
|
||||
@@ -27,15 +26,14 @@ class InlineKeyboardMarkup(ReplyMarkup):
|
||||
"""This object represents a Telegram InlineKeyboardMarkup.
|
||||
|
||||
Attributes:
|
||||
inline_keyboard (List[List[:class:`telegram.InlineKeyboardMarkup`]]):
|
||||
inline_keyboard (List[List[:class:`telegram.InlineKeyboardButton`]]):
|
||||
|
||||
Args:
|
||||
inline_keyboard (List[List[:class:`telegram.InlineKeyboardMarkup`]]):
|
||||
inline_keyboard (List[List[:class:`telegram.InlineKeyboardButton`]]):
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
inline_keyboard):
|
||||
def __init__(self, inline_keyboard):
|
||||
# Required
|
||||
self.inline_keyboard = inline_keyboard
|
||||
|
||||
@@ -46,9 +44,8 @@ class InlineKeyboardMarkup(ReplyMarkup):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data['inline_keyboard'] = \
|
||||
[InlineKeyboardButton.de_list(inline_keyboard) for inline_keyboard
|
||||
in data['inline_keyboard']]
|
||||
data['inline_keyboard'] = [InlineKeyboardButton.de_list(inline_keyboard)
|
||||
for inline_keyboard in data['inline_keyboard']]
|
||||
|
||||
return InlineKeyboardMarkup(**data)
|
||||
|
||||
@@ -57,7 +54,6 @@ class InlineKeyboardMarkup(ReplyMarkup):
|
||||
|
||||
data['inline_keyboard'] = []
|
||||
for inline_keyboard in self.inline_keyboard:
|
||||
data['inline_keyboard'].append(
|
||||
[x.to_dict() for x in inline_keyboard])
|
||||
data['inline_keyboard'].append([x.to_dict() for x in inline_keyboard])
|
||||
|
||||
return data
|
||||
|
||||
+10
-8
@@ -16,10 +16,9 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a Telegram InlineQuery"""
|
||||
|
||||
from telegram import TelegramObject, User
|
||||
from telegram import TelegramObject, User, Location
|
||||
|
||||
|
||||
class InlineQuery(TelegramObject):
|
||||
@@ -39,20 +38,22 @@ class InlineQuery(TelegramObject):
|
||||
from_user (:class:`telegram.User`):
|
||||
query (str):
|
||||
offset (str):
|
||||
**kwargs: Arbitrary keyword arguments.
|
||||
|
||||
Keyword Args:
|
||||
location (optional[:class:`telegram.Location`]):
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
from_user,
|
||||
query,
|
||||
offset,
|
||||
**kwargs):
|
||||
def __init__(self, id, from_user, query, offset, **kwargs):
|
||||
# Required
|
||||
self.id = id
|
||||
self.from_user = from_user
|
||||
self.query = query
|
||||
self.offset = offset
|
||||
|
||||
# Optional
|
||||
self.location = kwargs.get('location')
|
||||
|
||||
@staticmethod
|
||||
def de_json(data):
|
||||
"""
|
||||
@@ -68,6 +69,7 @@ class InlineQuery(TelegramObject):
|
||||
return None
|
||||
|
||||
data['from_user'] = User.de_json(data.get('from'))
|
||||
data['location'] = Location.de_json(data.get('location'))
|
||||
|
||||
return InlineQuery(**data)
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains the classes that represent Telegram
|
||||
InlineQueryResult"""
|
||||
|
||||
@@ -36,9 +35,7 @@ class InlineQueryResult(TelegramObject):
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
type,
|
||||
id):
|
||||
def __init__(self, type, id):
|
||||
# Required
|
||||
self.type = str(type)
|
||||
self.id = str(id)
|
||||
|
||||
@@ -16,12 +16,10 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains the classes that represent Telegram
|
||||
InlineQueryResultArticle"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, \
|
||||
InputMessageContent
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageContent
|
||||
|
||||
|
||||
class InlineQueryResultArticle(InlineQueryResult):
|
||||
@@ -97,12 +95,10 @@ class InlineQueryResultArticle(InlineQueryResult):
|
||||
|
||||
@staticmethod
|
||||
def de_json(data):
|
||||
data = super(InlineQueryResultArticle,
|
||||
InlineQueryResultArticle).de_json(data)
|
||||
data = super(InlineQueryResultArticle, InlineQueryResultArticle).de_json(data)
|
||||
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(
|
||||
data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(
|
||||
data.get('input_message_content'))
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(data.get(
|
||||
'input_message_content'))
|
||||
|
||||
return InlineQueryResultArticle(**data)
|
||||
|
||||
@@ -16,12 +16,10 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains the classes that represent Telegram
|
||||
InlineQueryResultAudio"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, \
|
||||
InputMessageContent
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageContent
|
||||
|
||||
|
||||
class InlineQueryResultAudio(InlineQueryResult):
|
||||
@@ -59,6 +57,7 @@ class InlineQueryResultAudio(InlineQueryResult):
|
||||
input_message_content (Optional[
|
||||
:class:`telegram.input_message_content`]):
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
audio_url,
|
||||
@@ -86,12 +85,10 @@ class InlineQueryResultAudio(InlineQueryResult):
|
||||
|
||||
@staticmethod
|
||||
def de_json(data):
|
||||
data = super(InlineQueryResultAudio,
|
||||
InlineQueryResultAudio).de_json(data)
|
||||
data = super(InlineQueryResultAudio, InlineQueryResultAudio).de_json(data)
|
||||
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(
|
||||
data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(
|
||||
data.get('input_message_content'))
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(data.get(
|
||||
'input_message_content'))
|
||||
|
||||
return InlineQueryResultAudio(**data)
|
||||
|
||||
@@ -16,12 +16,10 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains the classes that represent Telegram
|
||||
InlineQueryResultCachedAudio"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, \
|
||||
InputMessageContent
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageContent
|
||||
|
||||
|
||||
class InlineQueryResultCachedAudio(InlineQueryResult):
|
||||
@@ -54,12 +52,8 @@ class InlineQueryResultCachedAudio(InlineQueryResult):
|
||||
input_message_content (Optional[
|
||||
:class:`telegram.input_message_content`]):
|
||||
"""
|
||||
def __init__(self,
|
||||
id,
|
||||
audio_file_id,
|
||||
reply_markup=None,
|
||||
input_message_content=None,
|
||||
**kwargs):
|
||||
|
||||
def __init__(self, id, audio_file_id, reply_markup=None, input_message_content=None, **kwargs):
|
||||
# Required
|
||||
super(InlineQueryResultCachedAudio, self).__init__('audio', id)
|
||||
self.audio_file_id = audio_file_id
|
||||
@@ -72,12 +66,10 @@ class InlineQueryResultCachedAudio(InlineQueryResult):
|
||||
|
||||
@staticmethod
|
||||
def de_json(data):
|
||||
data = super(InlineQueryResultCachedAudio,
|
||||
InlineQueryResultCachedAudio).de_json(data)
|
||||
data = super(InlineQueryResultCachedAudio, InlineQueryResultCachedAudio).de_json(data)
|
||||
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(
|
||||
data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(
|
||||
data.get('input_message_content'))
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(data.get(
|
||||
'input_message_content'))
|
||||
|
||||
return InlineQueryResultCachedAudio(**data)
|
||||
|
||||
@@ -16,15 +16,14 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains the classes that represent Telegram
|
||||
InlineQueryResultCachedDocument"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, \
|
||||
InputMessageContent
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageContent
|
||||
|
||||
|
||||
class InlineQueryResultCachedDocument(InlineQueryResult):
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
title,
|
||||
@@ -54,9 +53,8 @@ class InlineQueryResultCachedDocument(InlineQueryResult):
|
||||
data = super(InlineQueryResultCachedDocument,
|
||||
InlineQueryResultCachedDocument).de_json(data)
|
||||
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(
|
||||
data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(
|
||||
data.get('input_message_content'))
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(data.get(
|
||||
'input_message_content'))
|
||||
|
||||
return InlineQueryResultCachedDocument(**data)
|
||||
|
||||
@@ -16,15 +16,14 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains the classes that represent Telegram
|
||||
InlineQueryResultCachedGif"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, \
|
||||
InputMessageContent
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageContent
|
||||
|
||||
|
||||
class InlineQueryResultCachedGif(InlineQueryResult):
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
gif_file_id,
|
||||
@@ -49,12 +48,10 @@ class InlineQueryResultCachedGif(InlineQueryResult):
|
||||
|
||||
@staticmethod
|
||||
def de_json(data):
|
||||
data = super(InlineQueryResultCachedGif,
|
||||
InlineQueryResultCachedGif).de_json(data)
|
||||
data = super(InlineQueryResultCachedGif, InlineQueryResultCachedGif).de_json(data)
|
||||
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(
|
||||
data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(
|
||||
data.get('input_message_content'))
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(data.get(
|
||||
'input_message_content'))
|
||||
|
||||
return InlineQueryResultCachedGif(**data)
|
||||
|
||||
@@ -16,15 +16,14 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains the classes that represent Telegram
|
||||
InlineQueryResultMpeg4Gif"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, \
|
||||
InputMessageContent
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageContent
|
||||
|
||||
|
||||
class InlineQueryResultCachedMpeg4Gif(InlineQueryResult):
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
mpeg4_file_id,
|
||||
@@ -52,9 +51,8 @@ class InlineQueryResultCachedMpeg4Gif(InlineQueryResult):
|
||||
data = super(InlineQueryResultCachedMpeg4Gif,
|
||||
InlineQueryResultCachedMpeg4Gif).de_json(data)
|
||||
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(
|
||||
data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(
|
||||
data.get('input_message_content'))
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(data.get(
|
||||
'input_message_content'))
|
||||
|
||||
return InlineQueryResultCachedMpeg4Gif(**data)
|
||||
|
||||
@@ -16,15 +16,14 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains the classes that represent Telegram
|
||||
InlineQueryResultPhoto"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, \
|
||||
InputMessageContent
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageContent
|
||||
|
||||
|
||||
class InlineQueryResultCachedPhoto(InlineQueryResult):
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
photo_file_id,
|
||||
@@ -52,12 +51,10 @@ class InlineQueryResultCachedPhoto(InlineQueryResult):
|
||||
|
||||
@staticmethod
|
||||
def de_json(data):
|
||||
data = super(InlineQueryResultCachedPhoto,
|
||||
InlineQueryResultCachedPhoto).de_json(data)
|
||||
data = super(InlineQueryResultCachedPhoto, InlineQueryResultCachedPhoto).de_json(data)
|
||||
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(
|
||||
data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(
|
||||
data.get('input_message_content'))
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(data.get(
|
||||
'input_message_content'))
|
||||
|
||||
return InlineQueryResultCachedPhoto(**data)
|
||||
|
||||
@@ -16,15 +16,14 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains the classes that represent Telegram
|
||||
InlineQueryResultCachedSticker"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, \
|
||||
InputMessageContent
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageContent
|
||||
|
||||
|
||||
class InlineQueryResultCachedSticker(InlineQueryResult):
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
sticker_file_id,
|
||||
@@ -43,12 +42,10 @@ class InlineQueryResultCachedSticker(InlineQueryResult):
|
||||
|
||||
@staticmethod
|
||||
def de_json(data):
|
||||
data = super(InlineQueryResultCachedSticker,
|
||||
InlineQueryResultCachedSticker).de_json(data)
|
||||
data = super(InlineQueryResultCachedSticker, InlineQueryResultCachedSticker).de_json(data)
|
||||
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(
|
||||
data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(
|
||||
data.get('input_message_content'))
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(data.get(
|
||||
'input_message_content'))
|
||||
|
||||
return InlineQueryResultCachedSticker(**data)
|
||||
|
||||
@@ -16,15 +16,14 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains the classes that represent Telegram
|
||||
InlineQueryResultCachedVideo"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, \
|
||||
InputMessageContent
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageContent
|
||||
|
||||
|
||||
class InlineQueryResultCachedVideo(InlineQueryResult):
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
video_file_id,
|
||||
@@ -51,12 +50,10 @@ class InlineQueryResultCachedVideo(InlineQueryResult):
|
||||
|
||||
@staticmethod
|
||||
def de_json(data):
|
||||
data = super(InlineQueryResultCachedVideo,
|
||||
InlineQueryResultCachedVideo).de_json(data)
|
||||
data = super(InlineQueryResultCachedVideo, InlineQueryResultCachedVideo).de_json(data)
|
||||
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(
|
||||
data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(
|
||||
data.get('input_message_content'))
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(data.get(
|
||||
'input_message_content'))
|
||||
|
||||
return InlineQueryResultCachedVideo(**data)
|
||||
|
||||
@@ -16,15 +16,14 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains the classes that represent Telegram
|
||||
InlineQueryResultCachedVoice"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, \
|
||||
InputMessageContent
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageContent
|
||||
|
||||
|
||||
class InlineQueryResultCachedVoice(InlineQueryResult):
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
voice_file_id,
|
||||
@@ -48,12 +47,10 @@ class InlineQueryResultCachedVoice(InlineQueryResult):
|
||||
|
||||
@staticmethod
|
||||
def de_json(data):
|
||||
data = super(InlineQueryResultCachedVoice,
|
||||
InlineQueryResultCachedVoice).de_json(data)
|
||||
data = super(InlineQueryResultCachedVoice, InlineQueryResultCachedVoice).de_json(data)
|
||||
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(
|
||||
data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(
|
||||
data.get('input_message_content'))
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(data.get(
|
||||
'input_message_content'))
|
||||
|
||||
return InlineQueryResultCachedVoice(**data)
|
||||
|
||||
@@ -16,15 +16,14 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains the classes that represent Telegram
|
||||
InlineQueryResultContact"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, \
|
||||
InputMessageContent
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageContent
|
||||
|
||||
|
||||
class InlineQueryResultContact(InlineQueryResult):
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
phone_number,
|
||||
@@ -57,12 +56,10 @@ class InlineQueryResultContact(InlineQueryResult):
|
||||
|
||||
@staticmethod
|
||||
def de_json(data):
|
||||
data = super(InlineQueryResultContact,
|
||||
InlineQueryResultContact).de_json(data)
|
||||
data = super(InlineQueryResultContact, InlineQueryResultContact).de_json(data)
|
||||
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(
|
||||
data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(
|
||||
data.get('input_message_content'))
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(data.get(
|
||||
'input_message_content'))
|
||||
|
||||
return InlineQueryResultContact(**data)
|
||||
|
||||
@@ -16,15 +16,14 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains the classes that represent Telegram
|
||||
InlineQueryResultDocument"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, \
|
||||
InputMessageContent
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageContent
|
||||
|
||||
|
||||
class InlineQueryResultDocument(InlineQueryResult):
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
document_url,
|
||||
@@ -62,12 +61,10 @@ class InlineQueryResultDocument(InlineQueryResult):
|
||||
|
||||
@staticmethod
|
||||
def de_json(data):
|
||||
data = super(InlineQueryResultDocument,
|
||||
InlineQueryResultDocument).de_json(data)
|
||||
data = super(InlineQueryResultDocument, InlineQueryResultDocument).de_json(data)
|
||||
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(
|
||||
data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(
|
||||
data.get('input_message_content'))
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(data.get(
|
||||
'input_message_content'))
|
||||
|
||||
return InlineQueryResultDocument(**data)
|
||||
|
||||
@@ -16,15 +16,14 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains the classes that represent Telegram
|
||||
InlineQueryResultGif"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, \
|
||||
InputMessageContent
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageContent
|
||||
|
||||
|
||||
class InlineQueryResultGif(InlineQueryResult):
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
gif_url,
|
||||
@@ -58,12 +57,10 @@ class InlineQueryResultGif(InlineQueryResult):
|
||||
|
||||
@staticmethod
|
||||
def de_json(data):
|
||||
data = super(InlineQueryResultGif,
|
||||
InlineQueryResultGif).de_json(data)
|
||||
data = super(InlineQueryResultGif, InlineQueryResultGif).de_json(data)
|
||||
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(
|
||||
data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(
|
||||
data.get('input_message_content'))
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(data.get(
|
||||
'input_message_content'))
|
||||
|
||||
return InlineQueryResultGif(**data)
|
||||
|
||||
@@ -16,15 +16,14 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains the classes that represent Telegram
|
||||
InlineQueryResultLocation"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, \
|
||||
InputMessageContent
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageContent
|
||||
|
||||
|
||||
class InlineQueryResultLocation(InlineQueryResult):
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
latitude,
|
||||
@@ -56,12 +55,10 @@ class InlineQueryResultLocation(InlineQueryResult):
|
||||
|
||||
@staticmethod
|
||||
def de_json(data):
|
||||
data = super(InlineQueryResultLocation,
|
||||
InlineQueryResultLocation).de_json(data)
|
||||
data = super(InlineQueryResultLocation, InlineQueryResultLocation).de_json(data)
|
||||
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(
|
||||
data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(
|
||||
data.get('input_message_content'))
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(data.get(
|
||||
'input_message_content'))
|
||||
|
||||
return InlineQueryResultLocation(**data)
|
||||
|
||||
@@ -16,15 +16,14 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains the classes that represent Telegram
|
||||
InlineQueryResultMpeg4Gif"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, \
|
||||
InputMessageContent
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageContent
|
||||
|
||||
|
||||
class InlineQueryResultMpeg4Gif(InlineQueryResult):
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
mpeg4_url,
|
||||
@@ -58,12 +57,10 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult):
|
||||
|
||||
@staticmethod
|
||||
def de_json(data):
|
||||
data = super(InlineQueryResultMpeg4Gif,
|
||||
InlineQueryResultMpeg4Gif).de_json(data)
|
||||
data = super(InlineQueryResultMpeg4Gif, InlineQueryResultMpeg4Gif).de_json(data)
|
||||
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(
|
||||
data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(
|
||||
data.get('input_message_content'))
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(data.get(
|
||||
'input_message_content'))
|
||||
|
||||
return InlineQueryResultMpeg4Gif(**data)
|
||||
|
||||
@@ -16,15 +16,14 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains the classes that represent Telegram
|
||||
InlineQueryResultPhoto"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, \
|
||||
InputMessageContent
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageContent
|
||||
|
||||
|
||||
class InlineQueryResultPhoto(InlineQueryResult):
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
photo_url,
|
||||
@@ -60,12 +59,10 @@ class InlineQueryResultPhoto(InlineQueryResult):
|
||||
|
||||
@staticmethod
|
||||
def de_json(data):
|
||||
data = super(InlineQueryResultPhoto,
|
||||
InlineQueryResultPhoto).de_json(data)
|
||||
data = super(InlineQueryResultPhoto, InlineQueryResultPhoto).de_json(data)
|
||||
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(
|
||||
data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(
|
||||
data.get('input_message_content'))
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(data.get(
|
||||
'input_message_content'))
|
||||
|
||||
return InlineQueryResultPhoto(**data)
|
||||
|
||||
@@ -16,15 +16,14 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains the classes that represent Telegram
|
||||
InlineQueryResultVenue"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, \
|
||||
InputMessageContent
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageContent
|
||||
|
||||
|
||||
class InlineQueryResultVenue(InlineQueryResult):
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
latitude,
|
||||
@@ -62,12 +61,10 @@ class InlineQueryResultVenue(InlineQueryResult):
|
||||
|
||||
@staticmethod
|
||||
def de_json(data):
|
||||
data = super(InlineQueryResultVenue,
|
||||
InlineQueryResultVenue).de_json(data)
|
||||
data = super(InlineQueryResultVenue, InlineQueryResultVenue).de_json(data)
|
||||
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(
|
||||
data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(
|
||||
data.get('input_message_content'))
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(data.get(
|
||||
'input_message_content'))
|
||||
|
||||
return InlineQueryResultVenue(**data)
|
||||
|
||||
@@ -16,15 +16,14 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains the classes that represent Telegram
|
||||
InlineQueryResultVideo"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, \
|
||||
InputMessageContent
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageContent
|
||||
|
||||
|
||||
class InlineQueryResultVideo(InlineQueryResult):
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
video_url,
|
||||
@@ -65,12 +64,10 @@ class InlineQueryResultVideo(InlineQueryResult):
|
||||
|
||||
@staticmethod
|
||||
def de_json(data):
|
||||
data = super(InlineQueryResultVideo,
|
||||
InlineQueryResultVideo).de_json(data)
|
||||
data = super(InlineQueryResultVideo, InlineQueryResultVideo).de_json(data)
|
||||
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(
|
||||
data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(
|
||||
data.get('input_message_content'))
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(data.get(
|
||||
'input_message_content'))
|
||||
|
||||
return InlineQueryResultVideo(**data)
|
||||
|
||||
@@ -16,15 +16,14 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains the classes that represent Telegram
|
||||
InlineQueryResultVoice"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, \
|
||||
InputMessageContent
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageContent
|
||||
|
||||
|
||||
class InlineQueryResultVoice(InlineQueryResult):
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
voice_url,
|
||||
@@ -49,12 +48,10 @@ class InlineQueryResultVoice(InlineQueryResult):
|
||||
|
||||
@staticmethod
|
||||
def de_json(data):
|
||||
data = super(InlineQueryResultVoice,
|
||||
InlineQueryResultVoice).de_json(data)
|
||||
data = super(InlineQueryResultVoice, InlineQueryResultVoice).de_json(data)
|
||||
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(
|
||||
data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(
|
||||
data.get('input_message_content'))
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(data.get('reply_markup'))
|
||||
data['input_message_content'] = InputMessageContent.de_json(data.get(
|
||||
'input_message_content'))
|
||||
|
||||
return InlineQueryResultVoice(**data)
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains the classes that represent Telegram
|
||||
InputContactMessageContent"""
|
||||
|
||||
@@ -26,10 +25,7 @@ from telegram import InputMessageContent
|
||||
class InputContactMessageContent(InputMessageContent):
|
||||
"""Base class for Telegram InputContactMessageContent Objects"""
|
||||
|
||||
def __init__(self,
|
||||
phone_number,
|
||||
first_name,
|
||||
last_name=None):
|
||||
def __init__(self, phone_number, first_name, last_name=None):
|
||||
# Required
|
||||
self.phone_number = phone_number
|
||||
self.first_name = first_name
|
||||
|
||||
+21
-32
@@ -17,33 +17,32 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a Telegram InputFile."""
|
||||
|
||||
try:
|
||||
# python 3
|
||||
from email.generator import _make_boundary as choose_boundary
|
||||
except ImportError:
|
||||
# python 2
|
||||
from mimetools import choose_boundary
|
||||
|
||||
import imghdr
|
||||
import mimetypes
|
||||
import os
|
||||
import sys
|
||||
import imghdr
|
||||
|
||||
try:
|
||||
from email.generator import _make_boundary as choose_boundary
|
||||
from urllib.request import urlopen
|
||||
except ImportError:
|
||||
from mimetools import choose_boundary
|
||||
from urllib2 import urlopen
|
||||
from future.moves.urllib.request import urlopen
|
||||
|
||||
from telegram import TelegramError
|
||||
|
||||
DEFAULT_MIME_TYPE = 'application/octet-stream'
|
||||
USER_AGENT = 'Python Telegram Bot' \
|
||||
' (https://github.com/python-telegram-bot/python-telegram-bot)'
|
||||
USER_AGENT = 'Python Telegram Bot (https://github.com/python-telegram-bot/python-telegram-bot)'
|
||||
|
||||
|
||||
class InputFile(object):
|
||||
"""This object represents a Telegram InputFile."""
|
||||
|
||||
def __init__(self,
|
||||
data):
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
self.boundary = choose_boundary()
|
||||
|
||||
@@ -81,18 +80,18 @@ class InputFile(object):
|
||||
if 'filename' in data:
|
||||
self.filename = self.data.pop('filename')
|
||||
elif hasattr(self.input_file, 'name'):
|
||||
# on py2.7, pylint fails to understand this properly
|
||||
# pylint: disable=E1101
|
||||
self.filename = os.path.basename(self.input_file.name)
|
||||
elif from_url:
|
||||
self.filename = os.path.basename(self.input_file.url) \
|
||||
.split('?')[0].split('&')[0]
|
||||
self.filename = os.path.basename(self.input_file.url).split('?')[0].split('&')[0]
|
||||
|
||||
try:
|
||||
self.mimetype = InputFile.is_image(self.input_file_content)
|
||||
if not self.filename or '.' not in self.filename:
|
||||
self.filename = self.mimetype.replace('/', '.')
|
||||
except TelegramError:
|
||||
self.mimetype = mimetypes.guess_type(self.filename)[0] or \
|
||||
DEFAULT_MIME_TYPE
|
||||
self.mimetype = mimetypes.guess_type(self.filename)[0] or DEFAULT_MIME_TYPE
|
||||
|
||||
@property
|
||||
def headers(self):
|
||||
@@ -100,8 +99,7 @@ class InputFile(object):
|
||||
Returns:
|
||||
str:
|
||||
"""
|
||||
return {'User-agent': USER_AGENT,
|
||||
'Content-type': self.content_type}
|
||||
return {'User-agent': USER_AGENT, 'Content-type': self.content_type}
|
||||
|
||||
@property
|
||||
def content_type(self):
|
||||
@@ -122,21 +120,14 @@ class InputFile(object):
|
||||
# Add data fields
|
||||
for name, value in self.data.items():
|
||||
form.extend([
|
||||
form_boundary,
|
||||
'Content-Disposition: form-data; name="%s"' % name,
|
||||
'',
|
||||
str(value)
|
||||
form_boundary, 'Content-Disposition: form-data; name="%s"' % name, '', str(value)
|
||||
])
|
||||
|
||||
# Add input_file to upload
|
||||
form.extend([
|
||||
form_boundary,
|
||||
'Content-Disposition: form-data; name="%s"; filename="%s"' % (
|
||||
form_boundary, 'Content-Disposition: form-data; name="%s"; filename="%s"' % (
|
||||
self.input_name, self.filename
|
||||
),
|
||||
'Content-Type: %s' % self.mimetype,
|
||||
'',
|
||||
self.input_file_content
|
||||
), 'Content-Type: %s' % self.mimetype, '', self.input_file_content
|
||||
])
|
||||
|
||||
form.append('--' + self.boundary + '--')
|
||||
@@ -189,14 +180,12 @@ class InputFile(object):
|
||||
bool
|
||||
"""
|
||||
if data:
|
||||
file_types = ['audio', 'document', 'photo', 'sticker', 'video',
|
||||
'voice', 'certificate']
|
||||
file_types = ['audio', 'document', 'photo', 'sticker', 'video', 'voice', 'certificate']
|
||||
file_type = [i for i in list(data.keys()) if i in file_types]
|
||||
|
||||
if file_type:
|
||||
file_content = data[file_type[0]]
|
||||
|
||||
return hasattr(file_content, 'read') or str(
|
||||
file_content).startswith('http')
|
||||
return hasattr(file_content, 'read') or str(file_content).startswith('http')
|
||||
|
||||
return False
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains the classes that represent Telegram
|
||||
InputLocationMessageContent"""
|
||||
|
||||
@@ -26,9 +25,7 @@ from telegram import InputMessageContent
|
||||
class InputLocationMessageContent(InputMessageContent):
|
||||
"""Base class for Telegram InputLocationMessageContent Objects"""
|
||||
|
||||
def __init__(self,
|
||||
latitude,
|
||||
longitude):
|
||||
def __init__(self, latitude, longitude):
|
||||
# Required
|
||||
self.latitude = latitude
|
||||
self.longitude = longitude
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains the classes that represent Telegram
|
||||
InputMessageContent"""
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains the classes that represent Telegram
|
||||
InputTextMessageContent"""
|
||||
|
||||
@@ -26,10 +25,7 @@ from telegram import InputMessageContent
|
||||
class InputTextMessageContent(InputMessageContent):
|
||||
"""Base class for Telegram InputTextMessageContent Objects"""
|
||||
|
||||
def __init__(self,
|
||||
message_text,
|
||||
parse_mode=None,
|
||||
disable_web_page_preview=None):
|
||||
def __init__(self, message_text, parse_mode=None, disable_web_page_preview=None):
|
||||
# Required
|
||||
self.message_text = message_text
|
||||
# Optionals
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains the classes that represent Telegram
|
||||
InputVenueMessageContent"""
|
||||
|
||||
@@ -26,12 +25,7 @@ from telegram import InputMessageContent
|
||||
class InputVenueMessageContent(InputMessageContent):
|
||||
"""Base class for Telegram InputVenueMessageContent Objects"""
|
||||
|
||||
def __init__(self,
|
||||
latitude,
|
||||
longitude,
|
||||
title,
|
||||
address,
|
||||
foursquare_id=None):
|
||||
def __init__(self, latitude, longitude, title, address, foursquare_id=None):
|
||||
# Required
|
||||
self.latitude = latitude
|
||||
self.longitude = longitude
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a Telegram KeyboardButton."""
|
||||
|
||||
from telegram import TelegramObject
|
||||
@@ -34,10 +33,7 @@ class KeyboardButton(TelegramObject):
|
||||
request_contact (Optional[bool]):
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
text,
|
||||
request_contact=None,
|
||||
request_location=None):
|
||||
def __init__(self, text, request_contact=None, request_location=None):
|
||||
# Required
|
||||
self.text = text
|
||||
# Optionals
|
||||
@@ -60,7 +56,6 @@ class KeyboardButton(TelegramObject):
|
||||
|
||||
keyboards = list()
|
||||
for keyboard in data:
|
||||
keyboards.append(KeyboardButton.
|
||||
de_json(keyboard))
|
||||
keyboards.append(KeyboardButton.de_json(keyboard))
|
||||
|
||||
return keyboards
|
||||
|
||||
@@ -16,14 +16,13 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a Telegram Location."""
|
||||
|
||||
from telegram import TelegramObject
|
||||
|
||||
|
||||
class Location(TelegramObject):
|
||||
"""This object represents a Telegram Sticker.
|
||||
"""This object represents a Telegram Location.
|
||||
|
||||
Attributes:
|
||||
longitude (float):
|
||||
@@ -34,9 +33,7 @@ class Location(TelegramObject):
|
||||
latitude (float):
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
longitude,
|
||||
latitude):
|
||||
def __init__(self, longitude, latitude):
|
||||
# Required
|
||||
self.longitude = float(longitude)
|
||||
self.latitude = float(latitude)
|
||||
|
||||
+10
-16
@@ -17,15 +17,13 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a Telegram Message."""
|
||||
|
||||
from datetime import datetime
|
||||
from time import mktime
|
||||
|
||||
from telegram import (Audio, Contact, Document, Chat, Location, PhotoSize,
|
||||
Sticker, TelegramObject, User, Video, Voice, Venue,
|
||||
MessageEntity)
|
||||
from telegram import (Audio, Contact, Document, Chat, Location, PhotoSize, Sticker, TelegramObject,
|
||||
User, Video, Voice, Venue, MessageEntity)
|
||||
|
||||
|
||||
class Message(TelegramObject):
|
||||
@@ -39,6 +37,7 @@ class Message(TelegramObject):
|
||||
from_user (:class:`telegram.User`):
|
||||
date (:class:`datetime.datetime`):
|
||||
forward_from (:class:`telegram.User`):
|
||||
forward_from_chat (:class:`telegram.Chat`):
|
||||
forward_date (:class:`datetime.datetime`):
|
||||
reply_to_message (:class:`telegram.Message`):
|
||||
text (str):
|
||||
@@ -78,6 +77,7 @@ class Message(TelegramObject):
|
||||
|
||||
Keyword Args:
|
||||
forward_from (Optional[:class:`telegram.User`]):
|
||||
forward_from_chat (:class:`telegram.Chat`):
|
||||
forward_date (Optional[:class:`datetime.datetime`]):
|
||||
reply_to_message (Optional[:class:`telegram.Message`]):
|
||||
text (Optional[str]):
|
||||
@@ -102,12 +102,7 @@ class Message(TelegramObject):
|
||||
channel_chat_created (Optional[bool]):
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
message_id,
|
||||
from_user,
|
||||
date,
|
||||
chat,
|
||||
**kwargs):
|
||||
def __init__(self, message_id, from_user, date, chat, **kwargs):
|
||||
# Required
|
||||
self.message_id = int(message_id)
|
||||
self.from_user = from_user
|
||||
@@ -115,6 +110,7 @@ class Message(TelegramObject):
|
||||
self.chat = chat
|
||||
# Optionals
|
||||
self.forward_from = kwargs.get('forward_from')
|
||||
self.forward_from_chat = kwargs.get('forward_from_chat')
|
||||
self.forward_date = kwargs.get('forward_date')
|
||||
self.reply_to_message = kwargs.get('reply_to_message')
|
||||
self.text = kwargs.get('text', '')
|
||||
@@ -135,12 +131,10 @@ class Message(TelegramObject):
|
||||
self.new_chat_photo = kwargs.get('new_chat_photo')
|
||||
self.delete_chat_photo = bool(kwargs.get('delete_chat_photo', False))
|
||||
self.group_chat_created = bool(kwargs.get('group_chat_created', False))
|
||||
self.supergroup_chat_created = bool(kwargs.get(
|
||||
'supergroup_chat_created', False))
|
||||
self.supergroup_chat_created = bool(kwargs.get('supergroup_chat_created', False))
|
||||
self.migrate_to_chat_id = int(kwargs.get('migrate_to_chat_id', 0))
|
||||
self.migrate_from_chat_id = int(kwargs.get('migrate_from_chat_id', 0))
|
||||
self.channel_chat_created = bool(kwargs.get('channel_chat_created',
|
||||
False))
|
||||
self.channel_chat_created = bool(kwargs.get('channel_chat_created', False))
|
||||
self.pinned_message = kwargs.get('pinned_message')
|
||||
|
||||
@property
|
||||
@@ -165,9 +159,9 @@ class Message(TelegramObject):
|
||||
data['chat'] = Chat.de_json(data.get('chat'))
|
||||
data['entities'] = MessageEntity.de_list(data.get('entities'))
|
||||
data['forward_from'] = User.de_json(data.get('forward_from'))
|
||||
data['forward_from_chat'] = Chat.de_json(data.get('forward_from_chat'))
|
||||
data['forward_date'] = Message._fromtimestamp(data.get('forward_date'))
|
||||
data['reply_to_message'] = \
|
||||
Message.de_json(data.get('reply_to_message'))
|
||||
data['reply_to_message'] = Message.de_json(data.get('reply_to_message'))
|
||||
data['audio'] = Audio.de_json(data.get('audio'))
|
||||
data['document'] = Document.de_json(data.get('document'))
|
||||
data['photo'] = PhotoSize.de_list(data.get('photo'))
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a Telegram MessageEntity."""
|
||||
|
||||
from telegram import TelegramObject
|
||||
@@ -34,11 +33,7 @@ class MessageEntity(TelegramObject):
|
||||
url (Optional[str]):
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
type,
|
||||
offset,
|
||||
length,
|
||||
url=None):
|
||||
def __init__(self, type, offset, length, url=None):
|
||||
# Required
|
||||
self.type = type
|
||||
self.offset = offset
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a logging NullHandler."""
|
||||
|
||||
import logging
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a Telegram
|
||||
Message Parse Modes."""
|
||||
|
||||
|
||||
+3
-10
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a Telegram PhotoSize."""
|
||||
|
||||
from telegram import TelegramObject
|
||||
@@ -41,11 +40,7 @@ class PhotoSize(TelegramObject):
|
||||
file_size (Optional[int]):
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
file_id,
|
||||
width,
|
||||
height,
|
||||
**kwargs):
|
||||
def __init__(self, file_id, width, height, **kwargs):
|
||||
# Required
|
||||
self.file_id = str(file_id)
|
||||
self.width = int(width)
|
||||
@@ -56,10 +51,8 @@ class PhotoSize(TelegramObject):
|
||||
def __eq__(self, other):
|
||||
if not isinstance(other, self.__class__):
|
||||
return False
|
||||
return (self.file_id == other.file_id and
|
||||
self.width == other.width and
|
||||
self.height == other.height and
|
||||
self.file_size == other.file_size)
|
||||
return (self.file_id == other.file_id and self.width == other.width and
|
||||
self.height == other.height and self.file_size == other.file_size)
|
||||
|
||||
@staticmethod
|
||||
def de_json(data):
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a Telegram
|
||||
ReplyKeyboardHide."""
|
||||
|
||||
@@ -38,9 +37,7 @@ class ReplyKeyboardHide(ReplyMarkup):
|
||||
selective (Optional[bool]):
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
hide_keyboard=True,
|
||||
**kwargs):
|
||||
def __init__(self, hide_keyboard=True, **kwargs):
|
||||
# Required
|
||||
self.hide_keyboard = bool(hide_keyboard)
|
||||
# Optionals
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a Telegram
|
||||
ReplyKeyboardMarkup."""
|
||||
|
||||
@@ -42,9 +41,7 @@ class ReplyKeyboardMarkup(ReplyMarkup):
|
||||
selective (Optional[bool]):
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
keyboard,
|
||||
**kwargs):
|
||||
def __init__(self, keyboard, **kwargs):
|
||||
# Required
|
||||
self.keyboard = keyboard
|
||||
# Optionals
|
||||
@@ -64,8 +61,7 @@ class ReplyKeyboardMarkup(ReplyMarkup):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data['keyboard'] = [KeyboardButton.de_list(keyboard) for keyboard in
|
||||
data['keyboard']]
|
||||
data['keyboard'] = [KeyboardButton.de_list(keyboard) for keyboard in data['keyboard']]
|
||||
|
||||
return ReplyKeyboardMarkup(**data)
|
||||
|
||||
@@ -73,7 +69,12 @@ class ReplyKeyboardMarkup(ReplyMarkup):
|
||||
data = super(ReplyKeyboardMarkup, self).to_dict()
|
||||
|
||||
data['keyboard'] = []
|
||||
for keyboard in self.keyboard:
|
||||
data['keyboard'].append([x.to_dict() for x in keyboard])
|
||||
|
||||
for row in self.keyboard:
|
||||
r = []
|
||||
for button in row:
|
||||
if hasattr(button, 'to_dict'):
|
||||
r.append(button.to_dict()) # telegram.KeyboardButton
|
||||
else:
|
||||
r.append(button) # str
|
||||
data['keyboard'].append(r)
|
||||
return data
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""Base class for Telegram ReplyMarkup Objects."""
|
||||
|
||||
from telegram import TelegramObject
|
||||
|
||||
+4
-6
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a Telegram Sticker."""
|
||||
|
||||
from telegram import PhotoSize, TelegramObject
|
||||
@@ -30,6 +29,7 @@ class Sticker(TelegramObject):
|
||||
width (int):
|
||||
height (int):
|
||||
thumb (:class:`telegram.PhotoSize`):
|
||||
emoji (str):
|
||||
file_size (int):
|
||||
|
||||
Args:
|
||||
@@ -40,20 +40,18 @@ class Sticker(TelegramObject):
|
||||
|
||||
Keyword Args:
|
||||
thumb (Optional[:class:`telegram.PhotoSize`]):
|
||||
emoji (Optional[str]):
|
||||
file_size (Optional[int]):
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
file_id,
|
||||
width,
|
||||
height,
|
||||
**kwargs):
|
||||
def __init__(self, file_id, width, height, **kwargs):
|
||||
# Required
|
||||
self.file_id = str(file_id)
|
||||
self.width = int(width)
|
||||
self.height = int(height)
|
||||
# Optionals
|
||||
self.thumb = kwargs.get('thumb')
|
||||
self.emoji = kwargs.get('emoji', '')
|
||||
self.file_size = int(kwargs.get('file_size', 0))
|
||||
|
||||
@staticmethod
|
||||
|
||||
+4
-10
@@ -16,11 +16,9 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a Telegram Update."""
|
||||
|
||||
from telegram import (Message, TelegramObject, InlineQuery,
|
||||
ChosenInlineResult, CallbackQuery)
|
||||
from telegram import (Message, TelegramObject, InlineQuery, ChosenInlineResult, CallbackQuery)
|
||||
|
||||
|
||||
class Update(TelegramObject):
|
||||
@@ -44,9 +42,7 @@ class Update(TelegramObject):
|
||||
callback_query (Optional[:class:`telegram.CallbackQuery`]):
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
update_id,
|
||||
**kwargs):
|
||||
def __init__(self, update_id, **kwargs):
|
||||
# Required
|
||||
self.update_id = int(update_id)
|
||||
# Optionals
|
||||
@@ -69,9 +65,7 @@ class Update(TelegramObject):
|
||||
|
||||
data['message'] = Message.de_json(data.get('message'))
|
||||
data['inline_query'] = InlineQuery.de_json(data.get('inline_query'))
|
||||
data['chosen_inline_result'] = \
|
||||
ChosenInlineResult.de_json(data.get('chosen_inline_result'))
|
||||
data['callback_query'] = \
|
||||
CallbackQuery.de_json(data.get('callback_query'))
|
||||
data['chosen_inline_result'] = ChosenInlineResult.de_json(data.get('chosen_inline_result'))
|
||||
data['callback_query'] = CallbackQuery.de_json(data.get('callback_query'))
|
||||
|
||||
return Update(**data)
|
||||
|
||||
+1
-5
@@ -17,7 +17,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a Telegram User."""
|
||||
|
||||
from telegram import TelegramObject
|
||||
@@ -44,10 +43,7 @@ class User(TelegramObject):
|
||||
username (Optional[str]):
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
first_name,
|
||||
**kwargs):
|
||||
def __init__(self, id, first_name, **kwargs):
|
||||
# Required
|
||||
self.id = int(id)
|
||||
self.first_name = first_name
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a Telegram
|
||||
UserProfilePhotos."""
|
||||
|
||||
@@ -35,9 +34,7 @@ class UserProfilePhotos(TelegramObject):
|
||||
photos (List[List[:class:`telegram.PhotoSize`]]):
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
total_count,
|
||||
photos):
|
||||
def __init__(self, total_count, photos):
|
||||
# Required
|
||||
self.total_count = int(total_count)
|
||||
self.photos = photos
|
||||
|
||||
@@ -44,9 +44,8 @@ class Botan(object):
|
||||
urlopen(request)
|
||||
return True
|
||||
except HTTPError as error:
|
||||
self.logger.warn('Botan track error ' +
|
||||
str(error.code) +
|
||||
':' + error.read().decode('utf-8'))
|
||||
self.logger.warn('Botan track error ' + str(error.code) + ':' + error.read().decode(
|
||||
'utf-8'))
|
||||
return False
|
||||
except URLError as error:
|
||||
self.logger.warn('Botan track error ' + str(error.reason))
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2016
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module facilitates the deprecation of functions"""
|
||||
|
||||
import warnings
|
||||
|
||||
|
||||
def deprecate(func, old, new):
|
||||
"""Warn users invoking old to switch to the new function."""
|
||||
|
||||
def f(*args, **kwargs):
|
||||
warnings.warn("{0} is being deprecated, please use {1} from now on".format(old, new))
|
||||
return func(*args, **kwargs)
|
||||
|
||||
return f
|
||||
@@ -1,5 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=no-name-in-module,unused-import
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2016
|
||||
@@ -17,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains methods to make POST and GET requests"""
|
||||
|
||||
import functools
|
||||
@@ -25,22 +23,9 @@ import json
|
||||
import socket
|
||||
from ssl import SSLError
|
||||
|
||||
try:
|
||||
# python2
|
||||
from httplib import HTTPException
|
||||
except ImportError:
|
||||
# python3
|
||||
from http.client import HTTPException
|
||||
|
||||
try:
|
||||
# python3
|
||||
from urllib.request import urlopen, urlretrieve, Request
|
||||
from urllib.error import HTTPError, URLError
|
||||
except ImportError:
|
||||
# python2
|
||||
from urllib import urlretrieve
|
||||
from urllib2 import urlopen, Request, URLError
|
||||
from urllib2 import HTTPError
|
||||
from future.moves.http.client import HTTPException
|
||||
from future.moves.urllib.error import HTTPError, URLError
|
||||
from future.moves.urllib.request import urlopen, urlretrieve, Request
|
||||
|
||||
from telegram import (InputFile, TelegramError)
|
||||
from telegram.error import Unauthorized, NetworkError, TimedOut
|
||||
@@ -71,6 +56,7 @@ def _parse(json_data):
|
||||
|
||||
def _try_except_req(func):
|
||||
"""Decorator for requests to handle known exceptions"""
|
||||
|
||||
@functools.wraps(func)
|
||||
def decorator(*args, **kwargs):
|
||||
try:
|
||||
@@ -128,10 +114,7 @@ def get(url):
|
||||
|
||||
|
||||
@_try_except_req
|
||||
def post(url,
|
||||
data,
|
||||
timeout=None,
|
||||
network_delay=2.):
|
||||
def post(url, data, timeout=None):
|
||||
"""Request an URL.
|
||||
Args:
|
||||
url:
|
||||
@@ -141,11 +124,6 @@ def post(url,
|
||||
timeout:
|
||||
float. If this value is specified, use it as the definitive timeout (in
|
||||
seconds) for urlopen() operations. [Optional]
|
||||
network_delay:
|
||||
float. If using the timeout specified in `data` (which is a timeout for
|
||||
the Telegram servers operation), then `network_delay` as an extra delay
|
||||
(in seconds) to compensate for network latency.
|
||||
default: 2 [Optional]
|
||||
|
||||
Notes:
|
||||
If neither `timeout` nor `data['timeout']` is specified. The underlying
|
||||
@@ -159,27 +137,20 @@ def post(url,
|
||||
|
||||
if timeout is not None:
|
||||
urlopen_kwargs['timeout'] = timeout
|
||||
elif 'timeout' in data:
|
||||
urlopen_kwargs['timeout'] = data['timeout'] + network_delay
|
||||
|
||||
if InputFile.is_inputfile(data):
|
||||
data = InputFile(data)
|
||||
request = Request(url,
|
||||
data=data.to_form(),
|
||||
headers=data.headers)
|
||||
request = Request(url, data=data.to_form(), headers=data.headers)
|
||||
else:
|
||||
data = json.dumps(data)
|
||||
request = Request(url,
|
||||
data=data.encode(),
|
||||
headers={'Content-Type': 'application/json'})
|
||||
request = Request(url, data=data.encode(), headers={'Content-Type': 'application/json'})
|
||||
|
||||
result = urlopen(request, **urlopen_kwargs).read()
|
||||
return _parse(result)
|
||||
|
||||
|
||||
@_try_except_req
|
||||
def download(url,
|
||||
filename):
|
||||
def download(url, filename):
|
||||
"""Download a file by its URL.
|
||||
Args:
|
||||
url:
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains functions to validate function arguments"""
|
||||
|
||||
from telegram.error import InvalidToken
|
||||
|
||||
@@ -9,7 +9,6 @@ try:
|
||||
except ImportError:
|
||||
import http.server as BaseHTTPServer
|
||||
|
||||
|
||||
logging.getLogger(__name__).addHandler(NullHandler())
|
||||
|
||||
|
||||
@@ -21,10 +20,9 @@ class _InvalidPost(Exception):
|
||||
|
||||
|
||||
class WebhookServer(BaseHTTPServer.HTTPServer, object):
|
||||
def __init__(self, server_address, RequestHandlerClass, update_queue,
|
||||
webhook_path):
|
||||
super(WebhookServer, self).__init__(server_address,
|
||||
RequestHandlerClass)
|
||||
|
||||
def __init__(self, server_address, RequestHandlerClass, update_queue, webhook_path):
|
||||
super(WebhookServer, self).__init__(server_address, RequestHandlerClass)
|
||||
self.logger = logging.getLogger(__name__)
|
||||
self.update_queue = update_queue
|
||||
self.webhook_path = webhook_path
|
||||
@@ -85,13 +83,11 @@ class WebhookHandler(BaseHTTPServer.BaseHTTPRequestHandler, object):
|
||||
self.logger.debug('Webhook received data: ' + json_string)
|
||||
|
||||
update = Update.de_json(json.loads(json_string))
|
||||
self.logger.debug('Received Update with ID %d on Webhook' %
|
||||
update.update_id)
|
||||
self.logger.debug('Received Update with ID %d on Webhook' % update.update_id)
|
||||
self.server.update_queue.put(update)
|
||||
|
||||
def _validate_post(self):
|
||||
if not (self.path == self.server.webhook_path and
|
||||
'content-type' in self.headers and
|
||||
if not (self.path == self.server.webhook_path and 'content-type' in self.headers and
|
||||
self.headers['content-type'] == 'application/json'):
|
||||
raise _InvalidPost(403)
|
||||
|
||||
|
||||
+1
-6
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a Telegram Venue."""
|
||||
|
||||
from telegram import TelegramObject, Location
|
||||
@@ -33,11 +32,7 @@ class Venue(TelegramObject):
|
||||
foursquare_id (Optional[str]):
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
location,
|
||||
title,
|
||||
address,
|
||||
foursquare_id=None):
|
||||
def __init__(self, location, title, address, foursquare_id=None):
|
||||
# Required
|
||||
self.location = location
|
||||
self.title = title
|
||||
|
||||
+1
-7
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a Telegram Video."""
|
||||
|
||||
from telegram import PhotoSize, TelegramObject
|
||||
@@ -47,12 +46,7 @@ class Video(TelegramObject):
|
||||
file_size (Optional[int]):
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
file_id,
|
||||
width,
|
||||
height,
|
||||
duration,
|
||||
**kwargs):
|
||||
def __init__(self, file_id, width, height, duration, **kwargs):
|
||||
# Required
|
||||
self.file_id = str(file_id)
|
||||
self.width = int(width)
|
||||
|
||||
+1
-4
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
"""This module contains a object that represents a Telegram Voice."""
|
||||
|
||||
from telegram import TelegramObject
|
||||
@@ -41,9 +40,7 @@ class Voice(TelegramObject):
|
||||
file_size (Optional[int]):
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
file_id,
|
||||
**kwargs):
|
||||
def __init__(self, file_id, **kwargs):
|
||||
# Required
|
||||
self.file_id = str(file_id)
|
||||
# Optionals
|
||||
|
||||
+8
-5
@@ -18,10 +18,10 @@
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents a Base class for tests"""
|
||||
|
||||
import signal
|
||||
import sys
|
||||
|
||||
import os
|
||||
import sys
|
||||
import signal
|
||||
|
||||
from nose.tools import make_decorator
|
||||
|
||||
sys.path.append('.')
|
||||
@@ -36,8 +36,8 @@ class BaseTest(object):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(BaseTest, self).__init__(*args, **kwargs)
|
||||
|
||||
bot = telegram.Bot(os.environ.get(
|
||||
'TOKEN', '133505823:AAHZFMHno3mzVLErU5b5jJvaeG--qUyLyG0'))
|
||||
bot = telegram.Bot(os.environ.get('TOKEN',
|
||||
'133505823:AAHZFMHno3mzVLErU5b5jJvaeG--qUyLyG0'))
|
||||
chat_id = os.environ.get('CHAT_ID', '12173560')
|
||||
|
||||
self._bot = bot
|
||||
@@ -61,6 +61,7 @@ class BaseTest(object):
|
||||
|
||||
|
||||
class TestTimedOut(AssertionError):
|
||||
|
||||
def __init__(self, time_limit, frame):
|
||||
super(TestTimedOut, self).__init__('time_limit={0}'.format(time_limit))
|
||||
self.time_limit = time_limit
|
||||
@@ -68,7 +69,9 @@ class TestTimedOut(AssertionError):
|
||||
|
||||
|
||||
def timeout(time_limit):
|
||||
|
||||
def decorator(func):
|
||||
|
||||
def timed_out(_signum, frame):
|
||||
raise TestTimedOut(time_limit, frame)
|
||||
|
||||
|
||||
+9
-9
@@ -197,9 +197,9 @@ class AudioTest(BaseTest, unittest.TestCase):
|
||||
del (json_dict['file_id'])
|
||||
json_dict['audio'] = open(os.devnull, 'rb')
|
||||
|
||||
self.assertRaises(telegram.TelegramError,
|
||||
lambda: self._bot.sendAudio(chat_id=self._chat_id,
|
||||
**json_dict))
|
||||
self.assertRaises(
|
||||
telegram.TelegramError,
|
||||
lambda: self._bot.sendAudio(chat_id=self._chat_id, **json_dict))
|
||||
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
@@ -209,9 +209,9 @@ class AudioTest(BaseTest, unittest.TestCase):
|
||||
del (json_dict['file_id'])
|
||||
json_dict['audio'] = ''
|
||||
|
||||
self.assertRaises(telegram.TelegramError,
|
||||
lambda: self._bot.sendAudio(chat_id=self._chat_id,
|
||||
**json_dict))
|
||||
self.assertRaises(
|
||||
telegram.TelegramError,
|
||||
lambda: self._bot.sendAudio(chat_id=self._chat_id, **json_dict))
|
||||
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
@@ -221,9 +221,9 @@ class AudioTest(BaseTest, unittest.TestCase):
|
||||
del (json_dict['file_id'])
|
||||
del (json_dict['duration'])
|
||||
|
||||
self.assertRaises(TypeError,
|
||||
lambda: self._bot.sendAudio(chat_id=self._chat_id,
|
||||
**json_dict))
|
||||
self.assertRaises(
|
||||
TypeError,
|
||||
lambda: self._bot.sendAudio(chat_id=self._chat_id, **json_dict))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
+22
-33
@@ -19,9 +19,9 @@
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents Tests for Telegram Bot"""
|
||||
|
||||
import sys
|
||||
from datetime import datetime
|
||||
import io
|
||||
from datetime import datetime
|
||||
import sys
|
||||
|
||||
from flaky import flaky
|
||||
|
||||
@@ -54,26 +54,22 @@ class BotTest(BaseTest, unittest.TestCase):
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
def testSendMessage(self):
|
||||
message = self._bot.sendMessage(
|
||||
chat_id=self._chat_id,
|
||||
text='Моё судно на воздушной подушке полно угрей')
|
||||
message = self._bot.sendMessage(chat_id=self._chat_id,
|
||||
text='Моё судно на воздушной подушке полно угрей')
|
||||
|
||||
self.assertTrue(self.is_json(message.to_json()))
|
||||
self.assertEqual(message.text,
|
||||
u'Моё судно на воздушной подушке полно угрей')
|
||||
self.assertEqual(message.text, u'Моё судно на воздушной подушке полно угрей')
|
||||
self.assertTrue(isinstance(message.date, datetime))
|
||||
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
def testSilentSendMessage(self):
|
||||
message = self._bot.sendMessage(
|
||||
chat_id=self._chat_id,
|
||||
text='Моё судно на воздушной подушке полно угрей',
|
||||
disable_notification=True)
|
||||
message = self._bot.sendMessage(chat_id=self._chat_id,
|
||||
text='Моё судно на воздушной подушке полно угрей',
|
||||
disable_notification=True)
|
||||
|
||||
self.assertTrue(self.is_json(message.to_json()))
|
||||
self.assertEqual(message.text,
|
||||
u'Моё судно на воздушной подушке полно угрей')
|
||||
self.assertEqual(message.text, u'Моё судно на воздушной подушке полно угрей')
|
||||
self.assertTrue(isinstance(message.date, datetime))
|
||||
|
||||
@flaky(3, 1)
|
||||
@@ -100,10 +96,9 @@ class BotTest(BaseTest, unittest.TestCase):
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
def testSendPhoto(self):
|
||||
message = self._bot.sendPhoto(
|
||||
photo=open('tests/data/telegram.png', 'rb'),
|
||||
caption='testSendPhoto',
|
||||
chat_id=self._chat_id)
|
||||
message = self._bot.sendPhoto(photo=open('tests/data/telegram.png', 'rb'),
|
||||
caption='testSendPhoto',
|
||||
chat_id=self._chat_id)
|
||||
|
||||
self.assertTrue(self.is_json(message.to_json()))
|
||||
self.assertEqual(message.photo[0].file_size, 1451)
|
||||
@@ -112,11 +107,10 @@ class BotTest(BaseTest, unittest.TestCase):
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
def testSilentSendPhoto(self):
|
||||
message = self._bot.sendPhoto(
|
||||
photo=open('tests/data/telegram.png', 'rb'),
|
||||
caption='testSendPhoto',
|
||||
chat_id=self._chat_id,
|
||||
disable_notification=True)
|
||||
message = self._bot.sendPhoto(photo=open('tests/data/telegram.png', 'rb'),
|
||||
caption='testSendPhoto',
|
||||
chat_id=self._chat_id,
|
||||
disable_notification=True)
|
||||
|
||||
self.assertTrue(self.is_json(message.to_json()))
|
||||
self.assertEqual(message.photo[0].file_size, 1451)
|
||||
@@ -130,9 +124,8 @@ class BotTest(BaseTest, unittest.TestCase):
|
||||
chat_id=self._chat_id)
|
||||
|
||||
self.assertTrue(self.is_json(message.to_json()))
|
||||
self.assertEqual(
|
||||
message.photo[0].file_id,
|
||||
'AgADAQADyKcxGx8j9Qdp6d-gpUsw4Gja1i8ABEVJsVqQk8LfJ3wAAgI')
|
||||
self.assertEqual(message.photo[0].file_id,
|
||||
'AgADAQADyKcxGx8j9Qdp6d-gpUsw4Gja1i8ABEVJsVqQk8LfJ3wAAgI')
|
||||
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
@@ -177,8 +170,7 @@ class BotTest(BaseTest, unittest.TestCase):
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
def testSendChatAction(self):
|
||||
self._bot.sendChatAction(action=telegram.ChatAction.TYPING,
|
||||
chat_id=self._chat_id)
|
||||
self._bot.sendChatAction(action=telegram.ChatAction.TYPING, chat_id=self._chat_id)
|
||||
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
@@ -189,8 +181,7 @@ class BotTest(BaseTest, unittest.TestCase):
|
||||
self.assertEqual(upf.photos[0][0].file_size, 12421)
|
||||
|
||||
def _test_invalid_token(self, token):
|
||||
self.assertRaisesRegexp(telegram.error.InvalidToken, 'Invalid token',
|
||||
telegram.Bot, token)
|
||||
self.assertRaisesRegexp(telegram.error.InvalidToken, 'Invalid token', telegram.Bot, token)
|
||||
|
||||
def testInvalidToken1(self):
|
||||
self._test_invalid_token('123')
|
||||
@@ -202,14 +193,12 @@ class BotTest(BaseTest, unittest.TestCase):
|
||||
self._test_invalid_token('12:')
|
||||
|
||||
def testUnauthToken(self):
|
||||
with self.assertRaisesRegexp(telegram.error.Unauthorized,
|
||||
'Unauthorized'):
|
||||
with self.assertRaisesRegexp(telegram.error.Unauthorized, 'Unauthorized'):
|
||||
bot = telegram.Bot('1234:abcd1234')
|
||||
bot.getMe()
|
||||
|
||||
def testInvalidSrvResp(self):
|
||||
with self.assertRaisesRegexp(telegram.TelegramError,
|
||||
'Invalid server response'):
|
||||
with self.assertRaisesRegexp(telegram.TelegramError, 'Invalid server response'):
|
||||
# bypass the valid token check
|
||||
bot = telegram.Bot.__new__(telegram.Bot)
|
||||
bot.base_url = 'https://api.telegram.org/bot{0}'.format('12')
|
||||
|
||||
+3
-8
@@ -1,4 +1,4 @@
|
||||
# !/usr/bin/env python
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2016
|
||||
@@ -18,9 +18,8 @@
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents Tests for Telegram Chat"""
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
import sys
|
||||
sys.path.append('.')
|
||||
|
||||
import telegram
|
||||
@@ -35,11 +34,7 @@ class ChatTest(BaseTest, unittest.TestCase):
|
||||
self.title = 'ToledosPalaceBot - Group'
|
||||
self.type = 'group'
|
||||
|
||||
self.json_dict = {
|
||||
'id': self.id,
|
||||
'title': self.title,
|
||||
'type': self.type
|
||||
}
|
||||
self.json_dict = {'id': self.id, 'title': self.title, 'type': self.type}
|
||||
|
||||
def test_group_chat_de_json_empty_json(self):
|
||||
group_chat = telegram.Chat.de_json({})
|
||||
|
||||
@@ -52,8 +52,7 @@ class ChosenInlineResultTest(BaseTest, unittest.TestCase):
|
||||
result = telegram.ChosenInlineResult.de_json(self.json_dict)
|
||||
|
||||
self.assertEqual(result.result_id, self.result_id)
|
||||
self.assertDictEqual(result.from_user.to_dict(),
|
||||
self.from_user.to_dict())
|
||||
self.assertDictEqual(result.from_user.to_dict(), self.from_user.to_dict())
|
||||
self.assertEqual(result.query, self.query)
|
||||
|
||||
def test_choseninlineresult_to_json(self):
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user