a
    ñ»j,,  ã                   @   s¾   d Z ddlmZmZ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ZddlZe e¡Ze ej¡ dZdZdZG dd„ deƒZdZG d	d
„ d
eƒZG dd„ deƒZdd„ ZeZdS )z(Easy to use python subprocess interface.é    )Úsplit_commandÚ	unidecodeÚ	uniencodeNÚlinkgš™™™™™¹?c                   @   s   e Zd Zddd„Zdd„ ZdS )ÚEasyProcessErrorÚ c                 C   s   || _ || _d S ©N)Úeasy_processÚmsg)Úselfr	   r
   © r   úBE:\soccer\ml_env\Lib\site-packages\sbvirtualdisplay/easyprocess.pyÚ__init__   s    zEasyProcessError.__init__c                 C   s   | j d t| jƒ S )Nú )r
   Úreprr	   ©r   r   r   r   Ú__str__   s    zEasyProcessError.__str__N)r   )Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r   r      s   
r   z)cmd=%s
OSError=%s
Program install error! c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚEasyProcessCheckInstalledErrorzoThis exception is raised when a process run by check() returns
    a non-zero exit status or OSError is raised.c                 C   s
   || _ d S r   )r	   )r   r	   r   r   r   r   )   s    z'EasyProcessCheckInstalledError.__init__c                 C   sd   t | jj| jjf }| jjr,|d| jj 7 }t ¡ d  ¡ dkr`| jjr`|d7 }|d| jj 7 }|S )Nz
home page: r   Zubuntuz!
You can install it in terminal:
zsudo apt-get install %s)	Útemplater	   ÚcmdÚoserrorÚurlÚplatformÚdistÚlowerÚubuntu_package©r   r
   r   r   r   r   ,   s    þÿÿz&EasyProcessCheckInstalledError.__str__N)r   r   r   Ú__doc__r   r   r   r   r   r   r   %   s   r   c                   @   sª   e Zd ZdZd'dd„Zdd„ Zedd	„ ƒZed
d„ ƒZd(dd„Z	dd„ Z
d)dd„Zdd„ Zdd„ Zd*dd„Zdd„ Zdd„ Zdd„ Zdd „ Zd+d!d"„Zd#d$„ Zd%d&„ ZdS ),ÚEasyProcessaÞ  
    .. module:: easyprocess

    simple interface for :mod:`subprocess`

    :param cmd: string ('ls -l') or list of strings (['ls','-l'])
    :param cwd: working directory
    :param use_temp_files: use temp files instead of pipes for
                           stdout and stderr,
                           pipes can cause deadlock in some cases
                           (see unit tests)
    :param env: If *env* is not ``None``, it must be a mapping that defines
                the environment variables for the new process;
                these are used instead of inheriting the current
                process' environment, which is the default behavior.
                (check :mod:`subprocess`  for more information)
    NTc                 C   sÂ   || _ d| _|| _d | _d | _d | _d | _d | _|| _|| _	d| _
d | _|| _d | _d| _d| _|| _t|ƒ}|| _d | j¡| _t d| j¡ t d| j¡ t d| j¡ t|ƒs¾t| dƒ‚d S )NFr   zparam: "%s" zcommand: %szjoined command: %szempty command!)Úuse_temp_filesÚ_outputs_processedÚenvÚpopenÚstdoutÚstderrÚ_stdout_fileÚ_stderr_filer   r   Ú
is_startedr   Ú	cmd_paramÚ_threadÚ_stop_threadÚtimeout_happenedÚcwdr   r   ÚjoinZcmd_as_stringÚlogÚdebugÚlenr   )r   r   r   r   r/   r"   r$   r   r   r   r   O   s2    	zEasyProcess.__init__c              	   C   s.   d| j j| j| j| j| j| j| j| jf }|S )Nz^<%s cmd_param=%s cmd=%s oserror=%s return_code=%s stdout="%s" stderr="%s" timeout_happened=%s>)	Ú	__class__r   r+   r   r   Úreturn_coder&   r'   r.   r   r   r   r   Ú__repr__r   s    øþÿzEasyProcess.__repr__c                 C   s   | j r| j jS dS )zH
        PID (:attr:`subprocess.Popen.pid`)
        :rtype: int
        N)r%   Úpidr   r   r   r   r7   ƒ   s    zEasyProcess.pidc                 C   s   | j r| j jS dS )zV
        returncode (:attr:`subprocess.Popen.returncode`)
        :rtype: int
        N)r%   Ú
