o
    h1                     @  s  d Z ddlmZ ddlZddlZddlZddl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 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 m!Z! ddl"m#Z# ddl$m%Z% ddl&m'Z'm(Z( ddl)m*Z*m+Z+ ddl,m-Z-m.Z.m/Z/ ddl0m1Z1m2Z2m3Z3 e4e5Z6d5ddZ7d6ddZ8	d7d8d%d&Z9d9d)d*Z:d:d-d.Z;d;d/d0Z<eG d1d2 d2Z=G d3d4 d4Z>dS )<z(Download files with progress indicators.    )annotationsN)IterableMapping)	dataclass)
HTTPStatus)BinaryIO)PreparedRequest)Response)HTTPResponse)HTTPHeaderDict)ReadTimeoutError)BarTypeget_download_progress_renderer)IncompleteDownloadErrorNetworkConnectionError)PyPI)Link)SafeFileCacheis_from_cache)CacheControlAdapter
PipSession)HEADERSraise_for_statusresponse_chunks)format_sizeredact_auth_from_urlsplitextrespr	   return
int | Nonec              
   C  s,   zt | jd W S  tttfy   Y d S w )N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)   
str | Nonec                 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-   linkr   progress_barr   total_lengthrange_startIterable[bytes]c           
      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sizeinitial_progress)netlocr   file_storage_domainshow_urlurl_without_fragmentr   r   r   loggerinfogetEffectiveLevelloggingINFOr   r   )
r   r.   r/   r0   r1   url
logged_urlshow_progresschunksrendererr'   r'   r(   _log_download/   s<   rF   filenamestrc                 C  s   t j| S )zJ
    Sanitize the "filename" value from a Content-Disposition header.
    )ospathbasename)rG   r'   r'   r(   sanitize_content_filenameb   s   rL   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-typerG   )emailmessageMessage	get_paramrL   rH   )rM   rN   mrG   r'   r'   r(   parse_content_dispositioni   s   

rU   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   rO    )
rG   r"   r,   rU   r   	mimetypesguess_extensionrA   rI   rJ   )r   r.   rG   rM   extr'   r'   r(   _get_http_response_filenamex   s   
r[   c                   @  s`   e Zd ZU dZded< ded< ded< dZd	ed
< dZd	ed< dddZdddZdddZ	dS )_FileDownloadz+Stores the state of a single link download.r   r.   r   output_filer   r6   r   r!   bytes_received
reattemptsr   boolc                 C  s   t | jd uo| j| jk S N)r`   r6   r^   selfr'   r'   r(   is_incomplete   s   z_FileDownload.is_incompletedatabytesNonec                 C  s"   |  j t|7  _ | j| d S ra   )r^   lenr]   write)rc   re   r'   r'   r(   write_chunk   s   z_FileDownload.write_chunkc                 C  s    | j d | j   d| _dS )z1Delete any saved data and reset progress to zero.r   N)r]   seektruncater^   rb   r'   r'   r(   
reset_file   s   

z_FileDownload.reset_fileN)r   r`   )re   rf   r   rg   )r   rg   )
__name__
__module____qualname____doc____annotations__r^   r_   rd   rj   rm   r'   r'   r'   r(   r\      s   
 

r\   c                   @  s`   e Zd Zd+d	d
Zd,ddZd-ddZd.ddZd/ddZd0d!d"Zd1d$d%Z	e
fd2d(d)Zd*S )3
Downloadersessionr   r/   r   resume_retriesr!   r   rg   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)rc   rt   r/   ru   r'   r'   r(   __init__   s   

zDownloader.__init__linksIterable[Link]locationrH   &Iterable[tuple[Link, tuple[str, str]]]c                 c  s,    |D ]}| ||\}}|||ffV  qdS )z.Convenience method to download multiple links.Nr'   )rc   rz   r|   r.   filepathcontent_typer'   r'   r(   batch   s
   zDownloader.batchr.   r   tuple[str, str]c           	      C  s   |  |}t|}tj|t||}t|d}t|||}| || |	 r/| 
|| W d   n1 s9w   Y  |jdd}||fS )z+Download a link and save it under location.wbNzContent-TyperW   )	_http_getr)   rI   rJ   joinr[   openr\   _process_responserd   _attempt_resumes_or_redownloadsr"   r,   )	rc   r.   r|   r   download_sizer~   content_filedownloadr   r'   r'   r(   __call__   s   
zDownloader.__call__r   r\   r   r	   c              
   C  st   t ||j| j|j|jd}z|D ]}|| qW dS  ty9 } z|jdu r)|td W Y d}~dS d}~ww )z)Download and save chunks from a response.)r1   Nz'Connection timed out while downloading.)	rF   r.   rw   r6   r^   rj   r   r<   warning)rc   r   r   rD   chunker'   r'   r(   r      s"   
