B
    l‚z]/  ã               @   sÎ  d dl mZmZmZmZ d dlZd dlmZ d dlmZm	Z	 d dl
Z
d dl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 yd dlmZmZmZmZ W n, ek
rÜ   d dlmZmZmZmZ Y nX dd„ Z edd„ ƒZ!dZ"edd„ ƒZ#edd„ ƒZ$dd„ Z%dd„ Z&dd„ Z'dd„ Z(dd„ Z)d d!„ Z*d"d#„ Z+e+Z,d$d%„ Z-d&d'„ Z.d(d)„ Z/d*d+„ Z0d,d-„ Z1d.d/„ Z2d0d1„ Z3d2d3„ Z4ed4d5„ ƒZ5d6d7„ Z6d>d9d:„Z7d;d<„ Z8e9d=krÊd dl:Z:e: ;¡  dS )?é    )Úabsolute_importÚdivisionÚprint_functionÚunicode_literalsN)Úgetpass)ÚabspathÚ
expanduseré   )ÚinputÚon_win)Úsplit_filenameÚstrip_pkg_extensioné   )Úmemoize)ÚLocationParseError)ÚUrlÚ	parse_url)ÚquoteÚ
quote_plusÚunquoteÚunquote_plusc             C   sd   t | ƒ} t dƒ}t dƒ}t dƒ}t dƒ}| |kr@| |kr@| | n| |kr\| |kr\| | d nd }|S )NÚ0Ú9ÚAÚFé
   )Úord)ZhoZo0Zo9ZoAZoFZres© r   ú/lib/python3.7/site-packages/conda/common/url.pyÚhex_octal_to_int   s    8r   c       
   
   C   sü   d| kr| S g }x*t  d| ¡D ]}| | ¡ | ¡ f¡ qW t|ƒsH| S d}d}xœt| ƒD ]\}}|dkrt|d8 }qZ| d¡}|}|dkrÞxR|D ]J}||d krdd l}	|	 	dt
| |d  ƒd	 t
| |d
  ƒ ¡}d
}P qW |rZ||7 }qZW t |¡d S )Nú%z(%[0-9A-F]{2})ó    r   r	   Úasciió   %ÚBé   r   )ÚreÚfinditerÚappendÚstartÚendÚlenÚ	enumerateÚencodeÚstructZpackr   ÚcodecsÚutf_8_decode)
ÚpathZrangesÚmÚresultZskipsÚiÚcÚemitÚrr.   r   r   r   Úpercent_decode$   s4    

(r8   zfile://c                sÞ   | st d|  ƒ‚|  t¡rNy|  d¡ W n  tk
rH   t d|  ƒ‚Y nX | S tt| ƒƒ dd¡} d‰ ‡ fdd„}td	d
„ | D ƒƒr¬|t	| dƒrš|  d¡nt
| dƒ d¡ƒ} t| ƒdkrÒ| d dkrÒtd |  } nt|  } | S )NzNot allowed: %rr"   z8Non-ascii not allowed for things claiming to be URLs: %rú\ú/z!'()*-._/\:c                s   d  ‡ fdd„| D ƒ¡S )NÚ c             3   s6   | ].}d t |ƒ |g|dk r$| ¡ p*|ˆ k V  qdS )z%%%02XÚ{N)r   Úisalnum)Ú.0r5   )Úpercent_encode_charsr   r   ú	<genexpr>n   s   z0path_to_url.<locals>.<lambda>.<locals>.<genexpr>)Újoin)Ús)r?   r   r   Ú<lambda>n   s   zpath_to_url.<locals>.<lambda>c             s   s   | ]}t |ƒd kV  qdS )é€   N)r   )r>   Úcharr   r   r   r@   q   s    zpath_to_url.<locals>.<genexpr>Údecodezunicode-escapezutf-8r	   ú:)Ú
ValueErrorÚ
startswithÚfile_schemerF   ÚUnicodeDecodeErrorr   r   ÚreplaceÚanyÚhasattrÚbytesr+   )r1   Zpercent_encoder   )r?   r   Úpath_to_urlU   s&    
rP   c             C   s"   t r|  d¡r|  dd¡ t| ƒS )Nzfile:r9   r:   )r   rI   rL   r   )Úurlr   r   r   Úurlparse~   s    rR   c             C   s4   t | ƒ}|jdkstd|  ƒ‚|j|j }}||fS )z¼Convert an s3 url to a tuple of bucket and key.

    Examples:
        >>> url_to_s3_info("s3://bucket-name.bucket/here/is/the/key")
        ('bucket-name.bucket', '/here/is/the/key')
    Zs3z"You can only use s3: urls (not %r))r   ÚschemeÚAssertionErrorÚhostr1   )rQ   Z
