
    IR-e                        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 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 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!m"Z" ddgZ#ddgZ$ G d d          Z% G d d          Z&dS )    N)
urlunparse)log   )SAMP_STATUS_OK__profile_version__)SAMPHubErrorSAMPProxyErrorSAMPWarning)create_lock_fileread_lockfile)ThreadingXMLRPCServer)ServerProxyPool_HubAsClientinternet_on)WebProfileXMLRPCServerweb_profile_text_dialogSAMPHubServerWebProfileDialog.zSAMPHubServer.*c                      e Zd ZdZ	 	 	 	 	 	 	 	 	 	 	 	 dJd	Zed
             Zd Zd Zd Z	d Z
dKdZdLdZd Zd Zd Zd ZdMdZed             Zd Zd Zd ZdLdZed             Zd Zd Zd Zd  Zd! Zd" Zd# Zd$ Zd% Z d& Z!d' Z"d( Z#d) Z$d* Z%d+ Z&d, Z'd- Z(d. Z)d/ Z*d0 Z+e,d1             Z-d2 Z.d3 Z/d4 Z0d5 Z1d6 Z2d7 Z3d8 Z4d9 Z5d: Z6d; Z7d< Z8d= Z9d> Z:d? Z;d@ Z<dLdAZ=dB Z>dC Z?dD Z@	 dNdGZAdH ZBdI ZCdS )Or   a
  
    SAMP Hub Server.

    Parameters
    ----------
    secret : str, optional
        The secret code to use for the SAMP lockfile. If none is is specified,
        the :func:`uuid.uuid1` function is used to generate one.

    addr : str, optional
        Listening address (or IP). This defaults to 127.0.0.1 if the internet
        is not reachable, otherwise it defaults to the host name.

    port : int, optional
        Listening XML-RPC server socket port. If left set to 0 (the default),
        the operating system will select a free port.

    lockfile : str, optional
        Custom lockfile name.

    timeout : int, optional
        Hub inactivity timeout. If ``timeout > 0`` then the Hub automatically
        stops after an inactivity period longer than ``timeout`` seconds. By
        default ``timeout`` is set to 0 (Hub never expires).

    client_timeout : int, optional
        Client inactivity timeout. If ``client_timeout > 0`` then the Hub
        automatically unregisters the clients which result inactive for a
        period longer than ``client_timeout`` seconds. By default
        ``client_timeout`` is set to 0 (clients never expire).

    mode : str, optional
        Defines the Hub running mode. If ``mode`` is ``'single'`` then the Hub
        runs using the standard ``.samp`` lock-file, having a single instance
        for user desktop session. Otherwise, if ``mode`` is ``'multiple'``,
        then the Hub runs using a non-standard lock-file, placed in
        ``.samp-1`` directory, of the form ``samp-hub-<UUID>``, where
        ``<UUID>`` is a unique UUID assigned to the hub.

    label : str, optional
        A string used to label the Hub with a human readable name. This string
        is written in the lock-file assigned to the ``hub.label`` token.

    web_profile : bool, optional
        Enables or disables the Web Profile support.

    web_profile_dialog : class, optional
        Allows a class instance to be specified using ``web_profile_dialog``
        to replace the terminal-based message with e.g. a GUI pop-up. Two
        `queue.Queue` instances will be added to the instance as attributes
        ``queue_request`` and ``queue_result``. When a request is received via
        the ``queue_request`` queue, the pop-up should be displayed, and a
        value of `True` or `False` should be added to ``queue_result``
        depending on whether the user accepted or refused the connection.

    web_port : int, optional
        The port to use for web SAMP. This should not be changed except for
        testing purposes, since web SAMP should always use port 21012.

    pool_size : int, optional
        The number of socket connections opened to communicate with the
        clients.
    Nr   single TR     c                 j   t          t          j                              | _        d| _        || _        d | _        || _        || _        || _	        || _
        || _        || _        || _        |	| _        |
| _        || _        d | _        i | _        d | _        d | _        d | _        d| _        t/                      rY	 t1          j                    | _        t1          j        | j        p| j        | j        pd           n# t6          $ r
 d| _        Y nw xY wt9          j                    | _        d | _        d | _         d | _!        g | _"        d | _#        i | _$        d| _%        || _&        | '                                | _(        d| _)        i | _*        i | _+        i | _,        i | _-        i | _.        i | _/        d| _0        d S )NF	127.0.0.1r   r   )1struuiduuid1_id_is_running_customlockfilename	_lockfile_addr_port_mode_label_timeout_client_timeout
_pool_size_web_profile_web_profile_dialog	_web_port_web_profile_server_web_profile_callbacks_web_profile_requests_queue_web_profile_requests_result_web_profile_requests_semaphore
_host_namer   socketgetfqdngetaddrinfoOSError	threadingLock_thread_lock_thread_run_thread_hub_timeout_thread_client_timeout_launched_threads_last_activity_time_client_activity_time_hub_msg_id_counter_hub_secret_code_customized_create_secret_code_hub_secret_hub_public_id_private_keys	_metadata
_mtype2ids
_id2mtypes_xmlrpc_endpoints_sync_msg_ids_heap_client_id_counter)selfsecretaddrportlockfiletimeoutclient_timeoutmodelabelweb_profileweb_profile_dialogweb_port	pool_sizes                0lib/python3.11/site-packages/astropy/samp/hub.py__init__zSAMPHubServer.__init___   s     tz||$$ !#+ 


