
    ce\                       d Z ddlm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 ddl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 dd
l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# ddl$m%Z%m&Z& ddl'm(Z(m)Z) ddl*m+Z, ej-        rddl	m.Z.  G d de          Z/ G d d          Z0 G d de          Z1da2d Z3dS )z1Worker threads for using the anaconda-client api.    )annotationsN)Unauthorized)QObjectQThreadQTimerSignal)SSLError)CondaAPI)TeamEditionAPI)is_internet_available)CONFAnacondaBrand)anaconda_solvers)	constants)notifications)	url_utils)version_utils)http_loggerlogger)is_text_stringto_text_string   )utils)Binstarc                  b     e Zd ZdZ eeee          Z eeee          Z fdZd Z	d Z
 xZS )ClientWorker#Anaconda Client API process worker.c                    t                                                       || _        || _        || _        d| _        dS )r   FN)super__init__methodargskwargs_is_finished)selfr!   r"   r#   	__class__s       Alib/python3.11/site-packages/anaconda_navigator/api/client_api.pyr    zClientWorker.__init__2   s<    	!    c                    | j         S )z?Return whether or not the worker has finished running the task.)r$   r%   s    r'   is_finishedzClientWorker.is_finished:   s      r(   c                T   d\  }}	 t          j        d            | j        | j        i | j        }nR# t
          $ rE}t          |          }|                    dd          }|                    dd          }Y d}~nd}~ww xY w| j        	                    | ||           d| _
        dS )zStart the worker process.NNg{Gz?( )NT)timesleepr!   r"   r#   	Exceptionstrreplacesig_finishedemitr$   )r%   erroroutputerrs       r'   startzClientWorker.start>   s    "v	+Jt T[$);t{;;FF 	+ 	+ 	+HHEMM#r**EMM#r**EEEEEE	+
 	tVU333 s   +3 
B;A==B)__name__
__module____qualname____doc__r   objectsig_chain_finishedr6   r    r+   r;   __classcell__r&   s   @r'   r   r   ,   s        --776&&&11L" " " " "! ! !! ! ! ! ! ! !r(   r   c                      e Zd ZdZdS )ArgszDDummy class to pass to anaconda client on token loading and removal.N)r<   r=   r>   r?    r(   r'   rE   rE   M   s        NNNNr(   rE   c                  ,    e Zd ZdZdZ fdZed             Zd Zd Z	d Z
ed(d	            Zed)d
            Zd*dZd Zd Zd Zd Z	 d(dZ	 d(dZd Zd(dZd)dZd Zd Z	 d+dZd Zd,dZd,dZed             Zd-d.d"Zd/d%Z d0d&Z!d0d'Z" xZ#S )1
_ClientAPIAnaconda Client API wrapper.   c                   t                                                       t                      | _        d| _        t          j                    | _        g | _        g | _	        t                      | _        | j                            d           | j        j                            | j                   t!          j                     |                                  dS )rI   Ni  )r   r    r
   
_conda_api_anaconda_client_apicollectionsdeque_queue_threads_workersr   _timersetIntervaltimeoutconnect_cleanr   set_logged_datareload_client)r%   r&   s    r'   r    z_ClientAPI.__init__V   s    "**$(!!'))hh%%%##DK000 	r(   c                    | j         S N)rM   r*   s    r'   anaconda_client_apiz_ClientAPI.anaconda_client_apig   s    ((r(   c                8   | j         r8| j         D ]0}|                                r| j                             |           1| j        r:| j        D ]0}|                                r| j                            |           1dS | j                                         dS )z7Check for inactive workers and remove their references.N)rR   r+   removerQ   
isFinishedrS   stop)r%   wts      r'   rW   z_ClientAPI._cleank   s    = 	,] , ,==?? ,M((+++= 	] , ,<<>> ,M((+++, , Kr(   c                    t          | j                  dk    rH| j                                        }|                                 | j                                         dS dS )z2Take avalaible worker from the queue and start it.r   N)lenrP   popleftr;   rS   )r%   threads     r'   _startz_ClientAPI._starty   sY    t{q  [((**FLLNNNK ! r(   c                   t                      }t          |||          }|                    |           |j                            | j                   |j                            |j                   |j                            |j                   | j	        
                    |           | j        
                    |           | j        
                    |           |                                  |S )z?Create a worker for this client to be run in a separate thread.)r   r   moveToThreadr6   rV   rg   quitstartedr;   rP   appendrQ   rR   )r%   r!   r"   r#   rf   workers         r'   _create_workerz_ClientAPI._create_worker   s     fdF33F#####DK000##FK000v|,,,6"""V$$$V$$$r(   Nc                j   |i }i }i }d |                                  D             D ]\  }}|                    dd          \  }}}|                    d|          }|                    d|          }|                    |d          Q|                    |d          pi i i                     dd          d	di                     d
