def download_media( self, message: Union["pyrogram.Message", str], file_name: str = "", block: bool = True, progress: callable = None, progress_args: tuple = ()) -> Union[str, None]: """Use this method to download the media from a Message. Args: message (:obj:`Message <pyrogram.Message>` | ``str``): Pass a Message containing the media, the media itself (message.audio, message.video, ...) or the file id as string. file_name (``str``, *optional*): A custom *file_name* to be used instead of the one provided by Telegram. By default, all files are downloaded in the *downloads* folder in your working directory. You can also specify a path for downloading files in a custom location: paths that end with "/" are considered directories. All non-existent folders will be created automatically. block (``bool``, *optional*): Blocks the code execution until the file has been downloaded. Defaults to True. progress (``callable``): Pass a callback function to view the download progress. The function must take *(client, current, total, \*args)* as positional arguments (look at the section below for a detailed description). progress_args (``tuple``): Extra custom arguments for the progress callback function. Useful, for example, if you want to pass a chat_id and a message_id in order to edit a message with the updated progress. Other Parameters: client (:obj:`Client <pyrogram.Client>`): The Client itself, useful when you want to call other API methods inside the callback function. current (``int``): The amount of bytes downloaded so far. total (``int``): The size of the file. *args (``tuple``, *optional*): Extra custom arguments as defined in the *progress_args* parameter. You can either keep *\*args* or add every single extra argument in your function signature. Returns: On success, the absolute path of the downloaded file as string is returned, None otherwise. In case the download is deliberately stopped with :meth:`stop_transmission`, None is returned as well. Raises: :class:`Error <pyrogram.Error>` in case of a Telegram RPC error. ``ValueError`` if the message doesn't contain any downloadable media """ error_message = "This message doesn't contain any downloadable media" if isinstance(message, pyrogram.Message): if message.photo: media = pyrogram.Document( file_id=message.photo.sizes[-1].file_id, file_size=message.photo.sizes[-1].file_size, mime_type="", date=message.photo.date, client=self) elif message.audio: media = message.audio elif message.document: media = message.document elif message.video: media = message.video elif message.voice: media = message.voice elif message.video_note: media = message.video_note elif message.sticker: media = message.sticker elif message.animation: media = message.animation else: raise ValueError(error_message) elif isinstance( message, (pyrogram.Photo, pyrogram.PhotoSize, pyrogram.Audio, pyrogram.Document, pyrogram.Video, pyrogram.Voice, pyrogram.VideoNote, pyrogram.Sticker, pyrogram.Animation)): if isinstance(message, pyrogram.Photo): media = pyrogram.Document( file_id=message.sizes[-1].file_id, file_size=message.sizes[-1].file_size, mime_type="", date=message.date, client=self) else: media = message elif isinstance(message, str): media = pyrogram.Document(file_id=message, file_size=0, mime_type="", client=self) else: raise ValueError(error_message) done = Event() path = [None] self.download_queue.put( (media, file_name, done, progress, progress_args, path)) if block: done.wait() return path[0]
def parse_message(client, message: types.Message, users: dict, chats: dict, replies: int = 1) -> pyrogram.Message: entities = parse_entities(message.entities, users) forward_from = None forward_from_chat = None forward_from_message_id = None forward_signature = None forward_date = None forward_header = message.fwd_from # type: types.MessageFwdHeader if forward_header: forward_date = forward_header.date if forward_header.from_id: forward_from = parse_user(users[forward_header.from_id]) else: forward_from_chat = parse_channel_chat( chats[forward_header.channel_id]) forward_from_message_id = forward_header.channel_post forward_signature = forward_header.post_author photo = None location = None contact = None venue = None audio = None voice = None video = None video_note = None sticker = None document = None media = message.media if media: if isinstance(media, types.MessageMediaPhoto): photo = media.photo if isinstance(photo, types.Photo): sizes = photo.sizes photo_sizes = [] for size in sizes: if isinstance(size, (types.PhotoSize, types.PhotoCachedSize)): loc = size.location if isinstance(size, types.PhotoSize): file_size = size.size else: file_size = len(size.bytes) if isinstance(loc, types.FileLocation): photo_size = pyrogram.PhotoSize( file_id=encode( pack("<iiqqqqi", 2, loc.dc_id, photo.id, photo.access_hash, loc.volume_id, loc.secret, loc.local_id)), width=size.w, height=size.h, file_size=file_size, date=photo.date) photo_sizes.append(photo_size) photo = photo_sizes elif isinstance(media, types.MessageMediaGeo): geo_point = media.geo if isinstance(geo_point, types.GeoPoint): location = pyrogram.Location(longitude=geo_point.long, latitude=geo_point.lat) elif isinstance(media, types.MessageMediaContact): contact = pyrogram.Contact(phone_number=media.phone_number, first_name=media.first_name, last_name=media.last_name or None, user_id=media.user_id or None) elif isinstance(media, types.MessageMediaVenue): venue = pyrogram.Venue(location=pyrogram.Location( longitude=media.geo.long, latitude=media.geo.lat), title=media.title, address=media.address, foursquare_id=media.venue_id or None) elif isinstance(media, types.MessageMediaDocument): doc = media.document if isinstance(doc, types.Document): attributes = {type(i): i for i in doc.attributes} file_name = getattr( attributes.get(types.DocumentAttributeFilename, None), "file_name", None) if types.DocumentAttributeAudio in attributes: audio_attributes = attributes[types.DocumentAttributeAudio] if audio_attributes.voice: voice = pyrogram.Voice( file_id=encode( pack("<iiqq", 3, doc.dc_id, doc.id, doc.access_hash)), duration=audio_attributes.duration, mime_type=doc.mime_type, file_size=doc.size, thumb=parse_thumb(doc.thumb), file_name=file_name, date=doc.date) else: audio = pyrogram.Audio( file_id=encode( pack("<iiqq", 9, doc.dc_id, doc.id, doc.access_hash)), duration=audio_attributes.duration, performer=audio_attributes.performer, title=audio_attributes.title, mime_type=doc.mime_type, file_size=doc.size, thumb=parse_thumb(doc.thumb), file_name=file_name, date=doc.date) elif types.DocumentAttributeAnimated in attributes: document = pyrogram.Document(file_id=encode( pack("<iiqq", 10, doc.dc_id, doc.id, doc.access_hash)), thumb=parse_thumb(doc.thumb), file_name=file_name, mime_type=doc.mime_type, file_size=doc.size, date=doc.date) elif types.DocumentAttributeVideo in attributes: video_attributes = attributes[types.DocumentAttributeVideo] if video_attributes.round_message: video_note = pyrogram.VideoNote( file_id=encode( pack("<iiqq", 13, doc.dc_id, doc.id, doc.access_hash)), length=video_attributes.w, duration=video_attributes.duration, thumb=parse_thumb(doc.thumb), file_size=doc.size, file_name=file_name, mime_type=doc.mime_type, date=doc.date) else: video = pyrogram.Video( file_id=encode( pack("<iiqq", 4, doc.dc_id, doc.id, doc.access_hash)), width=video_attributes.w, height=video_attributes.h, duration=video_attributes.duration, thumb=parse_thumb(doc.thumb), mime_type=doc.mime_type, file_size=doc.size, file_name=file_name, date=doc.date) elif types.DocumentAttributeSticker in attributes: image_size_attributes = attributes[ types.DocumentAttributeImageSize] sticker_attribute = attributes[ types.DocumentAttributeSticker] if isinstance(sticker_attribute.stickerset, types.InputStickerSetID): try: set_name = client.send( functions.messages.GetStickerSet( sticker_attribute.stickerset) ).set.short_name except StickersetInvalid: set_name = None else: set_name = None sticker = pyrogram.Sticker( file_id=encode( pack("<iiqq", 8, doc.dc_id, doc.id, doc.access_hash)), width=image_size_attributes.w, height=image_size_attributes.h, thumb=parse_thumb(doc.thumb), # TODO: mask_position set_name=set_name, emoji=sticker_attribute.alt or None, file_size=doc.size, mime_type=doc.mime_type, file_name=file_name, date=doc.date) else: document = pyrogram.Document(file_id=encode( pack("<iiqq", 5, doc.dc_id, doc.id, doc.access_hash)), thumb=parse_thumb(doc.thumb), file_name=file_name, mime_type=doc.mime_type, file_size=doc.size, date=doc.date) else: media = None m = pyrogram.Message( message_id=message.id, date=message.date, chat=parse_chat(message, users, chats), from_user=parse_user(users.get(message.from_id, None)), text=message.message or None if media is None else None, caption=message.message or None if media is not None else None, entities=entities or None if media is None else None, caption_entities=entities or None if media is not None else None, author_signature=message.post_author, forward_from=forward_from, forward_from_chat=forward_from_chat, forward_from_message_id=forward_from_message_id, forward_signature=forward_signature, forward_date=forward_date, edit_date=message.edit_date, media_group_id=message.grouped_id, photo=photo, location=location, contact=contact, venue=venue, audio=audio, voice=voice, video=video, video_note=video_note, sticker=sticker, document=document, views=message.views, via_bot=parse_user(users.get(message.via_bot_id, None))) if message.reply_to_msg_id and replies: m.reply_to_message = client.get_messages(m.chat.id, message.reply_to_msg_id) m.reply_to_message = m.reply_to_message return m