Skip to content

Instantly share code, notes, and snippets.

@verma
Created April 10, 2012 19:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save verma/2353932 to your computer and use it in GitHub Desktop.
Save verma/2353932 to your computer and use it in GitHub Desktop.
FileSystem Directory Watcher
# fswatcher.py
# Watches a particular directory for files with corresponding .lock files
#
from twisted.internet import reactor
import os
class DirectoryWatcher(object):
def __init__(self, dirname, interval=1.0):
self.dirname = dirname
self.interval = interval
self.callbacks = []
self.known_files = {}
self._notified = {}
if not os.path.exists(self.dirname):
raise Exception, "The watch directory does not exist: %s" % self.dirname
def start(self):
self.call = reactor.callWhenRunning(self._checkDir)
def stop(self):
self.call.cancel()
def addCallback(self, cb):
self.callbacks.append(cb)
def removeCallback(self, cb):
self.callbacks.remove(cb)
def _checkDir(self):
files=[]
for dirname, dirnames, filenames in os.walk(self.dirname):
for fn in filenames:
files.append(os.path.join(dirname, fn));
# we have all the files, lets filter .lock files out
clean_files = [f for f in files if os.path.splitext(f.lower())[1] != '.lock'];
lock_files = [os.path.basename(f) for f in files if os.path.splitext(f.lower())[1] == '.lock'];
clean_files_dict = {}
for c in clean_files:
id = os.path.splitext(os.path.basename(c))[0]
if id in clean_files_dict:
clean_files_dict[id].append(c)
else:
clean_files_dict[id] = [c]
to_notify = []
for k, v in clean_files_dict.items():
if k not in self._notified and ('%s.lock' % k) not in lock_files:
to_notify.append(v)
self._notified[k] = v
files_no_more = set(self._notified) - set(clean_files_dict)
for f in files_no_more:
del self._notified[f]
for v in to_notify:
for cb in self.callbacks:
cb(v)
self.call = reactor.callLater(self.interval, self._checkDir)
if __name__ == '__main__':
def on_file(v):
print 'Got:', v
d = DirectoryWatcher('/tmp/watcher-test', 1.0)
d.addCallback(on_file)
d.start()
reactor.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment