
    XhV              
          d Z ddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
Zddl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 ddlmZmZ dd	lmZ dd
lmZmZmZ ddl m!Z! ddl"m#Z# ddl$Z$ddl%Z%ddl&m'Z' ddl(m)Z) ddl*m+Z+m,Z,m-Z-m.Z.m/Z/ ddl0m1Z1 ddl2m3Z3m4Z4m5Z5m6Z6  G d dejn                  jp                        Z9 ejt                  d      Z; ejt                  d      xs  ejt                  d      xs e;Z< ejt                  d      xs  ejt                  d      xs e<xs e;Z= e)e$jb                        Z>i Z?dZ@e<r| e!e<      ZAeAj                  j                  d      \  ZDZEZFe> e)d      k\  r*d e$j                  e<       e$j                  e=      diZ?nde<e=diZ? e9       Z@e@j                  eDeF       de$j                  d eJd!eJd"eJd#eKf
d$ZL G d% d&e4      ZMy)'OExtension manager using pip as package manager and PyPi.org as packages source.    N)datetime	timedeltatimezone)partial)groupby)environ)Path)CalledProcessErrorrun)TarFile)AnyCallableOptional)urlparse)ZipFile)
alru_cache)Version)CFloatCIntUnicodeconfigobserve)__version__)ActionResultExtensionManagerExtensionManagerMetadataExtensionPackagec                       e Zd ZddZd Zy)ProxiedTransportNc                 $    ||f| _         || _        y N)proxyproxy_headers)selfhostportheaderss       N/var/www/html/myenv/lib/python3.12/site-packages/jupyterlab/extensions/pypi.py	set_proxyzProxiedTransport.set_proxy*   s    4Z
$    c                     t        j                  j                  | j                   }|j	                  || j
                         ||f| _        |S )Nr(   )httpclientHTTPConnectionr#   
set_tunnelr$   _connection)r%   r&   
connections      r)   make_connectionz ProxiedTransport.make_connection.   sF    [[//<
dD,>,>?+r+   )NN)__name__
__module____qualname__r*   r4    r+   r)   r    r    )   s    %r+   r    	ALL_PROXY
http_proxy
HTTP_PROXYhttps_proxyHTTPS_PROXY:z0.28.0mounts)r#   )zhttp://zhttps://proxiesr/   namelatest_versionbase_urlreturnc                 $  K   | j                  |d| d| dz   ddi       d {   }|j                  dk  rNt        j                  |j                        j                  d      }dD ci c]  }||j                  |       c}S i S 7 cc c}w w)	N//jsonContent-Typeapplication/jsonr-     info)	authorbugtrack_urldocs_url	home_pagelicensepackage_urlproject_urlproject_urlssummary)getstatus_codejsonloadstext)r/   rA   rB   rC   responsedataks          r)   _fetch_package_metadatar]   Z   s      ZZQtfAn-U33!34    H c!zz(--(,,V4


 txx{N
 	
 	/
s"   #BB	AB+BBBc                       e Zd ZdZ eddd      Z eddd      Z eddd	      Z	 ed
dd      Z
	 	 	 d&dee   dee   deej                     ddf fdZedefd       Zdedee   fdZdedefdZdededefdZ ed      d        Zdedededeeeef   ee   f   fdZde eeef      fd Z!d'd!ed"ee   de"fd#Z#dede"fd$Z$d!edefd%Z% xZ&S )(PyPIExtensionManagerr   zhttps://pypi.org/pypiTzThe base URL of PyPI index.)r   helpg     r@z.PyPI extensions list cache timeout in seconds.i  z$The cache size for package metadata.g      ?zGThrottling time in seconds between PyPI requests using the XML-RPC API.Napp_optionsext_optionsparentrD   c                    t         |   |||       t        j                  d	i t        | _        t        t        | j
                        | _        | j                  d| j                  i       t        j                  j                  | j                  t              | _        t!        j"                  t$        j&                        t)        | j*                  dz        z
  | _        d | _        | j0                  j3                  d| j                   d       t        r-| j0                  j5                  dt        j6                          y y )
