
    ob\E                        d Z ddlmZm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 ddlmZ dd	lmZ dd
lmZmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZmZmZm Z  ddl!m"Z" ddl#m$Z$ ddl%m&Z& ejN                  r8ddlm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1 ddlm2Z2 ddl3m4Z4  ejj                  dd      Z6 G d de      Z7 G d de&      Z8ejr                   G d de&             Z:ejr                   G d de             Z;y) z(Manage the filesystem in a Zip archive.
    )print_functionunicode_literalsN)datetime   )errors)	url_quote)FS)	write_zip)ResourceTypeSeek)Info)
RawWrapper)MemoryFS)open_fs)dirnameforcedirnormpathrelpath)Permissions)datetime_to_epoch)WrapFS)
AnyBinaryIO
CollectionDictListOptionalSupportsIntTextTupleUnion)RawInfo)SubFSR	ReadZipFS)boundc                        e Zd Z fdZej
                  dk  r!d	dZd	dZd Zd Z	e
j                  fdZ xZS e
j                  fdZ xZS )
_ZipExtFilec                     |j                   x| _         }|j                  |      j                  | _        d| _        t
        t        |   |j                  |      d|       y )Nr   r)	_zipgetinfo	file_size_end_possuperr(   __init__open)selffsnamer+   	__class__s       */usr/lib/python3/dist-packages/fs/zipfs.pyr1   z_ZipExtFile.__init__0   sK    77"	DLL&00		k4)$))D/3E    )      c                     | j                   j                  |dn|      }| xj                  t        |      z  c_        |S N)_freadr/   lenr3   sizebufs      r7   r?   z_ZipExtFile.read>   s1    '',,T\rt<CIIS!IJr8   c                     | j                   j                  |dn|      }| xj                  t        |      z  c_        |S r<   )r>   read1r/   r@   rA   s      r7   rE   z_ZipExtFile.read1D   s1    ''--dl=CIIS!IJr8   c                     | j                   S N)r/   r3   s    r7   tellz_ZipExtFile.tellJ   s    99r8   c                      y)NT rH   s    r7   seekablez_ZipExtFile.seekableN   s    r8   c                    t        |      }|t        j                  k(  r|| j                  z  }|t        j                  k(  s|t        j                  k(  r|dk  rt        dj                  |            |t        j                  k(  r/|dkD  rt        dj                  |            || j                  z  }nGt        dj                  |t        j                  t        j                  t        j                              || j                  k  r1| j                  j                  | j                        | _        d| _        | j                  || j                  z
         | j                  S )af  Change stream position.

            Change the stream position to the given byte offset. The
            offset is interpreted relative to the position indicated by
            ``whence``.

            Arguments:
                offset (int): the offset to the new position, in bytes.
                whence (int): the position reference. Possible values are:
                    * `Seek.set`: start of stream (the default).
                    * `Seek.current`: current position; offset may be negative.
                    * `Seek.end`: end of stream; offset must be negative.

            Returns:
                int: the new absolute position.

            Raises:
                ValueError: when ``whence`` is not known, or ``offset``
                    is invalid.

            Note:
                Zip compression does not support seeking, so the seeking
                is emulated. Seeking somewhere else than the current position
                will need to either:
                    * reopen the file and restart decompression
                    * read and discard data to advance in the file

            r   Negative seek position {}Positive seek position {}+Invalid whence ({}, should be {}, {} or {}))intr   currentr/   set
ValueErrorformatendr.   r+   r2   r5   r>   r?   )r3   offsetwhence_whences       r7   seekz_ZipExtFile.seekQ   s   < &kG$,,&$))#$,,&'TXX*=A:$%@%G%G%OPPDHH$A:$%@%G%G%OPP$))# AHH4<<  		!))..3	IIftyy()99r8   c                 0   t        |      }| j                         }|t        j                  k(  r|dk  rt	        dj                  |            |t        j                  k(  r"||z   dk  rt	        dj                  |            |t        j                  k(  r|dkD  rat	        dj                  |            t	        dj                  |t        j                  t        j                  t        j                              | j                  j                  ||      S )a  Change stream position.

            Change the stream position to the given byte offset. The
            offset is interpreted relative to the position indicated by
            ``whence``.

            Arguments:
                offset (int): the offset to the new position, in bytes.
                whence (int): the position reference. Possible values are:
                    * `Seek.set`: start of stream (the default).
                    * `Seek.current`: current position; offset may be negative.
                    * `Seek.end`: end of stream; offset must be negative.

            Returns:
                int: the new absolute position.

            Raises:
                ValueError: when ``whence`` is not known, or ``offset``
                    is invalid.

            r   rN   rO   rP   )
