Esempio n. 1
0
class InotifyEmitter(EventEmitter):
    """
    inotify(7)-based event emitter.
    
    :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).
    :type timeout:
        ``float``
    """

    def __init__(self, event_queue, watch, timeout = DEFAULT_EMITTER_TIMEOUT):
        EventEmitter.__init__(self, event_queue, watch, timeout)
        self._lock = threading.Lock()
        self._inotify = Inotify(watch.path, watch.is_recursive)

    def on_thread_stop(self):
        self._inotify.close()

    def queue_events(self, timeout):
        with self._lock:
            inotify_events = self._inotify.read_events()
            if not any([ event.is_moved_from or event.is_moved_to for event in inotify_events ]):
                self._inotify.clear_move_records()
            for event in inotify_events:
                if event.is_moved_to:
                    try:
                        src_path = self._inotify.source_for_move(event)
                        to_event = event
                        dest_path = to_event.src_path
                        klass = ACTION_EVENT_MAP[to_event.is_directory, EVENT_TYPE_MOVED]
                        event = klass(src_path, dest_path)
                        self.queue_event(event)
                        if event.is_directory and self.watch.is_recursive:
                            for sub_event in event.sub_moved_events():
                                self.queue_event(sub_event)

                    except KeyError:
                        pass

                elif event.is_attrib:
                    klass = ACTION_EVENT_MAP[event.is_directory, EVENT_TYPE_MODIFIED]
                    self.queue_event(klass(event.src_path))
                elif event.is_modify:
                    klass = ACTION_EVENT_MAP[event.is_directory, EVENT_TYPE_MODIFIED]
                    self.queue_event(klass(event.src_path))
                elif event.is_delete or event.is_delete_self:
                    klass = ACTION_EVENT_MAP[event.is_directory, EVENT_TYPE_DELETED]
                    self.queue_event(klass(event.src_path))
                elif event.is_create:
                    klass = ACTION_EVENT_MAP[event.is_directory, EVENT_TYPE_CREATED]
                    self.queue_event(klass(event.src_path))
Esempio n. 2
0
 def __init__(self, event_queue, watch, timeout=DEFAULT_EMITTER_TIMEOUT):
     EventEmitter.__init__(self, event_queue, watch, timeout)
     self._lock = threading.Lock()
     self._inotify = Inotify(watch.path, watch.is_recursive)
Esempio n. 3
0
class InotifyEmitter(EventEmitter):
    """
    inotify(7)-based event emitter.

    :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).
    :type timeout:
        ``float``
    """

    def __init__(self, event_queue, watch, timeout=DEFAULT_EMITTER_TIMEOUT):
        EventEmitter.__init__(self, event_queue, watch, timeout)
        self._lock = threading.Lock()
        self._inotify = Inotify(watch.path, watch.is_recursive)

    def on_thread_stop(self):
        self._inotify.close()

    def queue_events(self, timeout):
        with self._lock:
            inotify_events = self._inotify.read_events()
            if not any([event.is_moved_from or event.is_moved_to for event in inotify_events]):
                self._inotify.clear_move_records()
            for event in inotify_events:
                if event.is_moved_to:
                    # TODO: Sometimes this line will bomb even when a previous
                    # moved_from event with the same cookie has fired. I have
                    # yet to figure out why this is the case, so we're
                    # temporarily swallowing the exception and the move event.
                    # This happens only during massively quick file movement
                    # for example, when you execute `git gc` in a monitored
                    # directory.
                    try:
                        src_path = self._inotify.source_for_move(event)
                        to_event = event
                        dest_path = to_event.src_path
                        klass = ACTION_EVENT_MAP[(to_event.is_directory, EVENT_TYPE_MOVED)]
                        event = klass(src_path, dest_path)
                        self.queue_event(event)
                        # Generate sub events for the directory if recursive.
                        if event.is_directory and self.watch.is_recursive:
                            for sub_event in event.sub_moved_events():
                                self.queue_event(sub_event)
                    except KeyError:
                        pass
                elif event.is_close_write:
                    klass = ACTION_EVENT_MAP[(event.is_directory, EVENT_TYPE_MODIFIED)]
                    self.queue_event(klass(event.src_path))
                # elif event.is_modify:
                #     klass = ACTION_EVENT_MAP[(event.is_directory, EVENT_TYPE_MODIFIED)]
                #     self.queue_event(klass(event.src_path))
                elif event.is_delete or event.is_delete_self:
                    klass = ACTION_EVENT_MAP[(event.is_directory, EVENT_TYPE_DELETED)]
                    self.queue_event(klass(event.src_path))
                elif event.is_create:
                    klass = ACTION_EVENT_MAP[(event.is_directory, EVENT_TYPE_CREATED)]
                    self.queue_event(klass(event.src_path))
Esempio n. 4
0
 def __init__(self, event_queue, watch, timeout = DEFAULT_EMITTER_TIMEOUT):
     EventEmitter.__init__(self, event_queue, watch, timeout)
     self._lock = threading.Lock()
     self._inotify = Inotify(watch.path, watch.is_recursive)
Esempio n. 5
0
class InotifyEmitter(EventEmitter):
    """
    inotify(7)-based event emitter.

    :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).
    :type timeout:
        ``float``
    """
    def __init__(self, event_queue, watch, timeout=DEFAULT_EMITTER_TIMEOUT):
        EventEmitter.__init__(self, event_queue, watch, timeout)
        self._lock = threading.Lock()
        self._inotify = Inotify(watch.path, watch.is_recursive)

    def on_thread_stop(self):
        self._inotify.close()

    def queue_events(self, timeout):
        with self._lock:
            inotify_events = self._inotify.read_events()
            if not any([
                    event.is_moved_from or event.is_moved_to
                    for event in inotify_events
            ]):
                self._inotify.clear_move_records()
            for event in inotify_events:
                if event.is_moved_to:
                    # TODO: Sometimes this line will bomb even when a previous
                    # moved_from event with the same cookie has fired. I have
                    # yet to figure out why this is the case, so we're
                    # temporarily swallowing the exception and the move event.
                    # This happens only during massively quick file movement
                    # for example, when you execute `git gc` in a monitored
                    # directory.
                    try:
                        src_path = self._inotify.source_for_move(event)
                        to_event = event
                        dest_path = to_event.src_path
                        klass = ACTION_EVENT_MAP[(to_event.is_directory,
                                                  EVENT_TYPE_MOVED)]
                        event = klass(src_path, dest_path)
                        self.queue_event(event)
                        # Generate sub events for the directory if recursive.
                        if event.is_directory and self.watch.is_recursive:
                            for sub_event in event.sub_moved_events():
                                self.queue_event(sub_event)
                    except KeyError:
                        pass
                elif event.is_attrib:
                    klass = ACTION_EVENT_MAP[(event.is_directory,
                                              EVENT_TYPE_MODIFIED)]
                    self.queue_event(klass(event.src_path))
                elif event.is_modify:
                    klass = ACTION_EVENT_MAP[(event.is_directory,
                                              EVENT_TYPE_MODIFIED)]
                    self.queue_event(klass(event.src_path))
                elif event.is_delete or event.is_delete_self:
                    klass = ACTION_EVENT_MAP[(event.is_directory,
                                              EVENT_TYPE_DELETED)]
                    self.queue_event(klass(event.src_path))
                elif event.is_create:
                    klass = ACTION_EVENT_MAP[(event.is_directory,
                                              EVENT_TYPE_CREATED)]
                    self.queue_event(klass(event.src_path))