示例#1
0
    def _parse(client, chat_photo: Union["raw.types.UserProfilePhoto",
                                         "raw.types.ChatPhoto"], peer_id: int,
               peer_access_hash: int):
        if not isinstance(chat_photo,
                          (raw.types.UserProfilePhoto, raw.types.ChatPhoto)):
            return None

        return ChatPhoto(small_file_id=FileId(
            file_type=FileType.CHAT_PHOTO,
            dc_id=chat_photo.dc_id,
            media_id=chat_photo.photo_id,
            access_hash=0,
            volume_id=0,
            thumbnail_source=ThumbnailSource.CHAT_PHOTO_SMALL,
            local_id=0,
            chat_id=peer_id,
            chat_access_hash=peer_access_hash).encode(),
                         small_photo_unique_id=FileUniqueId(
                             file_unique_type=FileUniqueType.DOCUMENT,
                             media_id=chat_photo.photo_id).encode(),
                         big_file_id=FileId(
                             file_type=FileType.CHAT_PHOTO,
                             dc_id=chat_photo.dc_id,
                             media_id=chat_photo.photo_id,
                             access_hash=0,
                             volume_id=0,
                             thumbnail_source=ThumbnailSource.CHAT_PHOTO_BIG,
                             local_id=0,
                             chat_id=peer_id,
                             chat_access_hash=peer_access_hash).encode(),
                         big_photo_unique_id=FileUniqueId(
                             file_unique_type=FileUniqueType.DOCUMENT,
                             media_id=chat_photo.photo_id).encode(),
                         client=client)
示例#2
0
    async def generate_file_properties(msg: Message):
        error_message = "This message doesn't contain any downloadable media"
        available_media = ("audio", "document", "photo", "sticker", "animation", "video", "voice", "video_note")

        if isinstance(msg, Message):
            for kind in available_media:
                media = getattr(msg, kind, None)

                if media is not None:
                    break
            else:
                raise ValueError(error_message)
        else:
            media = msg

        if isinstance(media, str):
            file_id_str = media
        else:
            file_id_str = media.file_id

        file_id_obj = FileId.decode(file_id_str)

        # The below lines are added to avoid a break in routes.py
        setattr(file_id_obj, "file_size", getattr(media, "file_size", 0))
        setattr(file_id_obj, "mime_type", getattr(media, "mime_type", ""))
        setattr(file_id_obj, "file_name", getattr(media, "file_name", ""))

        return file_id_obj
示例#3
0
 def _parse(client,
            video: "raw.types.Document",
            video_attributes: "raw.types.DocumentAttributeVideo",
            file_name: str,
            ttl_seconds: int = None) -> "Video":
     return Video(file_id=FileId(
         file_type=FileType.VIDEO,
         dc_id=video.dc_id,
         media_id=video.id,
         access_hash=video.access_hash,
         file_reference=video.file_reference).encode(),
                  file_unique_id=FileUniqueId(
                      file_unique_type=FileUniqueType.DOCUMENT,
                      media_id=video.id).encode(),
                  width=video_attributes.w,
                  height=video_attributes.h,
                  duration=video_attributes.duration,
                  file_name=file_name,
                  mime_type=video.mime_type,
                  supports_streaming=video_attributes.supports_streaming,
                  file_size=video.size,
                  date=utils.timestamp_to_datetime(video.date),
                  ttl_seconds=ttl_seconds,
                  thumbs=types.Thumbnail._parse(client, video),
                  client=client)
示例#4
0
文件: files.py 项目: edguru/rexoma
async def get_document_from_file_id(file_id: str) -> raw.base.InputDocument:
    decoded = FileId.decode(file_id)
    return raw.types.InputDocument(
        id=decoded.media_id,
        access_hash=decoded.access_hash,
        file_reference=decoded.file_reference,
    )
