o
    i                     @  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   N/var/www/edux/Edux_v2/venv/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. )NNNLOG_TERMINAL_OUTPUTfalsetrue)r   	term_namesizeterminal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.Originr   N)requestheadersget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   get_terminalr   clientsappendsend_json_messageread_buffercopypoplefton_pty_read)r(   r3   bufferedpreopen_bufferr	   	__class__r   r   r7   2   s&   
zTermSocket.opentextr   c                 C  s   |  d|g dS )z$Data read from pty; send to frontendstdoutN)r<   r(   rE   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   rF      zSTDOUT: N)jsondumpswrite_messager'   r   r   log_terminal_output)r(   rH   json_msgr   r   r   r<   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stdinrI   zSTDIN: r   set_size   )	rJ   loadsr   stdin_to_ptyprocr'   rM   r#   r   resize_to_smallest)r(   rO   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"   r8   r   r:   removerV   r   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.
disconnectrI   N)r<   closer   r\   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(   ra   r   r   r   rM      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   ptyprocwriterG   r   r   r   rU      s   
zTermSocket.stdin_to_ptyproc)r   r   r   r   )N)r*   r+   r   r,   )r3   r   r   r   )rE   r   r   r   )rH   r   r   r   )rO   r   r   r   )r   r   )r   )ra   r   r   r   )r!   
__module____qualname____doc__r)   r2   r7   r@   r<   r   	coroutinerY   r]   r`   rM   r   rU   __classcell__r   r   rC   r   r      s    




r   )r	   r
   r   r   )rh   
__future__r   rJ   r   r%   typingr   r   tornado.websockettornador   tornado.concurrentr   terminado.managementr   r   r   	websocketWebSocketHandlerr   r   r   r   r   <module>   s    
