
    obu                        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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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& ddl'm(Z( ddl)m*Z* ddl+m,Z, ddl-m.Z.m/Z/m0Z0m1Z1m2Z2 ddl3m4Z4 ejj                  r@ddlm6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@mAZAmBZBmCZC ddlZddlDZDddl mEZE ddl'mFZF ddlGmHZH ddlImJZJ  ej                  dd      ZLdgZMed(d       ZNed        ZOd  ZPerd! ZQd" ZRnd# ZQd$ ZR G d% d&ej                        ZT G d' de!      ZUy# e$ rZeZY dZ[dZ[ww xY w))z*Manage filesystems on remote FTP servers.
    )print_functionunicode_literalsN)OrderedDict)contextmanager)FTP)FTP_TLS)cast)
error_perm
error_temp)PY2
raise_from	text_type   )
_ftp_parse)errors)FS)DEFAULT_CHUNK_SIZE)ResourceTypeSeek)Info)line_iterator)Mode)abspathbasenamedirnamenormpathsplit)epoch_to_datetime)AnyBinaryIO
ByteString	ContainerContextManagerDictIterableIteratorListOptionalSupportsIntTextTupleUnion)_OpendirFactory)RawInfo)Permissions)SubFS_FFTPFS)boundc              #     K   	 | j                   5  d  d d d        y # 1 sw Y   y xY w# t        j                  $ r0 t        j                  dj                  | j                              t        $ r0 t        j                  dj                  | j                              t        $ rS}|'t        j                  |dj                  ||            t        j                  dj                  |            d }~wt        $ rm}t        |      \  }}|dk(  rt        j                  ||      |dv r$t        j                  t        t         |      	      t        j"                  |      d }~ww xY ww)
Nzunable to connect to {})msgzlost connection to {}zftp error on resource '{}' ({})zftp error ({})552)pathr5   )501550r7   )_locksocketerrorr   RemoteConnectionErrorformathostEOFErrorr   ResourceErrorOperationFailedr
   _parse_ftp_errorInsufficientStorageResourceNotFoundr	   strPermissionDenied)fsr7   r=   codemessages        */usr/lib/python3/dist-packages/fs/ftpfs.py
ftp_errorsrM   H   sB    3XX 		 	 	<< 
**)009
 	
  X**/F/M/Mbgg/VWW M&&;BB4O  ((-=-D-DU-KLL 3(/g5=,,$GDD^#))tC??%%'223sM   E5* * E5'* E5* BE2+AC99E2A(E--E22E5c              #      K   	 |  	 | j                          y # t        $ r Y y w xY w# 	 | j                          w # t        $ r Y w w xY wxY wwN)quit	Exception)ftps    rL   
manage_ftprS   d   sO     		HHJ 			HHJ 		sO   A)  A	&A&AA<A	AAAAAc                 F    t        |       j                  d      \  }}}||fS )z(Extract code and message from ftp error. )r   	partition)r=   rJ   _rK   s       rL   rD   rD   p   s*     !'11#6D!W=    c                 H    t        | t              r| j                  |      S | S rO   )
isinstancer   encodestencodings     rL   _encoder_   y   s    &0Y&?ryy"GRGrX   c                 J    t        | t              r| j                  |d      S | S )Nreplace)rZ   bytesdecoder\   s     rL   _decoderd   }   s!    1;B1Fryy9-NBNrX   c                     | S rO    r]   rW   s     rL   r_   r_          	rX   c                     | S rO   rf   rg   s     rL   rd   rd      rh   rX   c                        e Zd Z fdZd Zed        Zed        Zd Z fdZ	d Z
d Zdd	Zd
 ZddZddZd Zd Zd ZddZd Zej,                  fdZ xZS )FTPFilec                     t         t        |           || _        || _        t        |      | _        d| _        t        j                         | _
        | j                         | _        d | _        d | _        y )Nr   )superrk   __init__rI   r7   r   modepos	threadingLockr;   	_open_ftprR   
