U
    g49                     @   s   d Z ddlZddlmZ ddlmZ ddlmZ ddl	m
Z
mZmZ ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZmZmZ e
rddlmZ G dd deZdS )z?This module contains an object that represents a Telegram File.    N)	b64decode)Path)TYPE_CHECKINGBinaryIOOptional)decrypt)TelegramObject)DEFAULT_NONE)is_local_file)FilePathInputJSONDictODVInput)FileCredentialsc                	       s  e Zd ZdZdZdddeeee ee ee d fddZ	edd	d
Z
eedddZdeeeedee ee ee ee ee edddZeeeedeee ee ee ee ddddZdeeeedee ee ee ee ee edddZdddddZ  ZS )Filea  
    This object represents a file ready to be downloaded. The file can be e.g. downloaded with
    :attr:`download_to_drive`. It is guaranteed that the link will be valid for at least 1 hour.
    When the link expires, a new one can be requested by calling :meth:`telegram.Bot.get_file`.

    Objects of this class are comparable in terms of equality. Two objects of this class are
    considered equal, if their :attr:`file_unique_id` is equal.

    .. versionchanged:: 20.0
        ``download`` was split into :meth:`download_to_drive` and :meth:`download_to_memory`.

    Note:
        * Maximum file size to download is
          :tg-const:`telegram.constants.FileSizeLimit.FILESIZE_DOWNLOAD`.
        * If you obtain an instance of this class from :attr:`telegram.PassportFile.get_file`,
          then it will automatically be decrypted as it downloads when you call e.g.
          :meth:`download_to_drive`.

    Args:
        file_id (:obj:`str`): Identifier for this file, which can be used to download
            or reuse the file.
        file_unique_id (:obj:`str`): Unique identifier for this file, which
            is supposed to be the same over time and for different bots.
            Can't be used to download or reuse the file.
        file_size (:obj:`int`, optional): File size in bytes, if known.
        file_path (:obj:`str`, optional): File path. Use e.g. :meth:`download_to_drive` to get the
            file.

    Attributes:
        file_id (:obj:`str`): Identifier for this file, which can be used to download
            or reuse the file.
        file_unique_id (:obj:`str`): Unique identifier for this file, which
            is supposed to be the same over time and for different bots.
            Can't be used to download or reuse the file.
        file_size (:obj:`int`): Optional. File size in bytes, if known.
        file_path (:obj:`str`): Optional. File path. Use e.g. :meth:`download_to_drive` to get the
            file.
    )_credentialsfile_id	file_path	file_sizefile_unique_idN
api_kwargs)r   r   r   r   r   c                   sJ   t  j|d t|| _t|| _|| _|| _d | _| jf| _| 	  d S )Nr   )
super__init__strr   r   r   r   r   Z	_id_attrsZ_freeze)selfr   r   r   r   r   	__class__ 8/tmp/pip-unpacked-wheel-swnnwir2/telegram/_files/file.pyr   T   s    	


zFile.__init__)returnc              	   C   s8   t t| j}t t |j|jt |j	|j
|jS )zPConvert any UTF-8 char in :obj:`File.file_path` into a url encoded ASCII string.)urllib_parseurlsplitr   r   
urlunsplitSplitResultschemenetlocquotepathqueryfragment)r   sresr   r   r   _get_encoded_urll   s      
  zFile._get_encoded_url)bufr   c                 C   s   t t| jjt| jj|S )N)r   r   r   secrethash)r   r,   r   r   r   _prepare_decryptu   s    zFile._prepare_decryptread_timeoutwrite_timeoutconnect_timeoutpool_timeout)custom_pathr1   r2   r3   r4   r   c                   s  t | j}|rdn|  }|rt| jrtt| j}| | }	|dk	rNt|}
ntt|jd |j	 }
|

