U
    l[?4                     @   s   d Z 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Zddlm	Z	 ddl
mZmZ ddlT ddlmZ dgZG d	d
 d
ZG dd dZG dd deZdS )aL  
websocket - WebSocket client library for Python

Copyright (C) 2010 Hiroki Ohtani(liris)

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA  02110-1335  USA

    N   )ABNF)	WebSocketgetdefaulttimeout)*)_loggingWebSocketAppc                   @   s   e Zd Zdd Zdd ZdS )
Dispatcherc                 C   s   || _ || _d S Nappping_timeoutselfr   r    r   0/usr/lib/python3/dist-packages/websocket/_app.py__init__,   s    zDispatcher.__init__c                 C   sB   | j jjr>t| j jjfdd| j\}}}|r6| s6q>|  q d S Nr   )r   sock	connectedselectr   )r   r   read_callbackcheck_callbackrwer   r   r   read0   s    

   
zDispatcher.readN)__name__
__module____qualname__r   r   r   r   r   r   r	   +   s   r	   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )SSLDispactherc                 C   s   || _ || _d S r
   r   r   r   r   r   r   :   s    zSSLDispacther.__init__c                 C   s*   | j jjr&|  }|r| sq&|  q d S r
   )r   r   r   r   )r   r   r   r   r   r   r   r   r   >   s    
zSSLDispacther.readc                 C   s6   | j jj}| r|gS t|fdd| j\}}}|S r   )r   r   pendingr   r   )r   r   r   r   r   r   r   r   r   F   s
    
zSSLDispacther.selectN)r   r   r   r   r   r   r   r   r   r   r    9   s   r    c                   @   sZ   e Zd ZdZdddZejfddZdd	 Zd
d Z	dddZ
dd Zdd Zdd ZdS )r   zc
    Higher level of APIs are provided.
    The interface is like JavaScript WebSocket object.
    NTc                 C   sv   || _ |dk	r|ng | _|| _|| _|| _|| _|| _|| _|| _|| _	|	| _
d| _|| _d| _d| _d| _|| _dS )a  
        url: websocket url.
        header: custom header for websocket handshake.
        on_open: callable object which is called at opening websocket.
          this function has one argument. The argument is this class object.
        on_message: callable 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 string which we get from the server.
        on_error: callable 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: callable object which is called when closed the connection.
         this function has one argument. The argument is this class object.
        on_cont_message: callback object which is called when receive continued
         frame data.
         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: 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: this parameter is obosleted and ignored it.
        get_mask_key: a callable to produce new mask keys,
          see the WebSocket.set_mask_key's docstring for more information
        subprotocols: array of available sub protocols. default is None.
        NFr   )urlheadercookieon_open
on_messageon_dataon_erroron_closeon_pingon_pongon_cont_messagekeep_runningget_mask_keyr   last_ping_tmlast_pong_tmsubprotocols)r   r"   r#   r%   r&   r(   r)   r*   r+   r,   r-   r.   r$   r1   r'   r   r   r   r   T   s"    *zWebSocketApp.__init__c                 C   s$   | j r| j ||dkr tddS )z
        send message.
        data: message to send. If you set opcode to OPCODE_TEXT,
              data must be utf-8 string or unicode.
        opcode: operation code of data. default is OPCODE_TEXT.
        r   zConnection is already closed.N)r   sendZ"WebSocketConnectionClosedException)r   dataopcoder   r   r   r2      s    zWebSocketApp.sendc                 K   s$   d| _ | jr | jjf | d| _dS )z-
        close websocket connection.
        FN)r-   r   close)r   kwargsr   r   r   r5      s    zWebSocketApp.closec              
   C   sj   | |sft | _| jr z| j  W q  tk
rb } ztd| W Y qfW 5 d }~X Y q X q d S )Nz send_ping routine terminated: {})	waittimer/   r   Zping	Exceptionr   Zwarningformat)r   Zintervaleventexr   r   r   
_send_ping   s    

zWebSocketApp._send_pingr   Fc                    s  dk	rrdkrdr0|r0|kr0t d|dkr<g }|dkrHi }jrVt ddd d_d_d_ fddztj||jrdpd|	|rdndd	_jt	  jj
jjj||||j|
||d
 |s}j |r4t tjj|fdd   fdd}fdd}|jj|| W nL tttfk