_read_conn_write_conn)selfftpfsr7   ro   	__class__s       rL   rn   zFTPFile.__init__   s[    gt%'	J	^^%
>>#rX   c                 n    | j                   j                         }|j                  t        d             |S )z Open an ftp object for the file.zTYPE I)rI   rs   voidcmdrG   rv   rR   s     rL   rs   zFTPFile._open_ftp   s+     gg!CM"
rX   c                     | j                   _| j                  j                  t        d      t	        | j
                  | j                  j                        z   | j                        | _         | j                   S )NRETR )rt   rR   transfercmdrG   r_   r7   r^   rp   rv   s    rL   	read_connzFTPFile.read_conn   sW     ??""hh22Gwtyy$((2C2CDDdhhDO rX   c                    | j                   | j                  j                  r`| j                  j	                  t        d      t        | j                  | j                  j                        z         | _         | j                   S | j                  j	                  t        d      t        | j                  | j                  j                        z   | j                        | _         | j                   S )NzAPPE STOR )
ru   ro   	appendingrR   r~   rG   r_   r7   r^   rp   r   s    rL   
write_connzFTPFile.write_conn   s     #yy""#'88#7#7L7499dhh6G6G#HH$   $(88#7#7L7499dhh6G6G#HH$(($  rX   c                 |    d}|j                  | j                  j                  | j                  | j                        S )Nz<ftpfile {!r} {!r} {!r}>)r?   rI   ftp_urlr7   ro   )rv   _reprs     rL   __repr__zFTPFile.__repr__   s*    *||DGGOOTYY		BBrX   c                    | j                   s| j                  5  	 | j                  ;| j                  j                          d | _        | j                  j                          | j                  !| j                  j                          d | _        	 | j                  j                          t        t        |           	 d d d        y y # t        $ r Y (w xY w# t        t        |           w xY w# 1 sw Y   y xY wrO   )closedr;   ru   closerR   voidresprt   rP   r   rm   rk   rv   rx   s    rL   r   zFTPFile.close   s    {{ 11''3((..0+/())+2--/*. '4.01 1  &  '4.01 1sA   C.A4CC+C.	CCCCC++C..C7c                     | j                   S rO   )rp   r   s    rL   tellzFTPFile.tell   s    xxrX   c                 .    | j                   j                  S rO   )ro   readingr   s    rL   readablezFTPFile.readable       yy   rX   c                    | j                   j                  st        d      g }|}| j                  }| j                  5  |rq|dk  rt
        }nt        t
        |      }	 |j                  |      }|sn@|j                  |       | xj                  t        |      z  c_        |t        |      z  }|rqd d d        dj                  |      S # t        j                  $ r Y .w xY w# 1 sw Y   3xY w)NzFile not open for readingr   rX   )ro   r   IOErrorr   r;   r   minrecvr<   r=   appendrp   lenjoin)rv   sizechunks	remainingconn	read_sizechunks          rL   readzFTPFile.read   s    yy  566	~~ZZ 	(q= 2I #$6	 BI IIi0E e$CJ&SZ'	 	( xx || 	( 	(s0   C$C/AC$C!C$ C!!C$$C-c                     | j                  t        |            }t        |      }t        |t        j                        r%t        j                  |j                  |      |d | |S ||d | |S rO   )r   r   rZ   arraytypecode)rv   bufferdata
bytes_reads       rL   readintozFTPFile.readinto   sb    yyV%Y
fekk*"'++foot"DF;J  #'F;JrX   c                 ,    t        t        | |            S rO   )nextr   )rv   r   s     rL   readlinezFTPFile.readline   s    M$-..rX   c                     g }d}t        |       D ]/  }|j                  |       |t        |      z  }|dk7  s(||kD  s. |S  |S )Nr   )r   r   r   )rv   hintlinesr   lines        rL   	readlineszFTPFile.readlines   sV    !$' 	DLLCIDrzdTk	
 rX   c                 .    | j                   j                  S rO   )ro   writingr   s    rL   writablezFTPFile.writable
  r   rX   c                    | j                   j                  st        d      t        |t        j                        r|j                         }| j                  5  | j                  }d}t        |      }|rIt        |t              }|j                  ||||z          }||z  }||z  }| xj                  |z  c_        |rId d d        |S # 1 sw Y   S xY w)NFile not open for writingr   )ro   r   r   rZ   r   tobytesr;   r   r   r   r   sendrp   )rv   r   r   data_posremaining_data
chunk_size	sent_sizes          rL   writezFTPFile.write  s    yy  566dEKK(<<>DZZ 
	&??DH YN  1CD
 IId8h6K&LM	I%)+I% !
	& 
	& s   A$CCc                     | j                   j                  st        d      t               }|D ]M  }t	        |t
        j
                        r |j                  |j                                =|j                  |       O | j                  |       y )Nr   )	ro   r   r   	bytearrayrZ   r   extendr   r   )rv   r   r   r   s       rL   
writelineszFTPFile.writelines$  sk    yy  566{ 	"D$,DLLN+D!		"
 	

4rX   c           	         | j                   5  || j                         }| j                  j                  | j                        5 }|j                  |      }d d d        | j                  j                  | j                  d      5 }|j                         t        |      |k  r |j                  d|t        |      z
  z         d d d        d d d        |S # 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   |S xY w)Nw    )r;   r   rI   openbinr7   r   r   r   )rv   r   fr   s       rL   truncatezFTPFile.truncate0  s     ZZ 	8|yy{+ $qvvd|$C0 8At9t#GGETCI%5678	8 $ $8 8	8 s<   8C/C.C/A C#C/C 	C/#C,	(C//C9c                      y)NTrf   r   s    rL   seekablezFTPFile.seekable>  s    rX   c                 0   t        |      }|t        j                  t        j                  t        j                  fvrt        d      | j                  5  |t        j                  k(  r|}n`|t        j                  k(  r| j                  |z   }n=|t        j                  k(  r*| j                  j                  | j                        }||z   }t        d      | _        | j                  j                          | j                         | _        | j                  r!| j                  j!                          d | _        | j"                  r!| j"                  j!                          d | _        d d d        | j%                         S # 1 sw Y   | j%                         S xY w)Nzinvalid value for whencer   )intr   setcurrentend
ValueErrorr;   rp   rI   getsizer7   maxrR   rP   rs   rt   r   ru   r   )rv   rp   whence_whencenew_pos	file_sizes         rL   seekzFTPFile.seekB  s#   f+488T\\488<<788ZZ 	($(("DLL(((S.DHH$ GGOODII6	#c/1gDHHHMMO~~'DH%%'"&  &&(#' %	(& yy{'	(& yy{s   DE==F)r   rO   )__name__
__module____qualname__rn   rs   propertyr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__rx   s   @rL   rk   rk      s    
       C
