B
    fd                  @   s   d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlmZ d dl	m
Z
 d dlmZmZmZ d dlZd dlmZ d dlmZ d dlmZ eeZG dd	 d	ZdS )
    N)md5)PurePath)UnionBinaryIOCallable)StopTransmission)raw)Sessionc               @   s.   e Zd Zddeeef eeeedddZ	dS )	SaveFileNr    zpyrogram.Client)selfpathfile_id	file_partprogressprogress_argsc                s~  j 4 I dH ^ |dkrdS  fddd}t|ttfrHt|d}nt|tjrZ|}ntdt|dd}|	d	t
j | }	|	d	 |	d	krtd
jjrdnd}
|	|
d d krtd|
 dtt|	| }|	dk}|rdnd}|dk	}|p }|s|st nd}tj I dH j I dH j I dH ddfddt|D }td zy I dH  |	||  x||}|s|s|sddd | D }P |rt j!j"j#||||d}nt j!j"j$|||d} %|I dH  |r"dS |s8|s8|&| |d7 }|rt'j(|t)|| |	|	f| }t*+|r~| I dH  nj,-j.|I dH  qW W nD t/k
r    Y nZ t0k
r } zt12| W dd}~X Y n.X |rt j3j4|||dS t j3j5||||dS W dx|D ]} %dI dH  qW tj6| I dH  7 I dH  t|ttfrh|8  X W dQ I dH R X dS )a	  Upload a file onto Telegram servers, without actually sending the message to anyone.
        Useful whenever an InputFile type is required.

        .. note::

            This is a utility method intended to be used **only** when working with raw
            :obj:`functions <pyrogram.api.functions>` (i.e: a Telegram API method you wish to use which is not
            available yet in the Client class as an easy-to-use method).

        .. include:: /_includes/usable-by/users-bots.rst

        Parameters:
            path (``str`` | ``BinaryIO``):
                The path of the file you want to upload that exists on your local machine or a binary file-like object
                with its attribute ".name" set for in-memory uploads.

            file_id (``int``, *optional*):
                In case a file part expired, pass the file_id and the file_part to retry uploading that specific chunk.

            file_part (``int``, *optional*):
                In case a file part expired, pass the file_id and the file_part to retry uploading that specific chunk.

            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:
            ``InputFile``: On success, the uploaded file is returned in form of an InputFile object.

        Raises:
            RPCError: In case of a Telegram RPC error.
        Nc          
      sf   x`   I d H }|d krd S y| |I d H  W q tk
r\ } zt| W d d }~X Y qX qW d S )N)getZinvoke	Exceptionlog	exception)sessiondatae)queuer   G/tmp/pip-unpacked-wheel-rcokkf2l/pyrogram/methods/advanced/save_file.pyworkere   s    z"SaveFile.save_file.<locals>.workeri   rbzPInvalid file. Expected a file path as string or a binary (not text) file pointernamezfile.jpgr   zFile size equals to 0 Bi  i  i   zCan't upload files bigger than z MiBi         T)Zis_mediac                s   g | ]} j qS r   )loopZcreate_task).0_)r   r   r   r   r   
<listcomp>   s    z&SaveFile.save_file.<locals>.<listcomp> c             S   s"   g | ]}t |d d d qS )   N)hexzfill)r!   ir   r   r   r#      s    )r   r   file_total_partsbytes)r   r   r*   )idpartsr   )r+   r,   r   Zmd5_checksum)9Zsave_file_semaphore
isinstancestrr   openioIOBase
ValueErrorgetattrseekosSEEK_ENDtellmeZ
is_premiumintmathceilZrnd_idr   r	   ZstorageZdc_idZauth_keyZ	test_moderangeasyncioQueuestartreadjoindigestr   Z	functionsuploadZSaveBigFilePartZSaveFilePartputupdate	functoolspartialmininspectiscoroutinefunctionr    Zrun_in_executorexecutorr   r   r   r   typesZInputFileBigZ	InputFileZgatherstopclose)r   r   r   r   r   r   Z	part_sizefp	file_name	file_sizeZfile_size_limit_mibr)   Zis_bigZworkers_countZis_missing_partZmd5_sumworkerschunkZrpcfuncr   r"   r   )r   r   r   r   r   	save_file'   s    :




 
zSaveFile.save_file)Nr   Nr   )
__name__
__module____qualname__r   r.   r   r9   r   tuplerU   r   r   r   r   r
   &   s      r
   )r=   rF   rI   r0   loggingr:   r5   hashlibr   pathlibr   typingr   r   r   Zpyrogramr   r   Zpyrogram.sessionr	   	getLoggerrV   r   r
   r   r   r   r   <module>   s   
