o
    hF+                     @   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(dedee) fddZ*dedee+ fddZ,	d,dedede+dee) dee) de
e- fddZ.de+de+fddZ/de+de+de+fd d!Z0dedede+fd"d#Z1		d-d$ededee) d%ee+ def
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   s,   zt | jd W S  tttfy   Y d S w )Nzcontent-length)intheaders
ValueErrorKeyError	TypeErrorr    r   Q/var/www/html/venv/lib/python3.10/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#   linkprogress_bartotal_lengthrange_startc           
      C   s   |j tjkr
|j}n|j}t|}|r/|r%| dt| dt| d}n
| dt| d}t| r:t	d| n|rCt	d| nt	d| t
 tjkrSd}nt| rZd}n|s_d}n	|d	krfd}nd}t| }|sp|S t|||d
}	|	|S )Nz (/)zUsing cached %szResuming download %szDownloading %sFTi   )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chunksrendererr   r   r   _prepare_download(   s<   r:   filenamec                 C   s   t j| S )zJ
    Sanitize the "filename" value from a Content-Disposition header.
    )ospathbasename)r;   r   r   r   sanitize_content_filename[   s   r?   content_dispositiondefault_filenamec                 C   s4   t j }| |d< |d}|rtt|}|p|S )z
    Parse the "filename" value from a Content-Disposition header, and
    return the default filename if the result is empty.
    content-typer;   )emailmessageMessage	get_paramr?   str)r@   rA   mr;   r   r   r   parse_content_dispositionb   s   

rI   c                 C   s   |j }| jd}|rt||}t|d }|s(t| jdd}|r(||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   rB    )
r;   r   r"   rI   r   	mimetypesguess_extensionr5   r<   r=   )r   r$   r;   r@   extr   r   r   _get_http_response_filenameq   s   
rO   sessionif_rangec              
   C   s   |j ddd }t }|rd| d|d< |r||d< z| j||dd	}t| W |S  tyI } z|jd us;J t	d
|jj
|  d }~ww )N#rJ   r   zbytes=-RangezIf-RangeT)r   streamzHTTP error %s while getting %s)r5   splitr   copyr"   r   r   responser0   criticalstatus_code)rP   r$   r'   rQ   
target_urlr   r   er   r   r   _http_get_download   s    
r]   c                   @   s   e Zd ZdedededdfddZded	edeeef fd
dZ	de
dedededee defddZdee dededefddZde
dededee deddfddZde
dedeeee ee f fddZdS )
DownloaderrP   r%   resume_retriesr   Nc                 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selfrP   r%   r_   r   r   r   __init__   s   

zDownloader.__init__r$   locationc           
      C   s   t | j|}t|}|jdd}t||}tj||}t	|d7}| 
|||d|}	|rE|	|k rO| |||||	 W d   ||fS W d   ||fS W d   ||fS 1 s\w   Y  ||fS )z.Download the file given by link into location.zContent-TyperK   wbr   N)r]   r`   r    r   r"   rO   r<   r=   joinopen_process_response_attempt_resume)
rd   r$   rf   r   r&   content_typer;   filepathcontent_filebytes_receivedr   r   r   __call__   s.   









zDownloader.__call__r   rn   ro   r&   c                 C   s(   t ||| j||d}| j||t|dS )z6Process the response and write the chunks to the file.)r'   )allow_partial)r:   ra   _write_chunks_to_filebool)rd   r   r$   rn   ro   r&   r8   r   r   r   rj      s   	
zDownloader._process_responser8   rq   c             
   C   sd   d}z|D ]}|t |7 }|| qW |S  ty1 } z|s!|td W Y d}~|S d}~ww )zEWrite the chunks to the file and return the number of bytes received.r   z'Connection timed out while downloading.N)lenwriter   r0   warning)rd   r8   rn   rq   ro   chunkr\   r   r   r   rr      s   z Downloader._write_chunks_to_filec           
   
   C   s   t |}| j}|r^|r^||k r^|d8 }tdt|t|| j|  z't| j|||d}|jtj	k}	|	r=| 
||\}}}|| |||||7 }W n tttfyU   Y qw |r^|r^||k s|rs||k rut|j t|||| jddS dS )z9Attempt to resume the download if connection was dropped.rJ   z<Attempting to resume incomplete download (%s/%s, attempt %d))r'   rQ   )retriesN)r#   rb   r0   rv   r   r]   r`   rZ   r   PARTIAL_CONTENT_reset_download_staterj   ConnectionErrorr   OSErrorr<   removenamer
   )
rd   r   r$   rn   r&   ro   etag_or_last_modifiedZattempts_leftZresume_respZmust_restartr   r   r   rk      sD   	



#
zDownloader._attempt_resumec                 C   s0   | d |  d}t|}t|}|||fS )zCReset the download state to restart downloading from the beginning.r   )seektruncater    r#   )rd   r   rn   ro   r&   r   r   r   r   rz     s   

z Downloader._reset_download_state)__name__
__module____qualname__r   rG   r   re   r   r   rp   r   r   r   rj   r   bytesrs   rr   rk   rz   r   r   r   r   r^      sj    



5r^   c                   @   sT   e Zd ZdedededdfddZdee d	edee	ee	eef f  fd
dZ
dS )BatchDownloaderrP   r%   r_   r   Nc                 C   s   t |||| _d S )N)r^   _downloaderrc   r   r   r   re   ,  s   zBatchDownloader.__init__linksrf   c                 c   s.    |D ]}|  ||\}}|||ffV  qdS )z0Download the files given by links into location.N)r   )rd   r   rf   r$   rm   rl   r   r   r   rp   4  s
   zBatchDownloader.__call__)r   r   r   r   rG   r   re   r   r   r   rp   r   r   r   r   r   +  s"    
r   )r   )r   N)5__doc__email.messagerC   r3   rL   r<   httpr   typingr   r   r   r   Zpip._vendor.requests.modelsr   Z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   r0   r   r    rG   r#   r   r:   r?   rI   rO   r]   r^   r   r   r   r   r   <module>   sj    

3
 