d          i g d	x||<   d                             |           |                    dd	          d         |<   d	}		 t	          |                    dd	                    }	n# t
          t          f$ r Y nw xY wt          j        |d                   |	fd	d         fk    rL|                    dd          pd         d<   |                    d
d          pd
         d
<   |	d<   |d<   |                    dd          }
|
rI|
d         |<   |                    dd          d         |<   |                    dd          d         |<   |	                                D ]o\  }}t          j
        |d         d          |d<   |d         rC|                                d
         rd
         d<   fdd         D             d<   ||<   p||fS )zp
        Load all the available package information.

        See load_repadata for full documentation.
        Nc              3  z   K   | ]6}d D ]1}|                     |i                                           D ]}|V  27dS ))packageszpackages.condaN)getitems).0contentgroupitems       r'   	<genexpr>z,_ClientAPI._load_repodata.<locals>.<genexpr>   s~       +
 +
;+
 +
 #KKr2288::	+
 +
  +
 +
 +
 +
 +
 +
 +
 +
r(   -   nameversionhomer/   r   summary)		app_entryapp_typer}   latest_buildlatest_versionsizer~   typeversionsr   r   build_numberr   r   r   r   r   T)uniquedescriptionc                (    g | ]}|d          v |S )r   rF   )rt   r|   records     r'   
<listcomp>z-_ClientAPI._load_repodata.<locals>.<listcomp>   s2     & & &&.00 000r(   )valuesrsplitrr   rl   int
ValueError	TypeErrorr   comparers   sortcopy)repodatametadataall_packagesall_appscanonical_name
definitionr{   r|   _record_buildrecord_typepackager   s               @r'   _load_repodataz_ClientAPI._load_repodata   sD    H+
 +
'00+
 +
 +
 /	O /	O&NJ  .44S!<<D'1>>&$//D nnY88G!%%dD11F~!dD117R!# ""JJvr22$%&(%zz)R88 "
/ 
/ 
T"V :%%g...&0nnVQ&?&?F6N7#L":>>.!#D#DEE	*   %gv6F/GHH,W[\^des^tZuuu!+!;!;!Mvf~v$.NN9b$A$A$VVIEVy!)5~&+2'($..44K O*5vw'/9~~k4/P/P{#G,.8nnZ.N.Nz"7+)//11 	( 	(MD'"/"4WZ5HQU"V"V"VGJv 	( )$ >,29,=F=)& & & &#)*#5& & &z"
 "(X%%s   #D>>EEc                H   |r|ng }g }i }|D ]0}t          |                    dd                    \  }}}	d|i||<   1i }
|D ]0}t          |                    dd                    \  }}}	d|i|
|<   1t          t          t	          t          |                                          t          |
                                          z   t          |                                           z                                 }|pi }|D ]}|                     |          p|                    |i           }|                    d          pd}|                    d          pd}|                    d          pg }|                    d          pd}||
v r5t          j        }|
|                             dd          }t          j	        }n||v rt          j
        }||                             dd          }t          j	        }||v rp|}||d	         k     ot          |          d
