o
    èó·i;  ã                   @   sJ  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
 d dlmZ z dZd d	lmZ d d
lmZmZmZ d dlmZ d dlmZ W n eyU   dZY nw 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!m"Z" dZ#dd„ Z$dd„ Z%dd„ Z&dd„ Z'G dd„ dej(ƒZ(d%d ee( d!e)d"e*fd#d$„Z+dS )&é    )Úwraps)ÚList)ÚIStreamClientEndpoint)ÚUNIXClientEndpoint)ÚTCP4ClientEndpoint)ÚFailure)ÚReactorNotRunningT)ÚSSL4ClientEndpoint)ÚoptionsForClientTLSÚCertificateOptionsÚCertificate)ÚIOpenSSLClientConnectionCreator)ÚSSLFN)ÚWampWebSocketClientFactory)ÚWampRawSocketClientFactory)Ú	component)Ú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/twisted/component.pyÚ
<listcomp>B   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>G   s   € z._camel_case_from_snake_case.<locals>.<genexpr>é   )ÚsplitÚjoin)ZsnakeÚpartsr   r   r   Ú_camel_case_from_snake_caseE   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)ÚreactorÚ	transportÚsession_factoryr.   Úfactoryr0   ÚkÚvr   r   r   Ú_create_transport_factoryJ   s8   
ü


ÿÿÿýûr?   c                 C   sØ  t  |¡rt |ƒ}|S |d dk�rL| dd¡}|dvr#td |¡ƒ‚|d }t|ƒtkr6td t|ƒ¡ƒ‚|d	 }t|ƒtkrItd
 t|ƒ¡ƒ‚| dd¡}t|ƒtkr^td t|ƒ¡ƒ‚| dd¡}|ròtslt	dƒ‚t
 |¡rvt
|ƒ}nat|tƒr½| ¡ D ]}	|	dvrŒtd |	¡ƒ‚q| d|¡}
t|
ƒtkr td |
¡ƒ‚d}| dd¡}|dur¶t t|dƒ ¡ ¡}t|
|d�}nt|tƒrÅ|}n|du rÎt|ƒ}n	t	d t|ƒ¡ƒ‚|dkræt| ||||d�}|S |dkrît	dƒ‚J dƒ‚| d¡�rzd dl}| ||¡}W |S  t�y   t	d! |¡ƒ‚w |dk�r$t| |||d�}|S |dk�rHzd d"lm} W n t�y=   t	d#ƒ‚w || |||d�}|S J dƒ‚|d d$k�rh|d% }t| dd¡ƒ}t| ||d�}|S J dƒ‚)&zI
    Create a Twisted client endpoint for a WAMP-over-XXX transport.
    r2   ÚtcpÚversioné   )rB   é   z6invalid IP version {} in client endpoint configurationÚhostz9invalid type {} for host in client endpoint configurationÚportz9invalid type {} for port in client endpoint configurationÚtimeouté
   z<invalid type {} for timeout in client endpoint configurationÚtlsNzKTLS configured in transport, but TLS support is not installed (eg OpenSSL?))ÚhostnameÚ
trust_rootz Invalid key '{}' in 'tls' configrI   zAinvalid type {} for hostname in TLS client endpoint configurationrJ   Úr)Z	trustRootTz4unknown type {} for "tls" configuration in transport)rF   rC   zTLS on IPv6 not implementedFr1   z.onionr   zC{} appears to be a Tor Onion service, but txtorcon is not installed)ÚTCP6ClientEndpointz.IPv6 is not supported (please upgrade Twisted)ÚunixÚpath)r   Ú
providedByÚgetr7   r8   r2   ÚstrÚintÚ_TLSÚRuntimeErrorr   Ú
isinstanceÚdictÚkeysr   ZloadPEMÚopenÚreadr
   r   r	   ÚendswithÚtxtorconZTorClientEndpointÚImportErrorr   Útwisted.internet.endpointsrL   r   )r9   Zendpoint_configÚendpointrA   rD   rE   rF   rH   Úcontextr=   rI   rJ   Z
cert_fnamer[   rL   rN   r   r   r   Ú_create_transport_endpointq   s˜   
a¢


ÿ

)Øæÿÿÿ

