75 lines
2.5 KiB
Python
75 lines
2.5 KiB
Python
import datetime, time
|
|
from src import ModuleManager, utils
|
|
|
|
TIMESTAMP_BOUNDS = [
|
|
[0, 59],
|
|
[0, 23],
|
|
[1, 31],
|
|
[1, 12],
|
|
[0, 6],
|
|
]
|
|
|
|
class Module(ModuleManager.BaseModule):
|
|
def on_load(self):
|
|
now = datetime.datetime.utcnow()
|
|
next_minute = now.replace(second=0, microsecond=0)
|
|
next_minute += datetime.timedelta(minutes=1)
|
|
until = time.time()+((next_minute-now).total_seconds())
|
|
self.timers.add("cron", self._minute, 60, until)
|
|
|
|
def _minute(self, timer):
|
|
now = datetime.datetime.utcnow().replace(second=0, microsecond=0)
|
|
timer.redo()
|
|
|
|
timestamp = [now.minute, now.hour, now.day, now.month,
|
|
now.isoweekday()%7]
|
|
|
|
events = self.events.on("cron")
|
|
def _check(schedule):
|
|
return self._schedule_match(timestamp, schedule.split(" "))
|
|
event = events.make_event(schedule=_check)
|
|
|
|
for cron in events.get_hooks():
|
|
schedule = cron.get_kwarg("schedule", None)
|
|
if schedule and not _check(schedule):
|
|
continue
|
|
else:
|
|
cron.call(event)
|
|
|
|
def _schedule_match(self, timestamp, schedule):
|
|
items = enumerate(zip(timestamp, schedule))
|
|
for i, (timestamp_part, schedule_part) in items:
|
|
if not self._schedule_match_part(i, timestamp_part, schedule_part):
|
|
return False
|
|
return True
|
|
|
|
def _schedule_match_part(self, i, timestamp_part, schedule_part):
|
|
if "," in schedule_part:
|
|
for schedule_part in schedule_part.split(","):
|
|
if self._schedule_match_part([timestamp_part], [schedule_part]):
|
|
return True
|
|
|
|
elif "/" in schedule_part:
|
|
range_s, _, step = schedule_part.partition("/")
|
|
if "-" in range_s:
|
|
range_min, _, range_max = range_s.partition("-")
|
|
range_min = int(range_min)
|
|
range_max = int(range_max)
|
|
else:
|
|
range_min, range_max = TIMESTAMP_BOUNDS[i]
|
|
|
|
if (range_min <= timestamp_part <= range_max and
|
|
((timestamp_part-range_min)%int(step)) == 0):
|
|
return True
|
|
|
|
elif "-" in schedule_part:
|
|
left, right = schedule_part.split("-", 1)
|
|
return int(left) <= timestamp_part <= int(right)
|
|
|
|
elif schedule_part == "*":
|
|
return True
|
|
|
|
elif timestamp_part == int(schedule_part):
|
|
return True
|
|
|
|
return False
|