
    cX2                        d Z 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mZmZmZmZ ddlmZ ddlmZmZmZmZmZmZmZ ddlmZmZ ddlm Z   G d	 d
e!      Z" G d de!      Z#d*dZ$ejJ                  fdZ&d Z'd Z(defde)deee)df   e)f   de*dee)df   dee)   f
dZ+efde)de)dee)e)e)e)e)e)e)e)f   dee)   fdZ,d Z- e d       G d d             Z. G d d e!      Z/ G d! d"e!      Z0 e!       Z1 G d# d$e!      Z2 G d% d&e!      Z3 e3       Z4d' Z5d(ejl                  ejn                  z   fd)Z8y)+zTshell/term utilities, useful to write some python scripts instead of shell
scripts.
zrestructuredtext en    N)existsisdirislinkbasenamejoin)StringIO)AnyCallableOptionalListUnionIteratorTuple)STD_BLACKLIST_handle_blacklist)callable_deprecatedc                       e Zd Zd Zd Zy)tempdirc                 L    t        j                         | _        | j                  S N)tempfilemkdtemppathselfs    ;/usr/lib/python3/dist-packages/logilab/common/shellutils.py	__enter__ztempdir.__enter__,   s    $$&	yy    c                 H    t        j                  | j                         |d u S r   )shutilrmtreer   r   exctypevalue	tracebacks       r   __exit__ztempdir.__exit__0   s    dii D  r   N)__name__
__module____qualname__r   r&    r   r   r   r   +   s    !r   r   c                       e Zd Zd Zd Zd Zy)pushdc                     || _         y r   )	directory)r   r.   s     r   __init__zpushd.__init__7   s	    "r   c                     t        j                         | _        t        j                  | j                         | j                  S r   )osgetcwdcwdchdirr.   r   s    r   r   zpushd.__enter__:   s)    99;
 ~~r   c                 B    t        j                  | j                         y r   )r1   r4   r3   r"   s       r   r&   zpushd.__exit__?   s    
r   N)r'   r(   r)   r/   r   r&   r*   r   r   r,   r,   6   s    #
r   r,   c                 .   |d}n	 t        |      }|d}n	 t        |      }t        j                  | ||       y# t        $ r" ddl}|j                  |      j                  }Y Sw xY w# t        $ r" ddl}|j                  |      j                  }Y pw xY w)zSame as `os.chown` function but accepting user login or group name as
    argument. If login or group is omitted, it's left unchanged.

    Note: you must own the file to chown it (or be root). Otherwise OSError is raised.
    Nr   )
int
ValueErrorpwdgetpwnampw_uidgrpgetgrnamgr_gidr1   chown)r   logingroupuidr:   gidr=   s          r   r@   r@   C   s     }	-e*C
 }	-e*C
 HHT3  	-,,u%,,C	-  	-,,u%,,C	-s    ; A) (A&%A&)(BBc           
         t        j                   |       }t        |      dkD  r1t        |      sJ |D ]  } ||t        |t	        |                     y	 |d   } t        |      r t        |      rt        |t	        |             }	  || |       y# t
        $ r t        d| z        w xY w# t        $ r}t        d| d|d|d      d}~ww xY w)	z&A shell-like mv, supporting wildcards.   r   zNo file matching %szUnable to move z to z ()N)globlenr   r   r   
IndexErrorOSErrorr   )sourcedestination_actionsourcesfilenameexs         r   mvrR   ^   s    iiG
7|a[!!! 	EHHd;0BCD	E	:QZF &"5{HV,<=K	VFK(  	:/&899	:  	VFKQSTUU	Vs$   B 	B, B),	C5C

Cc                      | D ]s  }t        j                   |      D ]Y  }t        |      rt        j                  |       $t	        |      rt        j                  |       Et        j                  |       [ u y)z&A shell-like rm, supporting wildcards.N)rH   r   r1   remover   r    r!   )fileswfilerP   s      r   rmrW   r   s\     $		%( 	$Hh		(#xh'		(#	$$r   c                 <    t        | |t        j                         y)z&A shell-like cp, supporting wildcards.)rN   N)rR   r    copy)rL   rM   s     r   cprZ   ~   s    v{FKK0r   Fr.   exts.exclude	blacklistreturnc           
         t        |t              r|f}|r dt        dt        t        df   dt        fd}ndt        dt        t        df   dt        fd}g }t	        j
                  |       D ]V  \  }}}t        |||       t        |      }	|	|v r$|j                  |D 
cg c]  }
 ||
|      st        ||
       c}
       X |S c c}
w )a  Recursively find files ending with the given extensions from the directory.

    :type directory: str
    :param directory:
      directory where the search should start

    :type exts: basestring or list or tuple
    :param exts:
      extensions or lists or extensions to search

    :type exclude: boolean
    :param exts:
      if this argument is True, returning files NOT ending with the given
      extensions

    :type blacklist: list or tuple
    :param blacklist:
      optional list of files or directory to ignore, default to the value of
      `logilab.common.STD_BLACKLIST`

    :rtype: list
    :return:
      the list of all matching files
    rP   r[   .r^   c                 8    |D ]  }| j                  |      s y y)NFTendswithrP   r[   exts      r   matchzfind.<locals>.match   s'     !$$S) ! r   c                 8    |D ]  }| j                  |      s y y)NTFra   rc   s      r   re   zfind.<locals>.match   s'      $$S)  r   )

