o
    i!                     @   s   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Zddl	Z	ddl
Z
ddlmZ ddlmZ zddlZW n eyG   dZY nw ejdkrQejZndd Zdd	d
ZG dd dZG dd deZeej dS )z!JupyterLab Server process handler    N)which)genFwin32c                 C   s   ddl }dt|j| S )zShim for list2cmdline on posix.r   N )shlexjoinmapquote)cmd_listr    r   T/var/www/edux/Edux_v2/venv/lib/python3.10/site-packages/jupyterlab_server/process.pylist2cmdline   s   r   c                 C   sv   |pt j}|dpt j}t| |d}| dkr!|s!d} td|d}|s5| dv r-d}t|tdd|   t j|S )	zGet the full path to a command.

    Parameters
    ----------
    command: str
        The command name or path.
    env: dict, optional
        The environment variables, defaults to `os.environ`.
    PATH)pathnodenodejs)r   r   npmzPlease install Node.js and npm before continuing installation. You may be able to install Node.js from your package manager, from conda, or directly from the Node.js website (https://nodejs.org).z%The command was not found or was not zexecutable: %s.)osenvirongetdefpath_which
ValueErrorr   abspath)commandenvr   command_with_pathmsgr   r   r   r   $   s   

r   c                   @   sl   e Zd ZU dZe Zejed< dZdddZ	dd Z
d	d
 Zejdd Zdd Zedd Zdd ZdS )ProcesszA wrapper for a child process._procsNFc           	      C   s   t |ttfsd}t||r| rd}t||p|  | _d| _|s0| jdt	|  || _
i }|r<tj|d< | jd||d|| _|pMt | _tj|  dS )	a)  Start a subprocess that can be run asynchronously.

        Parameters
        ----------
        cmd: list
            The command to run.
        logger: :class:`~logger.Logger`, optional
            The logger instance.
        cwd: string, optional
            The cwd of the process.
        env: dict, optional
            The environment for the process.
        kill_event: :class:`~threading.Event`, optional
            An event used to kill the process operation.
        quiet: bool, optional
            Whether to suppress output.
        zCommand must be given as a listzProcess aborted z> stdout)cwdr   Nr   )
isinstancelisttupler   is_setget_loglogger
_last_lineinfor   cmd
subprocessDEVNULL_create_processproc	threadingEvent_kill_eventr   r   add)	selfr+   r(   r"   
kill_eventr   quietr   kwargsr   r   r   __init__E   s"   
zProcess.__init__c              	   C   s   | j }| du rt|jtj z<z|jdd W n# tj	y=   tj
dkr+tj}ntj}| du r;t|j| Y nw W | tjv rJtj|  | S | tjv rZtj|  w w )z/Terminate the process and return the exit code.Ng       @)timeoutnt)r/   pollr   killpidsignalSIGTERMwaitr,   TimeoutExpirednameSIGBREAKSIGKILLr   r   remove)r4   r/   sigr   r   r   	terminaten   s(   



zProcess.terminatec                 C   sR   | j }| j}| du r%| r|   d}t|td | du s|  S )zhWait for the process to finish.

        Returns
        -------
        The process exit code.
        NProcess was aborted      ?)r/   r2   r;   r&   rG   r   timesleepr4   r/   r5   r   r   r   r   r@      s   
zProcess.waitc                 c   s\    | j }| j}| du r'| r|   d}t|tdV  | du st|  )z.Asynchronously wait for the process to finish.NrH   rI   )	r/   r2   r;   r&   rG   r   r   rK   ReturnrL   r   r   r   
wait_async   s   zProcess.wait_asyncc                 K   sX   t | j}|dtj t|d |d|d< tjdkr!d|d< tj	|fi |}|S )zCreate the process.stderrr   r   r:   Tshell)
r$   r+   
setdefaultr,   STDOUTr   r   r   rB   Popen)r4   r7   r+   r/   r   r   r   r.      s   

zProcess._create_processc                 C   s   t | jD ]}|  qdS )z*Clean up the started subprocesses at exit.N)r$   r   rG   )clsr/   r   r   r   _cleanup   s   
zProcess._cleanupc                 C   s6   t | dr| jr| jS td| _| jtj | jS )zGet our logger.r(   
jupyterlab)hasattrr(   logging	getLoggersetLevelINFO)r4   r   r   r   r'      s
   zProcess.get_log)NNNNF)__name__
__module____qualname____doc__weakrefWeakSetr   __annotations___poolr8   rG   r@   r   	coroutinerN   r.   classmethodrU   r'   r   r   r   r   r   ?   s   
 
)

r   c                       s>   e Zd ZdZd fdd	Zdd Zdd Z fd	d
Z  ZS )WatchHelperz%A process helper for a watch process.Nc           	         s   t  j|||||d ts| jj| _	 | j d}|s#d}t|t	|
  t||r0nqtj| jdd| _| j  dS )a  Initialize the process helper.

        Parameters
        ----------
        cmd: list
            The command to run.
        startup_regex: string
            The regex to wait for at startup.
        logger: :class:`~logger.Logger`, optional
            The logger instance.
        cwd: string, optional
            The cwd of the process.
        env: dict, optional
            The environment for the process.
        kill_event: callable, optional
            A function to call to check if we should abort.
        )r(   r"   r5   r      utf-8zProcess ended improperlyT)targetdaemonN)superr8   ptyr/   r!   _stdoutreadlinedecodeRuntimeErrorprintrstriprematchr0   Thread_read_incoming_read_threadstart)	r4   r+   startup_regexr(   r"   r5   r   liner   	__class__r   r   r8      s   
	zWatchHelper.__init__c              	   C   s   | j }| du r"tjdkrtt|jtj nt	|jtj z|
  W | tjv r3tj|  |jS | tjv rBtj|  w w )zTerminate the process.Nr:   )r/   r;   r   rB   killpggetpgidr=   r>   r?   r<   r@   r   r   rE   
returncode)r4   r/   r   r   r   rG      s   



zWatchHelper.terminatec              
   C   sn   | j  }	 zt|d}W n ty( } z| jd| W Y d}~dS d}~ww |s-dS t|ddd q)z(Run in a thread to read stdout and printrg   i   zRead incoming error %sNrh   r    )end)	rm   filenor   readOSErrorr(   debugrq   ro   )r4   r   bufer   r   r   rv      s   
zWatchHelper._read_incomingc                    s   d|d< t r t  \}}| |d< |d< d|d< t|d| _n#tj|d< tjdkrCt }| j	tj
O  _	||d	< tj|d
< d|d< t jdi |S )z"Create the watcher helper process.r   bufsizerO   r!   Tstart_new_sessionrbr:   startupinfocreationflagsrP   Nr   )rl   openptyr   fdopenrm   r,   PIPErB   STARTUPINFOdwFlagsSTARTF_USESHOWWINDOWCREATE_NEW_PROCESS_GROUPrk   r.   )r4   r7   masterslaver   r{   r   r   r.     s   


zWatchHelper._create_process)NNNN)	r\   r]   r^   r_   r8   rG   rv   r.   __classcell__r   r   r{   r   rf      s    #rf   )N)r_   atexitrX   r   rs   r>   r,   sysr0   rJ   r`   shutilr   r   tornador   rl   ImportErrorplatformr   r   rf   registerrU   r   r   r   r   <module>   s4    

 `