a
    $lJhF+                     @   s  d 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	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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! ddl"m#Z#m$Z$m%Z% e&e'Z(eee) dddZ*eee+ dddZ,d'eee+ee) ee) e
e- dddZ.e+e+dddZ/e+e+e+dddZ0eee+dddZ1d(eeee) ee+ ed d!d"Z2G d#d$ d$Z3G d%d& d&Z4dS ))z(Download files with progress indicators.    N)
HTTPStatus)BinaryIOIterableOptionalTuple)Response)ReadTimeoutError)get_download_progress_renderer)IncompleteDownloadErrorNetworkConnectionError)PyPI)Link)is_from_cache)
PipSession)HEADERSraise_for_statusresponse_chunks)format_sizeredact_auth_from_urlsplitext)respreturnc              
   C   s0   zt | jd W S  tttfy*   Y d S 0 d S )Nzcontent-length)intheaders
ValueErrorKeyError	TypeErrorr    r   P/var/www/shaz/venv/lib/python3.9/site-packages/pip/_internal/network/download.py_get_http_response_size   s    r    c                 C   s   | j d| j dS )z
    Return either the ETag or Last-Modified header (or None if neither exists).
    The return value can be used in an If-Range header.
    etagzlast-modified)r   getr   r   r   r   (_get_http_response_etag_or_last_modified    s    r#   )r   linkprogress_bartotal_lengthrange_startr   c           
      C   s   |j tjkr|j}n|j}t|}|r^|rJ| dt| dt| d}n| dt| d}t| rtt	d| n|rt	d| nt	d| t
 tjkrd}n*t| rd}n|sd}n|d	krd}nd}t| }|s|S t|||d
}	|	|S )Nz (/)zUsing cached %szResuming download %szDownloading %sFTi   )Zbar_typesizeZinitial_progress)netlocr   file_storage_domainshow_urlurl_without_fragmentr   r   r   loggerinfogetEffectiveLevelloggingINFOr   r	   )
r   r$   r%   r&   r'   url
logged_urlshow_progresschunksZrendererr   r   r   _prepare_download(   s<    r8   )filenamer   c                 C   s   t j| S )zJ
    Sanitize the "filename" value from a Content-Disposition header.
    )ospathbasename)r9   r   r   r   sanitize_content_filename[   s    r=   )content_dispositiondefault_filenamer   c                 C   s4   t j }| |d< |d}|r,tt|}|p2|S )z
    Parse the "filename" value from a Content-Disposition header, and
    return the default filename if the result is empty.
    content-typer9   )emailmessageMessage	get_paramr=   str)r>   r?   mr9   r   r   r   parse_content_dispositionb   s    

rG   )r   r$   r   c                 C   s   |j }| jd}|r t||}t|d }|sPt| jdd}|rP||7 }|s~|j| jkr~tj	| jd }|r~||7 }|S )zoGet an ideal filename from the given HTTP response, falling back to
    the link filename if not provided.
    zcontent-disposition   r@    )
r9   r   r"   rG   r   	mimetypesguess_extensionr4   r:   r;   )r   r$   r9   r>   extr   r   r   _get_http_response_filenameq   s    
rM   )sessionr$   r'   if_ranger   c              
   C   s   |j ddd }t }|r.d| d|d< |r:||d< z| j||dd	}t| W nF ty } z.|jd ustJ t	d
|jj
|  W Y d }~n
d }~0 0 |S )N#rH   r   zbytes=-RangezIf-RangeT)r   streamzHTTP error %s while getting %s)r4   splitr   copyr"   r   r   responser/   criticalstatus_code)rN   r$   r'   rO   
target_urlr   r   er   r   r   _http_get_download   s    r[   c                   @   s   e Zd ZeeeddddZeeeeef dddZ	e
eeeee edd	d
Zee eeedddZe
eeee eddddZe
eeeee ee f dddZdS )
DownloaderNrN   r%   resume_retriesr   c                 C   s&   |dksJ d|| _ || _|| _d S )Nr   z<Number of max resume retries must be bigger or equal to zero)_session_progress_bar_resume_retriesselfrN   r%   r^   r   r   r   __init__   s    zDownloader.__init__)r$   locationr   c           
      C   s   t | j|}t|}|jdd}t||}tj||}t	|d@}| 
