Skip to content

Commit 042d4bb

Browse files
authored
add support for 3.5 api (python-telegram-bot#920)
* add support for 3.5 api * removed "unused" import by accident * Hardcoded values Appearantly TG decided to change the size of a send image (again) * test_official * Improve coverage * Finishing up * spelling error * pytest fixed tot < than 3.3 for python 3.3 support * flake8 * rollback requirements * as per CR * object for provider_data Make it possible to send an object that will be json-serialized for send_invoice + tests * shorten error message * using string_types
1 parent 1e22d57 commit 042d4bb

16 files changed

+434
-16
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
telegram.InputMedia
2+
===================
3+
4+
.. autoclass:: telegram.InputMedia
5+
:members:
6+
:show-inheritance:
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
telegram.InputMediaPhoto
2+
========================
3+
4+
.. autoclass:: telegram.InputMediaPhoto
5+
:members:
6+
:show-inheritance:
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
telegram.InputMediaVideo
2+
========================
3+
4+
.. autoclass:: telegram.InputMediaVideo
5+
:members:
6+
:show-inheritance:

docs/source/telegram.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ telegram package
2121
telegram.inlinekeyboardbutton
2222
telegram.inlinekeyboardmarkup
2323
telegram.inputfile
24+
telegram.inputmedia
25+
telegram.inputmediaphoto
26+
telegram.inputmediavideo
2427
telegram.keyboardbutton
2528
telegram.location
2629
telegram.message

telegram/__init__.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@
9696
MAX_FILESIZE_DOWNLOAD, MAX_FILESIZE_UPLOAD,
9797
MAX_MESSAGES_PER_SECOND_PER_CHAT, MAX_MESSAGES_PER_SECOND,
9898
MAX_MESSAGES_PER_MINUTE_PER_GROUP)
99+
from .files.inputmedia import InputMedia
100+
from .files.inputmediavideo import InputMediaVideo
101+
from .files.inputmediaphoto import InputMediaPhoto
99102
from .version import __version__ # flake8: noqa
100103

101104
__author__ = 'devs@python-telegram-bot.org'
@@ -121,5 +124,6 @@
121124
'MAX_MESSAGES_PER_SECOND', 'MAX_MESSAGES_PER_MINUTE_PER_GROUP', 'WebhookInfo', 'Animation',
122125
'Game', 'GameHighScore', 'VideoNote', 'LabeledPrice', 'SuccessfulPayment', 'ShippingOption',
123126
'ShippingAddress', 'PreCheckoutQuery', 'OrderInfo', 'Invoice', 'ShippingQuery', 'ChatPhoto',
124-
'StickerSet', 'MaskPosition', 'CallbackGame'
127+
'StickerSet', 'MaskPosition', 'CallbackGame', 'InputMedia', 'InputMediaPhoto',
128+
'InputMediaVideo'
125129
]

telegram/bot.py

Lines changed: 65 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,13 @@
2121
"""This module contains an object that represents a Telegram Bot."""
2222

2323
import functools
24+
import json
2425
import logging
2526
import warnings
2627
from datetime import datetime
2728

