o
    ٷi>                     @   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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      || _ || _d S N)membersextract_dir)selfr	   r
    r   D/home/ubuntu/.local/lib/python3.10/site-packages/pooch/processors.py__init__1      
zExtractorProcessor.__init__c                 C      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   suffix5       zExtractorProcessor.suffixc                 C   r   )zf
        Return all the members in the archive.
        MUST BE IMPLEMENTED BY CHILD CLASSES.
        Nr   )r   fnamer   r   r   _all_members>   r   zExtractorProcessor._all_membersc                 C   r   )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_fileE   r   z ExtractorProcessor._extract_filec              
      s.  j du r|j _ n|jtjjddd }tj|j _ jdu s(js.|}nj}|dv sGtj	j rGt
fdd|D sVtjj dd	 |j  g }tj D ]6\}}}	|	D ].}
tjtjtj|j |
 jdu st fd
djD r|tj||
 qeq^|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>u   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__M   s:   
	zExtractorProcessor.__call__)NN)__name__
__module____qualname____doc__r   propertyabcabstractmethodr   r   r   r5   r   r   r   r   r      s    


r   c                   @   ,   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   r   )l
        String appended to unpacked archive folder name.
        Only used if extract_dir is None.
        z.unzipr   r   r   r   r   r         zUnzip.suffixc                 C   s6   t |d}| W  d   S 1 sw   Y  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F}| jdu rt d|| |j|d n!| jD ]% t d ||  fdd| D }|j||d qW d   dS W d   dS 1 sNw   Y  dS )	o
        This method receives an argument for the archive to extract and the
        destination path.
        rB   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
extractallrC   )r   r   r
   rD   subdir_membersr   rH   r   r      s$   


	"zUnzip._extract_fileNr6   r7   r8   r9   r:   r   r   r   r   r   r   r   r>          
r>   c                   @   r=   )	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   r   )r?   z.untarr   r   r   r   r   r      r@   zUntar.suffixc                 C   sB   t |d}dd | D W  d   S 1 sw   Y  dS )rA   rB   c                 S   s   g | ]}|j qS r   )rG   r    rL   r   r   r   rJ      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 jdk ri nddi}t|dN}| jdu r*t d|| |jdd|i| n%| jD ]) t d ||  fd	d
| D }|jd||d| q-W d   dS W d   dS 1 sbw   Y  dS )rE   )      filterdatarB   Nz"Untarring contents of '%s' to '%s'r   rF   c                    s,   g | ]}t j|jt j r|qS r   )r   r   r%   rG   r$   rR   rH   r   r   rJ     s    
z'Untar._extract_file.<locals>.<listcomp>rK   r   )	sysversion_infor   rS   r	   r   rL   rM   rT   )r   r   r
   filter_kwargrU   rN   r   rH   r   r      s.   


"zUntar._extract_fileNrO   r   r   r   r   rQ      rP   rQ   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bzip2r_   ra   rb   )z.xzz.gzz.bz2r^   c                 C   r   r   )methodrG   )r   rc   rG   r   r   r   r   S  r   zDecompress.__init__c              	   C   s   | j du r
|d }ntjtj|| j }|dv s tj|sht d||| j | 	|}t
|d,}|
|}t|| W d   n1 sKw   Y  W d   |S W d   |S 1 scw   Y  |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)rG   r   r   r   dirnamer   r   rL   rc   _compression_modulerS   shutilcopyfileobj)r   r   r.   r/   decompressedmoduleoutput
compressedr   r   r   r5   W  s,   




zDecompress.__call__c                 C   s   d}| j | jvr'd| j  dt| j  d}| j dv r#d||g}t|| j dkr^tj|d }|| j	vrVd	| dt| j	  d}|d
v rRd||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'.>   tarzip r^   zUnrecognized file extension '>   .tar.zip)
rc   moduleslistkeysr   
ValueErrorr   r   splitext
extensions)r   r   error_archivesmessageextr   r   r   re     s*   



zDecompress._compression_module)r^   N)r6   r7   r8   r9   r_   ra   bz2rr   rw   r   r5   re   r   r   r   r   r]   $  s    +
,r]   )r9   r;   r   r{   ra   r_   rf   rZ   zipfiler   tarfiler   utilsr   ABCr   r>   rQ   r]   r   r   r   r   <module>   s   tHO