U
    •uÄcÜ•  ã                   @   sÎ   d dl Z d dlZd dlm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mZ d dlmZmZ d dlmZmZ d dlmZ d	Zdd
d„Zddd„ZG dd„ deƒZG dd	„ d	eƒZddd„ZdS )é    N)Úpartial)ÚObservableMixin)Ú	parse_url)ÚComponentConfigÚSubscribeOptionsÚRegisterOptions)ÚSessionNotReadyÚApplicationError)Úcreate_authenticatorÚIAuthenticator)ÚSERID_TO_SERÚ	Componentc                 C   s.  |r|| ƒ nt | tƒs tdƒ‚t | tƒ�r*d| kr<tdƒ‚| d dkrZtd | d ¡ƒ‚|  ¡ D ]}|dkrbtd |¡ƒ‚qb| d dkrÌd	D ]}|| krŽtd
 |¡ƒ‚qŽdD ]}|| kr®td |¡ƒ‚q®n^| d dk�rdD ]}|| krÞtd |¡ƒ‚qÞdD ]}|| krþtd |¡ƒ‚qþnd�s*tdƒ‚dS )z9
    Check a WAMP connecting endpoint configuration.
    z'endpoint' must be a dictÚtypez)'type' required in endpoint configuration)ÚtcpÚunixzinvalid type "{}" in endpoint)r   ÚhostÚportÚpathÚtlsÚtimeoutÚversionz*Invalid key '{}' in endpoint configurationr   ©r   r   z&'{}' required in 'tcp' endpoint config)r   z''{}' not valid in 'tcp' endpoint configr   z('{}' required for 'unix' endpoint config)r   r   r   z('{}' not valid in 'unix' endpoint configFúshould not arrive hereN)Ú
isinstanceÚdictÚ
ValueErrorÚformatÚkeysÚAssertionError)ÚendpointÚcheck_native_endpointÚk© r"   úW/var/www/html/SARATH/school/venv/lib/python3.8/site-packages/autobahn/wamp/component.pyÚ_validate_endpoint1   sN    