k    }||d         k     ot          |          d
k    }|r|rt          j        }n6|rt          j        }n'|rt          j        }nt          j
        }t          j        }t          j        t          j        t          j        |t          j        |t          j        |                                t          j        |t          j        |t          j        |t          j        di}|                    |           |S )z0Prepare model data for the packages table model.ry   rz   r|   r~   r/   r}   r   r   r   r   N)tupler   sortedlistsetkeysrr   CPIP_PACKAGE	INSTALLEDCONDA_PACKAGErd   MIXGRADABLE
UPGRADABLEDOWNGRADABLENOT_INSTALLED
COL_ACTIONACTION_NONECOL_PACKAGE_TYPECOL_NAMECOL_DESCRIPTION
capitalizeCOL_VERSION
COL_STATUSCOL_URLCOL_ACTION_VERSIONrl   )rq   linkedpipr   datalinked_packagesr   r{   r|   r   pip_packagespackages_namespackages_metadatap_datar~   urlr   type_statusvers
upgradabledowngradablerows                          r'   _prepare_model_dataz_ClientAPI._prepare_model_data   s     ccb$ 	9 	9N$^%:%:3%B%BCCD'1%.$8OD!!! 	6 	6N$^%:%:3%B%BCCD'1"+W!5LT/..0011D9J9J9L9L4M4MMPTU]UbUbUdUdPePeeffii
 
 %N" +	 +	D\\$''J+<+@+@r+J+JFjj++1rG**V$$*Czz*--3Hjj!1228bG|##&t,00B??(()$/33IrBBh&&#D%,R%8!8!KSYY!^J'.$q''9#9#Lc$ii1nL! 0l 0!"# 0!"% 0!" am"E
D!7#5#5#7#7wf	3$d	C KKr(   return-typing.Union['Binstar', TeamEditionAPI, None]c                   t          j        ddd          }t          j                    \  }}|t          j        t          j        fv r|                     |          S |t          j        k    r|                     |          S |}t          j
                    5  t          j                                        d         }ddd           n# 1 swxY w Y   	 	 |                     |          }|                                 |S # t          t           t"          f$ r |                     |          cY S t$          j        j        $ r |                     |          cY S t          j        $ r_}|j        dd         dk    s|j        d	k    r;|                                  t2          j                            d
dd           Y d}~ d}~ww xY w)zX
        Sets the client depending on the settings from the configuration file.
        mainanaconda_api_urlNr   Tr   rz   )i  zEmail verification failed!z]Your email is not verified. Please verify it on anaconda.org and log into your account again.zEmail not verified)anacondaemail_verification)messagecaptiontags)r   rr   get_logged_datar   ANACONDA_ORGENTERPRISE_EDITION_load_binstar_clientTEAM_EDITION_load_team_edition_clientr   catch_and_notifybinstar_clientr   
