a
    DfP                     @   s   d Z ddlZddlmZ ddlmZmZ g dfddZdadi fd	d
Z	d(ddZ
d)ddZi dfddZd*ddZd+ddZd,ddZd-ddZd.ddZd/ddZd0d d!Zd1d"d#Zd2d%d&ZeZe
ZeZeZeZeZeZeZed'k rdS )3zN
higher-level shell utilities for user environment and filesystem exploration
    N   )shutils)kbytes	disk_used;c                 C   s4   d}| D ]}|dt |t |f 7 }q|t |S )a  generate a filter pattern from list of strings

    Args:
        list (list(str), default=[]): a list of filter elements.
        separator (str, default=';'): the separator string.

    Returns:
        a string composed of filter elements joined by the separator.
     z%s%s)strrstrip)list	separatorfilteritem r   V/nfs/NAS7/SABIOD/METHODE/ermites/ermites_venv/lib/python3.9/site-packages/pox/utils.pypattern   s    
r   c           
      C   s   |du rt j}i }|| || d| vr2| S tsHddl}|dad}t| |}|s^q|d\}}|d}|dd dkr|dd dkr|dd }||v r| |d }	| d| t	|| || } t
| }| |	 } qL|}qL| S )	a  expand shell variables in string

    Expand shell variables of form ``$var`` and ``${var}``. Unknown variables
    are left unchanged. If a reference dictionary (*ref*) is provided,
    restrict lookups to *ref*. A second reference dictionary (*secondref*)
    can also be provided for failover searches. If *ref* is not provided,
    lookup variables are defined by the user's environment variables.

    Args:
        string (str): a string with shell variables.
        ref (dict(str), default=None): a dict of lookup variables.
        secondref (dict(str), default={}): a failover reference dict.

    Returns:
        string with the selected shell variables substituted.

    Examples:
        >>> expandvars('found:: $PYTHONPATH')
        'found:: .:/Users/foo/lib/python3.4/site-packages'
        >>> 
        >>> expandvars('found:: $PYTHONPATH', ref={})
        'found:: $PYTHONPATH'
    N$r   z\$(\w+|\{[^}]*\})r   {})osenvironupdate_varprogrecompilesearchspangroup
expandvarslen)
stringrefZ	secondrefZrefdictr   imjnametailr   r   r   r   $   s0    



 
r   c              	   C   s   |du ri }i }|  |ptj}|D ]X}d|v r$| dd dd}z|| ||< W q$ tyz   tj| ||< Y q$0 q$|S )a  get a dictionary of all variables defined in path

    Extract shell variables of form ``$var`` and ``${var}``. Unknown variables
    will raise an exception. If a reference dictionary (*ref*) is provided,
    first try the lookup in *ref*.  Failover from *ref* will lookup variables
    defined in the user's environment variables.  Use *sep* to override the
    path separator (``os.sep``).

    Args:
        path (str): a path string with shell variables.
        ref (dict(str), default=None): a dict of lookup variables.
        sep (str, default=None): the path separator string.

    Returns:
        dict of shell variables found in the given path string.

    Examples:
        >>> getvars('$HOME/stuff')
        {'HOME': '/Users/foo'}
    Nr   r   r   r   )splitr   seplstripr	   KeyErrorr   )pathr!   r(   Zndictdirsdirkeyr   r   r   getvarsZ   s    r/   Tc                 C   s  |s
t j}|st j}d}d}d}|||g}|dv r8|}n0|dv rF|}n"|dv rT|}n|rdtd|  dS d	}	| |D ]}
zdt|
d
}| }|  |D ]}|||}qt|
d}|	| |  |rtd|
|f  W qv   |rtd|
  d}	Y qv0 qv|	S )a  convert text files to given platform type

    Ensure given files use the appropriate ``os.linesep`` and other formatting.

    Args:
        files (list(str)): a list of filenames.
        platform (str, default=None): platform name as in ``os.name``.
        pathsep (str, default=None): the path separator string.
        verbose (bool, default=True): if True, print debug statements..

    Returns:
        0 if converted, otherwise return 1.
    z

)Zlinux2linuxunixZlinposixZriscos)ZwindowsZ	mswindowswindosntZos2Zce)macmacosxz#Error: Platform '%s' not recognized   r   rwzConverted '%s' to '%s' formatzFile conversion failed for '%s'r   )
r   r%   pathsepprintr'   openreadclosereplacewrite)filesplatformr=   verboseZMACZWINZLINlinesepZ
newlinesepZallconvertedfileinfile
filestringr"   outfiler   r   r   convert~   s<    





