Skip to content

Commit

Permalink
add support for 3.5 api (#920)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
Eldinnie committed Dec 8, 2017
1 parent 1e22d57 commit 042d4bb
Show file tree
Hide file tree
Showing 16 changed files with 434 additions and 16 deletions.
6 changes: 6 additions & 0 deletions docs/source/telegram.inputmedia.rst
@@ -0,0 +1,6 @@
telegram.InputMedia
===================

.. autoclass:: telegram.InputMedia
:members:
:show-inheritance:
6 changes: 6 additions & 0 deletions docs/source/telegram.inputmediaphoto.rst
@@ -0,0 +1,6 @@
telegram.InputMediaPhoto
========================

.. autoclass:: telegram.InputMediaPhoto
:members:
:show-inheritance:
6 changes: 6 additions & 0 deletions docs/source/telegram.inputmediavideo.rst
@@ -0,0 +1,6 @@
telegram.InputMediaVideo
========================

.. autoclass:: telegram.InputMediaVideo
:members:
:show-inheritance:
3 changes: 3 additions & 0 deletions docs/source/telegram.rst
Expand Up @@ -21,6 +21,9 @@ telegram package
telegram.inlinekeyboardbutton
telegram.inlinekeyboardmarkup
telegram.inputfile
telegram.inputmedia
telegram.inputmediaphoto
telegram.inputmediavideo
telegram.keyboardbutton
telegram.location
telegram.message
Expand Down
6 changes: 5 additions & 1 deletion telegram/__init__.py
Expand Up @@ -96,6 +96,9 @@
MAX_FILESIZE_DOWNLOAD, MAX_FILESIZE_UPLOAD,
MAX_MESSAGES_PER_SECOND_PER_CHAT, MAX_MESSAGES_PER_SECOND,
MAX_MESSAGES_PER_MINUTE_PER_GROUP)
from .files.inputmedia import InputMedia
from .files.inputmediavideo import InputMediaVideo
from .files.inputmediaphoto import InputMediaPhoto
from .version import __version__ # flake8: noqa

__author__ = 'devs@python-telegram-bot.org'
Expand All @@ -121,5 +124,6 @@
'MAX_MESSAGES_PER_SECOND', 'MAX_MESSAGES_PER_MINUTE_PER_GROUP', 'WebhookInfo', 'Animation',
'Game', 'GameHighScore', 'VideoNote', 'LabeledPrice', 'SuccessfulPayment', 'ShippingOption',
'ShippingAddress', 'PreCheckoutQuery', 'OrderInfo', 'Invoice', 'ShippingQuery', 'ChatPhoto',
'StickerSet', 'MaskPosition', 'CallbackGame'
'StickerSet', 'MaskPosition', 'CallbackGame', 'InputMedia', 'InputMediaPhoto',
'InputMediaVideo'
]
72 changes: 65 additions & 7 deletions telegram/bot.py
Expand Up @@ -21,10 +21,13 @@
"""This module contains an object that represents a Telegram Bot."""

import functools
import json
import logging
import warnings
from datetime import datetime

from future.utils import string_types

