o
    Q `3                     @   s6  d Z ddlmZ ddlmZ ddlmZ ddl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 d	dlmZ d	dlmZmZ ejrddlmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z# d	dl$m%Z% d	dl&m'Z'm(Z( d	dl)m*Z* d	dl+m,Z, ej-dddZ.edddgZ/G dd deZ0dS )z2Manage several filesystems through a single view.
    )absolute_import)unicode_literals)print_functionN)
namedtupleOrderedDict)
itemgetter)	text_type   )errors)FS)check_writable)open_fs)abspathnormpath)AnyBinaryIO
CollectionIteratorIOMutableMappingList
MutableSetOptionalTextTuple)ResourceType)InfoRawInfo)Permissions)SubFSMMultiFS)Zbound_PrioritizedFSpriorityfsc                       s  e Zd ZdZddddZdV fdd	Zdd Zd	d
 ZdWddZdd Z	dd Z
dd Zdd Zdd Zdd ZdXddZdd ZdYd d!Zd"d# Z		dZd$d%Zd[d'd(Zd)d* Zd+d, Z		d\d-d.Zd/d0 ZdYd1d2Zd]d4d5Zd6d7 Zd8d9 Zd:d; Zd^d=d>Zd?d@ Zd^dAdBZ dCdD Z!dEdF Z"dGdH Z# fdIdJZ$		dZdKdLZ%		&			3d_dMdNZ&dYdOdPZ'dQdR Z(	S		3d`dTdUZ)  Z*S )ar!   zA filesystem that delegates to a sequence of other filesystems.

    Operations on the MultiFS will try each 'child' filesystem in order,
    until it succeeds. In effect, creating a filesystem that combines
    the files and dirs of its children.

    TF)ZvirtualZ	read_onlyZcase_insensitivec                    s<   t t|   || _d | _d | _d| _i | _d | _d| _	d S )Nr   F)
superr!   __init___auto_closewrite_fs_write_fs_name_sort_index_filesystems_fs_sequence_closed)selfZ
auto_close	__class__ ,/usr/lib/python3/dist-packages/fs/multifs.pyr&   8   s   
zMultiFS.__init__c                 C   s   | j rdS dS )Nz	MultiFS()zMultiFS(auto_close=False))r'   r.   r1   r1   r2   __repr__D   s   zMultiFS.__repr__c                 C   s   dS )Nz	<multifs>r1   r3   r1   r1   r2   __str__K   s   zMultiFS.__str__r   c                 C   sj   t |tr	t|}t |tstdt|| jf|d| j|< |  jd7  _|   |r3|| _	|| _
dS dS )a  Add a filesystem to the MultiFS.

        Arguments:
            name (str): A unique name to refer to the filesystem being
                added.
            fs (FS or str): The filesystem (instance or URL) to add.
            write (bool): If this value is True, then the ``fs`` will
                be used as the writeable FS (defaults to False).
            priority (int): An integer that denotes the priority of the
                filesystem being added. Filesystems will be searched in
                descending priority order and then by the reverse order
                they were added. So by default, the most recently added
                filesystem will be looked at first.

        z,fs argument should be an FS object or FS URL)r#   r$   r	   N)
isinstancer   r   r   	TypeErrorr"   r*   r+   _resortr(   r)   )r.   namer$   writer#   r1   r1   r2   add_fsO   s   



zMultiFS.add_fsc                 C   s   | j | jS )a+  Get a filesystem from its name.

        Arguments:
            name (str): The name of a filesystem previously added.

        Returns:
            FS: the filesystem added as ``name`` previously.

        Raises:
            KeyError: If no filesystem with given ``name`` could be found.

        )r+   r$   )r.   r9   r1   r1   r2   get_fsp   s   zMultiFS.get_fsc                 C   s
   d| _ dS )z9Force `iterate_fs` to re-sort on next reference.
        N)r,   r3   r1   r1   r2   r8      s   
zMultiFS._resortc                 C   s8   | j du rdd t| j tdddD | _ t| j S )z@Get iterator that returns (name, fs) in priority order.
        Nc                 S   s   g | ]
\}\}}||fqS r1   r1   ).0r9   _orderr$   r1   r1   r2   
<listcomp>   s    
z&MultiFS.iterate_fs.<locals>.<listcomp>r	   T)keyreverse)r,   sortedr+   itemsr   iterr3   r1   r1   r2   
iterate_fs   s   

zMultiFS.iterate_fsc                 C   s(   |   D ]\}}||r|  S qdS )z1Get a filesystem which has a given path.
        N)rE   exists)r.   path_namer$   r1   r1   r2   	_delegate   s
   
zMultiFS._delegatec                 C   s    |  |}|du rt||S )zBCheck that there is a filesystem with the given ``path``.
        N)rI   r
   ResourceNotFoundr.   rG   r$   r1   r1   r2   _delegate_required   s   

zMultiFS._delegate_requiredc                 C   s   | j du r
t|| j S )z*Check that ``path`` is writeable.
        N)r(   r
   ZResourceReadOnlyr.   rG   r1   r1   r2   _writable_required   s   

zMultiFS._writable_requiredrc                 C   s@   t |r
| j| jfS |  D ]\}}||r||f  S qdS )zGet a tuple of (name, fs) that the given path would map to.

        Arguments:
            path (str): A path on the filesystem.
            mode (str): An `io.open` mode.

        NN)r   r)   r(   rE   rF   )r.   rG   moder9   r$   r1   r1   r2   which   s   	
zMultiFS.whichc                 C   sZ   d| _ | jr+z| j D ]\}}|  qW | j  |   d S | j  |   w d S )NT)r-   r'   r+   valuescloseclearr8   )r.   r>   r$   r1   r1   r2   rT      s   



