
0c@_JR                 @   s  d  d l  Z  d  d l Z d  d l Z d  d l Z d  d l Z d  d l Z y d  d l m Z Wn" e k
 r d  d l	 m Z Yn Xd d l
 m Z d d l m Z m Z m Z m Z m Z m Z d d l m Z m Z m Z e j e  Z d Z d Z Gd	 d
   d
 e  Z d S)    N)Thread   )DistlibException)HTTPBasicAuthHandlerRequestHTTPPasswordMgrurlparsebuild_openerstring_types)cached_propertyzip_dirServerProxyzhttps://pypi.org/pypipypic               @   s  e  Z d  Z d Z d Z d d d  Z d d   Z d d	   Z d
 d   Z d d   Z	 d d   Z
 d d   Z d d d  Z d d d  Z d d d  Z d d d d d d d  Z d d   Z d d d  Z d d  d!  Z d d d" d#  Z d$ d%   Z d& d'   Z d d( d)  Z d S)*PackageIndexzc
    This class represents a package index compatible with PyPI, the Python
    Package Index.
    s.   ----------ThIs_Is_tHe_distlib_index_bouNdaRY_$Nc             C   s  | p	 t  |  _ |  j   t |  j  \ } } } } } } | sX | sX | sX | d k rk t d |  j   d |  _ d |  _ d |  _ d |  _ t	 t
 j d  h } x^ d D]V }	 y; t j |	 d g d	 | d
 | }
 |
 d k r |	 |  _ PWq t k
 r Yq Xq WWd QRXd S)z
        Initialise an instance.

        :param url: The URL of the index. If not specified, the URL for PyPI is
                    used.
        httphttpszinvalid repository: %sNwgpggpg2z	--versionstdoutstderrr   )zhttpzhttps)zgpgr   )DEFAULT_INDEXurlread_configurationr   r   password_handlerssl_verifierr   gpg_homeopenosdevnull
subprocess
check_callOSError)selfr   schemenetlocpathparamsqueryfragZsinksrc r,   8/tmp/pip-build-jynh7p1z/pip/pip/_vendor/distlib/index.py__init__$   s&    
!						zPackageIndex.__init__c             C   s3   d d l  m } d d l m } |   } | |  S)zs
        Get the distutils command for interacting with PyPI configurations.
        :return: the command.
        r   )Distribution)PyPIRCCommand)distutils.corer/   distutils.configr0   )r#   r/   r0   dr,   r,   r-   _get_pypirc_commandA   s    	z PackageIndex._get_pypirc_commandc             C   sy   |  j    } |  j | _ | j   } | j d  |  _ | j d  |  _ | j d d  |  _ | j d |  j  |  _ d S)z
        Read the PyPI access configuration as supported by distutils, getting
        PyPI to do the actual work. This populates ``username``, ``password``,
        ``realm`` and ``url`` attributes from the configuration.
        usernamepasswordrealmr   
repositoryN)r4   r   r8   _read_pypircgetr5   r6   r7   )r#   ccfgr,   r,   r-   r   K   s    zPackageIndex.read_configurationc             C   s0   |  j    |  j   } | j |  j |  j  d S)z
        Save the PyPI access configuration. You must have set ``username`` and
        ``password`` attributes before calling this method.

        Again, distutils is used to do the actual work.
        N)check_credentialsr4   _store_pypircr5   r6   )r#   r;   r,   r,   r-   save_configurationZ   s    
zPackageIndex.save_configurationc             C   s   |  j  d k s |  j d k r* t d   t   } t |  j  \ } } } } } } | j |  j | |  j  |  j  t |  |  _	 d S)zp
        Check that ``username`` and ``password`` have been set, and raise an
        exception if not.
        Nz!username and password must be set)
