a
    &ñ»jª"  ã                   @  sŽ   d Z ddlm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ZddlmZ dd	lmZ dd
lmZ G dd„ dƒZdS )zk
1:N rsync implementation on top of execnet.

(c) 2006-2009, Armin Rigo, Holger Krekel, Maciej Fijalkowski
é    )ÚannotationsN)Úmd5)ÚQueue)ÚCallable)ÚLiteral)ÚGateway)ÚBaseGateway)ÚChannelc                   @  s  e Zd ZdZd7dddœdd„Zd	dd
œdd„Zdddœdd„Zdddœdd„Zdddœdd„Zdddœdd„Z	dddddœdd„Z
dd	ddœdd„Zd8ddd œd!d"„Zd9d#d$d%dd&œd'd(„Zd)dd*œd+d,„Zd-d	d	dd.œd/d0„Zd	dd
œd1d2„Zd	dd
œd3d4„Zd	dd
œd5d6„ZdS ):ÚRSyncaT  This class allows to send a directory structure (recursively)
    to one or multiple remote filesystems.

    There is limited support for symlinks, which means that symlinks
    pointing to the sourcetree will be send "as is" while external
    symlinks will be just copied (regardless of existence of such
    a path on remote side).
    NTÚboolÚNone)ÚverboseÚreturnc                 C  sB   t |ƒ| _|| _|d u s$t|ƒs$J ‚|| _i | _tƒ | _g | _d S ©N)	ÚstrÚ
_sourcedirÚ_verboseÚcallableÚ	_callbackÚ	_channelsr   Ú_receivequeueÚ_links)ÚselfÚ	sourcedirÚcallbackr   © r   ú3E:\soccer\ml_env\Lib\site-packages\execnet/rsync.pyÚ__init__    s    
ôzRSync.__init__r   )Úpathr   c                 C  s   dS )NTr   )r   r   r   r   r   Úfilter5   s    zRSync.filterr	   )Úchannelr   c                 C  s(   || j v r$| ¡  td|j› d�ƒ‚d S )Nz connection unexpectedly closed: ú )r   Ú	waitcloseÚOSErrorÚgateway)r   r    r   r   r   Ú_end_of_channel8   s    
zRSync._end_of_channelc                 C  s$   | j D ]}| |¡ q| d¡ d S )Né*   )r   Úsend)r   r    Úlinkr   r   r   Ú_process_link?   s    
zRSync._process_linkc                 C  s"   | j  |¡}|r|ƒ  | ¡  dS )zCall all callbacks.N)r   Úpopr"   )r   r    Úfinishedcallbackr   r   r   Ú_doneE   s    zRSync._donec                   s4   ˆ j r0t‡ fdd„ˆ j| D ƒƒ}ˆ   d||¡ d S )Nc                   s   g | ]}ˆ j | ‘qS r   )Ú_paths)Ú.0Úi©r   r   r   Ú
<listcomp>O   ó    z$RSync._list_done.<locals>.<listcomp>Úlist)r   ÚsumÚ_to_send)r   r    Úsr   r0   r   Ú
_list_doneL   s    zRSync._list_donez	list[str]Úbytes)r    Úmodified_rel_path_componentsÚchecksumr   c                 C  sÞ   t jj| jg|¢R Ž }zt|dƒ}| ¡ }W n tyB   d}Y n0 d |¡}|durft|ƒ| j|< n
d| j|< || j	vr„g | j	|< | j	|  
|¡ |durÐ| ¡  |durÂ|t|ƒ ¡ krÂd}n|  |j|¡ | |¡ dS )zSend one item.ÚrbNú/r   )Úosr   Újoinr   ÚopenÚreadr#   Úlenr-   r5   ÚappendÚcloser   ÚdigestÚ_report_send_filer$   r'   )r   r    r9   r:   ZmodifiedpathÚfÚdataÚmodified_rel_pathr   r   r   Ú
_send_itemR   s&    





zRSync._send_itemr   )r$   rH   r   c                 C  s   | j rt|› d|› �ƒ d S )Nz <= )r   Úprint)r   r$   rH   r   r   r   rE   s   s    zRSync._report_send_file)Úraisesr   c                 C  s*  | j s|rtdƒ‚dS tj tj | jd¡¡| _|  | j¡ i | _i | _	| j �r&| j
 ¡ \}}|du rr|  |¡ qH|d dkrŠ|  |¡ qH|d dkr¢|  |¡ qH|d dkrÎ| jrÌ|  d| j|d  |¡ qH|d d	kræ|  |¡ qH|d d