zMultiFS.closeNc                 C   sJ   |    |pd}| |}|d u rt|tt|}|j||d}|S )Nr1   )
namespaces)checkrI   r
   rJ   r   r   getinfo)r.   rG   rV   r$   _pathinfor1   r1   r2   rX      s   

zMultiFS.getinfoc              	   C   sp   |    g }d}|  D ]\}}z
||| W n
 tjy$   Y qw d}q|s/t|tt|}|S )NFT)	rW   rE   extendlistdirr
   rJ   listr   fromkeys)r.   rG   Z	directoryrF   rH   _fsr1   r1   r2   r\      s   
zMultiFS.listdirc                 C   "   |    | |}|j|||dS N)permissionsrecreate)rW   rN   makedirr.   rG   rb   rc   r(   r1   r1   r2   rd         
zMultiFS.makedirc                 K   s>   |    t|r| |}n| |}|j|f||d|S )N)rQ   	buffering)rW   r   rN   rL   openbin)r.   rG   rQ   rh   optionsr_   r1   r1   r2   ri      s
   
zMultiFS.openbinc                 C      |    | |}||S N)rW   rL   removerK   r1   r1   r2   rm         

zMultiFS.removec                 C   rk   rl   )rW   rL   	removedirrK   r1   r1   r2   ro      rn   zMultiFS.removedirc           	   	   c   s    |    t }d}|  D ]+\}}z|j|||dD ]}|j|vr+|V  ||j qd}W q tjy9   Y qw |sAt|d S )NF)rV   pageT)rW   setrE   scandirr9   addr
   rJ   )	r.   rG   rV   rp   seenrF   rH   r$   rZ   r1   r1   r2   rr     s$   

zMultiFS.scandirc                 C   s.   |    | |}|d u rt|||S rl   )rW   rI   r
   rJ   	readbytesrK   r1   r1   r2   ru     s
   


zMultiFS.readbytesc                 K   s"   |  |}|j||fd|i|S N
chunk_size)rL   download)r.   rG   filerw   rj   r$   r1   r1   r2   rx   #  s   
zMultiFS.download c                 C   s$   |    | |}|j||||dS N)encodingr
   newline)rW   rL   readtext)r.   rG   r|   r
   r}   r$   r1   r1   r2   r~   (     
zMultiFS.readtextc                 C   rk   rl   )rW   rL   getsizerK   r1   r1   r2   r   .  rn   zMultiFS.getsizec                 C   rk   rl   )rW   rL   
getsyspathrK   r1   r1   r2   r   4  rn   zMultiFS.getsyspathc                 C   rk   rl   )rW   rL   gettyperK   r1   r1   r2   r   :  rn   zMultiFS.gettyperx   c                 C   s    |    | |}|j||dS N)purpose)rW   rL   geturlr.   rG   r   r$   r1   r1   r2   r   @  s   
zMultiFS.geturlc                 C   $   |    | |}|d uo||S rl   )rW   rI   
hassyspathrK   r1   r1   r2   r   F  r   zMultiFS.hassyspathc                 C   s(   |    | |}|d uo|j||dS r   )rW   rI   hasurlr   r1   r1   r2   r   L  s   
zMultiFS.hasurlc                 C   r   rl   )rW   rI   isdirrK   r1   r1   r2   r   R  r   zMultiFS.isdirc                 C   r   rl   )rW   rI   isfilerK   r1   r1   r2   r   X  r   zMultiFS.isfilec                 C   s   |    | |}|||S rl   )rW   rN   setinfo)r.   rG   rZ   r(   r1   r1   r2   r   ^  s   
zMultiFS.setinfoc                    s@   |    | jd ur| j| ntt| | tt|}|S rl   )rW   r(   validatepathr%   r!   r   r   rM   r/   r1   r2   r   d  s   
zMultiFS.validatepathc                 C   r`   ra   )rW   rN   makedirsre   r1   r1   r2   r   n  rf   zMultiFS.makedirsc           	      K   sD   |    t|r| |}n| |}|j|f|||||d|S )N)rQ   rh   r|   r
   r}   )rW   r   rN   rL   open)	r.   rG   rQ   rh   r|   r
   r}   kwargsr_   r1   r1   r2   r   y  s   
zMultiFS.openc                 K   s"   |  |j||fd|i| d S rv   )rN   upload)r.   rG   ry   rw   rj   r1   r1   r2   r     s   

zMultiFS.uploadc                 C   s   |  ||| d S rl   )rN   
writebytes)r.   rG   contentsr1   r1   r2   r     s   zMultiFS.writebytesutf-8c                 C   s   |  |}|j|||||dS r{   )rN   	writetext)r.   rG   r   r|   r
   r}   r(   r1   r1   r2   r     s   
	
zMultiFS.writetext)T)Fr   )rO   rl   )NF)rO   rg   rP   )NNrz   )rx   )rO   rg   NNrz   )r   Nrz   )+__name__
__module____qualname____doc__Z_metar&   r4   r5   r;   r<   r8   rE   rI   rL   rN   rR   rT   rX   r\   rd   ri   rm   ro   rr   ru   rx   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__r1   r1   r/   r2   r!   -   sl    
!		



		







)1r   Z
__future__r   r   r   typingcollectionsr   r   operatorr   Zsixr   rz   r
   baser   rQ   r   Zopenerr   rG   r   r   ZTYPE_CHECKINGr   r   r   r   r   r   r   r   r   r   r   Zenumsr   rZ   r   r   rb   r   Zsubfsr   TypeVarr    r"   r!   r1   r1   r1   r2   <module>   s,    4