U
    b.>                     @   sH  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	 d dl
m
Z
 d dlmZm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 z(d d
lmZmZmZmZmZmZmZ W n4 e k
r   d dl!mZmZmZmZmZmZ Y nX dd Z"e	dddd Z#dZ$e	dddd Z%dZ&G dd dede&Z'e	dde(e'd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' Z0d(d) Z1d*d+ Z2d,d- Z3d.d/ Z4e	ddd0d1 Z5d2d3 Z6d4d5 Z7d6d7 Z8e	ddd8d9 Z9e(e(e(e(d:d;d<Z:dHe(e(e(d>d?d@Z;dAdB Z<e(e(ddCdDZ=dEdF Z>e?dGkrDd dl@Z@e@A  dS )I    )absolute_importdivisionprint_functionunicode_literalsN)
namedtuple)	lru_cache)getpass)abspath
expanduser   )on_win)split_filenamestrip_pkg_extension)quote
quote_plusunquoteunquote_plusurlparse
urlunparseParseResult)r   r   r   r   r   r   c                 C   sh   t |  } t d}t d}t d}t d}| |krD| |krD| | n| |kr`| |kr`| | d nd }|S )N09AF
   )ordupper)ZhoZo0Zo9ZoAZoFres r   /lib/python3.8/site-packages/conda/common/url.pyhex_octal_to_int#   s    8r    )maxsizec           
   
   C   s   d| kr| S g }t jd| t jdD ]}|| | f q"t|sJ| S d}d}t| D ]\}}|dkrt|d8 }qZ|d}|}|dkr|D ]L}||d krdd l	}	|	
d	t| |d  d
 t| |d   }d} qq|rZ||7 }qZt|d S )N%z(%[0-9A-F]{2}))flags    r   r   ascii   %B      )refinditer
IGNORECASEappendstartendlen	enumerateencodestructZpackr    codecsutf_8_decode)
pathZrangesmresultZskipsicemitrr3   r   r   r   percent_decode-   s8    
 "
r=   zfile://c                    s   | st d|  | trNz| 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rt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).0r:   Zpercent_encode_charsr   r   	<genexpr>w   s   z0path_to_url.<locals>.<lambda>.<locals>.<genexpr>)join)srD   r   r   <lambda>w   s   zpath_to_url.<locals>.<lambda>c                 s   s   | ]}t |d kV  qdS )   N)r   )rC   charr   r   r   rE   z   s     zpath_to_url.<locals>.<genexpr>decodezunicode-escapezutf-8r   :)
ValueError
startswithfile_schemerK   UnicodeDecodeErrorr	   r
   replaceanyhasattrbytesr0   )r6   Zpercent_encoder   rD   r   path_to_url^   s*    
rU   )schemer6   queryfragmentusernamepasswordhostnameportc                       sr   e Zd ZdZd fdd	Zedd Zedd Zd	d
 Ze	dddZ
d dddZeed dddZ  ZS )Urla  
    Object used to represent a Url. The string representation of this object is a url string.

    This object was inspired by the urllib3 implementation as it gives you a way to construct
    URLs from various parts. The motivation behind this object was making something that is
    interoperable with built the `urllib.parse.urlparse` function and has more features than
    the built-in `ParseResult` object.
    Nc	           	         sN   |r| dsd| }|r"| }|r.| }tt| | ||||||||	S )Nr?   )rN   lowersuperr]   __new__)	clsrV   r6   rW   rX   rY   rZ   r[   r\   	__class__r   r   r`      s"    
        zUrl.__new__c                 C   s.   | j r| jr| j  d| j S | j r*| j S d S NrL   rY   rZ   selfr   r   r   auth   s    zUrl.authc                 C   s   | j r| j d| j  S | jS rd   )r\   r[   rf   r   r   r   netloc   s    z
Url.netlocc           
      C   s   | \}}}}}}}}d}	|r*|	| d7 }	|rF|rF|	| d| d7 }	|rR|	|7 }	|rd|	d| 7 }	|rp|	|7 }	|r|	d| 7 }	|r|	d| 7 }	|	S )Nr@   ://rL   @?#r   )
