U ÀÒ.eWFã@s dZddlZddlZddlZddlZddlZddlmZddlm Z m Z ddl m Z ddl mZmZmZddlmZddlmZdd lmZdd lmZdd lmZdd lmZdd lmZm Z ddl!m"Z"m#Z#e�rDddl$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-ddl.Z/ddl0m1Z1ddl2m3Z3ddl4m5Z5e/j6j7j8Z9e)e:e:fZ;e dd„Z?dd„Z@Gdd„deAƒZBdd„ZCGdd„deAƒZDdd„ZEdd „ZFd!d"„ZGd#d$„ZHd%d&„ZId'd(„ZJd)d*„ZKGd+d,„d,eLƒZMdd6d7„ZRGd8d9„d9eLƒZSGd:d;„d;eLƒZTdS)?zM The main purpose of this module is to expose LinkCollector.collect_links(). éN)Ú OrderedDict)Úhtml5libÚrequests)Úunescape)Ú HTTPErrorÚ RetryErrorÚSSLError)Úparse)Úrequest©ÚLink)ÚARCHIVE_EXTENSIONS)Úredact_auth_from_url)ÚMYPY_CHECK_RUNNING)Ú path_to_urlÚ url_to_path)Úis_urlÚvcs) ÚCallableÚDictÚIterableÚListÚMutableMappingÚOptionalÚSequenceÚTupleÚUnion)ÚResponse)Ú SearchScope)Ú PipSessioncCs6tjD]*}| ¡ |¡r|t|ƒdkr|SqdS)zgLook for VCS schemes in the URL. Returns the matched VCS scheme, or None if there's no match. z+:N)rZschemesÚlowerÚ startswithÚlen)ÚurlÚscheme©r%ú;/usr/lib/python3.8/site-packages/pip/_internal/collector.pyÚ_match_vcs_scheme/s  r'cCs(t|ƒj}tD]}| |¡rdSqdS)z2Return whether the URL looks like an archive. TF)r Úfilenamer Úendswith)r#r(Zbad_extr%r%r&Ú_is_url_like_archive;s   r*cseZdZ‡fdd„Z‡ZS)Ú_NotHTMLcs"tt|ƒ ||¡||_||_dS©N)Úsuperr+Ú__init__Ú content_typeÚ request_desc)Úselfr/r0©Ú __class__r%r&r.Gsz_NotHTML.__init__)Ú__name__Ú __module__Ú __qualname__r.Ú __classcell__r%r%r2r&r+Fsr+cCs.|j dd¡}| ¡ d¡s*t||jjƒ‚dS)z…Check the Content-Type header to ensure the response contains HTML. Raises `_NotHTML` if the content type is not text/html. ú Content-TypeÚú text/htmlN)ÚheadersÚgetr r!r+r Úmethod)Úresponser/r%r%r&Ú_ensure_html_headerNsr?c@s eZdZdS)Ú_NotHTTPN)r4r5r6r%r%r%r&r@Ysr@cCsDt |¡\}}}}}|dkr"tƒ‚|j|dd�}| ¡t|ƒdS)zÊSend a HEAD request to the URL, and ensure the response contains HTML. Raises `_NotHTTP` if the URL is not available for a HEAD request, or `_NotHTML` if the content type is not text/html. >ÚhttpÚhttpsT)Zallow_redirectsN)Ú urllib_parseZurlsplitr@ÚheadÚraise_for_statusr?)r#Úsessionr$ÚnetlocÚpathZqueryZfragmentÚrespr%r%r&Ú_ensure_html_response]s rJcCsLt|ƒrt||d�t dt|ƒ¡|j|dddœd�}| ¡t|ƒ|S)aAccess an HTML page with GET, and return the response. This consists of three parts: 1. If the URL looks suspiciously like an archive, send a HEAD first to check the Content-Type is HTML, to avoid downloading a large file. Raise `_NotHTTP` if the content type cannot be determined, or `_NotHTML` if it is not HTML. 2. Actually perform the request. Raise HTTP exceptions on network failures. 3. Check the Content-Type header to make sure we got HTML, and raise `_NotHTML` otherwise. ©rFzGetting page %sr:z max-age=0)ZAcceptz Cache-Control)r;)r*rJÚloggerÚdebugrr<rEr?)r#rFrIr%r%r&Ú_get_html_responsens ñþrNcCs2|r.d|kr.t |d¡\}}d|kr.|dSdS)zBDetermine if we have any encoding information in our headers. r8ÚcharsetN)ÚcgiZ parse_header)r;r/Zparamsr%r%r&Ú_get_encoding_from_headers¡s  rQcCs.| d¡D]}| d¡}|dk r |Sq |S)aöDetermine the HTML document's base URL. This looks for a ```` tag in the HTML document. If present, its href attribute denotes the base URL of anchor tags in the document. If there is no such tag (or if it does not have a valid href attribute), the HTML file's URL is used as the base URL. :param document: An HTML document representation. The current implementation expects the result of ``html5lib.parse()``. :param page_url: The URL of the HTML document. z.//baseÚhrefN)Úfindallr<)ÚdocumentÚpage_urlÚbaserRr%r%r&Ú_determine_base_url¬s   rWcCsPt |¡}|jdkr(t t |j¡¡}ntjt |j¡dd�}t  |j |d�¡S)z Makes sure a link is fully encoded. That is, if a ' ' shows up in the link, it will be rewritten to %20 (while not over-quoting % or other characters).r9z/@)Zsafe)rH) rCÚurlparserGÚurllib_requestZ pathname2urlÚ url2pathnamerHZquoteZunquoteZ urlunparseÚ_replace)r#ÚresultrHr%r%r&Ú _clean_linkÀs   ÿr]cCsf| d¡}|sdStt ||¡ƒ}| d¡}|r8t|ƒnd}| d¡}|rRt|ƒ}t||||d�}|S)zJ Convert an anchor element in a simple repository page to a Link. rRNzdata-requires-pythonz data-yanked)Z comes_fromZrequires_pythonÚ yanked_reason)r<r]rCÚurljoinrr )ÚanchorrUÚbase_urlrRr#Z pyrequirer^Úlinkr%r%r&Ú_create_link_from_elementÚs   ürcccsVtj|j|jdd�}|j}t||ƒ}| d¡D]"}t|||d�}|dkrJq.|Vq.dS)zP Parse an HTML document, and yield its anchor elements as Link objects. F)Ztransport_encodingZnamespaceHTMLElementsz.//a)rUraN)rr ÚcontentÚencodingr#rWrSrc)ÚpagerTr#rar`rbr%r%r&Ú parse_linksús ý ýrgc@s eZdZdZdd„Zdd„ZdS)ÚHTMLPagez'Represents one page, along with its URLcCs||_||_||_dS)zŒ :param encoding: the encoding to decode the given content. :param url: the URL from which the HTML was downloaded. N)rdrer#)r1rdrer#r%r%r&r.s zHTMLPage.__init__cCs t|jƒSr,)rr#©r1r%r%r&Ú__str__$szHTMLPage.__str__N)r4r5r6Ú__doc__r.rjr%r%r%r&rhsrhcCs|dkrtj}|d||ƒdS)Nz%Could not fetch URL %s: %s - skipping)rLrM)rbÚreasonÚmethr%r%r&Ú_handle_get_page_fail(srncCst|jƒ}t|j||jd�S)N)rer#)rQr;rhrdr#)r>rer%r%r&Ú_make_html_page3s roc Csþ|dkrtdƒ‚|j dd¡d}t|ƒ}|r@t d||¡dSt |¡\}}}}}}|dkrštj   t   |¡¡rš|  d¡s‚|d7}t |d¡}t d |¡zt||d �}W�nDtk rÎt d |¡Y�n,tk �r}zt d ||j|j¡W5d}~XYnötk �r0}zt||ƒW5d}~XYnÊtk �r\}zt||ƒW5d}~XYnžtk �rž}z$d } | t|ƒ7} t|| tjd�W5d}~XYn\tjk �rÐ}zt|d|ƒW5d}~XYn*tjk �rðt|dƒYn Xt|ƒSdS)Nz?_get_html_page() missing 1 required keyword argument: 'session'ú#érzCannot look at %s URL %sÚfileú/z index.htmlz# file: URL is directory, getting %srKzQSkipping page %s because it looks like an archive, and cannot be checked by HEAD.z.sort_pathzfile:z)Path '{0}' is ignored: it is a directory.z:Url '%s' is ignored: it is neither a file nor a directory.zQUrl '%s' is ignored. It is either a non-existing path or lacks a specific scheme.)rvrHÚexistsr!rrwÚrealpathÚlistdirÚjoinrƒrLZwarningÚformatÚisfiler)Ú locationsÚ expand_dirr†r#Z is_local_pathZ is_file_urlrHÚitemr%r„r&Úgroup_locationsxsF     ÿÿ  þ þr�c@seZdZdZdd„ZdS)ÚCollectedLinksa Encapsulates all the Link objects collected by a call to LinkCollector.collect_links(), stored separately as-- (1) links from the configured file locations, (2) links from the configured find_links, and (3) a dict mapping HTML page url to links from that page. cCs||_||_||_dS)z¸ :param files: Links from file locations. :param find_links: Links from find_links. :param pages: A dict mapping HTML page url to links from that page. N©r…Ú find_linksÚpages)r1r…r“r”r%r%r&r.¾s zCollectedLinks.__init__N)r4r5r6rkr.r%r%r%r&r‘³s r‘c@s4eZdZdZdd„Zedd„ƒZdd„Zdd „Zd S) Ú LinkCollectorz³ Responsible for collecting Link objects from all configured locations, making network requests as needed. The class's main method is its collect_links() method. cCs||_||_dSr,)Ú search_scoperF)r1rFr–r%r%r&r.ØszLinkCollector.__init__cCs|jjSr,)r–r“rir%r%r&r“ászLinkCollector.find_linksccs,|D]"}t||jd�}|dkr q|VqdS)zp Yields (page, page_url) from the given locations, skipping locations that have errors. rKN)r}rF)r1r�Úlocationrfr%r%r&Ú _get_pagesæs zLinkCollector._get_pagescsúˆj}| |¡}t|ƒ\}}tˆjdd�\}}dd„t ||¡Dƒ}dd„ˆjDƒ} ‡fdd„t dd„|Dƒd d„|Dƒ¡Dƒ} t| ƒ} d  t| ƒ|¡g} | D]} |   d  | ¡¡q t   d   | ¡¡i} ˆ  | ¡D]}tt|ƒƒ| |j<qÔt|| | d �S)zŽFind all available links for the given project name. :return: All the Link objects (unfiltered), as a CollectedLinks object. T)rŽcSsg|] }t|ƒ‘qSr%r ©Ú.0r#r%r%r&Ú sz/LinkCollector.collect_links..cSsg|]}t|dƒ‘qS)z-fr r™r%r%r&r›scsg|]}ˆj |¡r|‘qSr%)rFZis_secure_origin)ršrbrir%r&r› s ücss|]}t|ƒVqdSr,r r™r%r%r&Ú sz.LinkCollector.collect_links..css|]}t|ƒVqdSr,r r™r%r%r&rœ sz,{} location(s) to search for versions of {}:z* {}Ú r’)r–Zget_index_urls_locationsr�r“Ú itertoolsÚchainr€r‹r"rƒrLrMrŠr˜r~rgr#r‘)r1Z project_namer–Zindex_locationsZindex_file_locZ index_url_locZ fl_file_locZ fl_url_locZ file_linksZfind_link_linksZ url_locationsÚlinesrbZ pages_linksrfr%rir&Ú collect_linksósD  ÿ  ÿ   þÿÿÿýzLinkCollector.collect_linksN) r4r5r6rkr.Úpropertyr“r˜r¡r%r%r%r&r•Ïs    r•)N)N)F)UrkrPržZloggingr‚rvÚ collectionsrZ pip._vendorrrZpip._vendor.distlib.compatrZpip._vendor.requests.exceptionsrrrZpip._vendor.six.moves.urllibr rCr rYZpip._internal.models.linkr Zpip._internal.utils.filetypesr Zpip._internal.utils.miscrZpip._internal.utils.typingrZpip._internal.utils.urlsrrZpip._internal.vcsrrÚtypingrrrrrrrrrZxml.etree.ElementTreeZxmlZpip._vendor.requestsrZ!pip._internal.models.search_scoperZpip._internal.network.sessionrZetreeZ ElementTreeZElementZ HTMLElementrxZResponseHeadersZ getLoggerr4rLr'r*Ú Exceptionr+r?r@rJrNrQrWr]rcrgÚobjectrhrnror}r€r�r‘r•r%r%r%r&Ús^        ,         3  ý  6 ;