ÿ	ÿÿÿÿÿr$   c                 C   sš  t |ƒtkrtd t |ƒ¡ƒ‚dddddddd	d
dddg}| ¡ D ]}||krBtd |¡ƒ‚qBd}d|kr’|d dkrˆtd |d ¡ƒ‚|d }nd|d< d|kr²|dkr²tdƒ‚| dd¡}|dk	�r| ¡ D ]}|dkrÐtd |¡ƒ‚qÐdD ]}||krðtd |¡ƒ‚qðtƒ }d|k�rB|d }t|tƒ�sBtd t |ƒ¡ƒ‚|dk�r`dD ]}||k�rPtd |¡ƒ‚�qPd|k�r¢t|d ƒ\}	}
}}}}d|
||	dœ}n|d }t	||ƒ d|k�rÆtdƒ‚d|k�rNt|d t
tfƒ�sìtdƒ‚tdd„ |d D ƒƒ�stdƒ‚t ¡ }|d D ]0}||k�rtd  |d! d"d„ |D ƒ¡¡ƒ‚�q| dd#d$g¡}nî|d%k�r@d|k�rì|d  d&¡�r˜t|d ƒ\}}
}n0|d  d'¡�rÂt|d ƒ\}}
}}}}ntƒ ‚|
d(k�rÞd(|d)œ}nd|
|d*œ}n|d }d|k�rtd+ƒ‚d|k�r8t|d ttfƒ�s,td,ƒ‚|d g}nd#g}nd-�sNtd.ƒ‚i }d/D ]}||k�rV|| ||< �qVt| f|| dd¡||||d0œ|—ŽS )1a   
    Internal helper to insert defaults and create _Transport instances.

    :param transport: a (possibly valid) transport configuration
    :type transport: dict

    :returns: a _Transport instance

    :raises: ValueError on invalid configuration
    z<invalid type {} for transport configuration - must be a dictr   Úurlr   Z
serializerÚserializersÚoptionsÚmax_retriesÚmax_retry_delayÚinitial_retry_delayÚretry_delay_growthÚretry_delay_jitterÚproxyz&'{}' is not a valid configuration itemÚ	websocket)r.   Ú	rawsocketzInvalid transport type {}z3proxy= only supported for type=websocket transportsNr   z Unknown key '{}' in proxy configzProxy config requires '{}'zoptions must be a dict, not {})r%   zTransport requires '{}' keyr   )r   r   r   r   z5'serializer' is only for rawsocket; use 'serializers'z''serializers' must be a list of stringsc                 S   s   g | ]}t |ttfƒ‘qS r"   )r   Ústr©Ú.0Úsr"   r"   r#   Ú
<listcomp>½   s   ÿz%_create_transport.<locals>.<listcomp>z-Invalid serializer '{}' (expected one of: {})z, c                 S   s   g | ]}t |ƒ‘qS r"   )Úreprr1   r"   r"   r#   r4   Ç   s     ZcborÚjsonr/   ZrsÚwsr   )r   r   )r   r   r   z5'serializers' is only for websocket; use 'serializer'z'serializer' must be a stringFr   )r(   r)   r*   r+   r,   )Úkindr%   r   r&   r-   r'   )r   r   r   r   r   ÚgetZformaTr   Úparse_ws_urlr$   ÚlistÚtupleÚallr   ÚjoinÚ
startswithÚparse_rs_urlÚRuntimeErrorr0   r   Ú
_Transport)ÚindexÚ	transportr    Zvalid_transport_keysr!   r8   r-   r'   ÚkeyZ	is_securer   r   Úresourcer   ÚparamsZendpoint_configZvalid_serializersÚserialZserializer_configZisSecureÚkwr"   r"   r#   Ú_create_transportj   sò             ýÿ
ÿ
ÿÿ
ÿ


ü	


þ

þÿ


þý


ÿ
ùørJ   c                   @   sB   e Zd ZdZddd„Zd	d
„ Zdd„ Zdd„ Zdd„ Zdd„ Z	dS )rB   z@
    Thin-wrapper for WAMP transports used by a Connection.
    éÿÿÿÿé,  ç      ø?çš™™™™™¹?Nc                 C   s†   |dkrt ƒ }|| _|| _|| _|| _|| _|| _| jdkrPt|ƒdkrPtdƒ‚|| _	|| _
|| _|	| _|
| _|| _d| _|  ¡  dS )z	
        Nr/   é   z5'rawsocket' transport requires exactly one serializerF)r   Úidxr   r%   r   r'   r&   Úlenr   r(   r)   r*   r+   r,   r-   Ú_permanent_failureÚreset)ÚselfrP   r8   r%   r   r&   r(   r)   r*   r+   r,   r-   r'   r"   r"   r#   Ú__init__  s(    
ÿz_Transport.__init__c                 C   s   d| _ d| _d| _| j| _dS )zP
        set connection failure rates and retry-delay to initial values
        r   N)Úconnect_attemptsÚconnect_sucessesÚconnect_failuresr*   Úretry_delay©rT   r"   r"   r#   rS   .  s    z_Transport.resetc                 C   s
   d| _ dS )z¸
        Mark this transport as failed, meaning we won't try to connect to
        it any longer (that is: can_reconnect() will always return
        False afer calling this).
        TN)rR   rZ   r"   r"   r#   Úfailed7  s    z_Transport.failedc                 C   s(   | j r
dS | jdkrdS | j| jd k S )NFrK   TrO   )rR   r(   rV   rZ   r"   r"   r#   Úcan_reconnect?  s
    
z_Transport.can_reconnectc                 C   sv   | j dkrdS | jdkr2| j | jd kr2tdƒ‚n@| j| j | _t | j| j| j ¡| _| j| jkrl| j| _| jS d S )Nr   rK   rO   zmax reconnects reached)	rV   r(   rA   rY   r+   ÚrandomÚnormalvariater,   r)   rZ   r"   r"   r#   Ú
next_delayF  s    

z_Transport.next_delayc                 C   s    t | jtƒr| jd S t| jƒS )zF
        returns a human-readable description of the endpoint
        r   )r   r   r   r5   rZ   r"   r"   r#   Údescribe_endpointS  s    
z_Transport.describe_endpoint)rK   rL   rM   rM   rN   NN)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__rU   rS   r[   r\   r_   r`   r"   r"   r"   r#   rB     s          ù
&	rB   c                   @   s„   e Zd ZdZdZddd„Zd dd„Zd!d	d
„Zdd„ Zd"dd„Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS )#r   z‚
    A WAMP application component. A component holds configuration for
    (and knows how to create) transports and sessions.
    NFc                    s,   ˆdkst ˆtƒst‚‡ ‡‡‡fdd„}|S )a[  
        A decorator as a shortcut for subscribing during on-join

        For example::

            @component.subscribe(
                "some.topic",
                options=SubscribeOptions(match='prefix'),
            )
            def topic(*args, **kw):
                print("some.topic({}, {}): event received".format(args, kw))
        Nc                    s"   ‡‡ ‡‡fdd„}ˆ  d|¡ ˆ S )Nc                    s   | j ˆˆˆˆ d�S )N)Útopicr'   Úcheck_types)Ú	subscribe©ÚsessionÚdetails)rf   Úfnr'   re   r"   r#   Údo_subscription|  s    z?Component.subscribe.<locals>.decorator.<locals>.do_subscriptionr>   ©Úon)rk   rl   ©rf   r'   rT   re   ©rk   r#   Ú	decoratorz  s    z&Component.subscribe.<locals>.decorator)r   r   r   )rT   re   r'   rf   rq   r"   ro   r#   rg   k  s    zComponent.subscribec                    s,   ˆdkst ˆtƒst‚‡ ‡‡‡fdd„}|S )aZ  
        A decorator as a shortcut for registering during on-join

        For example::

            @component.register(
                "com.example.add",
                options=RegisterOptions(invoke='roundrobin'),
            )
            def add(*args, **kw):
                print("add({}, {}): event received".format(args, kw))
        Nc                    s"   ‡‡ ‡‡fdd„}ˆ  d|¡ ˆ S )Nc                    s   | j ˆˆˆˆ d�S )N)Z	procedurer'   rf   )Úregisterrh   )rf   rk   r'   Úurir"   r#   Údo_registration“  s    z>Component.register.<locals>.decorator.<locals>.do_registrationr>   rm   )rk   rt   ©rf   r'   rT   rs   rp   r#   rq   ‘  s    z%Component.register.<locals>.decorator)r   r   r   )rT   rs   r'   rf   rq   r"   ru   r#   rr   ‚  s    zComponent.registerÚrealm1c	              	   C   s  |   dddddddg¡ |dk	r0t|ƒs0td	ƒ‚|| _|dk	rNt|ƒsNtd
ƒ‚|| _|dkr`d}t|ttfƒr„|}	d|	dœ}
|
g}nt|tƒr”|g}g | _t	|ƒD ]:\}}
t
|
ƒtkrÂd|
dœ}n|
}| j t||| jƒ¡ q¢|päi | _|rò|| _|| _|| _d| _d| _d| _d| _dS )a  
        :param main: After a transport has been connected and a session
            has been established and joined to a realm, this (async)
            procedure will be run until it finishes -- which signals that
            the component has run to completion. In this case, it usually
            doesn't make sense to use the ``on_*`` kwargs. If you do not
            pass a main() procedure, the session will not be closed
            (unless you arrange for .leave() to be called).

        :type main: callable taking two args ``reactor`` and ``ISession``

        :param transports: Transport configurations for creating
            transports. Each transport can be a WAMP URL, or a dict
            containing the following configuration keys:

                - ``type`` (optional): ``websocket`` (default) or ``rawsocket``
                - ``url``: the router URL
                - ``endpoint`` (optional, derived from URL if not provided):
                    - ``type``: "tcp" or "unix"
                    - ``host``, ``port``: only for TCP
                    - ``path``: only for unix
                    - ``timeout``: in seconds
                    - ``tls``: ``True`` or (under Twisted) an
                      ``twisted.internet.ssl.IOpenSSLClientComponentCreator``
                      instance (such as returned from
                      ``twisted.internet.ssl.optionsForClientTLS``) or
                      ``CertificateOptions`` instance.
                - ``max_retries``: Maximum number of reconnection attempts. Unlimited if set to -1.
                - ``initial_retry_delay``: Initial delay for reconnection attempt in seconds (Default: 1.0s).
                - ``max_retry_delay``: Maximum delay for reconnection attempts in seconds (Default: 60s).
                - ``retry_delay_growth``: The growth factor applied to the retry delay between reconnection attempts (Default 1.5).
                - ``retry_delay_jitter``: A 0-argument callable that introduces nose into the delay. (Default random.random)
                - ``serializer`` (only for raw socket): Specify an accepted serializer (e.g. 'json', 'msgpack', 'cbor', 'ubjson', 'flatbuffers')
                - ``serializers``: Specify list of accepted serializers
                - ``options``: tbd
                - ``proxy``: tbd

        :type transports: None or str or list

        :param realm: the realm to join
        :type realm: str

        :param authentication: configuration of authenticators
        :type authentication: dict

        :param session_factory: if None, ``ApplicationSession`` is
            used, otherwise a callable taking a single ``config`` argument
            that is used to create a new `ApplicationSession` instance.

        :param is_fatal: a callable taking a single argument, an
            ``Exception`` instance. The callable should return ``True`` if
            this error is "fatal", meaning we should not try connecting to
            the current transport again. The default behavior (on None) is
            to always return ``False``
        ÚstartÚconnectr>   ÚreadyÚleaveÚ
disconnectÚconnectfailureNz%"is_fatal" must be a callable or Nonez""main" must be a callable if givenzws://127.0.0.1:8080/wsr.   )r   r%   F)Zset_valid_eventsÚcallabler   Ú	_is_fatalÚ_entryr   r0   r   Ú_transportsÚ	enumerater   ÚappendrJ   Z_check_native_endpointÚ_authenticationÚsession_factoryÚ_realmÚ_extraÚ_delay_fÚ_done_fÚ_sessionÚ	_stopping)rT   ÚmainÚ
transportsÚconfigÚrealmÚextraZauthenticationr„   Úis_fatalr%   rD   rP   Ú
_transportr"   r"   r#   rU   ™  sZ    9ùÿþ
þÿ
zComponent.__init__c                 C   s   | j D ]}| ¡ r dS qdS )NTF)r€   r\   )rT   rD   r"   r"   r#   Ú_can_reconnect  s    
zComponent._can_reconnectc                    s¾   ˆj dk	r2t ¡ ‰‡fdd„}t ˆj ||¡ ˆS t ¡ ˆ_ ‡fdd„}t ˆj ||¡ t ˆj¡‰dg‰‡fdd„‰‡‡‡‡fd	d
„‰ ‡ ‡‡‡‡fdd„‰ˆ dˆˆ¡}t |ˆˆ¡ ˆj S )aˆ  
        This starts the Component, which means it will start connecting
        (and re-connecting) to its configured transports. A Component
        runs until it is "done", which means one of:

        - There was a "main" function defined, and it completed successfully;
        - Something called ``.leave()`` on our session, and we left successfully;
        - ``.stop()`` was called, and completed successfully;
        - none of our transports were able to connect successfully (failure);

        :returns: a Future/Deferred which will resolve (to ``None``) when we are
            "done" or with an error if something went wrong.
        Nc                    s   t  ˆ | ¡ d S ©N)ÚtxaioÚresolve©Úarg)Údr"   r#   Ú_cb4  s    zComponent._start.<locals>._cbc                    s
   dˆ _ | S )z}
            if the _done_f future is resolved (good or bad), we want to set it
            to None in our class
            N)rˆ   r–   rZ   r"   r#   Ú_reset>  s    z Component._start.<locals>._resetr   c                    sZ   d ˆ _ ˆ jrt ˆ jd ¡ n:ˆ jjdt | ¡d� ˆ jjdt 	| ¡d� t 
ˆ j| ¡ d S )NzInternal error {msg}©Úmsgú{tb}©Útb)r‡   rŠ   r”   r•   rˆ   ÚlogÚinfoÚfailure_messageÚdebugÚfailure_format_tracebackÚreject)ÚfailrZ   r"   r#   ÚerrorN  s    zComponent._start.<locals>.errorc                    sb   d ˆ_ ‡‡‡fdd„‰ ‡fdd„‰‡ ‡fdd„}‡fdd„}t ˆjˆˆd	 ¡}t |||¡ d S )
Nc                    s  ˆ j jdt | ¡d� ˆ j jdt | ¡d� t| jtƒrPˆ j jd| j 	¡ d� nnt| jt
ƒrtˆ j jdt | ¡d� nJˆ  | j¡r¨| jjd d \}}}ˆ j jd	|d
� nˆ j jdt | ¡d� ˆ jd krÎd}nˆ  | j¡}|röˆ j  d¡ ˆd  ¡  t dˆd ¡ d S )Nzcomponent failed: {error})r§   r�   rž   z{msg}r›   z&Connection failed with OS error: {msg}r   zTLS failure: {reason})ÚreasonzConnection failed: {error}Fz"Error was fatal; failing transport)r    r£   r”   r¢   r¤   r   Úvaluer	   r§   Úerror_messageÚOSErrorr¡   Z_is_ssl_errorÚargsr~   r[   Ú
call_later)r¦   Zssl_libZssl_funcZ
ssl_reasonr�   )rT   Útransport_candidateÚtransport_checkr"   r#   Úhandle_connect_error^  s*    þ
zGComponent._start.<locals>.attempt_connect.<locals>.handle_connect_errorc                    s>   t  ¡ ‰ ˆ dˆˆj¡}t  |‡ ‡fdd„‡ ‡fdd„¡ ˆ S )Nr|   c                    s   t  ˆ ˆ¡S r“   ©r”   r¥   ©Ú_©Zchain_fr¦   r"   r#   Ú<lambda>—  ó    zYComponent._start.<locals>.attempt_connect.<locals>.notify_connect_error.<locals>.<lambda>c                    s   t  ˆ ˆ¡S r“   r±   r²   r´   r"   r#   rµ   ˜  r¶   )r”   Úcreate_futureÚfirer©   Úadd_callbacks)r¦   Z	handler_frZ   r´   r#   Únotify_connect_errorŽ  s    ýzGComponent._start.<locals>.attempt_connect.<locals>.notify_connect_errorc                    s   ˆ| ƒ}t  |d ˆ ¡ d S r“   )r”   r¹   )r¦   Znotify_f©r°   rº   r"   r#   Úconnect_errorœ  s    z@Component._start.<locals>.attempt_connect.<locals>.connect_errorc                    s   t  ˆ jd ¡ d S r“   )r”   r•   rˆ   )ÚxrZ   r"   r#   Úsession_done   s    z?Component._start.<locals>.attempt_connect.<locals>.session_doner   )r‡   r”   Ú	as_futureÚ_connect_oncer¹   )r³   r¼   r¾   Z	connect_f)ÚlooprT   r®   r¯   r»   r#   Úattempt_connect[  s    0 þz)Component._start.<locals>.attempt_connectc              
      sÄ   ˆj  d¡ ˆ ¡ shd}ˆj  |¡ zt|ƒ‚W n6 tk
rf } zt ˆj|¡ W Y ¢d S d }~X Y nX tˆƒ}| 	¡ rh|ˆd< q„qh| 
¡ }ˆj jd|j|j|d� t |¡ˆ_t ˆjˆ ˆ¡ d S )NzEntering re-connect loopz:Component failed: Exhausted all transport connect attemptsr   zZtrying transport {transport_idx} ("{transport_url}") using connect delay {transport_delay})Ztransport_idxZtransport_urlZtransport_delay)r    r£   r’   r¡   rA   r”   r¥   rˆ   Únextr\   r_   ÚwarnrP   r%   Úsleepr‡   r¹   )r³   Úerr_msgÚerD   Údelay)rÂ   r§   rT   r®   Útransport_genr"   r#   r¯   ©  s,    üz)Component._start.<locals>.transport_checkrw   )rˆ   r”   r·   r¹   Ú	itertoolsÚcycler€   r¸   )rT   rÁ   r™   rš   Zstart_fr"   )rÂ   r˜   r§   rÁ   rT   r®   r¯   rÉ   r#   Ú_start  s     

N zComponent._startc                 C   sZ   d| _ | jr | j ¡ r | j ¡ S | jr6t tj| j¡S t | j	¡sPt 
| j	d ¡ t d ¡S )NT)rŠ   r‰   Zis_attachedrz   r‡   r”   r¿   ÚcancelÚ	is_calledrˆ   r•   Zcreate_future_successrZ   r"   r"   r#   ÚstopÍ  s    
zComponent.stopc                    st   ˆj jdˆjˆ ¡ d� t ¡ ‰ ‡ ‡‡‡fdd„}ˆ jd7  _t ˆjˆˆ|ˆ ¡}‡ ‡fdd„}t 	|d |¡ ˆ S )NzWconnecting once using transport type "{transport_type}" over endpoint "{endpoint_desc}")Ztransport_typeZendpoint_descc            
   
      s  t ˆjˆjƒ} zTˆ | ¡ ˆ_}ˆj ¡ D ]4\}}t|tƒrH| 	|¡ q*t
|f|Ž}| 	|¡ q*W n: tk
rœ } zt |¡}t ˆ |¡ ‚ W 5 d }~X Y nhX ˆ|_‡ ‡fdd„}| d|¡ ‡ ‡‡‡fdd„}ˆjd k	ræ| d|¡ ‡ ‡fdd„}	| d	|	¡ |S d S )
Nc                    sV   ˆj jd|d� t ˆ ¡sR|jdkr2t ˆ d ¡ n t t|j|jƒ¡}t 	ˆ |¡ d S )Nz"session leaving '{details.reason}'©rj   )zwamp.close.normalzwamp.close.goodbye_and_out)
r    r¡   r”   rÎ   r¨   r•   Úcreate_failurer	   Úmessager¥   )ri   rj   Úf©ÚdonerT   r"   r#   Úon_leave  s    þ

ÿzAComponent._connect_once.<locals>.create_session.<locals>.on_leaverz   c                    sf   ˆ  ¡  ˆ jd7  _ˆjjd|d� t ˆjˆˆ ¡}‡‡ fdd„}‡‡‡ fdd„}t |||¡ d S )NrO   zsession on_join: {details}rÐ   c                    s(   ˆ j  d¡ ‡fdd„}t d|¡ d S )NÚmain_successc                      s&   zˆ   ¡  W n tk
r    Y nX d S r“   )rz   r   r"   ©ri   r"   r#   rz      s    zeComponent._connect_once.<locals>.create_session.<locals>.on_join.<locals>.main_success.<locals>.leaver   )r    r£   r”   r­   )r³   rz   )rT   ri   r"   r#   r×     s    zVComponent._connect_once.<locals>.create_session.<locals>.on_join.<locals>.main_successc                    s(   ˆj jd| d� t ˆ | ¡ ˆ ¡  d S )Nzmain_error: {err}©Úerr)r    r£   r”   r¥   r{   rÙ   )rÕ   rT   ri   r"   r#   Ú
main_error)  s    zTComponent._connect_once.<locals>.create_session.<locals>.on_join.<locals>.main_error)rS   rW   r    r£   r”   r¿   r   r¹   )ri   rj   r˜   r×   rÛ   ©rÕ   ÚreactorrT   rD   rØ   r#   Úon_join  s    z@Component._connect_once.<locals>.create_session.<locals>.on_joinr>   c                    s<   ˆj jd|d� t ˆ ¡s8|s,ˆj  d¡ nt ˆ d ¡ d S )Nz,session on_disconnect: was_clean={was_clean})Ú	was_cleanzSession disconnected uncleanly)r    r£   r”   rÎ   rÄ   r•   )ri   rß   rÔ   r"   r#   Úon_disconnect4  s    þ
ÿzFComponent._connect_once.<locals>.create_session.<locals>.on_disconnectr{   )r   r…   r†   r„   r‰   rƒ   Úitemsr   r   Zadd_authenticatorr
   Ú	Exceptionr”   rÑ   r¥   Z_parentrn   r   )
Zcfgri   Z	auth_nameZauth_configZauthenticatorrÇ   rÓ   rÖ   rÞ   rà   rÜ   r"   r#   Úcreate_sessioné  s*    


z/Component._connect_once.<locals>.create_sessionrO   c                    s(   ˆ j d7  _ t ˆ ¡s$t ˆ | ¡ dS )a  
            this may seem redundant after looking at _connect_transport, but
            it will handle a case where something goes wrong in
            _connect_transport itself -- as the only connect our
            caller has is the 'done' future
            rO   N)rX   r”   rÎ   r¥   rÙ   )rÕ   rD   r"   r#   Úon_errorN  s    
z)Component._connect_once.<locals>.on_error)
r    r¡   r   r`   r”   r·   rV   r¿   Z_connect_transportr¹   )rT   rÝ   rD   rã   r˜   rä   r"   rÜ   r#   rÀ   Ý  s$    ü^   þzComponent._connect_oncec                 C   s   |   d|¡ dS )zò
        A decorator as a shortcut for listening for 'join' events.

        For example::

           @component.on_join
           def joined(session, details):
               print("Session {} joined: {}".format(session, details))
        r>   Nrm   ©rT   rk   r"   r"   r#   rÞ   ^  s    