示例#5
0
 def _parse(
     client,
     video_note: "raw.types.Document",
     video_attributes: "raw.types.DocumentAttributeVideo"
 ) -> "VideoNote":
     return VideoNote(
         file_id=FileId(
             file_type=FileType.VIDEO_NOTE,
             dc_id=video_note.dc_id,
             media_id=video_note.id,
             access_hash=video_note.access_hash,
             file_reference=video_note.file_reference
         ).encode(),
         file_unique_id=FileUniqueId(
             file_unique_type=FileUniqueType.DOCUMENT,
             media_id=video_note.id
         ).encode(),
         length=video_attributes.w,
         duration=video_attributes.duration,
         file_size=video_note.size,
         mime_type=video_note.mime_type,
         date=utils.timestamp_to_datetime(video_note.date),
         thumbs=types.Thumbnail._parse(client, video_note),
         client=client
     )
def get_input_file_from_file_id(
    file_id: str,
    expected_file_type: FileType = None
) -> Union["raw.types.InputPhoto", "raw.types.InputDocument"]:
    try:
        decoded = FileId.decode(file_id)
    except Exception:
        raise ValueError(f'Failed to decode "{file_id}". The value does not represent an existing local file, '
                         f'HTTP URL, or valid file id.')

    file_type = decoded.file_type

    if expected_file_type is not None and file_type != expected_file_type:
        raise ValueError(f'Expected: "{expected_file_type}", got "{file_type}" file_id instead')

    if file_type in (FileType.THUMBNAIL, FileType.CHAT_PHOTO):
        raise ValueError(f"This file_id can only be used for download: {file_id}")

    if file_type in PHOTO_TYPES:
        return raw.types.InputPhoto(
            id=decoded.media_id,
            access_hash=decoded.access_hash,
            file_reference=decoded.file_reference
        )

    if file_type in DOCUMENT_TYPES:
        return raw.types.InputDocument(
            id=decoded.media_id,
            access_hash=decoded.access_hash,
            file_reference=decoded.file_reference
        )

    raise ValueError(f"Unknown file id: {file_id}")
示例#7
0
def test_stringify_file_id():
    file_id = "BQACAgIAAx0CAAGgr9AAAgmPX7b4UxbjNoFEO_L0I4s6wrXNJA8AAgQAA4GkuUm9FFvIaOhXWR4E"
    string = "{'major': 4, 'minor': 30, 'file_type': <FileType.DOCUMENT: 5>, 'dc_id': 2, " \
             "'file_reference': b'\\x02\\x00\\xa0\\xaf\\xd0\\x00\\x00\\t\\x8f_\\xb6\\xf8S\\x16\\xe36\\x81D;\\xf2\\xf4#\\x8b:\\xc2\\xb5\\xcd$\\x0f', " \
             "'media_id': 5312458109417947140, 'access_hash': 6437869729085068477, 'thumbnail_size': ''}"

    assert str(FileId.decode(file_id)) == string
示例#8
0
 def _parse(
     client,
     audio: "raw.types.Document",
     audio_attributes: "raw.types.DocumentAttributeAudio",
     file_name: str
 ) -> "Audio":
     return Audio(
         file_id=FileId(
             file_type=FileType.AUDIO,
             dc_id=audio.dc_id,
             media_id=audio.id,
             access_hash=audio.access_hash,
             file_reference=audio.file_reference
         ).encode(),
         file_unique_id=FileUniqueId(
             file_unique_type=FileUniqueType.DOCUMENT,
             media_id=audio.id
         ).encode(),
         duration=audio_attributes.duration,
         performer=audio_attributes.performer,
         title=audio_attributes.title,
         mime_type=audio.mime_type,
         file_size=audio.size,
         file_name=file_name,
         date=audio.date,
         thumbs=types.Thumbnail._parse(client, audio),
         client=client
     )
示例#9
0
    async def _parse(
            client, sticker: "raw.types.Document",
            image_size_attributes: "raw.types.DocumentAttributeImageSize",
            sticker_attributes: "raw.types.DocumentAttributeSticker",
            file_name: str) -> "Sticker":
        sticker_set = sticker_attributes.stickerset

        if isinstance(sticker_set, raw.types.InputStickerSetID):
            input_sticker_set_id = (sticker_set.id, sticker_set.access_hash)
            set_name = await Sticker._get_sticker_set_name(
                client.send, input_sticker_set_id)
        else:
            set_name = None

        return Sticker(
            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(),
            width=image_size_attributes.w if image_size_attributes else 512,
            height=image_size_attributes.h if image_size_attributes else 512,
            is_animated=sticker.mime_type == "application/x-tgsticker",
            # TODO: mask_position
            set_name=set_name,
            emoji=sticker_attributes.alt or None,
            file_size=sticker.size,
            mime_type=sticker.mime_type,
            file_name=file_name,
            date=sticker.date,
            thumbs=types.Thumbnail._parse(client, sticker),
            client=client)
