fix merge conflict snakes with master

This commit is contained in:
Rahiel Kasim 2016-04-30 14:56:48 +02:00
commit 5971cb35f8
17 changed files with 126 additions and 230 deletions

View file

@ -1,3 +1,10 @@
**2016-04-29**
*Released 4.0.2*
- Bugfixes
- ``KeyboardReplyMarkup`` now accepts ``str`` again
**2016-04-27** **2016-04-27**
*Released 4.0.1* *Released 4.0.1*

View file

@ -60,7 +60,7 @@ author = u'Leandro Toledo'
# The short X.Y version. # The short X.Y version.
version = '4.0' version = '4.0'
# The full version, including alpha/beta/rc tags. # The full version, including alpha/beta/rc tags.
release = '4.0.1' release = '4.0.2'
# The language for content autogenerated by Sphinx. Refer to documentation # The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages. # for a list of supported languages.

View file

@ -75,7 +75,7 @@ def main():
# on different commands - answer in Telegram # on different commands - answer in Telegram
dp.add_handler(CommandHandler("start", start)) dp.add_handler(CommandHandler("start", start))
dp.add_handler(CommandHandler("help", start)) dp.add_handler(CommandHandler("help", start))
dp.add_handler(CommandHandler("set", set)) dp.add_handler(CommandHandler("set", set, pass_args=True))
# log all errors # log all errors
dp.add_error_handler(error) dp.add_error_handler(error)

View file

