import croniter
import datetime
import time
import ConfigParser
import threading
import os
import logging
from logging.handlers import RotatingFileHandler
class ExecuteThread(threading.Thread):
_op_cmd = ""
_php_path = ""
_cmd_path = ""
_thread_stop = False
def __init__(self, execute_cmd, php_path, cmd_path, logger):
threading.Thread.__init__(self)
self._op_cmd = execute_cmd
self._php_path = php_path
self._cmd_path = cmd_path
self._logger = logger
def run(self):
retinfo = {'status':True,'msg':''}
self._logger.info("%s start."%(self._op_cmd))
try:
if self._php_path == "" or self._cmd_path == "":
raise Exception("php_path or cmd_path is empty.")
cmd = '%s %s Crontable/%s'%(self._php_path, \
self._cmd_path, self._op_cmd)
self._logger.info("CMD: %s"%(cmd))
cmd_ret = os.popen(cmd)
retinfo['msg'] = cmd_ret.read()
#retinfo['msg'] = cmd
time.sleep(160)
except:
retinfo['status'] = False
self._logger.error("%s execute failed."%(self._op_cmd))
#print retinfo
self._logger.info("%s end."%(self._op_cmd))
self.stop()
def stop(self):
self._thread_stop = True
class SMCOSched(object):
_cron_config = {}
_operator_dict = ['expiring','autocheck','dbbackup']
_cron_dict = {
'expiring':{'next_time':0,'cmd':'projectdelay','thread':None},
'autocheck':{'next_time':0,'cmd':'auto_check','thread':None},
'dbbackup':{'next_time':0,'cmd':'backupdb','thread':None}
}
_cron_log = None
def __init__(self):
# read configures
croninfo = self._read_cron_config("C:/dmg/sched_conf.ini")
if croninfo['status'] == True:
self._cron_config = croninfo['info']
self._is_read_cronconfig_success = True
else:
raise Exception(croninfo['info'])
# set work path
if self._cron_config['work_path'] == "":
raise Exception('work_path is empty.')
os.chdir(self._cron_config['work_path'])
# create log path
if os.path.exists(self._cron_config['log_path']) == False:
os.makedirs(self._cron_config['log_path'])
# create logger
self._cron_log = self._getLogger("smco_cron")
'''def run(self):
# create logger
self._cron_log = self._getLogger("smco_cron")
while True:
self._do_expriring()
self._do_autocheck()
self._do_dbbackup()
time.sleep(10)
'''
def do_expriring(self):
expiring_sched = self._cron_config['check_expiring_mark_timeout']
self._parse_execute(expiring_sched, self._cron_dict['expiring']['next_time'],'expiring')
def do_autocheck(self):
autocheck_sched = self._cron_config['auto_check_after_smco_limits_day']
self._parse_execute(autocheck_sched, self._cron_dict['autocheck']['next_time'],'autocheck')
def do_dbbackup(self):
dbbackup_sched = self._cron_config['bakup_db']
self._parse_execute(dbbackup_sched, self._cron_dict['dbbackup']['next_time'],'dbbackup')
def _parse_execute(self, sched, next_time, optype):
if next_time == 0:
basetime = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
next_time = self._get_next_time(sched, basetime)
self._cron_dict[optype]['next_time'] = next_time
else:
basetime = time.strftime('%Y-%m-%d %H:%M',time.localtime(next_time))
now_time = int(time.time())
now_time = now_time-now_time % 60
if next_time == now_time:
#print "execute %s ..." % optype
#print os.getcwd()
if self._cron_dict[optype]['thread'] is None or self._cron_dict[optype]['thread'].isAlive() == False:
self._cron_dict[optype]['thread'] = ExecuteThread(self._cron_dict[optype]['cmd'],\
self._cron_config['php_path'], self._cron_config['cli_path'], self._cron_log)
self._cron_dict[optype]['thread'].start()
self._cron_dict[optype]['thread'].setName(optype)
else:
self._cron_log.info("%s thread is running and jump."%(optype))
basetime = time.strftime('%Y-%m-%d %H:%M',time.localtime(now_time))
self._cron_dict[optype]['next_time'] = self._get_next_time(sched, basetime)
else:
pass
#self._cron_log.info("%s test %d %d" % (optype, now_time, next_time))
#print "%s test" % optype, now_time, next_time
def _get_next_time(self,sched, basetime):
cron = croniter.croniter(sched,
datetime.datetime.strptime(basetime,'%Y-%m-%d %H:%M'))
return cron.get_next()+time.timezone
def _read_cron_config(self, cron_name):
ret_dict = {"status":False,"info":""}
configures_dict = {}
try:
sysconf = ConfigParser.ConfigParser()
refilenames = sysconf.read(cron_name)
except IOError, e:
ret_dict['info'] = e
return ret_dict
if len(refilenames)==0 :
ret_dict['info'] = 'Read cron configure file failed.'
return ret_dict
sections = sysconf.sections()
configures_dict['check_expiring_mark_timeout'] = \
sysconf.get(sections[0],'check_expiring_mark_timeout')
configures_dict['auto_check_after_smco_limits_day'] = \
sysconf.get(sections[0],'auto_check_after_smco_limits_day')
configures_dict['bakup_db'] = sysconf.get(sections[0],'bakup_db')
configures_dict['work_path'] = sysconf.get(sections[0],'work_path')
configures_dict['php_path'] = sysconf.get(sections[0],'php_path')
configures_dict['cli_path'] = sysconf.get(sections[0],'cli_path')
configures_dict['log_path'] = sysconf.get(sections[0],'log_path')
ret_dict['status'] = True
ret_dict['info'] = configures_dict
return ret_dict
def _getLogger(self,log_file):
logger = logging.getLogger('[SMCO Cron]')
filename = '%s/%s.log'%(self._cron_config['log_path'], log_file)
handler = RotatingFileHandler(filename, mode='a',
maxBytes=5*1024*1024, backupCount=10, encoding=None, delay=0)
formatter = logging.Formatter('%(asctime)s %(name)-12s %(levelname)-8s %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.INFO)
return logger
if __name__ == "__main__":
tSMCOSched = SMCOSched()
tSMCOSched.run()