主要功能是自动发现被监控目录的上传文件。并通过socket传送给各个选定的父节点,然后父节点在同步到子节点IDC

#!/usr/bin/env python
#encoding=utf8

'''
@attention: This file is the main file
@license: GNU GPL v3
@author: Wayne
@contact: wangzhenyu@gyyx.cn
@note: 
    2015/06/18 lastest stable version 0.1 release
    
'''


import hashlib,sys,os,datetime,fcntl,re,socket,time,commands,threading,random
from  pyinotify import  WatchManager, Notifier,ProcessEvent,IN_DELETE, IN_CREATE,IN_MODIFY,IN_CLOSE_WRITE
from init_db import MyDB
def port_scan():
    print "start port scan.................."
    db2= MyDB(user = '***', passwd = '****', db = '******', socket = '/tmp/mysql.socket')
    if db2.connect():
        print "db2 connected"
    else:
        print "can not connect to db server!"
        return False
    ser_list=db2.select('select node_ip from ser_info')
    print  ser_list
    for ser in ser_list:
        sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            sk.connect((ser[0],6969))
            db2.modify("update ser_info set isalive=0 where node_ip='%s'" % ser[0])
        print "set %s is available" % ser[0]
            sk.close()
        except Exception:
            db2.modify("update ser_info set isalive=1 where node_ip='%s'" % ser[0])
        print "set %s is unavailable" % ser[0]
    return db2
def settopnode(db):

    
    sql_uni="select node_ip from ser_info  left join idc_info on (ser_info.idc_id=idc_info.idc_id and ser_info.isalive=0) where idc_info.line_id=1"
    sql_tel="select node_ip from ser_info  left join idc_info on (ser_info.idc_id=idc_info.idc_id and ser_info.isalive=0) where idc_info.line_id=0"
    print "searching server list............."
    uni_list=db.select(sql_uni)
    tel_list=db.select(sql_tel)
    if len(uni_list)==0:
        top_uni_node='error'
    else:
        top_uni_node=random.choice(uni_list)[0]
    if len(tel_list)==0:
        top_tel_node='error'
    else:
        top_tel_node=random.choice(tel_list)[0]
    return top_uni_node,top_tel_node
class ThreadSock(threading.Thread):
    def __init__(self,ip,fname,gdir,md5_sum):
        threading.Thread.__init__(self)
        self.setDaemon(True)
        self.ip=ip
        self.fname=fname
        self.gdir=gdir

        self.md5_sum=md5_sum
        self.port=6969
    def run(self):
        sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        sock.connect((self.ip,self.port))
        create_sync=rsync_file_cmd(self.fname,self.ip, self.gdir)
        starttime=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())
        commands.getstatusoutput(create_sync.cmd)
        sock.send(self.fname+" " +self.fdir+" "+self.md5_sum+" "+'END')

class rsync_file_cmd():
    def __init__(self,src_file,ip,dst):
        self.src_file=src_file
        self.ip=ip
        self.dst=dst
        self.cmd='/usr/bin/rsync -az --delete %s %s::htdocs/%s' % (src_file,ip,dst)
def save_trans_data(src,eventname,eventpath):
    db2=port_scan()
    print "start select topnode......."

    top_uni_node,top_tel_node=settopnode(db2)
    print top_uni_node,top_tel_node
    print src,eventname,eventpath
    os.chdir(eventpath)
    md5_sum=get_md5(eventname)
    gdir=eventpath.split('/')[-1]
    gid=int(db2.select('select gid from game_info where path="%s"' % eventpath)[0][0])
    print "gid is %d" % gid
    insert_sql="insert into file_info (fname,gid) values ('%s',%s)" % (eventname,gid)
    db2.modify(insert_sql)
    print "insert file to db......."
    db2.close()
    if top_uni_node !='error':
    print "start trans file to union nodes......"
        t1=ThreadSock(top_uni_node,eventname,gdir,md5_sum)
        t1.start()
    if top_tel_node !='error':
        t2=ThreadSock(top_tel_node,eventname,gdir,md5_sum)
        t2.start()
def get_md5(filename):
    md5_sum=hashlib.md5(filename).hexdigest()
    return md5_sum
class EventHandler(ProcessEvent):
    """Handle"""
    def process_IN_CREATE(self,event):
        if event.dir:
            if event.pathname.split('/')[-3]=='games':
                save_trans_data(event.pathname,event.name,event.path)
    def process_IN_CLOSE_WRITE(self, event):
        if event.pathname.split('/')[-3]=='games':
            save_trans_data(event.pathname,event.name,event.path)
        
def FSMonitor(path='/home/htdocs/games/'):
    wm = WatchManager()
    mask = IN_CLOSE_WRITE
    notifier = Notifier(wm,EventHandler())
    wm.add_watch(path,mask,rec=True,auto_add=True)
    while True:
                try:
                        notifier.process_events()
                        if notifier.check_events():
                                notifier.read_events()
                except:
                        notifier.stop()
                        break
if __name__=='__main__':

    try:
        pid = os.fork()
        if pid > 0:
            sys.exit(0)
    except OSError, e:
        print >>sys.stderr, 'fork failed: %d (%s)' % (e.errno, e.strerror)
        sys.exit(1)
    os.setsid()
    os.umask(0)
    FSMonitor()