3
ûâdeÊ"  ã               @   s¬  d 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m	Z	m
Z
 ddlmZ ddlmZ ddlmZmZmZmZ ddlmZ ejeƒZee ZyddlZee7 ZW n ek
rÈ   ejdƒ Y nX yddlZee7 ZW n ek
rü   ejd	ƒ Y nX ed
œdd„Zee	e dœdd„Z ee e!dœdd„Z"eee!dœdd„Z#eddœdd„Z$ee!dœdd„Z%d%eee!ddœdd„Z&eeddœd d!„Z'd&eee
e dd"œd#d$„Z(dS )'zUtilities related archives.
é    N)ÚIterableÚListÚOptional)ÚZipInfo)ÚInstallationError)ÚBZ2_EXTENSIONSÚTAR_EXTENSIONSÚXZ_EXTENSIONSÚZIP_EXTENSIONS)Ú
ensure_dirzbz2 module is not availablezlzma module is not available)Úreturnc              C   s   t jdƒ} t j| ƒ | S )zBGet the current umask which involves having to set it temporarily.r   )ÚosÚumask)Úmask© r   ú</tmp/pip-build-red6nood/pip/pip/_internal/utils/unpacking.pyÚcurrent_umask+   s    

r   )Úpathr   c             C   sh   | j dƒj dƒ} d| krHd| kr4| jdƒ| jdƒk s<d| krH| jddƒS d| kr\| jddƒS | dgS d S )Nú/ú\é   Ú )ÚlstripÚfindÚsplit)r   r   r   r   Úsplit_leading_dir2   s    $r   )Úpathsr   c             C   sD   d}x:| D ]2}t |ƒ\}}|s"dS |dkr0|}q
||kr
dS q
W dS )zyReturns true if all the paths have the same leading path name
    (i.e., everything is in one subdirectory in an archive)NFT)r   )r   Úcommon_prefixr   ÚprefixÚrestr   r   r   Úhas_leading_dir>   s    
r    )Ú	directoryÚtargetr   c             C   s0   t jj| ƒ}t jj|ƒ}t jj||gƒ}||kS )zL
    Return true if the absolute path of target is within the directory
    )r   r   ÚabspathÚcommonprefix)r!   r"   Zabs_directoryZ