r5   r6   r   r   r   r   add_passwordr7   r   r   )r#   Zpm_r%   r,   r,   r-   r=   f   s    	!zPackageIndex.check_credentialsc             C   s   |  j    | j   | j   } d | d <|  j | j   g   } |  j |  } d | d <|  j | j   g   } |  j |  S)aq  
        Register a distribution on PyPI, using the provided metadata.

        :param metadata: A :class:`Metadata` instance defining at least a name
                         and version number for the distribution to be
                         registered.
        :return: The HTTP response received from PyPI upon submission of the
                request.
        verifyz:actionsubmit)r=   validatetodictencode_requestitemssend_request)r#   metadatar3   requestresponser,   r,   r-   registerr   s    




zPackageIndex.registerc             C   sa   xP | j    } | s P| j d  j   } | j |  t j d | | f  q W| j   d S)ar  
        Thread runner for reading lines of from a subprocess into a buffer.

        :param name: The logical name of the stream (used for logging only).
        :param stream: The stream to read from. This will typically a pipe
                       connected to the output stream of a subprocess.
        :param outbuf: The list to append the read lines to.
        zutf-8z%s: %sN)readlinedecoderstripappendloggerdebugclose)r#   namestreamZoutbufr*   r,   r,   r-   _reader   s    	zPackageIndex._readerc             C   s   |  j  d d d g } | d k r* |  j } | rC | j d | g  | d k	 re | j d d d g  t j   } t j j | t j j |  d	  } | j d
 d d | d | | g  t	 j
 d d j |   | | f S)a  
        Return a suitable command for signing a file.

        :param filename: The pathname to the file to be signed.
        :param signer: The identifier of the signer of the file.
        :param sign_password: The passphrase for the signer's
                              private key used for signing.
        :param keystore: The path to a directory which contains the keys
                         used in verification. If not specified, the
                         instance's ``gpg_home`` attribute is used instead.
        :return: The signing command as a list suitable to be
                 passed to :class:`subprocess.Popen`.
        z--status-fd2z--no-ttyNz	--homedirz--batchz--passphrase-fd0z.ascz--detach-signz--armorz--local-userz--outputzinvoking: %s )r   r   extendtempfilemkdtempr   r&   joinbasenamerQ   rR   )r#   filenamesignersign_passwordkeystorecmdtdZsfr,   r,   r-   get_sign_command   s    	%zPackageIndex.get_sign_commandc       	      C   s  d t  j d t  j i } | d k	 r1 t  j | d <g  } g  } t  j | |  } t d |  j d d | j | f  } | j   t d |  j d d | j | f  } | j   | d k	 r | j j	 |  | j j
   | j   | j   | j   | j | | f S)a  
        Run a command in a child process , passing it any input data specified.

        :param cmd: The command to run.
        :param input_data: If specified, this must be a byte string containing
                           data to be sent to the child process.
        :return: A tuple consisting of the subprocess' exit code, a list of
                 lines read from the subprocess' ``stdout``, and a list of
                 lines read from the subprocess' ``stderr``.
        r   r   Nstdintargetargs)r    PIPEPopenr   rV   r   startr   rf   writerS   waitr]   
returncode)	r#   rc   Z
input_datakwargsr   r   pt1t2r,   r,   r-   run_command   s$    	$
$



zPackageIndex.run_commandc       
      C   sb   |  j  | | | |  \ } } |  j | | j d   \ } } }	 | d k r^ t d |   | S)aR  
        Sign a file.

        :param filename: The pathname to the file to be signed.
        :param signer: The identifier of the signer of the file.
        :param sign_password: The passphrase for the signer's
                              private key used for signing.
        :param keystore: The path to a directory which contains the keys
                         used in signing. If not specified, the instance's
                         ``gpg_home`` attribute is used instead.
        :return: The absolute pathname of the file where the signature is
                 stored.
        zutf-8r   z&sign command failed with error code %s)re   rs   encoder   )