isinstancestrr   boolr1   walkr   r   extendr   )r.   r[   r\   r]   re   rU   dirpathdirnames	filenamesdirnamefs              r   findrq      s    < $w	C 	uS#X 	4 		C 	uS#X 	4 	 E(*	(: N$9)Xy97#i	L1U1d^d7A&LMN L Ms   C
.C
patternc              #      K   t        j                  |       D ]<  \  }}}t        |||       t        j                  ||      D ]  }t        ||        > yw)aL  Recursively finds files matching glob `pattern` under `directory`.

    This is an alternative to `logilab.common.shellutils.find`.

    :type directory: str
    :param directory:
      directory where the search should start

    :type pattern: basestring
    :param pattern:
      the glob pattern (e.g *.py, foo*.py, etc.)

    :type blacklist: list or tuple
    :param blacklist:
      optional list of files or directory to ignore, default to the value of
      `logilab.common.STD_BLACKLIST`

    :rtype: iterator
    :return:
      iterator over the list of all matching files
    N)r1   rj   r   fnmatchfilterr   )r.   rr   r]   curdirrm   rn   fnames          r   globfindrx      sZ     4 (*wwy'9 &#))Xy9^^Iw7 	&Evu%%	&&s   AAc                    dd l }t        |      st        j                  |       |j	                  |       }|j                         D ]y  }|j                  d      r t        j                  t        ||             4t        t        ||      d      }|j                  |j                  |             |j                          { y )Nr   /wb)zipfiler   r1   mkdirZipFilenamelistrb   r   openwritereadclose)archivedestdirr|   zfobjnameoutfiles         r   unzipr      s    '?
OOG$E  ==HHT'4()4.5GMM%**T*+MMOr   zUse subprocess.Popen insteadc                       e Zd ZdZd Zy)ExecutezsThis is a deadlock safe version of popen2 (no stdin), that returns
    an object with errorlevel, out and err.
    c                     t        j                  |dt         j                  t         j                        }|j                         \  | _        | _        t        j                  |j                        | _	        y )NT)shellstdoutstderr)

subprocessPopenPIPEcommunicateouterrr1   WEXITSTATUS
returncodestatus)r   commandcmds      r   r/   zExecute.__init__   sL    wd:??S]SbSbc __.$(nnS^^4r   N)r'   r(   r)   __doc__r/   r*   r   r   r   r      s    5r   r   c                       e Zd ZdZdej
                  dfdededededd	f
d
Z	d Z
ddZd Z ee
ee      Zddededd	fdZddZd Zy	)ProgressBarzA simple text progression bar.    nbopssizestreamtitler^   Nc                     |rd|dt        |      d| _        ndt        |      z  | _        || _        || _        || _        d| _        d| _        d | _        d| _        y )Nz [%-zs]z	[%%-%ss]r   )	r8   _fstr_stream_total_size_current	_progress_current_text_last_text_write_size)r   r   r   r   r   s        r   r/   zProgressBar.__init__   sZ     ,13t9=DJ%D	1DJ
!%&"r   c                     | j                   S r   )r   r   s    r   	_get_textzProgressBar._get_text  s    !!!r   c                 R    || j                   k7  r|| _         | j                          y y r   )r   refresh)r   texts     r   	_set_textzProgressBar._set_text  s&    4%%%!%DLLN &r   c                     d | _         y r   r   r   s    r   	_del_textzProgressBar._del_text  s	    	r   offsetexactc                    |r|| _         n| xj                   |z  c_         t        t        | j                         t        | j                        z  | j                  z        }|| j
                  kD  r|| _        | j                          yy)zMove FORWARD to new cursor position (cursor will never go backward).

        :offset: fraction of ``size``

        :exact:

          - False: offset relative to current cursor position if True
          - True: offset as an asbsolute position

        N)r   r8   floatr   r   r   r   )r   r   r   progresss       r   updatezProgressBar.update  sg     "DMMMV#Mdmm,uT[[/AATZZOPdnn$%DNLLN %r   c                    | j                   j                  | j                  dt        | j                  | j
                        z  z         | j                  s| j                  r[d| j                  z  }| j                  }|d}| j                   j                  ||z         t        |j                               | _        | j                   j                          y)z$Refresh the progression bar display.=z %%-%isNr   )r   r   r   minr   r   r   r   rI   rstripflush)r   templater   s      r   r   zProgressBar.refresh-  s    4::s4>>4::/N)NOP%%);); D$>$>?H%%D|LLx$/),T[[]);D&r   c                 n    | j                   j                  d       | j                   j                          y )N
)r   r   r   r   s    r   finishzProgressBar.finish9  s$    4 r   r   )rF   F)r^   N)r'   r(   r)   r   sysr   r8   r   rh   r/   r   r   r   propertyr   ri   r   r   r   r*   r   r   r   r      s    ( ')SZZVX'' #'2:'PS'	'"
 Iy)4DS T d *
