o
    èó·iD>  ã                   @   s´   d dl Z 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 d dlmZ d dlmZmZ d	Zd
d„ Zdd„ Zdd„ ZG dd„ dejƒZddd„ZdS )é    N)Úwraps)ÚWampWebSocketClientFactory)ÚWampRawSocketClientFactory)Ú	component)ÚTransportLost)ÚSession)Úcreate_transport_serializersÚcreate_transport_serializer)Ú	ComponentÚrunc                    s   t ƒ ‰ ‡ fdd„| D ƒS )zM
    Return a list with unique elements from sequence, preserving order.
    c                    s"   g | ]}|ˆ vrˆ   |¡s|‘qS © )Úadd)Ú.0Úx©Úseenr   ú`C:\Users\psant\Downloads\PAF backend\school\venv\Lib\site-packages\autobahn/asyncio/component.pyÚ
<listcomp>3   s   " z _unique_list.<locals>.<listcomp>N)Úset)Úseqr   r   r   Ú_unique_list.   s   r   c                 C   s.   |   d¡}|d d dd„ |dd … D ƒ¡ S )NÚ_r   Ú c                 s   s   � | ]}|  ¡ V  qd S ©N)Ú
capitalize)r   Úsr   r   r   Ú	<genexpr>8   s   € z._camel_case_from_snake_case.<locals>.<genexpr>é   )ÚsplitÚjoin)ZsnakeÚpartsr   r   r   Ú_camel_case_from_snake_case6   s   
$r!   c                 C   sà   |j dkrt|ƒ}t||j||jd�}n|j dkr't|jd ƒ}t||d�}nJ dƒ‚|j 	¡ D ]=\}}z|j
d
i ||i¤Ž W q0 ttfym   z|j
d
i t|ƒ|i¤Ž W n ttfyj   td |j ||¡ƒ‚w Y q0w |S )z3
    Create a WAMP-over-XXX transport factory.
    Z	websocket)ÚurlÚserializersÚproxyZ	rawsocketr   )Ú
serializerFúshould not arrive herez"Unknown {} transport option: {}={}Nr   )Útyper   r   r"   r$   r	   r#   r   ÚoptionsÚitemsZsetProtocolOptionsÚ	TypeErrorÚKeyErrorr!   Ú
ValueErrorÚformat)ÚloopÚ	transportÚsession_factoryr#   Úfactoryr%   ÚkÚvr   r   r   Ú_create_transport_factory;   s8   
ü


ÿÿÿýûr4   c                   @   sH   e Zd ZdZe ¡ ZeZ	 dd„ Z	dd„ Z
dd„ Zdd	„ Zddd„Zd
S )r
   zæ
    A component establishes a transport and attached a session
    to a realm using the transport for communication.

    The transports a component tries to use can be configured,
    as well as the auto-reconnect strategy.
    c                 C   s   t |tjƒS )z"
        Internal helper.
        N)Ú
