Created
April 7, 2010 04:48
-
-
Save wnielson/358536 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This also saved me a lot of time, and I second John's compliment on the error messages. Thanks a bunch.