U
    ꥡc.                     @   s   d dl Z d dlZd dlmZ d dlmZ d dlmZ dZdZ	G dd deZ
G dd	 d	ZG d
d deZG dd deZG dd deZdS )    N)Path)
BaseThread)SkipRepeatsQueue   c                   @   s   e Zd ZdZdS )
EventQueuea.  Thread-safe event queue based on a special queue that skips adding
    the same event (:class:`FileSystemEvent`) multiple times consecutively.
    Thus avoiding dispatching multiple event handling
    calls when multiple identical events are produced quicker than an observer
    can consume them.
    N)__name__
__module____qualname____doc__ r   r   :/tmp/pip-unpacked-wheel-thtqfo2i/watchdog/observers/api.pyr      s   r   c                   @   s\   e Zd ZdZdd Zedd Zedd Zedd	 Zd
d Z	dd Z
dd Zdd ZdS )ObservedWatchzAn scheduled watch.

    :param path:
        Path string.
    :param recursive:
        ``True`` if watch is recursive; ``False`` otherwise.
    c                 C   s&   t |trt|| _n|| _|| _d S N)
isinstancer   str_path_is_recursive)selfpath	recursiver   r   r   __init__0   s    
zObservedWatch.__init__c                 C   s   | j S )z"The path that this watch monitors.)r   r   r   r   r   r   7   s    zObservedWatch.pathc                 C   s   | j S )z;Determines whether subdirectories are watched for the path.)r   r   r   r   r   is_recursive<   s    zObservedWatch.is_recursivec                 C   s   | j | jfS r   )r   r   r   r   r   r   keyA   s    zObservedWatch.keyc                 C   s   | j |j kS r   r   r   watchr   r   r   __eq__E   s    zObservedWatch.__eq__c                 C   s   | j |j kS r   r   r   r   r   r   __ne__H   s    zObservedWatch.__ne__c                 C   s
   t | jS r   )hashr   r   r   r   r   __hash__K   s    zObservedWatch.__hash__c                 C   s   dt | j| j| jf S )Nz<%s: path=%s, is_recursive=%s>)typer   r   r   r   r   r   r   __repr__N   s
      zObservedWatch.__repr__N)r   r   r	   r
   r   propertyr   r   r   r   r   r    r"   r   r   r   r   r   '   s   


r   c                       sT   e Zd ZdZef fdd	Zedd Zedd Zdd	 Z	d
d Z
dd Z  ZS )EventEmittera  
    Producer thread base class subclassed by event emitters
    that generate events and populate a queue with them.

    :param event_queue:
        The event queue to populate with generated events.
    :type event_queue:
        :class:`watchdog.events.EventQueue`
    :param watch:
        The watch to observe and produce events for.
    :type watch:
        :class:`ObservedWatch`
    :param timeout:
        Timeout (in seconds) between successive attempts at reading events.
    :type timeout:
        ``float``
    c                    s    t    || _|| _|| _d S r   )superr   _event_queue_watch_timeout)r   event_queuer   timeout	__class__r   r   r   g   s    
zEventEmitter.__init__c                 C   s   | j S )z6
        Blocking timeout for reading events.
        r(   r   r   r   r   r*   m   s    zEventEmitter.timeoutc                 C   s   | j S )z9
        The watch associated with this emitter.
        )r'   r   r   r   r   r   t   s    zEventEmitter.watchc                 C   s   | j || jf dS )z
        Queues a single event.

        :param event:
            Event to be queued.
        :type event:
            An instance of :class:`watchdog.events.FileSystemEvent`
            or a subclass.
        N)r&   putr   )r   eventr   r   r   queue_event{   s    
zEventEmitter.queue_eventc                 C   s   dS )a  Override this method to populate the event queue with events
        per interval period.

        :param timeout:
            Timeout (in seconds) between successive attempts at
            reading events.
        :type timeout:
            ``float``
        Nr   r   r*   r   r   r   queue_events   s    zEventEmitter.queue_eventsc                 C   s   |   r| | j q d S r   )should_keep_runningr2   r*   r   r   r   r   run   s    zEventEmitter.run)r   r   r	   r
   DEFAULT_EMITTER_TIMEOUTr   r#   r*   r   r0   r2   r4   __classcell__r   r   r+   r   r$   T   s   

