mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2025-03-14 11:43:50 +01:00
Merge from master and resolve conflicts
Merge from master and resolve conflicts
This commit is contained in:
commit
f735a37828
30 changed files with 246 additions and 131 deletions
2
.gitmodules
vendored
2
.gitmodules
vendored
|
@ -1,4 +1,4 @@
|
|||
[submodule "telegram/vendor/urllib3"]
|
||||
path = telegram/vendor/urllib3
|
||||
path = telegram/vendor/ptb_urllib3
|
||||
url = https://github.com/python-telegram-bot/urllib3.git
|
||||
branch = ptb
|
||||
|
|
|
@ -18,5 +18,6 @@ install:
|
|||
script:
|
||||
- nosetests -v --with-flaky --no-flaky-report --with-coverage --cover-package=telegram/ tests
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == 3.5 ]]; then pre-commit run --all-files; fi
|
||||
- python ./setup.py bdist_dumb
|
||||
after_success:
|
||||
coveralls
|
||||
|
|
|
@ -2,7 +2,13 @@
|
|||
Changes
|
||||
=======
|
||||
|
||||
**2017-05-21**
|
||||
**2017-05-29**
|
||||
|
||||
*Released 6.0.2*
|
||||
|
||||
- Avoid confusion with user's ``urllib3`` by renaming vendored ``urllib3`` to ``ptb_urllib3``
|
||||
|
||||
**2017-05-19**
|
||||
|
||||
*Released 6.0.1*
|
||||
|
||||
|
@ -80,6 +86,7 @@ Changes
|
|||
|
||||
- Rework ``JobQueue``
|
||||
- Introduce ``ConversationHandler``
|
||||
- Introduce ``telegram.constants`` - https://github.com/python-telegram-bot/python-telegram-bot/pull/342
|
||||
|
||||
**2016-07-12**
|
||||
|
||||
|
|
|
@ -84,7 +84,13 @@ make the development of bots easy and straightforward. These classes are contain
|
|||
Telegram API support
|
||||
====================
|
||||
|
||||
As of **4. Dec 2016**, all types and methods of the Telegram Bot API are supported.
|
||||
As of **21. May 2017**, all types and methods of the Telegram Bot API 2.3.1 are supported. Additionally, the ``deleteMessage`` API function and the field ``User.language_code`` are supported.
|
||||
|
||||
Also, version 6.1 beta 0 is available, offering full but experimental Bot API 3.0 coverage:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
$ pip install python-telegram-bot==6.1b0
|
||||
|
||||
==========
|
||||
Installing
|
||||
|
|
|
@ -61,7 +61,7 @@ author = u'Leandro Toledo'
|
|||
# The short X.Y version.
|
||||
version = '6.0' # telegram.__version__[:3]
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '6.0.1' # telegram.__version__
|
||||
release = '6.0.2' # telegram.__version__
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
|
5
setup.py
5
setup.py
|
@ -18,11 +18,6 @@ def requirements():
|
|||
|
||||
|
||||
packages = find_packages(exclude=['tests*'])
|
||||
packages.extend(['telegram.vendor.urllib3.urllib3',
|
||||
'telegram.vendor.urllib3.urllib3.packages', 'telegram.vendor.urllib3.urllib3.packages.ssl_match_hostname',
|
||||
'telegram.vendor.urllib3.urllib3.packages.backports', 'telegram.vendor.urllib3.urllib3.contrib',
|
||||
'telegram.vendor.urllib3.urllib3.util',
|
||||
])
|
||||
|
||||
with codecs.open('README.rst', 'r', 'utf-8') as fd:
|
||||
fn = os.path.join('telegram', 'version.py')
|
||||
|
|
|
@ -22,8 +22,6 @@ from sys import version_info
|
|||
import sys
|
||||
import os
|
||||
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'vendor', 'urllib3'))
|
||||
|
||||
from .base import TelegramObject
|
||||
from .user import User
|
||||
from .chat import Chat
|
||||
|
|
|
@ -687,9 +687,9 @@ class Bot(TelegramObject):
|
|||
|
||||
Args:
|
||||
chat_id (int|str): Unique identifier for the message recipient - Chat id.
|
||||
voice: Video note to send. Pass a file_id as String to send a video note that exists
|
||||
on the Telegram servers (recommended) or upload a new video. Sending video notes
|
||||
by a URL is currently unsupported
|
||||
video_note (InputFile|str): Video note to send. Pass a file_id as String to send a
|
||||
video note that exists on the Telegram servers (recommended) or upload a new video.
|
||||
Sending video notes by a URL is currently unsupported
|
||||
duration (Optional[int]): Duration of sent audio in seconds.
|
||||
length (Optional[int]): Video width and height
|
||||
disable_notification (Optional[bool]): Sends the message silently. iOS users will not
|
||||
|
@ -713,9 +713,9 @@ class Bot(TelegramObject):
|
|||
|
||||
data = {'chat_id': chat_id, 'video_note': video_note}
|
||||
|
||||
if duration:
|
||||
if duration is not None:
|
||||
data['duration'] = duration
|
||||
if length:
|
||||
if length is not None:
|
||||
data['length'] = length
|
||||
|
||||
return self._message_wrapper(
|
||||
|
@ -1906,23 +1906,23 @@ class Bot(TelegramObject):
|
|||
'prices': [p.to_dict() for p in prices]
|
||||
}
|
||||
|
||||
if photo_url:
|
||||
if photo_url is not None:
|
||||
data['photo_url'] = photo_url
|
||||
if photo_size:
|
||||
if photo_size is not None:
|
||||
data['photo_size'] = photo_size
|
||||
if photo_width:
|
||||
if photo_width is not None:
|
||||
data['photo_width'] = photo_width
|
||||
if photo_height:
|
||||
if photo_height is not None:
|
||||
data['photo_height'] = photo_height
|
||||
if need_name:
|
||||
if need_name is not None:
|
||||
data['need_name'] = need_name
|
||||
if need_phone_number:
|
||||
if need_phone_number is not None:
|
||||
data['need_phone_number'] = need_phone_number
|
||||
if need_email:
|
||||
data['need_email'] = need_email
|
||||
if need_shipping_address:
|
||||
if need_shipping_address is not None:
|
||||
data['need_shipping_address'] = need_shipping_address
|
||||
if is_flexible:
|
||||
if is_flexible is not None:
|
||||
data['is_flexible'] = is_flexible
|
||||
|
||||
return url, data
|
||||
|
@ -1944,12 +1944,12 @@ class Bot(TelegramObject):
|
|||
ok (bool): Specify True if delivery to the specified address is possible and False if
|
||||
there are any problems (for example, if delivery to the specified address
|
||||
is not possible)
|
||||
shipping_options (List[:class:`telegram.ShippingOption`]): Required if ok is True. A
|
||||
list of available shipping options.
|
||||
error_message (str): Required if ok is False. Error message in human readable form
|
||||
that explains why it is impossible to complete the order (e.g. "Sorry, delivery
|
||||
to your desired address is unavailable'). Telegram will display this message
|
||||
to the user.
|
||||
shipping_options (Optional[List[:class:`telegram.ShippingOption`]]): Required if ok is
|
||||
True. A list of available shipping options.
|
||||
error_message (Optional[str]): Required if ok is False. Error message in human readable
|
||||
form that explains why it is impossible to complete the order (e.g. "Sorry,
|
||||
delivery to your desired address is unavailable'). Telegram will display this
|
||||
message to the user.
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
Returns:
|
||||
|
@ -1976,7 +1976,7 @@ class Bot(TelegramObject):
|
|||
|
||||
if ok is True:
|
||||
data['shipping_options'] = shipping_options
|
||||
if error_message:
|
||||
if error_message is not None:
|
||||
data['error_message'] = error_message
|
||||
|
||||
result = self._request.post(url_, data, timeout=timeout)
|
||||
|
@ -1994,11 +1994,11 @@ class Bot(TelegramObject):
|
|||
pre_checkout_query_id (str): Unique identifier for the query to be answered
|
||||
ok (bool): Specify True if everything is alright (goods are available, etc.) and the
|
||||
bot is ready to proceed with the order. Use False if there are any problems.
|
||||
error_message (str): Required if ok is False. Error message in human readable form that
|
||||
explains the reason for failure to proceed with the checkout (e.g. "Sorry, somebody
|
||||
just bought the last of our amazing black T-shirts while you were busy filling out
|
||||
your payment details. Please choose a different color or garment!"). Telegram will
|
||||
display this message to the user.
|
||||
error_message (Optional[str]): Required if ok is False. Error message in human readable
|
||||
form that explains the reason for failure to proceed with the checkout (e.g.
|
||||
"Sorry, somebody just bought the last of our amazing black T-shirts while you were
|
||||
busy filling out your payment details. Please choose a different color or
|
||||
garment!"). Telegram will display this message to the user.
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
Returns:
|
||||
|
@ -2020,7 +2020,7 @@ class Bot(TelegramObject):
|
|||
|
||||
data = {'pre_checkout_query_id': pre_checkout_query_id, 'ok': ok}
|
||||
|
||||
if error_message:
|
||||
if error_message is not None:
|
||||
data['error_message'] = error_message
|
||||
|
||||
result = self._request.post(url_, data, timeout=timeout)
|
||||
|
|
|
@ -214,13 +214,68 @@ class Filters(object):
|
|||
|
||||
class _StatusUpdate(BaseFilter):
|
||||
|
||||
class _NewChatMembers(BaseFilter):
|
||||
|
||||
def filter(self, message):
|
||||
return bool(message.new_chat_members)
|
||||
|
||||
new_chat_members = _NewChatMembers()
|
||||
|
||||
class _LeftChatMember(BaseFilter):
|
||||
|
||||
def filter(self, message):
|
||||
return bool(message.left_chat_member)
|
||||
|
||||
left_chat_member = _LeftChatMember()
|
||||
|
||||
class _NewChatTitle(BaseFilter):
|
||||
|
||||
def filter(self, message):
|
||||
return bool(message.new_chat_title)
|
||||
|
||||
new_chat_title = _NewChatTitle()
|
||||
|
||||
class _NewChatPhoto(BaseFilter):
|
||||
|
||||
def filter(self, message):
|
||||
return bool(message.new_chat_photo)
|
||||
|
||||
new_chat_photo = _NewChatPhoto()
|
||||
|
||||
class _DeleteChatPhoto(BaseFilter):
|
||||
|
||||
def filter(self, message):
|
||||
return bool(message.delete_chat_photo)
|
||||
|
||||
delete_chat_photo = _DeleteChatPhoto()
|
||||
|
||||
class _ChatCreated(BaseFilter):
|
||||
|
||||
def filter(self, message):
|
||||
return bool(message.group_chat_created or message.supergroup_chat_created or
|
||||
message.channel_chat_created)
|
||||
|
||||
chat_created = _ChatCreated()
|
||||
|
||||
class _Migrate(BaseFilter):
|
||||
|
||||
def filter(self, message):
|
||||
return bool(message.migrate_from_chat_id or message.migrate_to_chat_id)
|
||||
|
||||
migrate = _Migrate()
|
||||
|
||||
class _PinnedMessage(BaseFilter):
|
||||
|
||||
def filter(self, message):
|
||||
return bool(message.pinned_message)
|
||||
|
||||
pinned_message = _PinnedMessage()
|
||||
|
||||
def filter(self, message):
|
||||
return bool(message.new_chat_member or message.left_chat_member
|
||||
or message.new_chat_title or message.new_chat_photo
|
||||
or message.delete_chat_photo or message.group_chat_created
|
||||
or message.supergroup_chat_created or message.channel_chat_created
|
||||
or message.migrate_to_chat_id or message.migrate_from_chat_id
|
||||
or message.pinned_message)
|
||||
return bool(self.new_chat_members(message) or self.left_chat_member(message) or
|
||||
self.new_chat_title(message) or self.new_chat_photo(message) or
|
||||
self.delete_chat_photo(message) or self.chat_created(message) or
|
||||
self.migrate(message) or self.pinned_message(message))
|
||||
|
||||
status_update = _StatusUpdate()
|
||||
|
||||
|
@ -276,6 +331,20 @@ class Filters(object):
|
|||
|
||||
group = _Group()
|
||||
|
||||
class _Invoice(BaseFilter):
|
||||
|
||||
def filter(self, message):
|
||||
return bool(message.invoice)
|
||||
|
||||
invoice = _Invoice()
|
||||
|
||||
class _SuccessfulPayment(BaseFilter):
|
||||
|
||||
def filter(self, message):
|
||||
return bool(message.successful_payment)
|
||||
|
||||
successful_payment = _SuccessfulPayment()
|
||||
|
||||
class language(BaseFilter):
|
||||
"""
|
||||
Filters messages to only allow those which are from users with a certain language code.
|
||||
|
|
|
@ -61,11 +61,11 @@ class InlineQueryResultGif(InlineQueryResult):
|
|||
thumb_url,
|
||||
gif_width=None,
|
||||
gif_height=None,
|
||||
gif_duration=None,
|
||||
title=None,
|
||||
caption=None,
|
||||
reply_markup=None,
|
||||
input_message_content=None,
|
||||
gif_duration=None,
|
||||
**kwargs):
|
||||
|
||||
# Required
|
||||
|
|
|
@ -62,11 +62,11 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult):
|
|||
thumb_url,
|
||||
mpeg4_width=None,
|
||||
mpeg4_height=None,
|
||||
mpeg4_duration=None,
|
||||
title=None,
|
||||
caption=None,
|
||||
reply_markup=None,
|
||||
input_message_content=None,
|
||||
mpeg4_duration=None,
|
||||
**kwargs):
|
||||
|
||||
# Required
|
||||
|
|
|
@ -46,30 +46,11 @@ class InputFile(object):
|
|||
self.data = data
|
||||
self.boundary = choose_boundary()
|
||||
|
||||
if 'audio' in data:
|
||||
self.input_name = 'audio'
|
||||
self.input_file = data.pop('audio')
|
||||
elif 'document' in data:
|
||||
self.input_name = 'document'
|
||||
self.input_file = data.pop('document')
|
||||
elif 'photo' in data:
|
||||
self.input_name = 'photo'
|
||||
self.input_file = data.pop('photo')
|
||||
elif 'sticker' in data:
|
||||
self.input_name = 'sticker'
|
||||
self.input_file = data.pop('sticker')
|
||||
elif 'video' in data:
|
||||
self.input_name = 'video'
|
||||
self.input_file = data.pop('video')
|
||||
elif 'voice' in data:
|
||||
self.input_name = 'voice'
|
||||
self.input_file = data.pop('voice')
|
||||
elif 'certificate' in data:
|
||||
self.input_name = 'certificate'
|
||||
self.input_file = data.pop('certificate')
|
||||
elif 'video_note' in data:
|
||||
self.input_name = 'video_note'
|
||||
self.input_file = data.pop('video_note')
|
||||
for t in FILE_TYPES:
|
||||
if t in data:
|
||||
self.input_name = t
|
||||
self.input_file = data.pop(t)
|
||||
break
|
||||
else:
|
||||
raise TelegramError('Unknown inputfile type')
|
||||
|
||||
|
@ -121,7 +102,7 @@ class InputFile(object):
|
|||
form_boundary, 'Content-Disposition: form-data; name="%s"' % name, '', str(value)
|
||||
])
|
||||
|
||||
# Add input_file to upload
|
||||
# Add input_file to upload
|
||||
form.extend([
|
||||
form_boundary, 'Content-Disposition: form-data; name="%s"; filename="%s"' %
|
||||
(self.input_name,
|
||||
|
|
|
@ -31,10 +31,11 @@ class Invoice(TelegramObject):
|
|||
be used to generate this invoice
|
||||
currency (str): Three-letter ISO 4217 currency code
|
||||
total_amount (int): Total price in the smallest units of the currency (integer)
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, title, description, start_parameter, currency, total_amount):
|
||||
def __init__(self, title, description, start_parameter, currency, total_amount, **kwargs):
|
||||
self.title = title
|
||||
self.description = description
|
||||
self.start_parameter = start_parameter
|
||||
|
|
|
@ -27,9 +27,10 @@ class LabeledPrice(TelegramObject):
|
|||
Attributes:
|
||||
label (str): Portion label
|
||||
amount (int): Price of the product in the smallest units of the currency (integer)
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
"""
|
||||
|
||||
def __init__(self, label, amount):
|
||||
def __init__(self, label, amount, **kwargs):
|
||||
self.label = label
|
||||
self.amount = amount
|
||||
|
||||
|
|
|
@ -23,9 +23,10 @@ from datetime import datetime
|
|||
from time import mktime
|
||||
|
||||
from telegram import (Audio, Contact, Document, Chat, Location, PhotoSize, Sticker, TelegramObject,
|
||||
User, Video, Voice, Venue, MessageEntity, Game, Invoice, SuccessfulPayment,
|
||||
VideoNote)
|
||||
User, Video, Voice, Venue, MessageEntity, Game, Invoice, SuccessfulPayment)
|
||||
from telegram.utils.deprecate import warn_deprecate_obj
|
||||
from telegram.utils.helpers import escape_html, escape_markdown
|
||||
from telegram.videonote import VideoNote
|
||||
|
||||
|
||||
class Message(TelegramObject):
|
||||
|
@ -55,6 +56,8 @@ class Message(TelegramObject):
|
|||
entities (List[:class:`telegram.MessageEntity`]): For text messages, special entities
|
||||
like usernames, URLs, bot commands, etc. that appear in the text. See
|
||||
parse_entity and parse_entities methods for how to use properly
|
||||
video_note (:class:`telegram.VideoNote`): Message is a video note, information about the
|
||||
video message
|
||||
audio (:class:`telegram.Audio`): Message is an audio file, information about the file
|
||||
document (:class:`telegram.Document`): Message is a general file, information about the
|
||||
file
|
||||
|
@ -63,8 +66,6 @@ class Message(TelegramObject):
|
|||
sticker (:class:`telegram.Sticker`): Message is a sticker, information about the sticker
|
||||
video (:class:`telegram.Video`): Message is a video, information about the video
|
||||
voice (:class:`telegram.Voice`): Message is a voice message, information about the file
|
||||
video_note (:class:`telegram.VideoNote`): Message is a video note, information about the
|
||||
video message
|
||||
caption (str): Caption for the document, photo or video, 0-200 characters
|
||||
contact (:class:`telegram.Contact`): Message is a shared contact, information about the
|
||||
contact
|
||||
|
@ -106,6 +107,43 @@ class Message(TelegramObject):
|
|||
left_chat_participant (:class:`telegram.User`): Use `left_chat_member`
|
||||
instead.
|
||||
|
||||
<<<<<<<<< Temporary merge branch 1
|
||||
=========
|
||||
Args:
|
||||
message_id (int):
|
||||
from_user (:class:`telegram.User`):
|
||||
date (:class:`datetime.datetime`):
|
||||
chat (:class:`telegram.Chat`):
|
||||
forward_from (Optional[:class:`telegram.User`]):
|
||||
forward_from_chat (Optional[:class:`telegram.Chat`]):
|
||||
forward_from_message_id (Optional[int]):
|
||||
forward_date (Optional[:class:`datetime.datetime`]):
|
||||
reply_to_message (Optional[:class:`telegram.Message`]):
|
||||
edit_date (Optional[:class:`datetime.datetime`]):
|
||||
text (Optional[str]):
|
||||
audio (Optional[:class:`telegram.Audio`]):
|
||||
document (Optional[:class:`telegram.Document`]):
|
||||
game (Optional[:class:`telegram.Game`]):
|
||||
photo (Optional[List[:class:`telegram.PhotoSize`]]):
|
||||
sticker (Optional[:class:`telegram.Sticker`]):
|
||||
video (Optional[:class:`telegram.Video`]):
|
||||
voice (Optional[:class:`telegram.Voice`]):
|
||||
video_note (Optional[:class:`telegram.VideoNote`]):
|
||||
caption (Optional[str]):
|
||||
contact (Optional[:class:`telegram.Contact`]):
|
||||
location (Optional[:class:`telegram.Location`]):
|
||||
new_chat_member (Optional[:class:`telegram.User`]):
|
||||
left_chat_member (Optional[:class:`telegram.User`]):
|
||||
new_chat_title (Optional[str]):
|
||||
new_chat_photo (Optional[List[:class:`telegram.PhotoSize`]):
|
||||
delete_chat_photo (Optional[bool]):
|
||||
group_chat_created (Optional[bool]):
|
||||
supergroup_chat_created (Optional[bool]):
|
||||
migrate_to_chat_id (Optional[int]):
|
||||
migrate_from_chat_id (Optional[int]):
|
||||
channel_chat_created (Optional[bool]):
|
||||
bot (Optional[Bot]): The Bot to use for instance methods
|
||||
>>>>>>>>> Temporary merge branch 2
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
|
@ -126,7 +164,6 @@ class Message(TelegramObject):
|
|||
sticker=None,
|
||||
video=None,
|
||||
voice=None,
|
||||
video_note=None,
|
||||
caption=None,
|
||||
contact=None,
|
||||
location=None,
|
||||
|
@ -147,6 +184,7 @@ class Message(TelegramObject):
|
|||
invoice=None,
|
||||
successful_payment=None,
|
||||
bot=None,
|
||||
video_note=None,
|
||||
**kwargs):
|
||||
# Required
|
||||
self.message_id = int(message_id)
|
||||
|
@ -173,7 +211,7 @@ class Message(TelegramObject):
|
|||
self.contact = contact
|
||||
self.location = location
|
||||
self.venue = venue
|
||||
self.new_chat_member = new_chat_member
|
||||
self._new_chat_member = new_chat_member
|
||||
self.new_chat_members = new_chat_members
|
||||
self.left_chat_member = left_chat_member
|
||||
self.new_chat_title = new_chat_title
|
||||
|
@ -270,6 +308,7 @@ class Message(TelegramObject):
|
|||
data['entities'] = [e.to_dict() for e in self.entities]
|
||||
if self.new_chat_photo:
|
||||
data['new_chat_photo'] = [p.to_dict() for p in self.new_chat_photo]
|
||||
data['new_chat_member'] = data.pop('_new_chat_member', None)
|
||||
if self.new_chat_members:
|
||||
data['new_chat_members'] = [u.to_dict() for u in self.new_chat_members]
|
||||
|
||||
|
@ -744,3 +783,8 @@ class Message(TelegramObject):
|
|||
else:
|
||||
markdown_text += escape_markdown(message_text[last_offset * 2:].decode('utf-16-le'))
|
||||
return markdown_text
|
||||
|
||||
@property
|
||||
def new_chat_member(self):
|
||||
warn_deprecate_obj('new_chat_member', 'new_chat_members')
|
||||
return self._new_chat_member
|
||||
|
|
|
@ -29,10 +29,11 @@ class OrderInfo(TelegramObject):
|
|||
phone_number (Optional[str]): User's phone number
|
||||
email (Optional[str]): User email
|
||||
shipping_address (Optional[:class:`telegram.ShippingAddress`]): User shipping address
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, name=None, phone_number=None, email=None, shipping_address=None):
|
||||
def __init__(self, name=None, phone_number=None, email=None, shipping_address=None, **kwargs):
|
||||
self.name = name
|
||||
self.phone_number = phone_number
|
||||
self.email = email
|
||||
|
|
|
@ -28,7 +28,7 @@ class PreCheckoutQuery(TelegramObject):
|
|||
* In Python `from` is a reserved word, use `from_user` instead.
|
||||
|
||||
Attributes:
|
||||
id (int): Unique query identifier
|
||||
id (str): Unique query identifier
|
||||
from_user (:class:`telegram.User`): User who sent the query
|
||||
currency (str): Three-letter ISO 4217 currency code
|
||||
total_amount (int): Total price in the smallest units of the currency (integer)
|
||||
|
@ -37,6 +37,7 @@ class PreCheckoutQuery(TelegramObject):
|
|||
Keyword Args:
|
||||
shipping_option_id (Optional[str]): Identifier of the shipping option chosen by the user
|
||||
order_info (Optional[:class:`telegram.OrderInfo`]): Order info provided by the user
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
|
|
|
@ -31,10 +31,11 @@ class ShippingAddress(TelegramObject):
|
|||
street_line1 (str): First line for the address
|
||||
street_line2 (str): Second line for the address
|
||||
post_code (str): Address post code
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, country_code, state, city, street_line1, street_line2, post_code):
|
||||
def __init__(self, country_code, state, city, street_line1, street_line2, post_code, **kwargs):
|
||||
self.country_code = country_code
|
||||
self.state = state
|
||||
self.city = city
|
||||
|
|
|
@ -28,13 +28,14 @@ class ShippingOption(TelegramObject):
|
|||
* In Python `from` is a reserved word, use `from_user` instead.
|
||||
|
||||
Attributes:
|
||||
id (int): Shipping option identifier
|
||||
id (str): Shipping option identifier
|
||||
title (str): Option title
|
||||
prices (List[:class:`telegram.LabeledPrice`]): List of price portions
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, id, title, prices):
|
||||
def __init__(self, id, title, prices, **kwargs):
|
||||
self.id = id
|
||||
self.title = title
|
||||
self.prices = prices
|
||||
|
|
|
@ -28,10 +28,11 @@ class ShippingQuery(TelegramObject):
|
|||
* In Python `from` is a reserved word, use `from_user` instead.
|
||||
|
||||
Attributes:
|
||||
id (int): Unique query identifier
|
||||
id (str): Unique query identifier
|
||||
from_user (:class:`telegram.User`): User who sent the query
|
||||
invoice_payload (str): Bot specified invoice payload
|
||||
shipping_address (:class:`telegram.ShippingQuery`): User specified shipping address
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
|
|
|
@ -33,10 +33,9 @@ class SuccessfulPayment(TelegramObject):
|
|||
invoice_payload (str): Bot specified invoice payload
|
||||
telegram_payment_charge_id (str): Telegram payment identifier
|
||||
provider_payment_charge_id (str): Provider payment identifier
|
||||
|
||||
Keyword Args:
|
||||
shipping_option_id (Optional[str]): Identifier of the shipping option chosen by the user
|
||||
order_info (Optional[:class:`telegram.OrderInfo`]): Order info provided by the user
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
|
@ -47,7 +46,8 @@ class SuccessfulPayment(TelegramObject):
|
|||
telegram_payment_charge_id,
|
||||
provider_payment_charge_id,
|
||||
shipping_option_id=None,
|
||||
order_info=None):
|
||||
order_info=None,
|
||||
**kwargs):
|
||||
self.currency = currency
|
||||
self.total_amount = total_amount
|
||||
self.invoice_payload = invoice_payload
|
||||
|
|
|
@ -21,8 +21,18 @@
|
|||
import warnings
|
||||
|
||||
|
||||
def warn_deprecate_obj(old, new):
|
||||
warnings.warn('{0} is being deprecated, please use {1} from now on'.format(old, new))
|
||||
# We use our own DeprecationWarning since they are muted by default and "UserWarning" makes it
|
||||
# seem like it's the user that issued the warning
|
||||
# We name it something else so that you don't get confused when you attempt to suppress it
|
||||
class TelegramDeprecationWarning(Warning):
|
||||
pass
|
||||
|
||||
|
||||
def warn_deprecate_obj(old, new, stacklevel=3):
|
||||
warnings.warn(
|
||||
'{0} is being deprecated, please use {1} from now on.'.format(old, new),
|
||||
category=TelegramDeprecationWarning,
|
||||
stacklevel=stacklevel)
|
||||
|
||||
|
||||
def deprecate(func, old, new):
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
import os
|
||||
import socket
|
||||
import logging
|
||||
import warnings
|
||||
|
||||
try:
|
||||
import ujson as json
|
||||
|
@ -27,10 +28,15 @@ except ImportError:
|
|||
import json
|
||||
|
||||
import certifi
|
||||
import urllib3
|
||||
import urllib3.contrib.appengine
|
||||
from urllib3.connection import HTTPConnection
|
||||
from urllib3.util.timeout import Timeout
|
||||
try:
|
||||
import telegram.vendor.ptb_urllib3.urllib3 as urllib3
|
||||
import telegram.vendor.ptb_urllib3.urllib3.contrib.appengine as appengine
|
||||
from telegram.vendor.ptb_urllib3.urllib3.connection import HTTPConnection
|
||||
from telegram.vendor.ptb_urllib3.urllib3.util.timeout import Timeout
|
||||
except ImportError:
|
||||
warnings.warn("python-telegram-bot wasn't properly installed. Please refer to README.rst on "
|
||||
"how to properly install.")
|
||||
raise
|
||||
|
||||
from telegram import (InputFile, TelegramError)
|
||||
from telegram.error import (Unauthorized, NetworkError, TimedOut, BadRequest, ChatMigrated,
|
||||
|
@ -90,16 +96,16 @@ class Request(object):
|
|||
proxy_url = os.environ.get('HTTPS_PROXY') or os.environ.get('https_proxy')
|
||||
|
||||
if not proxy_url:
|
||||
if urllib3.contrib.appengine.is_appengine_sandbox():
|
||||
if appengine.is_appengine_sandbox():
|
||||
# Use URLFetch service if running in App Engine
|
||||
mgr = urllib3.contrib.appengine.AppEngineManager()
|
||||
mgr = appengine.AppEngineManager()
|
||||
else:
|
||||
mgr = urllib3.PoolManager(**kwargs)
|
||||
else:
|
||||
kwargs.update(urllib3_proxy_kwargs)
|
||||
if proxy_url.startswith('socks'):
|
||||
try:
|
||||
from urllib3.contrib.socks import SOCKSProxyManager
|
||||
from telegram.vendor.ptb_urllib3.urllib3.contrib.socks import SOCKSProxyManager
|
||||
except ImportError:
|
||||
raise RuntimeError('PySocks is missing')
|
||||
mgr = SOCKSProxyManager(proxy_url, **kwargs)
|
||||
|
|
0
telegram/vendor/__init__.py
vendored
Normal file
0
telegram/vendor/__init__.py
vendored
Normal file
1
telegram/vendor/ptb_urllib3
vendored
Submodule
1
telegram/vendor/ptb_urllib3
vendored
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit ddb495340152a4e51800226dc68a479e48c055ff
|
1
telegram/vendor/urllib3
vendored
1
telegram/vendor/urllib3
vendored
|
@ -1 +0,0 @@
|
|||
Subproject commit 4b076eedffc1afabf0215ced3820603de73d1ce7
|
|
@ -17,4 +17,4 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
__version__ = '6.0.1'
|
||||
__version__ = '6.0.2'
|
||||
|
|
|
@ -317,7 +317,7 @@ class BotTest(BaseTest, unittest.TestCase):
|
|||
self.assertEqual(text, fwdmsg.text)
|
||||
self.assertEqual(fwdmsg.forward_from_message_id, msg.message_id)
|
||||
|
||||
@flaky(3, 1)
|
||||
@flaky(20, 1)
|
||||
@timeout(10)
|
||||
def test_set_webhook_get_webhook_info(self):
|
||||
url = 'https://python-telegram-bot.org/test/webhook'
|
||||
|
|
|
@ -127,48 +127,59 @@ class FiltersTest(BaseTest, unittest.TestCase):
|
|||
def test_filters_status_update(self):
|
||||
self.assertFalse(Filters.status_update(self.message))
|
||||
|
||||
self.message.new_chat_member = 'test'
|
||||
self.message.new_chat_members = ['test']
|
||||
self.assertTrue(Filters.status_update(self.message))
|
||||
self.message.new_chat_member = None
|
||||
self.assertTrue(Filters.status_update.new_chat_members(self.message))
|
||||
self.message.new_chat_members = None
|
||||
|
||||
self.message.left_chat_member = 'test'
|
||||
self.assertTrue(Filters.status_update(self.message))
|
||||
self.assertTrue(Filters.status_update.left_chat_member(self.message))
|
||||
self.message.left_chat_member = None
|
||||
|
||||
self.message.new_chat_title = 'test'
|
||||
self.assertTrue(Filters.status_update(self.message))
|
||||
self.assertTrue(Filters.status_update.new_chat_title(self.message))
|
||||
self.message.new_chat_title = ''
|
||||
|
||||
self.message.new_chat_photo = 'test'
|
||||
self.assertTrue(Filters.status_update(self.message))
|
||||
self.assertTrue(Filters.status_update.new_chat_photo(self.message))
|
||||
self.message.new_chat_photo = None
|
||||
|
||||
self.message.delete_chat_photo = True
|
||||
self.assertTrue(Filters.status_update(self.message))
|
||||
self.assertTrue(Filters.status_update.delete_chat_photo(self.message))
|
||||
self.message.delete_chat_photo = False
|
||||
|
||||
self.message.group_chat_created = True
|
||||
self.assertTrue(Filters.status_update(self.message))
|
||||
self.assertTrue(Filters.status_update.chat_created(self.message))
|
||||
self.message.group_chat_created = False
|
||||
|
||||
self.message.supergroup_chat_created = True
|
||||
self.assertTrue(Filters.status_update(self.message))
|
||||
self.assertTrue(Filters.status_update.chat_created(self.message))
|
||||
self.message.supergroup_chat_created = False
|
||||
|
||||
self.message.migrate_to_chat_id = 100
|
||||
self.assertTrue(Filters.status_update(self.message))
|
||||
self.assertTrue(Filters.status_update.migrate(self.message))
|
||||
self.message.migrate_to_chat_id = 0
|
||||
|
||||
self.message.migrate_from_chat_id = 100
|
||||
self.assertTrue(Filters.status_update(self.message))
|
||||
self.assertTrue(Filters.status_update.migrate(self.message))
|
||||
self.message.migrate_from_chat_id = 0
|
||||
|
||||
self.message.channel_chat_created = True
|
||||
self.assertTrue(Filters.status_update(self.message))
|
||||
self.assertTrue(Filters.status_update.chat_created(self.message))
|
||||
self.message.channel_chat_created = False
|
||||
|
||||
self.message.pinned_message = 'test'
|
||||
self.assertTrue(Filters.status_update(self.message))
|
||||
self.assertTrue(Filters.status_update.pinned_message(self.message))
|
||||
self.message.pinned_message = None
|
||||
|
||||
def test_entities_filter(self):
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents Tests for Telegram VideoNote"""
|
||||
|
||||
import numbers
|
||||
import sys
|
||||
import unittest
|
||||
import os
|
||||
|
@ -37,7 +37,7 @@ class VideoNoteTest(BaseTest, unittest.TestCase):
|
|||
self.videonote_file = open('tests/data/telegram.mp4', 'rb')
|
||||
self.videonote_file_id = 'DQADAQADBwAD5VIIRYemhHpbPmIQAg'
|
||||
self.duration = 5
|
||||
self.length = 1 # No bloody clue what this does, see note in first test
|
||||
self.length = 1 # No bloody clue what this does
|
||||
self.thumb = telegram.PhotoSize.de_json({
|
||||
'file_id': 'AAQBABOMsecvAAQqqoY1Pee_MqcyAAIC',
|
||||
'width': 51,
|
||||
|
@ -56,32 +56,8 @@ class VideoNoteTest(BaseTest, unittest.TestCase):
|
|||
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
def test_error_send_videonote_required_args_only(self):
|
||||
# This is where it gets weird....
|
||||
# According to telegram length is Video width and height.. but how that works with one
|
||||
# parameter I couldn't tell you
|
||||
# It would also seem that it is in fact a required parameter, so the original test below
|
||||
# fails. Therefore I decided I check for the error instead - that way we'll also know
|
||||
# when telegram fixes their shit
|
||||
with self.assertRaisesRegexp(telegram.error.BadRequest, r'Wrong video note length'):
|
||||
message = self._bot.sendVideoNote(self._chat_id, self.videonote_file, timeout=10)
|
||||
|
||||
# videonote = message.videonote
|
||||
#
|
||||
# self.assertTrue(isinstance(videonote.file_id, str))
|
||||
# self.assertNotEqual(videonote.file_id, None)
|
||||
# self.assertEqual(videonote.duration, self.duration)
|
||||
# self.assertEqual(videonote.length, self.length)
|
||||
# self.assertEqual(videonote.thumb, self.thumb)
|
||||
# self.assertEqual(videonote.file_size, self.file_size)
|
||||
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
def test_send_videonote_actual_required_args_only(self):
|
||||
# See above test... if you pass any number that's > 0 and < some high number, it seems
|
||||
# to work
|
||||
message = self._bot.sendVideoNote(
|
||||
self._chat_id, self.videonote_file, length=self.length, timeout=10)
|
||||
def test_send_videonote_required_args_only(self):
|
||||
message = self._bot.sendVideoNote(self._chat_id, self.videonote_file, timeout=10)
|
||||
|
||||
videonote = message.video_note
|
||||
|
||||
|
@ -89,6 +65,7 @@ class VideoNoteTest(BaseTest, unittest.TestCase):
|
|||
self.assertNotEqual(videonote.file_id, None)
|
||||
self.assertEqual(videonote.duration, self.duration)
|
||||
# self.assertEqual(videonote.length, self.length)
|
||||
self.assertIsInstance(videonote.length, numbers.Number)
|
||||
self.assertEqual(videonote.thumb, self.thumb)
|
||||
self.assertEqual(videonote.file_size, self.file_size)
|
||||
|
||||
|
@ -107,6 +84,7 @@ class VideoNoteTest(BaseTest, unittest.TestCase):
|
|||
self.assertTrue(isinstance(videonote.file_id, str))
|
||||
self.assertNotEqual(videonote.file_id, None)
|
||||
# self.assertEqual(videonote.length, self.length)
|
||||
self.assertIsInstance(videonote.length, numbers.Number)
|
||||
self.assertEqual(videonote.duration, self.duration)
|
||||
self.assertEqual(videonote.thumb, self.thumb)
|
||||
self.assertEqual(videonote.file_size, self.file_size)
|
||||
|
@ -125,15 +103,17 @@ class VideoNoteTest(BaseTest, unittest.TestCase):
|
|||
|
||||
self.assertEqual(videonote.file_id, self.videonote_file_id)
|
||||
# self.assertEqual(videonote.length, self.length)
|
||||
self.assertIsInstance(videonote.length, numbers.Number)
|
||||
self.assertEqual(videonote.duration, self.duration)
|
||||
self.assertEqual(videonote.thumb, self.thumb)
|
||||
self.assertEqual(videonote.file_size, self.file_size)
|
||||
# Telegram doesn't send file_size for resends?
|
||||
# self.assertEqual(videonote.file_size, self.file_size)
|
||||
|
||||
def test_videonote_de_json(self):
|
||||
videonote = telegram.VideoNote.de_json(self.json_dict, self._bot)
|
||||
|
||||
self.assertEqual(videonote.file_id, self.videonote_file_id)
|
||||
# self.assertEqual(videonote.duration, self.duration)
|
||||
self.assertEqual(videonote.duration, self.duration)
|
||||
self.assertEqual(videonote.thumb, self.thumb)
|
||||
self.assertEqual(videonote.length, self.length)
|
||||
self.assertEqual(videonote.file_size, self.file_size)
|
||||
|
|
Loading…
Add table
Reference in a new issue