
    "d7                        d Z ddl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
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j8                  d      Z G d d	e      Z G d
 de      Zy)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
    )annotationsN)
DirCreatedEventDirDeletedEventDirModifiedEventDirMovedEventFileCreatedEventFileDeletedEventFileModifiedEventFileMovedEventgenerate_sub_created_eventsgenerate_sub_moved_events)DEFAULT_EMITTER_TIMEOUTDEFAULT_OBSERVER_TIMEOUTBaseObserverEventEmitter)DirectorySnapshotfseventsc                       e Zd ZdZedf fd	Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zed        Zd Zd Zd Zd Zd Z x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                   t         |   |||       t               | _        || _        d| _        d | _        t        j                         | _	        t        j                  j                  t        j                  j                  t        j                  j                  | j                  j                                    | _        y )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__s        =/usr/lib/python3/dist-packages/watchdog/observers/fsevents.pyr   zFSEventsEmitter.__init__K   s     	eW5 0#^^%
$&GG$4$4GGOOBGG..tzz?@%
!    c                l    t        j                  | j                         t        j                  |        y N)	_fseventsremove_watchr&   stopr(   s    r,   on_thread_stopzFSEventsEmitter.on_thread_stop\   s     tzz*tr-   c                2   | j                   j                  r-t        j                  d|       t	        j
                  | |       y | j                  |      s-t        j                  d|       t	        j
                  | |       y t        j                  d|       y )Nzqueue_event %szdrop event %s)_watchis_recursiveloggerdebugr   queue_event_is_recursive_event)r(   events     r,   r:   zFSEventsEmitter.queue_event`   sk     ;;##LL)51$$T51++E2-u5((u5_e4r-   c                D   |j                   r|j                  n(t        j                  j	                  |j                        }|| j
                  k(  ryt        |t        t        f      r9t        j                  j	                  |j                        }|| j
                  k(  ryy)NFT)
is_directorysrc_pathr!   r"   dirnamer'   
isinstancer   r   	dest_path)r(   r<   r?   rB   s       r,   r;   z#FSEventsEmitter._is_recursive_eventm   sw    #00ENNbggooenn6U 	 t000enm<= 8ID555r-   c                    |j                   rt        nt        }| j                   ||             | j                  t	        |             y r/   )r>   r   r   r:   r   r(   r<   r?   r@   clss        r,   _queue_created_eventz$FSEventsEmitter._queue_created_event}   8    !&!3!3o9IX')'23r-   c                    |j                   rt        nt        }| j                   ||             | j                  t	        |             y r/   )r>   r   r	   r:   r   rD   s        r,   _queue_deleted_eventz$FSEventsEmitter._queue_deleted_event   rG   r-   c                b    |j                   rt        nt        }| j                   ||             y r/   )r>   r   r
   r:   rD   s        r,   _queue_modified_eventz%FSEventsEmitter._queue_modified_event   s%    "'"4"4:KX'r-   c                    |j                   rt        nt        }| j                  |      }| j	                   |||             | j	                  t        |             | j	                  t        |             y r/   )r>   r   r   _encode_pathr:   r   )r(   	src_eventr?   dst_pathsrc_dirnamedst_dirnamerE   s          r,   _queue_renamed_eventz$FSEventsEmitter._queue_renamed_event   s`      )55m>$$X.Xx01)+67)+67r-   c                    |j                   | j                  v }| j                  r9	 | j                  j                  |j                        d   }||j                   k(  }nd}|xs |S # t        $ r d}Y w xY w)Nr   F)inoder   r   r"   KeyError)r(   r<   
in_history	old_inodebefore_starts        r,   _is_historic_created_eventz*FSEventsEmitter._is_historic_created_event   sy     [[DMM1
% 0066uzzB1E	(EKK7 !L)\)  %$%s   7A& &A43A4c                R    | j                   xs | j                  xs | j                  S )z9Returns True if the event indicates a change in metadata.)is_inode_meta_modis_xattr_modis_owner_change)r<   s    r,   _is_meta_modzFSEventsEmitter._is_meta_mod   s&     &&U%*<*<U@U@UUr-   c                d
   t         j                         t        j                  k  rD|D ]?  dj	                  fdt              D              }t         j                   d|        A t        j                         | j                  z
  dkD  rd | _
        |r|j                  d      | j                  j                        }t        j                  j                  |      }	 t        j                   |      }|xr |j$                  j&                  k(  }j(                  rj*                  r| j-                        s| j/                  ||       | j0                  j3                  j&                         j4                  s| j7                        r| j9                  ||       | j;                  ||       | j0                  j=                  j&                         nj(                  r$| j-                        s| j/                  ||       | j0                  j3                  j&                         j4                  s| j7                        r| j9                  ||       j>                  rtA        tC        fd|D              d       }|r2t         j                  d|       | j                  |j                        }	t        j                  j                  |	      }
