a
    Df.                     @  s   d Z ddlm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
mZ ddlZddlmZ ddlmZ ddlmZmZ d	d
lmZ G dd dejZG dd deZdS )z
The Terminal Widget makes it easy to create Panel Applications with Terminals.

- For example apps which streams the output of processes or logs.
- For example apps which provide interactive bash, python or ipython terminals
    )annotationsN)ClassVarMapping)JupyterComm   )PeriodicCallback)edit_readonly	lazy_load   )Widgetc                      sh  e Zd ZdZejeefddZej	dddZ
ejddZejd	dd
dZejdddZejdddZejddZejeddZejdddZejdd	ddZejddZejddZ fddZedd Zdd Zdd Zejd d!dd"d#d$ Z d%d& Z!d'd( Z"ed)d* Z#d;d,d-Z$d.d/ Z%d0d1 Z&ejd2dd"d3d4 Z'ejd5dd"d6d7 Z(d<d9d:Z)  Z*S )=TerminalSubprocesszn
    The TerminalSubProcess is a utility class that makes running
    subprocesses via the Terminal easy.
    z
        The arguments used to run the subprocess. This may be a string
        or a list. The string cannot contain spaces. See subprocess.run
        docs for more details.)class_doczKills the running processTr   constantze
        Any other arguments to run the subprocess. See subprocess.run
        docs for more details.r   Fz2
        Whether or not the subprocess is running.)defaultr   r   r   zChild process idr   r   zChild file descriptor.i P  r   z*
        Watches the subprocess for output2   z#Period length of _periodic_callbackz;
        The Terminal to which the subprocess is connected.)r   Z
allow_refsr   z%Watches the subprocess for user inputc                   s   t  jf || jd| d S )N)	_terminalkill)super__init___kill)selfZterminalkwargs	__class__ c/nfs/NAS7/SABIOD/METHODE/ermites/ermites_venv/lib/python3.9/site-packages/panel/widgets/terminal.pyr   A   s    zTerminalSubprocess.__init__c                 C  s   d dd | D S )N c                 S  s   g | ]}t |qS r   )shlexquote).0cr   r   r    
<listcomp>F       z-TerminalSubprocess._quote.<locals>.<listcomp>)join)commandr   r   r    _quoteD   s    zTerminalSubprocess._quotec                   s4   t |tr |S t |tr0 fdd|D S |S )Nc                   s   g | ]}  |qS r   )r*   )r$   argr   r   r    r&   L   r'   z2TerminalSubprocess._clean_args.<locals>.<listcomp>)
isinstancestrr*   listr   argsr   r,   r    _clean_argsH   s
    


zTerminalSubprocess._clean_argsc              
   O  s6  ddl }|s| j}|std| jr,td| |}| jrJi | j|}| \}}|dkrz"tj|fi |}t	t
| W n4 ty } zt	t
|d  W Y d}~n
d}~0 0 nz|| _|| _|   t| j| jd| _| j  | jjj| jddd	| _t|  d
| _W d   n1 s(0    Y  dS )z,
        Runs a subprocess command.
        r   NzError. No args providedz@Error. A child process is already running. Cannot start another.z&
