o
    iJ                     @   s   d dl Z d dlZd dlZd dlZd dl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 ddlT 	 dgZd ad	d
 ZG dd dZG dd deZG dd deZG dd dZG dd dZdS )    N   )_logging)ABNF)	parse_url)	WebSocketgetdefaulttimeout)*WebSocketAppc                 C   s   | a d S N)	RECONNECT)reconnectInterval r   I/var/www/edux/Edux_v2/venv/lib/python3.10/site-packages/websocket/_app.pysetReconnect&   s   r   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	DispatcherBasez
    DispatcherBase
    c                 C   s   || _ || _d S r
   )appping_timeout)selfr   r   r   r   r   __init__/   s   
zDispatcherBase.__init__c                 C   s   t | |  d S r
   )timesleepr   secondscallbackr   r   r   timeout3   s   

zDispatcherBase.timeoutc              
   C   sl   zt d|tt f  t| |dd W d S  ty5 } zt d|f  W Y d }~d S d }~ww )Nz9reconnect() - retrying in %s seconds [%s frames in stack]T)reconnectingzUser exited %s)r   infoleninspectstackr   r   KeyboardInterrupt)r   r   reconnectorer   r   r   	reconnect7   s   
zDispatcherBase.reconnectN)__name__
__module____qualname____doc__r   r   r#   r   r   r   r   r   +   s
    r   c                   @   s   e Zd ZdZdd ZdS )
Dispatcherz
    Dispatcher
    c                 C   s\   | j jr,t }|| j jjtj || j}|r| sd S |  |	  | j jsd S d S r
   )
r   keep_running	selectorsDefaultSelectorregistersock
EVENT_READselectr   close)r   r-   read_callbackcheck_callbackselrr   r   r   readD   s   zDispatcher.readN)r$   r%   r&   r'   r5   r   r   r   r   r(   @   s    r(   c                   @   s    e Zd ZdZdd Zdd ZdS )SSLDispatcherz
    SSLDispatcher
    c                 C   s4   | j jr|  }|r| sd S |  | j jsd S d S r
   )r   r)   r/   )r   r-   r1   r2   r4   r   r   r   r5   U   s   zSSLDispatcher.readc                 C   s^   | j jj}| r|gS t }||tj || j}|	  t
|dkr-|d d S d S )Nr   )r   r-   pendingr*   r+   r,   r.   r/   r   r0   r   )r   r-   r3   r4   r   r   r   r/   ]   s   
zSSLDispatcher.selectN)r$   r%   r&   r'   r5   r/   r   r   r   r   r6   Q   s    r6   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )WrappedDispatcherz
    WrappedDispatcher
    c                 C   s$   || _ || _|| _|d|j d S )N   )r   r   
dispatchersignalabort)r   r   r   r:   r   r   r   r   p   s   zWrappedDispatcher.__init__c                 C   s,   | j || | jo| | j| d S  d S r
   )r:   r5   r   r   )r   r-   r1   r2   r   r   r   r5   v   s   zWrappedDispatcher.readc                 C   s   | j || d S r
   )r:   r   r   r   r   r   r   z   s   zWrappedDispatcher.timeoutc                 C   s   |  || d S r
   )r   )r   r   r!   r   r   r   r#   }   s   zWrappedDispatcher.reconnectN)r$   r%   r&   r'   r   r5   r   r#   r   r   r   r   r8   l   s    r8   c                   @   s   e Zd ZdZ								dddZejfddZdd	 Zd
d Z	dd Z
dd Z									dddZdddZdd Zdd ZdS )r	   z_
    Higher level of APIs are provided. The interface is like JavaScript WebSocket object.
    NTc                 C   s   || _ |dur	|ng | _|| _|| _|| _|| _|| _|| _|| _|| _	|	| _
d| _|| _d| _d| _d| _d| _d| _d| _d| _d| _|| _|| _d| _dS )a	  
        WebSocketApp initialization

        Parameters
        ----------
        url: str
            Websocket url.
        header: list or dict
            Custom header for websocket handshake.
        on_open: function
            Callback object which is called at opening websocket.
            on_open has one argument.
            The 1st argument is this class object.
        on_message: function
            Callback object which is called when received data.
            on_message has 2 arguments.
            The 1st argument is this class object.
            The 2nd argument is utf-8 data received from the server.
        on_error: function
            Callback object which is called when we get error.
            on_error has 2 arguments.
            The 1st argument is this class object.
            The 2nd argument is exception object.
        on_close: function
            Callback object which is called when connection is closed.
            on_close has 3 arguments.
            The 1st argument is this class object.
            The 2nd argument is close_status_code.
            The 3rd argument is close_msg.
        on_cont_message: function
            Callback object which is called when a continuation
            frame is received.
            on_cont_message has 3 arguments.
            The 1st argument is this class object.
            The 2nd argument is utf-8 string which we get from the server.
            The 3rd argument is continue flag. if 0, the data continue
            to next frame data
        on_data: function
            Callback object which is called when a message received.
            This is called before on_message or on_cont_message,
            and then on_message or on_cont_message is called.
            on_data has 4 argument.
            The 1st argument is this class object.
            The 2nd argument is utf-8 string which we get from the server.
            The 3rd argument is data type. ABNF.OPCODE_TEXT or ABNF.OPCODE_BINARY will be came.
            The 4th argument is continue flag. If 0, the data continue
        keep_running: bool
            This parameter is obsolete and ignored.
        get_mask_key: function
            A callable function to get new mask keys, see the
            WebSocket.set_mask_key's docstring for more information.
        cookie: str
            Cookie value.
        subprotocols: list
            List of available sub protocols. Default is None.
        socket: socket
            Pre-initialized stream socket.
        NFr    )urlheadercookieon_open