-# (#5 !#' &(#+/(,0)/3,%== 	.."(."2"2"4:#@$*/PQRRRR . . ."-. &N,,#' &*#!# $( %'" $%  ,2(3355 !      "$ #% #%s   :A C; ;DDc                     | j         S )z$
        The unique hub ID.
        )r!   rN   s    r[   idzSAMPHubServer.id   s    
 x    c                 f   |                     | j        d           |                     | j        d           |                     | j        d           |                     | j        d           |                     | j        d           |                     | j        d           |                     | j        d           |                     | j        d           |                     | j	        d	           |                     | j
        d
           |                     | j        d           |                     | j        d           |                     | j        d           |                     | j        d           |                     | j        d           |                     | j        d           d S )Nzsamp.hub.pingzsamp.hub.setXmlrpcCallbackzsamp.hub.registerzsamp.hub.unregisterzsamp.hub.declareMetadatazsamp.hub.getMetadatazsamp.hub.declareSubscriptionszsamp.hub.getSubscriptionszsamp.hub.getRegisteredClientszsamp.hub.getSubscribedClientszsamp.hub.notifyzsamp.hub.notifyAllzsamp.hub.callzsamp.hub.callAllzsamp.hub.callAndWaitzsamp.hub.reply)register_function_ping_set_xmlrpc_callback	_register_unregister_declare_metadata_get_metadata_declare_subscriptions_get_subscriptions_get_registered_clients_get_subscribed_clients_notify_notify_all_call	_call_all_call_and_wait_replyrN   servers     r[   _register_standard_apiz$SAMPHubServer._register_standard_api   s     _===  %'C	
 	
 	

 	  1DEEE  !13HIII  !79STTT  !35KLLL  ')H	
 	
 	
 	  !8:UVVV  (*I	
 	
 	
 	  (*I	
 	
 	
 	  /@AAA  !13GHHH  _===  1CDDD  !46LMMM  .>?????r`   c                    |                     | j        d           |                     | j        d           |                     | j        d           |                     | j        d           |                     | j        d           |                     | j        d           |                     | j        d           |                     | j        d           |                     | j	        d	           |                     | j
        d
           |                     | j        d           |                     | j        d           |                     | j        d           |                     | j        d           |                     | j        d           |                     | j        d           |                     | j        d           d S )Nzsamp.webhub.pingzsamp.webhub.unregisterzsamp.webhub.declareMetadatazsamp.webhub.getMetadataz samp.webhub.declareSubscriptionszsamp.webhub.getSubscriptionsz samp.webhub.getRegisteredClientsz samp.webhub.getSubscribedClientszsamp.webhub.notifyzsamp.webhub.notifyAllzsamp.webhub.callzsamp.webhub.callAllzsamp.webhub.callAndWaitzsamp.webhub.replyzsamp.webhub.registerz!samp.webhub.allowReverseCallbackszsamp.webhub.pullCallbacks)rb   rc   rf   rg   rh   ri   rj   rk   rl   rm   rn   ro   rp   rq   rr   _web_profile_register"_web_profile_allowReverseCallbacks_web_profile_pullCallbacksrs   s     r[   _register_web_profile_apiz'SAMPHubServer._register_web_profile_api   s     -?@@@  !13KLLL  !79VWWW  !35NOOO  ')K	
 	
 	
 	  #%C	
 	
 	
 	  (*L	
 	
 	
 	  (*L	
 	
 	
 	  /CDDD  !13JKKK  -?@@@  1FGGG  !46OPPP  .ABBB 	  !;=STTT  35X	
 	
 	
 	  +-H	
 	
 	
 	
 	
r`   c                    t          | j        p| j        | j        pdft          dd          | _        d}| j        j                                        d         | _        | j        p| j         d| j         }t          ||ddddf          | _	        | j        
                                 |                     | j                   d S )	Nr   FTlogRequests
allow_nonehttpr   :r   )r   r%   r4   r&   r   _serverr5   getsocknamer   _url register_introspection_functionsru   )rN   protrP   s      r[   _start_standard_serverz$SAMPHubServer._start_standard_server  s    ,Z*4?DJO!<	
 
 
 \(4466q9
*/>>$*>>dBB;<<	55777##DL11111r`   c                    t          j        d          | _        t          j        d          | _        t          j        d          | _        | j        "| j        | j        _        | j        | j        _        	 t          d| j	        ft          dd          | _        | j        j                                        d         | _	        | j                                         |                     | j                   t          j        d           d S # t"          $ rR t          j        d                    | j	                  t(                     d| _        d | _        d | _        d | _        Y d S w xY w)Nr   	localhostFTr|   z0Hub set to run with Web Profile support enabled.zKPort {} already in use. Impossible to run the Hub with Web Profile support.)queueQueuer1   r2   r3   r-   queue_requestqueue_resultr   r.   r   r/   r5   r   r   rz   infor8   warningformatr
   r,   r^   s    r[   _start_web_profile_serverz'SAMPHubServer._start_web_profile_server  sX   +0;q>>(,1KNN)/4{1~~,#/595UD$2484UD$1	8'=dn-sRV( ( (D$ "5<HHJJ1MDN$EEGGG**4+CDDDHGHHHHH 
	8 
	8 
	8K006t~0F0F  
 !&D/3D,04D-37D0000
	8s   6BD AE('E(c                 :   g }| j         D ]+}|                                s|                    |           ,|D ]}| j                             |           t	          j        ||||          }|                                 | j                             |           d S )N)grouptargetnameargs)r?   is_aliveappendremover9   Threadstart)rN   r   r   r   r   r   ts          r[   _launch_threadzSAMPHubServer._launch_thread3  s    ' 	! 	!A::<< !a    	- 	-A"))!,,,, 5dNNN				 	%%a(((((r`   c                 F    | j         D ]}|                    |           d S NrS   )r?   join)rN   rS   r   s      r[   _join_launched_threadsz$SAMPHubServer._join_launched_threadsC  s5    ' 	$ 	$AFF7F####	$ 	$r`   c                    | j         dk    rd S t          j                    }| j        rt          j        d           t          j                    }||z
  dk    rw| j        5  | j        O|| j        z
  | j         k    r<t          j        dt                     | 	                                 	 d d d            d S d d d            n# 1 swxY w Y   |}| j        d S d S )Nr   皙?      ?z&Timeout expired, Hub is shutting down!)
r)   timer"   sleepr;   r@   warningswarnr
   stop)rN   lastnows      r[   _timeout_test_hubzSAMPHubServer._timeout_test_hubG  sK   =AFy{{ 	Jt)++CTzC& # #/;!99T]JJ$M H+   !IIKKK"# # # # # # # # # # # # # # # # # # # # # # #   	 	 	 	 	s   A
CC	Cc                    | j         dk    rd S t          j                    }| j        rt          j        d           t          j                    }||z
  dk    r| j                                        D ]n}|| j        |         z
  | j         k    rS|| j        k    rHt          j        d| dt                     | 
                    |           |                     |           o|}| j        d S d S )Nr   r   r   zClient z timeout expired!)r*   r   r"   r   rA   keys_hub_private_keyr   r   r
   _notify_disconnectionrf   )rN   r   r   private_keys       r[   _timeout_test_clientz"SAMPHubServer._timeout_test_clientZ  s   1$$Fy{{ 	Jt)++CTzC#'#=#B#B#D#D 
6 
6Kd8EE./ /'4+@@@ DkDDDk   22;???((555  	 	 	 	 	r`   c                     |dk    r
 | j         | S |dk    r
 | j        | S |dk    r
 | j        | S |dk    r
 | j        | S d S )Nzsamp.client.receiveCallzsamp.client.receiveNotificationzsamp.client.receiveResponsesamp.app.ping)_receive_call_receive_notification_receive_responserc   )rN   methodr   s      r[   _hub_as_client_request_handlerz,SAMPHubServer._hub_as_client_request_handlerp  sx    ...%4%t,,888-4-t44444)4)400&&4:t$$ '&r`   c                 J   d| j         dd| j        dz   d}|                     | j                  }|d         | _        |d         | _        |                     | j        | j                   |                     | j        |           |                     | j        i i d           d S )	NzAstropy SAMP HubzThe Astropy Collaborationz'https://docs.astropy.org/en/stable/sampz