r#   r_   r`   ra   rb   rc   sig_filer+   r   r   r,   r,   r-   	sign_file   s    	
zPackageIndex.sign_filesdistsourcec             C   s  |  j    t j j |  s, t d |   | j   | j   } d }	 | r |  j sg t j	 d  n |  j
 | | | |  }	 t | d   }
 |
 j   } Wd QRXt j |  j   } t j |  j   } | j d d d d d	 | d
 | d | d | i  d t j j |  | f g } |	 rt |	 d   }
 |
 j   } Wd QRX| j d t j j |	  | f  t j t j j |	   |  j | j   |  } |  j |  S)a  
        Upload a release file to the index.

        :param metadata: A :class:`Metadata` instance defining at least a name
                         and version number for the file to be uploaded.
        :param filename: The pathname of the file to be uploaded.
        :param signer: The identifier of the signer of the file.
        :param sign_password: The passphrase for the signer's
                              private key used for signing.
        :param filetype: The type of the file being uploaded. This is the
                        distutils command which produced that file, e.g.
                        ``sdist`` or ``bdist_wheel``.
        :param pyversion: The version of Python which the release relates
                          to. For code compatible with any Python, this would
                          be ``source``, otherwise it would be e.g. ``3.2``.
        :param keystore: The path to a directory which contains the keys
                         used in signing. If not specified, the instance's
                         ``gpg_home`` attribute is used instead.
        :return: The HTTP response received from PyPI upon submission of the
                request.
        znot found: %sNz)no signing program available - not signedrbz:actionZfile_uploadZprotocol_version1filetype	pyversion
md5_digestsha256_digestcontentZgpg_signature)r=   r   r&   existsr   rD   rE   r   rQ   warningrv   r   readhashlibmd5	hexdigestsha256updater^   rP   shutilrmtreedirnamerF   rG   rH   )r#   rI   r_   r`   ra   r{   r|   rb   r3   ru   fZ	file_datar}   r~   filesZsig_datarJ   r,   r,   r-   upload_file   s>    

		
zPackageIndex.upload_filec       
      C   s   |  j    t j j |  s, t d |   t j j | d  } t j j |  sc t d |   | j   | j | j	 } } t
 |  j   } d	 d | f d | f g } d | | f g } |  j | |  }	 |  j |	  S)
a2  
        Upload documentation to the index.

        :param metadata: A :class:`Metadata` instance defining at least a name
                         and version number for the documentation to be
                         uploaded.
        :param doc_dir: The pathname of the directory which contains the
                        documentation. This should be the directory that
                        contains the ``index.html`` for the documentation.
        :return: The HTTP response received from PyPI upon submission of the
                request.
        znot a directory: %rz
index.htmlznot found: %r:action
doc_uploadrT   versionr   )r   r   )r=   r   r&   isdirr   r]   r   rD   rT   r   r   getvaluerF   rH   )
r#   rI   Zdoc_dirfnrT   r   zip_datafieldsr   rJ   r,   r,   r-   upload_documentation(  s    

z!PackageIndex.upload_documentationc             C   sv   |  j  d d d g } | d k r* |  j } | rC | j d | g  | j d | | g  t j d d j |   | S)	a|  
        Return a suitable command for verifying a file.

        :param signature_filename: The pathname to the file containing the
                                   signature.
        :param data_filename: The pathname to the file containing the
                              signed data.
        :param keystore: The path to a directory which contains the keys
                         used in verification. If not specified, the
                         instance's ``gpg_home`` attribute is used instead.
        :return: The verifying command as a list suitable to be
                 passed to :class:`subprocess.Popen`.
        z--status-fdrW   z--no-ttyNz	--homedirz--verifyzinvoking: %srY   )r   r   rZ   rQ   rR   r]   )r#   signature_filenamedata_filenamerb   rc   r,   r,   r-   get_verify_commandD  s    	zPackageIndex.get_verify_commandc             C   sh   |  j  s t d   |  j | | |  } |  j |  \ } } } | d k r^ t d |   | d k S)a6  
        Verify a signature for a file.

        :param signature_filename: The pathname to the file containing the
                                   signature.
        :param data_filename: The pathname to the file containing the
                              signed data.
        :param keystore: The path to a directory which contains the keys
                         used in verification. If not specified, the
                         instance's ``gpg_home`` attribute is used instead.
        :return: True if the signature was verified, else False.
        z0verification unavailable because gpg unavailabler   r   z(verify command failed with error code %s)r   r   )r   r   r   rs   )r#   r   r   rb   rc   r+   r   r   r,   r,   r-   verify_signature\  s    		