|	 |
S |dk	r|rt| jt| t|S |rt|}n4|rt| jS | jrtt| jj	}nt | j }|  jj|||||dI dH }	| jr| |	}	|
|	 |S )a
  
        Download this file. By default, the file is saved in the current working directory with
        :attr:`file_path` as file name. If the file has no filename, the file ID will be used as
        filename. If :paramref:`custom_path` is supplied as a :obj:`str` or :obj:`pathlib.Path`,
        it will be saved to that path.

        Note:
            If :paramref:`custom_path` isn't provided and :attr:`file_path` is the path of a
            local file (which is the case when a Bot API Server is running in local mode), this
            method will just return the path.

            The only exception to this are encrypted files (e.g. a passport file). For these, a
            file with the prefix `decrypted_` will be created in the same directory as the
            original file in order to decrypt the file without changing the existing one
            in-place.

        .. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`

        .. versionchanged:: 20.0

            * :paramref:`custom_path` parameter now also accepts :class:`pathlib.Path` as argument.
            * Returns :class:`pathlib.Path` object in cases where previously a :obj:`str` was
              returned.
            * This method was previously called ``download``. It was split into
              :meth:`download_to_drive` and :meth:`download_to_memory`.

        Args:
            custom_path (:class:`pathlib.Path` | :obj:`str` , optional): The path where the file
                will be saved to. If not specified, will be saved in the current working directory
                with :attr:`file_path` as file name or the :attr:`file_id` if :attr:`file_path`
                is not set.

        Keyword Args:
            read_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
                :paramref:`telegram.request.BaseRequest.post.read_timeout`. Defaults to
                :attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
            write_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
                :paramref:`telegram.request.BaseRequest.post.write_timeout`. Defaults to
                :attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
            connect_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
                :paramref:`telegram.request.BaseRequest.post.connect_timeout`. Defaults to
                :attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
            pool_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
                :paramref:`telegram.request.BaseRequest.post.pool_timeout`. Defaults to
                :attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.

        Returns:
            :class:`pathlib.Path`: Returns the Path object the file was downloaded to.

        Nz/decrypted_r0   )r
   r   r+   r   r   r/   
read_bytesr   parentnamewrite_bytesshutilcopyfilecwdr   get_botrequestretrieve)r   r5   r1   r2   r3   r4   
local_fileurlZfile_to_decryptr,   r'   filenamer   r   r   download_to_drivex   s>    ;









zFile.download_to_drive)outr1   r2   r3   r4   r   c          
         sx   t | j}|rdn|  }|r(t| jnd}|r:| }	n |  jj|||||dI dH }	| jrj| 	|	}	|
|	 dS )a  
        Download this file into memory. :paramref:`out` needs to be supplied with a
        :obj:`io.BufferedIOBase`, the file contents will be saved to that object using the
        :obj:`out.write<io.BufferedIOBase.write>` method.

        .. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`

        Hint:
            If you want to immediately read the data from ``out`` after calling this method, you
            should call ``out.seek(0)`` first. See also :meth:`io.IOBase.seek`.

        .. versionadded:: 20.0

        Args:
            out (:obj:`io.BufferedIOBase`): A file-like object. Must be opened for writing in
                binary mode.

        Keyword Args:
            read_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
                :paramref:`telegram.request.BaseRequest.post.read_timeout`. Defaults to
                :attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
            write_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
                :paramref:`telegram.request.BaseRequest.post.write_timeout`. Defaults to
                :attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
            connect_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
                :paramref:`telegram.request.BaseRequest.post.connect_timeout`. Defaults to
                :attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
            pool_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
                :paramref:`telegram.request.BaseRequest.post.pool_timeout`. Defaults to
                :attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
        Nr0   )r
   r   r+   r   r6   r=   r>   r?   r   r/   write)
r   rD   r1   r2   r3   r4   r@   rA   r'   r,   r   r   r   download_to_memory   s    (



zFile.download_to_memory)r,   r1   r2   r3   r4   r   c                   sr   |dkrt  }t| jr(t| j }n$|  jj|  ||||dI dH }| j	rd|
| | n
|
| |S )a  Download this file and return it as a bytearray.

        Args:
            buf (:obj:`bytearray`, optional): Extend the given bytearray with the downloaded data.

        Keyword Args:
            read_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
                :paramref:`telegram.request.BaseRequest.post.read_timeout`. Defaults to
                :attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.

                .. versionadded:: 20.0
            write_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
                :paramref:`telegram.request.BaseRequest.post.write_timeout`. Defaults to
                :attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.

                .. versionadded:: 20.0
            connect_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
                :paramref:`telegram.request.BaseRequest.post.connect_timeout`. Defaults to
                :attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.

                .. versionadded:: 20.0
            pool_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
                :paramref:`telegram.request.BaseRequest.post.pool_timeout`. Defaults to
                :attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.

                .. versionadded:: 20.0

        Returns:
            :obj:`bytearray`: The same object as :paramref:`buf` if it was specified. Otherwise a
            newly allocated :obj:`bytearray`.

        Nr0   )	bytearrayr
   r   r   r6   r=   r>   r?   r+   r   extendr/   )r   r,   r1   r2   r3   r4   
bytes_datar   r   r   download_as_bytearray  s    )


zFile.download_as_bytearrayr   )credentialsr   c                 C   s
   || _ dS )zSets the passport credentials for the file.

        Args:
            credentials (:class:`telegram.FileCredentials`): The credentials.
        N)r   )r   rK   r   r   r   set_credentialsO  s    zFile.set_credentials)NN)N)N)__name__
__module____qualname____doc__	__slots__r   r   intr   r   r+   bytesr/   r	   r   r   floatr   rC   r   rF   rG   rJ   rL   __classcell__r   r   r   r   r   $   sp   '  	 f; <r   )rP   r:   urllib.parseparser    base64r   pathlibr   typingr   r   r   Ztelegram._passport.credentialsr   Ztelegram._telegramobjectr   Ztelegram._utils.defaultvaluer	   Ztelegram._utils.filesr
   Ztelegram._utils.typesr   r   r   Ztelegramr   r   r   r   r   r   <module>   s   