isinstanceÚsslÚSSLError)ÚselfÚer   r   r   Ú_is_ssl_errorr   s   zComponent._is_ssl_errorc                 C   sP   t |tƒr$d|v r"|d }t |ttfƒrd S t |tjƒrd S tdƒ‚d S tdƒ‚)NÚtlsz?'tls' configuration must be a dict, bool or SSLContext instancezI'endpoint' configuration must be a dict or IStreamClientEndpoint provider)r5   ÚdictÚboolr6   Ú
SSLContextr,   )r8   Úendpointr;   r   r   r   Ú_check_native_endpointx   s   
ÿùÿz Component._check_native_endpointc                 C   s–  t |||ƒ}|jr>|j dd¡}t|ƒtkrtd t|ƒ¡ƒ‚|j||jd |jd d�}t	 
t	j||d�¡}|  |||¡S |jd d	k�r|j d
d¡}	|	dvrXtd |	¡ƒ‚|jd }
t|
ƒtkrltd t|
ƒ¡ƒ‚|jd }t|ƒtkr€td t|ƒ¡ƒ‚|j dd¡}t|ƒtkr–td t|ƒ¡ƒ‚|j dd¡}d}|rþt|tƒrã| ¡ D ]}|dvr·td |¡ƒ‚qª| d|
¡}t|ƒtkrËtd |¡ƒ‚| dd¡}|}d}|durâtjtjj|d�}nt|tjƒrì|
}n|dv rõ|rô|
}n	td t|ƒ¡ƒ‚|j||
|||d�}t	 
t	j||d�¡}|  |||¡S |jd dk�rG|jd }t|j dd¡ƒ}|j||d�}t	 
t	j||d�¡}|  |||¡S J d ƒ‚)!z?
        Create and connect a WAMP-over-XXX transport.
        Útimeouté
   z<invalid type {} for timeout in client endpoint configurationÚhostÚport)Úprotocol_factoryrC   rD   )rA   r'   ZtcpÚversioné   )rG   é   z6invalid IP version {} in client endpoint configurationz9invalid type {} for host in client endpoint configurationz9invalid type {} for port in client endpoint configurationr;   N)ÚhostnameÚ
trust_rootz Invalid key '{}' in 'tls' configrI   zAinvalid type {} for hostname in TLS client endpoint configurationrJ   T)ÚpurposeÚcafile)FTz4unknown type {} for "tls" configuration in transport)rE   rC   rD   r6   Úserver_hostnameÚunixÚpath)rE   rO   Fr&   )r4   r$   r?   Úgetr'   Úintr,   r-   Úcreate_connectionÚasyncioÚensure_futureÚwait_forÚ_wrap_connection_futureÚstrr5   r<   Úkeysr6   Úcreate_default_contextÚPurposeÚSERVER_AUTHr>   ÚRuntimeErrorÚcreate_unix_connection)r8   r.   r/   r0   Údoner1   rA   ÚfZtime_frF   rC   rD   r;   Ztls_hostnamer2   rI   Z
cert_fnamerO   r   r   r   Ú_connect_transportŒ   sŽ   ý


ÿþ€€û
þzComponent._connect_transportc                    s:   ‡ fdd„}‡ ‡fdd„}t  ||d ¡ t  |d |¡ |S )Nc                    s`   | \}}|  ¡ rt ˆ¡st|ddƒ}t ˆt|ƒ¡ d S |j‰ tˆ ƒ‡‡ fdd„ƒ}||_d S )NZ_onclose_reasonzConnection already closedc                    s2   ˆ| ƒ}t  ˆ ¡s| d u rtdƒ} t  ˆ | ¡ |S )Nzfailed to complete connection)ÚtxaioÚ	is_calledr   Úreject)ZfailZrtn)r^   Úorigr   r   Úlost  s   
zKComponent._wrap_connection_future.<locals>.on_connect_success.<locals>.lost)Ú
is_closingra   rb   Úgetattrrc   r   Úconnection_lostr   )Úresultr/   ÚprotoÚreasonre   )r^   )rd   r   Úon_connect_successð   s   


z=Component._wrap_connection_future.<locals>.on_connect_successc                    s   ˆ j d7  _ t ˆ | ¡ d S )Nr   )Zconnect_failuresra   rc   )Úerr©r^   r/   r   r   Úon_connect_failure  s   z=Component._wrap_connection_future.<locals>.on_connect_failure)ra   Zadd_callbacks)r8   r/   r^   Zconn_frl   ro   r   rn   r   rV   î   s
   (z!Component._wrap_connection_futureNc                 C   s(   |du r| j  d¡ t ¡ }| j|d�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 which will resolve (to ``None``) when we are
            "done" or with an error if something went wrong.
        NzUsing default loop)r.   )ÚlogÚwarnrS   Úget_event_loopÚ_start)r8   r.   r   r   r   Ústart$  s   zComponent.startr   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__ra   Úmake_loggerrp   r   r0   r:   r@   r`   rV   rt   r   r   r   r   r
   b   s    b6r
   TÚinfoc                    sè   |dur