rQ   rI   r   rS   rT   rU   rR   rV   r>   rZ   )r3   rW   rX   rY   r/   s        r7   rZ   z_ZipExtFile.seek   s    . &kG99;D$(("A:$%@%G%G%OPPDLL(&=1$$%@%G%G%OPPDHH$A:$%@%G%G%OPP AHH4<<  77<<00r8   )r=   )__name__
__module____qualname__r1   sysversion_infor?   rE   rI   rL   r   rS   rZ   __classcell__r6   s   @r7   r(   r(   /   sJ    F & 				 '+hh 3	n '+hh )	1r8   r(   c                   r    e Zd ZdZdej
                  ddfdZej                  rdej
                  ddfdZ	yy)ZipFSa.  Read and write zip files.

    There are two ways to open a `ZipFS` for the use cases of reading
    a zip file, and creating a new one.

    If you open the `ZipFS` with  ``write`` set to `False` (the default)
    then the filesystem will be a read-only filesystem which maps to
    the files and directories within the zip file. Files are
    decompressed on the fly when you open them.

    Here's how you might extract and print a readme from a zip file::

        with ZipFS('foo.zip') as zip_fs:
            readme = zip_fs.readtext('readme.txt')

    If you open the `ZipFS` with ``write`` set to `True`, then the `ZipFS`
    will be an empty temporary filesystem. Any files / directories you
    create in the `ZipFS` will be written in to a zip file when the `ZipFS`
    is closed.

    Here's how you might write a new zip file containing a ``readme.txt``
    file::

        with ZipFS('foo.zip', write=True) as new_zip:
            new_zip.writetext(
                'readme.txt',
                'This zip file was written by PyFilesystem'
            )


    Arguments:
        file (str or io.IOBase): An OS filename, or an open file object.
        write (bool): Set to `True` to write a new zip file, or `False`
            (default) to read an existing zip file.
        compression (int): Compression to use (one of the constants
            defined in the `zipfile` module in the stdlib).
        temp_fs (str or FS): An FS URL or an FS instance to use to
            store data prior to zipping. Defaults to creating a new
            `~fs.tempfs.TempFS`.

    Futf-8temp://__ziptemp__c                 >    |rt        ||||      S t        ||      S )N)compressionencodingtemp_fs)ri   )
WriteZipFSr%   )clsfilewriterh   ri   rj   s         r7   __new__zZipFS.__new__   s,     +'  TH55r8   c                      y rG   rK   )r3   rm   rn   rh   ri   rj   s         r7   r1   zZipFS.__init__   s     r8   N)
r\   r]   r^   __doc__zipfileZIP_DEFLATEDro   typingTYPE_CHECKINGr1   rK   r8   r7   rd   rd      sJ    (\ (($6$ 
 ,,(		 r8   rd   c                   n     e Zd ZdZej
                  ddf fd	Zd Zd Zd Z	d Z
 fd	Z	 	 	 dd
Z xZS )rk   zA writable zip file.re   rf   c                     || _         || _        || _        || _        t	        |      | _        t        | j
                  j                               | _        t        t        | /  | j
                         y rG   )_filerh   ri   _temp_fs_urlr   _temp_fsdictgetmeta_metar0   rk   r1   )r3   rm   rh   ri   rj   r6   s        r7   r1   zWriteZipFS.__init__  s[     
& #($--//12
j$(7r8   c                 ~    d}|j                  | j                  | j                  | j                  | j                        S )Nz?WriteZipFS({!r}, compression={!r}, encoding={!r}, temp_fs={!r}))rU   rx   rh   ri   ry   )r3   ts     r7   __repr__zWriteZipFS.__repr__  s0    Mxx