/samp/icon)	samp.namezsamp.description.textzauthor.namezsamp.documentation.urlzsamp.icon.urlsamp.self-idsamp.private-key)r   x-samp.query.by-meta)	r(   r   re   rE   rF   r   rd   rg   ri   )rN   hub_metadataresults      r[   _setup_hub_as_clientz"SAMPHubServer._setup_hub_as_clientz  s    +%)[6&O!Y5
 
  011$^4 &'9 :!!$"7CCCt4lCCC##!RQS#T#T	
 	
 	
 	
 	
r`   Fc                    | j         rt          d          | j        t          d          | j        r|                                  |                                  t          | j        | j        | j	        | j
                  | _        |                                  |                                  |                                  t          j        d           |r)| j         r$| j                                         d| _        dS dS dS )a<  
        Start the current SAMP Hub instance and create the lock file. Hub
        start-up can be blocking or non blocking depending on the ``wait``
        parameter.

        Parameters
        ----------
        wait : bool
            If `True` then the Hub process is joined with the caller, blocking
            the code flow. Usually `True` option is used to run a stand-alone
            Hub in an executable script. If `False` (default), then the Hub
            process runs in a separated thread. `False` is usually used in a
            Python shell.
        zHub is already runningNz&Hub is not running but lockfile is set)lockfilenamerU   hub_id
hub_paramszHub started)r"   r   r$   r,   r   r   r   r#   r'   r_   params_update_last_activity_timer   _start_threadsr   r   r<   r   )rN   waits     r[   r   zSAMPHubServer.start  s      	97888>%GHHH 	-**,,,##%%%)17{	
 
 
 	'')))!!### 	$D$ 	$!!####D	$ 	$ 	$ 	$r`   c                     i }| j         |d<   | j        |d<   t          |d<   | j        |d<   | j        p	d| j         |d<   |S )zH
        The hub parameters (which are written to the logfile).
        samp.secretzsamp.hub.xmlrpc.urlzsamp.profile.versionzhub.idzHub z	hub.label)rE   r   r   r_   r(   )rN   r   s     r[   r   zSAMPHubServer.params  s_    
  !% 0}(,	$%)<%&  7x"k=-=DG-=-={r`   c                    t          j        | j                  | _        d| j        _        | j        dk    r-t          j        | j        d          | _        d| j        _        nd | _        | j        dk    r-t          j        | j	        d          | _
        d| j
        _        nd | _
        d| _        | j                                         | j        | j                                         | j
        | j
                                         d S d S )N)r   Tr   zHub timeout test)r   r   zClient timeout test)r9   r   _serve_foreverr<   daemonr)   r   r=   r*   r   r>   r"   r   r^   s    r[   r   zSAMPHubServer._start_threads  s   $+43FGGG"&=1'0'7-4F( ( (D$ /3D$++'+D$!##*3*:07L+ + +D' 26D'..*.D'   #/$**,,,&2'--///// 32r`   c                 ^    | j         | j         S t          t          j                              S N)rC   r   r   r    r^   s    r[   rD   z!SAMPHubServer._create_secret_code  s(    +733tz||$$$r`   c                 L   | j         sdS t          j        d           |                                  d| _         | j        rbt
          j                            | j                  r>t          | j                  }|d         | j	        k    rt          j
        | j                   d| _        |                     d           d| _        |                                 | _	        d| _        i | _        i | _        i | _        i | _        i | _        d| _        t          j        d	           dS )
zN
        Stop the current SAMP Hub instance and delete the lock file.
        NzHub is stopping...Fr   g      $@r   r   r   zHub stopped.)r"   r   r   _notify_shutdownr$   ospathisfiler   rE   r   _join_all_threadsrB   rD   rF   rH   rG   rI   rJ   rK   r@   )rN   lockfiledicts     r[   r   zSAMPHubServer.stop  s     	F%&&& > 	*bgnnT^<< 	*(88LM*d.>>>	$.))) 	t,,,#$ 3355 !##'      r`   c                    t          j                    }| j        |ur;| j                            |           | j                                        sd | _        | j        D| j        |ur;| j                            |           | j                                        sd | _        | j        D| j        |ur;| j                            |           | j                                        sd | _        |                     |           d S r   )r9   current_threadr<   r   r   r=   r>   r   )rN   rS   r   s      r[   r   zSAMPHubServer._join_all_threads  s    #133>11!!'!222#,,.. (#' $0(>>$))'):::+4466 0+/('3+>AA',,W,===.7799 3.2+##G#44444r`   c                     | j         S )zReturn an information concerning the Hub running status.

        Returns
        -------
        running : bool
            Is the hub running?
        )r"   r^   s    r[   
is_runningzSAMPHubServer.is_running+  s     r`   c                 &   | j         rM	 t          j        | j        j        gg g d          d         }|r| j                                         n4# t
          $ r'}t          j        d| t                     Y d }~nd }~ww xY w| j	        r| j
        E	 | j                                        }t          || j                   n# t          j        $ r Y nw xY w	 t          j        | j        j        gg g d          d         }|r| j                                         n4# t
          $ r'}t          j        d| t                     Y d }~nd }~ww xY w| j         M| j                                         | j        | j                                         d S d S )N{Gz?r   z*Call to select() in SAMPHubServer failed: )r"   selectr   r5   handle_requestr8   r   r   r
   r,   r-   r1   
get_nowaitr   r2   r   Emptyr/   server_close)rN   
read_readyexcrequests       r[   r   zSAMPHubServer._serve_forever6  s%    $	B2#]DL,?+@"b$OOPQR
  2L//111    FFF          B +3"&"B"M"M"O"O 0#T%F    !;   
B!'1892r4" ""J " B0??AAA    MJSJJK       =  $	BL 	!!####/$1133333 0/sA   (A 
A?A::A?C   CC(D 
E$EEc           	          t                               d          }|D ]K}|| j        v r@| j        |         D ]2}|                     | j        | j        |         d         di d           3Ld S )Nzsamp.hub.event.shutdownr   
samp.mtypesamp.params)r   get_mtype_subtypesrI   _notify_r   rG   )rN   msubsmtypekeys       r[   r   zSAMPHubServer._notify_shutdowna  s    001JKK 	 	E''?51  CMM-*3/2'@QSTT   	 	r`   c           	          t                               d          }|D ]`}|| j        v rU| j        |         d         }| j        |         D ]4}|                     | j        | j        |         d         dd|id           5ad S )Nzsamp.hub.event.registerr   r_   r   r   r   rI   rG   rm   r   rN   r   r   r   	public_idr   s         r[   _notify_registerzSAMPHubServer._notify_registerl  s    001JKK 	 	E'' .{;A>	?51 	 	CLL-*3/2*C,0)+<    	 	r`   c           	         t                               d          }|D ]f}|| j        v r[| j        |         d         }| j        |         D ]:}||k    r2|                     | j        | j        |         d         dd|id           ;gd S )Nzsamp.hub.event.unregisterr   r_   r   r   r   s         r[   _notify_unregisterz SAMPHubServer._notify_unregister|  s    001LMM 	 	E'' .{;A>	?51 	 	Ck)) 1 .s3A6.I04i/@   	 	r`   c           
         t                               d          }|D ]l}|| j        v ra| j        |         d         }| j        |         D ]@}|                     | j        | j        |         d         d|| j        |         dd           Amd S )Nzsamp.hub.event.metadatar   )r_   metadatar   )r   r   rI   rG   rm   r   rH   r   s         r[   _notify_metadatazSAMPHubServer._notify_metadata  s    001JKK 	 	E'' .{;A>	?51  CLL-*3/2*C&/,0N;,G, , 
 
 
 
	 	r`   c           
         t                               d          }|D ]l}|| j        v ra| j        |         d         }| j        |         D ]@}|                     | j        | j        |         d         d|| j        |         dd           Amd S )Nzsamp.hub.event.subscriptionsr   )r_   subscriptionsr   )r   r   rI   rG   rm   r   rJ   r   s         r[   _notify_subscriptionsz#SAMPHubServer._notify_subscriptions  s    001OPP 	 	E'' .{;A>	?51  CLL-*3/2*H&/151M, , 
 
 
 
		 	r`   c           
      >   d }t                               d          }| j        |         d         }| j        |         d         }|D ]V}|| j        v rK|| j        |         v r<t          j        d|            |                     |||| j        dddidf	           Wd S )
Nc                 H    | j         j                            |||           d S r   )sampclientreceiveNotification)endpointr   hub_public_idmessages       r[   _xmlrpc_call_disconnectzDSAMPHubServer._notify_disconnection.<locals>._xmlrpc_call_disconnect  s0    M 44]G    r`   zsamp.hub.disconnectr   r   znotify disconnection to reasonTimeout expired!r   r   r   )	r   r   rG   rK   rI   r   debugr   rF   )rN   r   r  r   r   r  r   s          r[   r   z#SAMPHubServer._notify_disconnection  s    	 	 	
 001FGG&{3A6	))4Q7 	 	E''K4?5;Q,Q,Q	@Y@@AAA##2 #+*?,46H+I 	 $   	 	r`   c                 V    |                                   t          j        d           dS )Nping1)r   r   r  r^   s    r[   rc   zSAMPHubServer._ping  s)    '')))	&sr`   c                     g }| j         D ]N}|| j         |         v r=| j         |         |         |k    r&|                    | j        |         d                    O|S Nr   )rH   r   rG   )rN   r   valuepublic_id_list
