def _process_events(self, events):
        """Process the events from the queue."""
        # do not do it if we stop watching and the events are empty
        if not self._watching:
            return

        # we transform the events to be the same as the one in pyinotify
        # and then use the proc_fun
        for action, file_name in events:
            if any([file_name.startswith(path)
                        for path in self._ignore_paths]):
                continue
            # map the windows events to the pyinotify ones, tis is dirty but
            # makes the multiplatform better, linux was first :P
            syncdaemon_path = get_syncdaemon_valid_path(
                                        os.path.join(self._path, file_name))
            full_dir_path = os.path.join(self._path, file_name)
            is_dir = self._path_is_dir(full_dir_path)
            if is_dir:
                # we need to update the list of subdirs that we have
                self._update_subdirs(full_dir_path, action)
            mask = WINDOWS_ACTIONS[action]
            head, tail = os.path.split(file_name)
            if is_dir:
                mask |= IN_ISDIR
            event_raw_data = {
                'wd': self._descriptor,
                'dir': is_dir,
                'mask': mask,
                'name': tail,
                'path': '.'}
            # by the way in which the win api fires the events we know for
            # sure that no move events will be added in the wrong order, this
            # is kind of hacky, I dont like it too much
            if WINDOWS_ACTIONS[action] == IN_MOVED_FROM:
                self._cookie = str(uuid4())
                self._source_pathname = tail
                event_raw_data['cookie'] = self._cookie
            if WINDOWS_ACTIONS[action] == IN_MOVED_TO:
                event_raw_data['src_pathname'] = self._source_pathname
                event_raw_data['cookie'] = self._cookie
            event = Event(event_raw_data)
            # FIXME: event deduces the pathname wrong and we need to manually
            # set it
            event.pathname = syncdaemon_path
            # add the event only if we do not have an exclude filter or
            # the exclude filter returns False, that is, the event will not
            # be excluded
            self.log.debug('Pushing event %r to processor.', event)
            self._processor(event)
 def process_IN_MODIFY(self, event):
     """Capture a modify event and fake an open ^ close write events."""
     # lets ignore dir changes
     if event.dir:
         return
     # on windows we just get IN_MODIFY, lets always fake
     # an OPEN & CLOSE_WRITE couple
     raw_open = raw_close = {
        'wd': event.wd,
        'dir': event.dir,
        'name': event.name,
        'path': event.path}
     # caculate the open mask
     raw_open['mask'] = IN_OPEN
     # create the event using the raw data, then fix the pathname param
     open_event = Event(raw_open)
     open_event.pathname = event.pathname
     # push the open
     self.general_processor.push_event(open_event)
     raw_close['mask'] = IN_CLOSE_WRITE
     close_event = Event(raw_close)
     close_event.pathname = event.pathname
     # push the close event
     self.general_processor.push_event(close_event)