D$4$4dmmTEVEVWWr8   c                 8    dj                  | j                        S )Nz<zipfs-write '{}'>rU   rx   rH   s    r7   __str__zWriteZipFS.__str__  s    #**4::66r8   c                     | j                   |fS rG   rz   r3   paths     r7   delegate_pathzWriteZipFS.delegate_path  s    }}d""r8   c                     | j                   S rG   r   rH   s    r7   delegate_fszWriteZipFS.delegate_fs!  s    }}r8   c                     | j                         s+	 | j                          | j                  j                          t        t
        |           y # | j                  j                          w xY wrG   )isclosedr
   rz   closer0   rk   r3   r6   s    r7   r   zWriteZipFS.close%  sL    }}& ##%j$%' ##%s   A A,c                     | j                         sDt        | j                  |xs | j                  |xs | j                  |xs | j
                         yy)a5  Write zip to a file.

        Arguments:
            file (str or io.IOBase, optional): Destination file, may be
                a file name or an open file handle.
            compression (int, optional): Compression to use (one of the
                constants defined in the `zipfile` module in the stdlib).
            encoding (str, optional): The character encoding to use
                (default uses the encoding defined in
                `~WriteZipFS.__init__`).

        Note:
            This is called automatically when the ZipFS is closed.

        )rh   ri   N)r   r
   rz   rx   rh   ri   )r3   rm   rh   ri   s       r7   r
   zWriteZipFS.write_zip.  sG    , }}"

';4+;+;!2T]]	 r8   )NNN)r\   r]   r^   rq   rr   rs   r1   r   r   r   r   r   r
   ra   rb   s   @r7   rk   rk      sF    
 (($8 X
7#( 	r8   rk   c                        e Zd ZdZddddddddZej                  j                  d fd	       Zd Z	d Z
d Zed	        Zdd
Zd Zd Z	 	 ddZddZd Zd Z fdZd ZddZ xZS )r%   zA readable zip file.FT)case_insensitivenetwork	read_onlysupports_renamethread_safeunicode_pathsvirtualc                     t         t        |           || _        || _        t        j                  |d      | _        d | _        y )Nr*   )	r0   r%   r1   rx   ri   rr   ZipFiler+   _directory_fs)r3   rm   ri   r6   s      r7   r1   zReadZipFS.__init__[  s:     	i')
 OOD#.	!r8   c                 8    dj                  | j                        S )NzReadZipFS({!r})r   rH   s    r7   r   zReadZipFS.__repr__d  s     ''

33r8   c                 8    dj                  | j                        S )Nz<zipfs '{}'>r   rH   s    r7   r   zReadZipFS.__str__h  s    $$TZZ00r8   c                     t        t        |            }| j                  j                  |      rt	        |      }t
        j                  r|j                  | j                        S |S )z"Convert a path to a zip file name.)	r   r   
_directoryisdirr   sixPY2encoderi   r   s     r7   _path_to_zip_namezReadZipFS._path_to_zip_namel  sL     x~&??  &D>D77;;t}}--r8   c                    | j                          | j                  5  | j                  t               x| _        }| j                  j                         D ]  }|}t        j                  r|j                  | j                  d      }|j                  d      r|j                  |d       V|j                  t        |      d       |j                  |        | j                  cddd       S # 1 sw Y   yxY w)zC`MemoryFS`: a filesystem with the same folder hierarchy as the zip.Nreplace/T)recreate)check_lockr   r   r+   namelistr   r   decoderi   endswithmakedirsr   create)r3   _fszip_nameresource_names       r7   r   zReadZipFS._directoryv  s     	

ZZ 	&!!)+3:5"S $		 2 2 4 2H$,Mww(5(<(<T]]I(V$--c2]TBW]%;dK

