o
    jZh                     @   sF   d Z ddlZddlZddlmZ ddlmZ ddl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
    N)md5)Queuec                   @   s   e Zd ZdZd"ddZdd Zdd	 Zd
d Zdd Zdd Z	dd Z
dd Zd#ddZd$ddZdd Zdd Zdd Zdd Zd d! 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).
    NTc                 C   sD   t || _|| _|d u st|dsJ || _i | _t | _g | _d S )N__call__)	str
_sourcedir_verbosehasattr	_callback	_channelsr   _receivequeue_links)self	sourcedircallbackverbose r   D/var/www/html/lang_env/lib/python3.10/site-packages/execnet/rsync.py__init__   s   

zRSync.__init__c                 C   s   dS NTr   )r   pathr   r   r   filter!   s   zRSync.filterc                 C   s(   || j v r|  td|j dd S )Nz connection unexpectedly closed:  )r   	waitcloseOSErrorgateway)r   channelr   r   r   _end_of_channel$   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 callbacksN)r   popr   )r   r   finishedcallbackr   r   r   _done1   s   zRSync._donec                    s8    j rt fdd j| D }  d|| d S d S )Nc                    s   g | ]} j | qS r   )_paths).0ir   r   r   
<listcomp>;   s    z$RSync._list_done.<locals>.<listcomp>list)r
   sum_to_send)r   r   sr   r(   r   
_list_done8   s   zRSync._list_donec                 C   s   |\}}t jj| jg|R  }zt|d}| }W n ty%   d}Y nw d|}|dur7t|| j|< nd| j|< || j	vrFg | j	|< | j	| 
| |durl|  |dure|t| kred}n| |j| || dS )zSend one itemrbN/r   )osr   joinr   openreadr   lenr%   r,   appendcloser   digest_report_send_filer   r   )r   r   datamodified_rel_pathZchecksumZmodifiedpathfr   r   r   
_send_item>   s*   




zRSync._send_itemc                 C   s    | j rt| d|  d S d S )Nz <= )r   print)r   r   r;   r   r   r   r9   [   s   zRSync._report_send_filec                 C   s
  | j s|r	tddS tjtj| jd| _| | j i | _i | _	| j r| j
 \}}|du r8| | nF|\}}|dkrF| | n8|dkrP| | n.|dkrb| jra| d| j| | n|dkrl| | n|dkrx| || ~nd	| s~J | j s'dS dS )
zSends a sourcedir to all added targets. Flag 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xlinksdoneZackZ	list_doner   zUnknown command %s)r   r   r1   r   dirnamer2   r   _send_directory_structurer%   r,   r   getr   r!   r$   r
   r.   r=   )r   Zraisesr   reqcommandr:   r   r   r   r   _   s<   z
RSync.sendc                    sl   |D ]}|dv s
J q fdd}| tj  jddd  j|dd  t||f |j < dS )zaAdds a remote target specified via a gateway
        and a remote destination directory.
        )deletec                    s   j  | f d S N)r   put)rE   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   Zdestdirr#   optionsnamerK   r   rJ   r   
add_target   s   zRSync.add_targetc                 C   s   | j D ]}|| qd S rH   )r   r   )r   msgr   r   r   r   
_broadcast   s   
zRSync._broadcastc                 C   s   | j |||f d S rH   )r   r6   )r   linktypebasename	linkpointr   r   r   
_send_link   s   zRSync._send_linkc                 C   sx   g }g }t |D ]}t j||}| |r!|| || q	t |j}| |g|  |D ]}| 	| q2d S rH   )
r1   listdirr   r2   r   r6   lstatst_moderR   rC   )r   r   namesZsubpathsrO   pmoder   r   r   _send_directory   s   


zRSync._send_directoryc                 C   s   | j }|t| j d d  }t|}tjjdkr)|dr)| j ds)d| j  }z	tj||}W n ty=   d }Y nw |d tj	tj
fvrX|tj
tj sX| d|| n| d|| | d  d S )N   ntpathz\\?\Zlinkbaser    )r   r5   r1   readlinkr   __name__
startswithrelpath
ValueErrorcurdirpardirseprV   rR   )r   r   r   rT   rU   rc   r   r   r   _send_link_structure   s(   



zRSync._send_link_structurec                 C   s   zt |}W n ty   | d Y d S w t|jr*| |j|j|jf d S t	|jr7| 
| d S t|jrD| | d S td|)N)Nr   r   zcannot sync )r1   rX   r   rR   statS_ISREGrY   st_mtimest_sizeS_ISDIRr]   S_ISLNKrh   rd   )r   r   str   r   r   rC      s   
zRSync._send_directory_structurer   )TrH   )ra   
__module____qualname____doc__r   r   r   r!   r$   r.   r=   r9   r   rP   rR   rV   r]   rh   rC   r   r   r   r   r      s"    
		

+r   )
rr   r1   ri   hashlibr   queuer   Zexecnet.rsync_remoterL   r   r   r   r   r   <module>   s    