
    wBf=9                        d Z ddlZddl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mZ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 Z ed      d        ZdZ	  ed      d        ZdZ G d d ede            Z  ed      de!de fd       Zd Z"d Z#d Z$d Z%d Z&d Z'e'Z(d Z)d Z*d  Z+d! Z,d" Z- ed      d#        Z.d$ Z/d% Z0d& Z1 ed      d'        Z2de!d(e!d)e!de!fd*Z3d/de!d+e!de!fd,Z4d- Z5de!de!fd.Z6y)0zCommon URL utilities.    N)
namedtuple)	lru_cache)getpass)abspath
expanduser)ParseResultquote
quote_plusunquoteunquote_plus)urlparse)
urlunparse   )on_win)split_filenamestrip_pkg_extensionc                     t        | j                               } t        d      }t        d      }t        d      }t        d      }| |k\  r| |k  r| |z
  }|S | |k\  r| |k  r
| |z
  dz   }|S d }|S )N09AF
   )ordupper)hoo0o9oAoFress         0lib/python3.12/site-packages/conda/common/url.pyhex_octal_to_intr"      s    	RXXZB	SB	SB	SB	SB 8b 	R  J 8b 2gl  J   J    )maxsizec                 .   d| vr| S g }t        j                  d| t         j                        D ]1  }|j                  |j	                         |j                         f       3 t        |      s| S d}d}t        |       D ]}  \  }}|dkD  r|dz  }|j                  d      }|}|dk(  rM|D ]H  }||d   k(  sdd l	}	|	j                  d	t        | |dz            d