abs_targetr   r   r   r   Úis_within_directoryM   s    r%   c             C   s   t j| dtƒ  @ dB ƒ dS )zx
    Make file present at path have execute for user/group/world
    (chmod +x) is no-op on windows per python docs
    iÿ  éI   N)r   Úchmodr   )r   r   r   r   Ú2set_extracted_file_to_default_mode_plus_executableX   s    r(   )Úinfor   c             C   s$   | j d? }t|o tj|ƒo |d@ ƒS )Né   r&   )Úexternal_attrÚboolÚstatÚS_ISREG)r)   Úmoder   r   r   Úzip_item_is_executable`   s    
r0   T)ÚfilenameÚlocationÚflattenr   c             C   s  t |ƒ t| dƒ}zütj|dd�}t|jƒ ƒo0|}xØ|jƒ D ]Ì}|j}|}|rZt|ƒd }t	j
j||ƒ}t	j
j|ƒ}	t||ƒs”d}
t|
j| ||ƒƒ‚|jdƒs¨|jdƒr²t |ƒ q<t |	ƒ |j|ƒ}z&t|dƒ�}tj||ƒ W d	Q R X W d	|jƒ  t|ƒ�rt|ƒ X q<W W d	|jƒ  X d	S )
aŸ  
    Unzip the file (with path `filename`) to the destination `location`.  All
    files are written based on system defaults and umask (i.e. permissions are
    not preserved), except that regular file members with any execute
    permissions (user, group, or world) have "chmod +x" applied after being
    written. Note that for windows, any execute changes using os.chmod are
    no-ops per the python docs.
    ÚrbT)Ú
allowZip64r   zQThe zip file ({}) has a file ({}) trying to install outside target directory ({})r   r   ÚwbN)r   ÚopenÚzipfileÚZipFiler    ÚnamelistÚinfolistr1   r   r   r   ÚjoinÚdirnamer%   r   ÚformatÚendswithÚshutilÚcopyfileobjÚcloser0   r(   )r1   r2   r3   ÚzipfpÚzipÚleadingr)   ÚnameÚfnÚdirÚmessageÚfpÚdestfpr   r   r   Ú
unzip_fileg   s4    	




rL   )r1   r2   r   c             C   s(  t |ƒ | jƒ jdƒs$| jƒ jdƒr*d}nL| jƒ jtƒr>d}n8| jƒ jtƒrRd}n$| jƒ jdƒrfd}ntjd| ƒ d	}tj| |d
d�}�z�t	dd„ |j
ƒ D ƒƒ}�xr|j
ƒ D �]d}|j}|rÈt|ƒd }tjj||ƒ}t||ƒsöd}t|j| ||ƒƒ‚|jƒ �r
t |ƒ q¬|jƒ �r`y|j||ƒ W n8 tk
�r\ }	 ztjd| |j|	ƒ w¬W Y dd}	~	X nX q¬y|j|ƒ}
W n< ttfk
�rª }	 ztjd| |j|	ƒ w¬W Y dd}	~	X nX t tjj|ƒƒ |
dk	�sÊt‚t|dƒ�}tj|
|ƒ W dQ R X |
jƒ  |j||ƒ |j d@ r¬t!|ƒ q¬W W d|jƒ  X dS )aŸ  
    Untar the file (with path `filename`) to the destination `location`.
    All files are written based on system defaults and umask (i.e. permissions
    are not preserved), except that regular file members with any execute
    permissions (user, group, or world) have "chmod +x" applied after being
    written.  Note that for windows, any execute changes using os.chmod are
    no-ops per the python docs.
    z.gzz.tgzzr:gzzr:bz2zr:xzz.tarÚrz-Cannot determine compression type for file %szr:*zutf-8)Úencodingc             S   s   g | ]
}|j ‘qS r   )rF   )Ú.0Úmemberr   r   r   ú
<listcomp>¯   s    zuntar_file.<locals>.<listcomp>r   zQThe tar file ({}) has a file ({}) trying to install outside target directory ({})z/In the tar file %s the member %s is invalid: %sNr6   r&   )"r   Úlowerr?   r   r	   ÚloggerÚwarningÚtarfiler7   r    Ú
getmembersrF   r   r   r   r<   r%   r   r>   ÚisdirÚissymÚ_extract_memberÚ	ExceptionÚextractfileÚKeyErrorÚAttributeErrorr=   ÚAssertionErrorr@   rA   rB   Úutimer/   r(   )r1   r2   r/   ÚtarrE   rP   rG   r   rI   ÚexcrJ   rK   r   r   r   Ú
untar_file•   sl    	




rb   )r1   r2   Úcontent_typer   c             C   sš   t jj| ƒ} |dks,| jƒ jtƒs,tj| ƒrDt| || jdƒ d� nR|dkslt	j
| ƒsl| jƒ jtt t ƒrxt| |ƒ ntjd| ||ƒ td|› �ƒ‚d S )Nzapplication/zipz.whl)r3   zapplication/x-gzipzZCannot unpack file %s (downloaded from %s, content-type: %s); cannot detect archive formatz#Cannot determine archive format of )r   r   ÚrealpathrR   r?   r
   r8   Ú
is_zipfilerL   rU   Ú
is_tarfiler   r   r	   rb   rS   Úcriticalr   )r1   r2   rc   r   r   r   Úunpack_fileæ   s    

rh   )T)N))Ú__doc__Úloggingr   r@   r-   rU   r8   Útypingr   r   r   r   Zpip._internal.exceptionsr   Zpip._internal.utils.filetypesr   r   r	   r
   Zpip._internal.utils.miscr   Ú	getLoggerÚ__name__rS   ÚSUPPORTED_EXTENSIONSÚbz2ÚImportErrorÚdebugÚlzmaÚintr   Ústrr   r,   r    r%   r(   r0   rL   rb   rh   r   r   r   r   Ú<module>   sB   
.T