Skip to content

Commit

Permalink
- change _range() function in sheduler:
Browse files Browse the repository at this point in the history
  . add support for interval specification using "/x"
  . add support for range specification using "x-y"
  . refactor a little bit to have one block which handles a single
  item, which is used recursively when using ",", "/x" or "x-y"
# implements suggestion of issue mknx#59
- log exception message when error occurs while analyzing the crontab
  entry
  • Loading branch information
ohinckel committed Dec 6, 2013
1 parent 7b9df81 commit 3327f04
Showing 1 changed file with 32 additions and 12 deletions.
44 changes: 32 additions & 12 deletions lib/scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,8 +358,8 @@ def _crontab(self, crontab):
if not next_event:
next_event = self._parse_month(crontab, offset=1) # next month
return next_event
except:
logger.error("Error parsing crontab: {}".format(crontab))
except Exception as e:
logger.error('Error parsing crontab "{}": {}'.format(crontab, e))
return datetime.datetime.now(tzutc()) + dateutil.relativedelta.relativedelta(years=+10)

def _parse_month(self, crontab, offset=0):
Expand All @@ -378,7 +378,7 @@ def _parse_month(self, crontab, offset=0):
day_range = day_range + self._range(day, 0o1, mdays)
else:
day_range = self._range(day, 0o1, mdays)
# combine the differnt ranges
# combine the different ranges
event_range = sorted([str(day) + '-' + str(hour) + '-' + str(minute) for minute in minute_range for hour in hour_range for day in day_range])
if offset: # next month
next_event = event_range[0]
Expand Down Expand Up @@ -472,16 +472,36 @@ def _sun(self, crontab):
def _range(self, entry, low, high):
result = []
item_range = []
if entry == '*':
item_range = list(range(low, high + 1))
else:

# Check for multiple items and process each item recursively
if ',' in entry:
for item in entry.split(','):
item = int(item)
if item > high: # entry above range
item = high # truncate value to highest possible
item_range.append(item)
for entry in item_range:
result.append('{:02d}'.format(entry))
result.extend(self._range(item, low, high))

# Check for intervals, e.g. "*/2", "9-17/2"
elif '/' in entry:
spec_range, interval = entry.split('/')
logger.error('Cron spec interval {} {}'.format(entry, interval))
result = self._range(spec_range, low, high)[::int(interval)]

# Check for numeric ranges, e.g. "9-17"
elif '-' in entry:
spec_low, spec_high = entry.split('-')
result = self._range('*', int(spec_low), int(spec_high))

# Process single item
else:
if entry == '*':
item_range = list(range(low, high + 1))
else:
for item in entry.split(','):
item = int(item)
if item > high: # entry above range
item = high # truncate value to highest possible
item_range.append(item)
for entry in item_range:
result.append('{:02d}'.format(entry))

return result

def _day_range(self, days):
Expand Down

0 comments on commit 3327f04

Please sign in to comment.