simple file monitor by thread
import os
import sys
import time
import md5
import threading
nil = lambda *args , **kwargs : None
class SimpleFileMonitor() :
def __init__(self ,
path ,
on_init=nil ,
on_new=nil ,
on_del=nil ,
on_changed=nil ,
interval = 3
) :
self.xdir = os.path.normpath(path)
self.on_init = self.add_exception(on_init)
self.on_new = self.add_exception(on_new)
self.on_del = self.add_exception(on_del)
self.on_changed = self.add_exception(on_changed)
self.interval = float(interval)
self.isdir = os.path.isdir(self.xdir)
self.isover = False
self.thread = threading.Thread(target=self.monitor , args=())
thname = 'Simple.File.Monitor.on.%s' % (os.path.basename(self.xdir))
self.thread.setName(thname)
self.thread.setDaemon(True)
def add_exception(self , func) :
def _func(*args , **kwargs) :
try :
func(*args , **kwargs)
except BaseException , e :
print e
return _func
def get_hash(self , filepath) :
if not os.path.exists(filepath) : return None
_hash = md5.new()
_hash.update(open(filepath , 'rb').read())
return _hash.hexdigest()
def do_walk(self , on_init = nil) :
thash = {}
if not self.isdir :
try:
on_init(self.xdir)
except Exception,e:
print e
_hash = self.get_hash(self.xdir)
if _hash : thash[self.xdir] = _hash
else :
for _ , _ , files in os.walk(self.xdir) :
for xfile in files :
xfile = os.path.join(self.xdir , xfile)
on_init(xfile)
_hash = self.get_hash(xfile)
if _hash : thash[xfile] = _hash
return thash
def monitor(self) :
thash = self.do_walk(self.on_init)
while not self.isover :
time.sleep(self.interval)
xhash = self.do_walk()
adds = list(set(xhash) - set(thash))
dels = list(set(thash) - set(xhash))
changes = []
for x in set(xhash) & set(thash) :
if thash[x] != xhash[x] :
changes.append(x)
for x in adds : self.on_new(x)
for x in dels : self.on_del(x)
for x in changes : self.on_changed(x)
thash = xhash
def start(self) :
try :
self.thread.start()
except BaseException , e :
print e
def stop(self) :
self.isover = True
try :
self.thread.join(timeout=self.interval + 1)
except BaseException , e :
pass