private_ids        r[   _query_by_metadataz SAMPHubServer._query_by_metadata  sk    . 	M 	MJdnZ000>*-c2e;;"))$*<Z*H*KLLLr`   c                    |                      |           || j        v r|| j        k    r3| j        |         d         }|t          | j                  f| j        |<   dS t          j        d| d|            d }t          | j	        t          j        |d          }| j        |         d         }||f| j        |<   nt          dd| d	          dS )
Nr   r   zset_xmlrpc_callback:  r   )r~      Private-key  expired or invalid.)r   rG   r   r   r   rK   r   r  r   r+   xmlrpcServerProxyr	   )rN   r   xmlrpc_addrr   server_proxy_pools        r[   rd   z"SAMPHubServer._set_xmlrpc_callback  s   ''444$,,,d333 .{;A>	 !DEE5&y1 r IIkIIKIIJJJ $ /!3[Q! ! ! *;7:I1<>O0PD"9-- $T;$T$T$TUUUrr`   c                 F   | j         5  |                                 \  }}d d d            n# 1 swxY w Y   |t          j                    f| j        |<   |                     |           |                     |           t          j        d| d|            ||| j        dS )Nzregister: private-key = z and self-id = )r   r   zsamp.hub-id)	r;   _get_new_idsr   rG   r   r   r   r  rF   rN   r   r   s      r[   _perform_standard_registerz(SAMPHubServer._perform_standard_register  s     	9 	9%)%6%6%8%8"K	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9+4dikk*B;'''444k***	T[TTTTUUU% +.
 
 	
s   ,00c                     |                                   || j        k    r|                                 S t          dd          )N   zBad secret code)r   rE   r  r	   )rN   rO   s     r[   re   zSAMPHubServer._register  sG    '')))T%%%22444 !$5666r`   c                     t          t          j                              }| xj        dz  c_        d}| j        dk    r
d| j         }||fS )Nr   zcli#hubr   zcli#)r   r   r    rM   r  s      r[   r  zSAMPHubServer._get_new_ids
  sW    $*,,''1$	"Q&&8t688II%%r`   c                    |                                   d}|                     |           | j        5  || j        v r| j        |         d         }| j        |= n	 d d d            dS || j        v r| j        |= || j        v r| j        |= | j                                        D ]1}|| j        |         v r | j        |                             |           2|| j	        v r| j	        |= || j
        v r| j
        |= | j        r+|| j        v r| j        |= | j                            |           d d d            n# 1 swxY w Y   t          j        d| d| d           dS )Nr   r   zunregister z ())r   r   r;   rG   rH   rJ   rI   r   r   rK   rA   r,   r0   r/   remove_clientr   r  )rN   r   
public_keyr   s       r[   rf   zSAMPHubServer._unregister  s   '')))
,,, 	D 	Dd000!/<Q?
&{33	D 	D 	D 	D 	D 	D 	D 	D dn,,N;/do--OK0--// ? ?$/%"888OE*11+>>>T333*:6d888.{;  D$"===3K@(66{CCC5	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D8 		<
<<k<<<===rs   'D4'CD44D8;D8c                    |                      |           || j        v rUt          j        d                    |t          |                               || j        |<   |                     |           nt          dd| d          dS )Nz0declare_metadata: private-key = {} metadata = {}r  r  r  r   )	r   rG   r   r  r   r   rH   r   r	   )rN   r   r   s      r[   rg   zSAMPHubServer._declare_metadata:  s    ''444$,,,IBIIX   
 +3DN;'!!+.... $T;$T$T$TUUUrr`   c                 \   |                      |           || j        v r{|                     |          }t          j        d| d|            |:|| j        v r/t          j        d| j        |                     | j        |         S i S t          dd          t          dd| d          )	Nzget_metadata: private-key = z client-id = z--> metadata =    Invalid client IDr  r  r  )r   rG   _public_id_to_private_keyr   r  rH   r	   rN   r   	client_idclient_private_keys       r[   rh   zSAMPHubServer._get_metadataH  s    ''444$,,,!%!?!?	!J!JIT{TTTT   "-%77IT?Q0RTTUUU>*<==I$Q(;<<< $T;$T$T$TUUUr`   c                    |                      |           || j        v rt          j        d                    |t          |                               || j        v rC| j        |         }|D ]3}	 | j        |                             |           $# t          $ r Y 0w xY wt          j        |          | j        |<   t          j        |          }|D ]F}|                    d          r/|D ],}|                    |d d                   r||k    r||v r||= -Gt          j        d                    |t          |                               |D ]F}|| j        v r0|| j        |         vr | j        |                             |           ;|g| j        |<   G|                     |           nt!          dd| d          dS )	Nz3declare_subscriptions: private-key = {} mtypes = {}*r   z;declare_subscriptions: subscriptions accepted from {} => {}r  r  r  r   )r   rG   r   r  r   r   rJ   rI   r   
ValueErrorcopydeepcopyendswith
startswithr   r   r	   )rN   r   mtypesprev_mtypesr   original_mtypesmtype2s          r[   ri   z$SAMPHubServer._declare_subscriptionsZ  s!   ''444$,,,IELLV    do--"ok:(  E.55kBBBB%    ,0=+@+@DOK( #mF33O( 3 3>>#&& 3"1 3 3!,,U3B3Z88 3Vu__%//$*6NIMTTV      ; ;DO++"$/%*@@@.55kBBB.9]DOE**&&{3333 !$T;$T$T$TUUUrs   0 B
BBc           	         |                      |           || j        v r|                     |          }|p|| j        v rMt	          j        d                    |t          | j        |                                        | j        |         S t	          j        d| d           i S t          dd          t          dd| d          )	Nz-get_subscriptions: client-id = {} mtypes = {}zget_subscriptions: client-id = z mtypes = missingr(  r)  r  r  r  )	r   rG   r*  rJ   r   r  r   r   r	   r+  s       r[   rj   z SAMPHubServer._get_subscriptions  s    ''444$,,,!%!?!?	!J!J!-%88IGNN%s4?;M+N'O'O   
  ?+=>>IV)VVV   I$Q(;<<< $T;$T$T$TUUUr`   c                 N   |                      |           || j        v rtg }| j                                        D ].}||k    r&|                    | j        |         d                    /t	          j        d                    ||                     |S t          dd| d          )Nr   z5get_registered_clients: private_key = {} clients = {}r  r  r  )r   rG   r   r   r   r  r   r	   )rN   r   reg_clientspkeys       r[   rk   z%SAMPHubServer._get_registered_clients  s    ''444$,,,K*//11 D D;&&&&t'9$'?'BCCCIGNN   
  $T;$T$T$TUUUr`   c                 \   |                      |           || j        v r{i }| j                                        D ]4}||k    r,|                     ||          ri || j        |         d         <   5t	          j        d                    |||                     |S t          dd| d          )Nr   z@get_subscribed_clients: private_key = {} mtype = {} clients = {}r  r  r  )r   rG   r   _is_subscribedr   r  r   r	   )rN   r   r   sub_clientsr<  s        r[   rl   z%SAMPHubServer._get_subscribed_clients  s    ''444$,,,K*//11 B B;&&4+>+>tU+K+K&?AK 24 8 ;<I%vk5+FF    $T;$T$T$TUUUr`   c                 t   g }|                      d          }t          t          t          |                              }|                                 |                    d           |D ]K}d                    |d|dz                      }|| k    r|dk    r|dz   }nd}|                    |           L|S )a  
        Return a list containing all the possible wildcarded subtypes of MType.

        Parameters
        ----------
        mtype : str
            MType to be parsed.

        Returns
        -------
        types : list
            List of subtypes

        Examples
        --------
        >>> from astropy.samp import SAMPHubServer
        >>> SAMPHubServer.get_mtype_subtypes("samp.app.ping")
        ['samp.app.ping', 'samp.app.*', 'samp.*', '*']
        r   r   Nr   r   z.*r/  )splitlistrangelenreverser   r   )r   subtypesr   indexesi	tmp_mtypes         r[   r   z SAMPHubServer.get_mtype_subtypes  s    * C  uSZZ(())r 	' 	'AwQw00IE!!?? )D 0II #IOOI&&&&r`   c                 |    d}t                               |          }|D ]}|| j        v r|| j        |         v rd}|S )NFT)r   r   rI   )rN   r   r   