returncoder   r   r   r   r5   Œ   s    zEasyProcess.return_coder   c                 C   s*   |   ¡ j}||k}|s&t| d |¡ƒ‚| S )a  Run command with arguments. Wait for command to complete. If the
        exit code was as expected and there is no exception then return,
        otherwise raise EasyProcessError.
        :param return_code: int, expected return code
        :rtype: self
        z$check error, return code is not {0}!)Úcallr5   r   Úformat)r   r5   ÚretÚokr   r   r   Úcheck•   s    
þzEasyProcess.checkc                 C   s,   z|   ¡  W n ty&   t| ƒ‚Y n0 | S )aB  Used for testing if program is installed.
        Run command with arguments. Wait for command to complete.
        If OSError raised, then raise :class:`EasyProcessCheckInstalledError`
        with information about program installation.
        :param return_code: int, expected return code
        :rtype: self
        )r9   Ú	Exceptionr   r   r   r   r   Úcheck_installed¥   s
    zEasyProcess.check_installedc                 C   s$   |   ¡ j|d� |  ¡ r |  ¡  | S )z´Run command with arguments. Wait for command to complete.
        same as:
         1. :meth:`start`
         2. :meth:`wait`
         3. :meth:`stop`
        :rtype: self
        ©Útimeout)ÚstartÚwaitÚis_aliveÚstop©r   rA   r   r   r   r9   ³   s    zEasyProcess.callc              
   C   sÔ   | j rt| dƒ‚| jr@tjdd�| _tjdd�| _| j}| j}ntj}tj}t	t
t| jƒƒ}ztj|||| j| jd�| _W n@ tyº } z(t d|¡ || _t| dƒ‚W Y d}~n
d}~0 0 d	| _ t d
| j¡ | S )zSstart command in background and does not wait for it.
        :rtype: self
        zprocess was started twice!Zstdout_)ÚprefixZstderr_)r&   r'   r/   r$   zOSError exception: %szstart errorNTzprocess was started (pid=%s))r*   r   r"   ÚtempfileÚTemporaryFiler(   r)   Ú
subprocessÚPIPEÚlistÚmapr   r   ÚPopenr/   r$   r%   ÚOSErrorr1   r2   r   r7   )r   r&   r'   r   r   r   r   r   rB   À   s2    
û zEasyProcess.startc                 C   s   | j r| j  ¡ du S dS dS )zW
        poll process using :meth:`subprocess.Popen.poll`
        :rtype: bool
        NF)r%   Úpollr   r   r   r   rD   ß   s    zEasyProcess.is_alivec                 C   sd   |d ur0| j s0tj| jd�| _ d| j _| j  ¡  | j rX| j j|d� | jpR| j  ¡ | _n|  ¡  | S )N)Útargeté   r@   )	r,   Ú	threadingÚThreadÚ_wait4processÚdaemonrB   r0   r.   ZisAliverF   r   r   r   rC   é   s    
ÿzEasyProcess.waitc                 C   s  | j r
d S dd„ }| j�r| jr¢trL| j ¡ d ur4qV| jr>d S t t¡ q$n
| j 	¡  d| _ | j
 d¡ | j d¡ | j
 ¡ | _| j ¡ | _| j
 ¡  | j ¡  nd| _ | j ¡ \| _| _t d¡ |t| jƒƒ| _|t| jƒƒ| _t d| j¡ t d| j¡ t d| j¡ d S )	Nc                 S   s   |   d¡r| d d… S | S d S )NÚ
éÿÿÿÿ)Úendswith)Úsr   r   r   Úremove_ending_lfý   s    
z3EasyProcess._wait4process.<locals>.remove_ending_lfTr   zprocess has endedzreturn code=%sz	stdout=%sz	stderr=%s)r#   r%   r"   ÚUSE_POLLrP   r-   ÚtimeÚsleepÚ	POLL_TIMErC   r(   Úseekr)   Úreadr&   r'   ÚcloseÚcommunicater1   r2   r   r5   )r   r[   r   r   r   rU   ù   s6    


zEasyProcess._wait4processc                 C   s   |   ¡  ¡ S r   )ÚsendstoprC   r   r   r   r   rE     s    zEasyProcess.stopc              
   C   sÀ   | j st| dƒ‚t d| j| j¡ | jr²|  ¡ r¦t d¡ z8z| j ¡  W n$ t	yn   t
 | jjtj¡ Y n0 W q° ty¢ } zt d|¡ W Y d}~q°d}~0 0 q¼t d¡ n
t d¡ | S )z†
        Kill process (:meth:`subprocess.Popen.terminate`).
        Do not wait for command to complete.
        :rtype: self
        zprocess was not started!z"stopping process (pid=%s cmd="%s")z$process is active -> sending SIGTERMzexception in terminate:%sNzprocess was already stoppedzprocess was not started)r*   r   r1   r2   r7   r   r%   rD   Ú	terminateÚAttributeErrorÚosÚkillÚsignalZSIGKILLrO   )r   r   r   r   r   rd   "  s     

$
zEasyProcess.sendstopc                 C   s   t  |¡ | S r   )r]   r^   )r   Úsecr   r   r   r^   <  s    
zEasyProcess.sleepc                    s   ‡ ‡‡fdd„}|S )zÙ
        returns a function which:
         1. start process
         2. call func, save result
         3. stop process
         4. returns result
        similar to :keyword:`with` statement
        :rtype:
        c               
      s‚   ˆ  ¡  ˆ rˆ ˆ ¡ d } zXz
ˆƒ } W n@ tyf } z(t d|¡ |ˆ_tˆdƒ‚W Y d }~n
d }~0 0 W ˆ ¡  n
ˆ ¡  0 | S )NzOSError exception:%szwrap error!)rB   r^   rO   r1   r2   r   r   rE   )Úxr   ©ÚdelayÚfuncr   r   r   ÚwrappedJ  s    

"z!EasyProcess.wrap.<locals>.wrappedr   )r   rn   rm   ro   r   rl   r   Úwrap@  s    
zEasyProcess.wrapc                 C   s   |   ¡  | S )ú%used by the :keyword:`with` statement)rB   r   r   r   r   Ú	__enter__Z  s    zEasyProcess.__enter__c                 G   s   |   ¡  dS )rq   N)rE   )r   Úexc_infor   r   r   Ú__exit___  s    zEasyProcess.__exit__)NNNTN)r   )N)N)r   )r   r   r   r    r   r6   Úpropertyr7   r5   r=   r?   r9   rB   rD   rC   rU   rE   rd   r^   rp   rr   rt   r   r   r   r   r!   =   s2        ù
#





&
r!   c                 C   sj   |   dd¡ ¡ }d}t|ƒD ]H}t|ƒdkr|d  ¡ dkrH|dd… }d|v r|d  ¡ r|} qfq|S )	zQThis function tries to extract the version
    from the help text of any program.ú,r   Né   r   ÚvrR   Ú.)ÚreplaceÚsplitÚreversedr3   r   Úisdigit)ÚtxtÚwordsÚversionrk   r   r   r   Úextract_versiond  s    r�   )r    Zsbvirtualdisplay.unicodeutilr   r   r   ÚloggingÚos.pathrg   r   ri   rJ   rH   rS   r]   Ú	getLoggerr   r1   ÚsetLevelÚERRORZSECTION_LINKr_   r\   r>   r   r   r   Úobjectr!   r�   ZProcr   r   r   r   Ú<module>   s,   
	  )