1&! 4/	!,
  $xx rX   rk   c                       e Zd ZdZdddddddZ	 	 	 	 	 	 	 d* fd	Zd Zd Zed	        Z	ed
        Z
ed        Zd Zd Zed        Zed        Zd+dZd Zed        Zd Zed        Zed        Zd,dZed        Zed        Zed        Zej8                  rd-dZd-dZd.dZ fdZ d Z!	 	 d/dZ"d0d Z#d! Z$d" Z%d-d#Z&	 	 d1d$Z'd-d%Z(d& Z)d' Z*d( Z+ fd)Z, xZ-S )2r2   a  A FTP (File Transport Protocol) Filesystem.

    Optionally, the connection can be made securely via TLS. This is known as
    FTPS, or FTP Secure. TLS will be enabled when using the ftps:// protocol,
    or when setting the `tls` argument to True in the constructor.

    Examples:
        Create with the constructor::

            >>> from fs.ftpfs import FTPFS
            >>> ftp_fs = FTPFS("demo.wftpserver.com")

        Or via an FS URL::

            >>> ftp_fs = fs.open_fs('ftp://test.rebex.net')

        Or via an FS URL, using TLS::

            >>> ftp_fs = fs.open_fs('ftps://demo.wftpserver.com')

        You can also use a non-anonymous username, and optionally a
        password, even within a FS URL::

            >>> ftp_fs = FTPFS("test.rebex.net", user="demo", passwd="password")
            >>> ftp_fs = fs.open_fs('ftp://demo:password@test.rebex.net')

        Connecting via a proxy is supported. If using a FS URL, the proxy
        URL will need to be added as a URL parameter::

            >>> ftp_fs = FTPFS("ftp.ebi.ac.uk", proxy="test.rebex.net")
            >>> ftp_fs = fs.open_fs('ftp://ftp.ebi.ac.uk/?proxy=test.rebex.net')

     TF)invalid_path_charsnetwork	read_onlythread_safeunicode_pathsvirtualc	                 X   t         t        |           || _        || _        || _        || _        || _        || _        || _	        || _
        | j                  r7t        t        t              r#t        t        j                   d      t               d| _        d| _        d| _        i | _        y)au  Create a new `FTPFS` instance.

        Arguments:
            host (str): A FTP host, e.g. ``'ftp.mirror.nl'``.
            user (str): A username (default is ``'anonymous'``).
            passwd (str): Password for the server, or `None` for anon.
            acct (str): FTP account.
            timeout (int): Timeout for contacting server (in seconds,
                defaults to 10).
            port (int): FTP port number (default 21).
            proxy (str, optional): An FTP proxy, or ``None`` (default)
                for no proxy.
            tls (bool): Attempt to use FTP over TLS (FTPS) (default: False)

        zFTP over TLS not supportedlatin-1N)rm   r2   rn   _host_userpasswdaccttimeoutportproxytlsrZ   r   rQ   r   r   CreateFailedr^   _ftp_welcome	_features)