r$   c                       sZ   e Zd ZdZe Zef fdd	Zedd Z	dd Z
edd	 Zd
d Zdd Z  ZS )EventDispatchera<  
    Consumer thread base class subclassed by event observer threads
    that dispatch events from an event queue to appropriate event handlers.

    :param timeout:
        Timeout value (in seconds) passed to emitters
        constructions in the child class BaseObserver.
    :type timeout:
        ``float``
    c                    s   t    t | _|| _d S r   )r%   r   r   r&   r(   r1   r+   r   r   r      s    
zEventDispatcher.__init__c                 C   s   | j S )z)Timeout value to construct emitters with.r-   r   r   r   r   r*      s    zEventDispatcher.timeoutc                 C   s8   t |  z| jtj W n tjk
r2   Y nX d S r   )r   stopr)   
put_nowaitr7   _stop_eventqueueFullr   r   r   r   r8      s
    
zEventDispatcher.stopc                 C   s   | j S )zThe event queue which is populated with file system events
        by emitters and from which events are dispatched by a dispatcher
        thread.)r&   r   r   r   r   r)      s    zEventDispatcher.event_queuec                 C   s   dS )ag  Override this method to consume events from an event queue, blocking
        on the queue for the specified timeout before raising :class:`queue.Empty`.

        :param event_queue:
            Event queue to populate with one set of events.
        :type event_queue:
            :class:`EventQueue`
        :raises:
            :class:`queue.Empty`
        Nr   )r   r)   r   r   r   dispatch_events   s    zEventDispatcher.dispatch_eventsc                 C   s:   |   r6z| | j W q  tjk
r2   Y q Y q X q d S r   )r3   r=   r)   r;   Emptyr   r   r   r   r4      s
    zEventDispatcher.run)r   r   r	   r
   objectr:   DEFAULT_OBSERVER_TIMEOUTr   r#   r*   r8   r)   r=   r4   r6   r   r   r+   r   r7      s   

r7   c                       s   e Zd ZdZef fdd	Zdd Zdd Zdd	 Zd
d Z	dd Z
edd Z fddZd!ddZdd Zdd Zdd Zdd Zdd Zdd  Z  ZS )"BaseObserverzBase observer.c                    s@   t  | || _t | _t | _t | _	t | _
t | _d S r   )r%   r   _emitter_class	threadingRLock_lockset_watchesdict	_handlers	_emitters_emitter_for_watch)r   Zemitter_classr*   r+   r   r   r      s    
zBaseObserver.__init__c                 C   s   || j |j< | j| d S r   )rK   r   rJ   addr   emitterr   r   r   _add_emitter   s    zBaseObserver._add_emitterc                 C   sD   | j |j= | j| |  z|  W n tk
r>   Y nX d S r   )rK   r   rJ   remover8   joinRuntimeErrorrM   r   r   r   _remove_emitter   s    
zBaseObserver._remove_emitterc              	   C   sZ   | j D ]}|  q| j D ]&}z|  W q tk
r>   Y qX q| j   | j  d S r   )rJ   r8   rQ   rR   clearrK   rM   r   r   r   _clear_emitters   s    



zBaseObserver._clear_emittersc                 C   s*   || j krt | j |< | j | | d S r   )rI   rF   rL   r   event_handlerr   r   r   r   _add_handler_for_watch   s    
z#BaseObserver._add_handler_for_watchc                 C   s   | j |= d S r   )rI   r   r   r   r   _remove_handlers_for_watch   s    z'BaseObserver._remove_handlers_for_watchc                 C   s   | j S )z/Returns event emitter created by this observer.)rJ   r   r   r   r   emitters   s    zBaseObserver.emittersc              	      sL   | j  D ]2}z|  W q
 tk