CompletedProcess('FileNotFoundError'))callbackperiodvalueF)ZonlychangedT)ptyr1   
ValueErrorrunningr2   r   fork
subprocessrunprintr.   FileNotFoundError
_child_pid_fd_set_winsizer   &_forward_subprocess_output_to_terminal_period_periodic_callbackstartr   paramwatch%_forward_terminal_input_to_subprocess_watcheredit_constant)r   r1   r   r6   	child_pidfdresulter   r   r    r;   O   sB    
(
zTerminalSubprocess.runz_terminal.ncolsz_terminal.nrowsrF   c                 C  s~   | j d u s| jjr| jjsd S dd l}dd l}dd l}|d| jj| jjdd}z|| j |j	| W n t
yx   Y n0 d S )Nr   ZHHHH)r?   r   nrowsncolsfcntlstructtermiospackZioctl
TIOCSWINSZOSError)r   rQ   rR   rS   Zwinsizer   r   r    r@      s    zTerminalSubprocess._set_winsizec                 G  sL   | j }|   |r<tt|tj | jd| d n| jd d S )Nz
The process z was killed
z
No running process to kill
)	r>   _resetoskillpggetpgidsignalSIGTERMr   write)r   eventsrJ   r   r   r    r      s    zTerminalSubprocess._killc                 C  sl   d| _ d| _| jr"| j  d | _| jr8| jj| j t|  d| _	W d    n1 s^0    Y  d S )Nr   F)
r?   r>   rC   stoprH   r   rE   ZunwatchrI   r8   r,   r   r   r    rW      s    
zTerminalSubprocess._resetc                 C  s   | d |  d S NCompletedProcess)rfind)r5   r   r   r    _remove_last_line_from_string   s    z0TerminalSubprocess._remove_last_line_from_stringr   c              	   C  s^   t ||}t|d D ]8}z|dW   S  tyN   |t |d }Y q0 qtddS )zHUTF-8 characters can be multi-byte so need to decode on correct boundaryr
   zutf-8z(Could not find decode boundary for UTF-8N)rX   readrangedecodeUnicodeDecodeErrorUnicodeError)r   rK   Zmax_read_bytesZmax_extra_bytesdata_r   r   r    _decode_utf8_on_boundary   s    z+TerminalSubprocess._decode_utf8_on_boundaryc                 C  sh   | j s
d S t| j gg g | j\}}}|s.d S | | j | j}d|v rX|   | |}| j| d S r`   )	r?   select_timeout_secrk   _max_read_bytesrW   rc   r   r]   )r   Z
data_readyrj   outputr   r   r    rA      s    
z9TerminalSubprocess._forward_subprocess_output_to_terminalc                 G  s    | j rt| j | jj  d S N)r?   rX   r]   r   r5   encoder   r^   r   r   r    rG      s    z8TerminalSubprocess._forward_terminal_input_to_subprocessr1   c                 C  s6   | j }t|tr2d|v r2td| d|d d S )N z
The args 'zV' provided contains spaces. They must instead be provided as the
                list )r1   r-   r.   r7   splitr0   r   r   r    _validate_args   s    z!TerminalSubprocess._validate_argsrB   c                 C  s   | j r| j| j _d S rp   )rC   rB   r4   r,   r   r   r    _update_periodic_callback   s    z,TerminalSubprocess._update_periodic_callbackNc                 C  s   d| j  d| j dS )NzTerminalSubprocess(args=z
, running=))r1   r8   r   depthr   r   r    __repr__   s    zTerminalSubprocess.__repr__)r   )N)+__name__
__module____qualname____doc__rE   ZClassSelectorr.   r/   r1   Actionr   Dictr   Booleanr8   Integerr>   r?   rn   r   rC   rB   	Parameterr   rm   rH   r   staticmethodr*   r2   r;   dependsr@   r   rW   rc   rk   rA   rG   ru   rv   rz   __classcell__r   r   r   r    r      s@   
9






r   c                      sf  e Zd ZU dZejdddZeji dddZej	dd	d
Z
ejdddZejdddZej	ddddZejddd
ZejddZej	ddZdddddddZded< dA fdd	Zdd ZdB fdd 	Zd!d" Zd#d$ Zejd%dd&d'd( ZdCd)d*Zed+d, Zed-d. Zd/d0 Z d1d2 Z!d3d4 Z"d5d6 Z#dDd7d8Z$dEd9d:Z%d;d< Z&d=d> Z'd?d@ Z(  Z)S )FTerminala  
    The `Terminal` widget renders a live terminal in the browser using
    the xterm.js library making it possible to display logs or even
    provide an interactive terminal in a Panel application.

    Reference: https://panel.holoviz.org/reference/widgets/Terminal.html

    :Example:

    >>> Terminal(
    ...     "Welcome to the Panel Terminal!", options={"cursorBlink": True}
    ... )
    zClears the Terminal.Tr   z
        Initial Options for the Terminal Constructor. cf.
        https://xtermjs.org/docs/api/terminal/interfaces/iterminaloptions/)r   
precedencer   r!   z.
        System output written to the Terminalr   z/
        The number of columns in the terminal.)readonlyr   z,
        The number of rows in the terminal.ZInputzO
        User input received from the Terminal. Sent one character at the time.)labelr   r   Fz7
        Whether or not to write to the server console.z$Sends a signal to clear the terminalr   r   Nro   )clearnamero   _outputr5   write_to_consolez"ClassVar[Mapping[str, str | None]]_renamec                   s:   |pd |d< }| j |d< t jf d|i| d | _d S )Nr!   r   r   ro   )_clearr   r   _subprocess)r   ro   paramsr   r   r    r   
  s    
zTerminal.__init__c                 C  s`   |}t |tr|}nt |tr*|d}nt|}| j|krBd| _|| _|  j|7  _t| jS )Nutf8r!   )r-   r.   bytesrf   r   ro   len)r   Z_Terminal__scleanedr   r   r    r]     s    