rv   r@   userr   r   r   r   r   r   rx   s
            rL   rn   zFTPFS.__init__  s    6 	eT#%

		
88
7I6v**+GH'R!	rX   c                 N    dj                  | j                  | j                        S )NzFTPFS({!r}, port={!r}))r?   r@   r   r   s    rL   r   zFTPFS.__repr__  s    '..tyy$))DDrX   c                 v    | j                   dk(  rdnd}|j                  | j                  | j                         S )N   z<ftpfs '{host}'>z<ftpfs '{host}:{port}'>)r@   r   )r   r?   r@   )rv   _fmts     rL   __str__zFTPFS.__str__  s0    %)YY"_!:S{{				{::rX   c                 ~    | j                   | j                  S dj                  | j                  | j                        S )Nz{}@{})r   r   r?   r   r   s    rL   r   z
FTPFS.user  s4     **,DJJ	
29..TZZ2X	
rX   c                 J    | j                   | j                  S | j                   S rO   )r   r   r   s    rL   r@   z
FTPFS.host  s      "ZZ/tzz?TZZ?rX   c                     i }|j                  d      d   dk(  rD|j                         D ]1  }|j                  d      s|dd j                  d      \  }}}|||<   3 |S )z0Parse a dict of features from FTP feat response.-r   211rU   r   N)r   
splitlines
startswithrV   )clsfeat_responsefeaturesr   keyrW   values          rL   _parse_featureszFTPFS._parse_features  sq     s#A&%/%002 *??3'$(H$6$6s$;MCE$)HSM* rX   c                 "   | j                   r
t               n	t               }|j                  d       t	        |       5  |j                  | j                  | j                  | j                         |j                  | j                  | j                  | j                         	 |j                          i | _        	 t!        |j#                  d      d      }| j%                  |      | _        d| j                  v rdnd| _        t(        s-|j*                  j-                  d| j&                        |_        	 ddd       | j&                  |_        |j2                  | _        |S # t        $ r Y w xY w# t0        $ r
 d| _        Y Mw xY w# 1 sw Y   RxY w)	zOpen a new ftp object.r   FEATr   UTF8utf-8r)r^   N)r   r   r   set_debuglevelrM   connectr@   r   r   loginr   r   r   prot_pAttributeErrorr   rd   sendcmdr  r^   r   sockmakefilefiler
   welcomer   )rv   r   r  s      rL   rs   zFTPFS._open_ftp  s@    !HHwy#%A 	LLDIIt||<JJtyy$++tyy9  DN
 'V(<i H "&!5!5m!D+1T^^+C $		 2 2dmm !3 !DI!	& ! " 
  * )*	 	sU   A#F!E 1F9E/A F 	E,)F+E,,F/F?FFFFc                 8    | j                         }t        |      S rO   )rs   rS   r{   s     rL   _manage_ftpzFTPFS._manage_ftp  s    nn#rX   c                 X   | j                   dk(  r| j                  }n&dj                  | j                  | j                         }| j                  dk(  s| j                  d}n&dj                  | j                  | j                        }| j
                  rdnd}dj                  |||      }|S )	z*Get the FTP url this filesystem will open.r   z{}:{}	anonymous z{}:{}@ftpsrR   z	{}://{}{})r   r@   r?   r   r   r   )rv   