subscribedr   msubs         r[   r>  zSAMPHubServer._is_subscribed  sT    
0077 	& 	&Dt&&$/$"777!%Jr`   c                 Z   |                      |           || j        v rz|                     |                     |          |d                   s*t	          dd                    ||d                             |                     | j        |||f           i S t	          dd| d          )Nr      $Client {} not subscribed to MType {}r  r  r  r  )r   rG   r>  r*  r	   r   r   r   )rN   r   recipient_idr  s       r[   rm   zSAMPHubServer._notify  s    ''444$,,,##22<@@',BW 

 %:AA$gl&;    }Kw+O      I $T;$T$T$TUUUr`   c           	         || j         vrd S | j         |         d         }	 t          j        d                    |d         ||                     |                     |          }||f}d}|                     ||||           d S # t          $ rA}t          j        d                    |d         |||          t                     Y d }~d S d }~ww xY w)Nr   znotify {} from {} to {}r   r   z7{} notification from client {} to client {} failed [{}])
rG   r   r  r   r*  _retry_method	Exceptionr   r   r
   )	rN   sender_private_keyrecipient_public_idr  sender_public_idrecipient_private_key
arg_paramssamp_method_namer   s	            r[   r   zSAMPHubServer._notify_  s3   T%777F-.@A!D	I)00L)+;=P    %)$B$BCV$W$W!*G4J4%':<Lj      	 	 	MIPPL)+;=PRU  	        	s   A"B 
C6C

Cc                     |                      |           || j        v r,d|vrt          dd          |                     ||          }|S t          dd| d          )Nr      zsamp.mtype keyword is missingr  r  r  )r   rG   r	   _notify_all_)rN   r   r  recipient_idss       r[   rn   zSAMPHubServer._notify_all/  sw    ''444$,,,7**$Q(GHHH --k7CCM   $T;$T$T$TUUUr`   c                 X   g }t                               |d                   }|D ]h}|| j        v r]| j        |         D ]O}||k    rG| j        |         d         }|                    |           |                     | j        |||f           Pi|st          j        dt                     |S )Nr   r   r  z*No client was able to receive this message)
r   r   rI   rG   r   r   rm   r   r   r
   )rN   rT  r  r]  r   r   r   _recipient_ids           r[   r\  zSAMPHubServer._notify_all_:  s    001FGG 		 		E''?51  C000(,(:3(?(B%,,];;;++#'<"4mW!M ,     	M<  
 r`   c                    |                      |           || j        v r|                     |                     |          |d                   s*t	          dd                    ||d                             | j        |         d         }|                     ||          }|                     | j        |||||f           |S t	          dd| d          )	Nr   rN  rO  r   r  r  r  r  )	r   rG   r>  r*  r	   r   _get_new_hub_msg_idr   _call_)rN   r   rP  msg_tagr  r   msg_ids          r[   ro   zSAMPHubServer._callP  s   ''444$,,,##22<@@',BW 

 %:AA$gl&;    *;7:I--iAAF{!9lFGL      M $T;$T$T$TUUUr`   c                    || j         vrd S 	 t          j        d                    |                    d          d         |||d                              |                     |          }|||f}d}|                     ||||           d S # t          $ ri}	t          j	        d                    |d         |                    d          d         ||t          |	          |	          t                     Y d }	~	d S d }	~	ww xY w)Nzcall {} from {} to {} ({});;r   r   receiveCallz5{} call {} from client {} to client {} failed [{},{}])rG   r   r  r   rA  r*  rR  rS  r   r   typer
   )
rN   rT  rV  rU  rd  r  rW  rX  samp_methodNamer   s
             r[   rb  zSAMPHubServer._call_i  sR    T%777F	I,33LL&&q)$'L)	    %)$B$BCV$W$W!*FG<J+O%':OZ      	 	 	MGNNL)LL&&q)$'II  
 
 
 
 
 
 
 
 
	s   A=B 
C?AC::C?c                     |                      |           || j        v rDd|vrt          dd|           | j        |         d         }|                     ||||          }|S t          dd| d          )Nr   r[  z3samp.mtype keyword is missing in message tagged as r   r  r  r  )r   rG   r	   
_call_all_)rN   r   rc  r  r   rd  s         r[   rp   zSAMPHubServer._call_all  s    ''444$,,,7**$S'SS  
 *;7:I__[)WgNNFM $T;$T$T$TUUUr`   c           
      0   i }t                               |d                   }|D ]p}|| j        v re| j        |         D ]W}||k    rO|                     ||          }	| j        |         d         }
|	||
<   |                     | j        |||
|	|f           Xq|S )Nr   r   r  )r   r   rI   ra  rG   r   rb  )rN   rT  rV  rc  r  rd  r   r   r   _msg_idreceiver_public_ids              r[   rk  zSAMPHubServer._call_all_  s    001FGG 	 	E''?51  C000"&":":;KW"U"U-1-?-DQ-G*5<12++#'; 2 0 2 ' '" , 	 	 	 r`   c                    |                      |           || j        v rt          |          }t          j                    }i }|                     ||d|          }d | j        |<   | j        rd|cxk     rt          j                    |z
  k    rn n| j        |= t          dd          | j        |         (t          j	        | j        |                   }| j        |= nt          j
        d           | j        |S t          dd| d          )	Nsamp::sync::callr   r   r  r   r  r  r  )r   rG   intr   ro   rL   r"   r	   r1  r2  r   )rN   r   rP  r  rS   r   responserd  s           r[   rq   zSAMPHubServer._call_and_wait  s+   ''444$,,,'llG)++CHZZ\;MwWWF.2D#F+" 	!w3333$)++"333333/7(,>???*62>#}T-DV-LMMH/7
4    " 	! O $T;$T$T$TUUUr`   c                     |                      |           || j        v r |                     | j        |||f           nt	          dd| d          i S )z
        The main method that gets called for replying. This starts up an
        asynchronous reply thread and returns.
        r  r  r  r  )r   rG   r   _reply_r	   )rN   r   rd  rr  s       r[   rr   zSAMPHubServer._reply  sy    
 	''444$,,,|;*I       !$T;$T$T$TUUU	r`   c           	         || j         vs|sd S | j         |         d         }|                    dd          \  }}}}	 t          j        d| d| d|            |dk    r)|| j                                        v r|| j        |<   d S d S |                     |          }	|||f}
d}|                     |	|||
           d S # t          $ r;}t          j
        d	                    ||||          t                     Y d }~d S d }~ww xY w)
Nr   rf  r[  zreply z from z to rp  receiveResponsez0{} reply from client {} to client {} failed [{}])rG   rA  r   r  rL   r   r*  rR  rS  r   r   r   r
   )rN   responder_private_keyrd  rr  responder_public_idcounterr  rU  recipient_msg_tagrW  rX  rY  r   s                r[   rt  zSAMPHubServer._reply_  s    (:::&:F"01FGJIO!J
 J
F 35F	IVVV(;VVATVV   !$666T499;;;;6>D+F333 <; )-(F(F') )% 23DhO
#4 "")'$	      	 	 	MBII%':<OQT  	        	s   AB? 	4B? ?
D	0C??Dc           	         |t          d          ddlm} t          |j                  D ]}| j        st          j        d           	 | j        r/|| j	        v r&||d}| j	        |         
                    |           n4| j        |         d         } t          |j        j        |          |g|R    dS # t          j        $ rO}	t#          j        d                    ||dz   |	j                             t          j        d           Y d}	~	d}	~	ww xY w|dz   t+          |j                  z   d	z   }
t          |
          )
a  
        This method is used to retry a SAMP call several times.

        Parameters
        ----------
        recipient_private_key
            The private key of the receiver of the call
        recipient_public_key
            The public key of the receiver of the call
        samp_method_name : str
            The name of the SAMP method to call
        arg_params : tuple
            Any additional arguments to be passed to the SAMP method
        Nr)  r   )confr   )zsamp.methodNamer   z*{} XML-RPC endpoint error (attempt {}): {}z failed after z	 attempts)r   r   r|  rC  	n_retriesr"   r   r   r,   r0   putrK   getattrr   r   r  Faultr   r  r   faultStringr   )rN   rW  rU  rY  rX  r|  attemptcallbackhubr   error_messages              r[   rR  zSAMPHubServer._retry_method  s   " !(2333T^,,  	  	G# 
4   %-1LLL ,<'1   H /0EFJJ8TTTT 01DEaHC>GCHO-=>>-0:     < ! ! !	@GG+Wq[#/   
 
4        ! //#dn2E2EES 	 =)))s   A*B88DADDc                 t    | j                                         D ]}| j         |         d         |k    r|c S d S r  )rG   r   )rN   r   r   s      r[   r*  z'SAMPHubServer._public_id_to_private_keyE  sN    -2244 	# 	#K!+.q1Y>>"""" ?tr`   c                     | j         5  | xj        dz  c_        d d d            n# 1 swxY w Y   d                    | j        | j        ||          S )Nr   zmsg#{};;{};;{};;{})r;   rB   r   rF   )rN   rV  sender_msg_ids      r[   ra  z!SAMPHubServer._get_new_hub_msg_idK  s     	* 	*$$)$$	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	*#**$	
 
 	
s   %))c                     | j         5  t          j                    | _        |t          j                    | j        |<   d d d            d S # 1 swxY w Y   d S r   )r;   r   r@   rA   )rN   r   s     r[   r   z(SAMPHubServer._update_last_activity_timeU  s     	F 	F'+y{{D$&:>)++*;7	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	Fs   6AAAc                     dS Nr    )rN   r   	sender_idr  s       r[   r   z#SAMPHubServer._receive_notification[      rr`   c                 j   || j         k    rd|v r1|d         dk    r%|                     | j         |t          i d           npd|v rl|d         dk    s|d         dk    rT|                     |d         d         |d         d                   }|                     | j         |t          d	|id           d
S d
S )Nr   r   )zsamp.statuszsamp.resultr   zsamp.query.by-metar   r   r  idsr   )r   rr   r   r  )rN   r   r  rd  r  ids_lists         r[   r   zSAMPHubServer._receive_call^  s    $///w&&7<+@O+S+S)$22FF    ((%)???<(,@@@22M*517=3I'3R  )$2E8CTUU   22r`   c                     dS r  r  )rN   r   responder_idrc  rr  s        r[   r   zSAMPHubServer._receive_responsex  r  r`   unknownr   r  c                 f   |                                   |d         dvrt          dd          |sd}t          |t                    rd|vrt          dd          | j                            d           | j                            |||f           | j                                        }| j                                         |r\| 	                                }d	
                    | j        |d
                   }||d<   | j                            |d
                    |S t          dd          )Nr   )r   r   i  z,Request of registration rejected by the Hub.r  r   zLRequest of registration rejected by the Hub (application name not provided).r   z&http://localhost:{}/translator/{}?ref=r   zsamp.url-translatorz-Request of registration rejected by the user.)r   r	   