示例#10
0
def unpack_new_file_id(new_file_id):
    """Return file_id, file_ref"""
    decoded = FileId.decode(new_file_id)
    file_id = encode_file_id(
        pack("<iiqq", int(decoded.file_type), decoded.dc_id, decoded.media_id,
             decoded.access_hash))
    file_ref = encode_file_ref(decoded.file_reference)
    return file_id, file_ref
示例#11
0
    def _parse(
        client, media: Union["raw.types.Photo", "raw.types.Document"]
    ) -> Union[List[Union["types.StrippedThumbnail", "Thumbnail"]], None]:
        if isinstance(media, raw.types.Photo):
            raw_thumbnails = media.sizes[:-1]
        elif isinstance(media, raw.types.Document):
            raw_thumbnails = media.thumbs

            if not raw_thumbnails:
                return None
        else:
            return None

        thumbnails = []

        file_type = FileType.PHOTO if isinstance(
            media, raw.types.Photo) else FileType.THUMBNAIL
        thumbnail_file_type = file_type

        for thumbnail in raw_thumbnails:
            # TODO: Enable this
            # if isinstance(thumbnail, types.PhotoStrippedSize):
            #     thumbnails.append(StrippedThumbnail._parse(client, thumbnail))
            if isinstance(thumbnail, raw.types.PhotoSize):
                thumbnails.append(
                    Thumbnail(
                        file_id=FileId(
                            file_type=file_type,
                            dc_id=media.dc_id,
                            media_id=media.id,
                            access_hash=media.access_hash,
                            file_reference=media.file_reference,
                            thumbnail_file_type=thumbnail_file_type,
                            thumbnail_source=ThumbnailSource.THUMBNAIL,
                            thumbnail_size=thumbnail.type,
                            volume_id=thumbnail.location.volume_id,
                            local_id=thumbnail.location.local_id).encode(),
                        file_unique_id=FileUniqueId(
                            file_unique_type=FileUniqueType.PHOTO,
                            media_id=media.id,
                            volume_id=thumbnail.location.volume_id,
                            local_id=thumbnail.location.local_id).encode(),
                        width=thumbnail.w,
                        height=thumbnail.h,
                        file_size=thumbnail.size,
                        client=client))

        return thumbnails or None
示例#12
0
    def _parse(client,
               photo: "raw.types.Photo",
               ttl_seconds: int = None) -> "Photo":
        if isinstance(photo, raw.types.Photo):
            try:
                progressive = next(
                    p for p in photo.sizes
                    if isinstance(p, raw.types.PhotoSizeProgressive))
            except StopIteration:
                photo_size_objs = [
                    p for p in photo.sizes
                    if isinstance(p, raw.types.PhotoSize)
                ]
                photo_size_objs.sort(key=lambda p: p.size)

                big = photo_size_objs[-1]
            else:
                big = raw.types.PhotoSize(type=progressive.type,
                                          location=progressive.location,
                                          w=progressive.w,
                                          h=progressive.h,
                                          size=sorted(progressive.sizes)[-1])

            return Photo(file_id=FileId(
                file_type=FileType.PHOTO,
                dc_id=photo.dc_id,
                media_id=photo.id,
                access_hash=photo.access_hash,
                file_reference=photo.file_reference,
                thumbnail_source=ThumbnailSource.THUMBNAIL,
                thumbnail_file_type=FileType.PHOTO,
                thumbnail_size=big.type,
                volume_id=big.location.volume_id,
                local_id=big.location.local_id).encode(),
                         file_unique_id=FileUniqueId(
                             file_unique_type=FileUniqueType.PHOTO,
                             media_id=photo.id,
                             volume_id=big.location.volume_id,
                             local_id=big.location.local_id).encode(),
                         width=big.w,
                         height=big.h,
                         file_size=big.size,
                         date=photo.date,
                         ttl_seconds=ttl_seconds,
                         thumbs=types.Thumbnail._parse(client, photo),
                         client=client)
