# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors # MIT License. See license.txt from __future__ import unicode_literals """ Scheduler will call the following events from the module `startup.schedule_handler` and Control Panel (for server scripts) execute_always execute_daily execute_monthly execute_weekly The scheduler should be called from a cron job every x minutes (5?) depending on the need. """ import webnotes import webnotes.utils def execute(site=None): """ execute jobs this method triggers the other scheduler events Database connection: Ideally it should be connected from outside, if there is no connection, it will connect from defs.py """ from datetime import datetime format = '%Y-%m-%d %H:%M:%S' if not webnotes.conn: webnotes.connect(site=site) out = [] nowtime = webnotes.utils.now_datetime() last = webnotes.conn.get_global('scheduler_last_event') # set scheduler last event webnotes.conn.begin() webnotes.conn.set_global('scheduler_last_event', nowtime.strftime(format)) webnotes.conn.commit() if last: last = datetime.strptime(last, format) if nowtime.day != last.day: # if first task of the day execute daily tasks out.append(nowtime.strftime("%Y-%m-%d %H:%M:%S") + ' - daily:' + trigger('daily')) if nowtime.month != last.month: out.append(nowtime.strftime("%Y-%m-%d %H:%M:%S") + ' - monthly:' + trigger('monthly')) if nowtime.weekday()==0: out.append(nowtime.strftime("%Y-%m-%d %H:%M:%S") + ' - weekly:' + trigger('weekly')) if nowtime.hour != last.hour: out.append(nowtime.strftime("%Y-%m-%d %H:%M:%S") + ' - hourly:' + trigger('hourly')) out.append(nowtime.strftime("%Y-%m-%d %H:%M:%S") + ' - all:' + trigger('all')) return '\n'.join(out) def trigger(method): """trigger method in startup.schedule_handler""" traceback = "" for scheduler_event in webnotes.get_hooks().scheduler_event: event_name, handler = scheduler_event.split(":") if method==event_name: try: webnotes.get_attr(handler)() webnotes.conn.commit() except Exception: traceback += log("Method: {method}, Handler: {handler}".format(method=method, handler=handler)) traceback += log(webnotes.get_traceback()) webnotes.conn.rollback() return traceback or 'ok' def log(method, message=None): """log error in patch_log""" message = webnotes.utils.cstr(message) + "\n" if message else "" message += webnotes.get_traceback() if not (webnotes.conn and webnotes.conn._conn): webnotes.connect() webnotes.conn.rollback() webnotes.conn.begin() d = webnotes.doc("Scheduler Log") d.method = method d.error = message d.save() webnotes.conn.commit() return message def get_errors(from_date, to_date, limit): errors = webnotes.conn.sql("""select modified, method, error from `tabScheduler Log` where date(modified) between %s and %s and error not like '%%[Errno 110] Connection timed out%%' order by modified limit %s""", (from_date, to_date, limit), as_dict=True) return ["""

Time: {modified}

Method: {method}\n{error}
""".format(**e) for e in errors] def get_error_report(from_date=None, to_date=None, limit=10): from webnotes.utils import get_url, now_datetime, add_days if not from_date: from_date = add_days(now_datetime().date(), -1) if not to_date: to_date = add_days(now_datetime().date(), -1) errors = get_errors(from_date, to_date, limit) if errors: return 1, """

Scheduler Failed Events (max {limit}):

URL: {url}


{errors}""".format( limit=limit, url=get_url(), errors="
".join(errors)) else: return 0, "

Scheduler didn't encounter any problems.

" if __name__=='__main__': execute()