B
    .d                 @   s\   d 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 Z	G dd dej
jZdS )	z9Tornado websocket handler to serve a terminal interface.
    N)gen)run_on_executorc             C   s   t | tr| dS | S )Nzutf-8)
isinstancebytesdecode)s r   `/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/terminado/websocket.py_cast_unicode   s    

r
   c                   s   e Zd ZdZdd ZdddZd fdd	Zd	d
 Zdd Ze	j
dd Zdd Zdd ZdeddddZedddd Z  ZS )
TermSocketz Handler for a terminal websocketc             C   sN   || _ d| _d| _d | _|j| _tt| _	d| _
ttdddk| _d S )N )NNZLOG_TERMINAL_OUTPUTfalsetrue)term_manager	term_namesizeterminalZblocking_io_executor_blocking_io_executorlogging	getLogger__name___logger_user_commandstrlowerosgetenv_enable_output_logging)selfr   r   r   r	   
initialize   s    zTermSocket.initializeNc             C   s   |  |p| jjdS )z1Deprecated: backward-compat for terminado <= 0.5.ZOrigin)Zcheck_originrequestheadersget)r   originr   r   r	   origin_check&   s    zTermSocket.origin_checkc                s   t  | | jd| t|}|p(d| _| j|| _| jj	
|  | di g | jd| j d}| jj }x|s~P | }||7 }qxW |r| | dS )zWebsocket connection opened.

        Call our terminal manager to get a terminal, and connect to it as a
        client.
        zTermSocket.open: %sttysetupzTermSocket.open: Opened %sr   N)superopenr   infor
   r   r   Zget_terminalr   clientsappendsend_json_messageZread_buffercopypoplefton_pty_read)r   Zurl_componentbufferedZpreopen_bufferr   )	__class__r   r	   r(   *   s"    
zTermSocket.openc             C   s   |  d|g dS )z$Data read from pty; send to frontendstdoutN)r,   )r   textr   r   r	   r/   G   s    zTermSocket.on_pty_readc             C   sL   t |}| | | jrH|d dkrHt|d trH| d|d   d S )Nr   r2      zSTDOUT: )jsondumpsZwrite_messager   r   r   log_terminal_output)r   contentZjson_msgr   r   r	   r,   K   s
    

zTermSocket.send_json_messagec             c   s   t |}|d }| jdk	s t|dkrx| |d V  | jr|d dkrd| d| j  d| _q|  j|d 7  _n |dkr|dd	 | _| j	  dS )
zHandle incoming websocket message

        We send JSON arrays, where the first element is a string indicating
        what kind of message this is. Data associated with the message follows.
        r   Nstdinr4   zSTDIN: r   Zset_size   )
r5   loadsr   AssertionErrorstdin_to_ptyprocr   r7   r   r   resize_to_smallest)r   messagecommandZmsg_typer   r   r	   
on_messageS   s    
zTermSocket.on_messagec             C   s:   | j d | jr*| jj|  | j  | j|  dS )zHandle websocket closing.

        Disconnect from our terminal, and tell the terminal manager we're
        disconnecting.
        zWebsocket closedN)r   r)   r   r*   remover?   r   Zclient_disconnected)r   r   r   r	   on_closej   s
    
zTermSocket.on_closec             C   s    |  ddg |   d| _dS )z9Terminal closed: tell the frontend, and close the socket.Z
disconnectr4   N)r,   closer   )r   r   r   r	   on_pty_diedv   s    zTermSocket.on_pty_diedr   )logreturnc             C   s   | j | dS )zg
        Logs the terminal input/output
        :param log: log line to write
        :return:
        N)r   debug)r   rG   r   r   r	   r7   |   s    zTermSocket.log_terminal_outputr   )executorc             C   s   | j dk	r| j j| dS )a   Handles stdin messages sent on the websocket.

        This is a blocking call that should NOT be performed inside the
        server primary event loop thread. Messages must be handled
        asynchronously to prevent blocking on the PTY buffer.
        N)r   Zptyprocwrite)r   r3   r   r   r	   r>      s    
zTermSocket.stdin_to_ptyproc)N)N)r   )r   
__module____qualname____doc__r   r$   r(   r/   r,   r   	coroutinerB   rD   rF   r   r7   r   r>   __classcell__r   r   )r1   r	   r      s   
r   )rN   r5   r   r   Ztornado.websockettornador   Ztornado.concurrentr   r
   Z	websocketZWebSocketHandlerr   r   r   r   r	   <module>   s   