diff --git a/README.rst b/README.rst index 96901d5f513..9839d10c170 100644 --- a/README.rst +++ b/README.rst @@ -20,7 +20,7 @@ We have a vibrant community of developers helping each other in our `Telegram gr :target: https://pypi.org/project/python-telegram-bot/ :alt: Supported Python versions -.. image:: https://img.shields.io/badge/Bot%20API-5.6-blue?logo=telegram +.. image:: https://img.shields.io/badge/Bot%20API-5.7-blue?logo=telegram :target: https://core.telegram.org/bots/api-changelog :alt: Supported Bot API versions @@ -111,7 +111,7 @@ Installing both ``python-telegram-bot`` and ``python-telegram-bot-raw`` in conju Telegram API support ==================== -All types and methods of the Telegram Bot API **5.6** are supported. +All types and methods of the Telegram Bot API **5.7** are supported. ========== Installing diff --git a/README_RAW.rst b/README_RAW.rst index 40cd416e861..d7b2fa37e7a 100644 --- a/README_RAW.rst +++ b/README_RAW.rst @@ -20,7 +20,7 @@ We have a vibrant community of developers helping each other in our `Telegram gr :target: https://pypi.org/project/python-telegram-bot-raw/ :alt: Supported Python versions -.. image:: https://img.shields.io/badge/Bot%20API-5.6-blue?logo=telegram +.. image:: https://img.shields.io/badge/Bot%20API-5.7-blue?logo=telegram :target: https://core.telegram.org/bots/api-changelog :alt: Supported Bot API versions @@ -105,7 +105,7 @@ Installing both ``python-telegram-bot`` and ``python-telegram-bot-raw`` in conju Telegram API support ==================== -All types and methods of the Telegram Bot API **5.6** are supported. +All types and methods of the Telegram Bot API **5.7** are supported. ========== Installing diff --git a/telegram/bot.py b/telegram/bot.py index ab843f14e54..cc983d561fa 100644 --- a/telegram/bot.py +++ b/telegram/bot.py @@ -996,7 +996,7 @@ def send_sticker( protect_content: bool = None, ) -> Message: """ - Use this method to send static .WEBP or animated .TGS stickers. + Use this method to send static ``.WEBP``, animated ``.TGS``, or video ``.WEBM`` stickers. Note: The sticker argument can be either a file_id, an URL or a file from disk @@ -4753,7 +4753,7 @@ def upload_sticker_file( api_kwargs: JSONDict = None, ) -> File: """ - Use this method to upload a .png file with a sticker for later use in + Use this method to upload a ``.PNG`` file with a sticker for later use in :meth:`create_new_sticker_set` and :meth:`add_sticker_to_set` methods (can be used multiple times). @@ -4764,9 +4764,8 @@ def upload_sticker_file( Args: user_id (:obj:`int`): User identifier of sticker file owner. png_sticker (:obj:`str` | `filelike object` | :obj:`bytes` | :class:`pathlib.Path`): - Png image with the sticker, - must be up to 512 kilobytes in size, dimensions must not exceed 512px, - and either width or height must be exactly 512px. + **PNG** image with the sticker, must be up to 512 kilobytes in size, + dimensions must not exceed 512px, and either width or height must be exactly 512px. .. versionchanged:: 13.2 Accept :obj:`bytes` as input. @@ -4802,11 +4801,13 @@ def create_new_sticker_set( timeout: DVInput[float] = DEFAULT_20, tgs_sticker: FileInput = None, api_kwargs: JSONDict = None, + webm_sticker: FileInput = None, ) -> bool: """ Use this method to create new sticker set owned by a user. The bot will be able to edit the created sticker set. - You must use exactly one of the fields ``png_sticker`` or ``tgs_sticker``. + You must use exactly one of the fields ``png_sticker``, ``tgs_sticker``, or + ``webm_sticker``. Warning: As of API 4.7 ``png_sticker`` is an optional argument and therefore the order of the @@ -4826,7 +4827,7 @@ def create_new_sticker_set( 1-64 characters. title (:obj:`str`): Sticker set title, 1-64 characters. png_sticker (:obj:`str` | `filelike object` | :obj:`bytes` | :class:`pathlib.Path`, \ - optional): Png image with the sticker, + optional): **PNG** image with the sticker, must be up to 512 kilobytes in size, dimensions must not exceed 512px, and either width or height must be exactly 512px. Pass a file_id as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a @@ -4836,13 +4837,19 @@ def create_new_sticker_set( .. versionchanged:: 13.2 Accept :obj:`bytes` as input. tgs_sticker (:obj:`str` | `filelike object` | :obj:`bytes` | :class:`pathlib.Path`, \ - optional): TGS animation with the sticker, - uploaded using multipart/form-data. See - https://core.telegram.org/animated_stickers#technical-requirements for technical + optional): **TGS** animation with the sticker, uploaded using multipart/form-data. + See https://core.telegram.org/stickers#animated-sticker-requirements for technical requirements. .. versionchanged:: 13.2 Accept :obj:`bytes` as input. + webm_sticker (:obj:`str` | :term:`file object` | :obj:`bytes` | :class:`pathlib.Path`,\ + optional): **WEBM** video with the sticker, uploaded using multipart/form-data. + See https://core.telegram.org/stickers#video-sticker-requirements for + technical requirements. + + .. versionadded:: 13.11 + emojis (:obj:`str`): One or more emoji corresponding to the sticker. contains_masks (:obj:`bool`, optional): Pass :obj:`True`, if a set of mask stickers should be created. @@ -4867,6 +4874,8 @@ def create_new_sticker_set( data['png_sticker'] = parse_file_input(png_sticker) if tgs_sticker is not None: data['tgs_sticker'] = parse_file_input(tgs_sticker) + if webm_sticker is not None: + data['webm_sticker'] = parse_file_input(webm_sticker) if contains_masks is not None: data['contains_masks'] = contains_masks if mask_position is not None: @@ -4889,12 +4898,14 @@ def add_sticker_to_set( timeout: DVInput[float] = DEFAULT_20, tgs_sticker: FileInput = None, api_kwargs: JSONDict = None, + webm_sticker: FileInput = None, ) -> bool: """ Use this method to add a new sticker to a set created by the bot. - You must use exactly one of the fields ``png_sticker`` or ``tgs_sticker``. Animated - stickers can be added to animated sticker sets and only to them. Animated sticker sets can - have up to 50 stickers. Static sticker sets can have up to 120 stickers. + You **must** use exactly one of the fields ``png_sticker``, ``tgs_sticker`` or + ``webm_sticker``. Animated stickers can be added to animated sticker sets and only to them. + Animated sticker sets can have up to 50 stickers. Static sticker sets can have up to 120 + stickers. Warning: As of API 4.7 ``png_sticker`` is an optional argument and therefore the order of the @@ -4910,7 +4921,7 @@ def add_sticker_to_set( name (:obj:`str`): Sticker set name. png_sticker (:obj:`str` | `filelike object` | :obj:`bytes` | :class:`pathlib.Path`, \ - optional): PNG image with the sticker, + optional): **PNG** image with the sticker, must be up to 512 kilobytes in size, dimensions must not exceed 512px, and either width or height must be exactly 512px. Pass a file_id as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a @@ -4920,13 +4931,18 @@ def add_sticker_to_set( .. versionchanged:: 13.2 Accept :obj:`bytes` as input. tgs_sticker (:obj:`str` | `filelike object` | :obj:`bytes` | :class:`pathlib.Path`, \ - optional): TGS animation with the sticker, - uploaded using multipart/form-data. See - https://core.telegram.org/animated_stickers#technical-requirements for technical + optional): **TGS** animation with the sticker, uploaded using multipart/form-data. + See https://core.telegram.org/stickers#animated-sticker-requirements for technical requirements. .. versionchanged:: 13.2 Accept :obj:`bytes` as input. + webm_sticker (:obj:`str` | :term:`file object` | :obj:`bytes` | :class:`pathlib.Path`,\ + optional): **WEBM** video with the sticker, uploaded using multipart/form-data. + See https://core.telegram.org/stickers#video-sticker-requirements for + technical requirements. + + .. versionadded:: 13.11 emojis (:obj:`str`): One or more emoji corresponding to the sticker. mask_position (:class:`telegram.MaskPosition`, optional): Position where the mask should be placed on faces. @@ -4949,6 +4965,8 @@ def add_sticker_to_set( data['png_sticker'] = parse_file_input(png_sticker) if tgs_sticker is not None: data['tgs_sticker'] = parse_file_input(tgs_sticker) + if webm_sticker is not None: + data['webm_sticker'] = parse_file_input(webm_sticker) if mask_position is not None: # We need to_json() instead of to_dict() here, because we're sending a media # message here, which isn't json dumped by utils.request @@ -5032,7 +5050,8 @@ def set_sticker_set_thumb( api_kwargs: JSONDict = None, ) -> bool: """Use this method to set the thumbnail of a sticker set. Animated thumbnails can be set - for animated sticker sets only. + for animated sticker sets only. Video thumbnails can be set only for video sticker sets + only. Note: The thumb can be either a file_id, an URL or a file from disk ``open(filename, 'rb')`` @@ -5041,14 +5060,17 @@ def set_sticker_set_thumb( name (:obj:`str`): Sticker set name user_id (:obj:`int`): User identifier of created sticker set owner. thumb (:obj:`str` | `filelike object` | :obj:`bytes` | :class:`pathlib.Path`, \ - optional): A PNG image with the thumbnail, must - be up to 128 kilobytes in size and have width and height exactly 100px, or a TGS - animation with the thumbnail up to 32 kilobytes in size; see - https://core.telegram.org/animated_stickers#technical-requirements for animated - sticker technical requirements. Pass a file_id as a String to send a file that + optional): A **PNG** image with the thumbnail, must + be up to 128 kilobytes in size and have width and height exactly 100px, or a + **TGS** animation with the thumbnail up to 32 kilobytes in size; see + https://core.telegram.org/stickers#animated-sticker-requirements for animated + sticker technical requirements, or a **WEBM** video with the thumbnail up to 32 + kilobytes in size; see + https://core.telegram.org/stickers#video-sticker-requirements for video sticker + technical requirements. Pass a file_id as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. - Animated sticker set thumbnail can't be uploaded via HTTP URL. + Animated sticker set thumbnails can't be uploaded via HTTP URL. .. versionchanged:: 13.2 Accept :obj:`bytes` as input. diff --git a/telegram/constants.py b/telegram/constants.py index a7628cdef58..b7600a72df0 100644 --- a/telegram/constants.py +++ b/telegram/constants.py @@ -21,7 +21,7 @@ `Telegram Bots API `_. Attributes: - BOT_API_VERSION (:obj:`str`): `5.6`. Telegram Bot API version supported by this + BOT_API_VERSION (:obj:`str`): `5.7`. Telegram Bot API version supported by this version of `python-telegram-bot`. Also available as ``telegram.bot_api_version``. .. versionadded:: 13.4 @@ -247,7 +247,7 @@ """ from typing import List -BOT_API_VERSION: str = '5.6' +BOT_API_VERSION: str = '5.7' MAX_MESSAGE_LENGTH: int = 4096 MAX_CAPTION_LENGTH: int = 1024 ANONYMOUS_ADMIN_ID: int = 1087968824 diff --git a/telegram/files/sticker.py b/telegram/files/sticker.py index 5cce2af2e11..e3f22a99754 100644 --- a/telegram/files/sticker.py +++ b/telegram/files/sticker.py @@ -34,6 +34,11 @@ class Sticker(TelegramObject): Objects of this class are comparable in terms of equality. Two objects of this class are considered equal, if their :attr:`file_unique_id` is equal. + Note: + As of v13.11 ``is_video`` is a required argument and therefore the order of the + arguments had to be changed. Use keyword arguments to make sure that the arguments are + passed correctly. + Args: file_id (:obj:`str`): Identifier for this file, which can be used to download or reuse the file. @@ -43,6 +48,9 @@ class Sticker(TelegramObject): width (:obj:`int`): Sticker width. height (:obj:`int`): Sticker height. is_animated (:obj:`bool`): :obj:`True`, if the sticker is animated. + is_video (:obj:`bool`): :obj:`True`, if the sticker is a video sticker. + + .. versionadded:: 13.11 thumb (:class:`telegram.PhotoSize`, optional): Sticker thumbnail in the .WEBP or .JPG format. emoji (:obj:`str`, optional): Emoji associated with the sticker @@ -62,6 +70,9 @@ class Sticker(TelegramObject): width (:obj:`int`): Sticker width. height (:obj:`int`): Sticker height. is_animated (:obj:`bool`): :obj:`True`, if the sticker is animated. + is_video (:obj:`bool`): :obj:`True`, if the sticker is a video sticker. + + .. versionadded:: 13.11 thumb (:class:`telegram.PhotoSize`): Optional. Sticker thumbnail in the .webp or .jpg format. emoji (:obj:`str`): Optional. Emoji associated with the sticker. @@ -78,6 +89,7 @@ class Sticker(TelegramObject): 'width', 'file_id', 'is_animated', + 'is_video', 'file_size', 'thumb', 'set_name', @@ -95,6 +107,7 @@ def __init__( width: int, height: int, is_animated: bool, + is_video: bool, thumb: PhotoSize = None, emoji: str = None, file_size: int = None, @@ -109,6 +122,7 @@ def __init__( self.width = int(width) self.height = int(height) self.is_animated = is_animated + self.is_video = is_video # Optionals self.thumb = thumb self.emoji = emoji @@ -155,28 +169,40 @@ class StickerSet(TelegramObject): Objects of this class are comparable in terms of equality. Two objects of this class are considered equal, if their :attr:`name` is equal. - Attributes: + Note: + As of v13.11 ``is_video`` is a required argument and therefore the order of the + arguments had to be changed. Use keyword arguments to make sure that the arguments are + passed correctly. + + Args: name (:obj:`str`): Sticker set name. title (:obj:`str`): Sticker set title. is_animated (:obj:`bool`): :obj:`True`, if the sticker set contains animated stickers. + is_video (:obj:`bool`): :obj:`True`, if the sticker set contains video stickers. + + .. versionadded:: 13.11 contains_masks (:obj:`bool`): :obj:`True`, if the sticker set contains masks. stickers (List[:class:`telegram.Sticker`]): List of all set stickers. - thumb (:class:`telegram.PhotoSize`): Optional. Sticker set thumbnail in the .WEBP or .TGS - format. + thumb (:class:`telegram.PhotoSize`, optional): Sticker set thumbnail in the ``.WEBP``, + ``.TGS``, or ``.WEBM`` format. - Args: + Attributes: name (:obj:`str`): Sticker set name. title (:obj:`str`): Sticker set title. is_animated (:obj:`bool`): :obj:`True`, if the sticker set contains animated stickers. + is_video (:obj:`bool`): :obj:`True`, if the sticker set contains video stickers. + + .. versionadded:: 13.11 contains_masks (:obj:`bool`): :obj:`True`, if the sticker set contains masks. stickers (List[:class:`telegram.Sticker`]): List of all set stickers. - thumb (:class:`telegram.PhotoSize`, optional): Sticker set thumbnail in the .WEBP or .TGS - format. + thumb (:class:`telegram.PhotoSize`): Optional. Sticker set thumbnail in the ``.WEBP``, + ``.TGS`` or ``.WEBM`` format. """ __slots__ = ( 'is_animated', + 'is_video', 'contains_masks', 'thumb', 'title', @@ -192,12 +218,14 @@ def __init__( is_animated: bool, contains_masks: bool, stickers: List[Sticker], + is_video: bool, thumb: PhotoSize = None, **_kwargs: Any, ): self.name = name self.title = title self.is_animated = is_animated + self.is_video = is_video self.contains_masks = contains_masks self.stickers = stickers # Optionals diff --git a/tests/data/telegram_video_sticker.webm b/tests/data/telegram_video_sticker.webm new file mode 100644 index 00000000000..3110856aee7 Binary files /dev/null and b/tests/data/telegram_video_sticker.webm differ diff --git a/tests/test_bot.py b/tests/test_bot.py index d25442eedb4..ceb371b45dd 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -1429,11 +1429,11 @@ def test_get_chat_member(self, bot, channel_id, chat_id): assert chat_member.user.first_name == 'PTB' assert chat_member.user.last_name == 'Test user' - @pytest.mark.skip(reason="Not implemented yet.") + @pytest.mark.skip(reason="Not implemented since we need a supergroup with many members") def test_set_chat_sticker_set(self): pass - @pytest.mark.skip(reason="Not implemented yet.") + @pytest.mark.skip(reason="Not implemented since we need a supergroup with many members") def test_delete_chat_sticker_set(self): pass diff --git a/tests/test_helpers.py b/tests/test_helpers.py index 75985e78a44..dea4862ed22 100644 --- a/tests/test_helpers.py +++ b/tests/test_helpers.py @@ -272,7 +272,7 @@ def build_test_message(**kwargs): test_message.text = None test_message = build_test_message( - sticker=Sticker('sticker_id', 'unique_id', 50, 50, False) + sticker=Sticker('sticker_id', 'unique_id', 50, 50, False, False) ) assert helpers.effective_message_type(test_message) == 'sticker' test_message.sticker = None diff --git a/tests/test_message.py b/tests/test_message.py index 6c0169712e6..69db2a8e6dd 100644 --- a/tests/test_message.py +++ b/tests/test_message.py @@ -105,7 +105,7 @@ def message(bot): ) }, {'photo': [PhotoSize('photo_id', 'unique_id', 50, 50)], 'caption': 'photo_file'}, - {'sticker': Sticker('sticker_id', 'unique_id', 50, 50, True)}, + {'sticker': Sticker('sticker_id', 'unique_id', 50, 50, True, False)}, {'video': Video('video_id', 'unique_id', 12, 12, 12), 'caption': 'video_file'}, {'voice': Voice('voice_id', 'unique_id', 5)}, {'video_note': VideoNote('video_note_id', 'unique_id', 20, 12)}, diff --git a/tests/test_photo.py b/tests/test_photo.py index 27cdd19f9a0..bc908ccf571 100644 --- a/tests/test_photo.py +++ b/tests/test_photo.py @@ -473,7 +473,7 @@ def test_equality(self, photo): b = PhotoSize('', photo.file_unique_id, self.width, self.height) c = PhotoSize(photo.file_id, photo.file_unique_id, 0, 0) d = PhotoSize('', '', self.width, self.height) - e = Sticker(photo.file_id, photo.file_unique_id, self.width, self.height, False) + e = Sticker(photo.file_id, photo.file_unique_id, self.width, self.height, False, False) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_sticker.py b/tests/test_sticker.py index 6fe348870cd..d45cc83f843 100644 --- a/tests/test_sticker.py +++ b/tests/test_sticker.py @@ -54,6 +54,18 @@ def animated_sticker(bot, chat_id): return bot.send_sticker(chat_id, sticker=f, timeout=50).sticker +@pytest.fixture(scope='function') +def video_sticker_file(): + with open('tests/data/telegram_video_sticker.webm', 'rb') as f: + yield f + + +@pytest.fixture(scope='class') +def video_sticker(bot, chat_id): + with open('tests/data/telegram_video_sticker.webm', 'rb') as f: + return bot.send_sticker(chat_id, sticker=f, timeout=50).sticker + + class TestSticker: # sticker_file_url = 'https://python-telegram-bot.org/static/testfiles/telegram.webp' # Serving sticker from gh since our server sends wrong content_type @@ -66,6 +78,7 @@ class TestSticker: width = 510 height = 512 is_animated = False + is_video = False file_size = 39518 thumb_width = 319 thumb_height = 320 @@ -99,6 +112,7 @@ def test_expected_values(self, sticker): assert sticker.width == self.width assert sticker.height == self.height assert sticker.is_animated == self.is_animated + assert sticker.is_video == self.is_video assert sticker.file_size == self.file_size assert sticker.thumb.width == self.thumb_width assert sticker.thumb.height == self.thumb_height @@ -118,6 +132,7 @@ def test_send_all_args(self, bot, chat_id, sticker_file, sticker): assert message.sticker.width == sticker.width assert message.sticker.height == sticker.height assert message.sticker.is_animated == sticker.is_animated + assert message.sticker.is_video == sticker.is_video assert message.sticker.file_size == sticker.file_size assert isinstance(message.sticker.thumb, PhotoSize) @@ -169,6 +184,7 @@ def test_send_from_url(self, bot, chat_id): assert message.sticker.width == sticker.width assert message.sticker.height == sticker.height assert message.sticker.is_animated == sticker.is_animated + assert message.sticker.is_video == sticker.is_video assert message.sticker.file_size == sticker.file_size assert isinstance(message.sticker.thumb, PhotoSize) @@ -187,6 +203,7 @@ def test_de_json(self, bot, sticker): 'width': self.width, 'height': self.height, 'is_animated': self.is_animated, + 'is_video': self.is_video, 'thumb': sticker.thumb.to_dict(), 'emoji': self.emoji, 'file_size': self.file_size, @@ -198,6 +215,7 @@ def test_de_json(self, bot, sticker): assert json_sticker.width == self.width assert json_sticker.height == self.height assert json_sticker.is_animated == self.is_animated + assert json_sticker.is_video == self.is_video assert json_sticker.emoji == self.emoji assert json_sticker.file_size == self.file_size assert json_sticker.thumb == sticker.thumb @@ -268,6 +286,7 @@ def test_to_dict(self, sticker): assert sticker_dict['width'] == sticker.width assert sticker_dict['height'] == sticker.height assert sticker_dict['is_animated'] == sticker.is_animated + assert sticker_dict['is_video'] == sticker.is_video assert sticker_dict['file_size'] == sticker.file_size assert sticker_dict['thumb'] == sticker.thumb.to_dict() @@ -287,11 +306,18 @@ def test_error_without_required_args(self, bot, chat_id): def test_equality(self, sticker): a = Sticker( - sticker.file_id, sticker.file_unique_id, self.width, self.height, self.is_animated + sticker.file_id, + sticker.file_unique_id, + self.width, + self.height, + self.is_animated, + self.is_video, + ) + b = Sticker( + '', sticker.file_unique_id, self.width, self.height, self.is_animated, self.is_video ) - b = Sticker('', sticker.file_unique_id, self.width, self.height, self.is_animated) - c = Sticker(sticker.file_id, sticker.file_unique_id, 0, 0, False) - d = Sticker('', '', self.width, self.height, self.is_animated) + c = Sticker(sticker.file_id, sticker.file_unique_id, 0, 0, False, True) + d = Sticker('', '', self.width, self.height, self.is_animated, self.is_video) e = PhotoSize( sticker.file_id, sticker.file_unique_id, self.width, self.height, self.is_animated ) @@ -338,6 +364,20 @@ def animated_sticker_set(bot): return ss +@pytest.fixture(scope='function') +def video_sticker_set(bot): + ss = bot.get_sticker_set(f'video_test_by_{bot.username}') + if len(ss.stickers) > 100: + try: + for i in range(1, 50): + bot.delete_sticker_from_set(ss.stickers[-i].file_id) + except BadRequest as e: + if e.message == 'Stickerset_not_modified': + return ss + raise Exception('stickerset is growing too large.') + return ss + + @pytest.fixture(scope='function') def sticker_set_thumb_file(): f = open('tests/data/sticker_set_thumb.png', 'rb') @@ -348,8 +388,9 @@ def sticker_set_thumb_file(): class TestStickerSet: title = 'Test stickers' is_animated = True + is_video = True contains_masks = False - stickers = [Sticker('file_id', 'file_un_id', 512, 512, True)] + stickers = [Sticker('file_id', 'file_un_id', 512, 512, True, True)] name = 'NOTAREALNAME' def test_de_json(self, bot, sticker): @@ -358,6 +399,7 @@ def test_de_json(self, bot, sticker): 'name': name, 'title': self.title, 'is_animated': self.is_animated, + 'is_video': self.is_video, 'contains_masks': self.contains_masks, 'stickers': [x.to_dict() for x in self.stickers], 'thumb': sticker.thumb.to_dict(), @@ -367,14 +409,58 @@ def test_de_json(self, bot, sticker): assert sticker_set.name == name assert sticker_set.title == self.title assert sticker_set.is_animated == self.is_animated + assert sticker_set.is_video == self.is_video assert sticker_set.contains_masks == self.contains_masks assert sticker_set.stickers == self.stickers assert sticker_set.thumb == sticker.thumb + def test_create_sticker_set( + self, bot, chat_id, sticker_file, animated_sticker_file, video_sticker_file + ): + """Creates the sticker set (if needed) which is required for tests. Make sure that this + test comes before the tests that actually use the sticker sets! + """ + test_by = f"test_by_{bot.username}" + for sticker_set in [test_by, f'animated_{test_by}', f'video_{test_by}']: + try: + bot.get_sticker_set(sticker_set) + except BadRequest as e: + if not e.message == "Stickerset_invalid": + raise e + + if sticker_set.startswith(test_by): + s = bot.create_new_sticker_set( + chat_id, + name=sticker_set, + title="Sticker Test", + png_sticker=sticker_file, + emojis='😄', + ) + assert s + elif sticker_set.startswith("animated"): + a = bot.create_new_sticker_set( + chat_id, + name=sticker_set, + title="Animated Test", + tgs_sticker=animated_sticker_file, + emojis='😄', + ) + assert a + elif sticker_set.startswith("video"): + v = bot.create_new_sticker_set( + chat_id, + name=sticker_set, + title="Video Test", + webm_sticker=video_sticker_file, + emojis='🤔', + ) + assert v + @flaky(3, 1) def test_bot_methods_1_png(self, bot, chat_id, sticker_file): with open('tests/data/telegram_sticker.png', 'rb') as f: - file = bot.upload_sticker_file(95205500, f) + # chat_id was hardcoded as 95205500 but it stopped working for some reason + file = bot.upload_sticker_file(chat_id, f) assert file assert bot.add_sticker_to_set( chat_id, f'test_by_{bot.username}', png_sticker=file.file_id, emojis='😄' @@ -397,6 +483,13 @@ def test_bot_methods_1_tgs(self, bot, chat_id): emojis='😄', ) + @flaky(3, 1) + def test_bot_methods_1_webm(self, bot, chat_id): + with open('tests/data/telegram_video_sticker.webm', 'rb') as f: + assert bot.add_sticker_to_set( + chat_id, f'video_test_by_{bot.username}', webm_sticker=f, emojis='🤔' + ) + def test_sticker_set_to_dict(self, sticker_set): sticker_set_dict = sticker_set.to_dict() @@ -404,6 +497,7 @@ def test_sticker_set_to_dict(self, sticker_set): assert sticker_set_dict['name'] == sticker_set.name assert sticker_set_dict['title'] == sticker_set.title assert sticker_set_dict['is_animated'] == sticker_set.is_animated + assert sticker_set_dict['is_video'] == sticker_set.is_video assert sticker_set_dict['contains_masks'] == sticker_set.contains_masks assert sticker_set_dict['stickers'][0] == sticker_set.stickers[0].to_dict() @@ -417,6 +511,11 @@ def test_bot_methods_2_tgs(self, bot, animated_sticker_set): file_id = animated_sticker_set.stickers[0].file_id assert bot.set_sticker_position_in_set(file_id, 1) + @flaky(3, 1) + def test_bot_methods_2_webm(self, bot, video_sticker_set): + file_id = video_sticker_set.stickers[0].file_id + assert bot.set_sticker_position_in_set(file_id, 1) + @flaky(10, 1) def test_bot_methods_3_png(self, bot, chat_id, sticker_set_thumb_file): sleep(1) @@ -427,12 +526,19 @@ def test_bot_methods_3_png(self, bot, chat_id, sticker_set_thumb_file): @flaky(10, 1) def test_bot_methods_3_tgs(self, bot, chat_id, animated_sticker_file, animated_sticker_set): sleep(1) - assert bot.set_sticker_set_thumb( - f'animated_test_by_{bot.username}', chat_id, animated_sticker_file - ) + animated_test = f'animated_test_by_{bot.username}' + assert bot.set_sticker_set_thumb(animated_test, chat_id, animated_sticker_file) file_id = animated_sticker_set.stickers[-1].file_id # also test with file input and mask - assert bot.set_sticker_set_thumb(f'animated_test_by_{bot.username}', chat_id, file_id) + assert bot.set_sticker_set_thumb(animated_test, chat_id, file_id) + + # TODO: Try the below by creating a custom .webm and not by downloading another pack's thumb + @pytest.mark.skip( + "Skipped for now since Telegram throws a 'File is too big' error " + "regardless of the .webm file size." + ) + def test_bot_methods_3_webm(self, bot, chat_id, video_sticker_file, video_sticker_set): + pass @flaky(10, 1) def test_bot_methods_4_png(self, bot, sticker_set): @@ -446,6 +552,12 @@ def test_bot_methods_4_tgs(self, bot, animated_sticker_set): file_id = animated_sticker_set.stickers[-1].file_id assert bot.delete_sticker_from_set(file_id) + @flaky(10, 1) + def test_bot_methods_4_webm(self, bot, video_sticker_set): + sleep(1) + file_id = video_sticker_set.stickers[-1].file_id + assert bot.delete_sticker_from_set(file_id) + def test_upload_sticker_file_local_files(self, monkeypatch, bot, chat_id): # For just test that the correct paths are passed as we have no local bot API set up test_flag = False @@ -469,11 +581,21 @@ def test_create_new_sticker_set_local_files(self, monkeypatch, bot, chat_id): def make_assertion(_, data, *args, **kwargs): nonlocal test_flag - test_flag = data.get('png_sticker') == expected and data.get('tgs_sticker') == expected + test_flag = ( + data.get('png_sticker') == expected + and data.get('tgs_sticker') == expected + and data.get('webm_sticker') == expected + ) monkeypatch.setattr(bot, '_post', make_assertion) bot.create_new_sticker_set( - chat_id, 'name', 'title', 'emoji', png_sticker=file, tgs_sticker=file + chat_id, + 'name', + 'title', + 'emoji', + png_sticker=file, + tgs_sticker=file, + webm_sticker=file, ) assert test_flag monkeypatch.delattr(bot, '_post') @@ -520,10 +642,26 @@ def make_assertion(*_, **kwargs): assert sticker.get_file() def test_equality(self): - a = StickerSet(self.name, self.title, self.is_animated, self.contains_masks, self.stickers) - b = StickerSet(self.name, self.title, self.is_animated, self.contains_masks, self.stickers) - c = StickerSet(self.name, None, None, None, None) - d = StickerSet('blah', self.title, self.is_animated, self.contains_masks, self.stickers) + a = StickerSet( + self.name, + self.title, + self.is_animated, + self.contains_masks, + self.stickers, + self.is_video, + ) + b = StickerSet( + self.name, + self.title, + self.is_animated, + self.contains_masks, + self.stickers, + self.is_video, + ) + c = StickerSet(self.name, None, None, None, None, None) + d = StickerSet( + 'blah', self.title, self.is_animated, self.contains_masks, self.stickers, self.is_video + ) e = Audio(self.name, '', 0, None, None) assert a == b