U
    `»{jô=  ã                   @   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mZ ddl	m
Z
 ddlmZ G dd„ dejƒZG d	d
„ d
eƒZG dd„ deƒZG dd„ dƒZdS )z
Post-processing hooks
é    N)ÚZipFile)ÚTarFileé   )Ú
get_loggerc                   @   sP   e Zd ZdZddd„Zeejdd„ ƒƒZejdd„ ƒZ	ejd	d
„ ƒZ
dd„ ZdS )ÚExtractorProcessoraà  
    Abstract base class for extractions from compressed archives.

    Subclasses can be used with :meth:`pooch.Pooch.fetch` and
    :func:`pooch.retrieve` to unzip a downloaded data file into a folder in the
    local data store. :meth:`~pooch.Pooch.fetch` will return a list with the
    names of the extracted files instead of the archive.

    Parameters
    ----------
    members : list or None
        If None, will unpack all files in the archive. Otherwise, *members*
        must be a list of file names to unpack from the archive. Only these
        files will be unpacked.
    extract_dir : str or None
        If None, files will be unpacked to the default location (a folder in
        the same location as the downloaded zip file, with a suffix added).
        Otherwise, files will be unpacked to ``extract_dir``, which is
        interpreted as a *relative path* (relative to the cache location
        provided by :func:`pooch.retrieve` or :meth:`pooch.Pooch.fetch`).

    Nc                 C   s   || _ || _d S ©N)ÚmembersÚextract_dir)Úselfr   r	   © r   úO/var/www/html/bwave/python/venv/lib/python3.8/site-packages/pooch/processors.pyÚ__init__/   s    zExtractorProcessor.__init__c                 C   s   dS )zš
        String appended to unpacked archive folder name.
        Only used if extract_dir is None.
        MUST BE IMPLEMENTED BY CHILD CLASSES.
        Nr   ©r
   r   r   r   Úsuffix3   s    zExtractorProcessor.suffixc                 C   s   dS )zf
        Return all the members in the archive.
        MUST BE IMPLEMENTED BY CHILD CLASSES.
        Nr   )r
   Úfnamer   r   r   Ú_all_members<   s    zExtractorProcessor._all_membersc                 C   s   dS )z�
        This method receives an argument for the archive to extract and the
        destination path.
        MUST BE IMPLEMENTED BY CHILD CLASSES.
        Nr   )r
   r   r	   r   r   r   Ú_extract_fileC   s    z ExtractorProcessor._extract_filec              
      s0  ˆj dkr|ˆj ˆ_ n(|jtjjdd�d }tj |ˆj ¡ˆ_ ˆjdksPˆjs\ˆ |¡}nˆj}|dksŽtj 	ˆj ¡rŽt
‡fdd„|D ƒƒs¬tjˆj dd	� ˆ |ˆj ¡ g }t ˆj ¡D ]n\}}}	|	D ]^}
tj tj tj |ˆj ¡|
¡¡‰ ˆjdk�st‡ fd
d„ˆjD ƒƒrÊ| tj ||
¡¡ qÊq¼|S )a  
        Extract all files from the given archive.

        Parameters
        ----------
        fname : str
            Full path of the zipped file in local storage.
        action : str
            Indicates what action was taken by :meth:`pooch.Pooch.fetch` or
            :func:`pooch.retrieve`:

            * ``"download"``: File didn't exist locally and was downloaded
            * ``"update"``: Local file was outdated and was re-download
            * ``"fetch"``: File exists and is updated so it wasn't downloaded

        pooch : :class:`pooch.Pooch`
            The instance of :class:`pooch.Pooch` that is calling this.

        Returns
        -------
        fnames : list of str
            A list of the full path to all files in the extracted archive.

        Nr   )Úmaxsplitr   ©ÚupdateÚdownloadc                 3   s&   | ]}t j t j ˆ j|¡¡V  qd S r   )ÚosÚpathÚexistsÚjoinr	   ©Ú.0Úmr   r   r   Ú	<genexpr>s   s    z.ExtractorProcessor.__call__.<locals>.<genexpr>T)Úexist_okc                 3   s    | ]}ˆ   tj |¡¡V  qd S r   )Ú
startswithr   r   Únormpathr   )Úrelpathr   r   r   ƒ   s    )r	   r   Úrsplitr   r   Úsepr   r   r   r   ÚallÚmakedirsr   Úwalkr!   r"   ÚanyÚappend)r
   r   ÚactionÚpoochÚarchive_dirr   Úfnamesr   Ú_ÚfilesÚfilenamer   )r"   r
   r   Ú__call__K   s8    
ÿþÿýÿÿzExtractorProcessor.__call__)NN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   ÚpropertyÚabcÚabstractmethodr   r   r   r1   r   r   r   r   r      s   


r   c                   @   s,   e Zd ZdZedd„ ƒZdd„ Zdd„ ZdS )	ÚUnzipa  
    Processor that unpacks a zip archive and returns a list of all files.

    Use with :meth:`pooch.Pooch.fetch` or :func:`pooch.retrieve` to unzip a
    downloaded data file into a folder in the local data store. The
    method/function will return a list with the names of the unzipped files
    instead of the zip archive.

    The output folder is ``{fname}.unzip``.

    Parameters
    ----------
    members : list or None
        If None, will unpack all files in the zip archive. Otherwise, *members*
        must be a list of file names to unpack from the archive. Only these
        files will be unpacked.
    extract_dir : str or None
        If None, files will be unpacked to the default location (a folder in
        the same location as the downloaded zip file, with the suffix
        ``.unzip`` added). Otherwise, files will be unpacked to
        ``extract_dir``, which is interpreted as a *relative path* (relative to
        the cache location provided by :func:`pooch.retrieve` or
        :meth:`pooch.Pooch.fetch`).

    c                 C   s   dS )úl
        String appended to unpacked archive folder name.
        Only used if extract_dir is None.
        z.unzipr   r   r   r   r   r   ¦   s    zUnzip.suffixc              
   C   s*   t |dƒ�}| ¡ W  5 Q R £ S Q R X dS )ú(Return all members from a given archive.ÚrN)r   Únamelist)r
   r   Úzip_filer   r   r   r   ®   s    zUnzip._all_membersc              	      s„   t |dƒ�p}| jdkr4tƒ  d||¡ |j|d� nB| jD ]:‰ tƒ  dˆ ||¡ ‡ fdd„| ¡ D ƒ}|j||d� q:W 5 Q R X dS )	úo
        This method receives an argument for the archive to extract and the
        destination path.
        r<   Nz"Unzipping contents of '%s' to '%s'©r   ú!Extracting '%s' from '%s' to '%s'c                    s*   g | ]"}t j |¡ t j ˆ ¡¡r|‘qS r   )r   r   r!   r    )r   Úname©Úmemberr   r   Ú
<listcomp>Ê   s   þz'Unzip._extract_file.<locals>.<listcomp>©r   r   )r   r   r   ÚinfoÚ
extractallr=   )r
   r   r	   r>   Úsubdir_membersr   rC   r   r   ³   s&    
  ÿ
   ÿ	
þzUnzip._extract_fileN©r2   r3   r4   r5   r6   r   r   r   r   r   r   r   r9   ‹   s
   
r9   c                   @   s,   e Zd ZdZedd„ ƒZdd„ Zdd„ ZdS )	ÚUntara  
    Processor that unpacks a tar archive and returns a list of all files.

    Use with :meth:`pooch.Pooch.fetch` or :func:`pooch.retrieve` to untar a
    downloaded data file into a folder in the local data store. The
    method/function will return a list with the names of the extracted files
    instead of the archive.

    The output folder is ``{fname}.untar``.


    Parameters
    ----------
    members : list or None
        If None, will unpack all files in the archive. Otherwise, *members*
        must be a list of file names to unpack from the archive. Only these
        files will be unpacked.
    extract_dir : str or None
        If None, files will be unpacked to the default location (a folder in
        the same location as the downloaded tar file, with the suffix
        ``.untar`` added). Otherwise, files will be unpacked to
        ``extract_dir``, which is interpreted as a *relative path* (relative to
        the cache location  provided by :func:`pooch.retrieve` or
        :meth:`pooch.Pooch.fetch`).
    c                 C   s   dS )r:   z.untarr   r   r   r   r   r   î   s    zUntar.suffixc              
   C   s6   t  |d¡� }dd„ | ¡ D ƒW  5 Q R £ S Q R X dS )r;   r<   c                 S   s   g | ]
}|j ‘qS r   )rB   ©r   rG   r   r   r   rE   ù   s     z&Untar._all_members.<locals>.<listcomp>N)r   ÚopenÚ
getmembers)r
   r   Útar_filer   r   r   r   ö   s    zUntar._all_membersc              	      s†   t  |d¡�p}| jdkr6tƒ  d||¡ |j|d� nB| jD ]:‰ tƒ  dˆ ||¡ ‡ fdd„| ¡ D ƒ}|j||d� q<W 5 Q R X dS )	r?   r<   Nz"Untarring contents of '%s' to '%s'r@   rA   c                    s,   g | ]$}t j |j¡ t j ˆ ¡¡r|‘qS r   )r   r   r!   rB   r    rL   rC   r   r   rE     s
   
ÿþz'Untar._extract_file.<locals>.<listcomp>rF   )r   rM   r   r   rG   rH   rN   )r
   r   r	   rO   rI   r   rC   r   r   û   s&    
  ÿ
   ÿ
þzUntar._extract_fileNrJ   r   r   r   r   rK   Ó   s
   
rK   c                   @   sF   e Zd ZdZdeeeedœZddddœZdd	d
„Z	dd„ Z
dd„ ZdS )Ú
Decompressa3  
    Processor that decompress a file and returns the decompressed version.

    Use with :meth:`pooch.Pooch.fetch` or :func:`pooch.retrieve` to decompress
    a downloaded data file so that it can be easily opened. Useful for data
    files that take a long time to decompress (exchanging disk space for
    speed).

    Supported decompression methods are LZMA (``.xz``), bzip2 (``.bz2``), and
    gzip (``.gz``).

    File names with the standard extensions (see above) can use
    ``method="auto"`` to automatically determine the compression method. This
    can be overwritten by setting the *method* argument.

    .. note::

        To unpack zip and tar archives with one or more files, use
        :class:`pooch.Unzip` and :class:`pooch.Untar` instead.

    The output file is ``{fname}.decomp`` by default but it can be changed by
    setting the ``name`` parameter.

    .. warning::

        Passing in ``name`` can cause existing data to be lost! For example, if
        a file already exists with the specified name it will be overwritten
        with the new decompressed file content. **Use this option with
        caution.**

    Parameters
    ----------
    method : str
        Name of the compression method. Can be "auto", "lzma", "xz", "bzip2",
        or "gzip".
    name : None or str
        Defines the decompressed file name. The file name will be
        ``{fname}.decomp`` if ``None`` (default) or the given name otherwise.
        Note that the name should **not** include the full (or relative) path,
        it should be just the file name itself.

    N)ÚautoÚlzmaÚxzÚgzipÚbzip2rR   rT   rU   )z.xzz.gzz.bz2rQ   c                 C   s   || _ || _d S r   )ÚmethodrB   )r
   rV   rB   r   r   r   r   N  s    zDecompress.__init__c              
   C   sš   | j dkr|d }ntj tj |¡| j ¡}|dks@tj |¡s–tƒ  d||| j¡ |  	|¡}t
|dƒ�(}| 
|¡�}t ||¡ W 5 Q R X W 5 Q R X |S )aK  
        Decompress the given file.

        The output file will be either ``{fname}.decomp`` or the given *name*
        class attribute.

        Parameters
        ----------
        fname : str
            Full path of the compressed file in local storage.
        action : str
            Indicates what action was taken by :meth:`pooch.Pooch.fetch` or
            :func:`pooch.retrieve`:

            - ``"download"``: File didn't exist locally and was downloaded
            - ``"update"``: Local file was outdated and was re-download
            - ``"fetch"``: File exists and is updated so it wasn't downloaded

        pooch : :class:`pooch.Pooch`
            The instance of :class:`pooch.Pooch` that is calling this.

        Returns
        -------
        fname : str
            The full path to the decompressed file.
        Nz.decompr   z-Decompressing '%s' to '%s' using method '%s'.zw+b)rB   r   r   r   Údirnamer   r   rG   rV   Ú_compression_modulerM   ÚshutilÚcopyfileobj)r
   r   r*   r+   ÚdecompressedÚmoduleÚoutputÚ
compressedr   r   r   r1   R  s    

ü
 zDecompress.__call__c                 C   sÈ   d}| j | jkrNd| j › dt| j ¡ ƒ› d�}| j dkrFd ||g¡}t|ƒ‚| j dkr¼tj |¡d }|| j	kr¬d	|› dt| j	 ¡ ƒ› d�}|d
kr¤d ||g¡}t|ƒ‚| j| j	|  S | j| j  S )a  
        Get the Python module compatible with fname and the chosen method.

        If the *method* attribute is "auto", will select a method based on the
        extension. If no recognized extension is in the file name, will raise a
        ValueError.
        z:To unpack zip/tar archives, use pooch.Unzip/Untar instead.zInvalid compression method 'z'. Must be one of 'z'.>   ÚzipÚtarú rQ   éÿÿÿÿzUnrecognized file extension '>   ú.zipú.tar)
rV   ÚmodulesÚlistÚkeysr   Ú
ValueErrorr   r   ÚsplitextÚ
extensions)r
   r   Zerror_archivesÚmessageÚextr   r   r   rX   ~  s"    ÿ


ÿzDecompress._compression_module)rQ   N)r2   r3   r4   r5   rR   rT   Úbz2re   rj   r   r1   rX   r   r   r   r   rP     s   +
,rP   )r5   r7   r   rm   rT   rR   rY   Úzipfiler   Útarfiler   Úutilsr   ÚABCr   r9   rK   rP   r   r   r   r   Ú<module>   s   tHL