[CalendarServer-changes] [3771] CalendarServer/trunk

source_changes at macosforge.org source_changes at macosforge.org
Mon Mar 2 07:51:03 PST 2009


Revision: 3771
          http://trac.macosforge.org/projects/calendarserver/changeset/3771
Author:   cdaboo at apple.com
Date:     2009-03-02 07:51:03 -0800 (Mon, 02 Mar 2009)
Log Message:
-----------
Changed format of schedule-changes to provide detailed list of properties/parameters that changed.

Modified Paths:
--------------
    CalendarServer/trunk/run
    CalendarServer/trunk/twistedcaldav/customxml.py
    CalendarServer/trunk/twistedcaldav/scheduling/icaldiff.py
    CalendarServer/trunk/twistedcaldav/scheduling/processing.py
    CalendarServer/trunk/twistedcaldav/scheduling/test/test_icaldiff.py

Modified: CalendarServer/trunk/run
===================================================================
--- CalendarServer/trunk/run	2009-03-02 15:47:35 UTC (rev 3770)
+++ CalendarServer/trunk/run	2009-03-02 15:51:03 UTC (rev 3771)
@@ -707,7 +707,7 @@
 
 caldavtester="${top}/CalDAVTester";
 
-svn_get "CalDAVTester" "${caldavtester}" "${svn_uri_base}/CalDAVTester/trunk" 3766;
+svn_get "CalDAVTester" "${caldavtester}" "${svn_uri_base}/CalDAVTester/trunk" 3770;
 
 #
 # PyFlakes

Modified: CalendarServer/trunk/twistedcaldav/customxml.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/customxml.py	2009-03-02 15:47:35 UTC (rev 3770)
+++ CalendarServer/trunk/twistedcaldav/customxml.py	2009-03-02 15:51:03 UTC (rev 3771)
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2006-2008 Apple Inc. All rights reserved.
+# Copyright (c) 2006-2009 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.
@@ -517,72 +517,35 @@
     namespace = calendarserver_namespace
     name = "changes"
     allowed_children = {
-        (calendarserver_namespace, "datetime" )          : (0, 1),
-        (calendarserver_namespace, "location" )          : (0, 1),
-        (calendarserver_namespace, "summary" )           : (0, 1),
-        (calendarserver_namespace, "description" )       : (0, 1),
-        (calendarserver_namespace, "recurrence" )        : (0, 1),
-        (calendarserver_namespace, "status" )            : (0, 1),
-        (calendarserver_namespace, "attendees" )         : (0, 1),
-        (calendarserver_namespace, "attendee-partstat" ) : (0, 1),
+        (calendarserver_namespace, "changed-property" )  : (0, None),
     }
 
-class Datetime (davxml.WebDAVEmptyElement):
+class ChangedProperty (davxml.WebDAVElement):
     """
-    Date time change.
+    Changes to a property.
     """
     namespace = calendarserver_namespace
-    name = "datetime"
+    name = "changed-property"
 
-class Location (davxml.WebDAVEmptyElement):
-    """
-    Location changed.
-    """
-    namespace = calendarserver_namespace
-    name = "location"
+    allowed_children = {
+        (calendarserver_namespace, "changed-parameter" )  : (0, None),
+    }
 
-class Summary (davxml.WebDAVEmptyElement):
-    """
-    Summary changed.
-    """
-    namespace = calendarserver_namespace
-    name = "summary"
+    allowed_attributes = {
+        "name" : True,
+    }
 
-class Description (davxml.WebDAVEmptyElement):
+class ChangedParameter (davxml.WebDAVEmptyElement):
     """
-    Description changed.
+    Changes to a parameter.
     """
     namespace = calendarserver_namespace
-    name = "description"
+    name = "changed-parameter"
 
-class Recurrence (davxml.WebDAVEmptyElement):
-    """
-    Recurrence changed.
-    """
-    namespace = calendarserver_namespace
-    name = "recurrence"
+    allowed_attributes = {
+        "name" : True,
+    }
 
-class Status (davxml.WebDAVEmptyElement):
-    """
-    Status changed.
-    """
-    namespace = calendarserver_namespace
-    name = "status"
-
-class Attendees (davxml.WebDAVEmptyElement):
-    """
-    Attendees changed.
-    """
-    namespace = calendarserver_namespace
-    name = "attendees"
-
-class AttendeePartStat (davxml.WebDAVEmptyElement):
-    """
-    Attendee partstats changed.
-    """
-    namespace = calendarserver_namespace
-    name = "attendee-partstat"
-
 class Recurrences (davxml.WebDAVElement):
     """
     Changes to an event.

Modified: CalendarServer/trunk/twistedcaldav/scheduling/icaldiff.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/scheduling/icaldiff.py	2009-03-02 15:47:35 UTC (rev 3770)
+++ CalendarServer/trunk/twistedcaldav/scheduling/icaldiff.py	2009-03-02 15:51:03 UTC (rev 3771)
@@ -237,20 +237,11 @@
             log.debug("attendeeDiff: doing smart Attendee diff/merge")
             self._attendeeMerge()
 
-        def duplicateAndNormalize(calendar):
-            calendar = calendar.duplicate()
-            calendar.normalizePropertyValueLists("EXDATE")
-            calendar.removePropertyParameters("ORGANIZER", ("SCHEDULE-STATUS",))
-            calendar.normalizeAll()
-            calendar.normalizeAttachments()
-            iTipGenerator.prepareSchedulingMessage(calendar, reply=True)
-            return calendar
-
         # Do straight comparison without alarms
         self.originalCalendar1 = self.calendar1
         self.originalCalendar2 = self.calendar2
-        self.calendar1 = duplicateAndNormalize(self.calendar1)
-        self.calendar2 = duplicateAndNormalize(self.calendar2)
+        self.calendar1 = self._attendeeDuplicateAndNormalize(self.calendar1)
+        self.calendar2 = self._attendeeDuplicateAndNormalize(self.calendar2)
 
         if self.calendar1 == self.calendar2:
             return True, True
@@ -286,6 +277,15 @@
 
         return result
     
+    def _attendeeDuplicateAndNormalize(self, calendar):
+        calendar = calendar.duplicate()
+        calendar.normalizePropertyValueLists("EXDATE")
+        calendar.removePropertyParameters("ORGANIZER", ("SCHEDULE-STATUS",))
+        calendar.normalizeAll()
+        calendar.normalizeAttachments()
+        iTipGenerator.prepareSchedulingMessage(calendar, reply=True)
+        return calendar
+
     def _attendeeMerge(self):
         """
         Merge changes to ATTENDEE properties in calendar1 into calendar2.
@@ -302,6 +302,10 @@
         and PARTSTAT parameters that are different.
         """
 
+        # Do straight comparison without alarms
+        self.calendar1 = self._attendeeDuplicateAndNormalize(self.calendar1)
+        self.calendar2 = self._attendeeDuplicateAndNormalize(self.calendar2)
+
         # First get uid/rid map of components
         def mapComponents(calendar):
             map = {}
@@ -314,7 +318,7 @@
                 map[(name, uid, rid,)] = component
             return map
         
-        props_changed = set()
+        props_changed = {}
         rids = set()
 
         map1 = mapComponents(self.calendar1)
@@ -637,27 +641,28 @@
         propdiff = set(comp1.properties()) ^ set(comp2.properties())
         comp1.transformAllToNative()
         comp2.transformAllToNative()
+        addedChanges = False
         
-        regular_changes = [prop.name() for prop in propdiff if prop.name() != "ATTENDEE"]
-        changed.update(regular_changes)
+        for prop in propdiff:
+            if prop.name() in (
+                "TRANSP",
+                "DTSTAMP",
+                "CREATED",
+                "LAST-MODIFIED",
+                "SEQUENCE",
+            ):
+                continue
+            changed.setdefault(prop.name(), set())
+            addedChanges = True
+            prop1s = tuple(comp1.properties(prop.name()))
+            prop2s = tuple(comp2.properties(prop.name()))
+            if len(prop1s) == 1 and len(prop2s) == 1:
+                param1s = set(["%s=%s" % (name, value) for name, value in prop1s[0].params().iteritems()])
+                param2s = set(["%s=%s" % (name, value) for name, value in prop2s[0].params().iteritems()])
+                paramDiffs = param1s ^ param2s
+                changed[prop.name()].update([param.split("=")[0] for param in paramDiffs])
         
-        attendees = set([prop for prop in propdiff if prop.name() == "ATTENDEE"])
-        done_attendee = False
-        done_partstat = False
-        for ctr, attendee in enumerate(attendees):
-            for check_ctr, check_attendee in enumerate(attendees):
-                if (ctr != check_ctr) and check_attendee.value() == attendee.value():
-                    if check_attendee.params().get("PARTSTAT", ("NEEDS-ACTION",)) != attendee.params().get("PARTSTAT", ("NEEDS-ACTION",)):
-                        changed.add("PARTSTAT")
-                        done_partstat = True
-                    break
-            else:
-                changed.add("ATTENDEE")
-                done_attendee = True
-            if done_attendee and done_partstat:
-                break
-
-        if regular_changes or done_attendee or done_partstat:
+        if addedChanges:
             rid = comp1.getRecurrenceIDUTC()
             rids.add(dateTimeToString(rid) if rid is not None else "")
 

Modified: CalendarServer/trunk/twistedcaldav/scheduling/processing.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/scheduling/processing.py	2009-03-02 15:47:35 UTC (rev 3770)
+++ CalendarServer/trunk/twistedcaldav/scheduling/processing.py	2009-03-02 15:51:03 UTC (rev 3771)
@@ -305,25 +305,11 @@
                     reactor.callLater(2.0, self.sendAttendeeAutoReply, *(new_calendar, new_resource, partstat))
 
                 # Build the schedule-changes XML element
-                changes = ()
+                changes = []
                 if props_changed:
-                    changemap = {
-                        "DTSTART"     : customxml.Datetime(),
-                        "DTEND"       : customxml.Datetime(),
-                        "DURATION"    : customxml.Datetime(),
-                        "DUE"         : customxml.Datetime(),
-                        "COMPLETED"   : customxml.Datetime(),
-                        "LOCATION"    : customxml.Location(),
-                        "SUMMARY"     : customxml.Summary(),
-                        "DESCRIPTION" : customxml.Description(),
-                        "RRULE"       : customxml.Recurrence(),
-                        "RDATE"       : customxml.Recurrence(),
-                        "EXDATE"      : customxml.Recurrence(),
-                        "STATUS"      : customxml.Status(),
-                        "ATTENDEE"    : customxml.Attendees(),
-                        "PARTSTAT"    : customxml.PartStat(),
-                    }
-                    changes += tuple([changemap[prop] for prop in props_changed if prop in changemap])
+                    for propName, paramNames in sorted(props_changed.iteritems(), key=lambda x:x[0]):
+                        params = tuple([customxml.ChangedParameter(name=param) for param in paramNames])
+                        changes.append(customxml.ChangedProperty(*params, **{"name":propName}))
                 update_details = (customxml.Changes(*changes),)
                 if rids is not None:
                     recurrences = []

Modified: CalendarServer/trunk/twistedcaldav/scheduling/test/test_icaldiff.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/scheduling/test/test_icaldiff.py	2009-03-02 15:47:35 UTC (rev 3770)
+++ CalendarServer/trunk/twistedcaldav/scheduling/test/test_icaldiff.py	2009-03-02 15:51:03 UTC (rev 3771)
@@ -1334,8 +1334,8 @@
 END:VEVENT
 END:VCALENDAR
 """,