rL   c           	      C   sr   |dkr| }t | d}| }|  ddl}| D ]\}}||||}q6t |d}|| |  dS )a  make text substitutions given by *sub* in the given file

    Args:
        file (str): path to original file.
        sub (dict(str), default={}: dict of string replacements ``{old:new}``.
        outfile (str, default=None): if given, don't overwrite original file.

    Returns:
        None

    Notes:
        ``replace`` uses regular expressions, thus a pattern may be used as
        *old* text. ``replace`` can fail if order of substitution is important.
    Nr;   r   r<   )r?   r@   rA   r   itemsr   subrC   )	rH   rN   rK   inputrJ   r   oldnewoutputr   r   r   rB      s    


rB   Fc           	      C   sz   || v r|  |}nd}|r"d}n|}|| |d v rV| |d  |}|rZ||7 }nd}|rn|dkrn|d7 }t|||S )a  get the slice for a given sequence

    Slice indicies are determined by the positions of *start* and *stop*.
    If *start* is not found in the sequence, slice from the beginning. If
    *stop* is not found in the sequence, slice to the end.

    Args:
        sequence (list): an ordered sequence of elements.
        start (int): index for start of the slice.
        stop (int): index for stop position in the sequence.
        step (int, default=1): indices until next member of the slice.
        sequential (bool, default=False): if True, *start* must preceed *stop*.
        inclusive (bool, default=False): if True, include *stop* in the slice.

    Returns:
        slice corresponding to given *start*, *stop*, and *step*.
    Nr   )indexslice)	sequencestartstopstep
sequential	inclusivebeginhereendr   r   r   index_slice   s    
r^   c                 C   s    t | |||||}d| | S )a  slice a list of strings, then join the remaining strings

    If *start* is not found in the sequence, slice from the beginning. If
    *stop* is not found in the sequence, slice to the end.

    Args:
        sequence (list): an ordered sequence of elements.
        start (int): index for start of the slice.
        stop (int): index for stop position in the sequence.
        step (int, default=1): indices until next member of the slice.
        sequential (bool, default=True): if True, *start* must preceed *stop*.
        inclusive (bool, default=True): if True, include *stop* in the slice.

    Returns:
        string produced by slicing the given sequence and joining the elements.
    r   )r^   join)rU   rV   rW   rX   rY   rZ   islicer   r   r   
