o
    tf                     @  s   d Z ddlmZ ddlZddlZddlZddlmZmZ ddl	Z
ddl
mZ ddlmZ er6ddlmZmZ dddZG dd de
jjZdS )z9Tornado websocket handler to serve a terminal interface.
    )annotationsN)TYPE_CHECKINGAny)gen)run_on_executor)PtyWithClientsTermManagerBasesstr | bytesreturnstrc                 C  s   t | tr
| dS | S )Nzutf-8)
isinstancebytesdecode)r	    r   \/var/www/html/software/conda/envs/catlas/lib/python3.10/site-packages/terminado/websocket.py_cast_unicode   s   

r   c                      s   e Zd ZdZd(ddZd)d*ddZd)d+ fddZd,ddZd-ddZe	j
d.ddZd/ddZd/ddZd0d1d"d#Zed$d%d,d&d'Z  ZS )2
TermSocketz Handler for a terminal websocketterm_managerr   r   Nonec                 C  sN   || _ d| _d| _d| _|j| _tt| _	d| _
ttdddk| _dS )zInitialize the handler. )NNNZLOG_TERMINAL_OUTPUTfalsetrue)r   	term_namesizeterminalZblocking_io_executor_blocking_io_executorlogging	getLogger__name___logger_user_commandr   lowerosgetenv_enable_output_logging)selfr   r   r   r   
initialize   s   zTermSocket.initializeNorigin
str | Noneboolc                 C  s*   |p	| j jdd}|dusJ | |S )z1Deprecated: backward-compat for terminado <= 0.5.ZOriginr   N)requestheadersgetZcheck_origin)r&   r(   r   r   r   origin_check,   s   
zTermSocket.origin_checkurl_componentr   c                   s   t  | | jd| t|}|pd| _| j|| _| jj	
|  | di g | jd| j d}| jj }	 |s?n	| }||7 }q<|rQ| | dS 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   TN)superopenr    infor   r   r   Zget_terminalr   clientsappendsend_json_messageZread_buffercopypoplefton_pty_read)r&   r/   bufferedZpreopen_bufferr	   	__class__r   r   r3   2   s&   
zTermSocket.opentextr   c                 C  s   |  d|g dS )z$Data read from pty; send to frontendstdoutN)r7   r&   r>   r   r   r   r:   O   s   zTermSocket.on_pty_readcontentc                 C  sX   t |}| | | jr&|d dkr(t|d tr*| d|d   dS dS dS dS )z"Send a json message on the socket.r   r?      zSTDOUT: N)jsondumpsZwrite_messager%   r   r   log_terminal_output)r&   rA   Zjson_msgr   r   r   r7   S   s
   

 zTermSocket.send_json_messagemessagec                 c  s    t |}|d }| jdusJ |dkrA| |d V  | jr?|d dkr4| d| j  d| _dS |  j|d 7  _dS dS |dkrS|dd	 | _| j  dS 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stdinrB   zSTDIN: r   Zset_size   )	rC   loadsr   stdin_to_ptyprocr%   rE   r!   r   resize_to_smallest)r&   rF   commandmsg_typer   r   r   
on_message[   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    r4   r   r5   removerL   r   Zclient_disconnectedr&   r   r   r   on_closer   s
   
zTermSocket.on_closec                 C  s    |  ddg |   d| _dS )z9Terminal closed: tell the frontend, and close the socket.Z
disconnectrB   N)r7   closer   rQ   r   r   r   on_pty_died~   s   
zTermSocket.on_pty_diedr   logc                 C  s   | j | dS )zg
        Logs the terminal input/output
        :param log: log line to write
        :return:
        N)r    debug)r&   rU   r   r   r   rE      s   zTermSocket.log_terminal_outputr   )executorc                 C  s    | j dur| j j| dS 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writer@   r   r   r   rK      s   
zTermSocket.stdin_to_ptyproc)r   r   r   r   )N)r(   r)   r   r*   )r/   r   r   r   )r>   r   r   r   )rA   r   r   r   )rF   r   r   r   )r   r   )r   )rU   r   r   r   )r   
__module____qualname____doc__r'   r.   r3   r:   r7   r   	coroutinerO   rR   rT   rE   r   rK   __classcell__r   r   r<   r   r      s    




r   )r	   r
   r   r   )r[   
__future__r   rC   r   r#   typingr   r   Ztornado.websockettornador   Ztornado.concurrentr   Zterminado.managementr   r   r   Z	websocketZWebSocketHandlerr   r   r   r   r   <module>   s    