z  t        | |dz            z         }d} n |sy||z  } t        j                  |      d   S )N%z(%[0-9A-F]{2}))flagsr#   r   r   ascii   %B      )refinditer
IGNORECASEappendstartendlen	enumerateencodestructpackr"   codecsutf_8_decode)
pathrangesmresultskipsicemitrr6   s
             r!   percent_decoderC   *   s7    $F[[*DF ,qwwy!%%'*+,v; FE$ 119QJEHHW9 
!9!!;;(a!e5:*4A;78D
 E
 dNF'( v&q))r#   zfile://c                     | st        d| z        | j                  t              r	 | j                  d       | S t        t        |             j                  dd      } dfd}t        d | D              r> |t        | d	      r| j                  d
      nt        | d      j                  d
            } t        |       dkD  r| d   dk(  rt        dz   | z   } | S t        | z   } | S # t        $ r t        d| z        w xY w)NzNot allowed: %rr(   z8Non-ascii not allowed for things claiming to be URLs: %r\/z!'()*-._/\:c                 8    dj                  fd| D              S )N c              3   z   K   | ]2  }d t        |      z  |g|dk  xr |j                         xs |v     4 yw)z%%%02X{N)r   isalnum).0r@   percent_encode_charss     r!   	<genexpr>z0path_to_url.<locals>.<lambda>.<locals>.<genexpr>y   sF      ' 
CF	Aq3w6199;S!?S:ST's   8;)join)srM   s    r!   <lambda>zpath_to_url.<locals>.<lambda>y   s    rww ''   r#   c              3   8   K   | ]  }t        |      d k\    yw)   N)r   )rL   chars     r!   rN   zpath_to_url.<locals>.<genexpr>}   s     
-3t9
-s   decodezunicode-escapezutf-8r   :)
ValueError
startswithfile_schemerU   UnicodeDecodeErrorr   r   replaceanyhasattrbytesr3   )r:   percent_encoderM   s     @r!   path_to_urlr`   ^   s   *T122{#	KK 
 :d#$,,T37D *N 
-
--tX& KK()tW%,,-=>
 4y1}aCS 4' K T!KI " 	JTQ 	s   C% %C=)schemer:   queryfragmentusernamepasswordhostnameportc                        e Zd ZdZ	 	 	 	 	 	 	 	 d fd	Zed        Zed        Zd Zde	fdZ
ddZed	edd fd
       Z x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.
    c	                     |r|j                  d      sd|z   }|r|j                         }|r|j                         }t        	|   | ||||||||	      S )NrF   )rX   lowersuper__new__)
clsra   r:   rb   rc   rd   re   rf   rg   	__class__s
            r!   rm   zUrl.__new__   s]     ,:D\\^F~~'Hwuh(Hd
 	
r#   c                     | j                   r'| j                  r| j                    d| j                   S | j                   r| j                   S y NrV   rd   re   selfs    r!   authzUrl.auth   s>    ==T]]mm_Admm_55]]==  r#   c                 h    | j                   r| j                   d| j                    S | j                  S rq   )rg   rf   rs   s    r!   netlocz
Url.netloc   s,    99mm_Adii[11}}r#   c                     | \  }}}}}}}}d}	|r|	| dz  }	|r|r|	| d| dz  }	|r|	|z  }	|r|	d| z  }	|r|	|z  }	|r|	d| z  }	|r|	d| z  }	|	S )NrH   ://rV   @?# )
rt   ra   r:   rb   rc   rd   re   rf   rg   urls
             r!   __str__zUrl.__str__   s    LPIeXx8TfXS>!ChZq
!,,C8OCQtf:C4KCQug;CQxj>!C
r#   returnc                 "    | j                         S )z3Provide a public interface for namedtuple's _asdict)_asdictrs   s    r!   as_dictzUrl.as_dict   s    ||~r#   c                 &     | j                   di |S )z4Provide a public interface for namedtuple's _replacer}   )_replace)rt   kwargss     r!   r[   zUrl.replace   s    t}}&v&&r#   parse_resultc           	      Z    t         D ci c]  }|t        ||d       }} | di |S c c}w )NrH   r}   )	url_attrsgetattr)rn   r   fldvaluess       r!   from_parse_resultzUrl.from_parse_result   s5    AJK##w|S"55KK}V} Ls   ()NNNNNNNN)r   ri   )__name__
__module____qualname____doc__rm   propertyru   rw   r   dictr   r[   classmethodr   r   __classcell__)ro   s   @r!   ri   ri      s     
* ! !  
* ' [ U  r#   ri   r~   r   c                     t         r#| j                  d      r| j                  dd       t        |       sd| z   } t        j                  t        |             S )Nzfile:rE   rF   z//)r   rX   r[   
has_schemeri   r   	_urlparser~   s    r!   r   r      sC    #..)D#c?Sj  300r#   c                     t        |       }|j                  dk(  s
J d| z         |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')
    s3z"You can only use s3: urls (not %r))r   ra   rf   r:   )r~   
parsed_urlbucketkeys       r!   url_to_s3_infor      sI     #J$P&JS&PP$%%zCF3;r#   c                 X    | sy	 t        |       j                  dk7  S # t        $ r Y yw xY w)zn
    Examples:
        >>> is_url(None)
        False
        >>> is_url("s3://some/bucket")
        True
    FrH   )r   ra   rW   r   s    r!   is_urlr      s6     }##r)) s    	))c                 t    	 t        j                  |        | j                  d      dk(  S # t        $ r Y yw xY w)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.   )socket	inet_atonOSErrorcount	string_ips    r!   is_ipv4_addressr     s?    # ??31$$  s   + 	77c                 l    	 t        j                  t         j                  |        y# t        $ r Y yw xY w)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AF_INET6r   r   s    r!   is_ipv6_addressr     s4    )4   s   $' 	33c                 2    t        |       xs 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   s    r!   is_ip_addressr   ,  s     9%C)CCr#   c                      | d   r| d   j                  d      rdnd}|dj                  d d | D        D              z   S )Nr   rF   rH   c              3   &   K   | ]	  }|s|  y wNr}   )rL   ys     r!   rN   zjoin.<locals>.<genexpr>;  s     N!AANs   c              3   D   K   | ]  }|s|j                  d         yw)rF   N)strip)rL   xs     r!   rN   zjoin.<locals>.<genexpr>;  s     'Ha'Hs     )rX   rO   )argsr1   s     r!   rO   rO   9  s@    Aw$q'"4"4S"9CrE388N'Hd'HNNNNr#   c                 .    t        j                  d|       S )Nz[a-z][a-z0-9]{0,11}://)r-   match)values    r!   r   r   A  s    88-u55r#   c                 ,    | j                  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'
    ry   r   )splitr   s    r!   strip_schemer   E  s     99UAr""r#   c                 L    t        |       \  }}|r| j                  |dd      S | S )Nz<TOKEN>r   )split_anaconda_tokenr[   )r~   _tokens      r!   mask_anaconda_tokenr   P  s*    #C(HAu/43;;ui+=#=r#   c                     t        j                  d|       }|r|j                         d   nd}|| j                  d|z   dd      n| }|j	                  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/rH   r   rF   )r-   searchgroupsr[   rstrip)r~   _token_matchr   cleaned_urls       r!   r   r   U  s_      992C8L(4L!!$$E7<7H#++eemR3cKc"E))r#   c                     t        |       j                  |      }|r|j                         d   nd}||j                  d|z   dd      n|}|j	                  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   NrF   rH   r   )_split_platform_rer   r   r[   r   )known_subdirsr~   _platform_matchplatformr   s        r!   split_platformr   k  sd     )7>>sCO.=%%'*4H8@8L#++cHnb!4RUKc"H,,r#   c                     ddj                  d | D              z  }t        j                  |t        j                        S )Nz/(%s)(?:/|$)|c              3   &   K   | ]	  }d |z    yw)z%sNr}   )rL   ds     r!   rN   z%_split_platform_re.<locals>.<genexpr>|  s      8	8s   )rO   r-   compiler/   )r   _platform_match_regexs     r!   r   r   z  s=    +dii 8(8 /  ::+R]];;r#   c                 f    t        |       \  }}|sy |j                  dd      d   }||v xr |xs d S )NrF   r   r   )r   rsplit)r~   r   url_no_package_namer   maybe_a_platforms        r!   has_platformr     sF    +C0*11#q9"=},A1AITIr#   c                     | syt        |       \  }}t        |      }t        |j                  |j                  |j
                  |j                        }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)rf   rg   r:   rb   )
r   r   ri   rf   rg   r:   rb   strra   ru   )r~   r   r   	url_partsremainder_urls        r!   split_scheme_auth_tokenr     sk     %-c2K%I##^^^^oo	M }y//FFr#   c           	      :   t        |      \  }}t        | |      \  }}t        |      \  }}|rd|v r|j                  dd      n|d f\  }}t	        |      }|j
                  |j                  ||||j                  |j                  |j                  |j                  f	S )NrF   r   )r   r   r   r   r   ra   ru   rf   rg   r:   rb   )	r   r~   r   r   r   r   extpackage_filenamer   s	            r!   split_conda_url_easy_partsr     s    -c2K*=+FK -FAs 3+% 	3"4  "K! %I 	
 
r#   c                 <    t        d| z        }t        d      }||fS )Nz
%s proxy username: z
Password: )inputr   )ra   rd   passwds      r!   get_proxy_username_and_passr     s'    ,v56H\"FVr#   rd   re   c                 j    t        |       } | j                  |t        |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'
    rH   )saferr   )r   r[   r	   r   )r~   rd   re   url_with_auths       r!   add_username_and_passwordr     s2     3-CKKE(QS<TKUM}r#   ru   c                     |s| S t        |       }|j                  r|j                  r|s| S |j                  d      }t	        |      dkD  r|j                  |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'
    rV   r   r   rr   )r   rd   re   r   r3   r[   r   )r~   ru   forcer   
auth_partss        r!   maybe_add_authr     sn     
Ii00
CJ
:%%z!}zRS}%U	y>r#   c                 2    | rt        t        |             S | S r   )r   remove_authr   s    r!   maybe_unquoter     s    -0<C()9c9r#   c                 T    t        |       } | j                  dd      }t        |      S )zRemove embedded authentication from URL.

    .. code-block:: pycon

       >>> remove_auth("https://user:password@anaconda.com")
       'https://anaconda.com'
    rH   rr   )r   r[   r   )r~   url_no_auths     r!   r   r     s*     3-C++rB+7K{r#   )F)7r   r8   r-   r   collectionsr   	functoolsr   r   os.pathr   r   urllib.parser   r	   r
   r   r   r   r   r   _urlunparsecompatr   r:   r   r   r"   rC   rY   r`   r   ri   r   r   r   r   r   r   rO   join_urlr   r   r   r   r   r   r   r   r   r   r   r   r   r   r}   r#   r!   <module>r      s     	  "   '  / 2  5  4"* "*J  4* *Z		L*UI
& L^ 41# 1# 1 1
 %
DO
 6#>
*,- 4< <JG,6 4 	3 	# 	 	 	 3  4:S S r#   