o
    *ήc5                     @   s   d 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	m
Z
mZmZmZmZmZmZmZmZ ddlmZmZmZmZ ddlmZ edZG dd deZG d	d
 d
eZdS )u   
:module: watchdog.observers.fsevents
:synopsis: FSEvents based emitter implementation.
:author: yesudeep@google.com (Yesudeep Mangalapilly)
:author: contact@tiger-222.fr (Mickaël Schoentgen)
:platforms: macOS
    N)
FileDeletedEventFileModifiedEventFileCreatedEventFileMovedEventDirDeletedEventDirModifiedEventDirCreatedEventDirMovedEventgenerate_sub_created_eventsgenerate_sub_moved_events)BaseObserverEventEmitterDEFAULT_EMITTER_TIMEOUTDEFAULT_OBSERVER_TIMEOUT)DirectorySnapshotfseventsc                       s   e Zd ZdZedf f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 Zedd Zdd Zdd Zdd Zdd Zdd  Z  ZS )!FSEventsEmittera5  
    macOS FSEvents Emitter class.

    :param event_queue:
        The event queue to fill with events.
    :param watch:
        A watch object representing the directory to monitor.
    :type watch:
        :class:`watchdog.observers.api.ObservedWatch`
    :param timeout:
        Read events blocking timeout (in seconds).
    :param suppress_history:
        The FSEvents API may emit historic events up to 30 sec before the watch was
        started. When ``suppress_history`` is ``True``, those events will be suppressed
        by creating a directory snapshot of the watched path before starting the stream
        as a reference to suppress old events. Warning: This may result in significant
        memory usage in case of a large number of items in the watched path.
    :type timeout:
        ``float``
    Fc                    sZ   t  ||| t | _|| _d| _d | _t | _	t
jt
jt
j| jj| _d S )Ng        )super__init__set_fs_viewsuppress_history_start_time_starting_state	threadingLock_lockospathrealpathabspath
expanduserwatch_absolute_watch_path)selfevent_queuer"   timeoutr   	__class__ B/tmp/pip-target-vg8gfxp4/lib/python/watchdog/observers/fsevents.pyr   P   s   
&zFSEventsEmitter.__init__c                 C   s   t | j t |  d S N)	_fseventsremove_watchr"   stopr$   r)   r)   r*   on_thread_stopY   s   zFSEventsEmitter.on_thread_stopc                 C   sZ   | j jrtd| t| | d S | |s%td| t| | d S td| d S )Nzqueue_event %szdrop event %s)_watchis_recursiveloggerdebugr   queue_event_is_recursive_event)r$   eventr)   r)   r*   r5   ]   s   
zFSEventsEmitter.queue_eventc                 C   sV   |j r|jntj|j}|| jkrdS t|ttfr)tj|j	}|| jkr)dS dS )NFT)
is_directorysrc_pathr   r   dirnamer#   
isinstancer   r	   	dest_path)r$   r7   r9   r<   r)   r)   r*   r6   j   s   

z#FSEventsEmitter._is_recursive_eventc                 C   .   |j rtnt}| || | t| d S r+   )r8   r   r   r5   r   r$   r7   r9   r:   clsr)   r)   r*   _queue_created_eventx      z$FSEventsEmitter._queue_created_eventc                 C   r=   r+   )r8   r   r   r5   r   r>   r)   r)   r*   _queue_deleted_event}   rA   z$FSEventsEmitter._queue_deleted_eventc                 C   s    |j rtnt}| || d S r+   )r8   r   r   r5   r>   r)   r)   r*   _queue_modified_event   s   z%FSEventsEmitter._queue_modified_eventc                 C   sH   |j rtnt}| |}| ||| | t| | t| d S r+   )r8   r	   r   _encode_pathr5   r   )r$   	src_eventr9   dst_pathsrc_dirnamedst_dirnamer?   r)   r)   r*   _queue_renamed_event   s
   
