U
    •uÄcD>  ã                   @   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 | ]}|ˆ krˆ   |¡s|‘qS © )Úadd)Ú.0Úx©Úseenr   ú^/var/www/html/CISBACKEND/school/venv/lib/python3.8/site-packages/autobahn/asyncio/component.pyÚ
<listcomp>3   s      
 z _unique_list.<locals>.<listcomp>)Ú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�}n2|j dkrNt|jd ƒ}t||d�}ndsZtdƒ‚|j	 
¡ D ]|\}}z|jf ||iŽ W qd ttfk
rÞ   z|jf t|ƒ|iŽ W n, ttfk
rØ   td |j ||¡ƒ‚Y nX Y qdX qd|S )	z3
    Create a WAMP-over-XXX transport factory.
    Z	websocket)ÚurlÚserializersÚproxyZ	rawsocketr   )Ú
serializerFúshould not arrive herez"Unknown {} transport option: {}={})Útyper   r   r"   r$   r	   r#   r   ÚAssertionErrorÚoptionsÚitemsZsetProtocolOptionsÚ	TypeErrorÚKeyErrorr!   Ú
ValueErrorÚformat)ÚloopÚ	transportÚsession_factoryr#   Úfactoryr%   ÚkÚvr   r   r   Ú_create_transport_factory;   s2    
ü

ÿÿr5   c                   @   sF   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.
        )Ú
isinstanceÚsslÚSSLError)ÚselfÚer   r   r   Ú_is_ssl_errorr   s    zComponent._is_ssl_errorc                 C   sN   t |tƒrBd|krJ|d }t |ttfƒr*qJt |tjƒr8qJtdƒ‚ntdƒ‚d S )NÚtlsz?'tls' configuration must be a dict, bool or SSLContext instancezI'endpoint' configuration must be a dict or IStreamClientEndpoint provider)r6   ÚdictÚboolr7   Ú
SSLContextr-   )r9   Ú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�rH|j d
d¡}	|	dkr°td |	¡ƒ‚|jd }
t|
ƒtkrØtd t|
ƒ¡ƒ‚|jd }t|ƒtk�rtd t|ƒ¡ƒ‚|j dd¡}t|ƒtk�r0td t|ƒ¡ƒ‚|j dd¡}d}|�rt|tƒ�rÖ| ¡ D ]}|dk�r\td |¡ƒ‚�q\| d|
¡}t|ƒtk�r¤td |¡ƒ‚| dd¡}|}d}|dk	�rtjtjj|d�}n<t|tjƒ�rê|
}n(|dk�r |�r|
}ntd t|ƒ¡ƒ‚|j||
|||d�}t	 
t	j||d�¡}|  |||¡S |jd dk�r¤|jd }t|j dd¡ƒ}|j||d�}t	 
t	j||d�¡}|  |||¡S d�s²td ƒ‚dS )!z?
        Create and connect a WAMP-over-XXX transport.
        Útimeouté
   z<invalid type {} for timeout in client endpoint configurationÚhostÚport)Úprotocol_factoryrD   rE   )rB   r'   ZtcpÚversioné   )rH   é   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' configrJ   zAinvalid type {} for hostname in TLS client endpoint configurationrK   T)ÚpurposeÚcafile)FTz4unknown type {} for "tls" configuration in transport)rF   rD   rE   r7   Úserver_hostnameÚunixÚpath)rF   rP   Fr&   )r5   r$   r@   Úgetr'   Úintr-   r.   Úcreate_connectionÚasyncioÚensure_futureÚwait_forÚ_wrap_connection_futureÚstrr6   r=   Úkeysr7   Úcreate_default_contextÚPurposeÚSERVER_AUTHr?   ÚRuntimeErrorÚcreate_unix_connectionr(   )r9   r/   r0   r1   Údoner2   rB   ÚfZtime_frG   rD   rE   r<   Ztls_hostnamer3   rJ   Z
cert_fnamerP   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 ˆ¡s6t|ddƒ}t ˆt|ƒ¡ d S |j‰ tˆ ƒ‡‡ fdd„ƒ}||_d S )NZ_onclose_reasonzConnection already closedc                    s2   ˆ| ƒ}t  ˆ ¡s.| d kr"tdƒ} t  ˆ | ¡ |S )Nzfailed to complete connection)ÚtxaioÚ	is_calledr   Úreject)ÚfailZrtn)r_   Úorigr   r   Úlost  s    
zKComponent._wrap_connection_future.<locals>.on_connect_success.<locals>.lost)Ú
is_closingrb   rc   Úgetattrrd   r   Úconnection_lostr   )Úresultr0   ÚprotoÚreasonrg   )r_   )rf   r   Úon_connect_successð   s    

z=Component._wrap_connection_future.<locals>.on_connect_successc                    s   ˆ j d7  _ t ˆ | ¡ d S )Nr   )Zconnect_failuresrb   rd   )Úerr©r_   r0   r   r   Úon_connect_failure  s    z=Component._wrap_connection_future.<locals>.on_connect_failure)rb   Zadd_callbacks)r9   r0   r_   Zconn_frn   rq   r   rp   r   rW   î   s
    (z!Component._wrap_connection_futureNc                 C   s(   |dk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ÚwarnrT   Úget_event_loopÚ_start)r9   r/   r   r   r   Ústart$  s    zComponent.start)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rb   Úmake_loggerrr   r   r1   r;   rA   ra   rW   rv   r   r   r   r   r
   b   s   b6r
   TÚinfoc                    sè   |dk	rt j|d� t ¡ ‰ˆ ¡ rBt t ¡ ¡ t ¡ ‰ˆt j_t  	¡ ‰ ‡ ‡fdd„‰z0ˆ 
tj‡fdd„¡ ˆ 
tj‡fdd„¡ W n tk
rœ   Y nX dd	„ }t ˆ| |¡ |räzˆ ¡  W n tjk
rÚ   Y nX ˆ ¡  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k
r8   t ¡ }Y nX |D ]@}ztj ¡ }W n tk
rl   t ¡ }Y nX ||k	r>| ¡  q>‡ ‡fdd„}tj|Ž }| |¡ d S )NzShutting down due to {signal})Úsignalc              
      sp   z`z|  ¡  W nN tjk
r.   ˆ  d¡ Y n0 tk
r\ } zˆ jd|d� W 5 d }~X Y nX W 5 ˆ  ¡  X d S )NzAll task cancelledz&Error while shutting down: {exception})Ú	exception)Ústoprk   rT   ÚCancelledErrorÚdebugÚ	ExceptionÚerror)Úfutr:   ©rr   r/   r   r   Úcancel_all_callbacky  s    $z5run.<locals>.nicely_exit.<locals>.cancel_all_callback)	r|   rT   Ú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                      s   t  ˆ dƒ¡S )NÚSIGINT©rT   rU   r   ©r‘   r   r   Ú<lambda>‡  ó    zrun.<locals>.<lambda>c                      s   t  ˆ dƒ¡S )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)rb   Zstart_loggingrT   rt   Ú	is_closedÚset_event_loopÚnew_event_loopÚconfigr/   r{   Úadd_signal_handlerr~   r’   r—   ÚNotImplementedErrorr   Ú_runÚrun_foreverr�   Úclose)Ú
componentsZ
start_loopZ	log_levelr™   r   )rr   r/   r‘   r   r   9  s,    	!r   )Tr|   )rT   r7   r~   Ú	functoolsr   rb   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!   r5   r
   r   r   r   r   r   Ú<module>   s"   ' X