îÿõþr`   c                   @   s@   e Zd ZdZe ¡ Ze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 rt|tjƒS dS )zÂ
        Internal helper.

        This is so we can just return False if we didn't import any
        TLS/SSL libraries. Otherwise, returns True if this is an
        OpenSSL.SSL.Error
        FN)rS   rU   r   ÚError)ÚselfÚer   r   r   Ú_is_ssl_errorê   s   zComponent._is_ssl_errorc                 C   sj   t  |¡rd S t|tƒr1d|v r/|d }t|ttfƒrd S t |¡r$d S t|tƒr+d S tdƒ‚d S tdƒ‚)NrH   zb'tls' configuration must be a dict, CertificateOptions or IOpenSSLClientConnectionCreator providerzI'endpoint' configuration must be a dict or IStreamClientEndpoint provider)r   rO   rU   rV   Úboolr   r   r7   )rb   r^   rH   r   r   r   Ú_check_native_endpointö   s$   



ÿ÷ÿz Component._check_native_endpointc           
         s‚   t |ˆ|ƒ}ˆjrt|dˆjd ˆjd dœƒ}nt|ˆjƒ}| |¡}‡ fdd„}‡ ‡fdd„}	t ||d	¡ t |d	|	¡ |S )
zö
        Create and connect a WAMP-over-XXX transport.

        :param done: is a Deferred/Future from the parent which we
            should signal upon error if it is not done yet (XXX maybe an
            "on_error" callable instead?)
        r@   rD   rE   )r2   rD   rE   c                    s&   | j ‰ tˆ ƒ‡‡ fdd„ƒ}|| _ d S )Nc                    s"   ˆ| ƒ}t  ˆ ¡st  ˆ | ¡ |S r$   )ÚtxaioZ	is_calledÚreject)ZfailZrtn)ÚdoneÚorigr   r   Úlost-  s   
zFComponent._connect_transport.<locals>.on_connect_success.<locals>.lost)ZconnectionLostr   )Úprotork   )ri   )rj   r   Úon_connect_success#  s   
z8Component._connect_transport.<locals>.on_connect_successc                    s   ˆ j d7  _ t ˆ | ¡ d S )Nr(   )Zconnect_failuresrg   rh   )Úerr©ri   r:   r   r   Úon_connect_failure5  s   z8Component._connect_transport.<locals>.on_connect_failureN)r?   r/   r`   r^   Úconnectrg   Zadd_callbacks)
rb   r9   r:   r;   ri   Ztransport_factoryZtransport_endpointÚdrm   rp   r   ro   r   Ú_connect_transport  s    ýþ	
zComponent._connect_transportNc                 C   s,   |du r| j  d¡ ddlm} | 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 Deferred that fires (with ``None``) when we are
            "done" or with a Failure if something went wrong.
        NzUsing default reactorr   )r9   )Úloop)ÚlogÚwarnZtwisted.internetr9   Ú_start)rb   r9   r   r   r   Ústart>  s   zComponent.startr$   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__rg   Úmake_loggerru   r   r;   rd   rf   rs   rx   r   r   r   r   r   Ú   s    1r   ÚinfoÚ
componentsÚ	log_levelÚstop_at_closec                    sR   ddl m} |durtj|d� t ¡ ‰ |r‡ fdd„}nd}|tj| |fƒ 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
    :meth:`twisted.internet.reactor.run` -- if you wish to manage the
    reactor loop yourself, use the
    :meth:`autobahn.twisted.component.Component.start` method to start
    each component yourself.

    :param components: the Component(s) you wish to run
    :param log_level: a valid log-level (or None to avoid calling start_logging)
    :param stop_at_close: Flag to control whether to stop the reactor when done.
    r   )ÚreactN)Úlevelc                    sJ   t |tƒr#ˆ jd|d� zˆ  d¡ |  ¡  W d S  ty"   Y d S w d S )Nz#Something went wrong: {log_failure})ZfailurezStopping reactor ..)rU   r   Úerrorrv   Ústopr   )r9   Úarg©ru   r   r   Údone_callbackq  s   

ÿûzrun.<locals>.done_callback)Ztwisted.internet.taskr‚   rg   Zstart_loggingr}   r   Ú_run)r   r€   r�   r‚   rˆ   r   r‡   r   r   R  s   	r   )r~   T),Ú	functoolsr   Útypingr   Ztwisted.internet.interfacesr   r]   r   r   Ztwisted.python.failurer   Ztwisted.internet.errorr   rS   r	   Ztwisted.internet.sslr
   r   r   r   ZOpenSSLr   r\   rg   Zautobahn.twisted.websocketr   Zautobahn.twisted.rawsocketr   Zautobahn.wampr   Zautobahn.twisted.wampr   Zautobahn.wamp.serializerr   r   Ú__all__r!   r,   r?   r`   r   rQ   re   r   r   r   r   r   Ú<module>   s:   ÿ'i x