k�r|  ||d d |d d ¡ qHd|d  sHJ ‚qHdS )z’Sends a sourcedir to all added targets.

        raises indicates whether to raise an error or return in case of lack of
        targets.
        z=no targets available, maybe you are trying call send() twice?NÚxr   ÚlinksÚdoneZacké   Z	list_doner'   zUnknown command %s)r   r#   r=   r   Údirnamer>   r   Ú_send_directory_structurer-   r5   r   Úgetr%   r)   r,   r   r7   rI   )r   rK   r    Úreqr   r   r   r'   w   s4    ÿ z
RSync.sendr   zstr | os.PathLike[str]zCallable[[], None] | None)r$   Údestdirr+   r   c                   sr   |D ]}|dv sJ ‚qddœ‡ ‡fdd„}|  tj¡‰ ˆ jddd� ˆ j|dd	� ˆ  t|ƒ|f¡ |ˆjˆ < dS )
zWAdd a remote target specified via a gateway and a remote destination
        directory.)Údeleter   )r   c                   s   ˆj  ˆ | f¡ d S r   )r   Úput)rS   ©r    r   r   r   Úitemcallback­   s    z&RSync.add_target.<locals>.itemcallbackF)Zpy2str_as_py3strZpy3str_as_py2strN)Z	endmarker)Zremote_execÚexecnetZrsync_remoteÚreconfigureZsetcallbackr'   r   r   )r   r$   rT   r+   ÚoptionsÚnamerX   r   rW   r   Ú
add_target¡   s    	zRSync.add_targetÚobject)Úmsgr   c                 C  s   | j D ]}| |¡ qd S r   )r   r'   )r   r_   r    r   r   r   Ú
_broadcast¶   s    
zRSync._broadcastzLiteral['linkbase', 'link'])ÚlinktypeÚbasenameÚ	linkpointr   c                 C  s   | j  |||f¡ d S r   )r   rB   )r   ra   rb   rc   r   r   r   Ú
_send_linkº   s    zRSync._send_linkc                 C  sx   g }g }t  |¡D ]0}t j ||¡}|  |¡r| |¡ | |¡ qt  |¡j}|  |g|¢¡ |D ]}|  	|¡ qdd S r   )
r=   Úlistdirr   r>   r   rB   ÚlstatÚst_moder`   rQ   )r   r   ÚnamesZsubpathsr\   ÚpÚmoder   r   r   Ú_send_directoryÂ   s    

zRSync._send_directoryc                 C  sÒ   | j }|t| j ƒd d … }t |¡}tjjdkrR| d¡rR| j  d¡sRd| j  }ztj ||¡}W n tyz   d }Y n0 |d ur¶|tj	tj
fvr¶| tj
tj ¡s¶|  d||¡ n|  d||¡ |  d ¡ d S )NrO   Úntpathz\\?\Zlinkbaser(   )r   rA   r=   Úreadlinkr   Ú__name__Ú
startswithÚrelpathÚ
ValueErrorÚcurdirÚpardirÚseprd   r`   )r   r   r   rb   rc   rp   r   r   r   Ú_send_link_structureÐ   s.    

ÿþ
ý

ÿþýzRSync._send_link_structurec                 C  s”   zt  |¡}W n ty,   |  d¡ Y d S 0 t |j¡rR|  |j|j|jf¡ n>t 	|j¡rj|  
|¡ n&t |j¡r‚|  |¡ ntd|›�ƒ‚d S )N)Nr   r   zcannot sync )r=   rf   r#   r`   ÚstatÚS_ISREGrg   Úst_mtimeÚst_sizeÚS_ISDIRrk   ÚS_ISLNKru   rq   )r   r   Ústr   r   r   rQ   ì   s    
zRSync._send_directory_structure)NT)T)N)rn   Ú
__module__Ú__qualname__Ú__doc__r   r   r%   r)   r,   r7   rI   rE   r'   r]   r`   rd   rk   ru   rQ   r   r   r   r   r
      s"   	!. ür
   )r   Ú
__future__r   r=   rv   Úhashlibr   Úqueuer   Útypingr   r   Zexecnet.rsync_remoterY   Zexecnet.gatewayr   Zexecnet.gateway_baser   r	   r
   r   r   r   r   Ú<module>   s   