
    5                         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 ddlmZ dgZ G d	 d
      Z G d d      Z G d de      Zy)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                       e Zd Zd Zd Zy)
Dispatcherc                      || _         || _        y Nappping_timeoutselfr   r   s      !lib/third_party/websocket/_app.py__init__zDispatcher.__init__,       (    c                 4   | j                   j                  j                  rxt        j                  | j                   j                  j                  fdd| j                        \  }}}|r |       sy  |        | j                   j                  j                  rwy y N )r   sock	connectedselectr   )r   r   read_callbackcheck_callbackrwes          r   readzDispatcher.read0   sl    hhmm%%mmXX]]''*BD4E4EGGAq!$ hhmm%%r   N)__name__
__module____qualname__r   r"   r   r   r   r   r   +   s    )r   r   c                       e Zd Zd Zd Zd Zy)SSLDispactherc                      || _         || _        y r   r   r   s      r   r   zSSLDispacther.__init__:   r   r   c                     | j                   j                  j                  rC| j                         }|r |       sy  |        | j                   j                  j                  rBy y r   )r   r   r   r   )r   r   r   r   r   s        r   r"   zSSLDispacther.read>   sB    hhmm%%A$ hhmm%%r   c                     | j                   j                  j                  }|j                         r|gS t        j                  |fdd| j                        \  }}}|S r   )r   r   pendingr   r   )r   r   r   r    r!   s        r   r   zSSLDispacther.selectF   sL    xx}}!!<<>7N--"b$2C2CD1ar   N)r#   r$   r%   r   r"   r   r   r   r   r'   r'   9   s    )r   r'   c                   x    e Zd ZdZ	 	 	 	 	 	 	 ddZej                  fdZd Zd Z		 	 	 	 	 	 	 ddZ
d Zd	 Zd
 Zy)r	   zc
    Higher level of APIs are provided.
    The interface is like JavaScript WebSocket object.
    Nc                     || _         ||ng | _        || _        || _        || _        || _        || _        || _        || _        || _	        |	| _
        d| _        || _        d| _        d| _        d| _        || _        y)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 obsolete and ignored.
        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/   r1   r2   r4   r5   r6   r7   r8   r9   r:   r0   r=   r3   s                  r   r   zWebSocketApp.__init__T   s    T  & 2f$  .!(	(r   c                 p    | j                   r| j                   j                  ||      dk(  rt        d      y)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   send"WebSocketConnectionClosedException)r   dataopcodes      r   r?   zWebSocketApp.send   s6     yyDIINN48A=4/1 1 >r   c                 r    d| _         | j                  r$ | j                  j                  di | d| _        yy)z-
        close websocket connection.
        FNr   )r9   r   close)r   kwargss     r   rD   zWebSocketApp.close   s4     "99DIIOO%f%DI r   c                 @   |j                  |      sSt        j                         | _        | j                  r	 | j                  j	                          |j                  |      sRy y # t
        $ r.}t        j                  dj                  |             Y d }~y d }~ww xY w)Nz send_ping routine terminated: {})	waittimer;   r   ping	Exceptionr   warningformat)r   intervaleventexs       r   
_send_pingzWebSocketApp._send_ping   ss    **X& $		DyyIINN$	 **X&
 ! $$%G%N%Nr%RSs   A& &	B/$BBc                 L    dk  rdr|r|k  rt        d      |sg }|si } j                  rt        d      dd _        d _        d _        d fd		 t         j                  || j                  du|	|rdnd       _         j                  j                  t                       j                  j                   j                   j                   j                  |||| j                  |
|||	       |s j                        } j!                   j"                         |rXt%        j&                         t%        j(                   j*                  |f
      j-                  d       j/                           fd} fd}|j1                   j                  j                  ||       y# t2        t4        t6        f$ rO} j!                   j8                  |       t;        |t6              r          t;        |t4               cY d}~S d}~ww xY w)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.
        suppress_origin: suppress outputting origin header.

        Returns
        -------
        False if caught KeyboardInterrupt
        True if other exception was raised during a loop
        Nr   z#Ensure ping_interval > ping_timeoutzsocket is already openedTc                 J   r0j                         r j                          j                          d_        j                  rj                  j                          j                  | r| j                  nd      } j                  j                  g|  d_        y)z
            Tears down the connection.
            If close_frame is set, we will invoke the on_close handler with the
            statusCode and reason from there.
            FN)
isAlivesetjoinr9   r   rD   _get_close_argsrA   	_callbackr5   )close_frame
close_argsrN   r   threads     r   teardownz*WebSocketApp.run_forever.<locals>.teardown   s{     &..*		 %Dyy		!--$/  T;JDNN4==6:6DIr   F)sockoptssloptfire_cont_frameskip_utf8_validationenable_multithread)r/   r0   http_proxy_hosthttp_proxy_porthttp_no_proxyhttp_proxy_authr=   hostoriginsuppress_origin
proxy_type)targetargsc                     j                   s        S j                  j                  d      \  } }| t        j                  k(  r |      S | t        j
                  k(  r'j                  j                  |j                         y| t        j                  k(  r@t        j                         _        j                  j                  |j                         y| t        j                  k(  rzj                  rnj                  j                  |j                  |j                   |j"                         j                  j                  |j                  |j"                         y|j                  }t$        j&                  r$| t        j(                  k(  r|j+                  d      }j                  j                  ||j                   d       j                  j,                  |       y)NTutf-8)r9   r   recv_data_framer   OPCODE_CLOSEOPCODE_PINGrW   r6   rA   OPCODE_PONGrH   r<   r7   OPCODE_CONTr8   r3   rB   finsixPY3OPCODE_TEXTdecoder2   )op_codeframerA   r   r[   s      r   r"   z&WebSocketApp.run_forever.<locals>.read  se   ((#:%!%!:!:4!@d///#E?* 0 00NN4<<<    0 00(,		D%NN4<<<   0 00T5I5INN4<<#(<<<NN4#7#7#(::uyy:  !::Dww7d.>.>#>#{{73NN4<<u||TJNN4??D9r   c                      ryt        j                          j                  z
  kD  } j                  j                  z
  dk  }j                  j                  z
  kD  }j                  r| r|s|rt        d      y)Nr   zping/pong timed outT)rH   r;   r<   WebSocketTimeoutException)has_timeout_expired$has_pong_not_arrived_after_last_pinghas_pong_arrived_too_later   r   s      r   checkz'WebSocketApp.run_forever.<locals>.check%  s}     *.))+8I8I*IL*X';?;L;LtO`O`;`cd;d8040A0ADDUDU0UXd0d-)) 3!EIb78MNNr   r   )WebSocketExceptionr   r9   r;   r<   r   r:   r8   
settimeoutr   connectr.   r/   r0   r=   create_dispatcherrW   r1   	threadingEventThreadrP   	setDaemonstartr"   rJ   KeyboardInterrupt
SystemExitr4   
isinstance)r   r\   r]   ping_intervalr   ra   rb   rc   rd   r_   re   rf   
dispatcherrg   rh   r"   r~   r!   rN   r[   rZ   s   `   `             @@@r   run_foreverzWebSocketApp.run_forever   s   B #(9LMm|.K$%JKKGF99$%?@@ 	"G	8!!!76 $ 4 4D @%9+84e	EDI
 II  !2!45IIT[[ / /} /d>O>O&/%  ' !33LA
NN4<<(!)"))??-1GI  &4
 OODIINND%8,j9 	8NN4==!,!Z(J!!%6777	8s    "EG   H#AHH#H#c                 r    |xs d}| j                   j                         rt        | |      S t        | |      S )N
   )r   is_sslr'   r   )r   r   timeouts      r   r   zWebSocketApp.create_dispatcher:  s6    $"99 w//$((r   c                    t         j                  dk  rC| j                  r5t        t	        j
                  | j                        j                        dk7  rEg S | j                  r5t        t	        j                  | j                        j                        dk7  rg S |rZt        |      dk\  rLdt        j                  |dd       z  t        j                  |dd       z   }|dd j                  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   Nrl   )sysversion_infor5   leninspect
getargspecrj   getfullargspecrs   byte2intrv   )r   rA   codereasons       r   rV   zWebSocketApp._get_close_argsA  s     f$==C(:(:4==(I(N(N$OST$T	==C(>(>t}}(M(R(R$SWX$X	CINd1Qi003<<Qq	3JJD!"X__W-F&>!d|r   c                 V   |r&	 t        j                  |      r ||  y  || g|  y y # t        $ ru}t        j                  dj                  ||             t        j                         r2t        j                         \  }}}t        j                  |       Y d }~y Y d }~y d }~ww xY w)Nzerror from callback {}: {})r   ismethodrJ   r   errorrL   isEnabledForDebugr   exc_info	tracebackprint_tb)r   callbackrj   r!   _tbs         r   rW   zWebSocketApp._callbackS  s    
+##H-dOT)D)   +;BB8QOP--/"||~HAq"&&r** 0+s   * 	* 	B(A&B##B()NNNNNNNNTNNNN)NNr   NNNNNFNNNFN)r#   r$   r%   __doc__r   r   ru   r?   rD   rP   r   r   rV   rW   r   r   r   r	   r	   N   sk    
 $(9=6:!%>B";)z !% 0 0 
1 0426:>8<).7;8<H8T)$+r   )r   r   r   r   r   rH   r   rs   _abnfr   _corer   r   _exceptions r   __all__r   r'   objectr	   r   r   r   <module>r      s^   ,   
    
  /   
  *Q+6 Q+r   