_host_part
_user_partschemeurls        rL   r   zFTPFS.ftp_url  s     99?J 		499=J99#tyy'8J!DKK@J88  Z@
rX   c                 "    | j                         S )z'~ftplib.FTP: the underlying FTP client.)_get_ftpr   s    rL   rR   z	FTPFS.ftp
  s     }}rX   c                     | j                  |      }|dk7  rt        j                  ||      dj                  | j                  |      S )zGet FTP url for resource.downloadz{}{})validatepathr   NoURLr?   r   )rv   r7   purpose_paths       rL   geturlzFTPFS.geturl  sB     !!$'j ,,ug..}}T\\511rX   c                 \    | j                   | j                         | _         | j                   S rO   )r   rs   r   s    rL   r   zFTPFS._get_ftp  s$    99(DIyyrX   c                 :    | j                          | j                  S )z*`dict`: Features of the remote FTP server.)r   r   r   s    rL   r  zFTPFS.features  s     	~~rX   c                 2   t        t        |            }g }t        | |      5  | j                  j	                  t        d      t        || j                  j                        z   |j                         d d d        |D cg c]%  }t        |t              r|j                  d      n|' }}t        j                  |      D cg c]  }t        |       }}t        |D ci c]  }|j                   | c}      }|S # 1 sw Y   xY wc c}w c c}w c c}w )Nr:   zLIST r	  )r   r   rM   rR   	retrlinesrG   r_   r^   r   rZ   rb   rc   	ftp_parseparser   r   name)	rv   r7   r&  r   r   raw_info_listinfodir_listings	            rL   	_read_dirzFTPFS._read_dir%  s    '4( 	HHGwudhh.?.?@@%,,	
 SX
JNJtU$;DKK E
 
 1:0FGHhGG!u"Et499d?"EF	 	
 H"Es   AC>*D
D!D>Dc                     d| j                   v S )z/bool: whether the server supports MLST feature.MLSTr  r   s    rL   supports_mlstzFTPFS.supports_mlst4       &&rX   c                     d| j                   v S )z3bool: whether the server supports the MDTM feature.MDTMr6  r   s    rL   supports_mdtmzFTPFS.supports_mdtm:  r8  rX   c                 X   | j                  |      }t        | |      5  |s| j                  |      sdt        j                         }| j
                  j                  t        d      t        || j
                  j                        z   |       	 d d d        y	 d d d        y# 1 sw Y   yxY w)Nr   TF)
r#  rM   isfileioBytesIOrR   
storbinaryrG   r_   r^   )rv   r7   wiper&  
empty_files        rL   createzFTPFS.create@  s    !!$'d# 	4;;t,ZZ\
##L75$((2C2C#DDj 	 	,	 	 s   A/B  B)c                    	 t        |dd       }t        |dd       }t        |dd       }t        |dd       }t        |dd       }t        |dd       }t        j                  ||||||f      }|S # t        $ r Y yw xY w)	z+Parse a time from an ftp directory listing.r            
         N)r   r   calendartimegm)	r   	time_texttm_yeartm_monthtm_daytm_hourtm_mintm_sec
