[CalendarServer-changes] [3384] CalendarServer/trunk/twistedcaldav
source_changes at macosforge.org
source_changes at macosforge.org
Thu Nov 13 20:15:55 PST 2008
Revision: 3384
http://trac.macosforge.org/projects/calendarserver/changeset/3384
Author: cdaboo at apple.com
Date: 2008-11-13 20:15:55 -0800 (Thu, 13 Nov 2008)
Log Message:
-----------
Improve diff'ing of calendar data by doing more rigorous normalization of properties/parameters.
Modified Paths:
--------------
CalendarServer/trunk/twistedcaldav/ical.py
CalendarServer/trunk/twistedcaldav/scheduling/icaldiff.py
CalendarServer/trunk/twistedcaldav/test/test_icalendar.py
Modified: CalendarServer/trunk/twistedcaldav/ical.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/ical.py 2008-11-13 22:06:32 UTC (rev 3383)
+++ CalendarServer/trunk/twistedcaldav/ical.py 2008-11-14 04:15:55 UTC (rev 3384)
@@ -58,6 +58,66 @@
#"VAVAILABILITY",
)
+# 2445 default values and parameters
+# Structure: propname: (<default value>, <parameter defaults dict>)
+
+normalizeProps = {
+ "CALSCALE": ("GREGORIAN", {"VALUE": "TEXT"}),
+ "METHOD": (None, {"VALUE": "TEXT"}),
+ "PRODID": (None, {"VALUE": "TEXT"}),
+ "VERSION": (None, {"VALUE": "TEXT"}),
+ "ATTACH": (None, {"VALUE": "URI"}),
+ "CATEGORIES": (None, {"VALUE": "TEXT"}),
+ "CLASS": (None, {"VALUE": "TEXT"}),
+ "COMMENT": (None, {"VALUE": "TEXT"}),
+ "DESCRIPTION": (None, {"VALUE": "TEXT"}),
+ "GEO": (None, {"VALUE": "FLOAT"}),
+ "LOCATION": (None, {"VALUE": "TEXT"}),
+ "PERCENT-COMPLETE": (None, {"VALUE": "INTEGER"}),
+ "PRIORITY": ("0", {"VALUE": "INTEGER"}),
+ "RESOURCES": (None, {"VALUE": "TEXT"}),
+ "STATUS": (None, {"VALUE": "TEXT"}),
+ "SUMMARY": (None, {"VALUE": "TEXT"}),
+ "COMPLETED": (None, {"VALUE": "DATE-TIME"}),
+ "DTEND": (None, {"VALUE": "DATE-TIME"}),
+ "DUE": (None, {"VALUE": "DATE-TIME"}),
+ "DTSTART": (None, {"VALUE": "DATE-TIME"}),
+ "DURATION": (None, {"VALUE": "DURATION"}),
+ "FREEBUSY": (None, {"VALUE": "PERIOD"}),
+ "TRANSP": ("OPAQUE", {"VALUE": "TEXT"}),
+ "TZID": (None, {"VALUE": "TEXT"}),
+ "TZNAME": (None, {"VALUE": "TEXT"}),
+ "TZOFFSETFROM": (None, {"VALUE": "UTC-OFFSET"}),
+ "TZOFFSETTO": (None, {"VALUE": "UTC-OFFSET"}),
+ "TZURL": (None, {"VALUE": "URI"}),
+ "ATTENDEE": (None, {
+ "VALUE": "CAL-ADDRESS",
+ "CUTYPE": "INDIVIDUAL",
+ "ROLE": "REQ-PARTICIPANT",
+ "PARTSTAT": "NEEDS-ACTION",
+ "RSVP": "FALSE",
+
+ }),
+ "CONTACT": (None, {"VALUE": "TEXT"}),
+ "ORGANIZER": (None, {"VALUE": "CAL-ADDRESS"}),
+ "RECURRENCE-ID": (None, {"VALUE": "DATE-TIME"}),
+ "RELATED-TO": (None, {"VALUE": "TEXT"}),
+ "URL": (None, {"VALUE": "URI"}),
+ "UID": (None, {"VALUE": "TEXT"}),
+ "EXDATE": (None, {"VALUE": "DATE-TIME"}),
+ "EXRULE": (None, {"VALUE": "RECUR"}),
+ "RDATE": (None, {"VALUE": "DATE-TIME"}),
+ "RRULE": (None, {"VALUE": "RECUR"}),
+ "ACTION": (None, {"VALUE": "TEXT"}),
+ "REPEAT": ("0", {"VALUE": "INTEGER"}),
+ "TRIGGER": (None, {"VALUE": "DURATION"}),
+ "CREATED": (None, {"VALUE": "DATE-TIME"}),
+ "DTSTAMP": (None, {"VALUE": "DATE-TIME"}),
+ "LAST-MODIFIED": (None, {"VALUE": "DATE-TIME"}),
+ "SEQUENCE": ("0", {"VALUE": "INTEGER"}),
+ "REQUEST-STATUS": (None, {"VALUE": "TEXT"}),
+}
+
class Property (object):
"""
iCalendar Property
@@ -1553,6 +1613,32 @@
except ValueError:
pass
+ def normalizeAll(self):
+
+ # Normalize all properties
+ for prop in tuple(self.properties()):
+ result = normalizeProps.get(prop.name())
+ if result:
+ default_value, default_params = result
+ else:
+ # Assume default VALUE is TEXT
+ default_value = None
+ default_params = {"VALUE": "TEXT"}
+
+ # Remove any default parameters
+ for name, value in prop.params().items():
+ if value == [default_params.get(name),]:
+ del prop.params()[name]
+
+ # If there are no parameters, remove the property if it has the default value
+ if len(prop.params()) == 0:
+ if prop.value() == default_value:
+ self.removeProperty(prop)
+
+ # Do to all sub-components too
+ for component in self.subcomponents():
+ component.normalizeAll()
+
def normalizePropertyValueLists(self, propname):
"""
Convert properties that have a list of values into single properties, to make it easier
Modified: CalendarServer/trunk/twistedcaldav/scheduling/icaldiff.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/scheduling/icaldiff.py 2008-11-13 22:06:32 UTC (rev 3383)
+++ CalendarServer/trunk/twistedcaldav/scheduling/icaldiff.py 2008-11-14 04:15:55 UTC (rev 3384)
@@ -68,7 +68,7 @@
))
calendar.removeXProperties()
calendar.removePropertyParameters("ATTENDEE", ("RSVP", "SCHEDULE-AGENT", "SCHEDULE-STATUS",))
- calendar.removePropertyParametersByValue("ATTENDEE", (("PARTSTAT", "NEEDS-ACTION"),))
+ calendar.normalizeAll()
return calendar
# Normalize components for comparison
@@ -229,6 +229,7 @@
calendar = calendar.duplicate()
calendar.normalizePropertyValueLists("EXDATE")
calendar.removePropertyParameters("ORGANIZER", ("SCHEDULE-STATUS",))
+ calendar.normalizeAll()
iTipGenerator.prepareSchedulingMessage(calendar, reply=True)
return calendar
Modified: CalendarServer/trunk/twistedcaldav/test/test_icalendar.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_icalendar.py 2008-11-13 22:06:32 UTC (rev 3383)
+++ CalendarServer/trunk/twistedcaldav/test/test_icalendar.py 2008-11-14 04:15:55 UTC (rev 3384)
@@ -17,6 +17,7 @@
import os
import datetime
from dateutil.tz import tzutc
+from difflib import unified_diff
from twisted.trial.unittest import SkipTest
@@ -1956,4 +1957,71 @@
component_result = Component.fromString(result)
component_to.transferProperties(component_from, propnames)
self.assertEqual(str(component_to), str(component_result), "%s: mismatch" % (description,))
-
+
+ def test_normalize_all(self):
+
+ data = (
+ (
+ "1.1",
+ """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890-1
+DTSTART;VALUE=DATE-TIME:20071114T000000Z
+SEQUENCE:0
+END:VEVENT
+END:VCALENDAR
+""",
+ """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890-1
+DTSTART:20071114T000000Z
+END:VEVENT
+END:VCALENDAR
+""",
+ ),
+ (
+ "1.2",
+ """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890-1
+DTSTART;VALUE=DATE-TIME:20071114T000000Z
+TRANSP:OPAQUE
+ORGANIZER:mailto:user01 at example.com
+ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION:mailto:user02 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user03 at example.com
+ATTENDEE;RSVP=FALSE:mailto:user04 at example.com
+SEQUENCE:1
+END:VEVENT
+END:VCALENDAR
+""",
+ """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890-1
+DTSTART:20071114T000000Z
+ORGANIZER:mailto:user01 at example.com
+ATTENDEE;RSVP=TRUE:mailto:user02 at example.com
+ATTENDEE:mailto:user03 at example.com
+ATTENDEE:mailto:user04 at example.com
+SEQUENCE:1
+END:VEVENT
+END:VCALENDAR
+""",
+ ),
+ )
+
+ for title, original, result in data:
+ ical1 = Component.fromString(original)
+ ical1.normalizeAll()
+ ical1 = str(ical1)
+ ical2 = Component.fromString(result)
+ ical2 = str(ical2)
+ diff = "\n".join(unified_diff(ical1.split("\n"), ical2.split("\n")))
+ self.assertEqual(str(ical1), str(ical2), "Failed comparison: %s\n%s" % (title, diff,))
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20081113/72706f2b/attachment-0001.html>
More information about the calendarserver-changes
mailing list