index_join   s    ra   c                 C   s   |s
t j}|rtd|  | d t jkr2t j|  } t j| \}}tj|||dd}tjddd}tjddd}	g }
dd	l	}|D ]J}|	|d
|  r|	t j
||r|r||v s|	r|	|v r|
| q|
D ]}|| q|r|rtd|   ntd|   |r|S t|t jdddS )a  retrieve the path(s) for a package

    Args:
        package (str): name of the package to search for.
        root (str, default=None): path string of top-level directory to search.
        all (bool, defualt=False): if True, return everywhere package is found.
        verbose (bool, default=True): if True, print messages about the search.
        recurse (bool, default=True): if True, recurse down the root directory.

    Returns:
        string path (or list of paths) where package is found.

    Notes:
        On some OS, recursion can be specified by recursion depth (an integer).
        ``findpackage`` will do standard pattern matching for package names,
        attempting to match the head directory of the distribution.
    zsearching %s...r   d)recursetypeZBLD_ROOTFallZEXPORT_ROOTN*z%s found%s not foundT)counterminimumrf   )r   curdirr>   r(   r+   r'   r   findenvfnmatchbasenameappendremoveselect)packagerootrf   rF   rc   ZpackdirZbasedirZ	targetdirZbldrootZexprootZremlistrn   r-   r   r   r   findpackage   s<    
ru   r   c              	   C   s  t | }g }| D ]T}z||}W n6 ty8   d}Y n" tyX   ||krPdnd}Y n0 || q|rz|  |   |s|dkr|g S dS |rt|}	nt|}	|s| ||	 S g }
g }| D ]}|| q||	}t	|D ]*}|
|
||	 |
||	 q||
S )a  find items in iterable with the max (or min) count of the given counter.

    Find the items in an iterable that have the maximum number of *counter*
    (e.g. counter='3' counts occurances of '3'). Use ``minimum=True`` to
    search for the minimum number of occurances of the *counter*.

    Args:
        iterable (list): an iterable of iterables (e.g. lists, strings, etc).
        counter (str, default=''): the item to count.
        minimum (bool, default=False): if True, find min count (else, max).
        reverse (bool, default=False): if True, reverse order of the results.
        all (bool, default=True): if False, only return the first result.

    Returns:
        list of items in the iterable with the min (or max) count.

    Examples:
        >>> z = ['zero','one','two','three','4','five','six','seven','8','9/81']
        >>> select(z, counter='e')
        ['three', 'seven']
        >>> select(z, counter='e', minimum=True)
        ['two', '4', 'six', '8', '9/81']
        >>> 
        >>> y = [[1,2,3],[4,5,6],[1,3,5]]
        >>> select(y, counter=3)
        [[1, 2, 3], [1, 3, 5]]
        >>> select(y, counter=3, minumim=True, all=False)
        [4, 5, 6]
    r   r   TN)rd   count	TypeErrorAttributeErrorrp   reverseminmaxrS   rangepop)iterableri   rj   ry   rf   ityper#   r   rv   x	shortlisttmpZ
occurancesr"   r   r   r   rr   +  s8    

rr   c           
      C   s~   t |   \}}t||||d}|sBt||}|| || iS i }tt|D ]&}	||	 |v rR|||	 ||	 i qR|S )a  return a dict of items with the max (or min) count of the given counter.

    Get the items from a dict that have the maximum number of the *counter*
    (e.g. counter='3' counts occurances of '3') in the values. Use
    ``minimum=True`` to search for minimum number of occurances of *counter*.

    Args:
        dict (dict): dict with iterables as values (e.g. lists, strings, etc).
        counter (str, default=''): the item to count.
        minimum (bool, default=False): if True, find min count (else, max).
        all (bool, default=True): if False, only return the first result.

    Returns:
        dict of items composed of the entries with the min (or max) count.

    Examples:
        >>> z = ['zero','one','two','three','4','five','six','seven','8','9/81']
        >>> z = dict(enumerate(z))
        >>> selectdict(z, counter='e')
        {3: 'three', 7: 'seven'}
        >>> selectdict(z, counter='e', minimum=True)
        {8: '8', 9: '9/81', 2: 'two', 4: '4', 6: 'six'}
        >>> 
        >>> y = {1: [1,2,3], 2: [4,5,6], 3: [1,3,5]}
        >>> selectdict(y, counter=3)
        {1: [1, 2, 3], 3: [1, 3, 5]}
        >>> selectdict(y, counter=3, minumim=True)
        {2: [4, 5, 6]}
    re   )ziprM   rr   r
   rS   r|   r   r   )
dictri   rj   rf   keysvaluesr   r   Z	shortdictr"   r   r   r   
selectdicti  s    r   c                 C   s0   |r|sd}|r,d|| f } |r,d|| f } | S )a  build string for a remote connection of the form ``[[user@]host:]path``

    Args:
        path (str): path string for location of target on (remote) filesystem.
        host (str, default=None): string name/ip address of (remote) host.
        user (str, default=None): user name on (remote) host.
        loopback (bool, default=False): if True, ensure *host* is used.

    Returns:
        a remote connection string.

    Notes:
        if loopback=True and host=None, then host will be set to localhost.
    	localhostz%s:%sz%s@%sr   )r+   hostuserloopbackr   r   r   remote  s    r   c                 C   s   |  dd }|  dd }||kr<|r2dd|fS dd|fS | dd }| dd }||krjd||fS |rvd| }|||fS )a  parse remote connection string of the form ``[[user@]host:]path``

    Args:
        path (str): remote connection string.
        loopback (bool, default=False): if True, ensure *host* is used.
        login_flag (bool, default=False): if True, prepend user with ``-l``.

    Returns:
        a tuple of the form ``(user, host, path)``.

    Notes:
        if loopback=True and host=None, then host will be set to localhost.
    :r   r   r   r   @z-l )r'   )r+   r   Z
