예제 #1
0
    def _update(self):
        newObservedFolders = set(self.directories)
        if self.eventStreamRef is not None:
            if newObservedFolders == self.observedFolders:
                return
            FSEventStreamStop(self.eventStreamRef)
            FSEventStreamUnscheduleFromRunLoop(self.eventStreamRef,
                                               CFRunLoopGetCurrent(),
                                               kCFRunLoopDefaultMode)
            FSEventStreamInvalidate(self.eventStreamRef)

        self.observedFolders = newObservedFolders
        if not newObservedFolders:
            self.eventStreamRef = None
            return

        self.eventStreamRef = FSEventStreamCreate(None,
                                                  self._fsEventCallback,
                                                  None,
                                                  list(newObservedFolders),
                                                  kFSEventStreamEventIdSinceNow,
                                                  self.latency,
                                                  kFSEventStreamCreateFlagNone)
        FSEventStreamScheduleWithRunLoop(self.eventStreamRef,
                                         CFRunLoopGetCurrent(),
                                         kCFRunLoopDefaultMode)
        FSEventStreamStart(self.eventStreamRef)
예제 #2
0
    def __add_dir(self, path, event_mask):
        """override of FSMonitor.__add_dir()"""
        if self.trigger_events_for_initial_scan and self.persistent:
            FSMonitor.generate_missed_events(self, path, event_mask)
        else:
            # Perform an initial scan of the directory structure. If this has
            # already been done, then it will return immediately.
            self.pathscanner.initial_scan(path)

        # Use the FSEvents API to monitor a directory.
        streamRef = FSEventStreamCreate(kCFAllocatorDefault,
                                        self.__fsevents_callback, path, [path],
                                        self.__class__.sinceWhen,
                                        self.__class__.latency,
                                        self.__class__.flags)
        # Debug output.
        #FSEventStreamShow(streamRef)

        if streamRef is None:
            raise MonitorError, "Could not monitor %s" % path
            return None
        else:
            self.monitored_paths[path] = MonitoredPath(path, event_mask,
                                                       streamRef)
            return self.monitored_paths[path]
예제 #3
0
 def __init__(self, path):
     Thread.__init__(self)
     self._queue = queue.Queue()
     self._run_loop = None
     if isinstance(path, bytes):
         self._path = path.decode('utf-8')
     self._path = unicodedata.normalize('NFC', self._path)
     context = None
     latency = 1.0
     self._stream_ref = FSEventStreamCreate(
         kCFAllocatorDefault, self._callback, context, [self._path],
         kFSEventStreamEventIdSinceNow, latency,
         kFSEventStreamCreateFlagNoDefer
         | kFSEventStreamCreateFlagFileEvents)
     if self._stream_ref is None:
         raise IOError('FSEvents. Could not create stream.')
예제 #4
0
def start_fs_events():
    stream_ref = FSEventStreamCreate(
        None,                               # Use the default CFAllocator
        fsevent_callback,
        None,                               # We don't need a FSEventStreamContext
        FS_WATCHED_FILES.keys(),
        kFSEventStreamEventIdSinceNow,      # We only want events which happen in the future
        1.0,                                # Process events within 1 second
        0                                   # We don't need any special flags for our stream
    )

    if not stream_ref:
        raise RuntimeError("FSEventStreamCreate() failed!")

    FSEventStreamScheduleWithRunLoop(stream_ref, NSRunLoop.currentRunLoop().getCFRunLoop(), kCFRunLoopDefaultMode)

    if not FSEventStreamStart(stream_ref):
        raise RuntimeError("Unable to start FSEvent stream!")

    logging.debug("FSEventStream started for %d paths: %s" % (len(FS_WATCHED_FILES), ", ".join(FS_WATCHED_FILES)))
예제 #5
0
    def __add_dir(self, path, event_mask):
        """override of FSMonitor.__add_dir()"""

        # Immediately start monitoring this directory.
        streamRef = FSEventStreamCreate(kCFAllocatorDefault,
                                        self.__fsevents_callback, path, [path],
                                        self.__class__.sinceWhen,
                                        self.__class__.latency,
                                        self.__class__.flags)
        # Debug output.
        #FSEventStreamShow(streamRef)
        # Verify that FSEvents is able to monitor this directory.
        if streamRef is None:
            raise MonitorError, "Could not monitor %s" % path
            return None
        else:
            self.monitored_paths[path] = MonitoredPath(path, event_mask,
                                                       streamRef)
            # TRICKY: the monitoring has not yet started! This happens in
            # FSMonitorEvents.__process_queues(), which is called on every
            # runloop by FSMonitorEvents.run().
            self.monitored_paths[path].monitoring = False

        if self.persistent:
            # Generate the missed events. This implies that events that
            # occurred while File Conveyor was offline (or not yet in use)
            # will *always* be generated, whether this is the first run or the
            # thousandth.
            # TODO: use FSEvents' sinceWhen parameter instead of the current
            # inefficient scanning method.
            FSMonitor.generate_missed_events(self, path)
        else:
            # Perform an initial scan of the directory structure. If this has
            # already been done, then it will return immediately.
            self.pathscanner.initial_scan(path)

        return self.monitored_paths[path]