示例#13
0
 def _parse(client, document: "raw.types.Document",
            file_name: str) -> "Document":
     return Document(file_id=FileId(
         file_type=FileType.DOCUMENT,
         dc_id=document.dc_id,
         media_id=document.id,
         access_hash=document.access_hash,
         file_reference=document.file_reference).encode(),
                     file_unique_id=FileUniqueId(
                         file_unique_type=FileUniqueType.DOCUMENT,
                         media_id=document.id).encode(),
                     file_name=file_name,
                     mime_type=document.mime_type,
                     file_size=document.size,
                     date=utils.timestamp_to_datetime(document.date),
                     thumbs=types.Thumbnail._parse(client, document),
                     client=client)
示例#14
0
 def _parse(client, voice: "raw.types.Document",
            attributes: "raw.types.DocumentAttributeAudio") -> "Voice":
     return Voice(file_id=FileId(
         file_type=FileType.VOICE,
         dc_id=voice.dc_id,
         media_id=voice.id,
         access_hash=voice.access_hash,
         file_reference=voice.file_reference).encode(),
                  file_unique_id=FileUniqueId(
                      file_unique_type=FileUniqueType.DOCUMENT,
                      media_id=voice.id).encode(),
                  duration=attributes.duration,
                  mime_type=voice.mime_type,
                  file_size=voice.size,
                  waveform=attributes.waveform,
                  date=voice.date,
                  client=client)
示例#15
0
    def _parse(
        client, media: Union["raw.types.Photo", "raw.types.Document"]
    ) -> Optional[List["Thumbnail"]]:
        if isinstance(media, raw.types.Photo):
            raw_thumbs = [
                i for i in media.sizes if isinstance(i, raw.types.PhotoSize)
            ]
            raw_thumbs.sort(key=lambda p: p.size)
            raw_thumbs = raw_thumbs[:-1]

            file_type = FileType.PHOTO
        elif isinstance(media, raw.types.Document):
            raw_thumbs = media.thumbs
            file_type = FileType.THUMBNAIL
        else:
            return

        parsed_thumbs = []

        for thumb in raw_thumbs:
            if not isinstance(thumb, raw.types.PhotoSize):
                continue

            parsed_thumbs.append(
                Thumbnail(file_id=FileId(
                    file_type=file_type,
                    dc_id=media.dc_id,
                    media_id=media.id,
                    access_hash=media.access_hash,
                    file_reference=media.file_reference,
                    thumbnail_file_type=file_type,
                    thumbnail_source=ThumbnailSource.THUMBNAIL,
                    thumbnail_size=thumb.type,
                    volume_id=0,
                    local_id=0).encode(),
                          file_unique_id=FileUniqueId(
                              file_unique_type=FileUniqueType.DOCUMENT,
                              media_id=media.id).encode(),
                          width=thumb.w,
                          height=thumb.h,
                          file_size=thumb.size,
                          client=client))

        return parsed_thumbs or None
示例#16
0
    def _parse(client,
               photo: "raw.types.Photo",
               ttl_seconds: int = None) -> "Photo":
        if isinstance(photo, raw.types.Photo):
            photos: List[raw.types.PhotoSize] = []

            for p in photo.sizes:
                if isinstance(p, raw.types.PhotoSize):
                    photos.append(p)

                if isinstance(p, raw.types.PhotoSizeProgressive):
                    photos.append(
                        raw.types.PhotoSize(type=p.type,
                                            w=p.w,
                                            h=p.h,
                                            size=max(p.sizes)))

            photos.sort(key=lambda p: p.size)

            main = photos[-1]

            return Photo(file_id=FileId(
                file_type=FileType.PHOTO,
                dc_id=photo.dc_id,
                media_id=photo.id,
                access_hash=photo.access_hash,
                file_reference=photo.file_reference,
                thumbnail_source=ThumbnailSource.THUMBNAIL,
                thumbnail_file_type=FileType.PHOTO,
                thumbnail_size=main.type,
                volume_id=0,
                local_id=0).encode(),
                         file_unique_id=FileUniqueId(
                             file_unique_type=FileUniqueType.DOCUMENT,
                             media_id=photo.id).encode(),
                         width=main.w,
                         height=main.h,
                         file_size=main.size,
                         date=photo.date,
                         ttl_seconds=ttl_seconds,
                         thumbs=types.Thumbnail._parse(client, photo),
                         client=client)
