
[c           @` s  d  d l  m Z m Z m Z 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 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 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( d d g Z) d d g Z* d e+ f d     YZ, d e+ f d     YZ- d S(   i    (   t   absolute_importt   divisiont   print_functiont   unicode_literalsNi   (   t   queuet   range(   t   xmlrpc_client(   t
   urlunparse(   t   logi   (   t   SAMP_STATUS_OK(   t   __profile_version__(   t   SAMPWarningt   SAMPHubErrort   SAMPProxyError(   t   internet_ont   ServerProxyPoolt   _HubAsClient(   t   read_lockfilet   create_lock_file(   t   ThreadingXMLRPCServer(   t   WebProfileXMLRPCServert   web_profile_text_dialogu   SAMPHubServeru   WebProfileDialogu   .u   SAMPHubServer.*t   SAMPHubServerc           B` s  e  Z d  Z dE dE d dE d d d d e dE d d d  Z e d    Z d   Z d	   Z	 d
   Z
 d   Z dE dE dE dE d  Z dE d  Z d   Z d   Z d   Z d   Z e d  Z e d    Z d   Z d   Z d   Z dE d  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, d,   Z- e. d-    Z/ d.   Z0 d/   Z1 d0   Z2 d1   Z3 d2   Z4 d3   Z5 d4   Z6 d5   Z7 d6   Z8 d7   Z9 d8   Z: d9   Z; d:   Z< d;   Z= d<   Z> dE d=  Z? d>   Z@ d?   ZA d@   ZB dF dA dB  ZC dC   ZD dD   ZE RS(G   u
  
    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.
    i    u   singleu    iR  i   c         C` s  t  t j    |  _ t |  _ | |  _ d  |  _ | |  _	 | |  _
 | |  _ | |  _ | |  _ | |  _ | |  _ |	 |  _ |
 |  _ | |  _ d  |  _ i  |  _ d  |  _ d  |  _ d  |  _ d |  _ t   r$y8 t j   |  _ t j |  j	 p |  j |  j
 p d  Wq$t j k
 r d |  _ q$Xn  t j   |  _  d  |  _! d  |  _" d  |  _# g  |  _$ d  |  _% i  |  _& d |  _' | |  _( |  j)   |  _* d |  _+ i  |  _, i  |  _- i  |  _. i  |  _/ i  |  _0 i  |  _1 d |  _2 d  S(   Nu	   127.0.0.1i    u    i(3   t   strt   uuidt   uuid1t   _idt   Falset   _is_runningt   _customlockfilenamet   Nonet	   _lockfilet   _addrt   _portt   _modet   _labelt   _timeoutt   _client_timeoutt
   _pool_sizet   _web_profilet   _web_profile_dialogt	   _web_portt   _web_profile_servert   _web_profile_callbackst   _web_profile_requests_queuet   _web_profile_requests_resultt   _web_profile_requests_semaphoret
   _host_nameR   t   sockett   getfqdnt   getaddrinfot   errort	   threadingt   Lockt   _thread_lockt   _thread_runt   _thread_hub_timeoutt   _thread_client_timeoutt   _launched_threadst   _last_activity_timet   _client_activity_timet   _hub_msg_id_countert   _hub_secret_code_customizedt   _create_secret_codet   _hub_secrett   _hub_public_idt   _private_keyst	   _metadatat
   _mtype2idst
   _id2mtypest   _xmlrpc_endpointst   _sync_msg_ids_heapt   _client_id_counter(   t   selft   secrett   addrt   portt   lockfilet   timeoutt   client_timeoutt   modet   labelt   web_profilet   web_profile_dialogt   web_portt	   pool_size(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyt   __init__d   sZ    																																			c         C` s   |  j  S(   u$   
        The unique hub ID.
        (   R   (   RI   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyt   id   s    c         C` s4  | j  |  j d  | j  |  j d  | j  |  j d  | j  |  j d  | j  |  j d  | j  |  j d  | j  |  j d  | j  |  j d  | j  |  j	 d	  | j  |  j
 d
  | j  |  j d  | j  |  j d  | j  |  j d  | j  |  j d  | j  |  j d  | j  |  j d  d  S(   Nu   samp.hub.pingu   samp.hub.setXmlrpcCallbacku   samp.hub.registeru   samp.hub.unregisteru   samp.hub.declareMetadatau   samp.hub.getMetadatau   samp.hub.declareSubscriptionsu   samp.hub.getSubscriptionsu   samp.hub.getRegisteredClientsu   samp.hub.getSubscribedClientsu   samp.hub.notifyu   samp.hub.notifyAllu   samp.hub.callu   samp.hub.callAllu   samp.hub.callAndWaitu   samp.hub.reply(   t   register_functiont   _pingt   _set_xmlrpc_callbackt	   _registert   _unregistert   _declare_metadatat   _get_metadatat   _declare_subscriptionst   _get_subscriptionst   _get_registered_clientst   _get_subscribed_clientst   _notifyt   _notify_allt   _callt	   _call_allt   _call_and_waitt   _reply(   RI   t   server(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyt   _register_standard_api   s     c         C` sG  | j  |  j d  | j  |  j d  | j  |  j d  | j  |  j d  | j  |  j d  | j  |  j d  | j  |  j d  | j  |  j d  | j  |  j	 d	  | j  |  j
 d
  | j  |  j d  | j  |  j d  | j  |  j d  | j  |  j d  | j  |  j d  | j  |  j d  | j  |  j d  d  S(   Nu   samp.webhub.pingu   samp.webhub.unregisteru   samp.webhub.declareMetadatau   samp.webhub.getMetadatau    samp.webhub.declareSubscriptionsu   samp.webhub.getSubscriptionsu    samp.webhub.getRegisteredClientsu    samp.webhub.getSubscribedClientsu   samp.webhub.notifyu   samp.webhub.notifyAllu   samp.webhub.callu   samp.webhub.callAllu   samp.webhub.callAndWaitu   samp.webhub.replyu   samp.webhub.registeru!   samp.webhub.allowReverseCallbacksu   samp.webhub.pullCallbacks(   RX   RY   R\   R]   R^   R_   R`   Ra   Rb   Rc   Rd   Re   Rf   Rg   Rh   t   _web_profile_registert"   _web_profile_allowReverseCallbackst   _web_profile_pullCallbacks(   RI   Ri   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyt   _register_web_profile_api   s"    c         C` s   t  |  j p |  j |  j p d f t d t d t |  _ d } |  j j j	   d |  _ d j
 |  j pm |  j |  j  } t | | d d d d f  |  _ |  j j   |  j |  j  d  S(   Ni    t   logRequestst
   allow_noneu   httpi   u   {0}:{1}u    (   R   R    R/   R!   R   R   t   Truet   _serverR0   t   getsocknamet   formatR   t   _urlt    register_introspection_functionsRj   (   RI   t   protRK   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyt   _start_standard_server   s    !!c         C` s/  t  j d  |  _ t  j d  |  _ t  j d  |  _ |  j d  k	 rf |  j |  j _ |  j |  j _ n  yn t	 d |  j
 f t d t d t |  _ |  j j j   d |  _
 |  j j   |  j |  j  t j d  WnT t j k
 r*t j d j |  j
  t  t |  _ d  |  _ d  |  _ d  |  _ n Xd  S(   Ni   u	   localhostRo   Rp   u0   Hub set to run with Web Profile support enabled.uL   Port {0} already in use. Impossible to run the Hub with Web Profile support.(   R   t   QueueR,   R-   R.   R(   R   t   queue_requestt   queue_resultR   R)   R   R   Rq   R*   R0   Rs   Rv   Rn   t   infoR3   t   warningRt   R   R'   (   RI   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyt   _start_web_profile_server   s,    				c      	   C` s   g  } x- |  j  D]" } | j   s | j |  q q Wx | D] } |  j  j |  q= Wt j d | d | d | d |  } | j   |  j  j |  d  S(   Nt   groupt   targett   namet   args(   R:   t   is_alivet   appendt   removeR4   t   Threadt   start(   RI   R   R   R   R   R   t   t(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyt   _launch_thread  s    $
c         C` s(   x! |  j  D] } | j d |  q
 Wd  S(   NRN   (   R:   t   join(   RI   RN   R   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyt   _join_launched_threads*  s    c         C` s   |  j  d k r d  St j   } x |  j r t j d  t j   } | | d k r" |  j K |  j d  k	 r | |  j |  j  k r t j d t	  |  j
   d  Sn  Wd  QX| } q" q" Wd  S(   Ni    g?g      ?u&   Timeout expired, Hub is shutting down!(   R$   t   timeR   t   sleepR6   R;   R   t   warningst   warnR   t   stop(   RI   t   lastt   now(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyt   _timeout_test_hub.  s    
	
c         C` s   |  j  d k r d  St j   } x |  j r t j d  t j   } | | d k r" xv |  j j   D]e } | |  j | |  j  k rd | |  j k rd t j d j	 |  t
  |  j |  |  j |  qd qd W| } q" q" Wd  S(   Ni    g?g      ?u   Client {} timeout expired!(   R%   R   R   R   R<   t   keyst   _hub_private_keyR   R   Rt   R   t   _notify_disconnectionR\   (   RI   R   R   t   private_key(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyt   _timeout_test_clientA  s     c         C` sh   | d k r |  j  |   S| d k r2 |  j |   S| d k rK |  j |   S| d k rd |  j |   Sd  S(   Nu   samp.client.receiveCallu   samp.client.receiveNotificationu   samp.client.receiveResponseu   samp.app.ping(   t   _receive_callt   _receive_notificationt   _receive_responseRY   (   RI   t   methodR   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyt   _hub_as_client_request_handlerU  s    c         C` s   i d d 6|  j  d 6d d 6d d 6|  j d d	 6} |  j |  j  } | d
 |  _ | d |  _ |  j |  j |  j  |  j |  j |  |  j |  j i i  d 6i  d 6 d  S(   Nu   Astropy SAMP Hubu	   samp.nameu   samp.description.textu   The Astropy Collaborationu   author.nameu)   http://docs.astropy.org/en/stable/vo/sampu   samp.documentation.urlu
   /samp/iconu   samp.icon.urlu   samp.self-idu   samp.private-keyu   samp.app.pingu   x-samp.query.by-meta(	   R#   Ru   R[   R@   RA   R   RZ   R]   R_   (   RI   t   hub_metadatat   result(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyt   _setup_hub_as_client_  s    


c      	   C` s   |  j  r t d   n  |  j d k	 r6 t d   n  |  j rL |  j   n  |  j   t d |  j d |  j	 d |  j
 d |  j  |  _ |  j   |  j   |  j   t j d  | r |  j  r |  j j   d |  _ n  d S(	   u<  
        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.
        u   Hub is already runningu&   Hub is not running but lockfile is sett   lockfilenameRP   t   hub_idt
   hub_paramsu   Hub startedN(   R   R   R   R   R'   R~   Rx   R   R   R"   RW   t   paramst   _update_last_activity_timeR   t   _start_threadsR   R|   R7   R   (   RI   t   wait(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR   p  s"    		



c         C` sZ   i  } |  j  | d <|  j | d <t | d <|  j | d <|  j pO d j |  j  | d <| S(   uG   
        The hub parameters (which are written to the logfile)
        u   samp.secretu   samp.hub.xmlrpc.urlu   samp.profile.versionu   hub.idu   Hub {0}u	   hub.label(   R@   Ru   R
   RW   R#   Rt   (   RI   R   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR     s    
c         C` s  t  j d |  j  |  _ t |  j _ |  j d k r` t  j d |  j d d  |  _ t |  j _ n	 d  |  _ |  j
 d k r t  j d |  j d d  |  _ t |  j _ n	 d  |  _ t |  _ |  j j   |  j d  k	 r |  j j   n  |  j d  k	 r|  j j   n  d  S(   NR   i    R   u   Hub timeout testu   Client timeout test(   R4   R   t   _serve_foreverR7   Rq   t   daemonR$   R   R8   R   R%   R   R9   R   R   (   RI   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR     s(    							c         C` s*   |  j  d  k	 r |  j  St t j    Sd  S(   N(   R>   R   R   R   R   (   RI   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR?     s    c         C` s  |  j  s d St j d  |  j   t |  _  |  j r t j j |  j  r t	 |  j  } | d |  j
 k r t j |  j  q n  d |  _ |  j d d  d |  _ |  j   |  _
 d |  _ i  |  _ i  |  _ i  |  _ i  |  _ i  |  _ d |  _ t j d  d S(	   uN   
        Stop the current SAMP Hub instance and delete the lock file.
        Nu   Hub is stopping...u   samp.secretRN   g      $@i    u    u   Hub stopped.(   R   R   R|   t   _notify_shutdownR   R   t   ost   patht   isfileR   R@   R   R   t   _join_all_threadsR=   R?   RA   RC   RB   RD   RE   RF   R;   (   RI   t   lockfiledict(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR     s*    	
										c         C` s   t  j   } |  j | k	 rL |  j j d |  |  j j   sL d  |  _ qL n  |  j d  k	 r |  j | k	 r |  j j d |  |  j j   s d  |  _ q n  |  j d  k	 r |  j | k	 r |  j j d |  |  j j   s d  |  _ q n  |  j d |  d  S(   NRN   (	   R4   t   current_threadR7   R   R   R   R8   R9   R   (   RI   RN   R   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR     s    c         C` s   |  j  S(   u   Return an information concerning the Hub running status.

        Returns
        -------
        running : bool
            Is the hub running?
        (   R   (   RI   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyt
   is_running	  s    	c         C` sz  xG|  j  rIy) t j |  j j g g  g  d  d } Wn/ t j k
 rf } t j d j |  t  n X| r} |  j j	   n  |  j
 r |  j d  k r y |  j j   } Wn t j k
 r q Xt | |  j  n  y) t j |  j j g g  g  d  d } Wn/ t j k
 r,} t j d j |  t  qFX| rF|  j j	   qFq q W|  j j   |  j d  k	 rv|  j j   n  d  S(   Ng{Gz?i    u-   Call to select() in SAMPHubServer failed: {0}(   R   t   selectRr   R0   R3   R   R   Rt   R   t   handle_requestR'   R(   R   R,   t
   get_nowaitR   t   EmptyR   R-   R*   t   server_close(   RI   t
   read_readyt   exct   request(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR     s2    )	)c         C` s}   t  j d  } xg | D]_ } | |  j k r xG |  j | D]5 } |  j |  j |  j | d i d d 6i  d 6 q9 Wq q Wd  S(   Nu   samp.hub.event.shutdowni    u
   samp.mtypeu   samp.params(   R   t   get_mtype_subtypesRD   t   _notify_R   RB   (   RI   t   msubst   mtypet   key(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR   <  s    
c      	   C` s   t  j d  } x | D]w } | |  j k r |  j | d } xN |  j | D]< } |  j |  j |  j | d i d d 6i | d 6d 6 qJ Wq q Wd  S(   Nu   samp.hub.event.registeri    u
   samp.mtypeu   idu   samp.params(   R   R   RD   RB   Rc   R   (   RI   R   R   R   t	   public_idR   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyt   _notify_registerF  s    
c      	   C` s   t  j d  } x | D] } | |  j k r |  j | d } x] |  j | D]K } | | k rJ |  j |  j |  j | d i d d 6i | d 6d 6 qJ qJ Wq q Wd  S(   Nu   samp.hub.event.unregisteri    u
   samp.mtypeu   idu   samp.params(   R   R   RD   RB   Rc   R   (   RI   R   R   R   R   R   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyt   _notify_unregisterR  s    
c      	   C` s   t  j d  } x | D] } | |  j k r |  j | d } x\ |  j | D]J } |  j |  j |  j | d i d d 6i | d 6|  j | d 6d 6 qJ Wq q Wd  S(   Nu   samp.hub.event.metadatai    u
   samp.mtypeu   idu   metadatau   samp.params(   R   R   RD   RB   Rc   R   RC   (   RI   R   R   R   R   R   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyt   _notify_metadata^  s    

c      	   C` s   t  j d  } x | D] } | |  j k r |  j | d } x\ |  j | D]J } |  j |  j |  j | d i d d 6i | d 6|  j | d 6d 6 qJ Wq q Wd  S(   Nu   samp.hub.event.subscriptionsi    u
   samp.mtypeu   idu   subscriptionsu   samp.params(   R   R   RD   RB   Rc   R   RE   (   RI   R   R   R   R   R   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyt   _notify_subscriptionsl  s    

c         C` s   d   } t  j d  } |  j | d } |  j | d } x | D]{ } | |  j k rA | |  j | k rA t j d j |   |  j d | d | | |  j	 i d d 6i d	 d
 6d 6f  qA qA Wd  S(   Nc         S` s   |  j  j j | | |  d  S(   N(   t   sampt   clientt   receiveNotification(   t   endpointR   t   hub_public_idt   message(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyt   _xmlrpc_call_disconnect{  s    u   samp.hub.disconnecti    i   u   notify disconnection to {}R   R   u
   samp.mtypeu   Timeout expired!u   reasonu   samp.params(
   R   R   RB   RF   RD   R   t   debugRt   R   RA   (   RI   R   R   R   R   R   R   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR   y  s    	"
c         C` s   |  j    t j d  d S(   Nu   pingu   1(   R   R   R   (   RI   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyRY     s    
c         C` sf   g  } xY |  j  D]N } | |  j  | k r |  j  | | | k r^ | j |  j | d  q^ q q W| S(   Ni    (   RC   R   RB   (   RI   R   t   valuet   public_id_listt
   private_id(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyt   _query_by_metadata  s    "c         C` s   |  j  |  | |  j k r | |  j k r\ |  j | d } | t |  j  f |  j | <d St j d j | |   d  } t
 |  j t j | d d } |  j | d } | | f |  j | <n t d d j |    d S(   Ni    u    u   set_xmlrpc_callback: {} {}Rp   i   i   u"   Private-key {} expired or invalid.(   R   RB   R   R   R   RF   R   R   Rt   R   R   R&   t   xmlrpct   ServerProxyR   (   RI   R   t   xmlrpc_addrR   t   server_proxy_pool(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyRZ     s$    
	c         C` s   |  j   |  j   \ } } Wd  QX| t j   f |  j | <|  j |  |  j |  t j d j | |   i | d 6| d 6|  j	 d 6S(   Nu+   register: private-key = {} and self-id = {}u   samp.self-idu   samp.private-keyu   samp.hub-id(
   R6   t   _get_new_idsR   RB   R   R   R   R   Rt   RA   (   RI   R   R   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyt   _perform_standard_register  s    

c         C` s6   |  j    | |  j k r# |  j   St d d   d  S(   Ni   u   Bad secret code(   R   R@   R   R   (   RI   RJ   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR[     s    

c         C` sU   t  t j    } |  j d 7_ d } |  j d k rK d j |  j  } n  | | f S(   Ni   u   cli#hubi    u   cli#{}(   R   R   R   RH   Rt   (   RI   R   R   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR     s    c         C` sg  |  j    d } |  j |  |  j "| |  j k rT |  j | d } |  j | =n d S| |  j k rt |  j | =n  | |  j k r |  j | =n  xA |  j j   D]0 } | |  j | k r |  j | j |  q q W| |  j	 k r |  j	 | =n  | |  j
 k r|  j
 | =n  |  j rD| |  j k r1|  j | =n  |  j j |  n  Wd  QXt j d j | |   d S(   Nu    i    u   unregister {} ({})(   R   R   R6   RB   RC   RE   RD   R   R   RF   R<   R'   R+   R*   t   remove_clientR   R   Rt   (   RI   R   t
   public_keyR   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR\     s2    

	c         C` st   |  j  |  | |  j k rX t j d j | t |    | |  j | <|  j |  n t d d j |    d S(   Nu0   declare_metadata: private-key = {} metadata = {}i   u"   Private-key {} expired or invalid.u    (	   R   RB   R   R   Rt   R   RC   R   R   (   RI   R   t   metadata(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR]     s    c         C` s   |  j  |  | |  j k r |  j |  } t j d j | |   | d  k	 r | |  j k r t j d j |  j |   |  j | Si  Sq t d d   n t d d j |    d  S(   Nu-   get_metadata: private-key = {} client-id = {}u   --> metadata = {}i   u   Invalid client IDi   u"   Private-key {} expired or invalid.(	   R   RB   t   _public_id_to_private_keyR   R   Rt   R   RC   R   (   RI   R   t	   client_idt   client_private_key(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR^   	  s    c         C` s  |  j  |  | |  j k rt j d j | t |    | |  j k r |  j | } x= | D]2 } y |  j | j |  Wq^ t	 k
 r q^ Xq^ Wn  t
 j |  |  j | <t
 j |  } xi | D]a } | j d  r xI | D]> } | j | d   r | | k r | | k r| | =qq q Wq q Wt j d j | t |    xZ | D]R } | |  j k r| |  j | k r|  j | j |  qqN| g |  j | <qNW|  j |  n t d d j |    d S(   Nu3   declare_subscriptions: private-key = {} mtypes = {}u   *iu;   declare_subscriptions: subscriptions accepted from {} => {}i   u"   Private-key {} expired or invalid.u    (   R   RB   R   R   Rt   R   RE   RD   R   t
   ValueErrort   copyt   deepcopyt   endswitht
   startswithR   R   R   (   RI   R   t   mtypest   prev_mtypesR   t   original_mtypest   mtype2(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR_     s>    c         C` s   |  j  |  | |  j k r |  j |  } | d  k	 r | |  j k rw t j d j | t |  j |    |  j | St j d j |   i  Sq t	 d d   n t	 d d j |    d  S(   Nu-   get_subscriptions: client-id = {} mtypes = {}u2   get_subscriptions: client-id = {} mtypes = missingi   u   Invalid client IDi   u"   Private-key {} expired or invalid.(
   R   RB   R   R   RE   R   R   Rt   R   R   (   RI   R   R   R   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR`   P  s    
c         C` s   |  j  |  | |  j k r g  } x> |  j j   D]- } | | k r2 | j |  j | d  q2 q2 Wt j d j | |   | St d d j |    d  S(   Ni    u5   get_registered_clients: private_key = {} clients = {}i   u"   Private-key {} expired or invalid.(   R   RB   R   R   R   R   Rt   R   (   RI   R   t   reg_clientst   pkey(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyRa   f  s    c         C` s   |  j  |  | |  j k r i  } xM |  j j   D]< } | | k r2 |  j | |  r2 i  | |  j | d <q2 q2 Wt j d j | | |   | St d d j |    d  S(   Ni    u@   get_subscribed_clients: private_key = {} mtype = {} clients = {}i   u"   Private-key {} expired or invalid.(   R   RB   R   t   _is_subscribedR   R   Rt   R   (   RI   R   R   t   sub_clientsR   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyRb   v  s    c         C` s   g  } |  j  d  } t t t |    } | j   | j d  x` | D]X } d j | | d   } | |  k r | d k r | d } q d } n  | j |  qK W| S(   u  
        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.*', '*']
        u   .ii   u    u   .*u   *(   t   splitt   listR   t   lent   reverseR   R   (   R   t   subtypesR   t   indexest   it	   tmp_mtype(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR     s    
	c         C` sX   t  } t j |  } x< | D]4 } | |  j k r | |  j | k rP t } qP q q W| S(   N(   R   R   R   RD   Rq   (   RI   R   R   t
   subscribedR   t   msub(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR     s    c         C` s   |  j  |  | |  j k r |  j |  j |  | d  t k rc t d d j | | d    n  |  j d |  j d | | | f  i  St d d j |    d  S(   Nu
   samp.mtypei   u$   Client {} not subscribed to MType {}R   R   i   u"   Private-key {} expired or invalid.(	   R   RB   R   R   R   R   Rt   R   R   (   RI   R   t   recipient_idR   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyRc     s    
c   	      C` s   | |  j  k r d  S|  j  | d } y[ t j d j | d | |   |  j |  } | | f } d } |  j | | | |  Wn9 t k
 r } t j d j | d | | |  t	  n Xd  S(   Ni    u   notify {} from {} to {}u
   samp.mtypeu   receiveNotificationu7   {} notification from client {} to client {} failed [{}](
   RB   R   R   Rt   R   t   _retry_methodt	   ExceptionR   R   R   (	   RI   t   sender_private_keyt   recipient_public_idR   t   sender_public_idt   recipient_private_keyt
   arg_paramst   samp_method_nameR   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR     s"    

	c         C` sl   |  j  |  | |  j k rP d | k r: t d d   n  |  j | |  } | St d d j |    d  S(   Nu
   samp.mtypei   u   samp.mtype keyword is missingi   u"   Private-key {} expired or invalid.(   R   RB   R   t   _notify_all_Rt   (   RI   R   R   t   recipient_ids(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyRd     s    c      	   C` s   g  } t  j | d  } x | D] } | |  j k r  xg |  j | D]U } | | k rC |  j | d } | j |  |  j d |  j d | | | f  qC qC Wq  q  W| S(   Nu
   samp.mtypei    R   R   (   R   R   RD   RB   R   R   Rc   (   RI   R   R   R   R   R   R   t   _recipient_id(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR     s    c      	   C` s   |  j  |  | |  j k r |  j |  j |  | d  t k rc t d d j | | d    n  |  j | d } |  j | |  } |  j d |  j	 d | | | | | f  | St d d j |    d  S(	   Nu
   samp.mtypei   u$   Client {} not subscribed to MType {}i    R   R   i   u"   Private-key {} expired or invalid.(
   R   RB   R   R   R   R   Rt   t   _get_new_hub_msg_idR   t   _call_(   RI   R   R   t   msg_tagR   R   t   msg_id(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyRe     s    
c   
      C` s   | |  j  k r d  Syn t j d j | j d  d | | | d   |  j |  } | | | f } d } |  j | | | |  WnR t k
 r }	 t j	 d j | d | j d  d | | t
 |	  |	  t  n Xd  S(   Nu   call {} from {} to {} ({})u   ;;i    u
   samp.mtypeu   receiveCallu5   {} call {} from client {} to client {} failed [{},{}](   RB   R   R   Rt   R   R   R   R   R   R   t   typeR   (
   RI   R   R   R   R  R   R   R   t   samp_methodNameR   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR     s"    c         C` s   |  j  |  | |  j k rp d | k rC t d d j |    n  |  j | d } |  j | | | |  } | St d d j |    d  S(   Nu
   samp.mtypei   u5   samp.mtype keyword is missing in message tagged as {}i    i   u"   Private-key {} expired or invalid.(   R   RB   R   Rt   t
   _call_all_(   RI   R   R  R   R   R  (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyRf   2  s    c         C` s   i  } t  j | d  } x | D] } | |  j k r  x| |  j | D]j } | | k rC |  j | |  }	 |  j | d }
 |	 | |
 <|  j d |  j d | | |
 |	 | f  qC qC Wq  q  W| S(   Nu
   samp.mtypei    R   R   (   R   R   RD   R   RB   R   R   (   RI   R   R   R  R   R  R   R   R   t   _msg_idt   receiver_public_id(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR  A  s     		
c         C` s  |  j  |  | |  j k r t |  } t j   } i  } |  j | | d |  } d  |  j | <x |  j r | d k r t j   | | k r |  j | =t d d   n  |  j | d  k	 r t	 j
 |  j |  } |  j | =Pn  t j d  qb W| St d d j |    d  S(   Nu   samp::sync::calli    i   u   Timeout expired!g{Gz?i   u"   Private-key {} expired or invalid.(   R   RB   t   intR   Re   R   RG   R   R   R   R   R   Rt   (   RI   R   R   R   RN   R   t   responseR  (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyRg   V  s(    	"

c         C` s]   |  j  |  | |  j k rA |  j d |  j d | | | f  n t d d j |    i  S(   u   
        The main method that gets called for replying. This starts up an
        asynchronous reply thread and returns.
        R   R   i   u"   Private-key {} expired or invalid.(   R   RB   R   t   _reply_R   Rt   (   RI   R   R  R	  (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyRh   s  s    c         C` s  | |  j  k s | r d  S|  j  | d } | j d d  \ } } } } y t j d j | | |   | d k r | |  j j   k r | |  j | <q n: |  j |  }	 | | | f }
 d } |  j |	 | | |
  Wn5 t	 k
 r} t
 j d j | | | |  t  n Xd  S(   Ni    u   ;;i   u   reply {} from {} to {}u   samp::sync::callu   receiveResponseu0   {} reply from client {} to client {} failed [{}](   RB   R   R   R   Rt   RG   R   R   R   R   R   R   R   (   RI   t   responder_private_keyR  R	  t   responder_public_idt   counterR   R   t   recipient_msg_tagR   R   R   R   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR
    s&    	c         C` sG  | d k r t d   n  d d l m } x t | j  D] } |  j s] t j d  q; n  yt |  j	 r | |  j
 k r i | d 6| d 6} |  j
 | j |  n- |  j | d } t | j j |  | |  WnF t j k
 r}	 t j d j | | d |	 j   t j d  q; Xd Sq; W| d	 | j d
 }
 t |
   d S(   u  
        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
        u   Invalid client IDi   (   t   confg{Gz?u   samp.methodNameu   samp.paramsu*   {} XML-RPC endpoint error (attempt {}): {}Nu    failed after u	    attempts(   R   R   t    R  R   t	   n_retriesR   R   R   R'   R+   t   putRF   t   getattrR   R   R   t   FaultR   R   Rt   t   faultString(   RI   R   R   R   R   R  t   attemptt   callbackt   hubR   t   error_message(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR     s.    		

 
c         C` s9   x2 |  j  j   D]! } |  j  | d | k r | Sq Wd  S(   Ni    (   RB   R   R   (   RI   R   R   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR     s    c         C` s;   |  j   |  j d 7_ Wd  QXd j |  j |  j | |  S(   Ni   u   msg#{};;{};;{};;{}(   R6   R=   Rt   RA   (   RI   R   t   sender_msg_id(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR     s
    
c         C` sE   |  j  6 t j   |  _ | d  k	 r; t j   |  j | <n  Wd  QXd  S(   N(   R6   R   R;   R   R<   (   RI   R   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR     s    
c         C` s   d S(   Nu    (    (   RI   R   t	   sender_idR   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR     s    c         C` s   | |  j  k r d | k rR | d d k rR |  j |  j  | i t d 6i  d 6 n| d | k r | d d k s~ | d d k r |  j | d d | d d	  } |  j |  j  | i t d 6i | d
 6d 6 n  d Sd Sd  S(   Nu
   samp.mtypeu   samp.app.pingu   samp.statusu   samp.resultu   x-samp.query.by-metau   samp.query.by-metau   samp.paramsu   keyu   valueu   idsu    (   R   Rh   R	   R   (   RI   R   R  R  R   t   ids_list(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR     s    
c         C` s   d S(   Nu    (    (   RI   R   t   responder_idR  R	  (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR     s    u   unknownc         C` s  |  j    | d d k r, t d d   n  | s; d } n  t | t  rk d | k rk t d d   qk n  |  j j d	  |  j j | | | f  |  j j   } |  j j   | r |  j	   } d
 j
 |  j | d  } | | d <|  j j | d  | St d d   d  S(   Ni    u	   localhostu	   127.0.0.1i  u,   Request of registration rejected by the Hub.u   unknownu	   samp.nameuL   Request of registration rejected by the Hub (application name not provided).u   waitu&   http://localhost:{}/translator/{}?ref=u   samp.private-keyu   samp.url-translatoru-   Request of registration rejected by the user.(   u	   localhostu	   127.0.0.1(   R   R   t
   isinstancet   dictR.   R  R,   R-   t   getR   Rt   R)   R*   t
   add_client(   RI   t   identity_infot   client_addresst   originR	  t   register_mapt   translator_url(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyRk     s*    
	

c         C` sv   |  j    | |  j k rZ | d k rD | |  j k rW |  j | =qW qr t j   |  j | <n t d d j |    d S(   Nu   0i   u"   Private-key {} expired or invalid.u    (   R   RB   R+   R   Ry   R   Rt   (   RI   R   t   allow(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyRl   1  s    
c         C` s   |  j    | |  j k rt g  } |  j | } y- x& |  j rW | j   } | j |  q2 WWn t j k
 ro n X| St d d j	 |    d  S(   Ni   u"   Private-key {} expired or invalid.(
   R   RB   R+   R   R   R   R   R   R   Rt   (   RI   R   t   timeout_secsR  t   callback_queuet   item_queued(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyRm   >  s    
N(   u   unknowni    (F   t   __name__t
   __module__t   __doc__R   Rq   RV   t   propertyRW   Rj   Rn   Rx   R~   R   R   R   R   R   R   R   R   R   R   R?   R   R   R   R   R   R   R   R   R   R   RY   R   RZ   R   R[   R   R\   R]   R^   R_   R`   Ra   Rb   t   staticmethodR   R   Rc   R   Rd   R   Re   R   Rf   R  Rg   Rh   R
  R   R   R   R   R   R   R   Rk   Rl   Rm   (    (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR   #   s   ?	U							
	*			$	(	
														)			4			(												 	7					'	t   WebProfileDialogc           B` s)   e  Z d  Z d   Z d   Z d   Z RS(   uU  
    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         C` s   y |  j  j   } Wn$ t j k
 r) na t k
 r9 nQ Xt | d t  rZ | d } n | d d } |  j | | d | d | d  d  S(   Ni    u	   samp.namei   i   (   Rz   R   R   R   t   AttributeErrorR  R   t   show_dialog(   RI   R   t	   samp_name(    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyt   handle_queuej  s    c         C` s   |  j  j t  d  S(   N(   R{   R  Rq   (   RI   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyt   consenty  s    c         C` s   |  j  j t  d  S(   N(   R{   R  R   (   RI   (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyt   reject|  s    (   R+  R,  R-  R4  R5  R6  (    (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyR0  O  s   		(.   t
   __future__R    R   R   R   R   R   R   R0   R4   R   R   R   t   extern.six.movesR   R   R   R   t   extern.six.moves.urllib.parseR   R  R   t	   constantsR	   R
   t   errorsR   R   R   t   utilsR   R   R   t   lockfile_helpersR   R   t   standard_profileR   RR   R   R   t   __all__t   __doctest_skip__t   objectR   R0  (    (    (    s/   lib/python2.7/site-packages/astropy/samp/hub.pyt   <module>   s8   "     1