def process_events(self, action, file_name, cookie, syncdaemon_path):
        """Process the events from the queue."""
        # do not process events when the watch was stopped
        if not self.platform_watch.watching:
            return

        # do not process those events that should be ignored
        if any([file_name.startswith(path)
                for path in self.ignore_paths]):
            return

        # map the filesystem events to the pyinotify ones, tis is dirty but
        # makes the multiplatform better, linux was first :P
        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 = 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 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 ACTIONS[action] == IN_MOVED_FROM:
            self._cookie = cookie
            self._source_pathname = tail
            event_raw_data['cookie'] = self._cookie
        if 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 generate_from_event(self, event, cookie):
     """Return a fake from event from a rename one."""
     source_path = get_syncdaemon_valid_path(event.event_paths[0])
     mask = IN_MOVED_FROM
     if event.is_directory:
         mask |= IN_ISDIR
     head, tail = os.path.split(source_path)
     event_raw_data = {
         'wd': 0,  # we only have one factory
         'dir': event.is_directory,
         'mask': mask,
         'name': tail,
         'cookie': cookie,
         'path': '.'}
     move_from_event = Event(event_raw_data)
     move_from_event.pathname = source_path
     return move_from_event
Example #3
0
 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 someplatforms 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)
    def convert_in_pyinotify_event(self, event):
        """Get an event from the daemon and convert it in a pyinotify one."""
        # the rename is a special type of event because it has to be either
        # converted is a pair of events or in a single one (CREATE or DELETE)
        if event.event_type == fseventsd.FSE_RENAME:

            is_create = self.is_create(event)
            is_delete = self.is_delete(event)

            if is_create or is_delete:
                mask = IN_CREATE if is_create else IN_DELETE
                if event.is_directory:
                    mask |= IN_ISDIR
                # a create means that we moved from a not watched path to a
                # watched one and therefore we are interested in the SECOND
                # path of the event. A delete means that we moved from a
                # watched path for a not watched one and we care about the
                # FIRST path of the event
                path = (
                    event.event_paths[1] if is_create else event.event_paths[0]
                )
                path = get_syncdaemon_valid_path(path)
                head, tail = os.path.split(path)
                event_raw_data = {
                    'wd': 0,  # we only have one factory
                    'dir': event.is_directory,
                    'mask': mask,
                    'name': tail,
                    'path': '.'}
                orig_event = Event(event_raw_data)
                orig_event.pathname = path
                events = [orig_event]

                if is_create:
                    mod_event = Event(event_raw_data)
                    mod_event.pathname = path
                    mod_event.mask = IN_MODIFY
                    if event.is_directory:
                        mod_event.mask |= IN_ISDIR
                    events.append(mod_event)

                return events
            else:
                # we have a rename within watched paths, so let's
                # generate two fake events
                cookie = str(uuid4())
                return [self.generate_from_event(event, cookie),
                        self.generate_to_event(event, cookie)]
        else:
            mask = DARWIN_ACTIONS[event.event_type]
            if event.is_directory:
                mask |= IN_ISDIR
            # we do know that we are not dealing with a move which are the only
            # events that have more than one path
            path = get_syncdaemon_valid_path(event.event_paths[0])
            head, tail = os.path.split(path)
            event_raw_data = {
                'wd': 0,  # we only have one factory
                'dir': event.is_directory,
                'mask': mask,
                'name': tail,
                'path': '.'}
            pyinotify_event = Event(event_raw_data)
            # FIXME: event deduces the pathname wrong and we need to manually
            # set it
            pyinotify_event.pathname = path
            return [pyinotify_event]