zComponent.on_joinc                 C   s   |   d|¡ dS )zM
        A decorator as a shortcut for listening for 'leave' events.
        rz   Nrm   rå   r"   r"   r#   rÖ   j  s    zComponent.on_leavec                 C   s   |   d|¡ dS )zO
        A decorator as a shortcut for listening for 'connect' events.
        rx   Nrm   rå   r"   r"   r#   Ú
on_connectp  s    zComponent.on_connectc                 C   s   |   d|¡ dS )zR
        A decorator as a shortcut for listening for 'disconnect' events.
        r{   Nrm   rå   r"   r"   r#   rà   v  s    zComponent.on_disconnectc                 C   s   |   d|¡ dS )zM
        A decorator as a shortcut for listening for 'ready' events.
        ry   Nrm   rå   r"   r"   r#   Úon_ready|  s    zComponent.on_readyc                 C   s   |   d|¡ dS )zV
        A decorator as a shortcut for listening for 'connectfailure' events.
        r|   Nrm   rå   r"   r"   r#   Úon_connectfailure‚  s    zComponent.on_connectfailure)NF)NF)NNNrv   NNNN)N)ra   rb   rc   rd   r„   rg   rr   rU   r’   rÌ   rÏ   rÀ   rÞ   rÖ   ræ   rà   rç   rè   r"   r"   r"   r#   r   `  s*   

      ÿ

 / c           
         sØ   t |tƒr|g}t|ƒtkr.td t|ƒ¡ƒ‚|D ] }t |tƒs2td t|ƒ¡ƒ‚q2t ¡ ‰‡fdd„‰‡fdd„‰ ‡ ‡‡fdd„}g }|D ]}||ƒ}| |¡ qŒtj	|d	d
