def crondance(applications_parent, ctype='soft', startup=False): apppath = os.path.join(applications_parent, 'applications') cron_path = os.path.join(apppath, 'admin', 'cron') token = Token(cron_path) cronmaster = token.acquire(startup=startup) if not cronmaster: return now_s = time.localtime() checks = (('min', now_s.tm_min), ('hr', now_s.tm_hour), ('mon', now_s.tm_mon), ('dom', now_s.tm_mday), ('dow', (now_s.tm_wday + 1) % 7)) apps = [ x for x in os.listdir(apppath) if os.path.isdir(os.path.join(apppath, x)) ] for app in apps: if _cron_stopping: break apath = os.path.join(apppath, app) cronpath = os.path.join(apath, 'cron') crontab = os.path.join(cronpath, 'crontab') if not os.path.exists(crontab): continue try: cronlines = fileutils.readlines_file(crontab, 'rt') lines = [ x.strip() for x in cronlines if x.strip() and not x.strip().startswith('#') ] tasks = [parsecronline(cline) for cline in lines] except Exception, e: logger.error('WEB2PY CRON: crontab read error %s' % e) continue for task in tasks: if _cron_stopping: break commands = [sys.executable] w2p_path = fileutils.abspath('web2py.py', gluon=True) if os.path.exists(w2p_path): commands.append(w2p_path) if global_settings.applications_parent != global_settings.gluon_parent: commands.extend(('-f', global_settings.applications_parent)) citems = [(k in task and not v in task[k]) for k, v in checks] task_min = task.get('min', []) if not task: continue elif not startup and task_min == [-1]: continue elif task_min != [-1] and reduce(lambda a, b: a or b, citems): continue logger.info('WEB2PY CRON (%s): %s executing %s in %s at %s' \ % (ctype, app, task.get('cmd'), os.getcwd(), datetime.datetime.now())) action, command, models = False, task['cmd'], '' if command.startswith('**'): (action, models, command) = (True, '', command[2:]) elif command.startswith('*'): (action, models, command) = (True, '-M', command[1:]) else: action = False if action and command.endswith('.py'): commands.extend(( '-J', # cron job models, # import models? '-S', app, # app name '-a', '"<recycle>"', # password '-R', command)) # command shell = True elif action: commands.extend(( '-J', # cron job models, # import models? '-S', app + '/' + command, # app name '-a', '"<recycle>"')) # password shell = True else: commands = command shell = False try: cronlauncher(commands, shell=shell).start() except Exception, e: logger.warning( 'WEB2PY CRON: Execution error for %s: %s' \ % (task.get('cmd'), e))
def crondance(applications_parent, ctype='soft', startup=False, apps=None): apppath = os.path.join(applications_parent, 'applications') cron_path = os.path.join(applications_parent) token = Token(cron_path) cronmaster = token.acquire(startup=startup) if not cronmaster: return now_s = time.localtime() checks = (('min', now_s.tm_min), ('hr', now_s.tm_hour), ('mon', now_s.tm_mon), ('dom', now_s.tm_mday), ('dow', (now_s.tm_wday + 1) % 7)) if apps is None: apps = [x for x in os.listdir(apppath) if os.path.isdir(os.path.join(apppath, x))] full_apath_links = set() for app in apps: if _cron_stopping: break apath = os.path.join(apppath, app) # if app is a symbolic link to other app, skip it full_apath_link = absolute_path_link(apath) if full_apath_link in full_apath_links: continue else: full_apath_links.add(full_apath_link) cronpath = os.path.join(apath, 'cron') crontab = os.path.join(cronpath, 'crontab') if not os.path.exists(crontab): continue try: cronlines = fileutils.readlines_file(crontab, 'rt') lines = [x.strip() for x in cronlines if x.strip( ) and not x.strip().startswith('#')] tasks = [parsecronline(cline) for cline in lines] except Exception, e: logger.error('WEB2PY CRON: crontab read error %s' % e) continue for task in tasks: if _cron_stopping: break commands = [sys.executable] w2p_path = fileutils.abspath('web2py.py', gluon=True) if os.path.exists(w2p_path): commands.append(w2p_path) if global_settings.applications_parent != global_settings.gluon_parent: commands.extend(('-f', global_settings.applications_parent)) citems = [(k in task and not v in task[k]) for k, v in checks] task_min = task.get('min', []) if not task: continue elif not startup and task_min == [-1]: continue elif task_min != [-1] and reduce(lambda a, b: a or b, citems): continue logger.info('WEB2PY CRON (%s): %s executing %s in %s at %s' % (ctype, app, task.get('cmd'), os.getcwd(), datetime.datetime.now())) action, command, models = False, task['cmd'], '' if command.startswith('**'): (action, models, command) = (True, '', command[2:]) elif command.startswith('*'): (action, models, command) = (True, '-M', command[1:]) else: action = False if action and command.endswith('.py'): commands.extend(('-J', # cron job models, # import models? '-S', app, # app name '-a', '"<recycle>"', # password '-R', command)) # command elif action: commands.extend(('-J', # cron job models, # import models? '-S', app + '/' + command, # app name '-a', '"<recycle>"')) # password else: commands = command # from python docs: # You do not need shell=True to run a batch file or # console-based executable. shell = False try: cronlauncher(commands, shell=shell).start() except Exception, e: logger.warning( 'WEB2PY CRON: Execution error for %s: %s' % (task.get('cmd'), e))
def crondance(applications_parent, ctype="soft", startup=False, apps=None): apppath = os.path.join(applications_parent, "applications") cron_path = os.path.join(applications_parent) token = Token(cron_path) cronmaster = token.acquire(startup=startup) if not cronmaster: return now_s = time.localtime() checks = ( ("min", now_s.tm_min), ("hr", now_s.tm_hour), ("mon", now_s.tm_mon), ("dom", now_s.tm_mday), ("dow", (now_s.tm_wday + 1) % 7), ) if apps is None: apps = [x for x in os.listdir(apppath) if os.path.isdir(os.path.join(apppath, x))] full_apath_links = set() for app in apps: if _cron_stopping: break apath = os.path.join(apppath, app) # if app is a symbolic link to other app, skip it full_apath_link = absolute_path_link(apath) if full_apath_link in full_apath_links: continue else: full_apath_links.add(full_apath_link) cronpath = os.path.join(apath, "cron") crontab = os.path.join(cronpath, "crontab") if not os.path.exists(crontab): continue try: cronlines = fileutils.readlines_file(crontab, "rt") lines = [x.strip() for x in cronlines if x.strip() and not x.strip().startswith("#")] tasks = [parsecronline(cline) for cline in lines] except Exception, e: logger.error("WEB2PY CRON: crontab read error %s" % e) continue for task in tasks: if _cron_stopping: break if sys.executable.lower().endswith("pythonservice.exe"): _python_exe = os.path.join(sys.exec_prefix, "python.exe") else: _python_exe = sys.executable commands = [_python_exe] w2p_path = fileutils.abspath("web2py.py", gluon=True) if os.path.exists(w2p_path): commands.append(w2p_path) if applications_parent != global_settings.gluon_parent: commands.extend(("-f", applications_parent)) citems = [(k in task and not v in task[k]) for k, v in checks] task_min = task.get("min", []) if not task: continue elif not startup and task_min == [-1]: continue elif task_min != [-1] and reduce(lambda a, b: a or b, citems): continue logger.info( "WEB2PY CRON (%s): %s executing %s in %s at %s" % (ctype, app, task.get("cmd"), os.getcwd(), datetime.datetime.now()) ) action, command, models = False, task["cmd"], "" if command.startswith("**"): (action, models, command) = (True, "", command[2:]) elif command.startswith("*"): (action, models, command) = (True, "-M", command[1:]) else: action = False if action and command.endswith(".py"): commands.extend( ( "-J", # cron job models, # import models? "-S", app, # app name "-a", '"<recycle>"', # password "-R", command, ) ) # command elif action: commands.extend( ( "-J", # cron job models, # import models? "-S", app + "/" + command, # app name "-a", '"<recycle>"', ) ) # password else: commands = command # from python docs: # You do not need shell=True to run a batch file or # console-based executable. shell = False try: cronlauncher(commands, shell=shell).start() except Exception, e: logger.warning("WEB2PY CRON: Execution error for %s: %s" % (task.get("cmd"), e))