parsed_urlZbucketÚkeyr   r   r   Úurl_to_s3_info…   s    rW   c             C   s0   | sdS yt | ƒjdk	S  tk
r*   dS X dS )zn
    Examples:
        >>> is_url(None)
        False
        >>> is_url("s3://some/bucket")
        True
    FN)rR   rS   r   )rQ   r   r   r   Úis_url’   s    rX   c             C   s4   yt  | ¡ W n t jk
r$   dS X |  d¡dkS )a  
    Examples:
        >>> [is_ipv4_address(ip) for ip in ('8.8.8.8', '192.168.10.10', '255.255.255.255')]
        [True, True, True]
        >>> [is_ipv4_address(ip) for ip in ('8.8.8', '192.168.10.10.20', '256.255.255.255', '::1')]
        [False, False, False, False]
    FÚ.é   )ÚsocketZ	inet_atonÚerrorÚcount)Ú	string_ipr   r   r   Úis_ipv4_address¢   s
    r_   c             C   sP   y
t j}W n tk
r"   t| ƒS X y|t j| ƒ W n t jk
rJ   dS X dS )zô
    Examples:
        >> [is_ipv6_address(ip) for ip in ('::1', '2001:db8:85a3::370:7334', '1234:'*7+'1234')]
        [True, True, True]
        >> [is_ipv6_address(ip) for ip in ('192.168.10.10', '1234:'*8+'1234')]
        [False, False]
    FT)r[   Ú	inet_ptonÚAttributeErrorÚis_ipv6_address_win_py27ZAF_INET6r\   )r^   r`   r   r   r   Úis_ipv6_address±   s    

rc   c             C   s   t tjd| tjtjB dƒS )zç
    Examples:
        >>> [is_ipv6_address_win_py27(ip) for ip in ('::1', '1234:'*7+'1234')]
        [True, True]
        >>> [is_ipv6_address_win_py27(ip) for ip in ('192.168.10.10', '1234:'*8+'1234')]
        [False, False]
    z”^(((?=.*(::))(?!.*\3.+\3))\3?|[\dA-F]{1,4}:)([\dA-F]{1,4}(\3|:\b)|\2){5}(([\dA-F]{1,4}(\3|:\b|$)|\2){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4})\Z)Úflags)Úboolr&   ÚmatchÚDOTALLÚ
IGNORECASE)r^   r   r   r   rb   Ä   s    	rb   c             C   s   t | ƒpt| ƒS )z°
    Examples:
        >> is_ip_address('192.168.10.10')
        True
        >> is_ip_address('::1')
        True
        >> is_ip_address('www.google.com')
        False
    )r_   rc   )r^   r   r   r   Úis_ip_addressÖ   s    
ri   c              G   s@   | d r| d   d¡rdnd}|d dd„ dd„ | D ƒD ƒ¡ S )Nr   r:   r;   c             s   s   | ]}|r|V  qd S )Nr   )r>   Úyr   r   r   r@   å   s    zjoin.<locals>.<genexpr>c             s   s   | ]}|r|  d ¡V  qdS )r:   N)Ústrip)r>   Úxr   r   r   r@   å   s    )rI   rA   )Úargsr)   r   r   r   rA   ã   s    rA   c             C   s   t  d| ¡S )Nz[a-z][a-z0-9]{0,11}://)r&   rf   )Úvaluer   r   r   Ú
has_schemeë   s    ro   c             C   s   |   dd¡d S )z¾
    Examples:
        >>> strip_scheme("https://www.conda.io")
        'www.conda.io'
        >>> strip_scheme("s3://some.bucket/plus/a/path.ext")
        'some.bucket/plus/a/path.ext'
    z://r	   éÿÿÿÿ)Úsplit)rQ   r   r   r   Ústrip_schemeï   s    rr   c             C   s"   t | ƒ\}}|r|  |dd¡S | S )Nz<TOKEN>r	   )Úsplit_anaconda_tokenrL   )rQ   Ú_Útokenr   r   r   Úmask_anaconda_tokenú   s    rv   c             C   sL   t  d| ¡}|r| ¡ d nd}|dk	r:|  d| dd¡n| }| d¡|fS )aÛ  
    Examples:
        >>> split_anaconda_token("https://1.2.3.4/t/tk-123-456/path")
        (u'https://1.2.3.4/path', u'tk-123-456')
        >>> split_anaconda_token("https://1.2.3.4/t//path")
        (u'https://1.2.3.4/path', u'')
        >>> split_anaconda_token("https://some.domain/api/t/tk-123-456/path")
        (u'https://some.domain/api/path', u'tk-123-456')
        >>> split_anaconda_token("https://1.2.3.4/conda/t/tk-123-456/path")
        (u'https://1.2.3.4/conda/path', u'tk-123-456')
        >>> split_anaconda_token("https://1.2.3.4/path")
        (u'https://1.2.3.4/path', None)
        >>> split_anaconda_token("https://10.2.3.4:8080/conda/t/tk-123-45")
        (u'https://10.2.3.4:8080/conda', u'tk-123-45')
    z/t/([a-zA-Z0-9-]*)r   Nz/t/r;   r	   r:   )r&   ÚsearchÚgroupsrL   Úrstrip)rQ   Z_token_matchru   Úcleaned_urlr   r   r   rs   ÿ   s    rs   c             C   sh   dd  dd„ |D ƒ¡ }t || tj¡}|r8| ¡ d nd}|dk	rV|  d| dd	¡n| }| d¡|fS )
zæ

    Examples:
        >>> from conda.base.constants import PLATFORM_DIRECTORIES
        >>> split_platform("https://1.2.3.4/t/tk-123/osx-64/path", PLATFORM_DIRECTORIES)
        (u'https://1.2.3.4/t/tk-123/path', u'osx-64')

    z/(%s)/?ú|c             s   s   | ]}d | V  qdS )z%sNr   )r>   Údr   r   r   r@     s    z!split_platform.<locals>.<genexpr>r   Nr:   r;   r	   )rA   r&   rw   rh   rx   rL   ry   )rQ   Úknown_subdirsZ_platform_match_regexZ_platform_matchÚplatformrz   r   r   r   Úsplit_platform  s
    	r   c             C   s4   t | ƒ\}}|sd S | dd¡d }||kr0|p2d S )Nr:   r	   rp   )r   Úrsplit)rQ   r}   Zurl_no_package_namert   Zmaybe_a_platformr   r   r   Úhas_platform%  s
    r   c             C   sF   | sdS t | ƒ\}}t|ƒ}t|j|j|j|jdj}||j|j	|fS )zð
    Examples:
        >>> split_scheme_auth_token("https://u:p@conda.io/t/x1029384756/more/path")
        ('conda.io/more/path', 'https', 'u:p', 'x1029384756')
        >>> split_scheme_auth_token(None)
        (None, None, None, None)
    )NNNN)rU   Úportr1   Úquery)
rs   rR   r   rU   r‚   r1   rƒ   rQ   rS   Úauth)rQ   rz   ru   Ú	url_partsZremainder_urlr   r   r   Úsplit_scheme_auth_token-  s    r†   c       	   	   C   sl   t | ƒ\}}t||ƒ\}}t|ƒ\}}|r6| dd¡n|d f\}}t|ƒ}|j|j||||j|j|j	|j
f	S )Nr:   r	   )rs   r   r   r€   rR   rS   r„   rU   r‚   r1   rƒ   )	rQ   r}   rz   ru   r~   rt   ZextZpackage_filenamer…   r   r   r   Úsplit_conda_url_easy_parts>  s    r‡   c             C   s   t d|  ƒ}tdƒ}||fS )Nz
%s proxy username: z
Password: )r
   r   )rS   ÚusernameZpasswdr   r   r   Úget_proxy_username_and_passM  s    r‰   c             C   s.   t | ƒ ¡ }|d t|dƒ |d< tf |ŽjS )NrG   r;   r„   )r   Ú_asdictr   r   rQ   )rQ   rˆ   Zpasswordr…   r   r   r   Úadd_username_and_passwordT  s    r‹   Fc             C   s8   |s| S t | ƒ ¡ }|d r$|s$| S ||d< tf |ŽjS )a~  Add auth if the url doesn't currently have it.

    By default, does not replace auth if it already exists.  Setting ``force`` to ``True``
    overrides this behavior.

    Examples:
        >>> maybe_add_auth("https://www.conda.io", "user:passwd")
        'https://user:passwd@www.conda.io'
        >>> maybe_add_auth("https://www.conda.io", "")
        'https://www.conda.io'
    r„   )rR   rŠ   r   rQ   )rQ   r„   Zforcer…   r   r   r   Úmaybe_add_authZ  s    rŒ   c             C   s   | rt | ƒS | S )N)r   )rQ   r   r   r   Úmaybe_unquoteo  s    r   Ú__main__)F)<Z
__future__r   r   r   r   r/   r   Úos.pathr   r   r&   r[   Úcompatr
   r   r1   r   r   Z_vendor.auxlib.decoratorsr   Z_vendor.urllib3.exceptionsr   Z_vendor.urllib3.util.urlr   r   Zurllib.parser   r   r   r   ÚImportErrorZurllibr   r8   rJ   rP   rR   rW   rX   r_   rc   rb   ri   rA   Zjoin_urlro   rr   rv   rs   r   r   r†   r‡   r‰   r‹   rŒ   r   Ú__name__ZdoctestZtestmodr   r   r   r   Ú<module>   sT   
#)

