1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""simple scheduler class that scheduler programs can use"""
# Copyright 2004 St James Software
#
# This file is part of jToolkit.
#
# jToolkit is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# jToolkit is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with jToolkit; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
import datetime
import threading
import time
from jToolkit import errors
from jToolkit import prefs
from jToolkit import tail
class Scheduler:
WEEKDAYS = [
"monday",
"tuesday",
"wednesday",
"thursday",
"friday",
"saturday",
"sunday"]
def __init__(self, errorhandler=None):
if errorhandler is None:
self.errorhandler = errors.ConsoleErrorHandler()
else:
self.errorhandler = errorhandler
self.runLock = threading.Lock()
def MainLoop(self):
# runLock is acquired means the scheduler should keep running
# if it is released the scheduler should stop running
try:
self.runLock.acquire()
instartup = True
while not self.runLock.acquire(False):
try:
time.sleep(1)
except KeyboardInterrupt:
self.errorhandler.logtrace(self.name+" manually stopped at following traceback...")
self.errorhandler.logtrace(self.errorhandler.traceback_str())
self.errorhandler.logtrace(self.name+" shutting down...")
self.runLock.release()
continue
except Exception:
# this will make it restart...
continue
# run any events that are scheduled for now...
if not self.RunScheduledEvent(instartup):
print "RunScheduledEvent returned a False value!"
break
instartup = False
print "finished loop..."
finally:
print "in finally", self.runLock.locked()
if self.runLock.locked():
self.runLock.release()
if hasattr(self, "mailerrorhandler"):
self.mailerrorhandler.shutdown()
def RunScheduledEvent(self, instartup=False):
raise NotImplementedError("RunScheduledEvent in jToolkit/Scheduler")
def MaintainLogfiles(self, logmaintainConfig, avgcharsperline=75):
logfiles = logmaintainConfig.LogfilesWatched.split(',')
lineskept = logmaintainConfig.LinesKept
tail.reduce_files_to_tail(logfiles, lineskept, avgcharsperline)
def GetNextScheduledTime(self, timeConfig, instartup=False):
"""gets the next time at which an event should run"""
frequency = timeConfig.frequency.lower()
nextSchedule = datetime.datetime.now()
# sets a skip rate, only works up to days...
nrate = int(getattr(timeConfig, 'nrate', 1))
if instartup:
onstartup = prefs.evaluateboolean(getattr(timeConfig, "onstartup", None), False)
if onstartup:
return nextSchedule
snaptime = prefs.evaluateboolean(getattr(timeConfig, "snaptime", None), False)
if frequency == 'minutely':
if snaptime and nextSchedule.minute > 0:
nextHour = (nextSchedule + datetime.timedelta(hours=1)).hour
nextTime = nextSchedule + datetime.timedelta(minutes=nrate)
if nextTime.hour == nextHour and nextTime.minute > 0:
nextSchedule = nextSchedule.replace(hour=nextHour, minute=0, second=0, microsecond=0)
return nextSchedule
if nextSchedule.second >= 0:
nextSchedule += datetime.timedelta(minutes=nrate)
return nextSchedule.replace(second=0)
ScheduleHour, ScheduleMinute = map(int, getattr(timeConfig, "time", "12:00").split(':'))
if frequency == 'hourly':
if nextSchedule.minute >= ScheduleMinute:
nextSchedule += datetime.timedelta(hours=nrate)
return nextSchedule.replace(minute=ScheduleMinute, second=0)
elif frequency == 'daily':
if nextSchedule.hour > ScheduleHour or \
(nextSchedule.hour == ScheduleHour and nextSchedule.minute >= ScheduleMinute):
nextSchedule += datetime.timedelta(days=nrate)
elif frequency == 'weekly':
ScheduleDay = self.WEEKDAYS.index(timeConfig.day)
if nextSchedule.weekday() > ScheduleDay or \
(nextSchedule.weekday() == ScheduleDay and \
(nextSchedule.hour > ScheduleHour or \
(nextSchedule.hour == ScheduleHour and nextSchedule.minute >= ScheduleMinute))):
nextSchedule += datetime.timedelta(days = 7 - (nextSchedule.weekday() - ScheduleDay))
elif frequency == 'monthly':
ScheduleDay = int(timeConfig.date)
if nextSchedule.day > ScheduleDay or \
(nextSchedule.day == ScheduleDay and \
(nextSchedule.hour > ScheduleHour or \
(nextSchedule.hour == ScheduleHour and nextSchedule.minute >= ScheduleMinute))):
if nextSchedule.month < 12:
nextSchedule = nextSchedule.replace(month = nextSchedule.month + 1)
else:
nextSchedule = nextSchedule.replace(month = 1, year = nextSchedule.year + 1)
nextSchedule = nextSchedule.replace(day = ScheduleDay)
else:
raise ValueError("Unknown frequency type %s" % frequency)
return nextSchedule.replace(hour=ScheduleHour, minute=ScheduleMinute)
|