Permalink
Browse files

Merge branch 'newtools' of git://github.com/ixc/glamkit-eventtools in…

…to newtools
  • Loading branch information...
2 parents e65c590 + 4a3131a commit 19f1a9337cd78bdeb0573c2c090483e8c791e1af @Aramgutang Aramgutang committed Dec 14, 2010
Showing with 43 additions and 24 deletions.
  1. +8 −5 eventtools/admin.py
  2. +6 −6 eventtools/models/event.py
  3. +20 −11 eventtools/models/generator.py
  4. +3 −1 eventtools/settings.py
  5. +6 −1 setup.py
View
@@ -22,7 +22,7 @@ def create_children(modeladmin, request, queryset):
def EventForm(EventModel):
class _EventForm(forms.ModelForm):
- parent = TreeNodeChoiceField(queryset=EventModel.objects.all(), level_indicator=u"-", required=False)
+ parent = TreeNodeChoiceField(queryset=EventModel._event_manager.all(), level_indicator=u"-", required=False)
class Meta:
model = EventModel
@@ -70,10 +70,13 @@ def create_child(self, request, parent_id):
for field_name in EventModel._event_meta.fields_to_inherit:
parent_attr = getattr(parent, field_name)
- if hasattr(parent_attr, 'all'): #for m2m. Sufficient?
- GET[field_name] = u",".join([unicode(i.pk) for i in parent_attr.all()])
- else:
- GET[field_name] = parent_attr
+ if parent_attr:
+ if hasattr(parent_attr, 'all'): #for m2m. Sufficient?
+ GET[field_name] = u",".join([unicode(i.pk) for i in parent_attr.all()])
+ elif hasattr(parent_attr, 'pk'): #for fk. Sufficient?
+ GET[field_name] = parent_attr.pk
+ else:
+ GET[field_name] = parent_attr
return redirect(
reverse("%s:%s_%s_add" % (
View
@@ -295,8 +295,11 @@ def cascade_changes_to_children(self):
continue
child.save() #cascades to grandchildren
- def has_occurrences(self):
- return self.occurrences.count()
+ def occurrence_count(self, include_descendants=True):
+ if include_descendants:
+ return self.get_descendants().occurrences().count()
+ else:
+ return self.occurrences.count()
def opening_occurrence(self):
try:
@@ -312,18 +315,15 @@ def closing_occurrence(self):
def get_ancestors(self):
ancestorqs = super(EventModel, self).get_ancestors()
- # it's a django QuerySet, so we need to recast it as an EventQuerySet to call occurrences() on it.
return ancestorqs
def get_descendants(self, include_self=True):
descendantsqs = super(EventModel, self).get_descendants(include_self=include_self)
- # it's a django QuerySet, so we need to recast it as an EventQuerySet to call occurrences() on it.
return descendantsqs
def get_family(self, include_self=True):
#have to call super, because the clone buggers up the filter...
familyqs = super(EventModel, self).get_ancestors() | super(EventModel, self).get_descendants(include_self=include_self)
- # it's a django QuerySet, so we need to recast it as an EventQuerySet to call occurrences() on it.
return familyqs
def highest_ancestor_having_occurrences(self, include_self=True, test=False):
@@ -332,7 +332,7 @@ def highest_ancestor_having_occurrences(self, include_self=True, test=False):
ancestors_with_occurrences = ancestors.having_occurrences()
if ancestors_with_occurrences:
return ancestors_with_occurrences[0]
- if include_self and self.has_occurrences():
+ if include_self and self.occurrence_count():
return self
return None
@@ -36,16 +36,16 @@ class GeneratorModel(models.Model):
#define a field called 'event' in the subclass
event_start = models.DateTimeField(db_index=True)
event_end = models.DateTimeField(blank=True, db_index=True)
- rule = models.ForeignKey(Rule, verbose_name=_("repetition rule"), null = True, blank = True, help_text=_("Select '----' for a one-off event."))
- repeat_until = models.DateTimeField(null = True, blank = True, help_text=_("These start dates are ignored for one-off events."))
- exceptions = JSONField(null=True, blank=True, help_text="These dates are skipped by the generator.", default={})
+ rule = models.ForeignKey(Rule, verbose_name=_(u"repetition rule"), null = True, blank = True, help_text=_(u"Select '----' for a one-off event."))
+ repeat_until = models.DateTimeField(null = True, blank = True, help_text=_(u"These start dates are ignored for one-off events."))
+ exceptions = JSONField(null=True, blank=True, help_text=_(u"These dates are skipped by the generator."), default={})
class Meta:
abstract = True
ordering = ('event_start',)
def __unicode__(self):
- return "%s, %s" % (self.event, self.robot_description())
+ return u"%s, %s" % (self.event, self.robot_description())
def clean(self):
if self.event_end is None:
@@ -161,10 +161,19 @@ def create_occurrence(self, start, end=None, honour_exceptions=False):
* the occurrence doesn't already exist for this event (regardless of the generator it came from)
"""
if not honour_exceptions or (honour_exceptions and not self.is_exception(start)):
- if self.occurrences.filter(start=start, end=end).count() == 0:
- if self.Occurrence().objects.filter(event=self.event, start=start, end=end).count() == 0:
- occ = self.occurrences.create(event=self.event, start=start, end=end) #generator = self
- return occ
+
+ if settings.ALLOW_CLASHING_OCCURRENCES:
+ # if this occurrence is already genecrated by this generator, do nothing
+ if self.occurrences.filter(start=start, end=end).count():
+ return
+ else:
+ # if this occurrence exists at all, do nothing (it's a clash and they're not allowed)
+ if self.Occurrence().objects.filter(event=self.event, start=start, end=end).count():
+ return
+ #good to go
+ return self.occurrences.create(event=self.event, start=start, end=end) #generator = self
+ # it's an exception, don't generate it.
+ return
def generate_dates(self):
rule = self.rule.get_rrule(dtstart=self.event_start)
@@ -183,7 +192,7 @@ def generate(self):
generate my occurrences
"""
- if self.rule is None: #the only occurrence in the village
+ if self.rule is None: #the only occurrence in the village, boyo
self.create_occurrence(start=self.event_start, end=self.event_end, honour_exceptions=True)
return
@@ -196,13 +205,13 @@ def robot_description(self):
if self.rule:
if self.occurrences.count() > 3:
if self.repeat_until:
- return "%s, repeating %s until %s" % (
+ return u"%s, repeating %s until %s" % (
pprint_datetime_span(self.event_start, self.event_end),
self.rule,
pprint_date_span(self.repeat_until, self.repeat_until)
)
else:
- return "%s, repeating %s" % (
+ return u"%s, repeating %s" % (
pprint_datetime_span(self.event_start, self.event_end),
self.rule,
)
View
@@ -19,4 +19,6 @@
ICAL_CALDESC = "Events listing" #e.g. "Events listing from mysite.com"
from dateutil.relativedelta import relativedelta
-DEFAULT_GENERATOR_LIMIT = relativedelta(years=1) #months=6, etc
+DEFAULT_GENERATOR_LIMIT = relativedelta(years=1) #months=6, etc
+
+ALLOW_CLASHING_OCCURRENCES = True
View
@@ -20,7 +20,12 @@
'Operating System :: OS Independent',
'Programming Language :: Python',
'Topic :: Utilities'],
- install_requires=['setuptools', 'vobject', 'python-dateutil'],
+ install_requires=['setuptools', 'vobject', 'python-dateutil', 'django-mptt'],
license='BSD',
test_suite = "eventtools.tests",
)
+
+# also requires glamkit-convenient
+# pip install -e git+git://github.com/glamkit/glamkit-convenient.git#egg=convenient
+# JSONfield
+# pip install -e git+git://github.com/ixc/django-jsonfield.git#egg=jsonfield

0 comments on commit 19f1a93

Please sign in to comment.