from telegram import (User, Message, Update, Chat, ChatMember, UserProfilePhotos, File,
ReplyMarkup, TelegramObject, WebhookInfo, GameHighScore, StickerSet,
PhotoSize, Audio, Document, Sticker, Video, Voice, VideoNote, Location,
Expand Down Expand Up @@ -335,7 +338,7 @@ def send_photo(self,
disable_notification=False,
reply_to_message_id=None,
reply_markup=None,
timeout=20.,
timeout=20,
**kwargs):
"""Use this method to send photos.
Expand Down Expand Up @@ -394,7 +397,7 @@ def send_audio(self,
disable_notification=False,
reply_to_message_id=None,
reply_markup=None,
timeout=20.,
timeout=20,
**kwargs):
"""
Use this method to send audio files, if you want Telegram clients to display them in the
Expand Down Expand Up @@ -465,7 +468,7 @@ def send_document(self,
disable_notification=False,
reply_to_message_id=None,
reply_markup=None,
timeout=20.,
timeout=20,
**kwargs):
"""Use this method to send general files.
Expand Down Expand Up @@ -576,7 +579,7 @@ def send_video(self,
disable_notification=False,
reply_to_message_id=None,
reply_markup=None,
timeout=20.,
timeout=20,
width=None,
height=None,
**kwargs):
Expand Down Expand Up @@ -646,7 +649,7 @@ def send_voice(self,
disable_notification=False,
reply_to_message_id=None,
reply_markup=None,
timeout=20.,
timeout=20,
**kwargs):
"""
Use this method to send audio files, if you want Telegram clients to display the file
Expand Down Expand Up @@ -708,7 +711,7 @@ def send_video_note(self,
disable_notification=False,
reply_to_message_id=None,
reply_markup=None,
timeout=20.,
timeout=20,
**kwargs):
"""Use this method to send video messages.
Expand Down Expand Up @@ -757,6 +760,51 @@ def send_video_note(self,

return url, data

@log
def send_media_group(self,
chat_id,
media,
disable_notification=None,
reply_to_message_id=None,
timeout=20,
**kwargs):
"""Use this method to send a group of photos or videos as an album.
Args:
chat_id (:obj:`int` | :obj:`str`): Unique identifier for the target chat or username
of the target channel (in the format @channelusername).
media (List[:class:`telegram.InputMedia`]): An array describing photos and videos to be
sent, must include 2–10 items.
disable_notification (:obj:`bool`, optional): Sends the message silently. Users will
receive a notification with no sound.
reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the
original message.
timeout (:obj:`int` | :obj:`float`, optional): Send file timeout (default: 20 seconds).
**kwargs (:obj:`dict`): Arbitrary keyword arguments.
Returns:
List[:class:`telegram.Message`]: An array of the sent Messages.
Raises:
:class:`telegram.TelegramError`
"""
# TODO: Make InputMediaPhoto, InputMediaVideo and send_media_group work with new files

url = '{0}/sendMediaGroup'.format(self.base_url)

media = [med.to_dict() for med in media]

data = {'chat_id': chat_id, 'media': media}

if reply_to_message_id:
data['reply_to_message_id'] = reply_to_message_id
if disable_notification:
data['disable_notification'] = disable_notification

result = self._request.post(url, data, timeout=timeout)

return [Message.de_json(res, self) for res in result]

@log
@message
def send_location(self,
Expand Down Expand Up @@ -2153,6 +2201,7 @@ def send_invoice(self,
disable_notification=False,
reply_to_message_id=None,
reply_markup=None,
provider_data=None,
timeout=None,
**kwargs):
"""Use this method to send invoices.
Expand All @@ -2169,6 +2218,10 @@ def send_invoice(self,
currency (:obj:`str`): Three-letter ISO 4217 currency code.
prices (List[:class:`telegram.LabeledPrice`)]: Price breakdown, a list of components
(e.g. product price, tax, discount, delivery cost, delivery tax, bonus, etc.).
provider_data (:obj:`str` | :obj:`object`, optional): JSON-encoded data about the
invoice, which will be shared with the payment provider. A detailed description of
required fields should be provided by the payment provider. When an object is
passed, it will be encoded as JSON.
photo_url (:obj:`str`, optional): URL of the product photo for the invoice. Can be a
photo of the goods or a marketing image for a service. People like it better when
they see what they are paying for.
Expand Down Expand Up @@ -2216,7 +2269,11 @@ def send_invoice(self,
'currency': currency,
'prices': [p.to_dict() for p in prices]
}

if provider_data is not None:
if isinstance(provider_data, string_types):
data['provider_data'] = provider_data
else:
data['provider_data'] = json.dumps(provider_data)
if photo_url is not None:
data['photo_url'] = photo_url
if photo_size is not None:
Expand Down Expand Up @@ -2965,6 +3022,7 @@ def __reduce__(self):
sendVideo = send_video
sendVoice = send_voice
sendVideoNote = send_video_note
sendMediaGroup = send_media_group
sendLocation = send_location
editMessageLiveLocation = edit_message_live_location
stopMessageLiveLocation = stop_message_live_location
Expand Down
31 changes: 31 additions & 0 deletions telegram/files/inputmedia.py
@@ -0,0 +1,31 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2017
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""Base class for Telegram InputMedia Objects."""

from telegram import TelegramObject


class InputMedia(TelegramObject):
"""Base class for Telegram InputMedia Objects.
See :class:`telegram.InputMediaPhoto` and :class:`telegram.InputMediaVideo` for
detailed use.
"""
pass
57 changes: 57 additions & 0 deletions telegram/files/inputmediaphoto.py
@@ -0,0 +1,57 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2017
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram InputMediaPhoto."""
from telegram import InputMedia, PhotoSize


class InputMediaPhoto(InputMedia):
"""Represents a photo to be sent.
Attributes:
type (:obj:`str`): ``photo``.
media (:obj:`str`): File to send. Pass a file_id to send a file that exists on the
Telegram servers (recommended), pass an HTTP URL for Telegram to get a file from the
Internet. Lastly you can pass an existing :class:`telegram.PhotoSize` object to send.
caption (:obj:`str`): Optional. Caption of the photo to be sent, 0-200 characters.
Args:
media (:obj:`str`): File to send. Pass a file_id to send a file that exists on the
Telegram servers (recommended), pass an HTTP URL for Telegram to get a file from the
Internet. Lastly you can pass an existing :class:`telegram.PhotoSize` object to send.
caption (:obj:`str`, optional ): Caption of the photo to be sent, 0-200 characters.
Note:
At the moment using a new file is not yet supported.
"""

# TODO: Make InputMediaPhoto, InputMediaVideo and send_media_group work with new files

def __init__(self, media, caption=None):
self.type = 'photo'

if isinstance(media, PhotoSize):
self.media = media.file_id
elif hasattr(media, 'read'):
raise ValueError(
'Sending files is not supported (yet). Use file_id, url or PhotoSize')
else:
self.media = media

if caption:
self.caption = caption
74 changes: 74 additions & 0 deletions telegram/files/inputmediavideo.py
@@ -0,0 +1,74 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2017
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram InputMediaPhoto."""
from telegram import InputMedia, Video


class InputMediaVideo(InputMedia):
"""Represents a video to be sent.
Attributes:
type (:obj:`str`): ``video``.
media (:obj:`str`): File to send. Pass a file_id to send a file that exists on the Telegram
servers (recommended), pass an HTTP URL for Telegram to get a file from the Internet.
Lastly you can pass an existing :class:`telegram.Video` object to send.
caption (:obj:`str`): Optional. Caption of the video to be sent, 0-200 characters.
width (:obj:`int`): Optional. Video width.
height (:obj:`int`): Optional. Video height.
duration (:obj:`int`): Optional. Video duration.
Args:
media (:obj:`str`): File to send. Pass a file_id to send a file that exists on the Telegram
servers (recommended), pass an HTTP URL for Telegram to get a file from the Internet.
Lastly you can pass an existing :class:`telegram.Video` object to send.
caption (:obj:`str`, optional): Caption of the video to be sent, 0-200 characters.
width (:obj:`int`, optional): Video width.
height (:obj:`int`, optional): Video height.
duration (:obj:`int`, optional): Video duration.
Note:
When using a :class:`telegram.Video` for the :attr:`media` attribute. It will take the
width, height and duration from that video, unless otherwise specified with the optional
arguments.
At the moment using a new file is not yet supported.
"""

# TODO: Make InputMediaPhoto, InputMediaVideo and send_media_group work with new files

def __init__(self, media, caption=None, width=None, height=None, duration=None):
self.type = 'video'

if isinstance(media, Video):
self.media = media.file_id
self.width = media.width
self.height = media.height
self.duration = media.duration
elif hasattr(media, 'read'):
raise ValueError('Sending files is not supported (yet). Use file_id, url or Video')
else:
self.media = media

if caption:
self.caption = caption
if width:
self.width = width
if height:
self.height = height
if duration:
self.duration = duration

0 comments on commit 042d4bb

Please sign in to comment.