�}ˆrÔ‡‡‡fdd„}	t 
||	|	¡ |S )aˆ  
    Internal helper. Use "run" method from autobahn.twisted.wamp or
    autobahn.asyncio.wamp

    This is the generic parts of the run() method so that there's very
    little code in the twisted/asyncio specific run() methods.

    This is called by react() (or run_until_complete() so any errors
    coming out of this should be handled properly. Logging will
    already be started.
    zB"components" must be a list of Component objects - encountered {0}zN"components" must be a list of Component objects - encountereditem of type {0}c                    s   ˆ j d| |d� |S )Nz-Component '{c}' successfully completed: {arg})Úcr—   ©r£   )Úcompr—   ©r    r"   r#   Úcomponent_successª  s    z_run.<locals>.component_successc                    s.   ˆ j d| t |¡d� ˆ jdt |¡d� d S )NzComponent '{c}' error: {msg})ré   rœ   zComponent error: {tb}rž   )r§   r”   r¢   r£   r¤   )rë   rÓ   rì   r"   r#   Úcomponent_failure®  s    z_run.<locals>.component_failurec                    s,   t  | jˆ¡}t  |tˆ| ƒtˆ | ƒ¡ |S r“   )r”   r¿   rw   r¹   r   )rë   r˜   )rî   rí   rÝ   r"   r#   Úcomponent_start¶  s    ýz_run.<locals>.component_startF)Zconsume_exceptionsc                    s   ˆ  d¡ ˆ ˆ| ƒ d S )Nz&All components ended; stopping reactorrê   r–   )Údone_callbackr    rÝ   r"   r#   Úall_doneË  s    
z_run.<locals>.all_done)r   r   r   r;   r   r   r”   Zmake_loggerr‚   Úgatherr¹   )
rÝ   Ú
componentsrð   ré   rï   Zdlrë   r˜   Zdone_drñ   r"   )rî   rí   rð   r    rÝ   r#   Ú_run‰  s8    
ÿÿ
ÿÿrô   )N)N)N)rÊ   r]   Ú	functoolsr   r”   Zautobahn.utilr   Zautobahn.websocket.utilr   r:   Zautobahn.rawsocket.utilr@   Zautobahn.wamp.typesr   r   r   Zautobahn.wamp.exceptionr   r	   Zautobahn.wamp.authr
   r   Zautobahn.wamp.serializerr   Ú__all__r$   rJ   ÚobjectrB   r   rô   r"   r"   r"   r#   Ú<module>   s,   ÿ
9
 ]    -