o
    >hD>                     @   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   z/var/www/vedio/testing/chatpythonscript.ninositsolution.com/env/lib/python3.10/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)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.
    	websocket)urlserializersproxy	rawsocketr   )
serializerFshould not arrive herez"Unknown {} transport option: {}={}Nr   )typer   r   r$   r&   r	   r%   r   optionsitemssetProtocolOptions	TypeErrorKeyErrorr"   
ValueErrorformat)loop	transportsession_factoryr%   factoryr(   kvr   r   r   _create_transport_factory;   s8   



r8   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.
        )
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)r9   dictboolr:   
SSLContextr0   )r<   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rtdt||jdd}t|tkrtdt||jdd}d}|rt|tr| D ]}|dvrtd|q|d|
}t|tkrtd||dd}|}d}|durt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_factoryrG   rH   )rE   r*   tcpversion   )rL      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' configrN   zAinvalid type {} for hostname in TLS client endpoint configurationrO   T)purposecafile)FTz4unknown type {} for "tls" configuration in transport)rI   rG   rH   r:   server_hostnameunixpath)rI   rT   Fr)   )r8   r&   rC   getr*   intr0   r1   create_connectionasyncioensure_futurewait_for_wrap_connection_futurestrr9   r@   keysr:   create_default_contextPurposeSERVER_AUTHrB   RuntimeErrorcreate_unix_connection)r<   r2   r3   r4   doner5   rE   ftime_frK   rG   rH   r?   tls_hostnamer6   rN   
cert_fnamerT   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 )N_onclose_reasonzConnection already closedc                    s2   | }t  s| d u rtd} t  |  |S )Nzfailed to complete connection)txaio	is_calledr   reject)failrtn)rc   origr   r   lost  s   
zKComponent._wrap_connection_future.<locals>.on_connect_success.<locals>.lost)
is_closingrj   rk   getattrrl   r   connection_lostr   )resultr3   protoreasonrp   )rc   )ro   r   on_connect_success   s   


z=Component._wrap_connection_future.<locals>.on_connect_successc                    s    j d7  _ t |  d S )Nr   )connect_failuresrj   rl   )errrc   r3   r   r   on_connect_failure  s   z=Component._wrap_connection_future.<locals>.on_connect_failure)rj   add_callbacks)r<   r3   rc   conn_frw   r{   r   rz   r   r[      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)r2   )logwarnrX   get_event_loop_start)r<   r2   r   r   r   start$  s   zComponent.startr   )__name__
__module____qualname____doc__rj   make_loggerr~   r   r4   r>   rD   rh   r[   r   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)rt   rX   CancelledErrordebug	Exceptionerrorstop)futr=   r~   r2   r   r   cancel_all_callbacky  s   z5run.<locals>.nicely_exit.<locals>.cancel_all_callback)	r   rX   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rX   rY   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   )r2   argr   r   r   done_callback  s   zrun.<locals>.done_callback)rj   start_loggingrX   r   	is_closedset_event_loopnew_event_loopconfigr2   r   add_signal_handlerr   r   r   NotImplementedErrorr   _runrun_foreverr   close)
components
start_loop	log_levelr   r   )r~   r2   r   r   r   9  s2   	!r   )Tr   )rX   r:   r   	functoolsr   rj   autobahn.asyncio.websocketr   autobahn.asyncio.rawsocketr   autobahn.wampr   autobahn.wamp.exceptionr   autobahn.asyncio.wampr   autobahn.wamp.serializerr   r	   __all__r   r"   r8   r
   r   r   r   r   r   <module>   s$   ' X