Nnew)	transporttz)\(?secondsz%Extensions list will be fetched from .z=Extensions will be fetched using proxy, proxy host and port: r8   )super__init__httpxAsyncClient_httpx_client_args_httpx_clientr   r]   $_observe_package_metadata_cache_sizepackage_metadata_cache_sizexmlrpcr/   ServerProxyrC   xmlrpc_transport_override_rpc_clientr   nowr   utcr   cache_timeout5_PyPIExtensionManager__last_all_packages_request_time)_PyPIExtensionManager__all_packages_cachelogdebugrK   r#   )r%   ra   rb   rc   	__class__s       r)   rn   zPyPIExtensionManager.__init__   s    	k6:"..D1CD'./FHZHZ'[$115$:Z:Z2[\!==44MM%> 5 
 190MPY&&-Q
 1
- %)!>t}}oQOP$HHMMOPiPoPoOpq %r+   c                 8    t        ddt        j                        S )zExtension manager metadata.PyPIT)r   sysprefixr%   s    r)   metadatazPyPIExtensionManager.metadata   s     (cjjAAr+   pkgc                   K   	 | j                   j                  | j                  d| dz   ddi       d{   }|j                  dk  r0t	        j
                  |j                        j                  di       }n| j                  j                  d	|       y	 t        j                  |j                  d
d            xs dS 7 # t        $ r Y yw xY ww)zReturn the latest available version for a given extension.

        Args:
            pkg: The extension to search for
        Returns:
            The latest available version
        rF   rG   rH   rI   r-   NrJ   rK   z+Failed to get package information on PyPI; version )rr   rU   rC   rV   rW   rX   contentr~   r   r   get_semver_version	Exception)r%   r   rZ   r[   s       r)   get_latest_versionz'PyPIExtensionManager.get_latest_version   s     	X!//33!C5.I[8\ 4  H ##c)zz("2"2377C!LXLYZ  $66txx	27NOWSWW  		s?   C3C CA!C C)CC 	CCCC	extensionc                     |j                   (|j                   }|d   dk(  r| j                  |d         S | j                  |j                        S )a  Normalize extension name.

        Extension have multiple parts, npm package, Python package,...
        Sub-classes may override this method to ensure the name of
        an extension from the service provider and the local installed
        listing is matching.

        Args:
            extension: The extension metadata
        Returns:
            The normalized name
        packageManagerpythonpackageName)install_normalize_namerA   )r%   r   install_metadatas      r)   get_normalized_namez(PyPIExtensionManager.get_normalized_name   sV     ((00 01X=++,<],KLL##INN33r+   	recursivefnc                   K   t         j                  j                  j                         }	  |j                  d|g|  d{   }|S 7 # t
        j                  j                  $ r}|j                  dk(  r|j                  j                  d      rd}t        j                  d|j                        }|t        |j                  d      xs d      }| j                  j!                  d| d	       t#        j$                  || j&                  z  d
z          d{  7   |r | j(                  d|g|  d{  7  }n |j                  d|g|  d{  7  }Y d}~S d}~ww xY ww)a/  Throttle XMLRPC API request

        Args:
            recursive: Whether to call the throttling recursively once or not.
            fn: API method to call
            *args: API method arguments
        Returns:
            Result of the method
        Raises:
            xmlrpc.client.Fault
        NizHTTPTooManyRequests:ri   z!Limit may reset in (\d+) seconds.   1z>HTTPTooManyRequests - Perform next call to PyPI XMLRPC API in zs.g{Gz?F)tornadoioloopIOLoopcurrentrun_in_executorru   r/   Fault	faultCodefaultString