t j|d� t ¡ ‰ˆ ¡ r!t t ¡ ¡ t ¡ ‰ˆt j_t  	¡ ‰ ‡ ‡fdd„‰zˆ 
tj‡fdd„¡ ˆ 
tj‡fdd„¡ W n	 tyM   Y nw dd	„ }t ˆ| |¡ |rrzˆ ¡  W n
 tjyk   Y nw ˆ ¡  dS dS )
a.  
    High-level API to run a series of components.

    This will only return once all the components have stopped
    (including, possibly, after all re-connections have failed if you
    have re-connections enabled). Under the hood, this calls

    XXX fixme for asyncio

    -- if you wish to manage the loop yourself, use the
    :meth:`autobahn.asyncio.component.Component.start` method to start
    each component yourself.

    :param components: the Component(s) you wish to run
    :type components: instance or list of :class:`autobahn.asyncio.component.Component`

    :param start_loop: When ``True`` (the default) this method
        start a new asyncio loop.
    :type start_loop: bool

    :param log_level: a valid log-level (or None to avoid calling start_logging)
    :type log_level: string
    N)Úlevelc              	   “   s¤   �ˆ j d| d� ztj ¡ }W n ty   t ¡ }Y nw |D ]}ztj ¡ }W n ty5   t ¡ }Y nw ||ur>| ¡  q‡ ‡fdd„}tj|Ž }| |¡ d S )NzShutting down due to {signal})Úsignalc              
      s’   zCz|   ¡  W n' tjy   ˆ  d¡ Y n  ty. } zˆ jd|d� W Y d }~nd }~ww W ˆ ¡  d S W ˆ ¡  d S W ˆ ¡  d S ˆ ¡  w )NzAll task cancelledz&Error while shutting down: {exception})Ú	exception)ri   rS   ÚCancelledErrorÚdebugÚ	ExceptionÚerrorÚstop)Úfutr9   ©rp   r.   r   r   Úcancel_all_callbacky  s   €ÿýüþz5run.<locals>.nicely_exit.<locals>.cancel_all_callback)	rz   rS   ÚTaskÚ	all_tasksÚAttributeErrorÚcurrent_taskÚcancelÚgatherÚadd_done_callback)r|   ÚtasksÚtaskr‰   r…   rƒ   r„   r   r   Únicely_exite  s&   €þÿ€

zrun.<locals>.nicely_exitc                      ó   t  ˆ dƒ¡S )NÚSIGINT©rS   rT   r   ©r�   r   r   Ú<lambda>‡  ó    zrun.<locals>.<lambda>c                      r�   )NÚSIGTERMr’   r   r“   r   r   r”   ˆ  r•   c                 S   s   |   ¡  d S r   )r‚   )r.   Úargr   r   r   Údone_callback�  s   zrun.<locals>.done_callback)ra   Zstart_loggingrS   rr   Ú	is_closedÚset_event_loopÚnew_event_loopÚconfigr.   ry   Úadd_signal_handlerr|   r‘   r–   ÚNotImplementedErrorr   Ú_runÚrun_foreverr~   Úclose)Ú
componentsZ
start_loopÚ	log_levelr˜   r   )rp   r.   r�   r   r   9  s2   	!þÿòr   )Trz   )rS   r6   r|   Ú	functoolsr   ra   Zautobahn.asyncio.websocketr   Zautobahn.asyncio.rawsocketr   Zautobahn.wampr   Zautobahn.wamp.exceptionr   Zautobahn.asyncio.wampr   Zautobahn.wamp.serializerr   r	   Ú__all__r   r!   r4   r
   r   r   r   r   r   Ú<module>   s$   ' X