mirror of
				https://github.com/LonamiWebs/Telethon.git
				synced 2025-11-04 09:57:29 +03:00 
			
		
		
		
	Continue work on Message sending overhaul
This commit is contained in:
		
							parent
							
								
									3853f98e5f
								
							
						
					
					
						commit
						72fc8f6808
					
				| 
						 | 
					@ -650,3 +650,18 @@ CdnDecrypter has been removed
 | 
				
			||||||
-----------------------------
 | 
					-----------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
It was not really working and was more intended to be an implementation detail than anything else.
 | 
					It was not really working and was more intended to be an implementation detail than anything else.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					you can no longer pass an attributes list because the constructor is now nice.
 | 
				
			||||||
 | 
					use raw api if you really need it.
 | 
				
			||||||
 | 
					goal is to hide raw api from high level api. sorry.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					no parsemode. use the correct parameter. it's more convenient than setting two.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					formatting_entities stays because otherwise it's the only feasible way to manually specify it.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					todo update send_message and send_file docs (well review all functions)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					album overhaul. use a list of Message instead.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,10 +1,12 @@
 | 
				
			||||||
import inspect
 | 
					import inspect
 | 
				
			||||||
import itertools
 | 
					import itertools
 | 
				
			||||||
 | 
					import time
 | 
				
			||||||
import typing
 | 
					import typing
 | 
				
			||||||
import warnings
 | 
					import warnings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .._misc import helpers, utils, requestiter, hints
 | 
					from .._misc import helpers, utils, requestiter, hints
 | 
				
			||||||
from ..types import _custom
 | 
					from ..types import _custom
 | 
				
			||||||
 | 
					from ..types._custom.inputmessage import InputMessage
 | 
				
			||||||
from .. import errors, _tl
 | 
					from .. import errors, _tl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_MAX_CHUNK_SIZE = 100
 | 
					_MAX_CHUNK_SIZE = 100
 | 
				
			||||||