zPackageIndex.verify_signaturec             C   s  | d k r" d } t  j d  nM t | t t f  rF | \ } } n d } t t |    } t  j d |  t | d   } |  j t	 |   } z | j
   }	 d }
 d } d } d } d	 |	 k r t |	 d
  } | r | | |
 |  xj | j |
  } | sP| t |  7} | j |  | r8| j |  | d 7} | r | | |
 |  q WWd | j   XWd QRX| d k r| | k  rt d | | f   | r| j   } | | k rt d | | | | f   t  j d |  d S)a  
        This is a convenience method for downloading a file from an URL.
        Normally, this will be a file from the index, though currently
        no check is made for this (i.e. a file can be downloaded from
        anywhere).

        The method is just like the :func:`urlretrieve` function in the
        standard library, except that it allows digest computation to be
        done during download and checking that the downloaded data
        matched any expected value.

        :param url: The URL of the file to be downloaded (assumed to be
                    available via an HTTP GET request).
        :param destfile: The pathname where the downloaded file is to be
                         saved.
        :param digest: If specified, this must be a (hasher, value)
                       tuple, where hasher is the algorithm used (e.g.
                       ``'md5'``) and ``value`` is the expected value.
        :param reporthook: The same as for :func:`urlretrieve` in the
                           standard library.
        NzNo digest specifiedr   zDigest specified: %swbi    r   r   zcontent-lengthzContent-Lengthz1retrieval incomplete: got only %d out of %d bytesz.%s digest mismatch for %s: expected %s, got %szDigest verified: %s)rQ   rR   
isinstancelisttuplegetattrr   r   rH   r   infointr   lenrl   r   rS   r   r   )r#   r   destfiledigest
reporthookZdigesterZhasherZdfpZsfpheaders	blocksizesizer   blocknumblockactualr,   r,   r-   download_fileu  sV    
zPackageIndex.download_filec             C   sQ   g  } |  j  r | j |  j   |  j r8 | j |  j  t |   } | j |  S)z
        Send a standard library :class:`Request` to PyPI and return its
        response.

        :param req: The request to send.
        :return: The HTTP response from PyPI (a standard library HTTPResponse).
        )r   rP   r   r	   r   )r#   reqhandlersopenerr,   r,   r-   rH     s    		zPackageIndex.send_requestc             C   s7  g  } |  j  } xv | D]n \ } } t | t t f  s@ | g } xA | D]9 } | j d | d | j d  d | j d  f  qG Wq WxG | D]? \ } }	 }
 | j d | d | |	 f j d  d |
 f  q W| j d | d d f  d j |  } d | } d | d	 t t |   i } t	 |  j
 | |  S)
a&  
        Encode fields and files for posting to an HTTP server.

        :param fields: The fields to send as a list of (fieldname, value)
                       tuples.
        :param files: The files to send as a list of (fieldname, filename,
                      file_bytes) tuple.
        s   --z)Content-Disposition: form-data; name="%s"zutf-8    z8Content-Disposition: form-data; name="%s"; filename="%s"s   
s   multipart/form-data; boundary=zContent-typezContent-length)boundaryr   r   r   rZ   rt   r]   strr   r   r   )r#   r   r   partsr   kvaluesvkeyr_   valuebodyctr   r,   r,   r-   rF     s2    		
zPackageIndex.encode_requestc             C   s_   t  | t  r d | i } t |  j d d } z | j | | pE d  SWd  | d    Xd  S)NrT   timeoutg      @andrS   )r   r
   r   r   search)r#   ZtermsoperatorZ	rpc_proxyr,   r,   r-   r     s    zPackageIndex.search)__name__
__module____qualname____doc__r   r.   r4   r   r?   r=   rL   rV   re   rs   rv   r   r   r   r   r   rH   rF   r   r,   r,   r,   r-   r      s*   
#8M+r   )r   loggingr   r   r    r[   	threadingr   ImportErrordummy_threading r   compatr   r   r   r   r	   r
   utilr   r   r   	getLoggerr   rQ   r   DEFAULT_REALMobjectr   r,   r,   r,   r-   <module>   s    .