watch_dirs.py 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  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. import os
  16. import time
  17. from six import string_types
  18. class DirWatcher(object):
  19. """Helper to watch a (set) of directories for modifications."""
  20. def __init__(self, paths):
  21. if isinstance(paths, string_types):
  22. paths = [paths]
  23. self._done = False
  24. self.paths = list(paths)
  25. self.lastrun = time.time()
  26. self._cache = self._calculate()
  27. def _calculate(self):
  28. """Walk over all subscribed paths, check most recent mtime."""
  29. most_recent_change = None
  30. for path in self.paths:
  31. if not os.path.exists(path):
  32. continue
  33. if not os.path.isdir(path):
  34. continue
  35. for root, _, files in os.walk(path):
  36. for f in files:
  37. if f and f[0] == '.':
  38. continue
  39. try:
  40. st = os.stat(os.path.join(root, f))
  41. except OSError as e:
  42. if e.errno == os.errno.ENOENT:
  43. continue
  44. raise
  45. if most_recent_change is None:
  46. most_recent_change = st.st_mtime
  47. else:
  48. most_recent_change = max(most_recent_change,
  49. st.st_mtime)
  50. return most_recent_change
  51. def most_recent_change(self):
  52. if time.time() - self.lastrun > 1:
  53. self._cache = self._calculate()
  54. self.lastrun = time.time()
  55. return self._cache