+                {},
                 (),
-                (),
             ),
             (
                 "#1.2 Simple component, one property change",
@@ -1361,7 +1361,7 @@
 END:VEVENT
 END:VCALENDAR
 """,
-                ("SUMMARY",),
+                {"SUMMARY":set(),},
                 (),
             ),
             (
@@ -1390,7 +1390,7 @@
 END:VEVENT
 END:VCALENDAR
 """,
-                ("SUMMARY", "LOCATION", "DESCRIPTION",),
+                {"SUMMARY":set(), "LOCATION":set(), "DESCRIPTION":set(),},
                 (),
             ),
             (
@@ -1424,7 +1424,7 @@
 END:VEVENT
 END:VCALENDAR
 """,
-                ("ATTENDEE",),
+                {"ATTENDEE":set(),},
                 (),
             ),
             (
@@ -1456,7 +1456,7 @@
 END:VEVENT
 END:VCALENDAR
 """,
-                ("ATTENDEE",),
+                {"ATTENDEE":set(),},
                 (),
             ),
             (
@@ -1489,7 +1489,7 @@
 END:VEVENT
 END:VCALENDAR
 """,
-                ("PARTSTAT",),
+                {"ATTENDEE":set(),},
                 (),
             ),
             (
@@ -1523,7 +1523,7 @@
 END:VEVENT
 END:VCALENDAR
 """,
-                ("PARTSTAT", "ATTENDEE",),
+                {"ATTENDEE":set(),},
                 (),
             ),
             (
@@ -1556,7 +1556,40 @@
 END:VEVENT
 END:VCALENDAR
 """,
+                {"ATTENDEE":set(),},
                 (),
+            ),
+            (
+                "#1.9 Simple component, DTSTART/DTEND VALUE",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+SUMMARY:Test
+ORGANIZER;CN="User 01":mailto:user1 at example.com
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+END:VEVENT
+END:VCALENDAR
+""",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART;VALUE=DATE:20080601
+DTEND;VALUE=DATE:20080601
+SUMMARY:Test
+ORGANIZER;CN="User 01":mailto:user1 at example.com
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+END:VEVENT
+END:VCALENDAR
+""",
+                {"DTEND":set(("VALUE",)), "DTSTART":set(("VALUE",)),},
                 (),
             ),
         )
@@ -1594,8 +1627,8 @@
 END:VEVENT
 END:VCALENDAR
 """,
+                {},
                 (),
-                (),
             ),
             (
                 "#2.2 Simple component, one property change",
@@ -1623,7 +1656,7 @@
 END:VEVENT
 END:VCALENDAR
 """,
-                ("SUMMARY",),
+                {"SUMMARY":set(),},
                 ("",),
             ),
             (
@@ -1654,7 +1687,7 @@
 END:VEVENT
 END:VCALENDAR
 """,
-                ("SUMMARY", "LOCATION", "DESCRIPTION",),
+                {"SUMMARY":set(), "LOCATION":set(), "DESCRIPTION":set(),},
                 ("",),
             ),
             (
@@ -1690,7 +1723,7 @@
 END:VEVENT
 END:VCALENDAR
 """,
-                ("ATTENDEE",),
+                {"ATTENDEE":set(),},
                 ("",),
             ),
             (
@@ -1724,7 +1757,7 @@
 END:VEVENT
 END:VCALENDAR
 """,
-                ("ATTENDEE",),
+                {"ATTENDEE":set(),},
                 ("",),
             ),
             (
@@ -1759,7 +1792,7 @@
 END:VEVENT
 END:VCALENDAR
 """,
-                ("PARTSTAT",),
+                {"ATTENDEE":set(),},
                 ("",),
             ),
             (
@@ -1795,7 +1828,7 @@
 END:VEVENT
 END:VCALENDAR
 """,
-                ("PARTSTAT", "ATTENDEE",),
+                {"ATTENDEE":set(),},
                 ("",),
             ),
         )
