Source code for pyrogram.types.input_content.input_sticker

#  Pyrogram - Telegram MTProto API Client Library for Python
#  Copyright (C) 2017-present Dan <https://github.com/delivrance>
#
#  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 <http://www.gnu.org/licenses/>.

import asyncio
import io
import os
import re
import urllib.request
from typing import BinaryIO, Callable, List, Optional, Union

import pyrogram
from pyrogram import enums, raw, types, utils
from pyrogram.file_id import FileType
from ..object import Object

MAX_DOWNLOAD_SIZE = 10 * 1024 * 1024


[docs] class InputSticker(Object): """A sticker to be added to a sticker set. Parameters: sticker (``str`` | ``BinaryIO``): The added sticker. Pass a file_id as string to use a file that exists on the Telegram servers, pass an HTTP URL as string to download the file and upload it, pass a file path as string to upload a new file that exists on your local machine or pass a binary file-like object with its attribute ".name" set for in-memory uploads. format (:obj:`~pyrogram.enums.StickerFormat`): Format of the added sticker. emoji_list (List of ``str``): List of 1-20 emoji associated with the sticker. mask_position (:obj:`~pyrogram.types.MaskPosition`, *optional*): Position where the mask should be placed on faces. For mask stickers only. keywords (List of ``str``, *optional*): List of 0-20 search keywords for the sticker with total length of up to 64 characters. For regular and custom emoji stickers only. """ def __init__( self, sticker: Union[str, BinaryIO], format: "enums.StickerFormat", emoji_list: List[str], mask_position: Optional["types.MaskPosition"] = None, keywords: Optional[List[str]] = None ): super().__init__() self.sticker = sticker self.format = format self.emoji_list = emoji_list self.mask_position = mask_position self.keywords = keywords async def _upload( self, client: "pyrogram.Client", chat_id: Optional[Union[int, str]] = None, progress: Optional[Callable] = None, progress_args: tuple = () ) -> "raw.types.Document": if self.format == enums.StickerFormat.ANIMATED: file_name, mime_type = "sticker.tgs", "application/x-tgsticker" elif self.format == enums.StickerFormat.VIDEO: file_name, mime_type = "sticker.webm", "video/webm" else: file_name, mime_type = "sticker.png", "image/png" sticker = self.sticker if self._is_url(): sticker = io.BytesIO(await asyncio.to_thread(self._download, sticker)) sticker.name = file_name r = await client.invoke( raw.functions.messages.UploadMedia( peer=await client.resolve_peer(chat_id) if chat_id is not None else raw.types.InputPeerSelf(), media=raw.types.InputMediaUploadedDocument( mime_type=mime_type, file=await client.save_file(sticker, progress=progress, progress_args=progress_args), attributes=[ raw.types.DocumentAttributeFilename(file_name=file_name), raw.types.DocumentAttributeSticker( alt="".join(self.emoji_list), stickerset=raw.types.InputStickerSetEmpty(), mask=self.mask_position is not None, mask_coords=self.mask_position.write() if self.mask_position else None ) ] ) ) ) return r.document def _is_url(self) -> bool: return isinstance(self.sticker, str) and re.match("^https?://", self.sticker) is not None @staticmethod def _download(url: str) -> bytes: request = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"}) with urllib.request.urlopen(request, timeout=30) as response: data = response.read(MAX_DOWNLOAD_SIZE + 1) if len(data) > MAX_DOWNLOAD_SIZE: raise ValueError(f"The sticker at {url} is larger than {MAX_DOWNLOAD_SIZE} bytes") return data def _is_upload(self) -> bool: return not isinstance(self.sticker, str) or self._is_url() or os.path.isfile(self.sticker) async def write( self, client: "pyrogram.Client", chat_id: Optional[Union[int, str]] = None, progress: Optional[Callable] = None, progress_args: tuple = () ) -> "raw.types.InputStickerSetItem": if self._is_upload(): document = await self._upload(client, chat_id, progress, progress_args) input_document = raw.types.InputDocument( id=document.id, access_hash=document.access_hash, file_reference=document.file_reference ) else: input_document = utils.get_input_media_from_file_id(self.sticker, FileType.STICKER).id return raw.types.InputStickerSetItem( document=input_document, emoji="".join(self.emoji_list), mask_coords=self.mask_position.write() if self.mask_position else None, keywords=",".join(self.keywords) if self.keywords else None )