def __init__(self, basedir, ignore_event=None): super(INotifyTreeWatcher, self).__init__() self.basedir = realpath(basedir) self.watch_tree() self.modified = True self.ignore_event = ( lambda path, name: False) if ignore_event is None else ignore_event
def unwatch(self, path): path = realpath(path) with self.lock: try: watch = self.watches.pop(path) except KeyError: return watch.close(partial(self._stopped_watching, path))
def __call__(self, path): path = realpath(path) with self.lock: events = self.events.pop(path, None) if events: return True if path not in self.watches: self.watch(path) return True return False
def __call__(self, path): path = realpath(path) with self.lock: if path not in self.watches: self.watches[path] = os.path.getmtime(path) return True mtime = os.path.getmtime(path) if mtime != self.watches[path]: self.watches[path] = mtime return True return False
def unwatch(self, path): ''' Remove the watch for path. Raises an OSError if removing the watch fails for some reason. ''' path = realpath(path) with self.lock: self.modified.pop(path, None) self.last_query.pop(path, None) wd = self.watches.pop(path, None) if wd is not None: if self._rm_watch(self._inotify_fd, wd) != 0: self.handle_error()
def watch(self, path): path = realpath(path) with self.lock: if path not in self.watches: try: self.watches[path] = pyuv.fs.FSEvent( self.loop, path, partial(self._record_event, path), pyuv.fs.UV_CHANGE | pyuv.fs.UV_RENAME ) except pyuv.error.FSEventError as e: code = e.args[0] if code == pyuv.errno.UV_ENOENT: raise OSError('No such file or directory: ' + path) else: raise
def add_watches(self, base, top_level=True): ''' Add watches for this directory and all its descendant directories, recursively. ''' base = realpath(base) # There may exist a link which leads to an endless # add_watches loop or to maximum recursion depth exceeded if not top_level and base in self.watched_dirs: return try: is_dir = self.add_watch(base) except OSError as e: if e.errno == errno.ENOENT: # The entry could have been deleted between listdir() and # add_watch(). if top_level: raise NoSuchDir('The dir {0} does not exist'.format(base)) return if e.errno == errno.EACCES: # We silently ignore entries for which we dont have permission, # unless they are the top level dir if top_level: raise NoSuchDir( 'You do not have permission to monitor {0}'.format( base)) return raise else: if is_dir: try: files = os.listdir(base) except OSError as e: if e.errno in (errno.ENOTDIR, errno.ENOENT): # The dir was deleted/replaced between the add_watch() # and listdir() if top_level: raise NoSuchDir( 'The dir {0} does not exist'.format(base)) return raise for x in files: self.add_watches(os.path.join(base, x), top_level=False) elif top_level: # The top level dir is a file, not good. raise NoSuchDir('The dir {0} does not exist'.format(base))
def __call__(self, path, ignore_event=None): path = realpath(path) self.expire_old_queries() self.last_query_times[path] = monotonic() w = self.watches.get(path, None) if w is None: try: self.watch(path, ignore_event=ignore_event) except NoSuchDir: pass return True try: return w() except BaseDirChanged: self.watches.pop(path, None) return True except DirTooLarge as e: self.pl.warn(str(e)) self.watches[path] = DummyTreeWatcher(path) return False
def add_watches(self, base, top_level=True): ''' Add watches for this directory and all its descendant directories, recursively. ''' base = realpath(base) # There may exist a link which leads to an endless # add_watches loop or to maximum recursion depth exceeded if not top_level and base in self.watched_dirs: return try: is_dir = self.add_watch(base) except OSError as e: if e.errno == errno.ENOENT: # The entry could have been deleted between listdir() and # add_watch(). if top_level: raise NoSuchDir('The dir {0} does not exist'.format(base)) return if e.errno == errno.EACCES: # We silently ignore entries for which we dont have permission, # unless they are the top level dir if top_level: raise NoSuchDir('You do not have permission to monitor {0}'.format(base)) return raise else: if is_dir: try: files = os.listdir(base) except OSError as e: if e.errno in (errno.ENOTDIR, errno.ENOENT): # The dir was deleted/replaced between the add_watch() # and listdir() if top_level: raise NoSuchDir('The dir {0} does not exist'.format(base)) return raise for x in files: self.add_watches(os.path.join(base, x), top_level=False) elif top_level: # The top level dir is a file, not good. raise NoSuchDir('The dir {0} does not exist'.format(base))
def __call__(self, path): ''' Return True if path has been modified since the last call. Can raise OSError if the path does not exist. ''' path = realpath(path) with self.lock: self.last_query[path] = monotonic() self.expire_watches() if path not in self.watches: # Try to re-add the watch, it will fail if the file does not # exist/you don't have permission self.watch(path) return True self.read(get_name=False) if path not in self.modified: # An ignored event was received which means the path has been # automatically unwatched return True ans = self.modified[path] if ans: self.modified[path] = False return ans
def __call__(self, path): ''' Return True if path has been modified since the last call. Can raise OSError if the path does not exist. ''' path = realpath(path) with self.lock: self.last_query[path] = monotonic() self.expire_watches() if path not in self.watches: # Try to re-add the watch, it will fail if the file does not # exist/you dont have permission self.watch(path) return True self.read(get_name=False) if path not in self.modified: # An ignored event was received which means the path has been # automatically unwatched return True ans = self.modified[path] if ans: self.modified[path] = False return ans
def watch(self, path): ''' Register a watch for the file/directory named path. Raises an OSError if path does not exist. ''' path = realpath(path) with self.lock: if path not in self.watches: bpath = path if isinstance(path, bytes) else path.encode(self.fenc) flags = self.MOVE_SELF | self.DELETE_SELF buf = ctypes.c_char_p(bpath) # Try watching path as a directory wd = self._add_watch(self._inotify_fd, buf, flags | self.ONLYDIR) if wd == -1: eno = ctypes.get_errno() if eno != errno.ENOTDIR: self.handle_error() # Try watching path as a file flags |= (self.MODIFY | self.ATTRIB) wd = self._add_watch(self._inotify_fd, buf, flags) if wd == -1: self.handle_error() self.watches[path] = wd self.modified[path] = False
def __init__(self, basedir, ignore_event=None): super(INotifyTreeWatcher, self).__init__() self.basedir = realpath(basedir) self.watch_tree() self.modified = True self.ignore_event = (lambda path, name: False) if ignore_event is None else ignore_event
def is_watched(self, path): with self.lock: return realpath(path) in self.watches
def unwatch(self, path): path = realpath(path) with self.lock: self.watches.pop(path, None)
def watch(self, path): path = realpath(path) with self.lock: self.watches[path] = os.path.getmtime(path)
def normpath(path, fenc): path = realpath(path) if isinstance(path, bytes): return path.decode(fenc) else: return path
def watch(self, path, ignore_event=None): path = realpath(path) w = self.get_watcher(path, ignore_event) self.watches[path] = w return w
def is_watching(self, path): with self.lock: return realpath(path) in self.watches
def watch_directory(self, path): os.path.walk(realpath(path), self.watch_one_directory, None)
def __init__(self, basedir): self.basedir = realpath(basedir)
def __init__(self, basedir, ignore_event=None): super(UvTreeWatcher, self).__init__() self.ignore_event = ignore_event or (lambda path, name: False) self.basedir = realpath(basedir) self.modified = True self.watch_directory(self.basedir)