#!/usr/bin/env python # Inotify Updater # Hermann Kaser, 2007 # hermann.kaser@gmail.com # http://www.theragingche.com/ # License: Attribution-ShareAlike 3.0 Unported # http://creativecommons.org/licenses/by-sa/3.0/ # usage: ./threaded_rec.py [file with paths to watch] # file must contain one set of rules per line such as: # src_dir dest_dir # /home/hermann/folder1 /home/hermann/folder2 # Note that it depends on pretty up-to-date versions of pyinotify (0.7.0) # http://pyinotify.sourceforge.net/ import os import string from pyinotify import ThreadedNotifier, WatchManager, EventsCodes, ProcessEvent class PRec(ProcessEvent): def __init__(self, watch_manager,src,dest,mask): # no need to call ProcessEvent.__init__(self) self._watch_manager = watch_manager self.src = src self.dest = dest self.mask = mask # given a path, it figures out what the different bit is # if you're monitoring /home/hermann/folder1 # and file /home/hermann/folder1/test/somefile changes # this function return 'test/somefile' # you then proceed to stick this to the destination path and # do whatever you want to do with it def maskPath(self,event): fullPath = os.path.join(event.path,event.name) return fullPath[len(self.src):len(fullPath)] def process_IN_CREATE(self, event): diff = self.maskPath(event) # check to see if it's a dir in which case we need to do a mkdir # and add the dir to be watched if event.is_dir: # add watch to new dir self._watch_manager.add_watch(os.path.join(event.path,event.name), self.mask, proc_fun=self) command = 'mkdir %s' % self.dest+diff else: command = 'touch %s' % self.dest+diff print command pipe = os.popen(command, 'r') def process_IN_MODIFY(self, event): diff = self.maskPath(event) command = 'cp %s' % self.src+diff+' '+self.dest+diff print command pipe = os.popen(command,'r') pipe.close() if __name__ == '__main__': # # Full description: see threaded.py # import sys notifiers = [] # BITMASK of events, add or remove to suit your pleasure # note that you'll need to add the appropriate functions in PRec # http://pyinotify.sourceforge.net/#The_EventsCodes_Class mask = EventsCodes.IN_MODIFY | EventsCodes.IN_CREATE f = open(sys.argv[1],'r') # loop through lines adding watches for line in f: (src,dest) = string.split(line) # watch manager instance wm = WatchManager() # notifier instance and init notifier = ThreadedNotifier(wm) # start notifier's thread notifier.start() # append it to the notifier list notifiers.append(notifier) wm.add_watch(src, mask, proc_fun=PRec(wm,src,dest,mask),rec=True) print 'start monitoring %s with mask 0x%08x' % (src, mask) # keep artificially the main thread alive forever while True: try: import time time.sleep(5) except KeyboardInterrupt: # ...until c^c signal print 'stop monitoring...' # loop through notifiers to stop them for n in notifiers: n.stop() break except Exception, err: # otherwise keep on looping print err