@@ -1853,8 +1886,8 @@
 END:VEVENT
 END:VCALENDAR
 """,
+                {},
                 (),
-                (),
             ),
             (
                 "#3.2 Simple component, one property change in instance",
@@ -1902,7 +1935,7 @@
 END:VEVENT
 END:VCALENDAR
 """,
-                ("SUMMARY",),
+                {"SUMMARY":set(),},
                 ("20080602T120000Z",),
             ),
             (
@@ -1951,7 +1984,7 @@
 END:VEVENT
 END:VCALENDAR
 """,
-                ("SUMMARY",),
+                {"SUMMARY":set(),},
                 ("",),
             ),
             (
@@ -2000,7 +2033,7 @@
 END:VEVENT
 END:VCALENDAR
 """,
-                ("SUMMARY",),
+                {"SUMMARY":set(),},
                 ("", "20080602T120000Z",),
             ),
             (
@@ -2050,7 +2083,7 @@
 END:VEVENT
 END:VCALENDAR
 """,
-                ("SUMMARY", "DESCRIPTION"),
+                {"SUMMARY":set(), "DESCRIPTION":set()},
                 ("", "20080602T120000Z",),
             ),
             (
@@ -2086,8 +2119,8 @@
 END:VEVENT
 END:VCALENDAR
 """,
+                {},
                 (),
-                (),
             ),
             (
                 "#3.7 Simple component, instance added time change",
@@ -2122,7 +2155,7 @@
 END:VEVENT
 END:VCALENDAR
 """,
-                ("DTSTART", "DTEND", ),
+                {"DTSTART":set(), "DTEND":set(), },
                 ("20080602T120000Z",),
             ),
             (
@@ -2158,8 +2191,8 @@
 END:VEVENT
 END:VCALENDAR
 """,
+                {},
                 (),
-                (),
             ),
             (
                 "#3.9 Simple component, instance removed time change",
@@ -2194,14 +2227,14 @@
 END:VEVENT
 END:VCALENDAR
 """,
-                ("DTSTART", "DTEND", ),
+                {"DTSTART":set(), "DTEND":set(), },
                 ("20080602T120000Z",),
             ),
         )
         
         for description, calendar1, calendar2, changes, rids in itertools.chain(data1, data2, data3,):
             differ = iCalDiff(Component.fromString(calendar1), Component.fromString(calendar2), False)
-            expected_changes = set(changes)
+            expected_changes = changes
             expected_rids = set(rids) if rids else None
             got_changes, got_rids = differ.whatIsDifferent()
             self.assertEqual(got_changes, expected_changes, msg="%s expected changes: '%s', got: '%s'" % (description, expected_changes, got_changes,))
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20090302/231a496c/attachment-0001.html>


More information about the calendarserver-changes mailing list