示例#17
0
    def _parse(client,
               photo: "raw.types.Photo",
               ttl_seconds: int = None) -> Optional["Photo"]:
        if isinstance(photo, raw.types.Photo):
            big = photo.sizes[-1]

            if isinstance(
                    big,
                (raw.types.PhotoStrippedSize, raw.types.PhotoPathSize)):
                return None

            if isinstance(big, raw.types.PhotoSizeProgressive):
                big = raw.types.PhotoSize(type=big.type,
                                          location=big.location,
                                          w=big.w,
                                          h=big.h,
                                          size=big.sizes[-1])

            return Photo(file_id=FileId(
                file_type=FileType.PHOTO,
                dc_id=photo.dc_id,
                media_id=photo.id,
                access_hash=photo.access_hash,
                file_reference=photo.file_reference,
                thumbnail_source=ThumbnailSource.THUMBNAIL,
                thumbnail_file_type=FileType.PHOTO,
                thumbnail_size=big.type,
                volume_id=big.location.volume_id,
                local_id=big.location.local_id).encode(),
                         file_unique_id=FileUniqueId(
                             file_unique_type=FileUniqueType.PHOTO,
                             media_id=photo.id,
                             volume_id=big.location.volume_id,
                             local_id=big.location.local_id).encode(),
                         width=big.w,
                         height=big.h,
                         file_size=big.size,
                         date=photo.date,
                         ttl_seconds=ttl_seconds,
                         thumbs=types.Thumbnail._parse(client, photo),
                         client=client)
示例#18
0
    async def pyro_dl(self, file_id):
        file_id_obj = FileId.decode(file_id)
        file_type = file_id_obj.file_type
        mime_type = ""
        date = 0
        file_name = ""

        directory, file_name = os.path.split(file_name)
        if not os.path.isabs(file_name):
            directory = self.client.PARENT_DIR / (directory
                                                  or DEFAULT_DOWNLOAD_DIR)
        if not file_name:
            guessed_extension = self.client.guess_extension(mime_type)

            if file_type in PHOTO_TYPES:
                extension = ".jpg"
            elif file_type == FileType.VOICE:
                extension = guessed_extension or ".ogg"
            elif file_type in (FileType.VIDEO, FileType.ANIMATION,
                               FileType.VIDEO_NOTE):
                extension = guessed_extension or ".mp4"
            elif file_type == FileType.DOCUMENT:
                extension = guessed_extension or ".zip"
            elif file_type == FileType.STICKER:
                extension = guessed_extension or ".webp"
            elif file_type == FileType.AUDIO:
                extension = guessed_extension or ".mp3"
            else:
                extension = ".unknown"

            file_name = "{}_{}_{}{}".format(
                FileType(file_id_obj.file_type).name.lower(),
                datetime.fromtimestamp(
                    date or time.time()).strftime("%Y-%m-%d_%H-%M-%S"),
                self.client.rnd_id(), extension)
        final_file_path = os.path.abspath(
            re.sub("\\\\", "/", os.path.join(directory, file_name)))
        os.makedirs(directory, exist_ok=True)
        downloaderr = self.handle_download(file_id_obj, final_file_path)
        asyncio.get_event_loop().create_task(downloaderr)
        return final_file_path
示例#19
0
 def _parse(client, animation: "raw.types.Document",
            video_attributes: "raw.types.DocumentAttributeVideo",
            file_name: str) -> "Animation":
     return Animation(file_id=FileId(
         file_type=FileType.ANIMATION,
         dc_id=animation.dc_id,
         media_id=animation.id,
         access_hash=animation.access_hash,
         file_reference=animation.file_reference).encode(),
                      file_unique_id=FileUniqueId(
                          file_unique_type=FileUniqueType.DOCUMENT,
                          media_id=animation.id).encode(),
                      width=getattr(video_attributes, "w", 0),
                      height=getattr(video_attributes, "h", 0),
                      duration=getattr(video_attributes, "duration", 0),
                      mime_type=animation.mime_type,
                      file_size=animation.size,
                      file_name=file_name,
                      date=animation.date,
                      thumbs=types.Thumbnail._parse(client, animation),
                      client=client)
