1# Copyright 2015 gRPC authors. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14"""Helper to watch a (set) of directories for modifications.""" 15 16import os 17import time 18 19 20class DirWatcher(object): 21 """Helper to watch a (set) of directories for modifications.""" 22 23 def __init__(self, paths): 24 if isinstance(paths, basestring): 25 paths = [paths] 26 self._done = False 27 self.paths = list(paths) 28 self.lastrun = time.time() 29 self._cache = self._calculate() 30 31 def _calculate(self): 32 """Walk over all subscribed paths, check most recent mtime.""" 33 most_recent_change = None 34 for path in self.paths: 35 if not os.path.exists(path): 36 continue 37 if not os.path.isdir(path): 38 continue 39 for root, _, files in os.walk(path): 40 for f in files: 41 if f and f[0] == '.': continue 42 try: 43 st = os.stat(os.path.join(root, f)) 44 except OSError as e: 45 if e.errno == os.errno.ENOENT: 46 continue 47 raise 48 if most_recent_change is None: 49 most_recent_change = st.st_mtime 50 else: 51 most_recent_change = max(most_recent_change, 52 st.st_mtime) 53 return most_recent_change 54 55 def most_recent_change(self): 56 if time.time() - self.lastrun > 1: 57 self._cache = self._calculate() 58 self.lastrun = time.time() 59 return self._cache 60