r } z&j| t|tr   W 5 d}~X Y nX dS )a  
        run event loop for WebSocket framework.
        This loop is infinite loop and is alive during websocket is available.
        sockopt: values for socket.setsockopt.
            sockopt must be tuple
            and each element is argument of sock.setsockopt.
        sslopt: ssl socket optional dict.
        ping_interval: automatically send "ping" command
            every specified period(second)
            if set to 0, not send automatically.
        ping_timeout: timeout(second) if the pong message is not received.
        http_proxy_host: http proxy host name.
        http_proxy_port: http proxy port. If not set, set to 80.
        http_no_proxy: host names, which doesn't use proxy.
        skip_utf8_validation: skip utf8 validation.
        host: update host header.
        origin: update origin header.
        dispatcher: customize reading data from socket.
        supress_origin: suppress outputting origin header.
        Nr   z#Ensure ping_interval > ping_timeoutzsocket is already openedTc                     sb   r  r    d_jr2j   r@ jnd } jj	f|   d _d S )NF)
ZisAlivesetjoinr-   r   r5   _get_close_argsr3   	_callbackr)   )Z
close_args)close_framer;   r   threadr   r   teardown   s    
z*WebSocketApp.run_forever.<locals>.teardownF)sockoptssloptZfire_cont_frameskip_utf8_validationZenable_multithread)
r#   r$   http_proxy_hosthttp_proxy_porthttp_no_proxyhttp_proxy_authr1   hostoriginsupress_origin)targetargsc                     s    j s S  jd\} }| tjkr0|} S | tjkrL  j|j n| tj	krrt

  _  j|j n| tjkr jr  j|j|j|j   j|j|j nB|j}tjr| tjkr|d}  j||jd   j| dS )NTutf-8)r-   r   Zrecv_data_framer   ZOPCODE_CLOSEZOPCODE_PINGrA   r*   r3   ZOPCODE_PONGr8   r0   r+   ZOPCODE_CONTr,   r'   r4   ZfinsixZPY3OPCODE_TEXTdecoder&   )Zop_codeframerB   r3   )r   rD   r   r   r     s4    



  
z&WebSocketApp.run_forever.<locals>.readc                     sT    rPt   j  k} jj dk }jj  k}jrP| rP|sH|rPtddS )Nr   zping/pong timed outT)r8   r/   r0   ZWebSocketTimeoutException)Zhas_timeout_expiredZ$has_pong_not_arrived_after_last_pingZhas_pong_arrived_too_late)r   r   r   r   check  s    z'WebSocketApp.run_forever.<locals>.check)ZWebSocketExceptionr   r-   r/   r0   r   r.   r,   Z
settimeoutr   Zconnectr"   r#   r$   r1   create_dispatcherrA   r%   	threadingZEventZThreadr=   Z	setDaemonstartr   r9   KeyboardInterrupt
SystemExitr(   
isinstance)r   rE   rF   Zping_intervalr   rH   rI   rJ   rK   rG   rL   rM   
dispatcherrN   r   rV   r   r   )rB   r;   r   r   rD   rC   r   run_forever   st      
      
 
zWebSocketApp.run_foreverc                 C   s&   |pd}| j  rt| |S t| |S )N
   )r   Zis_sslr    r	   )r   r   Ztimeoutr   r   r   rW   0  s    

zWebSocketApp.create_dispatcherc                 C   s   t jdk r,| jr&tt| jjdkrLg S n | jrHtt| jjdkrLg S |rt|dkrdt	|dd  t	|dd  }|dd 
d}||gS ddgS )	z this functions extracts the code, reason from the close body
        if they exists, and if the self.on_close except three arguments )   r   r`         r   r   NrQ   )sysversion_infor)   leninspectZ
getargspecrP   ZgetfullargspecrR   Zbyte2intrT   )r   r3   codereasonr   r   r   r@   7  s    
(zWebSocketApp._get_close_argsc              
   G   s   |rz&t |r||  n|| f|  W nT tk
r~ } z6td|| t rnt \}}}t	
| W 5 d }~X Y nX d S )Nzerror from callback {}: {})rf   Zismethodr9   r   errorr:   ZisEnabledForDebugrc   exc_info	tracebackprint_tb)r   callbackrP   r   _tbr   r   r   rA   I  s    

zWebSocketApp._callback)NNNNNNNNTNNNN)NNr   NNNNNFNNNF)r   r   r   __doc__r   r   rS   r2   r5   r=   r^   rW   r@   rA   r   r   r   r   r   N   sF                      
=	
                 
 )rp   rf   r   rc   rX   r8   rk   rR   Z_abnfr   Z_corer   r   _exceptions r   __all__r	   r    objectr   r   r   r   r   <module>   s   