| 
						 | 
					@ -395,82 +397,95 @@ async def send_message(
 | 
				
			||||||
        entity: 'hints.EntityLike',
 | 
					        entity: 'hints.EntityLike',
 | 
				
			||||||
        message: 'hints.MessageLike' = '',
 | 
					        message: 'hints.MessageLike' = '',
 | 
				
			||||||
        *,
 | 
					        *,
 | 
				
			||||||
        reply_to: 'typing.Union[int, _tl.Message]' = None,
 | 
					        # - Message contents
 | 
				
			||||||
        attributes: 'typing.Sequence[_tl.TypeDocumentAttribute]' = None,
 | 
					        # Formatting
 | 
				
			||||||
        parse_mode: typing.Optional[str] = (),
 | 
					        markdown: str = None,
 | 
				
			||||||
        formatting_entities: typing.Optional[typing.List[_tl.TypeMessageEntity]] = None,
 | 
					        html: str = None,
 | 
				
			||||||
        link_preview: bool = True,
 | 
					        formatting_entities: list = None,
 | 
				
			||||||
        file: 'typing.Union[hints.FileLike, typing.Sequence[hints.FileLike]]' = None,
 | 
					        link_preview: bool = (),
 | 
				
			||||||
        thumb: 'hints.FileLike' = None,
 | 
					        # Media
 | 
				
			||||||
        force_document: bool = False,
 | 
					        file: typing.Optional[hints.FileLike] = None,
 | 
				
			||||||
        clear_draft: bool = False,
 | 
					        file_name: str = None,
 | 
				
			||||||
        buttons: 'hints.MarkupLike' = None,
 | 
					        mime_type: str = None,
 | 
				
			||||||
        silent: bool = None,
 | 
					        thumb: str = False,
 | 
				
			||||||
        background: bool = None,
 | 
					        force_file: bool = False,
 | 
				
			||||||
 | 
					        file_size: int = None,
 | 
				
			||||||
 | 
					        # Media attributes
 | 
				
			||||||
 | 
					        duration: int = None,
 | 
				
			||||||
 | 
					        width: int = None,
 | 
				
			||||||
 | 
					        height: int = None,
 | 
				
			||||||
 | 
					        title: str = None,
 | 
				
			||||||
 | 
					        performer: str = None,
 | 
				
			||||||
        supports_streaming: bool = False,
 | 
					        supports_streaming: bool = False,
 | 
				
			||||||
 | 
					        video_note: bool = False,
 | 
				
			||||||
 | 
					        voice_note: bool = False,
 | 
				
			||||||
 | 
					        waveform: bytes = None,
 | 
				
			||||||
 | 
					        # Additional parametrization
 | 
				
			||||||
 | 
					        silent: bool = False,
 | 
				
			||||||
 | 
					        buttons: list = None,
 | 
				
			||||||
 | 
					        ttl: int = None,
 | 
				
			||||||
 | 
					        # - Send options
 | 
				
			||||||
 | 
					        reply_to: 'typing.Union[int, _tl.Message]' = None,
 | 
				
			||||||
 | 
					        clear_draft: bool = False,
 | 
				
			||||||
 | 
					        background: bool = None,
 | 
				
			||||||
        schedule: 'hints.DateLike' = None,
 | 
					        schedule: 'hints.DateLike' = None,
 | 
				
			||||||
        comment_to: 'typing.Union[int, _tl.Message]' = None
 | 
					        comment_to: 'typing.Union[int, _tl.Message]' = None,
 | 
				
			||||||
) -> '_tl.Message':
 | 
					) -> '_tl.Message':
 | 
				
			||||||
    if file is not None:
 | 
					    if isinstance(message, str):
 | 
				
			||||||
        return await self.send_file(
 | 
					        message = InputMessage(
 | 
				
			||||||
            entity, file, caption=message, reply_to=reply_to,
 | 
					            text=message,
 | 
				
			||||||
            attributes=attributes, parse_mode=parse_mode,
 | 
					            markdown=markdown,
 | 
				
			||||||
            force_document=force_document, thumb=thumb,
 | 
					            html=html,
 | 
				
			||||||
            buttons=buttons, clear_draft=clear_draft, silent=silent,
 | 
					 | 
				
			||||||
            schedule=schedule, supports_streaming=supports_streaming,
 | 
					 | 
				
			||||||
            formatting_entities=formatting_entities,
 | 
					            formatting_entities=formatting_entities,
 | 
				
			||||||
            comment_to=comment_to, background=background
 | 
					            link_preview=link_preview,
 | 
				
			||||||
 | 
					            file=file,
 | 
				
			||||||
 | 
					            file_name=file_name,
 | 
				
			||||||
 | 
					            mime_type=mime_type,
 | 
				
			||||||
 | 
					            thumb=thumb,
 | 
				
			||||||
 | 
					            force_file=force_file,
 | 
				
			||||||
 | 
					            file_size=file_size,
 | 
				
			||||||
 | 
					            duration=duration,
 | 
				
			||||||
 | 
					            width=width,
 | 
				
			||||||
 | 
					            height=height,
 | 
				
			||||||
 | 
					            title=title,
 | 
				
			||||||
 | 
					            performer=performer,
 | 
				
			||||||
 | 
					            supports_streaming=supports_streaming,
 | 
				
			||||||
 | 
					            video_note=video_note,
 | 
				
			||||||
 | 
					            voice_note=voice_note,
 | 
				
			||||||
 | 
					            waveform=waveform,
 | 
				
			||||||
 | 
					            silent=silent,
 | 
				
			||||||
 | 
					            buttons=buttons,
 | 
				
			||||||
 | 
					            ttl=ttl,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					    elif isinstance(message, _custom.Message):
 | 
				
			||||||
 | 
					        message = message._as_input()
 | 
				
			||||||
 | 
					    elif not isinstance(message, InputMessage):
 | 
				
			||||||
 | 
					        raise TypeError(f'message must be either str, Message or InputMessage, but got: {message!r}')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    entity = await self.get_input_entity(entity)
 | 
					    entity = await self.get_input_entity(entity)
 | 
				
			||||||
    if comment_to is not None:
 | 
					    if comment_to is not None:
 | 
				
			||||||
        entity, reply_to = await _get_comment_data(self, entity, comment_to)
 | 
					        entity, reply_to = await _get_comment_data(self, entity, comment_to)
 | 
				
			||||||
 | 
					    elif reply_to:
 | 
				
			||||||
 | 
					        reply_to = utils.get_message_id(reply_to)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if isinstance(message, _tl.Message):
 | 
					    if message._file:
 | 
				
			||||||
        if buttons is None:
 | 
					        # TODO Properly implement allow_cache to reuse the sha256 of the file
 | 
				
			||||||
            markup = message.reply_markup
 | 
					        # i.e. `None` was used
 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            markup = _custom.button.build_reply_markup(buttons)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if silent is None:
 | 
					        # TODO album
 | 
				
			||||||
            silent = message.silent
 | 
					        if message._file._should_upload_thumb():
 | 
				
			||||||
 | 
					            message._file._set_uploaded_thumb(await self.upload_file(message._file._thumb))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (message.media and not isinstance(
 | 
					        if message._file._should_upload_file():
 | 
				
			||||||
                message.media, _tl.MessageMediaWebPage)):
 | 
					            message._file._set_uploaded_file(await self.upload_file(message._file._file))
 | 
				
			||||||
            return await self.send_file(
 | 
					 | 
				
			||||||
                entity,
 | 
					 | 
				
			||||||
                message.media,
 | 
					 | 
				
			||||||
                caption=message.message,
 | 
					 | 
				
			||||||
                silent=silent,
 | 
					 | 
				
			||||||
                background=background,
 | 
					 | 
				
			||||||
                reply_to=reply_to,
 | 
					 | 
				
			||||||
                buttons=markup,
 | 
					 | 
				
			||||||
                formatting_entities=message.entities,
 | 
					 | 
				
			||||||
                schedule=schedule
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        request = _tl.fn.messages.SendMessage(
 | 
					        request = _tl.fn.messages.SendMedia(
 | 
				
			||||||
            peer=entity,
 | 
					            entity, message._file._media, reply_to_msg_id=reply_to, message=message._text,
 | 
				
			||||||
            message=message.message or '',
 | 
					            entities=message._fmt_entities, reply_markup=message._reply_markup, silent=message._silent,
 | 
				
			||||||
            silent=silent,
 | 
					            schedule_date=schedule, clear_draft=clear_draft,
 | 
				
			||||||
            background=background,
 | 
					            background=background
 | 
				
			||||||
            reply_to_msg_id=utils.get_message_id(reply_to),
 | 
					 | 
				
			||||||
            reply_markup=markup,
 | 
					 | 
				
			||||||
            entities=message.entities,
 | 
					 | 
				
			||||||
            clear_draft=clear_draft,
 | 
					 | 
				
			||||||
            no_webpage=not isinstance(
 | 
					 | 
				
			||||||
                message.media, _tl.MessageMediaWebPage),
 | 
					 | 
				
			||||||
            schedule_date=schedule
 | 
					 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        message = message.message
 | 
					 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        if formatting_entities is None:
 | 
					 | 
				
			||||||
            message, formatting_entities = await self._parse_message_text(message, parse_mode)
 | 
					 | 
				
			||||||
        if not message:
 | 
					 | 
				
			||||||
            raise ValueError(
 | 
					 | 
				
			||||||
                'The message cannot be empty unless a file is provided'
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        request = _tl.fn.messages.SendMessage(
 | 
					        request = _tl.fn.messages.SendMessage(
 | 
				
			||||||
            peer=entity,
 | 
					            peer=entity,
 | 
				
			||||||
            message=message,
 | 
					            message=message,
 | 
				
			||||||
| 
						 | 
					@ -489,7 +504,7 @@ async def send_message(
 | 
				
			||||||
        return _custom.Message._new(self, _tl.Message(
 | 
					        return _custom.Message._new(self, _tl.Message(
 | 
				
			||||||
            id=result.id,
 | 
					            id=result.id,
 | 
				
			||||||
            peer_id=await _get_peer(self, entity),
 | 
					            peer_id=await _get_peer(self, entity),
 | 
				
			||||||
            message=message,
 | 
					            message=message._text,
 | 
				
			||||||
            date=result.date,
 | 
					            date=result.date,
 | 
				
			||||||
            out=result.out,
 | 
					            out=result.out,
 | 
				
			||||||
            media=result.media,
 | 
					            media=result.media,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2075,31 +2075,46 @@ class TelegramClient:
 | 
				
			||||||
            entity: 'hints.EntityLike',
 | 
					            entity: 'hints.EntityLike',
 | 
				
			||||||
            message: 'hints.MessageLike' = '',
 | 
					            message: 'hints.MessageLike' = '',
 | 
				
			||||||
            *,
 | 
					            *,
 | 
				
			||||||
            reply_to: 'typing.Union[int, _tl.Message]' = None,
 | 
					            # - Message contents
 | 
				
			||||||
            attributes: 'typing.Sequence[_tl.TypeDocumentAttribute]' = None,
 | 
					            # Formatting
 | 
				
			||||||
            parse_mode: typing.Optional[str] = (),
 | 
					            markdown: str = None,
 | 
				
			||||||
            formatting_entities: typing.Optional[typing.List[_tl.TypeMessageEntity]] = None,
 | 
					            html: str = None,
 | 
				
			||||||
            link_preview: bool = True,
 | 
					            formatting_entities: list = None,
 | 
				
			||||||
            file: 'typing.Union[hints.FileLike, typing.Sequence[hints.FileLike]]' = None,
 | 
					            link_preview: bool = (),
 | 
				
			||||||
            thumb: 'hints.FileLike' = None,
 | 
					            # Media
 | 
				
			||||||
            force_document: bool = False,
 | 
					            file: 'typing.Optional[hints.FileLike]' = None,
 | 
				
			||||||
            clear_draft: bool = False,
 | 
					            file_name: str = None,
 | 
				
			||||||
            buttons: 'hints.MarkupLike' = None,
 | 
					            mime_type: str = None,
 | 
				
			||||||
            silent: bool = None,
 | 
					            thumb: str = False,
 | 
				
			||||||
            background: bool = None,
 | 
					            force_file: bool = False,
 | 
				
			||||||
 | 
					            file_size: int = None,
 | 
				
			||||||
 | 
					            # Media attributes
 | 
				
			||||||
 | 
					            duration: int = None,
 | 
				
			||||||
 | 
					            width: int = None,
 | 
				
			||||||
 | 
					            height: int = None,
 | 
				
			||||||
 | 
					            title: str = None,
 | 
				
			||||||
 | 
					            performer: str = None,
 | 
				
			||||||
            supports_streaming: bool = False,
 | 
					            supports_streaming: bool = False,
 | 
				
			||||||
 | 
					            video_note: bool = False,
 | 
				
			||||||
 | 
					            voice_note: bool = False,
 | 
				
			||||||
 | 
					            waveform: bytes = None,
 | 
				
			||||||
 | 
					            # Additional parametrization
 | 
				
			||||||
 | 
					            silent: bool = False,
 | 
				
			||||||
 | 
					            buttons: list = None,
 | 
				
			||||||
 | 
					            ttl: int = None,
 | 
				
			||||||
 | 
					            # - Send options
 | 
				
			||||||
 | 
					            reply_to: 'typing.Union[int, _tl.Message]' = None,
 | 
				
			||||||
 | 
					            clear_draft: bool = False,
 | 
				
			||||||
 | 
					            background: bool = None,
 | 
				
			||||||
            schedule: 'hints.DateLike' = None,
 | 
					            schedule: 'hints.DateLike' = None,
 | 
				
			||||||
            comment_to: 'typing.Union[int, _tl.Message]' = None
 | 
					            comment_to: 'typing.Union[int, _tl.Message]' = None,
 | 
				
			||||||
    ) -> '_tl.Message':
 | 
					    ) -> '_tl.Message':
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Sends a message to the specified user, chat or channel.
 | 
					        Sends a Message to the specified user, chat or channel.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        The default parse mode is the same as the official applications
 | 
					        The message can be either a string or a previous Message instance.
 | 
				
			||||||
        (a _custom flavour of markdown). ``**bold**, `code` or __italic__``
 | 
					        If it's a previous Message instance, the rest of parameters will be ignored.
 | 
				
			||||||
        are available. In addition you can send ``[links](https://example.com)``
 | 
					        If it's not, a Message instance will be constructed, and send_to used.
 | 
				
			||||||
        and ``[mentions](@username)`` (or using IDs like in the Bot API:
 | 
					 | 
				
			||||||
        ``[mention](tg://user?id=123456789)``) and ``pre`` blocks with three
 | 
					 | 
				
			||||||
        backticks.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Sending a ``/start`` command with a parameter (like ``?start=data``)
 | 
					        Sending a ``/start`` command with a parameter (like ``?start=data``)
 | 
				
			||||||
        is also done through this method. Simply send ``'/start data'`` to
 | 
					        is also done through this method. Simply send ``'/start data'`` to
 | 
				
			||||||
| 
						 | 
					@ -3517,15 +3532,6 @@ class TelegramClient:
 | 
				
			||||||
    async def _parse_message_text(self: 'TelegramClient', message, parse_mode):
 | 
					    async def _parse_message_text(self: 'TelegramClient', message, parse_mode):
 | 
				
			||||||
        pass
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @forward_call(uploads._file_to_media)
 | 
					 | 
				
			||||||
    async def _file_to_media(
 | 
					 | 
				
			||||||
            self, file, force_document=False, file_size=None,
 | 
					 | 
				
			||||||
            progress_callback=None, attributes=None, thumb=None,
 | 
					 | 
				
			||||||
            allow_cache=True, voice_note=False, video_note=False,
 | 
					 | 
				
			||||||
            supports_streaming=False, mime_type=None, as_image=None,
 | 
					 | 
				
			||||||
            ttl=None):
 | 
					 | 
				
			||||||
        pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @forward_call(messageparse._get_response_message)
 | 
					    @forward_call(messageparse._get_response_message)
 | 
				
			||||||
    def _get_response_message(self: 'TelegramClient', request, result, input_chat):
 | 
					    def _get_response_message(self: 'TelegramClient', request, result, input_chat):
 | 
				
			||||||
        pass
 | 
					        pass
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -92,105 +92,74 @@ def _resize_photo_if_needed(
 | 
				
			||||||
async def send_file(
 | 
					async def send_file(
 | 
				
			||||||
        self: 'TelegramClient',
 | 
					        self: 'TelegramClient',
 | 
				
			||||||
        entity: 'hints.EntityLike',
 | 
					        entity: 'hints.EntityLike',
 | 
				
			||||||
        file: 'typing.Union[hints.FileLike, typing.Sequence[hints.FileLike]]',
 | 
					        file: typing.Optional[hints.FileLike] = None,
 | 
				
			||||||
        *,
 | 
					        *,
 | 
				
			||||||
        caption: typing.Union[str, typing.Sequence[str]] = None,
 | 
					        # - Message contents
 | 
				
			||||||
        force_document: bool = False,
 | 
					        # Formatting
 | 
				
			||||||
 | 
					        caption: 'hints.MessageLike' = '',
 | 
				
			||||||
 | 
					        markdown: str = None,
 | 
				
			||||||
 | 
					        html: str = None,
 | 
				
			||||||
 | 
					        formatting_entities: list = None,
 | 
				
			||||||
 | 
					        link_preview: bool = (),
 | 
				
			||||||
 | 
					        # Media
 | 
				
			||||||
 | 
					        file_name: str = None,
 | 
				
			||||||
 | 
					        mime_type: str = None,
 | 
				
			||||||
 | 
					        thumb: str = False,
 | 
				
			||||||
 | 
					        force_file: bool = False,
 | 
				
			||||||
        file_size: int = None,
 | 
					        file_size: int = None,
 | 
				
			||||||
        clear_draft: bool = False,
 | 
					        # Media attributes
 | 
				
			||||||
        progress_callback: 'hints.ProgressCallback' = None,
 | 
					        duration: int = None,
 | 
				
			||||||
        reply_to: 'hints.MessageIDLike' = None,
 | 
					        width: int = None,
 | 
				
			||||||
        attributes: 'typing.Sequence[_tl.TypeDocumentAttribute]' = None,
 | 
					        height: int = None,
 | 
				
			||||||
        thumb: 'hints.FileLike' = None,
 | 
					        title: str = None,
 | 
				
			||||||
        allow_cache: bool = True,
 | 
					        performer: str = None,
 | 
				
			||||||
        parse_mode: str = (),
 | 
					 | 
				
			||||||
        formatting_entities: typing.Optional[typing.List[_tl.TypeMessageEntity]] = None,
 | 
					 | 
				
			||||||
        voice_note: bool = False,
 | 
					 | 
				
			||||||
        video_note: bool = False,
 | 
					 | 
				
			||||||
        buttons: 'hints.MarkupLike' = None,
 | 
					 | 
				
			||||||
        silent: bool = None,
 | 
					 | 
				
			||||||
        background: bool = None,
 | 
					 | 
				
			||||||
        supports_streaming: bool = False,
 | 
					        supports_streaming: bool = False,
 | 
				
			||||||
 | 
					        video_note: bool = False,
 | 
				
			||||||
 | 
					        voice_note: bool = False,
 | 
				
			||||||
 | 
					        waveform: bytes = None,
 | 
				
			||||||
 | 
					        # Additional parametrization
 | 
				
			||||||
 | 
					        silent: bool = False,
 | 
				
			||||||
 | 
					        buttons: list = None,
 | 
				
			||||||
 | 
					        ttl: int = None,
 | 
				
			||||||
 | 
					        # - Send options
 | 
				
			||||||
 | 
					        reply_to: 'typing.Union[int, _tl.Message]' = None,
 | 
				
			||||||
 | 
					        clear_draft: bool = False,
 | 
				
			||||||
 | 
					        background: bool = None,
 | 
				
			||||||
        schedule: 'hints.DateLike' = None,
 | 
					        schedule: 'hints.DateLike' = None,
 | 
				
			||||||
        comment_to: 'typing.Union[int, _tl.Message]' = None,
 | 
					        comment_to: 'typing.Union[int, _tl.Message]' = None,
 | 
				
			||||||
        ttl: int = None,
 | 
					) -> '_tl.Message':
 | 
				
			||||||
        **kwargs) -> '_tl.Message':
 | 
					    self.send_message(
 | 
				
			||||||
    # TODO Properly implement allow_cache to reuse the sha256 of the file
 | 
					        entity=entity,
 | 
				
			||||||
    # i.e. `None` was used
 | 
					        message=caption,
 | 
				
			||||||
    if not file:
 | 
					        markdown=markdown,
 | 
				
			||||||
        raise TypeError('Cannot use {!r} as file'.format(file))
 | 
					        html=html,
 | 
				
			||||||
 | 
					        formatting_entities=formatting_entities,
 | 
				
			||||||
    if not caption:
 | 
					        link_preview=link_preview,
 | 
				
			||||||
        caption = ''
 | 
					        file=file,
 | 
				
			||||||
 | 
					        file_name=file_name,
 | 
				
			||||||
    entity = await self.get_input_entity(entity)
 | 
					        mime_type=mime_type,
 | 
				
			||||||
    if comment_to is not None:
 | 
					        thumb=thumb,
 | 
				
			||||||
        entity, reply_to = await _get_comment_data(self, entity, comment_to)
 | 
					        force_file=force_file,
 | 
				
			||||||
    else:
 | 
					 | 
				
			||||||
        reply_to = utils.get_message_id(reply_to)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # First check if the user passed an iterable, in which case
 | 
					 | 
				
			||||||
    # we may want to send grouped.
 | 
					 | 
				
			||||||
    if utils.is_list_like(file):
 | 
					 | 
				
			||||||
        if utils.is_list_like(caption):
 | 
					 | 
				
			||||||
            captions = caption
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            captions = [caption]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        result = []
 | 
					 | 
				
			||||||
        while file:
 | 
					 | 
				
			||||||
            result += await _send_album(
 | 
					 | 
				
			||||||
                self, entity, file[:10], caption=captions[:10],
 | 
					 | 
				
			||||||
                progress_callback=progress_callback, reply_to=reply_to,
 | 
					 | 
				
			||||||
                parse_mode=parse_mode, silent=silent, schedule=schedule,
 | 
					 | 
				
			||||||
                supports_streaming=supports_streaming, clear_draft=clear_draft,
 | 
					 | 
				
			||||||
                force_document=force_document, background=background,
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
            file = file[10:]
 | 
					 | 
				
			||||||
            captions = captions[10:]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for doc, cap in zip(file, captions):
 | 
					 | 
				
			||||||
            result.append(await self.send_file(
 | 
					 | 
				
			||||||
                entity, doc, allow_cache=allow_cache,
 | 
					 | 
				
			||||||
                caption=cap, force_document=force_document,
 | 
					 | 
				
			||||||
                progress_callback=progress_callback, reply_to=reply_to,
 | 
					 | 
				
			||||||
                attributes=attributes, thumb=thumb, voice_note=voice_note,
 | 
					 | 
				
			||||||
                video_note=video_note, buttons=buttons, silent=silent,
 | 
					 | 
				
			||||||
                supports_streaming=supports_streaming, schedule=schedule,
 | 
					 | 
				
			||||||
                clear_draft=clear_draft, background=background,
 | 
					 | 
				
			||||||
                **kwargs
 | 
					 | 
				
			||||||
            ))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return result
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if formatting_entities is not None:
 | 
					 | 
				
			||||||
        msg_entities = formatting_entities
 | 
					 | 
				
			||||||
    else:
 | 
					 | 
				
			||||||
        caption, msg_entities =\
 | 
					 | 
				
			||||||
            await self._parse_message_text(caption, parse_mode)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    file_handle, media, image = await _file_to_media(
 | 
					 | 
				
			||||||
        self, file, force_document=force_document,
 | 
					 | 
				
			||||||
        file_size=file_size,
 | 
					        file_size=file_size,
 | 
				
			||||||
        progress_callback=progress_callback,
 | 
					        duration=duration,
 | 
				
			||||||
        attributes=attributes,  allow_cache=allow_cache, thumb=thumb,
 | 
					        width=width,
 | 
				
			||||||
        voice_note=voice_note, video_note=video_note,
 | 
					        height=height,
 | 
				
			||||||
        supports_streaming=supports_streaming, ttl=ttl
 | 
					        title=title,
 | 
				
			||||||
 | 
					        performer=performer,
 | 
				
			||||||
 | 
					        supports_streaming=supports_streaming,
 | 
				
			||||||
 | 
					        video_note=video_note,
 | 
				
			||||||
 | 
					        voice_note=voice_note,
 | 
				
			||||||
 | 
					        waveform=waveform,
 | 
				
			||||||
 | 
					        silent=silent,
 | 
				
			||||||
 | 
					        buttons=buttons,
 | 
				
			||||||
 | 
					        ttl=ttl,
 | 
				
			||||||
 | 
					        reply_to=reply_to,
 | 
				
			||||||
 | 
					        clear_draft=clear_draft,
 | 
				
			||||||
 | 
					        background=background,
 | 
				
			||||||
 | 
					        schedule=schedule,
 | 
				
			||||||
 | 
					        comment_to=comment_to,
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # e.g. invalid cast from :tl:`MessageMediaWebPage`
 | 
					 | 
				
			||||||
    if not media:
 | 
					 | 
				
			||||||
        raise TypeError('Cannot use {!r} as file'.format(file))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    markup = _custom.button.build_reply_markup(buttons)
 | 
					 | 
				
			||||||
    request = _tl.fn.messages.SendMedia(
 | 
					 | 
				
			||||||
        entity, media, reply_to_msg_id=reply_to, message=caption,
 | 
					 | 
				
			||||||
        entities=msg_entities, reply_markup=markup, silent=silent,
 | 
					 | 
				
			||||||
        schedule_date=schedule, clear_draft=clear_draft,
 | 
					 | 
				
			||||||
        background=background
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
    return self._get_response_message(request, await self(request), entity)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
async def _send_album(self: 'TelegramClient', entity, files, caption='',
 | 
					async def _send_album(self: 'TelegramClient', entity, files, caption='',
 | 
				
			||||||
                        progress_callback=None, reply_to=None,
 | 
					                        progress_callback=None, reply_to=None,
 | 
				
			||||||
                        parse_mode=(), silent=None, schedule=None,
 | 
					                        parse_mode=(), silent=None, schedule=None,
 | 
				
			||||||
| 
						 | 
					@ -368,98 +337,3 @@ async def upload_file(
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async def _file_to_media(
 | 
					 | 
				
			||||||
        self, file, force_document=False, file_size=None,
 | 
					 | 
				
			||||||
        progress_callback=None, attributes=None, thumb=None,
 | 
					 | 
				
			||||||
        allow_cache=True, voice_note=False, video_note=False,
 | 
					 | 
				
			||||||
        supports_streaming=False, mime_type=None, as_image=None,
 | 
					 | 
				
			||||||
        ttl=None):
 | 
					 | 
				
			||||||
    if not file:
 | 
					 | 
				
			||||||
        return None, None, None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if isinstance(file, pathlib.Path):
 | 
					 | 
				
			||||||
        file = str(file.absolute())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    is_image = utils.is_image(file)
 | 
					 | 
				
			||||||
    if as_image is None:
 | 
					 | 
				
			||||||
        as_image = is_image and not force_document
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # `aiofiles` do not base `io.IOBase` but do have `read`, so we
 | 
					 | 
				
			||||||
    # just check for the read attribute to see if it's file-like.
 | 
					 | 
				
			||||||
    if not isinstance(file, (str, bytes, _tl.InputFile, _tl.InputFileBig))\
 | 
					 | 
				
			||||||
            and not hasattr(file, 'read'):
 | 
					 | 
				
			||||||
        # The user may pass a Message containing media (or the media,
 | 
					 | 
				
			||||||
        # or anything similar) that should be treated as a file. Try
 | 
					 | 
				
			||||||
        # getting the input media for whatever they passed and send it.
 | 
					 | 
				
			||||||
        #
 | 
					 | 
				
			||||||
        # We pass all attributes since these will be used if the user
 | 
					 | 
				
			||||||
        # passed :tl:`InputFile`, and all information may be relevant.
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            return (None, utils.get_input_media(
 | 
					 | 
				
			||||||
                file,
 | 
					 | 
				
			||||||
                is_photo=as_image,
 | 
					 | 
				
			||||||
                attributes=attributes,
 | 
					 | 
				
			||||||
                force_document=force_document,
 | 
					 | 
				
			||||||
                voice_note=voice_note,
 | 
					 | 
				
			||||||
                video_note=video_note,
 | 
					 | 
				
			||||||
                supports_streaming=supports_streaming,
 | 
					 | 
				
			||||||
                ttl=ttl
 | 
					 | 
				
			||||||
            ), as_image)
 | 
					 | 
				
			||||||
        except TypeError:
 | 
					 | 
				
			||||||
            # Can't turn whatever was given into media
 | 
					 | 
				
			||||||
            return None, None, as_image
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    media = None
 | 
					 | 
				
			||||||
    file_handle = None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if isinstance(file, (_tl.InputFile, _tl.InputFileBig)):
 | 
					 | 
				
			||||||
        file_handle = file
 | 
					 | 
				
			||||||
    elif not isinstance(file, str) or os.path.isfile(file):
 | 
					 | 
				
			||||||
        file_handle = await self.upload_file(
 | 
					 | 
				
			||||||
            _resize_photo_if_needed(file, as_image),
 | 
					 | 
				
			||||||
            file_size=file_size,
 | 
					 | 
				
			||||||
            progress_callback=progress_callback
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
    elif re.match('https?://', file):
 | 
					 | 
				
			||||||
        if as_image:
 | 
					 | 
				
			||||||
            media = _tl.InputMediaPhotoExternal(file, ttl_seconds=ttl)
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            media = _tl.InputMediaDocumentExternal(file, ttl_seconds=ttl)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if media:
 | 
					 | 
				
			||||||
        pass  # Already have media, don't check the rest
 | 
					 | 
				
			||||||
    elif not file_handle:
 | 
					 | 
				
			||||||
        raise ValueError(
 | 
					 | 
				
			||||||
            'Failed to convert {} to media. Not an existing file or '
 | 
					 | 
				
			||||||
            'HTTP URL'.format(file)
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
    elif as_image:
 | 
					 | 
				
			||||||
        media = _tl.InputMediaUploadedPhoto(file_handle, ttl_seconds=ttl)
 | 
					 | 
				
			||||||
    else:
 | 
					 | 
				
			||||||
        attributes, mime_type = utils.get_attributes(
 | 
					 | 
				
			||||||
            file,
 | 
					 | 
				
			||||||
            mime_type=mime_type,
 | 
					 | 
				
			||||||
            attributes=attributes,
 | 
					 | 
				
			||||||
            force_document=force_document and not is_image,
 | 
					 | 
				
			||||||
            voice_note=voice_note,
 | 
					 | 
				
			||||||
            video_note=video_note,
 | 
					 | 
				
			||||||
            supports_streaming=supports_streaming,
 | 
					 | 
				
			||||||
            thumb=thumb
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if not thumb:
 | 
					 | 
				
			||||||
            thumb = None
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            if isinstance(thumb, pathlib.Path):
 | 
					 | 
				
			||||||
                thumb = str(thumb.absolute())
 | 
					 | 
				
			||||||
            thumb = await self.upload_file(thumb, file_size=file_size)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        media = _tl.InputMediaUploadedDocument(
 | 
					 | 
				
			||||||
            file=file_handle,
 | 
					 | 
				
			||||||
            mime_type=mime_type,
 | 
					 | 
				
			||||||
            attributes=attributes,
 | 
					 | 
				
			||||||
            thumb=thumb,
 | 
					 | 
				
			||||||
            force_file=force_document and not is_image,
 | 
					 | 
				
			||||||
            ttl_seconds=ttl
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
    return file_handle, media, as_image
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,11 +1,36 @@
 | 
				
			||||||
import mimetypes
 | 
					import mimetypes
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
import pathlib
 | 
					import re
 | 
				
			||||||
 | 
					import time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from pathlib import Path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from ... import _tl
 | 
					from ... import _tl
 | 
				
			||||||
 | 
					from ..._misc import utils
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class InputFile:
 | 
					class InputFile:
 | 
				
			||||||
 | 
					    # Expected Time-To-Live for _uploaded_*.
 | 
				
			||||||
 | 
					    # After this period they should be reuploaded.
 | 
				
			||||||
 | 
					    # Telegram's limit are unknown, so this value is conservative.
 | 
				
			||||||
 | 
					    UPLOAD_TTL = 8 * 60 * 60
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    __slots__ = (
 | 
				
			||||||
 | 
					        # main media
 | 
				
			||||||
 | 
					        '_file',  # can reupload
 | 
				
			||||||
 | 
					        '_media',  # can only use as-is
 | 
				
			||||||
 | 
					        '_uploaded_file',  # (input file, timestamp)
 | 
				
			||||||
 | 
					        # thumbnail
 | 
				
			||||||
 | 
					        '_thumb',  # can reupload
 | 
				
			||||||
 | 
					        '_uploaded_thumb',  # (input file, timestamp)
 | 
				
			||||||
 | 
					        # document parameters
 | 
				
			||||||
 | 
					        '_mime_type',
 | 
				
			||||||
 | 
					        '_attributes',
 | 
				
			||||||
 | 
					        '_video_note',
 | 
				
			||||||
 | 
					        '_force_file',
 | 
				
			||||||
 | 
					        '_ttl',
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(
 | 
					    def __init__(
 | 
				
			||||||
            self,
 | 
					            self,
 | 
				
			||||||
            file = None,
 | 
					            file = None,
 | 
				
			||||||
| 
						 | 
					@ -26,145 +51,125 @@ class InputFile:
 | 
				
			||||||
            waveform: bytes = None,
 | 
					            waveform: bytes = None,
 | 
				
			||||||
            ttl: int = None,
 | 
					            ttl: int = None,
 | 
				
			||||||
    ):
 | 
					    ):
 | 
				
			||||||
        if isinstance(file, pathlib.Path):
 | 
					        # main media
 | 
				
			||||||
            if not file_name:
 | 
					        self._file =  None
 | 
				
			||||||
                file_name = file.name
 | 
					        self._media = None
 | 
				
			||||||
            file = str(file.absolute())
 | 
					        self._uploaded_file = None
 | 
				
			||||||
        elif not file_name:
 | 
					
 | 
				
			||||||
            if isinstance(file, str):
 | 
					        if isinstance(file, str) and re.match('https?://', file, flags=re.IGNORECASE):
 | 
				
			||||||
                file_name = os.path.basename(file)
 | 
					            if not force_file and mime_type.startswith('image'):
 | 
				
			||||||
 | 
					                self._media = _tl.InputMediaPhotoExternal(file, ttl_seconds=ttl)
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                file_name = getattr(file, 'name', 'unnamed')
 | 
					                self._media = _tl.InputMediaDocumentExternal(file, ttl_seconds=ttl)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not mime_type:
 | 
					        elif isinstance(file, (str, bytes, Path)) or callable(getattr(file, 'read', None)):
 | 
				
			||||||
            mime_type = mimetypes.guess_type(file_name)[0] or 'application/octet-stream'
 | 
					            self._file = file
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mime_type = mime_type.lower()
 | 
					        elif isinstance(file, (_tl.InputFile, _tl.InputFileBig)):
 | 
				
			||||||
 | 
					            self._uploaded_file = (file, time.time())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        attributes = [_tl.DocumentAttributeFilename(file_name)]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # TODO hachoir or tinytag or ffmpeg
 | 
					 | 
				
			||||||
        if mime_type.startswith('image'):
 | 
					 | 
				
			||||||
            if width is not None and height is not None:
 | 
					 | 
				
			||||||
                attributes.append(_tl.DocumentAttributeImageSize(
 | 
					 | 
				
			||||||
                    w=width,
 | 
					 | 
				
			||||||
                    h=height,
 | 
					 | 
				
			||||||
                ))
 | 
					 | 
				
			||||||
        elif mime_type.startswith('audio'):
 | 
					 | 
				
			||||||
            attributes.append(_tl.DocumentAttributeAudio(
 | 
					 | 
				
			||||||
                duration=duration,
 | 
					 | 
				
			||||||
                voice=voice_note,
 | 
					 | 
				
			||||||
                title=title,
 | 
					 | 
				
			||||||
                performer=performer,
 | 
					 | 
				
			||||||
                waveform=waveform,
 | 
					 | 
				
			||||||
            ))
 | 
					 | 
				
			||||||
        elif mime_type.startswith('video'):
 | 
					 | 
				
			||||||
            attributes.append(_tl.DocumentAttributeVideo(
 | 
					 | 
				
			||||||
                duration=duration,
 | 
					 | 
				
			||||||
                w=width,
 | 
					 | 
				
			||||||
                h=height,
 | 
					 | 
				
			||||||
                round_message=video_note,
 | 
					 | 
				
			||||||
                supports_streaming=supports_streaming,
 | 
					 | 
				
			||||||
            ))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # mime_type: str = None,
 | 
					 | 
				
			||||||
        # thumb: str = False,
 | 
					 | 
				
			||||||
        # force_file: bool = False,
 | 
					 | 
				
			||||||
        # file_size: int = None,
 | 
					 | 
				
			||||||
        # ttl: int = None,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self._file = file
 | 
					 | 
				
			||||||
        self._attributes = attributes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # TODO rest
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        is_image = utils.is_image(file)
 | 
					 | 
				
			||||||
        if as_image is None:
 | 
					 | 
				
			||||||
            as_image = is_image and not force_document
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # `aiofiles` do not base `io.IOBase` but do have `read`, so we
 | 
					 | 
				
			||||||
        # just check for the read attribute to see if it's file-like.
 | 
					 | 
				
			||||||
        if not isinstance(file, (str, bytes, _tl.InputFile, _tl.InputFileBig))\
 | 
					 | 
				
			||||||
                and not hasattr(file, 'read'):
 | 
					 | 
				
			||||||
            # The user may pass a Message containing media (or the media,
 | 
					 | 
				
			||||||
            # or anything similar) that should be treated as a file. Try
 | 
					 | 
				
			||||||
            # getting the input media for whatever they passed and send it.
 | 
					 | 
				
			||||||
            #
 | 
					 | 
				
			||||||
            # We pass all attributes since these will be used if the user
 | 
					 | 
				
			||||||
            # passed :tl:`InputFile`, and all information may be relevant.
 | 
					 | 
				
			||||||
            try:
 | 
					 | 
				
			||||||
                return (None, utils.get_input_media(
 | 
					 | 
				
			||||||
                    file,
 | 
					 | 
				
			||||||
                    is_photo=as_image,
 | 
					 | 
				
			||||||
                    attributes=attributes,
 | 
					 | 
				
			||||||
                    force_document=force_document,
 | 
					 | 
				
			||||||
                    voice_note=voice_note,
 | 
					 | 
				
			||||||
                    video_note=video_note,
 | 
					 | 
				
			||||||
                    supports_streaming=supports_streaming,
 | 
					 | 
				
			||||||
                    ttl=ttl
 | 
					 | 
				
			||||||
                ), as_image)
 | 
					 | 
				
			||||||
            except TypeError:
 | 
					 | 
				
			||||||
                # Can't turn whatever was given into media
 | 
					 | 
				
			||||||
                return None, None, as_image
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        media = None
 | 
					 | 
				
			||||||
        file_handle = None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if isinstance(file, (_tl.InputFile, _tl.InputFileBig)):
 | 
					 | 
				
			||||||
            file_handle = file
 | 
					 | 
				
			||||||
        elif not isinstance(file, str) or os.path.isfile(file):
 | 
					 | 
				
			||||||
            file_handle = await self.upload_file(
 | 
					 | 
				
			||||||
                _resize_photo_if_needed(file, as_image),
 | 
					 | 
				
			||||||
                file_size=file_size,
 | 
					 | 
				
			||||||
                progress_callback=progress_callback
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
        elif re.match('https?://', file):
 | 
					 | 
				
			||||||
            if as_image:
 | 
					 | 
				
			||||||
                media = _tl.InputMediaPhotoExternal(file, ttl_seconds=ttl)
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                media = _tl.InputMediaDocumentExternal(file, ttl_seconds=ttl)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if media:
 | 
					 | 
				
			||||||
            pass  # Already have media, don't check the rest
 | 
					 | 
				
			||||||
        elif not file_handle:
 | 
					 | 
				
			||||||
            raise ValueError(
 | 
					 | 
				
			||||||
                'Failed to convert {} to media. Not an existing file or '
 | 
					 | 
				
			||||||
                'HTTP URL'.format(file)
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
        elif as_image:
 | 
					 | 
				
			||||||
            media = _tl.InputMediaUploadedPhoto(file_handle, ttl_seconds=ttl)
 | 
					 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            attributes, mime_type = utils.get_attributes(
 | 
					            self._media = utils.get_input_media(
 | 
				
			||||||
                file,
 | 
					                file,
 | 
				
			||||||
                mime_type=mime_type,
 | 
					                is_photo=not force_file and mime_type.startswith('image'),
 | 
				
			||||||
                attributes=attributes,
 | 
					                attributes=[],
 | 
				
			||||||
                force_document=force_document and not is_image,
 | 
					                force_document=force_file,
 | 
				
			||||||
                voice_note=voice_note,
 | 
					                voice_note=voice_note,
 | 
				
			||||||
                video_note=video_note,
 | 
					                video_note=video_note,
 | 
				
			||||||
                supports_streaming=supports_streaming,
 | 
					                supports_streaming=supports_streaming,
 | 
				
			||||||
                thumb=thumb
 | 
					                ttl=ttl
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if not thumb:
 | 
					        # thumbnail
 | 
				
			||||||
                thumb = None
 | 
					        self._thumb = None
 | 
				
			||||||
            else:
 | 
					        self._uploaded_thumb = None
 | 
				
			||||||
                if isinstance(thumb, pathlib.Path):
 | 
					 | 
				
			||||||
                    thumb = str(thumb.absolute())
 | 
					 | 
				
			||||||
                thumb = await self.upload_file(thumb, file_size=file_size)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            media = _tl.InputMediaUploadedDocument(
 | 
					        if isinstance(thumb, (str, bytes, Path)) or callable(getattr(thumb, 'read', None)):
 | 
				
			||||||
                file=file_handle,
 | 
					            self._thumb = thumb
 | 
				
			||||||
                mime_type=mime_type,
 | 
					
 | 
				
			||||||
                attributes=attributes,
 | 
					        elif isinstance(thumb, (_tl.InputFile, _tl.InputFileBig)):
 | 
				
			||||||
                thumb=thumb,
 | 
					            self._uploaded_thumb = (thumb, time.time())
 | 
				
			||||||
                force_file=force_document and not is_image,
 | 
					
 | 
				
			||||||
                ttl_seconds=ttl
 | 
					        else:
 | 
				
			||||||
 | 
					            raise TypeError(f'thumb must be a file to upload, but got: {thumb!r}')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # document parameters (only if it's our file, i.e. there's no media ready yet)
 | 
				
			||||||
 | 
					        if self._media:
 | 
				
			||||||
 | 
					            self._mime_type = None
 | 
				
			||||||
 | 
					            self._attributes = None
 | 
				
			||||||
 | 
					            self._video_note = None
 | 
				
			||||||
 | 
					            self._force_file = None
 | 
				
			||||||
 | 
					            self._ttl = None
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            if isinstance(file, Path):
 | 
				
			||||||
 | 
					                if not file_name:
 | 
				
			||||||
 | 
					                    file_name = file.name
 | 
				
			||||||
 | 
					                file = str(file.absolute())
 | 
				
			||||||
 | 
					            elif not file_name:
 | 
				
			||||||
 | 
					                if isinstance(file, str):
 | 
				
			||||||
 | 
					                    file_name = os.path.basename(file)
 | 
				
			||||||
 | 
					                else:
 | 
				
			||||||
 | 
					                    file_name = getattr(file, 'name', 'unnamed')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if not mime_type:
 | 
				
			||||||
 | 
					                mime_type = mimetypes.guess_type(file_name)[0] or 'application/octet-stream'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            mime_type = mime_type.lower()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            attributes = [_tl.DocumentAttributeFilename(file_name)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # TODO hachoir or tinytag or ffmpeg
 | 
				
			||||||
 | 
					            if mime_type.startswith('image'):
 | 
				
			||||||
 | 
					                if width is not None and height is not None:
 | 
				
			||||||
 | 
					                    attributes.append(_tl.DocumentAttributeImageSize(
 | 
				
			||||||
 | 
					                        w=width,
 | 
				
			||||||
 | 
					                        h=height,
 | 
				
			||||||
 | 
					                    ))
 | 
				
			||||||
 | 
					            elif mime_type.startswith('audio'):
 | 
				
			||||||
 | 
					                attributes.append(_tl.DocumentAttributeAudio(
 | 
				
			||||||
 | 
					                    duration=duration,
 | 
				
			||||||
 | 
					                    voice=voice_note,
 | 
				
			||||||
 | 
					                    title=title,
 | 
				
			||||||
 | 
					                    performer=performer,
 | 
				
			||||||
 | 
					                    waveform=waveform,
 | 
				
			||||||
 | 
					                ))
 | 
				
			||||||
 | 
					            elif mime_type.startswith('video'):
 | 
				
			||||||
 | 
					                attributes.append(_tl.DocumentAttributeVideo(
 | 
				
			||||||
 | 
					                    duration=duration,
 | 
				
			||||||
 | 
					                    w=width,
 | 
				
			||||||
 | 
					                    h=height,
 | 
				
			||||||
 | 
					                    round_message=video_note,
 | 
				
			||||||
 | 
					                    supports_streaming=supports_streaming,
 | 
				
			||||||
 | 
					                ))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            self._mime_type = mime_type
 | 
				
			||||||
 | 
					            self._attributes = attributes
 | 
				
			||||||
 | 
					            self._video_note = video_note
 | 
				
			||||||
 | 
					            self._force_file = force_file
 | 
				
			||||||
 | 
					            self._ttl = ttl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _should_upload_thumb(self):
 | 
				
			||||||
 | 
					        return self._thumb and (
 | 
				
			||||||
 | 
					            not self._uploaded_thumb
 | 
				
			||||||
 | 
					            or time.time() > self._uploaded_thumb[1] + InputFile.UPLOAD_TTL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _should_upload_file(self):
 | 
				
			||||||
 | 
					        return self._file and (
 | 
				
			||||||
 | 
					            not self._uploaded_file
 | 
				
			||||||
 | 
					            or time.time() > self._uploaded_file[1] + InputFile.UPLOAD_TTL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _set_uploaded_thumb(self, input_file):
 | 
				
			||||||
 | 
					        self._uploaded_thumb = (input_file, time.time())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _set_uploaded_file(self, input_file):
 | 
				
			||||||
 | 
					        if not self._force_file and self._mime_type.startswith('image'):
 | 
				
			||||||
 | 
					            self._media = _tl.InputMediaUploadedPhoto(input_file, ttl_seconds=self._ttl)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            self._media = _tl.InputMediaUploadedDocument(
 | 
				
			||||||
 | 
					                file=input_file,
 | 
				
			||||||
 | 
					                mime_type=self._mime_type,
 | 
				
			||||||
 | 
					                attributes=self._attributes,
 | 
				
			||||||
 | 
					                thumb=self._uploaded_thumb[0] if self._uploaded_thumb else None,
 | 
				
			||||||
 | 
					                force_file=self._force_file,
 | 
				
			||||||
 | 
					                ttl_seconds=self._ttl,
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        return file_handle, media, as_image
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,3 +1,8 @@
 | 
				
			||||||
 | 
					from typing import Optional
 | 
				
			||||||
 | 
					from .inputfile import InputFile
 | 
				
			||||||
 | 
					from ... import _misc
 | 
				
			||||||
 | 
					from .button import build_reply_markup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class InputMessage:
 | 
					class InputMessage:
 | 
				
			||||||
    __slots__ = (
 | 
					    __slots__ = (
 | 
				
			||||||
| 
						 | 
					@ -9,21 +14,83 @@ class InputMessage:
 | 
				
			||||||
        '_file',
 | 
					        '_file',
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _default_parse_mode = (lambda t: (t, []), lambda t, e: t)
 | 
				
			||||||
 | 
					    _default_link_preview = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(
 | 
					    def __init__(
 | 
				
			||||||
            self,
 | 
					            self,
 | 
				
			||||||
            text,
 | 
					            text: str = None,
 | 
				
			||||||
            *,
 | 
					            *,
 | 
				
			||||||
            link_preview,
 | 
					            markdown: str = None,
 | 
				
			||||||
            silent,
 | 
					            html: str = None,
 | 
				
			||||||
            reply_markup,
 | 
					            formatting_entities: list = None,
 | 
				
			||||||
            fmt_entities,
 | 
					            link_preview: bool = (),
 | 
				
			||||||
            file,
 | 
					            file=None,
 | 
				
			||||||
 | 
					            file_name: str = None,
 | 
				
			||||||
 | 
					            mime_type: str = None,
 | 
				
			||||||
 | 
					            thumb: str = False,
 | 
				
			||||||
 | 
					            force_file: bool = False,
 | 
				
			||||||
 | 
					            file_size: int = None,
 | 
				
			||||||
 | 
					            duration: int = None,
 | 
				
			||||||
 | 
					            width: int = None,
 | 
				
			||||||
 | 
					            height: int = None,
 | 
				
			||||||
 | 
					            title: str = None,
 | 
				
			||||||
 | 
					            performer: str = None,
 | 
				
			||||||
 | 
					            supports_streaming: bool = False,
 | 
				
			||||||
 | 
					            video_note: bool = False,
 | 
				
			||||||
 | 
					            voice_note: bool = False,
 | 
				
			||||||
 | 
					            waveform: bytes = None,
 | 
				
			||||||
 | 
					            silent: bool = False,
 | 
				
			||||||
 | 
					            buttons: list = None,
 | 
				
			||||||
 | 
					            ttl: int = None,
 | 
				
			||||||
 | 
					            parse_fn = None,
 | 
				
			||||||
    ):
 | 
					    ):
 | 
				
			||||||
 | 
					        if (text and markdown) or (text and html) or (markdown and html):
 | 
				
			||||||
 | 
					            raise ValueError('can only set one of: text, markdown, html')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if formatting_entities:
 | 
				
			||||||
 | 
					            text = text or markdown or html
 | 
				
			||||||
 | 
					        elif text:
 | 
				
			||||||
 | 
					            text, formatting_entities = self._default_parse_mode[0](text)
 | 
				
			||||||
 | 
					        elif markdown:
 | 
				
			||||||
 | 
					            text, formatting_entities = _misc.markdown.parse(markdown)
 | 
				
			||||||
 | 
					        elif html:
 | 
				
			||||||
 | 
					            text, formatting_entities = _misc.html.parse(html)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        reply_markup = build_reply_markup(buttons) if buttons else None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if not text:
 | 
				
			||||||
 | 
					            text = ''
 | 
				
			||||||
 | 
					        if not formatting_entities:
 | 
				
			||||||
 | 
					            formatting_entities = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if link_preview == ():
 | 
				
			||||||
 | 
					            link_preview = self._default_link_preview
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if file and not isinstance(file, InputFile):
 | 
				
			||||||
 | 
					            file = InputFile(
 | 
				
			||||||
 | 
					                file=file,
 | 
				
			||||||
 | 
					                file_name=file_name,
 | 
				
			||||||
 | 
					                mime_type=mime_type,
 | 
				
			||||||
 | 
					                thumb=thumb,
 | 
				
			||||||
 | 
					                force_file=force_file,
 | 
				
			||||||
 | 
					                file_size=file_size,
 | 
				
			||||||
 | 
					                duration=duration,
 | 
				
			||||||
 | 
					                width=width,
 | 
				
			||||||
 | 
					                height=height,
 | 
				
			||||||
 | 
					                title=title,
 | 
				
			||||||
 | 
					                performer=performer,
 | 
				
			||||||
 | 
					                supports_streaming=supports_streaming,
 | 
				
			||||||
 | 
					                video_note=video_note,
 | 
				
			||||||
 | 
					                voice_note=voice_note,
 | 
				
			||||||
 | 
					                waveform=waveform,
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self._text = text
 | 
					        self._text = text
 | 
				
			||||||
        self._link_preview = link_preview
 | 
					        self._link_preview = link_preview
 | 
				
			||||||
        self._silent = silent
 | 
					        self._silent = silent
 | 
				
			||||||
        self._reply_markup = reply_markup
 | 
					        self._reply_markup = reply_markup
 | 
				
			||||||
        self._fmt_entities = fmt_entities
 | 
					        self._fmt_entities = formatting_entities
 | 
				
			||||||
        self._file = file
 | 
					        self._file = file
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # oh! when this message is used, the file can be cached in here! if not inputfile upload and set inputfile
 | 
					    # oh! when this message is used, the file can be cached in here! if not inputfile upload and set inputfile
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -228,9 +228,6 @@ class Message(ChatGetter, SenderGetter):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # region Initialization
 | 
					    # region Initialization
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    _default_parse_mode = None
 | 
					 | 
				
			||||||
    _default_link_preview = True
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(
 | 
					    def __init__(
 | 
				
			||||||
            self,
 | 
					            self,
 | 
				
			||||||
            text: str = None,
 | 
					            text: str = None,
 | 
				
			||||||
| 
						 | 
					@ -241,7 +238,7 @@ class Message(ChatGetter, SenderGetter):
 | 
				
			||||||
            formatting_entities: list = None,
 | 
					            formatting_entities: list = None,
 | 
				
			||||||
            link_preview: bool = (),
 | 
					            link_preview: bool = (),
 | 
				
			||||||
            # Media
 | 
					            # Media
 | 
				
			||||||
            file: Optional[hints.FileLike] = None,
 | 
					            file: 'Optional[hints.FileLike]' = None,
 | 
				
			||||||
            file_name: str = None,
 | 
					            file_name: str = None,
 | 
				
			||||||
            mime_type: str = None,
 | 
					            mime_type: str = None,
 | 
				
			||||||
            thumb: str = False,
 | 
					            thumb: str = False,
 | 
				
			||||||
| 
						 | 
					@ -379,54 +376,30 @@ class Message(ChatGetter, SenderGetter):
 | 
				
			||||||
        Not all types of media can be used with this parameter, such as text documents, which
 | 
					        Not all types of media can be used with this parameter, such as text documents, which
 | 
				
			||||||
        will fail with ``TtlMediaInvalidError``.
 | 
					        will fail with ``TtlMediaInvalidError``.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        if (text and markdown) or (text and html) or (markdown and html):
 | 
					 | 
				
			||||||
            raise ValueError('can only set one of: text, markdown, html')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if formatting_entities:
 | 
					 | 
				
			||||||
            text = text or markdown or html
 | 
					 | 
				
			||||||
        elif text:
 | 
					 | 
				
			||||||
            text, formatting_entities = self._default_parse_mode[0](text)
 | 
					 | 
				
			||||||
        elif markdown:
 | 
					 | 
				
			||||||
            text, formatting_entities = _misc.markdown.parse(markdown)
 | 
					 | 
				
			||||||
        elif html:
 | 
					 | 
				
			||||||
            text, formatting_entities = _misc.html.parse(html)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        reply_markup = build_reply_markup(buttons) if buttons else None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if not text:
 | 
					 | 
				
			||||||
            text = ''
 | 
					 | 
				
			||||||
        if not formatting_entities:
 | 
					 | 
				
			||||||
            formatting_entities = None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if link_preview == ():
 | 
					 | 
				
			||||||
            link_preview = self._default_link_preview
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if file:
 | 
					 | 
				
			||||||
            file = InputFile(
 | 
					 | 
				
			||||||
                file=file,
 | 
					 | 
				
			||||||
                file_name=file_name,
 | 
					 | 
				
			||||||
                mime_type=mime_type,
 | 
					 | 
				
			||||||
                thumb=thumb,
 | 
					 | 
				
			||||||
                force_file=force_file,
 | 
					 | 
				
			||||||
                file_size=file_size,
 | 
					 | 
				
			||||||
                duration=duration,
 | 
					 | 
				
			||||||
                width=width,
 | 
					 | 
				
			||||||
                height=height,
 | 
					 | 
				
			||||||
                title=title,
 | 
					 | 
				
			||||||
                performer=performer,
 | 
					 | 
				
			||||||
                supports_streaming=supports_streaming,
 | 
					 | 
				
			||||||
                video_note=video_note,
 | 
					 | 
				
			||||||
                voice_note=voice_note,
 | 
					 | 
				
			||||||
                waveform=waveform,
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self._message = InputMessage(
 | 
					        self._message = InputMessage(
 | 
				
			||||||
            text=text,
 | 
					            text=text,
 | 
				
			||||||
 | 
					            markdown=markdown,
 | 
				
			||||||
 | 
					            html=html,
 | 
				
			||||||
 | 
					            formatting_entities=formatting_entities,
 | 
				
			||||||
            link_preview=link_preview,
 | 
					            link_preview=link_preview,
 | 
				
			||||||
 | 
					            file =file,
 | 
				
			||||||
 | 
					            file_name=file_name,
 | 
				
			||||||
 | 
					            mime_type=mime_type,
 | 
				
			||||||
 | 
					            thumb=thumb,
 | 
				
			||||||
 | 
					            force_file=force_file,
 | 
				
			||||||
 | 
					            file_size=file_size,
 | 
				
			||||||
 | 
					            duration=duration,
 | 
				
			||||||
 | 
					            width=width,
 | 
				
			||||||
 | 
					            height=height,
 | 
				
			||||||
 | 
					            title=title,
 | 
				
			||||||
 | 
					            performer=performer,
 | 
				
			||||||
 | 
					            supports_streaming=supports_streaming,
 | 
				
			||||||
 | 
					            video_note=video_note,
 | 
				
			||||||
 | 
					            voice_note=voice_note,
 | 
				
			||||||
 | 
					            waveform=waveform,
 | 
				
			||||||
            silent=silent,
 | 
					            silent=silent,
 | 
				
			||||||
            reply_markup=reply_markup,
 | 
					            buttons=buttons,
 | 
				
			||||||
            fmt_entities=formatting_entities,
 | 
					            ttl=ttl,
 | 
				
			||||||
            file=file,
 | 
					 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
| 
						 | 
					@ -446,7 +419,7 @@ class Message(ChatGetter, SenderGetter):
 | 
				
			||||||
                sender_id = utils.get_peer_id(message.peer_id)
 | 
					                sender_id = utils.get_peer_id(message.peer_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Note that these calls would reset the client
 | 
					        # Note that these calls would reset the client
 | 
				
			||||||
        ChatGetter.__init__(self, self.peer_id, broadcast=self.post)
 | 
					        ChatGetter.__init__(self, message.peer_id, broadcast=message.post)
 | 
				
			||||||
        SenderGetter.__init__(self, sender_id)
 | 
					        SenderGetter.__init__(self, sender_id)
 | 
				
			||||||
        self._client = client
 | 
					        self._client = client
 | 
				
			||||||
        self._message = message
 | 
					        self._message = message
 | 
				
			||||||
| 
						 | 
					@ -511,8 +484,8 @@ class Message(ChatGetter, SenderGetter):
 | 
				
			||||||
        return self
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @staticmethod
 | 
				
			||||||
    def set_default_parse_mode(cls, mode):
 | 
					    def set_default_parse_mode(mode):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Change the default parse mode when creating messages. The ``mode`` can be:
 | 
					        Change the default parse mode when creating messages. The ``mode`` can be:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -531,27 +504,29 @@ class Message(ChatGetter, SenderGetter):
 | 
				
			||||||
        if isinstance(mode, str):
 | 
					        if isinstance(mode, str):
 | 
				
			||||||
            mode = mode.lower()
 | 
					            mode = mode.lower()
 | 
				
			||||||
            if mode in ('md', 'markdown'):
 | 
					            if mode in ('md', 'markdown'):
 | 
				
			||||||
                cls._default_parse_mode = (_misc.markdown.parse, _misc.markdown.unparse)
 | 
					                mode = (_misc.markdown.parse, _misc.markdown.unparse)
 | 
				
			||||||
            elif mode in ('htm', 'html'):
 | 
					            elif mode in ('htm', 'html'):
 | 
				
			||||||
                cls._default_parse_mode = (_misc.html.parse, _misc.html.unparse)
 | 
					                mode = (_misc.html.parse, _misc.html.unparse)
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                raise ValueError(f'mode must be one of md, markdown, htm or html, but was {mode!r}')
 | 
					                raise ValueError(f'mode must be one of md, markdown, htm or html, but was {mode!r}')
 | 
				
			||||||
        elif callable(mode):
 | 
					        elif callable(mode):
 | 
				
			||||||
            cls._default_parse_mode = (mode, lambda t, e: t)
 | 
					            mode = (mode, lambda t, e: t)
 | 
				
			||||||
        elif isinstance(mode, tuple):
 | 
					        elif isinstance(mode, tuple):
 | 
				
			||||||
            if len(mode) == 2 and callable(mode[0]) and callable(mode[1]):
 | 
					            if len(mode) == 2 and callable(mode[0]) and callable(mode[1]):
 | 
				
			||||||
                cls._default_parse_mode = mode
 | 
					                mode = mode
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                raise ValueError(f'mode must be a tuple of exactly two callables')
 | 
					                raise ValueError(f'mode must be a tuple of exactly two callables')
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            raise TypeError(f'mode must be either a str, callable or tuple, but was {mode!r}')
 | 
					            raise TypeError(f'mode must be either a str, callable or tuple, but was {mode!r}')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        InputMessage._default_parse_mode = mode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def set_default_link_preview(cls, enabled):
 | 
					    def set_default_link_preview(cls, enabled):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Change the default value for link preview (either ``True`` or ``False``).
 | 
					        Change the default value for link preview (either ``True`` or ``False``).
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        cls._default_link_preview = enabled
 | 
					        InputMessage._default_link_preview = enabled
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # endregion Initialization
 | 
					    # endregion Initialization
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1297,6 +1272,14 @@ class Message(ChatGetter, SenderGetter):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # region Private Methods
 | 
					    # region Private Methods
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _as_input(self):
 | 
				
			||||||
 | 
					        if isinstance(self._message, InputMessage):
 | 
				
			||||||
 | 
					            return self._message
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return InputMessage(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def _reload_message(self):
 | 
					    async def _reload_message(self):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Re-fetches this message to reload the sender and chat entities,
 | 
					        Re-fetches this message to reload the sender and chat entities,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user