startswithresearchintgroupr~   rK   asynciosleeprpc_request_throttling&_PyPIExtensionManager__throttleRequest)	r%   r   r   argscurrent_loopr[   errdelaymatchs	            r)   __throttleRequestz&PyPIExtensionManager.__throttleRequest   sM     ~~,,446	O555dBFFFD$ % G}}"" 	O}}&3??+E+E&, 		"FX$A 5#6ETUZT[[]^ mmED,G,G$G$$NOOO!7!7!7r!ID!IIID!=!=!=dB!N!NNND#	Ose   )E.A A
A E.
A E+*B3E&D E&<D?=E&EE& E.&E++E.rt   c                 h     t        |d         t        t        | j                              | _        y )Nre   )maxsize)r   r   r]   rr   )r%   changes     r)   rs   z9PyPIExtensionManager._observe_package_metadata_cache_size   s+    'Hz&-'H+T-?-?@(
$r+   querypageper_pagec                 ,  K   | j                          d{   }i }g }t        t        fd|      d       D ]  \  }}t        |      d   \  }	}
| j	                  ||
| j
                         d{   }| j                  |      }|j                  d      xs i }|j                  d      }|j                  d      xs |j                  d      }|j                  d	      xs |j                  d
      }|j                  d      xs |j                  d      }|xs0 |j                  d      xs |j                  d      xs
 |xs |xs |}t        ||j                  d      ||j                  d      |j                  d      t        j                  |
      d|||j                  d      |      }d}|||fD cg c]  }|st        |      j                           }}ddg}|D ]*  |v rd} n"t        fddD              rd} n
dv s(d} n |j                  ||f        t        |d       }|dz
  |z  }||z   }||| }|D ]  \  }	}|||j                   <    t#        j$                  t'        |      |z        }||fS 7 q7 c c}w w)a  List the available extensions.

        Note:
            This will list the packages based on the classifier
                Framework :: Jupyter :: JupyterLab :: Extensions :: Prebuilt

            Then it filters it with the query and sorts by organization priority:
            1. Project Jupyter (@jupyter)
            2. JupyterLab Community (@jupyterlab-contrib)
            3. Others

        Args:
            query: The search extension query
            page: The result page
            per_page: The number of results per page
        Returns:
            The available extensions in a mapping {name: metadata}
            The results last page; None if the manager does not support pagination
        Nc                     | d   v S Nr   r8   )mr   s    r)   <lambda>z4PyPIExtensionManager.list_packages.<locals>.<lambda>  s    EQqTM r+   c                     | d   S r   r8   )es    r)   r   z4PyPIExtensionManager.list_packages.<locals>.<lambda>  s    WXYZW[ r+   rS   zSource CoderO   HomepagerN   DocumentationrM   zBug TrackerrR   rQ   rT   rL   rP   prebuilt)rA   descriptionhomepage_urlrL   rP   rB   pkg_typebug_tracker_urldocumentation_urlpackage_manager_urlrepository_url   z-https://github.com/jupyterlab/jupyterlab_apodz0https://github.com/jupyterlab/extension-examples   c              3   &   K   | ]  }|v  
 y wr"   r8   ).0orgurls     r)   	<genexpr>z5PyPIExtensionManager.list_packages.<locals>.<genexpr>J  s       3Js   )zgithub.com/jupyter/zjupyter.orgzgithub.com/jupyterlab/r   zgithub.com/jupyterlab-contrib/   c                 *    | d   | d   j                   fS )Nr   r   rA   )xs    r)   r   z4PyPIExtensionManager.list_packages.<locals>.<lambda>V  s    AaD!A$));L r+   )key))_PyPIExtensionManager__get_all_extensionsr   filterlistr]   rC   r   rU   r   r   r   strloweranyappendsortedrA   mathceillen)r%   r   r   r   matches
