[CalendarServer-changes] [6720] CalendarServer/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Thu Jan 6 16:58:37 PST 2011
Revision: 6720
http://trac.macosforge.org/projects/calendarserver/changeset/6720
Author: sagen at apple.com
Date: 2011-01-06 16:58:30 -0800 (Thu, 06 Jan 2011)
Log Message:
-----------
First pass at fixing DTSTART/UNTIL type mismatches in existing data as it's read in from .ics files. We can improve the logic for how UNTIL is modified if we need to.
Modified Paths:
--------------
CalendarServer/trunk/twistedcaldav/ical.py
CalendarServer/trunk/twistedcaldav/test/test_icalendar.py
CalendarServer/trunk/txdav/caldav/datastore/file.py
Modified: CalendarServer/trunk/twistedcaldav/ical.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/ical.py 2011-01-06 22:36:44 UTC (rev 6719)
+++ CalendarServer/trunk/twistedcaldav/ical.py 2011-01-07 00:58:30 UTC (rev 6720)
@@ -1279,9 +1279,10 @@
self.validateComponentsForCalDAV(False)
- def validateComponentsForCalDAV(self, method):
+ def validateComponentsForCalDAV(self, method, fix=False):
"""
@param method: True if METHOD property is allowed, False otherwise.
+ @param fix: True to try and fix bogus data
@raise InvalidICalendarDataError: if the given calendar component is not valid for
use as a X{CalDAV} resource.
"""
@@ -1374,19 +1375,39 @@
# If they're not both date or both date-time, raise error
if (subcomponent.hasProperty("DTSTART") and
subcomponent.hasProperty("RRULE")):
- dtType = type(subcomponent.getProperty("DTSTART").value())
+ # dtValue may be datetime or date, or unicode in which case
+ # we look at the length to see if it's datetime or date.
+ dtValue = subcomponent.getProperty("DTSTART").value()
+ dtType = type(dtValue)
+ if dtType is unicode:
+ dtType = datetime.date if len(dtValue) == 8 else datetime.datetime
for rrule in subcomponent.properties("RRULE"):
indexedTokens = {}
indexedTokens.update([valuePart.split("=")
for valuePart in rrule.value().split(";")])
- until = indexedTokens.get('UNTIL', None)
+ until = indexedTokens.get("UNTIL", None)
+ # FIXME: can "until" ever be anything but a unicode?
if until:
untilType = datetime.date if len(until) == 8 else datetime.datetime
if untilType is not dtType:
msg = "Calendar resources must have matching type for DTSTART and UNTIL"
log.debug(msg)
- raise InvalidICalendarDataError(msg)
+ if fix:
+ log.debug("Fixing mismatch")
+ if dtType is datetime.datetime:
+ # TODO: does this need to be smarter?
+ indexedTokens["UNTIL"] = "%sT000000" % (until,)
+ else:
+ # TODO: does this need to be smarter?
+ # It's just stripping off the time.
+ indexedTokens["UNTIL"] = until[:8]
+ # Update rrule
+ newValue = u";".join(["%s=%s" % (k,v) for k,v in indexedTokens.iteritems()])
+ rrule.setValue(newValue)
+ else:
+ raise InvalidICalendarDataError(msg)
+
timezone_refs.update(subcomponent.timezoneIDs())
#
Modified: CalendarServer/trunk/twistedcaldav/test/test_icalendar.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_icalendar.py 2011-01-06 22:36:44 UTC (rev 6719)
+++ CalendarServer/trunk/twistedcaldav/test/test_icalendar.py 2011-01-07 00:58:30 UTC (rev 6720)
@@ -81,6 +81,96 @@
try: calendar.validateForCalDAV()
except ValueError: self.fail("Resource iCalendar %s didn't validate for CalDAV" % (filename,))
+ def test_component_validate_and_fix(self):
+ """
+ CalDAV resource validation and fixing.
+ """
+ data = """BEGIN:VCALENDAR
+BEGIN:VTIMEZONE
+TZID:America/Los_Angeles
+BEGIN:DAYLIGHT
+TZOFFSETFROM:-0800
+RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
+DTSTART:20070311T020000
+TZNAME:PDT
+TZOFFSETTO:-0700
+END:DAYLIGHT
+BEGIN:STANDARD
+TZOFFSETFROM:-0700
+RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
+DTSTART:20071104T020000
+TZNAME:PST
+TZOFFSETTO:-0800
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+CREATED:20110105T191945Z
+UID:5D70FD7E-3DFA-4981-8B91-E9E6CD5FCE28
+DTEND;TZID=America/Los_Angeles:20110107T141500
+RRULE:FREQ=DAILY;INTERVAL=1;UNTIL=20110121
+TRANSP:OPAQUE
+SUMMARY:test
+DTSTART;TZID=America/Los_Angeles:20110107T123000
+DTSTAMP:20110105T192229Z
+END:VEVENT
+END:VCALENDAR
+"""
+ # Ensure it starts off invalid
+ calendar = Component.fromString(data)
+ try: calendar.validateComponentsForCalDAV(False)
+ except InvalidICalendarDataError: pass
+ else: self.fail("Shouldn't validate for CalDAV")
+
+ # Fix it
+ calendar.validateComponentsForCalDAV(False, fix=True)
+
+ # Now it should pass without fixing
+ calendar.validateComponentsForCalDAV(False, fix=False)
+
+ data = """BEGIN:VCALENDAR
+BEGIN:VTIMEZONE
+TZID:America/Los_Angeles
+BEGIN:DAYLIGHT
+TZOFFSETFROM:-0800
+RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
+DTSTART:20070311T020000
+TZNAME:PDT
+TZOFFSETTO:-0700
+END:DAYLIGHT
+BEGIN:STANDARD
+TZOFFSETFROM:-0700
+RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
+DTSTART:20071104T020000
+TZNAME:PST
+TZOFFSETTO:-0800
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTART;VALUE=DATE:20110107
+DTEND;VALUE=DATE:20110108
+DTSTAMP:20110106T231917Z
+RRULE:FREQ=DAILY;INTERVAL=1;UNTIL=20110131T123456
+TRANSP:TRANSPARENT
+SUMMARY:test
+CREATED:20110105T191945Z
+UID:5D70FD7E-3DFA-4981-8B91-E9E6CD5FCE28
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
+"""
+ # Ensure it starts off invalid
+ calendar = Component.fromString(data)
+ try: calendar.validateComponentsForCalDAV(False)
+ except InvalidICalendarDataError: pass
+ else: self.fail("Shouldn't validate for CalDAV")
+
+ # Fix it
+ calendar.validateComponentsForCalDAV(False, fix=True)
+
+ # Now it should pass without fixing
+ calendar.validateComponentsForCalDAV(False, fix=False)
+
+
def test_component_timeranges(self):
"""
Component time range query.
Modified: CalendarServer/trunk/txdav/caldav/datastore/file.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/file.py 2011-01-06 22:36:44 UTC (rev 6719)
+++ CalendarServer/trunk/txdav/caldav/datastore/file.py 2011-01-07 00:58:30 UTC (rev 6720)
@@ -311,6 +311,8 @@
try:
component = VComponent.fromString(text)
+ # Fix any bogus data we can
+ component.validateComponentsForCalDAV(False, fix=True)
except InvalidICalendarDataError, e:
raise InternalDataStoreError(
"File corruption detected (%s) in file: %s"
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110106/99c27374/attachment.html>
More information about the calendarserver-changes
mailing list