|||d|}	|rv|	|k rv| |||||	 W d   n1 s0    Y  ||fS )z.Download the file given by link into location.zContent-TyperI   wbr   N)r[   r_   r    r   r"   rM   r:   r;   joinopen_process_response_attempt_resume)
rc   r$   re   r   r&   content_typer9   filepathcontent_filebytes_receivedr   r   r   __call__   s    


"zDownloader.__call__)r   r$   rm   rn   r&   r   c                 C   s(   t ||| j||d}| j||t|dS )z6Process the response and write the chunks to the file.)r'   )allow_partial)r8   r`   _write_chunks_to_filebool)rc   r   r$   rm   rn   r&   r7   r   r   r   ri      s    	
zDownloader._process_response)r7   rm   rp   r   c             
   C   sd   d}z$|D ]}|t |7 }|| q
W n6 ty^ } z|s@|td W Y d}~n
d}~0 0 |S )zEWrite the chunks to the file and return the number of bytes received.r   z'Connection timed out while downloading.N)lenwriter   r/   warning)rc   r7   rm   rp   rn   chunkrZ   r   r   r   rq      s     z Downloader._write_chunks_to_file)r   r$   rm   r&   rn   r   c           
   
   C   s   t |}| j}|r|r||k r|d8 }tdt|t|| j|  zNt| j|||d}|jtj	k}	|	rz| 
||\}}}|| |||||7 }W q tttfy   Y qY q0 q|r||k rt|j t|||| jddS )z9Attempt to resume the download if connection was dropped.rH   z<Attempting to resume incomplete download (%s/%s, attempt %d))r'   rO   )retriesN)r#   ra   r/   ru   r   r[   r_   rX   r   PARTIAL_CONTENT_reset_download_stateri   ConnectionErrorr   OSErrorr:   removenamer
   )
rc   r   r$   rm   r&   rn   etag_or_last_modifiedZattempts_leftZresume_respZmust_restartr   r   r   rj      s>    	




zDownloader._attempt_resume)r   rm   r   c                 C   s0   | d |  d}t|}t|}|||fS )zCReset the download state to restart downloading from the beginning.r   )seektruncater    r#   )rc   r   rm   rn   r&   r~   r   r   r   ry     s    
z Downloader._reset_download_state)__name__
__module____qualname__r   rE   r   rd   r   r   ro   r   r   r   ri   r   bytesrr   rq   rj   ry   r   r   r   r   r\      s6   
7r\   c                   @   sJ   e Zd ZeeeddddZee eee	ee	eef f  dddZ
dS )BatchDownloaderNr]   c                 C   s   t |||| _d S )N)r\   _downloaderrb   r   r   r   rd   ,  s    zBatchDownloader.__init__)linksre   r   c                 c   s,   |D ]"}|  ||\}}|||ffV  qdS )z0Download the files given by links into location.N)r   )rc   r   re   r$   rl   rk   r   r   r   ro   4  s    zBatchDownloader.__call__)r   r   r   r   rE   r   rd   r   r   r   ro   r   r   r   r   r   +  s   	r   )r   )r   N)5__doc__email.messagerA   r2   rJ   r:   httpr   typingr   r   r   r   pip._vendor.requests.modelsr   pip._vendor.urllib3.exceptionsr   pip._internal.cli.progress_barsr	   pip._internal.exceptionsr
   r   pip._internal.models.indexr   pip._internal.models.linkr   pip._internal.network.cacher   pip._internal.network.sessionr   pip._internal.network.utilsr   r   r   pip._internal.utils.miscr   r   r   	getLoggerr   r/   r   r    rE   r#   r   r8   r=   rG   rM   r[   r\   r   r   r   r   r   <module>   sV   
 3   