zTerminal.writec                   sP   | j d u r tddt|t|| _ t ||||}| j|_| jd|||d |S )Nzpanel.models.terminalr   Z	keystroke)modelr   comm)Z_widget_typer	   r-   r   r   
_get_modelro   Z_register_events)r   r   rootparentr   r   r   r   r    r   !  s    
zTerminal._get_modelc              	   C  sd   t | H |j| _t|  d| _W d    n1 s80    Y  W d    n1 sV0    Y  d S )Nr!   )r   keyr5   rE   Zdiscard_events)r   eventr   r   r    _process_event+  s    
zTerminal._process_eventc                 G  s   d| _ |  jd7  _dS )z4
        Clears all output on the terminal.
        r!   r
   N)ro   _clearsrr   r   r   r    r   1  s    zTerminal._clearr   rN   c                 C  s   | j rtj| j d S rp   )r   sys
__stdout__r]   r   r,   r   r   r    _write8  s    zTerminal._writec                 C  s   dt |  dS )NzTerminal(id=rw   )idrx   r   r   r    rz   =  s    zTerminal.__repr__c                 C  s   | j st| | _ | j S )z
        The subprocess enables running commands like 'ls', ['ls',
        '-l'], 'bash', 'python' and 'ipython' in the terminal.
        )r   r   r,   r   r   r    r:   @  s    
zTerminal.subprocessc                 C  s   dS NFr   r,   r   r   r    closedL  s    zTerminal.closedc                 C  s   dS Nr   r   r,   r   r   r    filenoP  s    zTerminal.filenoc                 C  s   d S rp   r   r,   r   r   r    flushS  s    zTerminal.flushc                 C  s   | j S rp   ro   r,   r   r   r    getvalueV  s    zTerminal.getvaluec                 C  s   dS NTr   r,   r   r   r    readableY  s    zTerminal.readablec                 C  s   |dkr| j S | j d | S r   r   )r   sizer   r   r    rd   \  s    zTerminal.readc                 C  sJ   g }d}| j dD ]0}|dkr:||kr:|t|7 } qF|| q|S )Nr   
r   )ro   rt   r   	getsizeofappend)r   hintlinesr   liner   r   r    	readlinesa  s    zTerminal.readlinesc                 C  s   dS r   r   r,   r   r   r    seekablek  s    zTerminal.seekablec                 C  s   dS r   r   r,   r   r   r    writablen  s    zTerminal.writablec                 C  s   |D ]}|  | qd S rp   )r]   )r   r   r   r   r   r    
writelinesq  s    zTerminal.writelines)N)NNN)N)r   )r   )*r{   r|   r}   r~   rE   r   r   r   optionsStringro   r   rP   rO   r5   r   r   r   r   r   __annotations__r   r]   r   r   r   r   r   rz   propertyr:   r   r   r   r   r   rd   r   r   r   r   r   r   r   r   r    r      sD   








r   )r~   
__future__r   rX   rl   r"   r[   r:   r   typingr   r   rE   Zpyviz_commsr   Zio.callbacksr   utilr   r	   baser   ZParameterizedr   r   r   r   r   r    <module>   s     C