Skip to content

Instantly share code, notes, and snippets.

@wnielson
Created April 7, 2010 04:48
Show Gist options
  • Save wnielson/358536 to your computer and use it in GitHub Desktop.
Save wnielson/358536 to your computer and use it in GitHub Desktop.
from django.db import models
from django.utils.translation import ugettext, ugettext_lazy as _
from dateutil import rrule
RRULE_WEEKDAYS = {"MO":0,"TU":1,"WE":2,"TH":3,"FR":4,"SA":5,"SU":6}
freqs = ( ("YEARLY", _("Yearly")),
("MONTHLY", _("Monthly")),
("WEEKLY", _("Weekly")),
("DAILY", _("Daily")),
("HOURLY", _("Hourly")),
("MINUTELY", _("Minutely")),
("SECONDLY", _("Secondly")))
class Rule(models.Model):
"""
This defines a rule by which an event will recur. This is defined by the
rrule in the dateutil documentation.
* name - the human friendly name of this kind of recursion.
* description - a short description describing this type of recursion.
* frequency - the base recurrence period
* param - extra params required to define this type of recursion. The params
should follow this format:
param = [rruleparam:value;]*
rruleparam = see list below
value = int[,int]*
The options are: (documentation for these can be found at
http://labix.org/python-dateutil#head-470fa22b2db72000d7abe698a5783a46b0731b57)
** count
** bysetpos
** bymonth
** bymonthday
** byyearday
** byweekno
** byweekday
** byhour
** byminute
** bysecond
** byeaster
"""
name = models.CharField(_("name"), max_length=32)
description = models.TextField(_("description"))
frequency = models.CharField(_("frequency"), choices=freqs, max_length=10)
params = models.TextField(_("params"), null=True, blank=True)
class Meta:
verbose_name = _('rule')
verbose_name_plural = _('rules')
app_label = 'schedule'
def parse_param(self, param_value):
param = param_value.split('(',1)[0]
if param in RRULE_WEEKDAYS:
try:
return eval("rrule.%s" % param_value)
except ValueError:
raise ValueError('rrule parameter improperly formatted. Error on: %s' % param_value)
try:
return int(param_value)
except ValueError:
raise ValueError('rrule parameter should be integer or weekday constant (e.g. MO, TU, etc.). Error on: %s' % param_value)
def get_params(self):
"""
>>> rule = Rule(params = "count:1;bysecond:1;byminute:1,2,4,5")
>>> rule.get_params()
{'count': 1, 'byminute': [1, 2, 4, 5], 'bysecond': 1}
"""
if self.params is None:
return {}
params = self.params.split(';')
param_dict = []
for param in params:
if param.strip() == "":
continue # skip blanks
param = param.split(':')
if len(param) == 2:
param = (str(param[0]).strip(), [self.parse_param(p.strip()) for p in param[1].split(',')])
if len(param[1]) == 1:
param = (param[0], param[1][0])
param_dict.append(param)
return dict(param_dict)
def __unicode__(self):
"""Human readable string for Rule"""
return self.name
@colbypalmer
Copy link

This also saved me a lot of time, and I second John's compliment on the error messages. Thanks a bunch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment