diff --git a/compiler/docs/compiler.py b/compiler/docs/compiler.py index 2e724106ef..a6214eadb3 100644 --- a/compiler/docs/compiler.py +++ b/compiler/docs/compiler.py @@ -465,10 +465,16 @@ def get_title_list(s: str) -> list: """, stickers=""" Stickers + get_suggested_sticker_set_name send_sticker get_custom_emoji_stickers get_message_effects + upload_sticker_file + set_sticker_position_in_set + set_sticker_set_title get_stickers + delete_sticker_from_set + delete_sticker_set """, stories=""" Stories @@ -604,6 +610,7 @@ def get_title_list(s: str) -> list: Animation Audio Document + File Story Video VideoNote @@ -1022,6 +1029,7 @@ def get_title_list(s: str) -> list: ProfileColor AccentColor SentCodeType + StickerFormat NextCodeType UserStatus """, diff --git a/pyrogram/enums/__init__.py b/pyrogram/enums/__init__.py index 8a744e7f9c..cc13599412 100644 --- a/pyrogram/enums/__init__.py +++ b/pyrogram/enums/__init__.py @@ -31,6 +31,7 @@ from .parse_mode import ParseMode from .poll_type import PollType from .sent_code_type import SentCodeType +from .sticker_format import StickerFormat from .user_status import UserStatus from .client_platform import ClientPlatform from .accent_color import AccentColor @@ -52,6 +53,7 @@ 'ParseMode', 'PollType', 'SentCodeType', + 'StickerFormat', 'UserStatus', 'ClientPlatform', 'AccentColor', diff --git a/pyrogram/enums/sticker_format.py b/pyrogram/enums/sticker_format.py new file mode 100644 index 0000000000..550afc1d2a --- /dev/null +++ b/pyrogram/enums/sticker_format.py @@ -0,0 +1,34 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present +# +# This file is part of Pyrogram. +# +# Pyrogram is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrogram 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 General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . + +from enum import auto + +from .auto_name import AutoName + + +class StickerFormat(AutoName): + """Format of the sticker.""" + + STATIC = auto() + "static" + + ANIMATED = auto() + "animated" + + VIDEO = auto() + "video" diff --git a/pyrogram/methods/messages/__init__.py b/pyrogram/methods/messages/__init__.py index a9961350d5..ebf15ad15e 100644 --- a/pyrogram/methods/messages/__init__.py +++ b/pyrogram/methods/messages/__init__.py @@ -33,7 +33,6 @@ from .forward_messages import ForwardMessages from .get_chat_history import GetChatHistory from .get_chat_history_count import GetChatHistoryCount -from .get_custom_emoji_stickers import GetCustomEmojiStickers from .get_discussion_message import GetDiscussionMessage from .get_discussion_replies import GetDiscussionReplies from .get_discussion_replies_count import GetDiscussionRepliesCount @@ -96,7 +95,6 @@ class Messages( ForwardMessages, GetChatHistory, GetChatHistoryCount, - GetCustomEmojiStickers, GetDiscussionMessage, GetDiscussionReplies, GetDiscussionRepliesCount, diff --git a/pyrogram/methods/stickers/__init__.py b/pyrogram/methods/stickers/__init__.py index f213537d69..292408f255 100644 --- a/pyrogram/methods/stickers/__init__.py +++ b/pyrogram/methods/stickers/__init__.py @@ -16,12 +16,26 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . +from .delete_sticker_from_set import DeleteStickerFromSet +from .delete_sticker_set import DeleteStickerSet +from .get_custom_emoji_stickers import GetCustomEmojiStickers from .get_message_effects import GetMessageEffects from .get_stickers import GetStickers +from .get_suggested_sticker_set_name import GetSuggestedStickerSetName +from .set_sticker_position_in_set import SetStickerPositionInSet +from .set_sticker_set_title import SetStickerSetTitle +from .upload_sticker_file import UploadStickerFile class Stickers( + DeleteStickerFromSet, + DeleteStickerSet, + GetCustomEmojiStickers, GetMessageEffects, GetStickers, + GetSuggestedStickerSetName, + SetStickerPositionInSet, + SetStickerSetTitle, + UploadStickerFile, ): pass diff --git a/pyrogram/methods/stickers/delete_sticker_from_set.py b/pyrogram/methods/stickers/delete_sticker_from_set.py new file mode 100644 index 0000000000..5a988de6aa --- /dev/null +++ b/pyrogram/methods/stickers/delete_sticker_from_set.py @@ -0,0 +1,55 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present +# +# This file is part of Pyrogram. +# +# Pyrogram is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrogram 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 General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . + +import logging + +import pyrogram +from pyrogram import raw, types, utils + +log = logging.getLogger(__name__) + + +class DeleteStickerFromSet: + async def delete_sticker_from_set( + self: "pyrogram.Client", + sticker: str + ) -> "types.StickerSet": + """Use this method to delete a sticker from a set created by the current user. + + .. include:: /_includes/usable-by/users-bots.rst + + Parameters: + sticker (``str``): + File identifier of the sticker. + + Returns: + :obj:`~pyrogram.types.StickerSet`: The updated StickerSet on success. + + Raises: + RPCError: In case of Telegram RPCError. + + """ + stickerdocument = utils.get_input_media_from_file_id(sticker) + stickerid = stickerdocument.id + r = await self.invoke( + raw.functions.stickers.RemoveStickerFromSet( + sticker=stickerid + ) + ) + # TODO: + return r diff --git a/pyrogram/methods/stickers/delete_sticker_set.py b/pyrogram/methods/stickers/delete_sticker_set.py new file mode 100644 index 0000000000..f0a50c96ad --- /dev/null +++ b/pyrogram/methods/stickers/delete_sticker_set.py @@ -0,0 +1,54 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present +# +# This file is part of Pyrogram. +# +# Pyrogram is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrogram 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 General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . + +import logging + +import pyrogram +from pyrogram import raw + +log = logging.getLogger(__name__) + + +class DeleteStickerSet: + async def delete_sticker_set( + self: "pyrogram.Client", + name: str + ) -> bool: + """Use this method to delete a sticker set that was created by the current user. + + .. include:: /_includes/usable-by/users-bots.rst + + Parameters: + name (``str``): + Sticker set name. + + Returns: + ``bool``: True on success. + + Raises: + RPCError: In case of Telegram RPCError. + + """ + r = await self.invoke( + raw.functions.stickers.DeleteStickerSet( + stickerset=raw.types.InputStickerSetShortName( + short_name=name + ) + ) + ) + return r diff --git a/pyrogram/methods/messages/get_custom_emoji_stickers.py b/pyrogram/methods/stickers/get_custom_emoji_stickers.py similarity index 100% rename from pyrogram/methods/messages/get_custom_emoji_stickers.py rename to pyrogram/methods/stickers/get_custom_emoji_stickers.py diff --git a/pyrogram/methods/stickers/get_suggested_sticker_set_name.py b/pyrogram/methods/stickers/get_suggested_sticker_set_name.py new file mode 100644 index 0000000000..5c6af87e59 --- /dev/null +++ b/pyrogram/methods/stickers/get_suggested_sticker_set_name.py @@ -0,0 +1,52 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present +# +# This file is part of Pyrogram. +# +# Pyrogram is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrogram 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 General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . + +import logging + +import pyrogram +from pyrogram import raw + +log = logging.getLogger(__name__) + + +class GetSuggestedStickerSetName: + async def get_suggested_sticker_set_name( + self: "pyrogram.Client", + title: str + ) -> str: + """Use this method to return a suggested name for a new sticker set with a given title. + + .. include:: /_includes/usable-by/users.rst + + Parameters: + title (``str``): + Sticker set title; 1-64 characters. + + Returns: + ``str``: the suggested name on success. + + Raises: + RPCError: In case of Telegram RPCError. + + """ + r = await self.invoke( + raw.functions.stickers.SuggestShortName( + title=title + ) + ) + return r.short_name diff --git a/pyrogram/methods/stickers/set_sticker_position_in_set.py b/pyrogram/methods/stickers/set_sticker_position_in_set.py new file mode 100644 index 0000000000..7bfbd18f17 --- /dev/null +++ b/pyrogram/methods/stickers/set_sticker_position_in_set.py @@ -0,0 +1,60 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present +# +# This file is part of Pyrogram. +# +# Pyrogram is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrogram 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 General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . + +import logging + +import pyrogram +from pyrogram import raw, utils + +log = logging.getLogger(__name__) + + +class SetStickerPositionInSet: + async def set_sticker_position_in_set( + self: "pyrogram.Client", + sticker: str, + position: int + ) -> bool: + """Use this method to move a sticker in a set created by the bot to a specific position. + + .. include:: /_includes/usable-by/users-bots.rst + + Parameters: + sticker (``str``): + File identifier of the sticker. + + position (``str``): + New sticker position in the set, zero-based. + + Returns: + ``bool``: True on success. + + Raises: + RPCError: In case of Telegram RPCError. + + """ + stickerdocument = utils.get_input_media_from_file_id(sticker) + stickerid = stickerdocument.id + r = await self.invoke( + raw.functions.stickers.ChangeStickerPosition( + sticker=stickerid, + position=position + ) + ) + # TODO + return r diff --git a/pyrogram/methods/stickers/set_sticker_set_title.py b/pyrogram/methods/stickers/set_sticker_set_title.py new file mode 100644 index 0000000000..dfbf7ea682 --- /dev/null +++ b/pyrogram/methods/stickers/set_sticker_set_title.py @@ -0,0 +1,59 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present +# +# This file is part of Pyrogram. +# +# Pyrogram is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrogram 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 General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . + +import logging + +import pyrogram +from pyrogram import raw + +log = logging.getLogger(__name__) + + +class SetStickerSetTitle: + async def set_sticker_set_title( + self: "pyrogram.Client", + name: str, + title: str + ) -> bool: + """Use this method to set the title of a created sticker set. + + .. include:: /_includes/usable-by/users-bots.rst + + Parameters: + name (``str``): + Sticker set name. + + title (``str``): + Sticker set title, 1-64 characters. + + Returns: + ``bool``: True on success. + + Raises: + RPCError: In case of Telegram RPCError. + + """ + r = await self.invoke( + raw.functions.stickers.RenameStickerSet( + stickerset=raw.types.InputStickerSetShortName( + short_name=name + ), + title=title + ) + ) + return r diff --git a/pyrogram/methods/stickers/upload_sticker_file.py b/pyrogram/methods/stickers/upload_sticker_file.py new file mode 100644 index 0000000000..7cd84d9f29 --- /dev/null +++ b/pyrogram/methods/stickers/upload_sticker_file.py @@ -0,0 +1,119 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present +# +# This file is part of Pyrogram. +# +# Pyrogram is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrogram 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 General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . + +import logging +import os + +import pyrogram +from pyrogram import enums, raw, types +from pyrogram.file_id import FileId, FileType, FileUniqueId, FileUniqueType + +log = logging.getLogger(__name__) + + +class UploadStickerFile: + async def upload_sticker_file( + self: "pyrogram.Client", + user_id: int, + sticker: str, + sticker_format: "enums.StickerFormat" + ) -> "types.File": + """Use this method to upload a file with a sticker for later use in the :meth:`~pyrogram.Client.create_new_sticker_set`, :meth:`~pyrogram.Client.add_sticker_to_set`, or :meth:`~pyrogram.Client.replace_sticker_in_set` methods (the file can be used multiple times). + + .. include:: /_includes/usable-by/users-bots.rst + + Parameters: + user_id (``int``): + User identifier of sticker file owner; ignored for regular users. + + sticker (``str``): + A file with the sticker in .WEBP, .PNG, .TGS, or .WEBM format. + File to upload; must fit in a 512x512 square. For WEBP stickers the file must be in WEBP or PNG format, which will be converted to WEBP server-side. + See https://core.telegram.org/animated_stickers#technical-requirements for technical requirements + + sticker_format (:obj:`~pyrogram.enums.StickerFormat`): + Format of the sticker. + + Returns: + :obj:`~pyrogram.types.File`: Returns the uploaded file on success. + + Raises: + RPCError: In case of Telegram RPCError. + ValueError: In case of invalid arguments. + + """ + mime_type = None + if sticker_format == enums.StickerFormat.STATIC: + mime_type = "image/png" + elif sticker_format == enums.StickerFormat.ANIMATED: + mime_type = "application/x-tgsticker" + elif sticker_format == enums.StickerFormat.VIDEO: + mime_type = "video/webm" + else: + raise ValueError("Invalid sticker_format") + peer = None + if self.me.is_bot: + peer = await self.resolve_peer(user_id) + else: + peer = await self.resolve_peer("me") + file = await self.save_file(sticker) + media = raw.types.InputMediaUploadedDocument( + mime_type=mime_type, + file=file, + attributes=[ + raw.types.DocumentAttributeFilename( + file_name=os.path.basename(sticker) + ), + ] + ) + media = await self.invoke( + raw.functions.messages.UploadMedia( + peer=peer, + media=media + ) + ) + media = raw.types.InputMediaDocument( + id=raw.types.InputDocument( + id=media.document.id, + access_hash=media.document.access_hash, + file_reference=media.document.file_reference + ) + ) + sticker = media.document + document_attributes = sticker.attributes + sticker_attributes = ( + document_attributes[raw.types.DocumentAttributeSticker] + if raw.types.DocumentAttributeSticker in document_attributes + else document_attributes[raw.types.DocumentAttributeCustomEmoji] + ) + file_name = getattr(document_attributes.get(raw.types.DocumentAttributeFilename, None), "file_name", None) + return types.File( + file_id=FileId( + file_type=FileType.STICKER, + dc_id=sticker.dc_id, + media_id=sticker.id, + access_hash=sticker.access_hash, + file_reference=sticker.file_reference + ).encode(), + file_unique_id=FileUniqueId( + file_unique_type=FileUniqueType.DOCUMENT, + media_id=sticker.id + ).encode(), + file_name=file_name, + file_size=sticker.size, + ) diff --git a/pyrogram/types/messages_and_media/__init__.py b/pyrogram/types/messages_and_media/__init__.py index 8f4a2eb5df..2aaec56444 100644 --- a/pyrogram/types/messages_and_media/__init__.py +++ b/pyrogram/types/messages_and_media/__init__.py @@ -24,6 +24,7 @@ from .dice import Dice from .direct_messages_topic import DirectMessagesTopic from .document import Document +from .file import File from .game import Game from .location import Location from .message import Message @@ -87,6 +88,7 @@ "ContactRegistered", "Dice", "Document", + "File", "Game", "PaymentForm", "GiftCode", diff --git a/pyrogram/types/messages_and_media/file.py b/pyrogram/types/messages_and_media/file.py new file mode 100644 index 0000000000..7f0e73ced5 --- /dev/null +++ b/pyrogram/types/messages_and_media/file.py @@ -0,0 +1,57 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present +# +# This file is part of Pyrogram. +# +# Pyrogram is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrogram 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 General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . + + +import pyrogram +from ..object import Object + + +class File(Object): + """a file. + + Parameters: + file_id (``str``): + Identifier for this file, which can be used to download or reuse the file. + + file_unique_id (``str``): + Unique identifier for this file, which is supposed to be the same over time and for different accounts. + Can't be used to download or reuse the file. + + file_name (``str``, *optional*): + file name. + + file_size (``int``, *optional*): + File size. + + """ + + def __init__( + self, + *, + client: "pyrogram.Client" = None, + file_id: str, + file_unique_id: str, + file_name: str = None, + file_size: int = None, + ): + super().__init__(client) + + self.file_id = file_id + self.file_unique_id = file_unique_id + self.file_name = file_name + self.file_size = file_size diff --git a/pyrogram/types/messages_and_media/sticker.py b/pyrogram/types/messages_and_media/sticker.py index 1e9f641a62..498d8442e9 100644 --- a/pyrogram/types/messages_and_media/sticker.py +++ b/pyrogram/types/messages_and_media/sticker.py @@ -37,6 +37,7 @@ class Sticker(Object): Unique identifier for this file, which is supposed to be the same over time and for different accounts. Can't be used to download or reuse the file. + width (``int``): Sticker width. @@ -49,26 +50,28 @@ class Sticker(Object): is_video (``bool``): True, if the sticker is a video sticker + thumbs (List of :obj:`~pyrogram.types.Thumbnail`, *optional*): + Sticker thumbnails in the .webp or .jpg format. + + emoji (``str``, *optional*): + Emoji associated with the sticker. + + set_name (``str``, *optional*): + Name of the sticker set to which the sticker belongs. + + + file_size (``int``, *optional*): + File size in bytes. + file_name (``str``, *optional*): Sticker file name. mime_type (``str``, *optional*): MIME type of the file as defined by sender. - file_size (``int``, *optional*): - File size. - date (:py:obj:`~datetime.datetime`, *optional*): Date the sticker was sent. - emoji (``str``, *optional*): - Emoji associated with the sticker. - - set_name (``str``, *optional*): - Name of the sticker set to which the sticker belongs. - - thumbs (List of :obj:`~pyrogram.types.Thumbnail`, *optional*): - Sticker thumbnails in the .webp or .jpg format. """ # TODO: Add mask position @@ -111,7 +114,7 @@ def __init__( cache = {} @staticmethod - async def _get_sticker_set_name(invoke, input_sticker_set_id): + async def _get_sticker_set_name(client, input_sticker_set_id): try: set_id = input_sticker_set_id[0] set_access_hash = input_sticker_set_id[1] @@ -121,17 +124,24 @@ async def _get_sticker_set_name(invoke, input_sticker_set_id): if name is not None: return name - name = ( - await invoke( - raw.functions.messages.GetStickerSet( - stickerset=raw.types.InputStickerSetID( - id=set_id, - access_hash=set_access_hash - ), - hash=0 - ) + # _, _sticker_set = await client._get_raw_stickers( + # raw.types.InputStickerSetID( + # id=set_id, + # access_hash=set_access_hash + # ) + # ) + # name = _sticker_set.short_name + # TODO: FIXME! + sticker_set = await client.invoke( + raw.functions.messages.GetStickerSet( + stickerset=raw.types.InputStickerSetID( + id=set_id, + access_hash=set_access_hash + ), + hash=0 ) - ).set.short_name + ) + name = sticker_set.set.short_name Sticker.cache[(set_id, set_access_hash)] = name @@ -164,7 +174,14 @@ async def _parse( if isinstance(sticker_set, raw.types.InputStickerSetID): input_sticker_set_id = (sticker_set.id, sticker_set.access_hash) # TODO: FIXME! - set_name = await Sticker._get_sticker_set_name(client.invoke, input_sticker_set_id) + # _, _sticker_set = await client._get_raw_stickers( + # raw.types.InputStickerSetID( + # id=input_sticker_set_id[0], + # access_hash=input_sticker_set_id[1] + # ) + # ) + # set_name = _sticker_set.short_name + set_name = await Sticker._get_sticker_set_name(client, input_sticker_set_id) else: set_name = None