extensionsall_matchesrA   r   _rB   r[   normalized_namepackage_urls
source_urlr   r   r   best_guess_home_urlr   priorityr   urls_to_checkexcludesorted_matches	start_idxend_idxpage_matchestotal_pagess    `                   `       r)   list_packagesz"PyPIExtensionManager.list_packages   s    , 1133
"6*A7#K^\ ;	6KD% $UBA~55dNDMMZZD"2248O88N39rL%))-8J88K0PL4D4DZ4PL $ 4 Y8H8H8Y"hh~6Y,:J:J=:YO  #88M*#88M*# %# 	#
 #   )$ HHY/0xx)+/BB>R# /"3$(HH]$;)I H-7GZ,[%(_bC M  @BG
 % '> H _   !H5< H )45w;	6z  1LM AX)	h&%i8( 	3LAy)2Jy~~&	3 iiN 3h >?;&&] 4 [FsB   JJ	AJ3J4E	J=JJ /JA:JJJc                   K   | j                   Ht        j                  t        j                        | j
                  t        | j                        z   kD  ry| j                  j                  d       | j                  d| j                  j                  dg       d {   | _         t        j                  t        j                        | _        | j                   S 7 >w)Nrg   rj   z?Requesting PyPI.org RPC API for prebuilt JupyterLab extensions.Tz<Framework :: Jupyter :: JupyterLab :: Extensions :: Prebuilt)r}   r   ry   r   rz   r|   r   r{   r~   r   r   rx   browser   s    r)   __get_all_extensionsz)PyPIExtensionManager.__get_all_extensionsd  s     $$,||1
11IdFXFX4YY1Z HHNN\].2.D.D  ''OP/ )D%
 5=LLHLL4QD1((()s   BCC?CrA   r   c                 J  K   t         j                  j                  j                         }t	        j
                         5 }t	        j                  d|d      5 }|j                  dt                |j                          t        j                  ddddd	d
dd|j                  g
}||j                   d|        n|j                         i }	 |j                         }|j                  dd       |j                  dd       |j                  dd       |j!                  dt#        t$        |dd             d{   }	t'        j(                  |	j*                  j-                  d            }
t/        t1        fd|
j3                  dg                   }| j4                  j7                  dt'        j8                  |
       d       | j4                  j7                  ddjA                  |       d       |j!                  dt#        t$        |d             d{   }	| j4                  j7                  d |	jB                          | j4                  j7                  d!|	j*                  j-                  d              |	j<                  j-                  d      }|	jB                  d"k(  r@| j4                  j7                  d#|        d}	 |j3                  d$i       j3                  d%      }|| jD                  j3                  |       d{   }|jF                  d&k  rG|jI                  d'      rtK        tM        jN                  |jP                              5 }t1        d( |jS                               D ];  }t'        j(                  |jU                  |            }|j3                  d)      }|; n ddd       n|jI                  d*      rtW        tM        jN                  |jP                              5 }t1        d+ |jY                               D ]J  }t'        jZ                  |j]                  |j_                  |                  }|j3                  d)      }|J n ddd       n!| j4                  j7                  d,| d-|       d/g}|<|j3                  d0i       }d1|v r|j                  d1       d2|v r|j                  d2       ta        d3|4      cddd       cddd       S | j4                  jc                  d5 d6|	jB                   d7|        ta        d8|9      cddd       cddd       S 7 # t:        $ r5}| j4                  j7                  d|j<                   |       Y d}~d}~wt>        $ r(}| j4                  j7                  d|       Y d}~d}~ww xY w7 7 # 1 sw Y   0xY w# 1 sw Y   =xY w# t>        $ r(}| j4                  j7                  d.|       Y d}~ld}~ww xY w# 1 sw Y   nxY wddd       y# 1 sw Y   yxY ww):a  Install the required extension.

        Note:
            If the user must be notified with a message (like asking to restart the
            server), the result should be
            {"status": "warning", "message": "<explanation for the user>"}

        Args:
            name: The extension name
            version: The version to install; default None (i.e. the latest possible)
        Returns:
            The action result
        zw+F)modedirdeletezjupyterlab==-mpipr   