r   r   c                   "    e Zd ZdZd Zd Zd Zy)DummyProgressBarr   c                      y r   r*   r   s    r   r   zDummyProgressBar.refreshA      r   c                      y r   r*   r   s    r   r   zDummyProgressBar.updateD  r   r   c                      y r   r*   r   s    r   r   zDummyProgressBar.finishG  r   r   N)r'   r(   r)   	__slots__r   r   r   r*   r   r   r   r   >  s    Ir   r   c                   *    e Zd ZeeeedfdZd Zd Zy)r   Tc                 J    || _         || _        || _        || _        || _        y r   )r   r   r   r   enabled)r   r   r   r   r   r   s         r   r/   zprogress.__init__O  s%    
	
r   c                     | j                   r?i }dD ]  }t        | |      }|t        us|||<    t        di || _        | j                  S t               | _        | j                  S )N)r   r   r   r   r*   )r   getattr_MARKERr   pbr   )r   kwargsattrr$   s       r   r   zprogress.__enter__V  sk    <<F< )d+'#(F4L) "+F+DG ww '(DGwwr   c                 8    | j                   j                          y r   )r   r   )r   exc_typeexc_valexc_tbs       r   r&   zprogress.__exit__b  s    r   N)r'   r(   r)   r   r/   r   r&   r*   r   r   r   r   N  s    $77'[_ 
r   r   c            	       n    e Zd Z	 	 ddee   dee   deddfdZdedeed	f   d
edefdZ	ddede
de
fdZy)RawInputNinput_functionprinterr   r^   c                     d|v r+|j                  d      }t        j                  dt               |xs t        | _        || _        y )Ninputz;'input' argument is deprecated,use 'input_function' instead)popwarningswarnDeprecationWarningr   _input_print)r   r   r   r   s       r   r/   zRawInput.__init__g  sA     f#ZZ0NMMP" %-r   questionoptions.defaultc           	      $   ||v sJ g }|D ]h  }||k(  r|d   j                         }n|d   j                         }t        |      dkD  r|d|dd  j                         z  z  }|j                  ||f       j |ddj	                  |D cg c]  }|d   	 c}      d}d}	|	dkD  r| j                  |      j                         j                         }
|
s|S |D cg c]'  \  }}|j                         j                  |
      s&|) }}}t        |      dk(  r|d   S t        |      dk(  rd|
z  }n|
d	d
j	                  |      d}| j                  r| j                  |       nt        |       |	dz  }	|	dkD  rt        d      c c}w c c}}w )Nr   rF   z(%s)z [rz   z]:    z%s is not an option.z% is an ambiguous answer, do you mean z or z ?zunable to get a sensible answer)upperlowerrI   appendr   r   strip
startswithr   print	Exception)r   r   r   r   choicesoptionlabeloptprompttriesanswerpossiblemsgs                r   askzRawInput.askv  s   '!!! 	,F q	)q	)6{Q&*"2"2"444NNFE?+	, !)#((g3NsCF3N*OPai[[(..0668F4;a=65v||~?X?XY_?`aHa8}!{"X!#,v5 KK) {{C c
QJE% ai& 9::+ 4O bs   F'FFdefault_is_yesc                 F    |xr dxs d}| j                  |d|      }|dk(  S )Nyn)r   r  )r   )r   r   r   r   r   s        r   confirmzRawInput.confirm  s-     (S/C(J8}r   NN)T)r'   r(   r)   r   r
   r	   r/   rh   r   r   ri   r  r*   r   r   r   r   f  s     .2&* * (# 	
 
 ;C  ;%S/  ;C  ;C  ;D T T r   r   c                      t         j                  dk7  r*ddl} | j                  t	        j
                               d   S t        j                  d   S )zavoid using os.getlogin() because of strange tty / stdin problems
    (man 3 getlogin)
    Another solution would be to use $LOGNAME, $USER or $USERNAME
    win32r   NUSERNAME)r   platformr:   getpwuidr1   getuidenviron)r:   s    r   getloginr    s<    
 ||w||BIIK(++zz*%%r      c                 Z    d}t        |       D ]  }|t        j                  |      z  } |S )z!dumb password generation functionr   )rangerandomchoice)lengthvocabr:   is       r   generate_passwordr    s2    
C6] $v}}U##$Jr   r  )9r   __docformat__r1   rH   r    r   r   rt   stringr  r   r   os.pathr   r   r   r   r   _ior   typingr	   r
   r   r   r   r   r   logilab.commonr   r   logilab.common.deprecationr   objectr   r,   r@   moverR   rW   rZ   rh   ri   rq   rx   r   r   r   r   r   r   r   ASKr  ascii_lettersdigitsr  r*   r   r   <module>r!     s  $
 & 	   
       9 9  H H H ; :!f !
F 
6 %+KK V(	$1 !.	88
c3h$
%8 8 S#X	8
 
#Y8| @M&&& S#sCc3;<& c]	&@ 345 5 55B& BJ
v 
 (v 05v 5p j
& f&:&:V]]&J r   