z$FSEventsEmitter._queue_renamed_eventc                 C   sV   |j | jv }| jr%z| j |jd }||j k}W n ty$   d}Y nw d}|p*|S )Nr   F)inoder   r   r   KeyError)r$   r7   
in_history	old_inodebefore_startr)   r)   r*   _is_historic_created_event   s   z*FSEventsEmitter._is_historic_created_eventc                 C   s   | j p| jp| jS )z9Returns True if the event indicates a change in metadata.)is_inode_meta_modis_xattr_modis_owner_changer7   r)   r)   r*   _is_meta_mod   s   zFSEventsEmitter._is_meta_modc                    s  t  tjkr$|D ] d fddt D }t   d|  q	t | j	 dkr0d | _
|r|d |  j}tj|}zt|}W n tyV   d }Y nw |o^|j jk} jr jr|  sq|  || | j j  js|  r|  || |  || | j j n҈ jr|  s|  || | j j  js|  r|  ||  jrVt t! fdd|D d }|r(t d| | |j}	tj|	}
| " ||	||
 | j j t#||	D ]}| $| q|%| |js| |r| ||	|
 |jr'| ||	|
 | j|j n.|rG|  || | j j t&|D ]}| $| q=n|  || | j j q0 jrh|  || | j j  j'r| $t(| j)j t d	 | *  | j+  |s3d S d S )
Nz, c                 3   s"    | ]}t  |d u r|V  qdS )TN)getattr).0attrrS   r)   r*   	<genexpr>   s     z/FSEventsEmitter.queue_events.<locals>.<genexpr>z: <   r   c                 3   s&    | ]}|j r|j jkr|V  qd S r+   )
is_renamedrJ   )rV   erS   r)   r*   rX      s   $ z"Destination event for rename is %sz&Stopping because root path was changed),r3   getEffectiveLevelloggingDEBUGjoindirr4   time	monotonicr   r   poprD   r   r   r:   statOSErrorst_inorJ   
is_created
is_removedrO   r@   r   addis_modifiedrT   rC   rB   discardrZ   nextiterrI   r   r5   remover
   is_root_changedr   r"   r.   clear)r$   r&   eventsflagsr9   rG   rd   exists	dst_eventrF   rH   	sub_eventr)   rS   r*   queue_events   s   




zFSEventsEmitter.queue_eventsc                    s   t j z- fddt||||D }| j | | j| W d   W dS 1 s)w   Y  W dS  ty?   td Y dS w )zhCallback passed to FSEventStreamCreate(), it will receive all
        FS events and queue them.
        c                    s"   g | ]\}}}} ||||qS r)   r)   )rV   r   rJ   event_flagsevent_idr?   r)   r*   
<listcomp>,  s    
z3FSEventsEmitter.events_callback.<locals>.<listcomp>Nz(Unhandled exception in fsevents callback)	r,   NativeEventzipr   rv   r&   	Exceptionr3   	exception)r$   pathsinodesrr   idsrq   r)   ry   r*   events_callback&  s   
&zFSEventsEmitter.events_callbackc                 C   s\   | j jg| _t | _zt| | j | j| j t	|  W d S  t
y-   td Y d S w )Nz&Unhandled exception in FSEventsEmitter)r"   r   	pathnamesra   rb   r   r,   	add_watchr   read_eventsr}   r3   r~   r/   r)   r)   r*   run7  s   
zFSEventsEmitter.runc                 C   s>   | j rt| jjtrt| jj}n| jj}t|| _d S d S r+   )	r   r;   r"   r   bytesr   fsdecoder   r   )r$   
watch_pathr)   r)   r*   on_thread_start@  s   zFSEventsEmitter.on_thread_startc                 C   s   t | jjtrt|S |S )z7Encode path only if bytes were passed to this emitter. )r;   r"   r   r   r   fsencode)r$   r   r)   r)   r*   rD   J  s   
zFSEventsEmitter._encode_path)__name__
__module____qualname____doc__r   r   r0   r5   r6   r@   rB   rC   rI   rO   staticmethodrT   rv   r   r   r   rD   __classcell__r)   r)   r'   r*   r   9   s&    	
 	
r   c                       s*   e Zd Zef fdd	ZdddZ  ZS )FSEventsObserverc                    s   t  jt|d d S )N)emitter_classr&   )r   r   r   )r$   r&   r'   r)   r*   r   S  s   zFSEventsObserver.__init__Fc                 C   s&   t |trtd|}t| |||S )NNFC)r;   strunicodedata	normalizer   schedule)r$   event_handlerr   	recursiver)   r)   r*   r   V  s   
zFSEventsObserver.schedule)F)r   r   r   r   r   r   r   r)   r)   r'   r*   r   Q  s    r   )r   ra   r]   r   r   r   _watchdog_fseventsr,   watchdog.eventsr   r   r   r   r   r   r   r	   r
   r   watchdog.observers.apir   r   r   r   watchdog.utils.dirsnapshotr   	getLoggerr3   r   r   r)   r)   r)   r*   <module>   s   0
  