[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