epoch_times	            rL   _parse_ftp_timezFTPFS._parse_ftp_timeL  s    	)Aa.)G9Qq>*H1Q(F)Ab/*G2b)*F2b)*F __h@

   		s   AA3 3	A?>A?c                 4   d }i }|j                  d      D ]u  }|j                  d      \  }}}|r4|j                         j                         }|j                         }|||<   Nt	        |j                  d      j                               }w |dvr||fS d |fS )N;=/).z..)r   rV   striplowerr   rstrip)r   r   r.  factsfactr  sepr  s           rL   _parse_factszFTPFS._parse_facts^  s     JJsO 	:D"nnS1OCeiik'')"c
C 0 6 6 89	: ;.t%??D%??rX   c              #   $  K   |D ]  }| j                  |j                               \  }}|)|j                  dd      }|dvr@|dk(  }i }||d|d<   ||d<   dt        |rt        j
                  nt        j                        i|d<   |d   }|j                  d	|j                  d
d            }	d}
|	j                         rt        |	      }
|
|d	<   d|v r| j                  |d         |d<   d|v r| j                  |d         |d<   | 	 y w)Ntyper  >   dirr  rd  r.  is_dirbasicrR   detailsr   sizd0r   modifymodifiedrC  created)	ra  r[  getr   r   	directoryr  isdigitrU  )r   r   r   r.  r^  _typerf  r/  rh  size_strr   s              rL   _parse_mlsxzFTPFS._parse_mlsxm  s1      	D**4::<8KD%|IIff-EO+e^FH)- @HW#HUOv\33<CTCTU#HY y)Gyy63)?@HD!8}"GFO5 &)&9&9%/&J
#5 %(%8%8x%I	"N5	s   DDc                      y rO   rf   )rv   r7   factorys      rL   opendirzFTPFS.opendir  s    rX   c           	      4   | j                  |      }|xs d}|dk(  r*t        ddddt        t        j                        id      S | j
                  r| j                  5  t        | |      5  | j                  j                  t        d	      t        || j                  j                        z         }d d d        t        | j                  j                        j                         d
d }| j                  |      D ]  }t        |      c cd d d        S  	 d d d        t        | |      5  t!        |      \  }}| j#                  |      }	||	vrt%        j&                  |      |	|   }
|
cd d d        S # 1 sw Y   xY w# 1 sw Y   kxY w# 1 sw Y   y xY w)Nrf   rY  r  Tre  rc  )rg  rh  r:   zMLST r   r   )r#  r   r   r   ro  r7  r;   rM   rR   r  rG   r_   r^   rd   r   rs  r   r3  r   rF   )rv   r7   
namespacesr&  responser   r/  dir_name	file_namero  r1  s              rL   getinfozFTPFS.getinfo  s   !!$'%2
C<&(D9 &L,B,B(CD   *40 #xx//Gwudhh6G6G'HH H  $((*;*;<GGI!BO $ 0 0 7 *H>)* *** 4( 	"',Hix0I	)--d33Y'D	 	 * *	 	s8   F-AE63AFF-?F6E?	;FFFc                     i }| j                          |dk(  r<| j                  j                         }d| j                  v |d<   d| j                  v |d<   |S )Nstandardr  r   r:  supports_mtime)r   _metacopyr  )rv   	namespacer  s      rL   getmetazFTPFS.getmeta  sT    
"JJOO%E%+t}}%<E/"&,&=E"#rX   c                    | j                   r| j                  |      }| j                  5  t        | |      5  dt	        || j
                  j                        z   }| j
                  j                  |      }| j                  |j                         d         }t        |      cd d d        cd d d        S t        t        | 7  |      S # 1 sw Y   nxY w	 d d d        )# 1 sw Y   2xY w)Nr:   zMDTM r   )r;  r#  r;   rM   r_   rR   r^   r  rU  r   r   rm   r2   getmodified)rv   r7   r&  cmdry  mtimerx   s         rL   r  zFTPFS.getmodified  s    %%d+E 440 4!GE4883D3D$EEC#xx//4H 001A!1DEE,U3	4 44 4 UD-d334 4 44 4 4s#   C A+C
$	C 
C	C  C)c                     | j                  |      }| j                  5  | j                  |      D cg c]  }|j                   }}d d d        |S c c}w # 1 sw Y   S xY wrO   )r#  r;   scandirr.  )rv   r7   r&  r1  dir_lists        rL   listdirzFTPFS.listdir  s\    !!$'ZZ 	C.2ll5.ABd		BHB	C C	Cs   AAAAA c                    | j                  |      }t        | |      5  |dk(  r1|r| j                  |      cd d d        S t        j                  |      |r| j                  |      s:	 | j                  j                  t        || j                  j                               d d d        | j                  |      S # t        $ ry}t        |      \  }}|dk(  rL| j                  |      rt        j                  |      | j                  |      rt        j                  |      t        j                  |      d }~ww xY w# 1 sw Y   xY w)Nr:   rY  r9   )r#  rM   rv  r   DirectoryExistsisdirrR   mkdr_   r^   r
   rD   existsrF   )rv   r7   permissionsrecreater&  r=   rJ   rW   s           rL   makedirzFTPFS.makedir  s    !!$'4( 	8|<<-	8 	8
 !0066D!1
8HHLL0A0A!BC	8& ||D!! " 8.u5GD!u}::d+"("8"8">>#{{40&,&<&<T&B B 11$778	8 	8s0   E(E*9B<<	D>A4D99D>>EE
c                 j   t        |      }|j                          | j                  |      }| j                  5  	 | j	                  |      }|j
                  rt        j                  |      |j                  rt        j                  |      t        | ||j!                               }d d d        |S # t        j                  $ r_ |j                  rt        j                  |      |j                  r/| j                  t        |            st        j                  |      Y w xY w# 1 sw Y   S xY wrO   )r   validate_binr#  r;   r|  rf  r   FileExpected	exclusive
FileExistsrF   r   r   r  r   rk   to_platform_bin)	rv   r7   ro   	bufferingoptions_moder&  r1  ftp_files	            rL   r   zFTPFS.openbin  s   T
!!$'ZZ 	E2||E* ;; --d33?? ++D11tUE,A,A,CDH	E  ** 8== 11$77==GEN)C 11$77	8	E s0   D(B3AD(3A/D%"D($D%%D((D2c                    | j                          | j                  |      }| j                  5  | j                  |      rt	        j
                  |      t        | |      5  | j                  j                  t        || j                  j                               d d d        d d d        y # 1 sw Y   xY w# 1 sw Y   y xY w)Nr:   )checkr#  r;   r  r   r  rM   rR   deleter_   r^   )rv   r7   r&  s      rL   removezFTPFS.remove  s    

!!$'ZZ 	Czz$))t44D$' Ctxx/@/@ ABC	C 	CC C	C 	Cs#   4B9":B-B9-B6	2B99Cc                    | j                  |      }|dk(  rt        j                         t        | |      5  	 | j                  j                  t        || j                  j                               	 d d d        y # t        $ re}t        |      \  }}|dk(  rL| j                  |      rt        j                  |      | j                  |      st        j                  |       d }~ww xY w# 1 sw Y   y xY w)NrY  r9   )r#  r   RemoveRootErrorrM   rR   rmdr_   r^   r
   rD   r=  DirectoryExpectedisemptyDirectoryNotEmpty)rv   r7   r&  r=   rJ   rW   s         rL   	removedirzFTPFS.removedir  s    !!$'C<((**d# 
		WUDHH,=,=>?
	 
	  *51a5={{4($66t<<<<-$66t<<
	 
	s)   C-9A<<	C*A C%%C**C--C6c           	   #      K    j                  |      } j                  5   j                  rg t         |      5  	  j                  j                  t        d      t        | j                  j                        z    fd       	 d d d        r- j                        D ]  }t        |        	 d d d        y  j!                  |      j#                         D ]  }|  	 d d d        y # t        $ r2  j                  |      j                  st        j                  |       w xY w# 1 sw Y   xY w# 1 sw Y   y xY ww)Nr:   zMLSD c                 b    j                  t        | j                  j                              S rO   )r   rd   rR   r^   )lr   rv   s    rL   <lambda>z FTPFS._scandir.<locals>.<lambda>(  s!    ell71dhh>O>O3P&Q rX   )r#  r;   r7  rM   rR   r+  rG   r_   r^   r
   r|  rf  r   r  rs  r   r3  values)rv   r7   rx  r&  r/  r1  r   s   `     @rL   _scandirzFTPFS._scandir  s0    !!$'ZZ 	!!40 	**L75$((:K:K+LLQ	 $($4$4U$; -"8n,-!	 	" u-446 
#	 	 & #||D188"(":":4"@@	 		 	sR   E
D>D2 A
C4.D>9	E
(D>+	E
4;D//D22D;	7D>>EE
c                     | j                   s0| j                  |      j                  st        j                  |      | j                  ||      }||\  }}t        j                  |||      }|S )N)rx  )r7  r|  rf  r   r  r  	itertoolsislice)rv   r7   rx  page	iter_infostartr   s          rL   r  zFTPFS.scandir5  sj     !!$,,t*<*C*C**400MM$:M>	JE3!((E3?IrX   c           	      6   | j                  |      }| j                  5  t        | |      5  | j                  j	                  t        d      t        || j                  j                        z   |       d d d        d d d        y # 1 sw Y   xY w# 1 sw Y   y xY w)Nr   )r#  r;   rM   rR   r@  rG   r_   r^   )rv   r7   r  r   r  r&  s         rL   uploadzFTPFS.uploadD  s    !!$'ZZ 	D$' ##L75$((2C2C#DDd	 	 	 	s#   BAB2BB	BBc                     t        |t              st        d      | j                  |t	        j
                  |             y )Nzcontents must be bytes)rZ   rb   	TypeErrorr  r>  r?  )rv   r7   contentss      rL   
writebyteszFTPFS.writebytesM  s/    (E*455D"**X./rX   c                    d}d| j                   v r0d }d|v r|d   }n	d|v r|d   }|rd|v rd}t        t        |d         }|rt        | |      5  dt        j                  j                        j                  d      z   dz   t        || j                  j                        z   }	 | j                  j                  |       d d d        y | j                  |      st        j                  |      y # t        $ r Y ;w xY w# 1 sw Y   y xY w)	NFMFMTrl  rh  TzMFMT z%Y%m%d%H%M%SrU   )r  r	   floatrM   datetimeutcfromtimestampstrftimer_   rR   r^   r  r
   r  r   rF   )rv   r7   r1  use_mfmtinfo_detailsr  r  s          rL   setinfozFTPFS.setinfoS  s!   T]]"LT!#J/d"#I
l :UL$<=D$' 
''88?HHXY dDHH$5$567 HH$$S)
 
 ;;t$--d33 % " 
 
s+   AD &C11	C=:D <C==D  D	c           	      "   | j                  |      }t        j                         }t        | |      5  | j	                         5 }	 |j                  t        d      t        || j                  j                        z   |j                         	 d d d        d d d        |j!                         }|S # t        $ r?}t        |      \  }}|dk(  r&| j                  |      rt        j                  |       d }~ww xY w# 1 sw Y   nxY w# 1 sw Y   rxY w)Nr}   r9   )r#  r>  r?  rM   r  
retrbinaryrG   r_   rR   r^   r   r
   rD   r  r   r  getvalue)	rv   r7   r&  r   rR   r=   rJ   rW   
data_bytess	            rL   	readbyteszFTPFS.readbytesp  s    !!$'zz|d# 	!!# 
s	NNGwudhh6G6G'HH$**
	 ]]_
 " .u5GD!u}::d+"("5"5d";;
 
	 	sB   DC9AB.D.	C67:C11C66C99D	>DDc                     | j                         s"	 | j                  j                          d | _        t
        t        |           y # t        $ r Y %w xY wrO   )isclosedrR   rP   rQ   r   rm   r2   r   r   s    rL   r   zFTPFS.close  sH    }} DIeT "  s   A 	AA)r  r  r  rH  r   NF)r"  )FrO   )r~  )NF)r
  r   )NN).r   r   r   __doc__r  rn   r   r   r   r   r@   classmethodr  rs   r  r   rR   r'  r   r  r3  r7  r;  rC  rU  ra  rs  typingTYPE_CHECKINGrv  r|  r  r  r  r  r   r  r  r  r  r  r  r  r  r   r   r   s   @rL   r2   r2   ]  s    F #E +ZE;
 
 
 @ @ 	 	8
  "  
2   ' '
 ' '

  " @ @  < 	>
4 	"<,C$4 	04:(# #rX   rO   )Vr  
__future__r   r   r  r   rK  r  r>  r  r<   rq   collectionsr   
contextlibr   ftplibr   r   ImportErrorerrr	   r
   r   sixr   r   r   r  r   r,  r   baser   	constantsr   enumsr   r   r1  r   iotoolsr   ro   r   r7   r   r   r   r   r   timer   r  r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   mmapr-   r.   r  r/   subfsr0   TypeVarr1   __all__rM   rS   rD   r_   rd   	RawIOBaserk   r2   rf   rX   rL   <module>r     s6   8     	    # %   ) * * %   ) %  "  = = #	   " %( V^^D( ) 3 36   HO
Nbll Nbo#B o#Q
  Gs   E	 	EEE