zDownloader._process_response
first_respc              
   C  s   |j | jk r`| r`|jdusJ | j d7  _ tdt|jt|j|j  z"| j||d}|j	t
jk}|rB|  t||_|}| || W n tttfyU   Y q w |j | jk r`| s
| rot|jj t||j dkr|| || dS dS )zAAttempt to resume/restart the download if connection was dropped.NrV   z<Attempting to resume incomplete download (%s/%s, attempt %d))should_matchr   )r_   rx   rd   r6   r<   r   r   r^   _http_get_resumestatus_coder   PARTIAL_CONTENTrm   r)   r   ConnectionErrorr   OSErrorrI   remover]   namer   _cache_resumed_download)rc   r   r   resume_respmust_restartr'   r'   r(   r      s6   

z*Downloader._attempt_resumes_or_redownloadsoriginal_responsec                 C  s&  |j j}| j|}t|tstd| dS t|jt	s!J dt
 }|jd|i d t }|j D ]\}}| dvrB|||< q4t|j|d< td|d	d
d}	|j|}
|jj||	d}|j|
| |j  t|jjd}|j|
| W d   n1 sw   Y  td| dS )an  
        Manually cache a file that was successfully downloaded via resume retries.

        cachecontrol doesn't cache 206 (Partial Content) responses, since they
        are not complete files. This method manually adds the final file to the
        cache as though it was downloaded in a single request, so that future
        requests can use the cache.
        z<Skipping resume download caching: no cache controller for %sNzseparate body cache not in use!GET)methodrA   r"   )zcontent-ranger    r    rW      F)bodyr"   statuspreload_content    rbz?Cached resumed download as complete response for future use: %s)r.   r;   rv   get_adapter
isinstancer   r<   debugcacher   r   preparer   r"   itemslowerrH   r6   URLlib3Response
controller	cache_url
serializerdumpssetr]   flushr   r   set_body_from_io)rc   r   r   rA   adaptersynthetic_requestsynthetic_response_headerskeyvaluesynthetic_responser   metadata_blobfr'   r'   r(   r     sL   

z"Downloader._cache_resumed_downloadr   c                 C  s<   t  }d|j d|d< t| }r||d< | |j|S )z2Issue a HTTP range request to resume the download.zbytes=-RangezIf-Range)r   copyr^   r-   r   r.   )rc   r   r   r"   
identifierr'   r'   r(   r   =  s
   zDownloader._http_get_resumer"   Mapping[str, str]c              
   C  sb   |j }z| jj||dd}t| W |S  ty0 } z|jd us"J td|jj|  d }~ww )NT)r"   streamzHTTP error %s while getting %s)	r;   rv   r,   r   r   responser<   criticalr   )rc   r.   r"   
target_urlr   r   r'   r'   r(   r   K  s   

zDownloader._http_getN)rt   r   r/   r   ru   r!   r   rg   )rz   r{   r|   rH   r   r}   )r.   r   r|   rH   r   r   )r   r\   r   r	   r   rg   )r   r\   r   r	   r   rg   )r   r\   r   r	   r   rg   )r   r\   r   r	   r   r	   )r.   r   r"   r   r   r	   )rn   ro   rp   ry   r   r   r   r   r   r   r   r   r'   r'   r'   r(   rs      s    





(
8rs   )r   r	   r   r   )r   r	   r   r*   )r   )r   r	   r.   r   r/   r   r0   r   r1   r   r   r2   )rG   rH   r   rH   )rM   rH   rN   rH   r   rH   )r   r	   r.   r   r   rH   )?rq   
__future__r   email.messagerP   r?   rX   rI   collections.abcr   r   dataclassesr   httpr   typingr   pip._vendor.requestsr   pip._vendor.requests.modelsr	   pip._vendor.urllib3r
   r    pip._vendor.urllib3._collectionsr   pip._vendor.urllib3.exceptionsr   pip._internal.cli.progress_barsr   r   pip._internal.exceptionsr   r   pip._internal.models.indexr   pip._internal.models.linkr   pip._internal.network.cacher   r   pip._internal.network.sessionr   r   pip._internal.network.utilsr   r   r   pip._internal.utils.miscr   r   r   	getLoggerrn   r<   r)   r-   rF   rL   rU   r[   r\   rs   r'   r'   r'   r(   <module>   sD    



3