rg   rV   r6   rW   rX   rY   rZ   r[   r\   urlr   r   r   __str__   s"    zUrl.__str__)returnc                 C   s   |   S )z3Provide a public interface for namedtuple's _asdict)_asdictrf   r   r   r   as_dict   s    zUrl.as_dictc                 K   s   | j f |S )z4Provide a public interface for namedtuple's _replace)_replace)rg   kwargsr   r   r   rQ      s    zUrl.replace)parse_resultrp   c                    s    fddt D }| f |S )Nc                    s   i | ]}|t  |d qS )r@   )getattr)rC   Zfldru   r   r   
<dictcomp>   s      z)Url.from_parse_result.<locals>.<dictcomp>)	url_attrs)ra   ru   valuesr   rw   r   from_parse_result   s    zUrl.from_parse_result)NNNNNNNN)__name__
__module____qualname____doc__r`   propertyrh   ri   ro   dictrr   rQ   classmethodr   r{   __classcell__r   r   rb   r   r]      s&           

r]   )rn   rp   c                 C   s8   t r| dr| dd t| s*d|  } tt| S )Nfile:r>   r?   z//)r   rN   rQ   
has_schemer]   r{   	_urlparsern   r   r   r   r      s
    r   c                 C   s4   t | }|jdkstd|  |j|j }}||fS )zConvert 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   rV   AssertionErrorr[   r6   )rn   Z
parsed_urlZbucketkeyr   r   r   url_to_s3_info   s    r   c                 C   s4   | sdS zt | jdkW S  tk
r.   Y dS X dS )zn
    Examples:
        >>> is_url(None)
        False
        >>> is_url("s3://some/bucket")
        True
    Fr@   N)r   rV   rM   r   r   r   r   is_url   s    r   c                 C   s6   zt |  W n t jk
r&   Y 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Z	string_ipr   r   r   is_ipv4_address	  s
    r   c                 C   s0   zt t j|  W n t jk
r*   Y 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   Z	inet_ptonZAF_INET6r   r   r   r   r   is_ipv6_address  s
    r   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   r   r   r   r   r   is_ip_address'  s    
r   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   )rC   yr   r   r   rE   6  s      zjoin.<locals>.<genexpr>c                 s   s   | ]}|r| d V  qdS )r?   N)strip)rC   xr   r   r   rE   6  s      )rN   rF   )argsr.   r   r   r   rF   4  s    rF   c                 C   s   t d| S )Nz[a-z][a-z0-9]{0,11}://)r*   match)valuer   r   r   r   <  s    r   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'
    rj   r   )splitr   r   r   r   strip_scheme@  s    r   c                 C   s"   t | \}}|r| |ddS | S )Nz<TOKEN>r   )split_anaconda_tokenrQ   )rn   _tokenr   r   r   mask_anaconda_tokenK  s    r   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groupsrQ   rstrip)rn   Z_token_matchr   cleaned_urlr   r   r   r   P  s    r   c                 C   sN   t | |}|r| d nd}|dk	r<|d| ddn|}|d|fS )z

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

    r   Nr?   r@   r   )_split_platform_rer   r   rQ   r   )known_subdirsrn   Z_platform_matchplatformr   r   r   r   split_platformf  s    	r   c                 C   s&   dd dd | D  }t|tjS )Nz/(%s)(?:/|$)|c                 s   s   | ]}d | V  qdS )z%sNr   )rC   dr   r   r   rE   w  s     z%_split_platform_re.<locals>.<genexpr>)rF   r*   compiler,   )r   Z_platform_match_regexr   r   r   r   u  s    r   c                 C   s4   t | \}}|sd S |ddd }||kr0|p2d S )Nr?   r   r   )r   rsplit)rn   r   Zurl_no_package_namer   Zmaybe_a_platformr   r   r   has_platform{  s
    r   c                 C   sH   | sdS t | \}}t|}t|j|j|j|jd}t||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)r[   r\   r6   rW   )
r   r   r]   r[   r\   r6   rW   strrV   rh   )rn   r   r   	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   )r   r   r   r   r   rV   rh   r[   r\   r6   rW   )	r   rn   r   r   r   r   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: )inputr   )rV   rY   Zpasswdr   r   r   get_proxy_username_and_pass  s    r   )rn   rY   rZ   rp   c                 C   s&   t | } | j|t|ddd}t|S )z
    Inserts `username` and `password` into provided `url`

    >>> add_username_and_password('https://anaconda.org', 'TestUser', 'Password')
    'https://TestUser:Password@anaconda.org'
    r@   )Zsafere   )r   rQ   r   r   )rn   rY   rZ   Zurl_with_authr   r   r   add_username_and_password  s    r   F)rn   rh   rp   c                 C   sX   |s| S t | }|jr$|jr$|s$| S |d}t|dkrP|j|d |d d}t|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'
    rL   r   r   re   )r   rY   rZ   r   r0   rQ   r   )rn   rh   Zforcer   Z
auth_partsr   r   r   maybe_add_auth  s    
r   c                 C   s   | rt t| S | S r   )r   remove_authr   r   r   r   maybe_unquote  s    r   c                 C   s   t | } | jddd}t|S )zZ
    >>> remove_auth('https://user:password@anaconda.com')
    'https://anaconda.com'
    r@   re   )r   rQ   r   )rn   Zurl_no_authr   r   r   r     s    r   c                 C   s   t dt | dr2d| kr"| S tr2| dd} t| }|jr|j	d}tr|j
rt|j
dkr|j
d dkrd|j
gd	d
 |D  }|jdd}qd|d d dd
 |dd  D  }nddd
 |D }|j|d}t|S | S )Nz^This function lives now under conda-libmamba-solver and will be deprecated in a future releaser   r"   r>   r?   r)   r   rL   c                 S   s   g | ]}t |qS r   r   rC   pr   r   r   
<listcomp>  s     z&escape_channel_url.<locals>.<listcomp>r@   )ri   c                 S   s   g | ]}t |qS r   r   r   r   r   r   r      s     c                 S   s   g | ]}t |qS r   r   r   r   r   r   r     s     )r6   )warningswarnPendingDeprecationWarningrN   r   rQ   r   rV   r6   r   ri   r0   rF   r   )ZchannelpartsZ
componentsr6   r   r   r   escape_channel_url  s*    
"*r   __main__)F)BZ
__future__r   r   r   r   r4   collectionsr   	functoolsr   r   os.pathr	   r
   r*   r   r   compatr   r6   r   r   Zurllib.parser   r   r   r   r   r   r   Z_urlunparser   ImportErrorZurllibr    r=   rO   rU   ry   r]   r   r   r   r   r   r   rF   Zjoin_urlr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r|   ZdoctestZtestmodr   r   r   r   <module>   sf   (	&

"
(O	