29+
from future.utils import string_types
30+
2831
from telegram import (User, Message, Update, Chat, ChatMember, UserProfilePhotos, File,
2932
ReplyMarkup, TelegramObject, WebhookInfo, GameHighScore, StickerSet,
3033
PhotoSize, Audio, Document, Sticker, Video, Voice, VideoNote, Location,
@@ -335,7 +338,7 @@ def send_photo(self,
335338
disable_notification=False,
336339
reply_to_message_id=None,
337340
reply_markup=None,
338-
timeout=20.,
341+
timeout=20,
339342
**kwargs):
340343
"""Use this method to send photos.
341344
@@ -394,7 +397,7 @@ def send_audio(self,
394397
disable_notification=False,
395398
reply_to_message_id=None,
396399
reply_markup=None,
397-
timeout=20.,
400+
timeout=20,
398401
**kwargs):
399402
"""
400403
Use this method to send audio files, if you want Telegram clients to display them in the
@@ -465,7 +468,7 @@ def send_document(self,
465468
disable_notification=False,
466469
reply_to_message_id=None,
467470
reply_markup=None,
468-
timeout=20.,
471+
timeout=20,
469472
**kwargs):
470473
"""Use this method to send general files.
471474
@@ -576,7 +579,7 @@ def send_video(self,
576579
disable_notification=False,
577580
reply_to_message_id=None,
578581
reply_markup=None,
579-
timeout=20.,
582+
timeout=20,
580583
width=None,
581584
height=None,
582585
**kwargs):
@@ -646,7 +649,7 @@ def send_voice(self,
646649
disable_notification=False,
647650
reply_to_message_id=None,
648651
reply_markup=None,
649-
timeout=20.,
652+
timeout=20,
650653
**kwargs):
651654
"""
652655
Use this method to send audio files, if you want Telegram clients to display the file
@@ -708,7 +711,7 @@ def send_video_note(self,
708711
disable_notification=False,
709712
reply_to_message_id=None,
710713
reply_markup=None,
711-
timeout=20.,
714+
timeout=20,
712715
**kwargs):
713716
"""Use this method to send video messages.
714717
@@ -757,6 +760,51 @@ def send_video_note(self,
757760

758761
return url, data
759762

763+
@log
764+
def send_media_group(self,
765+
chat_id,
766+
media,
767+
disable_notification=None,
768+
reply_to_message_id=None,
769+
timeout=20,
770+
**kwargs):
771+
"""Use this method to send a group of photos or videos as an album.
772+
773+
Args:
774+
chat_id (:obj:`int` | :obj:`str`): Unique identifier for the target chat or username
775+
of the target channel (in the format @channelusername).
776+
media (List[:class:`telegram.InputMedia`]): An array describing photos and videos to be
777+
sent, must include 2–10 items.
778+
disable_notification (:obj:`bool`, optional): Sends the message silently. Users will
779+
receive a notification with no sound.
780+
reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the
781+
original message.
782+
timeout (:obj:`int` | :obj:`float`, optional): Send file timeout (default: 20 seconds).
783+
**kwargs (:obj:`dict`): Arbitrary keyword arguments.
784+
785+
Returns:
786+
List[:class:`telegram.Message`]: An array of the sent Messages.
787+
788+
Raises:
789+
:class:`telegram.TelegramError`
790+
"""
791+
# TODO: Make InputMediaPhoto, InputMediaVideo and send_media_group work with new files
792+
793+
url = '{0}/sendMediaGroup'.format(self.base_url)
794+
795+
media = [med.to_dict() for med in media]
796+
797+
data = {'chat_id': chat_id, 'media': media}
798+
799+
if reply_to_message_id:
800+
data['reply_to_message_id'] = reply_to_message_id
801+
if disable_notification:
802+
data['disable_notification'] = disable_notification
803+
804+
result = self._request.post(url, data, timeout=timeout)
805+
806+
return [Message.de_json(res, self) for res in result]
807+
760808
@log
761809
@message
762810
def send_location(self,
@@ -2153,6 +2201,7 @@ def send_invoice(self,
21532201
disable_notification=False,
21542202
reply_to_message_id=None,
21552203
reply_markup=None,
2204+
provider_data=None,
21562205
timeout=None,
21572206
**kwargs):
21582207
"""Use this method to send invoices.
@@ -2169,6 +2218,10 @@ def send_invoice(self,
21692218
currency (:obj:`str`): Three-letter ISO 4217 currency code.
21702219
prices (List[:class:`telegram.LabeledPrice`)]: Price breakdown, a list of components
21712220
(e.g. product price, tax, discount, delivery cost, delivery tax, bonus, etc.).
2221+
provider_data (:obj:`str` | :obj:`object`, optional): JSON-encoded data about the
2222+
invoice, which will be shared with the payment provider. A detailed description of
2223+
required fields should be provided by the payment provider. When an object is
2224+
passed, it will be encoded as JSON.
21722225
photo_url (:obj:`str`, optional): URL of the product photo for the invoice. Can be a
21732226
photo of the goods or a marketing image for a service. People like it better when
21742227
they see what they are paying for.
@@ -2216,7 +2269,11 @@ def send_invoice(self,
22162269
'currency': currency,
22172270
'prices': [p.to_dict() for p in prices]
22182271
}
2219-
2272+
if provider_data is not None:
2273+
if isinstance(provider_data, string_types):
2274+
data['provider_data'] = provider_data
2275+
else:
2276+
data['provider_data'] = json.dumps(provider_data)
22202277
if photo_url is not None:
22212278
data['photo_url'] = photo_url
22222279
if photo_size is not None:
@@ -2965,6 +3022,7 @@ def __reduce__(self):
29653022
sendVideo = send_video
29663023
sendVoice = send_voice
29673024
sendVideoNote = send_video_note
3025+
sendMediaGroup = send_media_group
29683026
sendLocation = send_location
29693027
editMessageLiveLocation = edit_message_live_location
29703028
stopMessageLiveLocation = stop_message_live_location

telegram/files/inputmedia.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/usr/bin/env python
2+
#
3+
# A library that provides a Python interface to the Telegram Bot API
4+
# Copyright (C) 2015-2017
5+
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
6+
#
7+
# This program is free software: you can redistribute it and/or modify
8+
# it under the terms of the GNU Lesser Public License as published by
9+
# the Free Software Foundation, either version 3 of the License, or
10+
# (at your option) any later version.
11+
#
12+
# This program is distributed in the hope that it will be useful,
13+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
# GNU Lesser Public License for more details.
16+
#
17+
# You should have received a copy of the GNU Lesser Public License
18+
# along with this program. If not, see [http://www.gnu.org/licenses/].
19+
"""Base class for Telegram InputMedia Objects."""
20+
21+
from telegram import TelegramObject
22+
23+
24+
class InputMedia(TelegramObject):
25+
"""Base class for Telegram InputMedia Objects.
26+
27+
See :class:`telegram.InputMediaPhoto` and :class:`telegram.InputMediaVideo` for
28+
detailed use.
29+
30+
"""
31+
pass

telegram/files/inputmediaphoto.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#!/usr/bin/env python
2+
#
3+
# A library that provides a Python interface to the Telegram Bot API
4+
# Copyright (C) 2015-2017
5+
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
6+
#
7+
# This program is free software: you can redistribute it and/or modify
8+
# it under the terms of the GNU Lesser Public License as published by
9+
# the Free Software Foundation, either version 3 of the License, or
10+
# (at your option) any later version.
11+
#
12+
# This program is distributed in the hope that it will be useful,
13+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
# GNU Lesser Public License for more details.
16+
#
17+
# You should have received a copy of the GNU Lesser Public License
18+
# along with this program. If not, see [http://www.gnu.org/licenses/].
19+
"""This module contains an object that represents a Telegram InputMediaPhoto."""
20+
from telegram import InputMedia, PhotoSize
21+
22+
23+
class InputMediaPhoto(InputMedia):
24+
"""Represents a photo to be sent.
25+
26+
Attributes:
27+
type (:obj:`str`): ``photo``.
28+
media (:obj:`str`): File to send. Pass a file_id to send a file that exists on the
29+
Telegram servers (recommended), pass an HTTP URL for Telegram to get a file from the
30+
Internet. Lastly you can pass an existing :class:`telegram.PhotoSize` object to send.
31+
caption (:obj:`str`): Optional. Caption of the photo to be sent, 0-200 characters.
32+
33+
Args:
34+
media (:obj:`str`): File to send. Pass a file_id to send a file that exists on the
35+
Telegram servers (recommended), pass an HTTP URL for Telegram to get a file from the
36+
Internet. Lastly you can pass an existing :class:`telegram.PhotoSize` object to send.
37+
caption (:obj:`str`, optional ): Caption of the photo to be sent, 0-200 characters.
38+
39+
Note:
40+
At the moment using a new file is not yet supported.
41+
"""
42+
43+
# TODO: Make InputMediaPhoto, InputMediaVideo and send_media_group work with new files
44+
45+
def __init__(self, media, caption=None):
46+
self.type = 'photo'
47+
48+
if isinstance(media, PhotoSize):
49+
self.media = media.file_id
50+
elif hasattr(media, 'read'):
51+
raise ValueError(
52+
'Sending files is not supported (yet). Use file_id, url or PhotoSize')
53+
else:
54+
self.media = media
55+
56+
if caption:
57+
self.caption = caption

telegram/files/inputmediavideo.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#!/usr/bin/env python
2+
#
3+
# A library that provides a Python interface to the Telegram Bot API
4+
# Copyright (C) 2015-2017
5+
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
6+
#
7+
# This program is free software: you can redistribute it and/or modify
8+
# it under the terms of the GNU Lesser Public License as published by
9+
# the Free Software Foundation, either version 3 of the License, or
10+
# (at your option) any later version.
11+
#
12+
# This program is distributed in the hope that it will be useful,
13+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
# GNU Lesser Public License for more details.
16+
#
17+
# You should have received a copy of the GNU Lesser Public License
18+
# along with this program. If not, see [http://www.gnu.org/licenses/].
19+
"""This module contains an object that represents a Telegram InputMediaPhoto."""
20+
from telegram import InputMedia, Video
21+
22+
23+
class InputMediaVideo(InputMedia):
24+
"""Represents a video to be sent.
25+
26+
Attributes:
27+
type (:obj:`str`): ``video``.
28+
media (:obj:`str`): File to send. Pass a file_id to send a file that exists on the Telegram
29+
servers (recommended), pass an HTTP URL for Telegram to get a file from the Internet.
30+
Lastly you can pass an existing :class:`telegram.Video` object to send.
31+
caption (:obj:`str`): Optional. Caption of the video to be sent, 0-200 characters.
32+
width (:obj:`int`): Optional. Video width.
33+
height (:obj:`int`): Optional. Video height.
34+
duration (:obj:`int`): Optional. Video duration.
35+
36+
Args:
37+
media (:obj:`str`): File to send. Pass a file_id to send a file that exists on the Telegram
38+
servers (recommended), pass an HTTP URL for Telegram to get a file from the Internet.
39+
Lastly you can pass an existing :class:`telegram.Video` object to send.
40+
caption (:obj:`str`, optional): Caption of the video to be sent, 0-200 characters.
41+
width (:obj:`int`, optional): Video width.
42+
height (:obj:`int`, optional): Video height.
43+
duration (:obj:`int`, optional): Video duration.
44+
45+
Note:
46+
When using a :class:`telegram.Video` for the :attr:`media` attribute. It will take the
47+
width, height and duration from that video, unless otherwise specified with the optional
48+
arguments.
49+
At the moment using a new file is not yet supported.
50+
"""
51+
52+
# TODO: Make InputMediaPhoto, InputMediaVideo and send_media_group work with new files
53+
54+
def __init__(self, media, caption=None, width=None, height=None, duration=None):
55+
self.type = 'video'
56+
57+
if isinstance(media, Video):
58+
self.media = media.file_id
59+
self.width = media.width
60+
self.height = media.height
61+
self.duration = media.duration
62+
elif hasattr(media, 'read'):
63+
raise ValueError('Sending files is not supported (yet). Use file_id, url or Video')
64+
else:
65+
self.media = media
66+
67+
if caption:
68+
self.caption = caption
69+
if width:
70+
self.width = width
71+
if height:
72+
self.height = height
73+
if duration:
74+
self.duration = duration

0 commit comments

Comments
 (0)