r:   | |  Y q
X q
t   d S r   )rJ   copystart	ExceptionrS   r%   rM   r+   r   r   r\     s    

zBaseObserver.startFc              	   C   sv   | j f t||}| || | j|dkr\| j| j|| jd}|  rR|	  | 
| | j| W 5 Q R X |S )am  
        Schedules watching a path and calls appropriate methods specified
        in the given event handler in response to file system events.

        :param event_handler:
            An event handler instance that has appropriate event handling
            methods which will be called by the observer in response to
            file system events.
        :type event_handler:
            :class:`watchdog.events.FileSystemEventHandler` or a subclass
        :param path:
            Directory path that will be monitored.
        :type path:
            ``str``
        :param recursive:
            ``True`` if events will be emitted for sub-directories
            traversed recursively; ``False`` otherwise.
        :type recursive:
            ``bool``
        :return:
            An :class:`ObservedWatch` object instance representing
            a watch.
        N)r)   r   r*   )rE   r   rX   rK   getrB   r)   r*   is_aliver\   rO   rG   rL   )r   rW   r   r   r   rN   r   r   r   schedule  s    

zBaseObserver.schedulec              	   C   s"   | j  | || W 5 Q R X dS )a!  Adds a handler for the given watch.

        :param event_handler:
            An event handler instance that has appropriate event handling
            methods which will be called by the observer in response to
            file system events.
        :type event_handler:
            :class:`watchdog.events.FileSystemEventHandler` or a subclass
        :param watch:
            The watch to add a handler for.
        :type watch:
            An instance of :class:`ObservedWatch` or a subclass of
            :class:`ObservedWatch`
        N)rE   rX   rV   r   r   r   add_handler_for_watch3  s    z"BaseObserver.add_handler_for_watchc              	   C   s&   | j  | j| | W 5 Q R X dS )a'  Removes a handler for the given watch.

        :param event_handler:
            An event handler instance that has appropriate event handling
            methods which will be called by the observer in response to
            file system events.
        :type event_handler:
            :class:`watchdog.events.FileSystemEventHandler` or a subclass
        :param watch:
            The watch to remove a handler for.
        :type watch:
            An instance of :class:`ObservedWatch` or a subclass of
            :class:`ObservedWatch`
        N)rE   rI   rP   rV   r   r   r   remove_handler_for_watchE  s    z%BaseObserver.remove_handler_for_watchc              	   C   s>   | j . | j| }| j|= | | | j| W 5 Q R X dS )zUnschedules a watch.

        :param watch:
            The watch to unschedule.
        :type watch:
            An instance of :class:`ObservedWatch` or a subclass of
            :class:`ObservedWatch`
        N)rE   rK   rI   rS   rG   rP   )r   r   rN   r   r   r   
unscheduleW  s
    	

zBaseObserver.unschedulec              	   C   s2   | j " | j  |   | j  W 5 Q R X dS )zKUnschedules all watches and detaches all associated event
        handlers.N)rE   rI   rT   rU   rG   r   r   r   r   unschedule_allf  s    
zBaseObserver.unschedule_allc                 C   s   |    d S r   )rd   r   r   r   r   on_thread_stopn  s    zBaseObserver.on_thread_stopc              	   C   st   |j dd}|tjkrd S |\}}| j: t| j |g D ] }|| j |g kr<|| q<W 5 Q R X |  d S )NT)block)r^   r7   r:   rE   listrI   dispatch	task_done)r   r)   entryr/   r   handlerr   r   r   r=   q  s    
zBaseObserver.dispatch_events)F)r   r   r	   r
   r@   r   rO   rS   rU   rX   rY   r#   rZ   r\   r`   ra   rb   rc   rd   re   r=   r6   r   r   r+   r   rA      s"   		
	
'rA   )r;   rC   pathlibr   Zwatchdog.utilsr   Zwatchdog.utils.bricksr   r5   r@   r   r   r$   r7   rA   r   r   r   r   <module>   s   	-C;