--no-inputz--quietz--progress-baroffz--constraintNz==r   z	--dry-runz--report-T)capture_outputcheckutf-8c                 l    | j                  di       j                  d      j                  dd      k(  S )Nr   rA   r   r   )rU   replace)prA   s    r)   r   z.PyPIExtensionManager.install.<locals>.<lambda>  s/    !%%
B"7";";F"Ct||TWY\G]"] r+   zActions to be executed by pip rl   z!Fail to get installation report: exc_infoz Fail to get installation report.Executing ' 'r   return code: stdout: r   stderr: download_infor   rJ   z.whlc                 2    t        |       j                  dk(  S Nzpackage.jsonr
   rA   fs    r)   r   z.PyPIExtensionManager.install.<locals>.<lambda>      $q',,.2P r+   
jupyterlabztar.gzc                 2    t        |       j                  dk(  S r  r  r  s    r)   r   z.PyPIExtensionManager.install.<locals>.<lambda>  r  r+   zFailed to get 'z'; zFail to get package.json.frontend	discoverykernelserverokstatusneeds_restartzFailed to install : code 
errorr  message)2r   r   r   r   tempfileTemporaryDirectoryNamedTemporaryFilewriter   flushr   
executablerA   r   copyinsertr   r   r   rW   rX   stdoutdecodenextr   rU   r~   r   dumpsr   stderrr   join
returncoderr   rV   endswithr   ioBytesIOr   namelistreadr   getnamesloadextractfile	getmemberr   r"  )r%   rA   r   r   ve_dirfconstraintcmdline
pkg_actiontmp_cmdresultaction_infor   r   r"  jlab_metadatadownload_urlrZ   wheelfilenamer[   sdist
follow_upsr  s    `                     r)   r   zPyPIExtensionManager.installr  s     ~~,,446'')j	C-3''TveLj	CP[[M:;    G "$r'34t$J\!,,.r;/r:.r3'+;;'#wt4P   #jj)=)=g)FG!]#	26
 !?

;@W?XXYZ[HHNN['):(;1=>'77gc74@ F HHNN]6+<+<*=>?HHNNXfmm&:&:7&C%DEFMM((1E  A%%12 $L(2(K(O(OPU(VL#/)-););)?)?)M#M#//#5+44V<%,RZZ8H8H-I%J !2e4:(P(-(85& %2 04zz%**X:N/O8<8N+8+D,1%2!2 !2 ".!6!6x!@%,RZZ8H8H-I%J 
!2e4:(P(-(85& 	%2 04yy,1,=,=eooh>W,X0* 9=8N+8+D,1	%2
!2 
!2 !HHNN_\N#h\+Z[
 
 !, - 1 1+r BI9,"))(39,"))(3#4zJOj	C j	C j	CR !3D6ARAR@SSUV[U\]^#7EBUj	C j	C j	C< & [!B188*MXYZZ QACPPQ $N!2 !2
!2 
!2 ! LHHNN#>NKKLuj	C j	C j	C j	C j	Cs*  =X# XA9XA,T>?T; AT>BXV. B.XAWV1AWAV46V49AW;A%W!W$*WAX	X$
X#.:X(	X1
X#;T>>	V+*U71X7V+V& X&V++X1W4V>9WWW	W?W:4X:W??XX	X	X#X X#c           	        K   t         j                  j                  j                         }t        j
                  ddddd|g}d}	 |j                         }|j                  d       |j                  dt        t        |d             d{   }t        d	 t        d
 |j                  j                  d      j                                     }t        d t        t         |            D ]:  }t#        j$                  |j'                               }	|	j)                  d      }|: n | j,                  j/                  ddj1                  |       d       |j                  dt        t        |d             d{   }| j,                  j/                  d|j2                          | j,                  j/                  d|j                  j                  d              |j4                  j                  d      }|j2                  dk(  rl| j,                  j/                  d|        dg}|<|j)                  di       }d|v r|j7                  d       d|v r|j7                  d       t9        d|      S | j,                  j;                  d| d|j2                   d|        t9        d |!      S 7 $# t*        $ r(}
| j,                  j/                  d|
       Y d}
~
d}
~
ww xY w7 lw)"aj  Uninstall the required extension.

        Note:
            If the user must be notified with a message (like asking to restart the
            server), the result should be
            {"status": "warning", "message": "<explanation for the user>"}

        Args:
            extension: The extension name
        Returns:
            The action result
        r   r   	uninstallz--yesr   NTr  c                 $    | j                  d      S r  )r4  lines    r)   r   z0PyPIExtensionManager.uninstall.<locals>.<lambda>  s    T]]>: r+   c                 "    | j                         S r"   )striprM  s    r)   r   z0PyPIExtensionManager.uninstall.<locals>.<lambda>  s     r+   r  c                      | j                   dk(  S r  r   r  s    r)   r   z0PyPIExtensionManager.uninstall.<locals>.<lambda>  s    !&&N2 r+   r  z%Fail to list files to be uninstalled.r  r  r	  r
  r  r  r   r  r  r  r  r  r  r  zFailed to installed r   r!  r"  r#  )r   r   r   r   r   r*  r+  remover   r   r   r   mapr-  r.  
splitlinesr
   rW   rX   
read_bytesrU   r   r~   r   r2  r3  r1  r   r   r"  )r%   r   r   r?  rD  rA  rB  linesfilepathr[   r   r"  rI  r  s                 r)   rK  zPyPIExtensionManager.uninstall  s     ~~,,446NN
 	PllnGNN7#'77gc74@ F :-v}}/C/CG/L/W/W/YZE #2D%   zz("5"5"78 $ 6 , 	SXXg%6$7q9:#33'#wt<
 
 	v'8'8&9:;&--"6"6w"?!@AB$$W-!HHNNXeW-.J ()--k2>	y(%%h/y(%%h/t:FFHHNN1)GFDUDUCVVXY^X_`aw>>U  	PHHNNBQNOO	P

sX   AK)AJ2 J/BJ2 $J2 'AK):K&;D4K)/J2 2	K#;KK)K##K)c                 f    |j                  dd      j                  dd      j                  dd      S )zNormalize extension name.

        Remove `@` from npm scope and replace `/` and `_` by `-`.

        Args:
            name: Extension name
        Returns:
            Normalized name
        @r   rF   r   r   )r  )r%   rA   s     r)   r   z$PyPIExtensionManager._normalize_name6  s/     ||C$,,S#6>>sCHHr+   )NNNr"   )'r5   r6   r7   __doc__r   rC   r   r{   r   rt   r   r   dictr   Configurablern   propertyr   r   r   r   r   r   boolr   r   r   r   rs   r   tupler   r   r   r   r   rK  r   __classcell__)r   s   @r)   r_   r_   z   s   Y.tB_`H$TM #'T F# $V '+&*04	d^ d^ ,,-	
 
4 B2 B BXC XHSM X.4-= 4# 4&   8  s  D *+
 ,

d'd' #d'/2d'	tC))*HSM9	:d'L)DsCx,A )yC# yC yC yCvG? G? G?R
IC 
IC 
Ir+   r_   )NrZ  r   http.clientr.   r5  rW   r   r   r   r%  xmlrpc.clientru   r   r   r   	functoolsr   	itertoolsr   osr	   pathlibr
   
subprocessr   r   tarfiler   typingr   r   r   urllib.parser   zipfiler   ro   r   	async_lrur   packaging.versionr   	traitletsr   r   r   r   r   jupyterlab._versionr   jupyterlab.extensions.managerr   r   r   r   r/   	Transportr    rU   all_proxy_urlhttp_proxy_urlhttps_proxy_url_httpx_versionrq   rw   r:   netloc	partition
proxy_hostr   
proxy_portAsyncHTTPTransportr*   rp   r   r[  r]   r_   r8   r+   r)   <module>r{     s   V   	   	 
   2 2     .  * * !      % < < + 	v}}.. 	 K( \*Xkgkk,.GX=GKK_+'++m"<__R_ 
 **+   .)J * 1 1 ; ;C @J:**3533.I4E44?K
 )+
 !1 2''
J?
  	
 
@FI+ FIr+   