=12 %%	& 	& 	&s   CC//C8c                    | j                  |      }|xs d}i }|dk(  r6ddd|d<   d|v rdt        t        j                        i|d<   t1        |      S | j                  j                  |      }|j                  |j                  d|d<   h d	j                  |      s&| j                  |      }	 | j                  j                  |      }d|v r_|j                  t        |j                  rt        j                  nt        j                        t        t        |j                         d
|d<   d|v r9|j                   D ci c]   }|j#                  d      s|t%        ||      " c}|d<   d|v rU|j&                  rI|j(                  dk(  r:dt+        |j&                  dz	  dz        j-                         i|d<   t1        |      S t1        |      S c c}w # t.        $ r Y t1        |      S w xY w)NrK   r    T)r5   is_dirbasicdetailstype>   zipaccessr   )rB   r   modifiedr   _r   r9   permissions   i  )mode)validatepathrQ   r   	directoryr   r,   r5   r   
isdisjointr   r+   r-   rm   r   r   	date_time	__slots__
startswithgetattrexternal_attrcreate_systemr   dumpKeyErrorr   )	r3   r   
namespaces_pathraw_info
basic_infor   zip_infoks	            r7   r,   zReadZipFS.getinfo  s   !!$'%2
C<)+t <HWJ&'-s<3I3I/J&K#R H~M 007J)3JDUDU VHW/:::F11$7#yy00:H
 !J.$,$6$6$'#-#4#4 !- 6 6%1%6%6%
 ): ((*<*< =)
/+ 
* &.%7%7+ !#$<<#4 wx33+
  :-#11h6L6LPQ6Q -{)1)?)?2)E)M0""&$&2HX. H~tH~+#   : H~?s   2G %G	G,+G,c                 L    | j                          t        j                  |      rG   r   r   ResourceReadOnly)r3   r   infos      r7   setinfozReadZipFS.setinfo      

%%d++r8   c                 X    | j                          | j                  j                  |      S rG   )r   r   listdirr   s     r7   r   zReadZipFS.listdir  s     

&&t,,r8   c                 L    | j                          t        j                  |      rG   r   )r3   r   r   r   s       r7   makedirzReadZipFS.makedir  s     	

%%d++r8   c                 ^   | j                          d|v sd|v sd|v rt        j                  |      | j                  j	                  |      st        j
                  |      | j                  j                  |      rt        j                  |      | j                  |      }t        | |      S )Nw+a)
r   r   r   r   existsResourceNotFoundr   FileExpectedr   r(   )r3   r   r   	bufferingkwargsr   s         r7   openbinzReadZipFS.openbin  s    

$;#+))$//%%d+))$//__""4(%%d++))$/4**r8   c                 L    | j                          t        j                  |      rG   r   r   s     r7   removezReadZipFS.remove  r   r8   c                 L    | j                          t        j                  |      rG   r   r   s     r7   	removedirzReadZipFS.removedir  r   r8   c                 x    t         t        |           t        | d      r| j                  j                          y y )Nr+   )r0   r%   r   hasattrr+   r   s    r7   r   zReadZipFS.close  s-    i$&4 IIOO !r8   c                     | j                          | j                  j                  |      st        j                  |      | j                  |      }| j                  j                  |      }|S rG   )r   r   isfiler   r   r   r+   r?   )r3   r   r   	zip_bytess       r7   	readbyteszReadZipFS.readbytes  sV    

%%d+))$//))$/IINN8,	r8   c                     |dk(  rVt        | j                  t        j                        r2t	        | j                        }t	        |      }dj                  ||      S t        j                  ||      )Nr4   zzip://{}!/{})
isinstancerx   r   string_typesr   rU   r   NoURL)r3   r   purposequoted_filequoted_paths        r7   geturlzReadZipFS.geturl  sW    d?z$**c6F6FG#DJJ/K#D/K!((kBB,,tW--r8   )re   rG   )NF)r*   r=   )download)r\   r]   r^   rq   r}   r   CreateFailed	catch_allr1   r   r   r   propertyr   r,   r   r   r   r   r   r   r   r   r   ra   rb   s   @r7   r%   r%   M  s     " E """ #"41 & &$2h,
- 	,+,
,
.r8   )<rq   
__future__r   r   r_   rt   r   rr   r   r   r   
_url_toolsr   baser	   compressr
   enumsr   r   r   r   iotoolsr   memoryfsr   openerr   r   r   r   r   r   r   r   timer   wrapfsr   ru   r   r   r   r   r   r   r   r   r    r!   r"   subfsr#   TypeVarr$   r(   rd   python_2_unicode_compatiblerk   r%   rK   r8   r7   <module>r     s    8 
  
    !   %     6 6 $ # 	   s+.AB1* B1JIF IX   I I !IX   q. q. !q.r8   