@ -26,7 +26,7 @@ def requirements():
setup( setup(
name='python-telegram-bot', name='python-telegram-bot',
version='4.0.1', version='4.0.2',
author='Leandro Toledo', author='Leandro Toledo',
author_email='devs@python-telegram-bot.org', author_email='devs@python-telegram-bot.org',
license='LGPLv3', license='LGPLv3',

View file

@ -83,7 +83,7 @@ from .bot import Bot
__author__ = 'devs@python-telegram-bot.org' __author__ = 'devs@python-telegram-bot.org'
__version__ = '4.0.1' __version__ = '4.0.2'
__all__ = ['Audio', __all__ = ['Audio',
'Bot', 'Bot',
'Chat', 'Chat',

View file

@ -43,11 +43,9 @@ class Bot(TelegramObject):
Args: Args:
token (str): Bot's unique authentication. token (str): Bot's unique authentication.
**kwargs: Arbitrary keyword arguments.
Keyword Args:
base_url (Optional[str]): Telegram Bot API service URL. base_url (Optional[str]): Telegram Bot API service URL.
base_file_url (Optional[str]): Telegram Bot API file URL. base_file_url (Optional[str]): Telegram Bot API file URL.
""" """
def __init__(self, def __init__(self,
@ -141,8 +139,7 @@ class Bot(TelegramObject):
data['reply_markup'] = reply_markup data['reply_markup'] = reply_markup
result = request.post(url, data, result = request.post(url, data,
timeout=kwargs.get('timeout'), timeout=kwargs.get('timeout'))
network_delay=kwargs.get('network_delay'))
if result is True: if result is True:
return result return result
@ -208,10 +205,6 @@ class Bot(TelegramObject):
keyboard or to force a reply from the user. keyboard or to force a reply from the user.
timeout (Optional[float]): If this value is specified, use it as timeout (Optional[float]): If this value is specified, use it as
the definitive timeout (in seconds) for urlopen() operations. the definitive timeout (in seconds) for urlopen() operations.
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: Returns:
:class:`telegram.Message`: On success, the sent message is :class:`telegram.Message`: On success, the sent message is
@ -258,10 +251,6 @@ class Bot(TelegramObject):
receive a notification with no sound. receive a notification with no sound.
timeout (Optional[float]): If this value is specified, use it as timeout (Optional[float]): If this value is specified, use it as
the definitive timeout (in seconds) for urlopen() operations. the definitive timeout (in seconds) for urlopen() operations.
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: Returns:
:class:`telegram.Message`: On success, instance representing the :class:`telegram.Message`: On success, instance representing the
@ -317,10 +306,6 @@ class Bot(TelegramObject):
keyboard or to force a reply from the user. keyboard or to force a reply from the user.
timeout (Optional[float]): If this value is specified, use it as timeout (Optional[float]): If this value is specified, use it as
the definitive timeout (in seconds) for urlopen() operations. the definitive timeout (in seconds) for urlopen() operations.
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: Returns:
:class:`telegram.Message`: On success, instance representing the :class:`telegram.Message`: On success, instance representing the
@ -387,10 +372,6 @@ class Bot(TelegramObject):
keyboard or to force a reply from the user. keyboard or to force a reply from the user.
timeout (Optional[float]): If this value is specified, use it as timeout (Optional[float]): If this value is specified, use it as
the definitive timeout (in seconds) for urlopen() operations. the definitive timeout (in seconds) for urlopen() operations.
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: Returns:
:class:`telegram.Message`: On success, instance representing the :class:`telegram.Message`: On success, instance representing the
@ -451,10 +432,6 @@ class Bot(TelegramObject):
keyboard or to force a reply from the user. keyboard or to force a reply from the user.
timeout (Optional[float]): If this value is specified, use it as timeout (Optional[float]): If this value is specified, use it as
the definitive timeout (in seconds) for urlopen() operations. the definitive timeout (in seconds) for urlopen() operations.
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: Returns:
:class:`telegram.Message`: On success, instance representing the :class:`telegram.Message`: On success, instance representing the
@ -505,10 +482,6 @@ class Bot(TelegramObject):
keyboard or to force a reply from the user. keyboard or to force a reply from the user.
timeout (Optional[float]): If this value is specified, use it as timeout (Optional[float]): If this value is specified, use it as
the definitive timeout (in seconds) for urlopen() operations. the definitive timeout (in seconds) for urlopen() operations.
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: Returns:
:class:`telegram.Message`: On success, instance representing the :class:`telegram.Message`: On success, instance representing the
@ -562,10 +535,6 @@ class Bot(TelegramObject):
keyboard or to force a reply from the user. keyboard or to force a reply from the user.
timeout (Optional[float]): If this value is specified, use it as timeout (Optional[float]): If this value is specified, use it as
the definitive timeout (in seconds) for urlopen() operations. the definitive timeout (in seconds) for urlopen() operations.
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: Returns:
:class:`telegram.Message`: On success, instance representing the :class:`telegram.Message`: On success, instance representing the
@ -624,10 +593,6 @@ class Bot(TelegramObject):
keyboard or to force a reply from the user. keyboard or to force a reply from the user.
timeout (Optional[float]): If this value is specified, use it as timeout (Optional[float]): If this value is specified, use it as
the definitive timeout (in seconds) for urlopen() operations. the definitive timeout (in seconds) for urlopen() operations.
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: Returns:
:class:`telegram.Message`: On success, instance representing the :class:`telegram.Message`: On success, instance representing the
@ -677,10 +642,6 @@ class Bot(TelegramObject):
keyboard or to force a reply from the user. keyboard or to force a reply from the user.
timeout (Optional[float]): If this value is specified, use it as timeout (Optional[float]): If this value is specified, use it as
the definitive timeout (in seconds) for urlopen() operations. the definitive timeout (in seconds) for urlopen() operations.
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: Returns:
:class:`telegram.Message`: On success, instance representing the :class:`telegram.Message`: On success, instance representing the
@ -739,10 +700,6 @@ class Bot(TelegramObject):
keyboard or to force a reply from the user. keyboard or to force a reply from the user.
timeout (Optional[float]): If this value is specified, use it as timeout (Optional[float]): If this value is specified, use it as
the definitive timeout (in seconds) for urlopen() operations. the definitive timeout (in seconds) for urlopen() operations.
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: Returns:
:class:`telegram.Message`: On success, instance representing the :class:`telegram.Message`: On success, instance representing the
@ -800,10 +757,6 @@ class Bot(TelegramObject):
keyboard or to force a reply from the user. keyboard or to force a reply from the user.
timeout (Optional[float]): If this value is specified, use it as timeout (Optional[float]): If this value is specified, use it as
the definitive timeout (in seconds) for urlopen() operations. the definitive timeout (in seconds) for urlopen() operations.
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: Returns:
:class:`telegram.Message`: On success, instance representing the :class:`telegram.Message`: On success, instance representing the
@ -895,10 +848,6 @@ class Bot(TelegramObject):
Keyword Args: Keyword Args:
timeout (Optional[float]): If this value is specified, use it as timeout (Optional[float]): If this value is specified, use it as
the definitive timeout (in seconds) for urlopen() operations. the definitive timeout (in seconds) for urlopen() operations.
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: Returns:
bool: On success, `True` is returned. bool: On success, `True` is returned.
@ -927,8 +876,7 @@ class Bot(TelegramObject):
data['switch_pm_parameter'] = switch_pm_parameter data['switch_pm_parameter'] = switch_pm_parameter
result = request.post(url, data, result = request.post(url, data,
timeout=kwargs.get('timeout'), timeout=kwargs.get('timeout'))
network_delay=kwargs.get('network_delay'))
return result return result
@ -953,10 +901,6 @@ class Bot(TelegramObject):
Keyword Args: Keyword Args:
timeout (Optional[float]): If this value is specified, use it as timeout (Optional[float]): If this value is specified, use it as
the definitive timeout (in seconds) for urlopen() operations. the definitive timeout (in seconds) for urlopen() operations.
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: Returns:
list[:class:`telegram.UserProfilePhotos`]: A list of list[:class:`telegram.UserProfilePhotos`]: A list of
@ -977,8 +921,7 @@ class Bot(TelegramObject):
data['limit'] = limit data['limit'] = limit
result = request.post(url, data, result = request.post(url, data,
timeout=kwargs.get('timeout'), timeout=kwargs.get('timeout'))
network_delay=kwargs.get('network_delay'))
return UserProfilePhotos.de_json(result) return UserProfilePhotos.de_json(result)
@ -997,10 +940,6 @@ class Bot(TelegramObject):
Keyword Args: Keyword Args:
timeout (Optional[float]): If this value is specified, use it as timeout (Optional[float]): If this value is specified, use it as
the definitive timeout (in seconds) for urlopen() operations. the definitive timeout (in seconds) for urlopen() operations.
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: Returns:
:class:`telegram.File`: On success, a :class:`telegram.File` :class:`telegram.File`: On success, a :class:`telegram.File`
@ -1016,8 +955,7 @@ class Bot(TelegramObject):
data = {'file_id': file_id} data = {'file_id': file_id}
result = request.post(url, data, result = request.post(url, data,
timeout=kwargs.get('timeout'), timeout=kwargs.get('timeout'))
network_delay=kwargs.get('network_delay'))
if result.get('file_path'): if result.get('file_path'):
result['file_path'] = '%s/%s' % (self.base_file_url, result['file_path'] = '%s/%s' % (self.base_file_url,
@ -1045,10 +983,6 @@ class Bot(TelegramObject):
Keyword Args: Keyword Args:
timeout (Optional[float]): If this value is specified, use it as timeout (Optional[float]): If this value is specified, use it as
the definitive timeout (in seconds) for urlopen() operations. the definitive timeout (in seconds) for urlopen() operations.
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: Returns:
bool: On success, `True` is returned. bool: On success, `True` is returned.
@ -1064,8 +998,7 @@ class Bot(TelegramObject):
'user_id': user_id} 'user_id': user_id}
result = request.post(url, data, result = request.post(url, data,
timeout=kwargs.get('timeout'), timeout=kwargs.get('timeout'))
network_delay=kwargs.get('network_delay'))
return result return result
@ -1089,10 +1022,6 @@ class Bot(TelegramObject):
Keyword Args: Keyword Args:
timeout (Optional[float]): If this value is specified, use it as timeout (Optional[float]): If this value is specified, use it as
the definitive timeout (in seconds) for urlopen() operations. the definitive timeout (in seconds) for urlopen() operations.
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: Returns:
bool: On success, `True` is returned. bool: On success, `True` is returned.
@ -1108,8 +1037,7 @@ class Bot(TelegramObject):
'user_id': user_id} 'user_id': user_id}
result = request.post(url, data, result = request.post(url, data,
timeout=kwargs.get('timeout'), timeout=kwargs.get('timeout'))
network_delay=kwargs.get('network_delay'))
return result return result
@ -1158,13 +1086,11 @@ class Bot(TelegramObject):
data['show_alert'] = show_alert data['show_alert'] = show_alert
result = request.post(url, data, result = request.post(url, data,
timeout=kwargs.get('timeout'), timeout=kwargs.get('timeout'))
network_delay=kwargs.get('network_delay'))
return result return result
@log @log
@message
def editMessageText(self, def editMessageText(self,
text, text,
chat_id=None, chat_id=None,
@ -1172,6 +1098,7 @@ class Bot(TelegramObject):
inline_message_id=None, inline_message_id=None,
parse_mode=None, parse_mode=None,
disable_web_page_preview=None, disable_web_page_preview=None,
reply_markup=None,
**kwargs): **kwargs):
"""Use this method to edit text messages sent by the bot or via the bot """Use this method to edit text messages sent by the bot or via the bot
(for inline bots). (for inline bots).
@ -1194,16 +1121,12 @@ class Bot(TelegramObject):
italic, fixed-width text or inline URLs in your bot's message. italic, fixed-width text or inline URLs in your bot's message.
disable_web_page_preview: disable_web_page_preview:
Disables link previews for links in this message. Disables link previews for links in this message.
reply_markup:
A JSON-serialized object for an inline keyboard.
Keyword Args: 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 timeout (Optional[float]): If this value is specified, use it as
the definitive timeout (in seconds) for urlopen() operations. the definitive timeout (in seconds) for urlopen() operations.
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: Returns:
:class:`telegram.Message`: On success, if edited message is sent by :class:`telegram.Message`: On success, if edited message is sent by
@ -1229,8 +1152,16 @@ class Bot(TelegramObject):
data['parse_mode'] = parse_mode data['parse_mode'] = parse_mode
if disable_web_page_preview: if disable_web_page_preview:
data['disable_web_page_preview'] = disable_web_page_preview data['disable_web_page_preview'] = disable_web_page_preview
if reply_markup:
if isinstance(reply_markup, ReplyMarkup):
data['reply_markup'] = reply_markup.to_json()
else:
data['reply_markup'] = reply_markup
return url, data result = request.post(url, data,
timeout=kwargs.get('timeout'))
return Message.de_json(result)
@log @log
@message @message
@ -1259,10 +1190,6 @@ class Bot(TelegramObject):
A JSON-serialized object for an inline keyboard. A JSON-serialized object for an inline keyboard.
timeout (Optional[float]): If this value is specified, use it as timeout (Optional[float]): If this value is specified, use it as
the definitive timeout (in seconds) for urlopen() operations. the definitive timeout (in seconds) for urlopen() operations.
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: Returns:
:class:`telegram.Message`: On success, if edited message is sent by :class:`telegram.Message`: On success, if edited message is sent by
@ -1314,10 +1241,6 @@ class Bot(TelegramObject):
A JSON-serialized object for an inline keyboard. A JSON-serialized object for an inline keyboard.
timeout (Optional[float]): If this value is specified, use it as timeout (Optional[float]): If this value is specified, use it as
the definitive timeout (in seconds) for urlopen() operations. the definitive timeout (in seconds) for urlopen() operations.
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: Returns:
:class:`telegram.Message`: On success, if edited message is sent by :class:`telegram.Message`: On success, if edited message is sent by
@ -1346,7 +1269,8 @@ class Bot(TelegramObject):
def getUpdates(self, def getUpdates(self,
offset=None, offset=None,
limit=100, limit=100,
**kwargs): timeout=0,
network_delay=.2):
"""Use this method to receive incoming updates using long polling. """Use this method to receive incoming updates using long polling.
Args: Args:
@ -1359,14 +1283,14 @@ class Bot(TelegramObject):
limit: limit:
Limits the number of updates to be retrieved. Values between 1-100 Limits the number of updates to be retrieved. Values between 1-100
are accepted. Defaults to 100. are accepted. Defaults to 100.
timeout:
Keyword Args: Timeout in seconds for long polling. Defaults to 0, i.e. usual
timeout (Optional[float]): If this value is specified, use it as short polling.
the definitive timeout (in seconds) for urlopen() operations. network_delay:
network_delay (Optional[float]): If using the timeout (which is Additional timeout in seconds to allow the response from Telegram
a `timeout` for the Telegram servers operation), to take some time when using long polling. Defaults to 2, which
then `network_delay` as an extra delay (in seconds) to should be enough for most connections. Increase it if it takes very
compensate for network latency. Defaults to 2. long for data to be transmitted from and to the Telegram servers.
Returns: Returns:
list[:class:`telegram.Message`]: A list of :class:`telegram.Update` list[:class:`telegram.Message`]: A list of :class:`telegram.Update`
@ -1379,16 +1303,16 @@ class Bot(TelegramObject):
url = '{0}/getUpdates'.format(self.base_url) url = '{0}/getUpdates'.format(self.base_url)
data = {} data = {'timeout': timeout}
if offset: if offset:
data['offset'] = offset data['offset'] = offset
if limit: if limit:
data['limit'] = limit data['limit'] = limit
result = request.post(url, data, urlopen_timeout = timeout + network_delay
timeout=kwargs.get('timeout'),
network_delay=kwargs.get('network_delay')) result = request.post(url, data, timeout=urlopen_timeout)
if result: if result:
self.logger.debug( self.logger.debug(
@ -1417,10 +1341,6 @@ class Bot(TelegramObject):
Keyword Args: Keyword Args:
timeout (Optional[float]): If this value is specified, use it as timeout (Optional[float]): If this value is specified, use it as
the definitive timeout (in seconds) for urlopen() operations. the definitive timeout (in seconds) for urlopen() operations.
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: Returns:
bool: On success, `True` is returned. bool: On success, `True` is returned.
@ -1440,8 +1360,7 @@ class Bot(TelegramObject):
data['certificate'] = certificate data['certificate'] = certificate
result = request.post(url, data, result = request.post(url, data,
timeout=kwargs.get('timeout'), timeout=kwargs.get('timeout'))
network_delay=kwargs.get('network_delay'))
return result return result

View file

@ -20,17 +20,19 @@
"""This module contains a object that represents a Telegram InputFile.""" """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 mimetypes
import os import os
import sys import sys
import imghdr
try: from future.moves.urllib.request import urlopen
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 telegram import TelegramError from telegram import TelegramError
@ -81,6 +83,8 @@ class InputFile(object):
if 'filename' in data: if 'filename' in data:
self.filename = self.data.pop('filename') self.filename = self.data.pop('filename')
elif hasattr(self.input_file, 'name'): 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) self.filename = os.path.basename(self.input_file.name)
elif from_url: elif from_url:
self.filename = os.path.basename(self.input_file.url) \ self.filename = os.path.basename(self.input_file.url) \

View file

@ -73,7 +73,12 @@ class ReplyKeyboardMarkup(ReplyMarkup):
data = super(ReplyKeyboardMarkup, self).to_dict() data = super(ReplyKeyboardMarkup, self).to_dict()
data['keyboard'] = [] data['keyboard'] = []
for keyboard in self.keyboard: for row in self.keyboard:
data['keyboard'].append([x.to_dict() for x in 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 return data

View file

@ -1,5 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python
# pylint: disable=no-name-in-module,unused-import
# #
# A library that provides a Python interface to the Telegram Bot API # A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2016 # Copyright (C) 2015-2016
@ -25,22 +24,9 @@ import json
import socket import socket
from ssl import SSLError from ssl import SSLError
try: from future.moves.http.client import HTTPException
# python2 from future.moves.urllib.error import HTTPError, URLError
from httplib import HTTPException from future.moves.urllib.request import urlopen, urlretrieve, Request
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 telegram import (InputFile, TelegramError) from telegram import (InputFile, TelegramError)
from telegram.error import Unauthorized, NetworkError, TimedOut from telegram.error import Unauthorized, NetworkError, TimedOut
@ -130,8 +116,7 @@ def get(url):
@_try_except_req @_try_except_req
def post(url, def post(url,
data, data,
timeout=None, timeout=None):
network_delay=2.):
"""Request an URL. """Request an URL.
Args: Args:
url: url:
@ -141,11 +126,6 @@ def post(url,
timeout: timeout:
float. If this value is specified, use it as the definitive timeout (in float. If this value is specified, use it as the definitive timeout (in
seconds) for urlopen() operations. [Optional] 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: Notes:
If neither `timeout` nor `data['timeout']` is specified. The underlying If neither `timeout` nor `data['timeout']` is specified. The underlying
@ -159,8 +139,6 @@ def post(url,
if timeout is not None: if timeout is not None:
urlopen_kwargs['timeout'] = timeout urlopen_kwargs['timeout'] = timeout
elif 'timeout' in data:
urlopen_kwargs['timeout'] = data['timeout'] + network_delay
if InputFile.is_inputfile(data): if InputFile.is_inputfile(data):
data = InputFile(data) data = InputFile(data)

View file

@ -16,12 +16,13 @@
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents a Base class for tests""" """This module contains a object that represents a Base class for tests"""
import signal
import sys
import os import os
import sys
import signal
from nose.tools import make_decorator from nose.tools import make_decorator
sys.path.append('.') sys.path.append('.')
@ -61,6 +62,7 @@ class BaseTest(object):
class TestTimedOut(AssertionError): class TestTimedOut(AssertionError):
def __init__(self, time_limit, frame): def __init__(self, time_limit, frame):
super(TestTimedOut, self).__init__('time_limit={0}'.format(time_limit)) super(TestTimedOut, self).__init__('time_limit={0}'.format(time_limit))
self.time_limit = time_limit self.time_limit = time_limit

View file

@ -17,11 +17,12 @@
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents Tests for Telegram Bot""" """This module contains a object that represents Tests for Telegram Bot"""
import sys
from datetime import datetime
import io import io
from datetime import datetime
import sys
from flaky import flaky from flaky import flaky
@ -54,26 +55,22 @@ class BotTest(BaseTest, unittest.TestCase):
@flaky(3, 1) @flaky(3, 1)
@timeout(10) @timeout(10)
def testSendMessage(self): def testSendMessage(self):
message = self._bot.sendMessage( message = self._bot.sendMessage(chat_id=self._chat_id,
chat_id=self._chat_id, text='Моё судно на воздушной подушке полно угрей')
text='Моё судно на воздушной подушке полно угрей')
self.assertTrue(self.is_json(message.to_json())) self.assertTrue(self.is_json(message.to_json()))
self.assertEqual(message.text, self.assertEqual(message.text, u'Моё судно на воздушной подушке полно угрей')
u'Моё судно на воздушной подушке полно угрей')
self.assertTrue(isinstance(message.date, datetime)) self.assertTrue(isinstance(message.date, datetime))
@flaky(3, 1) @flaky(3, 1)
@timeout(10) @timeout(10)
def testSilentSendMessage(self): def testSilentSendMessage(self):
message = self._bot.sendMessage( message = self._bot.sendMessage(chat_id=self._chat_id,
chat_id=self._chat_id, text='Моё судно на воздушной подушке полно угрей',
text='Моё судно на воздушной подушке полно угрей', disable_notification=True)
disable_notification=True)
self.assertTrue(self.is_json(message.to_json())) self.assertTrue(self.is_json(message.to_json()))
self.assertEqual(message.text, self.assertEqual(message.text, u'Моё судно на воздушной подушке полно угрей')
u'Моё судно на воздушной подушке полно угрей')
self.assertTrue(isinstance(message.date, datetime)) self.assertTrue(isinstance(message.date, datetime))
@flaky(3, 1) @flaky(3, 1)
@ -100,10 +97,9 @@ class BotTest(BaseTest, unittest.TestCase):
@flaky(3, 1) @flaky(3, 1)
@timeout(10) @timeout(10)
def testSendPhoto(self): def testSendPhoto(self):
message = self._bot.sendPhoto( message = self._bot.sendPhoto(photo=open('tests/data/telegram.png', 'rb'),
photo=open('tests/data/telegram.png', 'rb'), caption='testSendPhoto',
caption='testSendPhoto', chat_id=self._chat_id)
chat_id=self._chat_id)
self.assertTrue(self.is_json(message.to_json())) self.assertTrue(self.is_json(message.to_json()))
self.assertEqual(message.photo[0].file_size, 1451) self.assertEqual(message.photo[0].file_size, 1451)
@ -112,11 +108,10 @@ class BotTest(BaseTest, unittest.TestCase):
@flaky(3, 1) @flaky(3, 1)
@timeout(10) @timeout(10)
def testSilentSendPhoto(self): def testSilentSendPhoto(self):
message = self._bot.sendPhoto( message = self._bot.sendPhoto(photo=open('tests/data/telegram.png', 'rb'),
photo=open('tests/data/telegram.png', 'rb'), caption='testSendPhoto',
caption='testSendPhoto', chat_id=self._chat_id,
chat_id=self._chat_id, disable_notification=True)
disable_notification=True)
self.assertTrue(self.is_json(message.to_json())) self.assertTrue(self.is_json(message.to_json()))
self.assertEqual(message.photo[0].file_size, 1451) self.assertEqual(message.photo[0].file_size, 1451)
@ -125,21 +120,17 @@ class BotTest(BaseTest, unittest.TestCase):
@flaky(3, 1) @flaky(3, 1)
@timeout(10) @timeout(10)
def testResendPhoto(self): def testResendPhoto(self):
message = self._bot.sendPhoto( message = self._bot.sendPhoto(photo='AgADAQADyKcxGx8j9Qdp6d-gpUsw4Gja1i8ABEVJsVqQk8LfJ3wAAgI',
photo='AgADAQADyKcxGx8j9Qdp6d-gpUsw4Gja1i8ABEVJsVqQk8LfJ3wAAgI', chat_id=self._chat_id)
chat_id=self._chat_id)
self.assertTrue(self.is_json(message.to_json())) self.assertTrue(self.is_json(message.to_json()))
self.assertEqual( self.assertEqual(message.photo[0].file_id, 'AgADAQADyKcxGx8j9Qdp6d-gpUsw4Gja1i8ABEVJsVqQk8LfJ3wAAgI')
message.photo[0].file_id,
'AgADAQADyKcxGx8j9Qdp6d-gpUsw4Gja1i8ABEVJsVqQk8LfJ3wAAgI')
@flaky(3, 1) @flaky(3, 1)
@timeout(10) @timeout(10)
def testSendJPGURLPhoto(self): def testSendJPGURLPhoto(self):
message = self._bot.sendPhoto( message = self._bot.sendPhoto(photo='http://dummyimage.com/600x400/000/fff.jpg&text=telegram',
photo='http://dummyimage.com/600x400/000/fff.jpg&text=telegram', chat_id=self._chat_id)
chat_id=self._chat_id)
self.assertTrue(self.is_json(message.to_json())) self.assertTrue(self.is_json(message.to_json()))
self.assertEqual(message.photo[0].file_size, 822) self.assertEqual(message.photo[0].file_size, 822)
@ -147,9 +138,8 @@ class BotTest(BaseTest, unittest.TestCase):
@flaky(3, 1) @flaky(3, 1)
@timeout(10) @timeout(10)
def testSendPNGURLPhoto(self): def testSendPNGURLPhoto(self):
message = self._bot.sendPhoto( message = self._bot.sendPhoto(photo='http://dummyimage.com/600x400/000/fff.png&text=telegram',
photo='http://dummyimage.com/600x400/000/fff.png&text=telegram', chat_id=self._chat_id)
chat_id=self._chat_id)
self.assertTrue(self.is_json(message.to_json())) self.assertTrue(self.is_json(message.to_json()))
self.assertEqual(message.photo[0].file_size, 684) self.assertEqual(message.photo[0].file_size, 684)
@ -157,9 +147,8 @@ class BotTest(BaseTest, unittest.TestCase):
@flaky(3, 1) @flaky(3, 1)
@timeout(10) @timeout(10)
def testSendGIFURLPhoto(self): def testSendGIFURLPhoto(self):
message = self._bot.sendPhoto( message = self._bot.sendPhoto(photo='http://dummyimage.com/600x400/000/fff.gif&text=telegram',
photo='http://dummyimage.com/600x400/000/fff.gif&text=telegram', chat_id=self._chat_id)
chat_id=self._chat_id)
self.assertTrue(self.is_json(message.to_json())) self.assertTrue(self.is_json(message.to_json()))
self.assertEqual(message.photo[0].file_size, 684) self.assertEqual(message.photo[0].file_size, 684)
@ -169,7 +158,8 @@ class BotTest(BaseTest, unittest.TestCase):
def testSendBufferedReaderPhoto(self): def testSendBufferedReaderPhoto(self):
photo = open('tests/data/telegram.png', 'rb') photo = open('tests/data/telegram.png', 'rb')
br_photo = io.BufferedReader(io.BytesIO(photo.read())) br_photo = io.BufferedReader(io.BytesIO(photo.read()))
message = self._bot.sendPhoto(photo=br_photo, chat_id=self._chat_id) message = self._bot.sendPhoto(photo=br_photo,
chat_id=self._chat_id)
self.assertTrue(self.is_json(message.to_json())) self.assertTrue(self.is_json(message.to_json()))
self.assertEqual(message.photo[0].file_size, 1451) self.assertEqual(message.photo[0].file_size, 1451)
@ -189,8 +179,7 @@ class BotTest(BaseTest, unittest.TestCase):
self.assertEqual(upf.photos[0][0].file_size, 12421) self.assertEqual(upf.photos[0][0].file_size, 12421)
def _test_invalid_token(self, token): def _test_invalid_token(self, token):
self.assertRaisesRegexp(telegram.error.InvalidToken, 'Invalid token', self.assertRaisesRegexp(telegram.error.InvalidToken, 'Invalid token', telegram.Bot, token)
telegram.Bot, token)
def testInvalidToken1(self): def testInvalidToken1(self):
self._test_invalid_token('123') self._test_invalid_token('123')
@ -202,14 +191,12 @@ class BotTest(BaseTest, unittest.TestCase):
self._test_invalid_token('12:') self._test_invalid_token('12:')
def testUnauthToken(self): def testUnauthToken(self):
with self.assertRaisesRegexp(telegram.error.Unauthorized, with self.assertRaisesRegexp(telegram.error.Unauthorized, 'Unauthorized'):
'Unauthorized'):
bot = telegram.Bot('1234:abcd1234') bot = telegram.Bot('1234:abcd1234')
bot.getMe() bot.getMe()
def testInvalidSrvResp(self): def testInvalidSrvResp(self):
with self.assertRaisesRegexp(telegram.TelegramError, with self.assertRaisesRegexp(telegram.TelegramError, 'Invalid server response'):
'Invalid server response'):
# bypass the valid token check # bypass the valid token check
bot = telegram.Bot.__new__(telegram.Bot) bot = telegram.Bot.__new__(telegram.Bot)
bot.base_url = 'https://api.telegram.org/bot{0}'.format('12') bot.base_url = 'https://api.telegram.org/bot{0}'.format('12')

View file

@ -1,4 +1,4 @@
# !/usr/bin/env python #!/usr/bin/env python
# #
# A library that provides a Python interface to the Telegram Bot API # A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2016 # Copyright (C) 2015-2016
@ -16,11 +16,11 @@
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents Tests for Telegram Chat""" """This module contains a object that represents Tests for Telegram Chat"""
import sys
import unittest import unittest
import sys
sys.path.append('.') sys.path.append('.')
import telegram import telegram
@ -66,6 +66,5 @@ class ChatTest(BaseTest, unittest.TestCase):
self.assertEqual(group_chat['title'], self.title) self.assertEqual(group_chat['title'], self.title)
self.assertEqual(group_chat['type'], self.type) self.assertEqual(group_chat['type'], self.type)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View file

@ -1,4 +1,4 @@
# !/usr/bin/env python #!/usr/bin/env python
# #
# A library that provides a Python interface to the Telegram Bot API # A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2016 # Copyright (C) 2015-2016
@ -16,11 +16,11 @@
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents Tests for Telegram Contact""" """This module contains a object that represents Tests for Telegram Contact"""
import sys
import unittest import unittest
import sys
sys.path.append('.') sys.path.append('.')
import telegram import telegram
@ -65,6 +65,5 @@ class ContactTest(BaseTest, unittest.TestCase):
self.assertEqual(contact['last_name'], self.last_name) self.assertEqual(contact['last_name'], self.last_name)
self.assertEqual(contact['user_id'], self.user_id) self.assertEqual(contact['user_id'], self.user_id)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View file

@ -16,13 +16,14 @@
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents Tests for Telegram Emoji""" """This module contains a object that represents Tests for Telegram Emoji"""
import sys
import unittest import unittest
import sys
sys.path.append('.') sys.path.append('.')
import telegram
from telegram.emoji import Emoji from telegram.emoji import Emoji
from tests.base import BaseTest from tests.base import BaseTest

View file

@ -29,11 +29,6 @@ if sys.version_info[0:2] == (2, 6):
else: else:
import unittest import unittest
try:
from urllib2 import urlopen, Request
except ImportError:
from urllib.request import Request, urlopen
sys.path.append('.') sys.path.append('.')
from telegram.ext import JobQueue, Updater from telegram.ext import JobQueue, Updater

View file

@ -16,11 +16,11 @@
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents Tests for Telegram Location""" """This module contains a object that represents Tests for Telegram Location"""
import sys
import unittest import unittest
import sys
sys.path.append('.') sys.path.append('.')
import telegram import telegram
@ -40,7 +40,8 @@ class LocationTest(BaseTest, unittest.TestCase):
} }
def test_send_location_implicit_args(self): def test_send_location_implicit_args(self):
message = self._bot.sendLocation(self._chat_id, self.latitude, message = self._bot.sendLocation(self._chat_id,
self.latitude,
self.longitude) self.longitude)
location = message.location location = message.location

View file

@ -1,4 +1,4 @@
# !/usr/bin/env python #!/usr/bin/env python
# #
# A library that provides a Python interface to the Telegram Bot API # A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2016 # Copyright (C) 2015-2016
@ -16,11 +16,11 @@
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents Tests for Telegram User""" """This module contains a object that represents Tests for Telegram User"""
import sys
import unittest import unittest
import sys
sys.path.append('.') sys.path.append('.')
import telegram import telegram
@ -59,7 +59,7 @@ class UserTest(BaseTest, unittest.TestCase):
def test_user_de_json_without_username(self): def test_user_de_json_without_username(self):
json_dict = self.json_dict json_dict = self.json_dict
del (json_dict['username']) del(json_dict['username'])
user = telegram.User.de_json(self.json_dict) user = telegram.User.de_json(self.json_dict)
@ -68,14 +68,14 @@ class UserTest(BaseTest, unittest.TestCase):
self.assertEqual(user.last_name, self.last_name) self.assertEqual(user.last_name, self.last_name)
self.assertEqual(user.type, self.type) self.assertEqual(user.type, self.type)
self.assertEqual(user.name, self.assertEqual(user.name, '%s %s' % (self.first_name, self.last_name))
'%s %s' % (self.first_name, self.last_name))
def test_user_de_json_without_username_and_lastname(self): def test_user_de_json_without_username_and_lastname(self):
json_dict = self.json_dict json_dict = self.json_dict
del (json_dict['username']) del(json_dict['username'])
del (json_dict['last_name']) del(json_dict['last_name'])
user = telegram.User.de_json(self.json_dict) user = telegram.User.de_json(self.json_dict)
@ -99,6 +99,5 @@ class UserTest(BaseTest, unittest.TestCase):
self.assertEqual(user['username'], self.username) self.assertEqual(user['username'], self.username)
self.assertEqual(user['type'], self.type) self.assertEqual(user['type'], self.type)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()