Your IP : 216.73.216.213


Current Path : /opt/alt/python37/lib/python3.7/site-packages/logilab/common/__pycache__/
Upload File :
Current File : //opt/alt/python37/lib/python3.7/site-packages/logilab/common/__pycache__/fileutils.cpython-37.pyc

B

�d{T�1�@srdZddlmZdZddlZddlZddlZddlmZm	Z	m
Z
mZmZm
Z
mZddlmZddlmZmZmZmZmZmZmZddlmZmZdd	lmZmZdd
lmZddl m!Z!ddl"m#Z#d
d�Z$dd�Z%dd�Z&dd�Z'efdd�Z(Gdd�de#�Z)Gdd�de*�Z+dd�Z,dd�Z-e!d�e-�Z-d d!�Z.e!d"�e.�Z.d+d#d$�Z/d,d%d&�Z0eedfd'd(�Z1d-d)d*�Z2dS).a3File and file-path manipulation utilities.

:group path manipulation: first_level_directory, relative_path, is_binary,get_by_ext, remove_dead_links
:group file manipulation: norm_read, norm_open, lines, stream_lines, lines,write_open_mode, ensure_fs_mode, export
:sort: path manipulation, file manipulation
�)�print_functionzrestructuredtext enN)�isabs�isdir�islink�split�exists�normpath�join)�abspath)�sep�mkdir�remove�listdir�stat�chmod�walk)�ST_MODE�S_IWRITE)�
STD_BLACKLIST�IGNORED_EXTENSIONS)�find)�
deprecated)�FileIOcCs2t|�\}}x|r$|r$t|�\}}qW|r.|S|S)a�Return the first level directory of a path.

    >>> first_level_directory('home/syt/work')
    'home'
    >>> first_level_directory('/home/syt/work')
    '/'
    >>> first_level_directory('work')
    'work'
    >>>

    :type path: str
    :param path: the path for which we want the first level directory

    :rtype: str
    :return: the first level directory appearing in `path`
    )r)�path�head�tail�r�I/opt/alt/python37/lib/python3.7/site-packages/logilab/common/fileutils.py�first_level_directory,s
rcst����fdd�t��D�S)z�Lists path's content using absolute paths.

    >>> os.listdir('/home')
    ['adim', 'alf', 'arthur', 'auc']
    >>> abspath_listdir('/home')
    ['/home/adim', '/home/alf', '/home/arthur', '/home/auc']
    csg|]}t�|��qSr)r	)�.0�filename)rrr�
<listcomp>Nsz#abspath_listdir.<locals>.<listcomp>)r
r)rr)rr�abspath_listdirEsr"cCs0yt�|�d�d�Stk
r*dSXdS)aReturn true if filename may be a binary file, according to it's
    extension.

    :type filename: str
    :param filename: the name of the file

    :rtype: bool
    :return:
      true if the file is a binary file (actually if it's mime type
      isn't beginning by text/)
    r�text�N)�	mimetypesZ
guess_type�
startswith�AttributeError)r rrr�	is_binaryQsr(cCst|�rdSdS)z�Return the write mode that should used to open file.

    :type filename: str
    :param filename: the name of the file

    :rtype: str
    :return: the mode that should be use to open the file ('w' or 'wb')
    �wb�w)r()r rrr�write_open_modecs	r+cCs&t|�t}||@s"t|||B�dS)a;Check that the given file has the given mode(s) set, else try to
    set it.

    :type filepath: str
    :param filepath: path of the file

    :type desired_mode: int
    :param desired_mode:
      ORed flags describing the desired mode. Use constants from the
      `stat` module for file permission's modes
    N)rrr)�filepathZdesired_mode�moderrr�ensure_fs_modeqsr.c@s0eZdZdZdd�Zdd�Zdd�Zdd	�Zd
S)�
ProtectedFileaKA special file-object class that automatically does a 'chmod +w' when
    needed.

    XXX: for now, the way it is done allows 'normal file-objects' to be
    created during the ProtectedFile object lifetime.
    One way to circumvent this would be to chmod / unchmod on each
    write operation.

    One other way would be to :

    - catch the IOError in the __init__

    - if IOError, then create a StringIO object

    - each write operation writes in this StringIO object

    - on close()/del(), write/append the StringIO content to the file and
      do the chmod only once
    cCsNt|�t|_d|_|dkr<|jt@s<t||jtB�d|_t�|||�dS)NF)r*�ar)�abT)rr�
original_mode�mode_changedrrr�__init__)�selfr,r-rrrr4�s
zProtectedFile.__init__cCs|jrt|j|j�d|_dS)z$restores the original mode if neededFN)r3r�namer2)r5rrr�
_restore_mode�szProtectedFile._restore_modecCs|��t�|�dS)zrestore mode before closingN)r7r�close)r5rrrr8�szProtectedFile.closecCs|js|��dS)N)�closedr8)r5rrr�__del__�szProtectedFile.__del__N)�__name__�
__module__�__qualname__�__doc__r4r7r8r:rrrrr/�s
	r/c@seZdZdZdS)�UnresolvableErrorzgException raised by relative path when it's unable to compute relative
    path between two paths.
    N)r;r<r=r>rrrrr?�sr?cCs�t|�}t|�}||krdSt|�r2t|�s@|Snt|�r@t��|�t�}|�t�}d}g}xPt|�dkr�|�d�}|r�t|�dkr�||dkr�|�d�q^d}|�d�q^W||7}t�|�S)ajTry to get a relative path from `from_file` to `to_file`
    (path will be absolute if to_file is an absolute file). This function
    is useful to create link in `from_file` to `to_file`. This typical use
    case is used in this function description.

    If both files are relative, they're expected to be relative to the same
    directory.

    >>> relative_path( from_file='toto/index.html', to_file='index.html')
    '../index.html'
    >>> relative_path( from_file='index.html', to_file='toto/index.html')
    'toto/index.html'
    >>> relative_path( from_file='tutu/index.html', to_file='toto/index.html')
    '../toto/index.html'
    >>> relative_path( from_file='toto/index.html', to_file='/index.html')
    '/index.html'
    >>> relative_path( from_file='/toto/index.html', to_file='/index.html')
    '../index.html'
    >>> relative_path( from_file='/toto/index.html', to_file='/toto/summary.html')
    'summary.html'
    >>> relative_path( from_file='index.html', to_file='index.html')
    ''
    >>> relative_path( from_file='/index.html', to_file='toto/index.html')
    Traceback (most recent call last):
      File "<string>", line 1, in ?
      File "<stdin>", line 37, in relative_path
    UnresolvableError
    >>> relative_path( from_file='/index.html', to_file='/index.html')
    ''
    >>>

    :type from_file: str
    :param from_file: source file (where links will be inserted)

    :type to_file: str
    :param to_file: target file (on which links point)

    :raise UnresolvableError: if it has been unable to guess a correct path

    :rtype: str
    :return: the relative path of `to_file` from `from_file`
    �r$rz..)	rrr?rr�len�pop�appendr	)�	from_fileZto_fileZ
from_partsZto_partsZidem�result�dirnamerrr�
relative_path�s*+


rGcCst|d���S)z�Return the content of the file with normalized line feeds.

    :type path: str
    :param path: path to the file to read

    :rtype: str
    :return: the content of the file with normalized line feeds
    �U)�open�read)rrrr�	norm_read�s	rKzuse "open(path, 'U').read()"cCs
t|d�S)z�Return a stream for a file with content with normalized line feeds.

    :type path: str
    :param path: path to the file to open

    :rtype: file or StringIO
    :return: the opened file with normalized line feeds
    rH)rI)rrrr�	norm_opens	rLzuse "open(path, 'U')"cCs t|d�}t||�}|��|S)a�Return a list of non empty lines in the file located at `path`.

    :type path: str
    :param path: path to the file

    :type comments: str or None
    :param comments:
      optional string which can be used to comment a line in the file
      (i.e. lines starting with this string won't be returned)

    :rtype: list
    :return:
      a list of stripped line in the file, without empty and commented
      lines

    :warning: at some point this function will probably return an iterator
    rH)rI�stream_linesr8)r�comments�streamrErrr�liness

rPcCsfy
|j}Wntk
r$|j}YnXg}x6|�D],}|��}|r2|dksT|�|�s2|�|�q2W|S)aReturn a list of non empty lines in the given `stream`.

    :type stream: object implementing 'xreadlines' or 'readlines'
    :param stream: file like object

    :type comments: str or None
    :param comments:
      optional string which can be used to comment a line in the file
      (i.e. lines starting with this string won't be returned)

    :rtype: list
    :return:
      a list of stripped line in the file, without empty and commented
      lines

    :warning: at some point this function will probably return an iterator
    N)Z
xreadlinesr'�	readlines�stripr&rC)rOrNrQrE�linerrrrM)s
rMc
s2yt|�Wntk
r YnX�xt|�D]�\}}}x2|D]*}y|�|�Wq>tk
rfw>Yq>Xq>WxB|D]:}	t||	�}
||
t|�d�}t|
�rrt|�srt|�qrWxx|D]p�t	�fdd�|D��r�q�t|��}
||
t|�d�}|�rt
|
d|tjd�t|��rt|�t
�|
|�q�Wq.WdS)a�Make a mirror of `from_dir` in `to_dir`, omitting directories and
    files listed in the black list or ending with one of the given
    extensions.

    :type from_dir: str
    :param from_dir: directory to export

    :type to_dir: str
    :param to_dir: destination directory

    :type blacklist: list or tuple
    :param blacklist:
      list of files or directories to ignore, default to the content of
      `BASE_BLACKLIST`

    :type ignore_ext: list or tuple
    :param ignore_ext:
      list of extensions to ignore, default to  the content of
      `IGNORED_EXTENSIONS`

    :type verbose: bool
    :param verbose:
      flag indicating whether information about exported files should be
      printed to stderr, default to False
    Ncsg|]}��|��qSr)�endswith)r�ext)r rrr!wszexport.<locals>.<listcomp>z->)�file)r�OSErrorrr
�
ValueErrorr	rArr�any�print�sys�stderr�shutil�copy2)Zfrom_dirZto_dirZ	blacklistZ
ignore_ext�verbose�	directory�dirnames�	filenamesZnorecursrF�src�destr)r r�exportGs4





recCs^xXt|�D]L\}}}x@t|D]4}t||�}t|�rt|�s|rJtd|�t|�qWq
WdS)a"Recursively traverse directory and remove all dead links.

    :type directory: str
    :param directory: directory to cleanup

    :type verbose: bool
    :param verbose:
      flag indicating whether information about deleted links should be
      printed to stderr, default to False
    zremove dead linkN)rrar	rrrZr
)r`r_�dirpathrFrbr rcrrr�remove_dead_links�s

rg)N)N)r)3r>�
__future__r�
__docformat__r[r]r%�os.pathrrrrrrr	r
�osrrr
rrrrrrZlogilab.commonrZBASE_BLACKLISTrZlogilab.common.shellutilsrZlogilab.common.deprecationrZlogilab.common.compatrrr"r(r+r.r/�	Exceptionr?rGrKrLrPrMrergrrrr�<module>s<$$.C



9