get_configuserr   r	   r   requests
exceptionsConnectionErrorBinstarErrorr"   r   logoutr   NOTIFICATION_QUEUEpush)r%   r   logged_brandlogged_api_urlr   clientr8   s          r'   rY   z_ClientAPI.reload_client$  s)    26&BTVZ1[1['+';'='=$nM68XYYY,,^<<<=55511.AAA
 .00 	; 	; &1133E:C	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	;	22377 (J7 C C C 001ABBBBB&6 C C C001ABBBBB!.   JqsOv--5=D`3`3`KKMMM!499% !5? :    HHHHs=   %CCC*C? ?,G-(GG%AF?>F??Gc                   i }t          j                    5  t          j                                        }ddd           n# 1 swxY w Y   ||d<   |d                                         D ]}||d<   t          j                    5  t          j                            |           ddd           n# 1 swxY w Y   |                                 }t          j                            |dd|t          j
                  }|| _        |S )ar  
        Recreate the binstar client with new updated values.

        Notes:
        ------
        The Client needs to be restarted because on domain change it will not
        validate the user since it will check against the old domain, which
        was used to create the original client.

        See: https://github.com/ContinuumIO/navigator/issues/1325
        Nr   sites)tokensiteclsconfig	log_level)r   r   r   r   r   r   
set_config
load_tokenget_server_apiloggingNOTSETrM   )r%   api_urlr   r   r   binstars         r'   r   z_ClientAPI._load_binstar_clientY  s{     .00 	7 	7#)4466F	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7  u7O**,, 	" 	"D!DKK.00 	4 	4 ++F333	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 !! &55dVw~ 6 
 
 %,!s#   AAA B22B69B6c                    | j                                                             dd          }t          ||          | _        | j        S )zt
        Sets the '_anaconda_client_api' to user TeamEdition API instead of
        default Binstar client.
        
ssl_verifyF)rL   load_rcrr   r   rM   )r%   r   
verify_ssls      r'   r   z$_ClientAPI._load_team_edition_clientw  sB    
 _,,..22<GG
$27J$G$G!((r(   c                    | j         j        S )z6Return the current token registered with authenticate.)rM   r   r*   s    r'   r   z_ClientAPI.token  s    (..r(   c                    d}	 t          | j        t                    r| j                                        }n1t          j                            |                                           }n# t          $ r Y nw xY w|S )z!Load current authenticated token.N)
isinstancerM   r   r   r   r   get_api_urlOSError)r%   r   s     r'   r   z_ClientAPI.load_token  s    	$3^DD L1<<>>&,778H8H8J8JKK 	 	 	D	 s   A%A* *
A76A7c                Z   t          | j        t                    r7| j                            |||          }| j                            |           nY| j                            ||||          }t                      }d|_        ||_        t          j	                            ||           |S )zLogin callback.N)
r   rM   r   authenticatestore_tokenrE   r   r   r   r   )r%   usernamepasswordapplicationapplication_urlr   	new_tokenr"   s           r'   _loginz_ClientAPI._login  s     d/@@ 	>1>>xS]^^I%11)<<<< 1>>xS^`oppI66DDI"DJ ,,Y===r(   c                D    | j         }|                     ||||||          S )zLogin to anaconda server.)r  rn   )r%   r   r  r  r  r   r!   s          r'   loginz_ClientAPI.login  s*     ""68X{O]ghhhr(   c                &   d}t                      }d|_        |                                 |_        t          | j        t
                    r| j                                         nt          j        	                    |           |                                 rR	 | j        
                                 n7# t          j        j        $ r}|}Y d}~nd}~wt          $ r}|}Y d}~nd}~ww xY wt          j        d           t!          j                     |S )zr
        Logout from anaconda.org.

        This method removes the authentication and removes the token.
        Nzlogout successful)rE   r   r   r   rM   r   r   r   r   remove_tokenremove_authenticationerrorsr   r3   r   infor   rX   )r%   r8   r"   es       r'   r   z_ClientAPI.logout  s    vv	ZZ\\
d/@@ 	-%,,.... --d333zz|| -CCEEEE%,9   EEEEEE    EEEEEE K+,,,s$   B3 3C'CC'C""C'c                <    |                      | j        ||          S )a  
        Load all the available packages information for downloaded repodata.

        For downloaded repodata files (repo.anaconda.com), additional data provided (anaconda cloud), and additional
        metadata and merge into a single set of packages and apps.

        :param repodata: Data loaded from the conda cache directories.
        :param metadata: Metadata info form different sources. For now only from repo.anaconda.com
        )r   )rn   r   )r%   r   r   s      r'   load_repodataz_ClientAPI.load_repodata  s"     ""4#68"TTTr(   c                D    | j         }|                     |||||          S )z=Prepare downloaded package info along with pip pacakges info.)r   r   )r   rn   )r%   rq   r   r   r   r!   s         r'   prepare_model_dataz_ClientAPI.prepare_model_data  s6    )"" # 
 
 	