示例#20
0
 def is_photo(file_id: str) -> bool:
     return bool(FileId.decode(file_id).file_type in PHOTO_TYPES)
示例#21
0
def check(file_id: str, expected_file_type: FileType):
    decoded = FileId.decode(file_id)

    assert decoded.file_type == expected_file_type
    assert decoded.encode() == file_id
示例#22
0
    async def stream_media(
        self,
        message: Union["types.Message", str],
        progress: callable = None,
        progress_args: tuple = ()
    ) -> Optional[AsyncGenerator]:
        """Stream the media from a message.

        Parameters:
            message (:obj:`~pyrogram.types.Message` | ``str``):
                Pass a Message containing the media, the media itself (message.audio, message.video, ...) or a file id
                as string.

            progress (``callable``, *optional*):
                Pass a callback function to view the file transmission progress.
                The function must take *(current, total)* as positional arguments (look at Other Parameters below for a
                detailed description) and will be called back each time a new file chunk has been successfully
                transmitted.

            progress_args (``tuple``, *optional*):
                Extra custom arguments for the progress callback function.
                You can pass anything you need to be available in the progress callback scope; for example, a Message
                object or a Client instance in order to edit the message with the updated progress status.

        Other Parameters:
            current (``int``):
                The amount of bytes transmitted so far.

            total (``int``):
                The total 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:
            ``async_generator``: In case the download failed or was deliberately stopped with :meth:`~pyrogram.Client.stop_transmission`, None is
            returned.

        Raises:
            ValueError: if the message doesn't contain any downloadable media

        Example:
            .. code-block:: python

                # Stream from Message
                media_streaming = app.stream_media(message)

                async for media_bytes in media_streaming:
                    print(f"New bytes received: {media_bytes}")

                # Stream from file id
                media_streaming = app.stream_media("CAADBAADzg4AAvLQYAEz_x2EOgdRwBYE")

                async for media_bytes in media_streaming:
                    print(f"New bytes received: {media_bytes}")

                # Keep track of the progress while downloading
                def progress(current, total):
                    print(f"{current * 100 / total:.1f}%")

                media_streaming = app.stream_media(message, progress=progress)

                async for media_bytes in media_streaming:
                    print(f"New bytes received: {media_bytes}")
        """
        available_media = ("audio", "document", "photo", "sticker",
                           "animation", "video", "voice", "video_note",
                           "new_chat_photo")

        if isinstance(message, types.Message):
            for kind in available_media:
                media = getattr(message, kind, None)

                if media is not None:
                    break
            else:
                raise ValueError(
                    "This message doesn't contain any downloadable media")
        else:
            media = message

        if isinstance(media, str):
            file_id_str = media
        else:
            file_id_str = media.file_id

        file_id_obj = FileId.decode(file_id_str)

        media_file_name = getattr(media, "file_name", "")
        file_size = getattr(media, "file_size", 0)

        return self.get_streaming_file(file_id_obj, file_size, progress,
                                       progress_args)