login_flagdpathZrhostZdhostZduserr   r   r   parse_remote  s    
r   c                 C   s  ddl }ddl}|j|j}|d}|r0dnd}d}	|r\|jdd dks\d|}d	}	|rhd
|v rld
nd}
t| drd
t| v r|
rt| nd	t| 
d
}qd|v rtt| nt| }n,t| r|
	dd |jdd D }nd}|r
d|v r
dnd}d	|	||g|	g}|s|r|
d
} |jdt|  }|rltdd | D |krt|j}ntj|dd}|sd}|S )a  get the command to launch the selected version of python

    ``which_python`` composes a command string that can be used to launch
    the desired python executable. The user's path is searched for the
    executable, unless ``lazy=True`` and thus only a lazy-evaluating command
    (e.g. ``which python``) is produced.

    Args:
        version (bool, default=False): if True, include the version of python.
        lazy (bool, default=False): if True, build a lazy-evaluating command.
        fullpath (bool, default=True): if True, provide the full path.
        ignore_errors (bool, default=True): if True, ignore path search errors.

    Returns:
        string of the implicit or explicit location of the python executable.

    Notes:
        if version is given as an int or float, include the version number
        in the command string.

        if the executable is not found, an error will be thrown unless
        ``ignore_error=True``.
    r   Npypypythonr      r5   z
`which {0}`.)
2345678910-c                 s   s   | ]}t |V  qd S N)r   .0r"   r   r   r   	<genexpr>      zwhich_python.<locals>.<genexpr>r:   c                 s   s   | ]}t |V  qd S r   )intr   r   r   r   r     r   T)ignore_errors)r   sysr+   ro   
executable
startswithrE   formatr   r_   r'   floatboolversion_infor   tupler   which)versionZlazyfullpathr   r   r   baseZIS_PYPYtargetr&   DOTZ	pyversionZDASHZ
sysversionr   r   r   which_python  s2    
" 

r      c           	      C   s   ddl m} t|}d}tjddd}tj| s|rB|ddd ddl}|	| |d	7 }||kr&|stt
d
|  td|  qq&dS )a  block execution by waiting for a file to appear at the given path
        
    Args:
        path (str): the path string to watch for the file.
        sleep (float, default=1): the time between checking results.
        tries (int, default=150): the number of times to try.
        ignore_errors (bool, default=False): if True, ignore timeout error.

    Returns:
        None

    Notes:
        if the file is not found after the given number of tries, an error
        will be thrown unless ``ignore_error=True``.

        using ``subproc = Popen(...)`` and ``subproc.wait()`` is usually
        a better approach. However, when a handle to the subprocess is
        unavailable, waiting for a file to appear at a given path is a
        decent last resort.
    r   )callsyncFre   T)shellNr   rh   z$Warning: exceeded timeout (%s tries))
subprocessr   r   r   r   r   r+   existstimesleepIOErrorr>   )	r+   r   triesr   r   Zmaxcountri   r   r   r   r   r   wait_for  s    r   __main__)NN)NNT)r   FF)r   TT)NFTT)r   FFT)r   FT)NNF)FF)FFTT)r   r   F)__doc__r   r   r   Z_diskr   r   r   r   r   r/   rL   rB   r^   ra   ru   rr   r   r   r   r   r   Z
makefilterZgetVarsZreplaceTextZgetLinesZ
makeTargetZparseTargetZ	prunelistZ	prunedict__name__r   r   r   r   <module>
   s8   6
$
/


.
>
+


8
&
