leafsummer
1/4/2016 - 5:15 AM

simple file monitor by thread

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