示例#23
0
    async def download_media(
        self,
        message: Union["types.Message", str],
        file_name: str = DEFAULT_DOWNLOAD_DIR,
        block: bool = True,
        progress: callable = None,
        progress_args: tuple = ()) -> Optional[str]:
        """Download the media from a message.

        Parameters:
            message (:obj:`~pyrogram.types.Message` | ``str``):
                Pass a Message containing the media, the media itself (message.audio, message.video, ...) or a 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``, *optional*):
                Pass a callback function to view the file transmission progress.
                The function must take *(current, total)* as positional arguments (look at Other Parameters below for a
                detailed description) and will be called back each time a new file chunk has been successfully
                transmitted.

            progress_args (``tuple``, *optional*):
                Extra custom arguments for the progress callback function.
                You can pass anything you need to be available in the progress callback scope; for example, a Message
                object or a Client instance in order to edit the message with the updated progress status.

        Other Parameters:
            current (``int``):
                The amount of bytes transmitted so far.

            total (``int``):
                The total 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:
            ``str`` | ``None``: On success, the absolute path of the downloaded file is returned, otherwise, in case
            the download failed or was deliberately stopped with :meth:`~pyrogram.Client.stop_transmission`, None is
            returned.

        Raises:
            ValueError: if the message doesn't contain any downloadable media

        Example:
            .. code-block:: python

                # Download from Message
                app.download_media(message)

                # Download from file id
                app.download_media("CAADBAADzg4AAvLQYAEz_x2EOgdRwBYE")

                # Keep track of the progress while downloading
                def progress(current, total):
                    print(f"{current * 100 / total:.1f}%")

                app.download_media(message, progress=progress)
        """
        available_media = ("audio", "document", "photo", "sticker",
                           "animation", "video", "voice", "video_note",
                           "new_chat_photo")

        if isinstance(message, types.Message):
            for kind in available_media:
                media = getattr(message, kind, None)

                if media is not None:
                    break
            else:
                raise ValueError(
                    "This message doesn't contain any downloadable media")
        else:
            media = message

        if isinstance(media, str):
            file_id_str = media
        else:
            file_id_str = media.file_id

        file_id_obj = FileId.decode(file_id_str)

        file_type = file_id_obj.file_type
        media_file_name = getattr(media, "file_name", "")
        file_size = getattr(media, "file_size", 0)
        mime_type = getattr(media, "mime_type", "")
        date = getattr(media, "date", 0)

        directory, file_name = os.path.split(file_name)
        file_name = file_name or media_file_name or ""

        if not os.path.isabs(file_name):
            directory = self.PARENT_DIR / (directory or DEFAULT_DOWNLOAD_DIR)

        if not file_name:
            guessed_extension = self.guess_extension(mime_type)

            if file_type in PHOTO_TYPES:
                extension = ".jpg"
            elif file_type == FileType.VOICE:
                extension = guessed_extension or ".ogg"
            elif file_type in (FileType.VIDEO, FileType.ANIMATION,
                               FileType.VIDEO_NOTE):
                extension = guessed_extension or ".mp4"
            elif file_type == FileType.DOCUMENT:
                extension = guessed_extension or ".zip"
            elif file_type == FileType.STICKER:
                extension = guessed_extension or ".webp"
            elif file_type == FileType.AUDIO:
                extension = guessed_extension or ".mp3"
            else:
                extension = ".unknown"

            file_name = "{}_{}_{}{}".format(
                FileType(file_id_obj.file_type).name.lower(),
                datetime.fromtimestamp(
                    date or time.time()).strftime("%Y-%m-%d_%H-%M-%S"),
                self.rnd_id(), extension)

        downloader = self.handle_download((file_id_obj, directory, file_name,
                                           file_size, progress, progress_args))

        if block:
            return await downloader
        else:
            asyncio.get_event_loop().create_task(downloader)
示例#24
0
async def inline_query_handler(c: Client, iq: InlineQuery):
    q = iq.query
    res = []
    if len(q.strip()) < 2:
        await iq.answer([])
        return
    if q.strip().startswith('dl:'):
        q_res_data = await BookdlFiles().get_file_by_name(
            q.split(':')[1].strip(), 50)
        if q_res_data:
            for file in q_res_data:
                file_id_obj = FileId.decode(file['file_id'])
                res.append(
                    InputBotInlineResultDocument(
                        id=str(file['_id']),
                        type='file',
                        document=InputDocument(
                            id=file_id_obj.media_id,
                            access_hash=file_id_obj.access_hash,
                            file_reference=file_id_obj.file_reference),
                        send_message=InputBotInlineMessageMediaAuto(
                            message=file['title']),
                        title=file['title'],
                        description=f"File Name: {file['file_name']}\n"
                        f"File Type: {file['file_type']}",
                    ))

            await BookDLBot.invoke(data=SetInlineBotResults(
                query_id=int(iq.id), results=res, cache_time=0))
        else:
            await iq.answer([])
        return
    else:
        if q.strip():
            result = await Libgen(result_limit=50
                                  ).search(query=q.strip(),
                                           return_fields=[
                                               'title', 'pages', 'language',
                                               'publisher', 'year', 'author',
                                               'extension', 'coverurl',
                                               'volumeinfo', 'mirrors', 'md5'
                                           ])
            if result is not None:
                for item in result:
                    res.append(
                        InlineQueryResultArticle(
                            title=result[item]['title'],
                            description=f"Author: {result[item]['author']}\n"
                            f"Volume: {result[item]['volumeinfo']}   Year: {result[item]['year']}  Pages: {result[item]['pages']}\n"
                            f"Language: {result[item]['language']}  Extension: {result[item]['extension']}\n"
                            f"Publisher: {result[item]['publisher']}\n",
                            thumb_url="https://cdn3.iconfinder.com/data/icons/"
                            "education-vol-1-34/512/15_File_files_office-256.png"
                            if result[item]['coverurl'] is None else
                            result[item]['coverurl'],
                            input_message_content=InputTextMessageContent(
                                message_text=f"MD5: {result[item]['md5']}\n"
                                f"Title: **{result[item]['title']}**\n"
                                f"Author: **{result[item]['author']}**"),
                            reply_markup=None))

    if res:
        await iq.answer(results=res, cache_time=60, is_personal=False)
    else:
        await iq.answer(
            results=[],
            cache_time=7,
            switch_pm_text=f'{emoji.CROSS_MARK} No results for "{q}"',
            switch_pm_parameter="okay",
        )
示例#25
0
async def parse_file_id(message: "Message") -> Optional[FileId]:
    media = get_media_from_message(message)
    if media:
        return FileId.decode(media.file_id)
示例#26
0
    async def stream_media(self: "pyrogram.Client",
                           message: Union["types.Message", str],
                           limit: int = 0,
                           offset: int = 0) -> Optional[Union[str, BinaryIO]]:
        """Stream the media from a message chunk by chunk.

        You can use this method to partially download a file into memory or to selectively download chunks of file.
        The chunk maximum size is 1 MiB (1024 * 1024 bytes).

        Parameters:
            message (:obj:`~pyrogram.types.Message` | ``str``):
                Pass a Message containing the media, the media itself (message.audio, message.video, ...) or a file id
                as string.

            limit (``int``, *optional*):
                Limit the amount of chunks to stream.
                Defaults to 0 (stream the whole media).

            offset (``int``, *optional*):
                How many chunks to skip before starting to stream.
                Defaults to 0 (start from the beginning).

        Returns:
            ``Generator``: A generator yielding bytes chunk by chunk

        Example:
            .. code-block:: python

                # Stream the whole media
                async for chunk in app.stream_media(message):
                    print(len(chunk))

                # Stream the first 3 chunks only
                async for chunk in app.stream_media(message, limit=3):
                    print(len(chunk))

                # Stream the rest of the media by skipping the first 3 chunks
                async for chunk in app.stream_media(message, offset=3):
                    print(len(chunk))

                # Stream the last 3 chunks only (negative offset)
                async for chunk in app.stream_media(message, offset=-3):
                    print(len(chunk))
        """
        available_media = ("audio", "document", "photo", "sticker",
                           "animation", "video", "voice", "video_note",
                           "new_chat_photo")

        if isinstance(message, types.Message):
            for kind in available_media:
                media = getattr(message, kind, None)

                if media is not None:
                    break
            else:
                raise ValueError(
                    "This message doesn't contain any downloadable media")
        else:
            media = message

        if isinstance(media, str):
            file_id_str = media
        else:
            file_id_str = media.file_id

        file_id_obj = FileId.decode(file_id_str)
        file_size = getattr(media, "file_size", 0)

        if offset < 0:
            if file_size == 0:
                raise ValueError(
                    "Negative offsets are not supported for file ids, pass a Message object instead"
                )

            chunks = math.ceil(file_size / 1024 / 1024)
            offset += chunks

        async for chunk in self.get_file(file_id_obj, file_size, limit,
                                         offset):
            yield chunk