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)
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]
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.')
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)))
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]