[CalendarServer-changes] [7506] CalendarServer/trunk/twistedcaldav
source_changes at macosforge.org
source_changes at macosforge.org
Thu May 19 17:21:05 PDT 2011
Revision: 7506
http://trac.macosforge.org/projects/calendarserver/changeset/7506
Author: cdaboo at apple.com
Date: 2011-05-19 17:21:05 -0700 (Thu, 19 May 2011)
Log Message:
-----------
Fix bug where VTODO time-ranges were not calculated according to the spec.
Modified Paths:
--------------
CalendarServer/trunk/twistedcaldav/ical.py
CalendarServer/trunk/twistedcaldav/instance.py
Modified: CalendarServer/trunk/twistedcaldav/ical.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/ical.py 2011-05-20 00:19:15 UTC (rev 7505)
+++ CalendarServer/trunk/twistedcaldav/ical.py 2011-05-20 00:21:05 UTC (rev 7506)
@@ -1,6 +1,6 @@
# -*- test-case-name: twistedcaldav.test.test_icalendar -*-
##
-# Copyright (c) 2005-2010 Apple Inc. All rights reserved.
+# Copyright (c) 2005-2011 Apple Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -135,6 +135,10 @@
ignoredComponents = ("VTIMEZONE", "X-CALENDARSERVER-PERUSER",)
+# Used for min/max time-range query limits
+minDateTime = PyCalendarDateTime(1900, 1, 1, 0, 0, 0, tzid=PyCalendarTimezone(utc=True))
+maxDateTime = PyCalendarDateTime(2100, 1, 1, 0, 0, 0, tzid=PyCalendarTimezone(utc=True))
+
class InvalidICalendarDataError(ValueError):
pass
@@ -658,6 +662,26 @@
return due.duplicateAsUTC() if due is not None else None
+ def getCompletedDateUTC(self):
+ """
+ Return the completed date or date-time for the specified component
+ converted to UTC.
+ @param component: the Component whose start should be returned.
+ @return: the datetime.date or datetime.datetime for the start.
+ """
+ completed = self.propertyValue("COMPLETED")
+ return completed.duplicateAsUTC() if completed is not None else None
+
+ def getCreatedDateUTC(self):
+ """
+ Return the created date or date-time for the specified component
+ converted to UTC.
+ @param component: the Component whose start should be returned.
+ @return: the datetime.date or datetime.datetime for the start.
+ """
+ created = self.propertyValue("CREATED")
+ return created.duplicateAsUTC() if created is not None else None
+
def getRecurrenceIDUTC(self):
"""
Return the recurrence-id for the specified component.
Modified: CalendarServer/trunk/twistedcaldav/instance.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/instance.py 2011-05-20 00:19:15 UTC (rev 7505)
+++ CalendarServer/trunk/twistedcaldav/instance.py 2011-05-20 00:21:05 UTC (rev 7506)
@@ -1,5 +1,5 @@
##
-# Copyright (c) 2006-2009 Apple Inc. All rights reserved.
+# Copyright (c) 2006-2011 Apple Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -165,16 +165,14 @@
if len(self.instances) > max_allowed_instances:
raise TooManyInstancesError()
- def _addMasterEventComponent(self, component, limit):
+ def _getMasterEventDetails(self, component):
"""
- Add the specified master VEVENT Component to the instance list, expanding it
- within the supplied time range.
- @param component: the Component to expand
- @param limit: the end L{PyCalendarDateTime} for expansion
+ Logic here comes from RFC4791 Section 9.9
"""
+
start = component.getStartDateUTC()
if start is None:
- return
+ return None
rulestart = component.propertyValue("DTSTART")
end = component.getEndDateUTC()
@@ -189,7 +187,22 @@
end = start + duration
else:
duration = differenceDateTime(start, end)
+
+ return (rulestart, start, end, duration,)
+ def _addMasterEventComponent(self, component, limit):
+ """
+ Add the specified master VEVENT Component to the instance list, expanding it
+ within the supplied time range.
+ @param component: the Component to expand
+ @param limit: the end L{PyCalendarDateTime} for expansion
+ """
+
+ details = self._getMasterEventDetails(component)
+ if details is None:
+ return
+ rulestart, start, end, duration = details
+
self._addMasterComponent(component, limit, rulestart, start, end, duration)
def _addOverrideEventComponent(self, component, limit, got_master):
@@ -202,23 +215,58 @@
#TODO: This does not take into account THISANDPRIOR - only THISANDFUTURE
- start = component.getStartDateUTC()
- if start is None:
+ details = self._getMasterEventDetails(component)
+ if details is None:
return
+ _ignore_rulestart, start, end, _ignore_duration = details
- end = component.getEndDateUTC()
- duration = None
- if end is None:
- if not start.isDateOnly():
- # Timed event with zero duration
- duration = PyCalendarDuration(days=0)
+ self._addOverrideComponent(component, limit, start, end, got_master)
+
+ def _getMasterToDoDetails(self, component):
+ """
+ Logic here comes from RFC4791 Section 9.9
+ """
+
+ dtstart = component.getStartDateUTC()
+ dtend = component.getEndDateUTC()
+ dtdue = component.getDueDateUTC()
+
+ # DTSTART and DURATION or DUE case
+ if dtstart is not None:
+ rulestart = component.propertyValue("DTSTART")
+ start = dtstart
+ if dtend is not None:
+ end = dtend
+ elif dtdue is not None:
+ end = dtdue
else:
- # All day event default duration is one day
- duration = PyCalendarDuration(days=1)
- end = start + duration
+ end = dtstart
+
+ # DUE case
+ elif dtdue is not None:
+ rulestart = component.propertyValue("DUE")
+ start = end = dtdue
+
+ # Fall back to COMPLETED or CREATED - cannot be recurring
+ else:
+ rulestart = None
+ from twistedcaldav.ical import maxDateTime, minDateTime
+ dtcreated = component.getCreatedDateUTC()
+ dtcompleted = component.getCompletedDateUTC()
+ if dtcompleted:
+ end = dtcompleted
+ start = dtcreated if dtcreated else dtend
+ elif dtcreated:
+ start = dtcreated
+ end = maxDateTime
+ else:
+ start = minDateTime
+ end = maxDateTime
- self._addOverrideComponent(component, limit, start, end, got_master)
+ duration = differenceDateTime(start, end)
+ return (rulestart, start, end, duration,)
+
def _addMasterToDoComponent(self, component, limit):
"""
Add the specified master VTODO Component to the instance list, expanding it
@@ -226,22 +274,13 @@
@param component: the Component to expand
@param limit: the end L{PyCalendarDateTime} for expansion
"""
- start = component.getStartDateUTC()
- due = component.getDueDateUTC()
-
- if start is None and due is None:
+ details = self._getMasterToDoDetails(component)
+ if details is None:
return
+ rulestart, start, end, duration = details
- rulestart = component.propertyValue("DTSTART")
- if start is None:
- start = due
- rulestart = component.propertyValue("DUE")
- elif due is None:
- due = start
- duration = differenceDateTime(start, due)
+ self._addMasterComponent(component, limit, rulestart, start, end, duration)
- self._addMasterComponent(component, limit, rulestart, start, due, duration)
-
def _addOverrideToDoComponent(self, component, limit, got_master):
"""
Add the specified overridden VTODO Component to the instance list, replacing
@@ -252,23 +291,17 @@
#TODO: This does not take into account THISANDPRIOR - only THISANDFUTURE
- start = component.getStartDateUTC()
- due = component.getDueDateUTC()
-
- if start is None and due is None:
+ details = self._getMasterToDoDetails(component)
+ if details is None:
return
+ _ignore_rulestart, start, end, _ignore_duration = details
- if start is None:
- start = due
- elif due is None:
- due = start
+ self._addOverrideComponent(component, limit, start, end, got_master)
- self._addOverrideComponent(component, limit, start, due, got_master)
-
def _addMasterComponent(self, component, limit, rulestart, start, end, duration):
rrules = component.getRecurrenceSet()
- if rrules is not None:
+ if rrules is not None and rulestart is not None:
# Do recurrence set expansion
expanded = []
limited = rrules.expand(rulestart, PyCalendarPeriod(start, limit), expanded)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110519/4c49b7ca/attachment.html>
More information about the calendarserver-changes
mailing list