r(   c                .    |                      d          S )z'Return current logged user information.Nr  )organizationsr*   s    r'   r   z_ClientAPI.user  s    !!!---r(   c                    | j         j        S )zReturn current domain.)rM   domainr*   s    r'   r  z_ClientAPI.domain  s    (//r(   c                P    | j         j        }|                     ||||||          S )a]  Return all the available packages for a given user.

        Parameters
        ----------
        type_: Optional[str]
            Only find packages that have this conda `type`, (i.e. 'app').
        access : Optional[str]
            Only find packages that have this access level (e.g. 'private',
            'authenticated', 'public').
        )r  platformpackage_typer   access)rM   user_packagesrn   )r%   r  r  r  r   r  r!   s          r'   rq   z_ClientAPI.packages  s>     *8""% # 
 
 	
r(   c                d    	 | j                             |          }n# t          $ r i }Y nw xY w|S )z0List all the organizations a user has access to.r  )rM   r   r3   )r%   r  r   s      r'   r  z_ClientAPI.organizations  sK    	,111>>DD 	 	 	DDD	s    --r4   c                "   t          | j        t                    rt          j        dd          S i }t          j                    5  t          j        	                                }ddd           n# 1 swxY w Y   |                    dd          S )z*Get the anaconda client url configuration.r   anaconda_server_api_urlNr   https://api.anaconda.org)
r   rM   r   r   rr   r   r   r   r   r   r%   config_datas     r'   r   z_ClientAPI.get_api_url  s    d/@@ 	?8F$=>>>"$.00 	< 	<(.99;;K	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< u&@AAAs   A00A47A4c                H   t          | j        t                    r(t          j        t          j        dd          d          S i }t          j                    5  t          j
                                        }ddd           n# 1 swxY w Y   |                    dd          S )z/Get the anaconda client info url configuration.r   r  z