on_messageon_dataon_erroron_closeon_pingon_pongon_cont_messager)   get_mask_keyr-   last_ping_tmlast_pong_tmping_thread	stop_pingping_intervalr   ping_payloadsubprotocolsprepared_sockethas_errored)r   r>   r?   rA   rB   rD   rE   rF   rG   rH   r)   rI   r@   rP   rC   socketr   r   r   r      s0   B
zWebSocketApp.__init__c                 C   s$   | j r| j ||dkrtddS )a  
        send message

        Parameters
        ----------
        data: str
            Message to send. If you set opcode to OPCODE_TEXT,
            data must be utf-8 string or unicode.
        opcode: int
            Operation code of data. Default is OPCODE_TEXT.
        r   zConnection is already closed.N)r-   send"WebSocketConnectionClosedException)r   dataopcoder   r   r   rT      s
   zWebSocketApp.sendc                 K   s,   d| _ | jr| jjdi | d| _dS dS )z-
        Close websocket connection.
        FNr   )r)   r-   r0   )r   kwargsr   r   r   r0      s
   
zWebSocketApp.closec                 C   s<   d | _ | _t | _tj| jd| _d| j_| j	  d S )Nr   )targetT)
rJ   rK   	threadingEventrM   Thread
_send_pingrL   daemonstartr   r   r   r   _start_ping_thread   s
   