| jE                  ||	||
       | j0                  j3                  j&                         tG        ||	      D ]  }| jI                  |        |jK                  |       |j4                  s| j7                  |      r| j9                  ||	|
       |j*                  r| j;                  ||	|
       | j0                  j=                  |j&                         n|rZ| j/                  ||       | j0                  j3                  j&                         tM        |      D ]  }| jI                  |        n:| j;                  ||       | j0                  j=                  j&                         ǉj*                  r8| j;                  ||       | j0                  j=                  j&                         jN                  rm| jI                  tQ        | jR                  j                               t         j                  d       | jU                          | j0                  jW                          |ry y # t"        $ r d }Y 4w xY w)	Nz, c              3  @   K   | ]  }t        |      d u s|  yw)TN)getattr).0attrr<   s     r,   	<genexpr>z/FSEventsEmitter.queue_events.<locals>.<genexpr>   s$      "!75$3G43OD"s   z: <   r   c              3  p   K   | ]-  }|j                   s|j                  j                  k(  s*| / y wr/   )
is_renamedrT   )rb   er<   s     r,   rd   z/FSEventsEmitter.queue_events.<locals>.<genexpr>   s+      "#!''U[[BXAs   666z"Destination event for rename is %sz&Stopping because root path was changed),r8   getEffectiveLevelloggingDEBUGjoindirr9   time	monotonicr   r   poprM   r"   r!   r@   statOSErrorst_inorT   
is_created
is_removedrY   rF   r   addis_modifiedr^   rK   rI   discardrg   nextiterrR   r   r:   remover   is_root_changedr   r&   r2   clear)r(   r*   eventsflagsr?   rP   rq   exists	dst_eventrO   rQ   	sub_eventr<   s               @r,   queue_eventszFSEventsEmitter.queue_events   s"   ##%6 2		 "%(Z"  wb01	2 >>d...3#'D JJqME((4H''//(3Kwwx( 8dkkU[[8F( E$4$4
 66u=--eX{K!!%++.$$(9(9%(@..uhL))%;G%%ekk2 ##D,K,KE,R--eX{K!!%++.$$(9(9%(@..uhL## $ '-  	!I !%I9U#'#4#4Y^^#D&(ggooh&?11!8X{K ))%++6)B8X)V 8I ,,Y78
 i0$00D4E4Ei4P 66y(KX$// 55i;W MM11)//B 11%;O))%++6)DX)N 8I ,,Y78 11%;O--ekk: !##--eX{KMM))%++6$$   !ABEF		##%s   s   %T   T/.T/c                V   t         j                  }	 t        ||||      D 	cg c]  \  }}}}	 |||||	       }
}}}}	| j                  5  | j	                  | j
                  |
       ddd       yc c}	}}}w # 1 sw Y   yxY w# t        $ r t        j                  d       Y yw xY w)zhCallback passed to FSEventStreamCreate(), it will receive all
        FS events and queue them.
        Nz(Unhandled exception in fsevents callback)	r0   NativeEventzipr    r   r*   	Exceptionr8   	exception)r(   pathsinodesr   idsrE   r"   rT   event_flagsevent_idr~   s              r,   events_callbackzFSEventsEmitter.events_callback1  s     ##	I ;>eVUTW:X 6D%h D%h7F   8!!$,,78 8	8 8 	IGH	Is?   B A3
B A;*B 3B ;B B B B('B(c                N   | j                   j                  g| _        t        j                         | _        	 t        j                  | | j                   | j                  | j                         t        j                  |        y # t        $ r t        j                  d       Y y w xY w)Nz&Unhandled exception in FSEventsEmitter)r&   r"   	pathnamesrn   ro   r   r0   	add_watchr   read_eventsr   r8   r   r3   s    r,   runzFSEventsEmitter.run@  sy    **//*>>+	Gdjj$2F2FW!!$' 	GEF	Gs   AB B$#B$c                   | j                   rut        | j                  j                  t              r*t        j                  | j                  j                        }n| j                  j                  }t        |      | _        y y r/   )	r   rA   r&   r"   bytesr!   fsdecoder   r   )r(   
watch_paths     r,   on_thread_startzFSEventsEmitter.on_thread_startI  sR      $**//51[[9
!ZZ__
#4Z#@D  !r-   c                x    t        | j                  j                  t              rt	        j
                  |      S |S )z6Encode path only if bytes were passed to this emitter.)rA   r&   r"   r   r!   fsencode)r(   r"   s     r,   rM   zFSEventsEmitter._encode_pathR  s(    djjoou-;;t$$r-   )__name__
__module____qualname____doc__r   r   r4   r:   r;   rF   rI   rK   rR   rY   staticmethodr^   r   r   r   r   rM   __classcell__r+   s   @r,   r   r   4   sq    2 (
"5 4
4
(8*" V VE&NIGAr-   r   c                  *     e Zd Zef fd	ZddZ xZS )FSEventsObserverc                0    t         |   t        |       y )N)emitter_classr*   )r   r   r   )r(   r*   r+   s     r,   r   zFSEventsObserver.__init__Z  s    Hr-   c                ~    t        |t              rt        j                  d|      }t	        j
                  | |||      S )NNFC)rA   strunicodedata	normalizer   schedule)r(   event_handlerr"   	recursives       r,   r   zFSEventsObserver.schedule]  s7     dC ((5D$$T=$	JJr-   )F)r   r   r   r   r   r   r   r   s   @r,   r   r   Y  s    7 IKr-   r   ) r   
__future__r   rj   r!   r   rn   r   _watchdog_fseventsr0   watchdog.eventsr   r   r   r   r   r	   r
   r   r   r   watchdog.observers.apir   r   r   r   watchdog.utils.dirsnapshotr   	getLoggerr8   r   r    r-   r,   <module>r      sk     #  	    &   q p 8			:	&bl bJ		K| 	Kr-   