api/systemNr   r  )r   rM   r   r   joinr   rr   r   r   r   r   r   r   s     r'   get_api_info_urlz_ClientAPI.get_api_info_url  s    d/@@ 	]>$(63L"M"M|\\\"$.00 	< 	<(.99;;K	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< u&@AAAs   BB
Bc                    t          j                    5  t          j                                        }| |d<   t          j                            |           ddd           dS # 1 swxY w Y   dS )*Set the anaconda client url configuration.r   N)r   r   r   r   r   r   )r   r!  s     r'   set_api_urlz_ClientAPI.set_api_url  s     .00 	9 	9(.99;;K!$K ++K888	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9s   AA$$A(+A(Tset_conda_sslboolc                   i }t          j                    5  t          j                                        }ddd           n# 1 swxY w Y   |s*|                    d|                    dd                    S | j                            d                                          d                             d          }|x|d<   |d<   t          j                    5  t          j        	                    |           ddd           n# 1 swxY w Y   t          j        ddd          }t          j        dd	g           }t          j        |pd
          |v rnnt          |t                    r-t          j        dd|           t          j        ddd           n,t          j        ddd           t          j        dd|           |S )z`
        Get conda ssl configuration and set navigator and anaconda-client accordingly.
        Nr   r   Tr   r   r   ssltrusted_serversr/   ssl_verificationssl_certificate)r   r   r   r   r   rr   rL   
config_getcommunicater   r   r   netlocr   r)  r   )r%   r(  r   valuer   r,  s         r'   get_sslz_ClientAPI.get_ssl$  s*     .00 	7 	7#)4466F	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7  	L::lFJJ|T,J,JKKK**<88DDFFqIMMl[[6;;|vl3.00 	4 	4 ++F333	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 04x@PRV/W/W,0HU<Mr,R,RN0b11_DD t$$ 	7HV/777HV.5555HV/666HV.666s#   AAA DD
D
r2  Nonec                   i }t          j                    5  t          j                                        }ddd           n# 1 swxY w Y   ||d<   ||d<   t          j                    5  t          j                            |           ddd           n# 1 swxY w Y   | j                            d|                                           dS )r&  Nr   r   )	r   r   r   r   r   r   rL   
config_setr0  )r%   r2  r!  s      r'   set_sslz_ClientAPI.set_sslD  s:   "$.00 	< 	<(.99;;K	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	<$)L!$)L!.00 	9 	9 ++K888	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	""<77CCEEEEEs#   AAA) BBBc                *   |pi }|dt           j        ddddd}t                      r	 t          j        ||t          j        |          | j                  }t          j	        |           t          |j        d	
          }t          j        |          }|                                D ]/\  }}	t          |	          r|	d         dk    r
|	dd         n|	||<   0n8# t           $ r+}
t#          j        t'          |
                     Y d}
~
nd}
~
ww xY w|S )z	Callback.zhttps://api.anaconda.org/docszhttps://conda.anaconda.orgzhttps://anaconda.orgzhttps://pypi.anaconda.orgz%https://api.anaconda.org/swagger.json)r   api_docs_urlbrand	conda_urlmain_urlpypi_urlswagger_url)proxiesverifyrU   )responsezutf-8)encodingr   /N)r   DEFAULTr   r   rr   	api_utilsnormalize_certificateDEFAULT_TIMEOUTr   httpr   ru   jsonloadsrs   r   r3   r   r8   r4   )r%   r   proxy_serversr@  r   rru   new_datakeyr2  r8   s              r'   _get_api_infoz_ClientAPI._get_api_infoP  sW   %+;"*5.3B
 
 !"" 	))L)$:6BB 0	    !,,,,(WEEE:g.. #+.."2"2 N NJC%e,, N27)s2B2BE#2#JJS	N  ) ) )SZZ(((((((() s   B2C 
D%!DDc                J    |pi }| j         }|                     ||||          S )zQuery anaconda api info.)rK  r@  )rO  rn   )r%   r   rK  r@  r!   s        r'   get_api_infoz_ClientAPI.get_api_infor  s2    %+#""63mTZ"[[[r(   r[   r-   )r   r   )NNNNN)r   r4   )T)r(  r)  r   r)  )r2  r)  r   r4  )NT)$r<   r=   r>   r?   rG  r    propertyr\   rW   rg   rn   staticmethodr   r   rY   r   r   r   r   r  r  r   r  r  r   r  rq   r  r   r$  r'  r3  r7  rO  rQ  rB   rC   s   @r'   rH   rH   Q   s       &&O    " ) ) X)         " M& M& M& \M&^ > > > \>D3 3 3 3j  <) ) )/ / /   PT   ( PTi i i i  :
U 
U 
U 
U	
 	
 	
 	
. . .0 0 0
 TX
 
 
 
.  	B 	B 	B 	B	B 	B 	B 	B 9 9 \9    @
F 
F 
F 
F       D\ \ \ \ \ \ \ \r(   rH   c                 :    t           t                      a t           S )zClient API threaded worker.)
CLIENT_APIrH   rF   r(   r'   	ClientAPIrV  |  s     \\
r(   )4r?   
__future__r   collections.abcrN   rI  r   r1   typingr   r   binstar_client.errorsr   qtpy.QtCorer   r   r   r   requests.exceptionsr	    anaconda_navigator.api.conda_apir
   'anaconda_navigator.api.team_edition_apir   anaconda_navigator.api.utilsr   anaconda_navigator.configr   r   anaconda_navigator.utilsr   r   r   r   r   r   anaconda_navigator.utils.logsr   r   "anaconda_navigator.utils.py3compatr   r   r/   r   rE  TYPE_CHECKINGr   r   rE   rH   rU  rV  rF   r(   r'   <module>re     si   8 7 " " " " " "              . . . . . . 8 8 8 8 8 8 8 8 8 8 8 8 ( ( ( ( ( ( 5 5 5 5 5 5 B B B B B B > > > > > > 9 9 9 9 9 9 9 9 5 5 5 5 5 5 3 3 3 3 3 3 2 2 2 2 2 2 . . . . . . 2 2 2 2 2 2 = = = = = = = = M M M M M M M M            	 '&&&&&&! ! ! ! !7 ! ! !BO O O O O O O Oe\ e\ e\ e\ e\ e\ e\ e\P 
    r(   