zWebSocketApp._start_ping_threadc                 C   s<   | j r| j   | jr| j r| jd d | _| _d S )N   r   )rM   setrL   is_alivejoinrJ   rK   r`   r   r   r   _stop_ping_thread  s
   
zWebSocketApp._stop_ping_threadc              
   C   s   | j | jr	d S | j | jsH| jr?t | _ztd | j| j	 W n t
y> } ztd| W Y d }~nd }~ww | j | jrd S d S )NzSending pingzFailed to send ping: %s)rM   waitrN   r-   r   rJ   r   debugpingrO   	Exception)r   exr   r   r   r]   
  s   

zWebSocketApp._send_pingr   r=   Fc                    s`  du rt |dur|dkrtd|dur|dk rtd|r*|r*||kr*tds.g s2i jr9td|_|_|_d_dfdd		d 	
fdd	fddfdd dfdd	t|t	j
d   srjrtdtt    jsjS )a  
        Run event loop for WebSocket framework.

        This loop is an infinite loop and is alive while websocket is available.

        Parameters
        ----------
        sockopt: tuple
            Values for socket.setsockopt.
            sockopt must be tuple
            and each element is argument of sock.setsockopt.
        sslopt: dict
            Optional dict object for ssl socket option.
        ping_interval: int or float
            Automatically send "ping" command
            every specified period (in seconds).
            If set to 0, no ping is sent periodically.
        ping_timeout: int or float
            Timeout (in seconds) if the pong message is not received.
        ping_payload: str
            Payload message to send with each ping.
        http_proxy_host: str
            HTTP proxy host name.
        http_proxy_port: int or str
            HTTP proxy port. If not set, set to 80.
        http_no_proxy: list
            Whitelisted host names that don't use the proxy.
        http_proxy_timeout: int or float
            HTTP proxy timeout, default is 60 sec as per python-socks.
        http_proxy_auth: tuple
            HTTP proxy auth information. tuple of username and password. Default is None.
        skip_utf8_validation: bool
            skip utf8 validation.
        host: str
            update host header.
        origin: str
            update origin header.
        dispatcher: Dispatcher object
            customize reading data from socket.
        suppress_origin: bool
            suppress outputting origin header.
        proxy_type: str
            type of proxy from: http, socks4, socks4a, socks5, socks5h
        reconnect: int
            delay interval when reconnecting

        Returns
        -------
        teardown: bool
            False if the `WebSocketApp` is closed or caught KeyboardInterrupt,
            True if any other exception was raised during a loop.
        Nr   zEnsure ping_timeout > 0zEnsure ping_interval >= 0z#Ensure ping_interval > ping_timeoutzsocket is already openedTc                    sN       d _ jr j   | r| nd\}}d _  j|| dS )a  
            Tears down the connection.

            Parameters
            ----------
            close_frame: ABNF frame
                If close_frame is set, the on_close handler is invoked
                with the statusCode and reason from the provided frame.
            FN)rf   r)   r-   r0   _get_close_args	_callbackrE   )close_frameclose_status_codeclose_reasonr`   r   r   teardowni  s   

z*WebSocketApp.run_forever.<locals>.teardownFc                    s   | r
j r
j   tjjd udd_ j t  z7j jjj	j
j	
jd td jrF  j j j   W d S  tttttfyt } z||  W Y d }~d S d }~ww )NT)sockoptssloptfire_cont_frameskip_utf8_validationenable_multithread)r?   r@   http_proxy_hosthttp_proxy_porthttp_no_proxyhttp_proxy_authhttp_proxy_timeoutrP   hostoriginsuppress_origin
proxy_typerS   zWebsocket connected)r-   shutdownr   rI   rH   
settimeoutr   connectr>   r?   r@   rP   rQ   r   r   rN   ra   rm   rA   r5   rU   ConnectionRefusedErrorr    
SystemExitrj   )r   r"   )checkr:   handleDisconnectr|   ry   rz   rw   rx   r{   r}   r   r5   r   ru   rr   rs   r~   r   r   setSock  s8   


	z)WebSocketApp.run_forever.<locals>.setSockc               
      s6  j s S z
jd\} }W n ttfy, } z r&|W  Y d }~S |d }~ww | tjkr6|S | tjkrEj	|j
 dS | tjkrYt _j|j
 dS | tjkryjryj|j
|j|j j|j
|j dS |j
}| tjkrs|d}j||jd j| dS )NTutf-8)r)   r-   recv_data_framerU   r    r   OPCODE_CLOSEOPCODE_PINGrm   rF   rV   OPCODE_PONGr   rK   rG   OPCODE_CONTrH   rC   rW   finOPCODE_TEXTdecoderB   )op_codeframer"   rV   )custom_dispatcherr   r   ru   rq   r   r   r5     sB   



	
z&WebSocketApp.run_forever.<locals>.readc                     sZ    j r+t  j  j k}  j j dk } j j  j k} jr+| r+|s'|r+tddS )Nr   zping/pong timed outT)r   r   rJ   rK   WebSocketTimeoutException)has_timeout_expired$has_pong_not_arrived_after_last_pinghas_pong_arrived_too_later`   r   r   r     s   z'WebSocketApp.run_forever.<locals>.checkc                    s   d_   |sj|  t| ttfr   r;td|    r9t	dt
t    d S d S td|     d S )NTz%s - reconnectz8Calling custom dispatcher reconnect [%s frames in stack]z%s - goodbye)rR   rf   rm   rD   
isinstancer    r   r   r   rh   r   r   r   r#   error)r"   r   )r   r:   r#   r   r   rq   r   r   r     s   
z2WebSocketApp.run_forever.<locals>.handleDisconnectrb   z1Calling dispatcher reconnect [%s frames in stack]r
   )F)r   WebSocketExceptionr-   rN   r   rO   r)   boolcreate_dispatcherr   r>   r   rh   r   r   r   r#   rR   )r   rr   rs   rN   r   rO   rw   rx   ry   rz   r{   ru   r|   r}   r:   r~   r   r#   r   )r   r   r:   r   r|   ry   rz   rw   rx   r{   r}   r   r5   r#   r   r   ru   rr   rs   r~   rq   r   run_forever  s@   >. !zWebSocketApp.run_foreverc                 C   s0   |rt | ||S |pd}|rt| |S t| |S )N
   )r8   r6   r(   )r   r   r:   is_sslr   r   r   r   r     s   

zWebSocketApp.create_dispatcherc                 C   sb   | j r|s	ddgS |jr-t|jdkr-d|jd  |jd  }|jdd d}||gS ddgS )z
        _get_close_args extracts the close code and reason from the close body
        if it exists (RFC6455 says WebSocket Connection Close Code is optional)
        Nr9      r   r   r   )rE   rV   r   r   )r   rn   ro   reasonr   r   r   rl     s   
zWebSocketApp._get_close_argsc              
   G   sx   |r:z|| g|R   W d S  t y9 } z td|| | jr.| | | W Y d }~d S W Y d }~d S d }~ww d S )Nzerror from callback {}: {})rj   r   r   formatrD   )r   r   argsr"   r   r   r   rm     s   zWebSocketApp._callback)NNNNNNNNTNNNNN)NNr   Nr=   NNNNNFNNNFNN)NF)r$   r%   r&   r'   r   r   r   rT   r0   ra   rf   r]   r   r   rl   rm   r   r   r   r   r	      s<    
\	
 
V	)r   r*   sysrZ   r   	tracebackr=   r   _abnfr   _urlr   _corer   r   _exceptions__all__r   r   r   r(   r6   r8   r	   r   r   r   r   <module>   s(    