isinstancedictr3   r~  r1   r2   getr  r   r.   r/   
add_client)rN   identity_infoclient_addressoriginrr  register_maptranslator_urls          r[   rw   z#SAMPHubServer._web_profile_register{  sZ    	'')))!$>>> &TUUU 	FmT** 	-//$!   	,00888(,,m^V-TUUU488::,00222 		W::<<LELL-? @ N 3AL./$//=O0PQQQ &UVVVr`   c                     |                                   || j        v r4|dk    r|| j        v r| j        |= n0t          j                    | j        |<   nt          dd| d          dS )N0r  r  r  r   )r   rG   r0   r   r   r	   )rN   r   allows      r[   rx   z0SAMPHubServer._web_profile_allowReverseCallbacks  s|    '')))$,,,||$"===3K@;@;==+K88 $T;$T$T$TUUUrr`   c                 "   |                                   || j        v r_g }| j        |         }	 | j        r0|                                }|                    |           | j        0n# t          j        $ r Y nw xY w|S t          dd| d          )Nr  r  r  )	r   rG   r0   r"   r   r   r   r   r	   )rN   r   timeout_secsr  callback_queueitem_queueds         r[   ry   z(SAMPHubServer._web_profile_pullCallbacks  s    '')))$,,,H!8EN& 1"0";";"="=KOOK000 & 1 ;   O $T;$T$T$TUUUs   7A& &A87A8)NNr   Nr   r   r   r   TNr   r   )NNNNr   )F)r  r  )D__name__
__module____qualname____doc__r\   propertyr_   ru   rz   r   r   r   r   r   r   r   r   r   r   r   rD   r   r   r   r   r   r   r   r   r   r   rc   r  rd   r  re   r  rf   rg   rh   ri   rj   rk   rl   staticmethodr   r>  rm   r   rn   r\  ro   rb  rp   rk  rq   rr   rt  rR  r*  ra  r   r   r   r   rw   rx   ry   r  r`   r[   r   r      s|       > >D _% _% _% _%B   X@ @ @: 
  
  
D2 2 28 8 8<) ) ) ) $ $ $ $  &  ,% % %
 
 
$*$ *$ *$ *$X   X&0 0 08% % %!! !! !!F5 5 5 54     X )4 )4 )4V	 	 	        &  $  4  
    8
 
 
7 7 7& & &% % %N  V V V$2 2 2hV V V.V V V"V V V$ $ $ \$L
 
 
V V V.  :	V 	V 	V  ,V V V2# # #JV V V   .V V V6  & & &P<* <* <*|  
 
 
F F F F    4   DM'W 'W 'W 'WR
 
 
V V V V Vr`   c                   $    e Zd ZdZd Zd Zd ZdS )r   aU  
    A base class to make writing Web Profile GUI consent dialogs
    easier.

    The concrete class must:

        1) Poll ``handle_queue`` periodically, using the timer services
           of the GUI's event loop.  This function will call
           ``self.show_dialog`` when a request requires authorization.
           ``self.show_dialog`` will be given the arguments:

              - ``samp_name``: The name of the application making the request.

              - ``details``: A dictionary of details about the client
                making the request.

              - ``client``: A hostname, port pair containing the client
                address.

              - ``origin``: A string containing the origin of the
                request.

        2) Call ``consent`` or ``reject`` based on the user's response to
           the dialog.
    c                 6   	 | j                                         }t          |d         t                    r	|d         }n|d         d         }|                     ||d         |d         |d                    d S # t
          j        $ r Y d S t          $ r Y d S w xY w)Nr   r   r   rN  )r   r   r  r   show_dialogr   r   AttributeError)rN   r   	samp_names      r[   handle_queuezWebProfileDialog.handle_queue  s    	L(3355G '!*c** 4#AJ		#AJ{3	Y
GAJ
KKKKK { 	 	 	DD 	 	 	DD	s   A9 9B	BBc                 :    | j                             d           d S )NTr   r~  r^   s    r[   consentzWebProfileDialog.consent  s    d#####r`   c                 :    | j                             d           d S )NFr  r^   s    r[   rejectzWebProfileDialog.reject  s    e$$$$$r`   N)r  r  r  r  r  r  r  r  r`   r[   r   r     sN         4L L L$ $ $% % % % %r`   )'r1  r   r   r   r5   r9   r   r   r   xmlrpc.clientr   r  urllib.parser   astropyr   	constantsr   r   errorsr   r	   r
   lockfile_helpersr   r   standard_profiler   utilsr   r   r   rW   r   r   __all____doctest_skip__r   r   r  r`   r[   <module>r     s    				                 # # # # # #       : : : : : : : : = = = = = = = = = = = = = = = = = = 3 3 3 3 3 3 = = = = = = = = = = H H H H H H H H.
/*+ _V _V _V _V _V _V _V _VD-.% .% .% .% .% .% .% .% .% .%r`   