[CalendarServer-changes] [12349] CalendarServer/trunk

source_changes at macosforge.org source_changes at macosforge.org
Wed Mar 12 11:21:42 PDT 2014


Revision: 12349
          http://trac.calendarserver.org//changeset/12349
Author:   cdaboo at apple.com
Date:     2014-01-15 08:23:30 -0800 (Wed, 15 Jan 2014)
Log Message:
-----------
STATUS:CANCELLED now sends METHOD:CANCEL.

Modified Paths:
--------------
    CalendarServer/trunk/twistedcaldav/ical.py
    CalendarServer/trunk/txdav/caldav/datastore/scheduling/icaldiff.py
    CalendarServer/trunk/txdav/caldav/datastore/scheduling/implicit.py
    CalendarServer/trunk/txdav/caldav/datastore/scheduling/processing.py
    CalendarServer/trunk/txdav/caldav/datastore/scheduling/test/test_icaldiff.py

Modified: CalendarServer/trunk/twistedcaldav/ical.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/ical.py	2014-01-15 16:21:14 UTC (rev 12348)
+++ CalendarServer/trunk/twistedcaldav/ical.py	2014-01-15 16:23:30 UTC (rev 12349)
@@ -2700,7 +2700,7 @@
     def filterComponents(self, rids):
 
         # If master is in rids do nothing
-        if not rids or "" in rids:
+        if not rids or None in rids:
             return True
 
         assert self.name() == "VCALENDAR", "Not a calendar: %r" % (self,)
@@ -2713,7 +2713,7 @@
                 remaining -= 1
                 continue
             rid = component.getRecurrenceIDUTC()
-            if (rid.getText() if rid else "") not in rids:
+            if rid not in rids:
                 self.removeComponent(component)
                 remaining -= 1
 

Modified: CalendarServer/trunk/txdav/caldav/datastore/scheduling/icaldiff.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/scheduling/icaldiff.py	2014-01-15 16:21:14 UTC (rev 12348)
+++ CalendarServer/trunk/txdav/caldav/datastore/scheduling/icaldiff.py	2014-01-15 16:23:30 UTC (rev 12349)
@@ -334,7 +334,7 @@
                     overridden = returnCalendar.overriddenComponent(rid)
                     if self._attendeeDecline(overridden):
                         changeCausesReply = True
-                        changedRids.append(rid.getText() if rid else "")
+                        changedRids.append(rid)
 
                     # When a master component is present we keep the missing override in place but mark it as hidden.
                     # When no master is present we now do the same so we can track updates to the override correctly.
@@ -417,7 +417,7 @@
                 #return False, False, (), None
             changeCausesReply |= reply
             if reply:
-                changedRids.append(rid.getText() if rid else "")
+                changedRids.append(rid)
 
         # We need to derive instances for any declined using an EXDATE
         for decline in sorted(declines):
@@ -427,7 +427,7 @@
                 if overridden is not None:
                     if self._attendeeDecline(overridden):
                         changeCausesReply = True
-                        changedRids.append(decline.getText() if decline else "")
+                        changedRids.append(decline)
 
                     # When a master component is present we keep the missing override in place but mark it as hidden.
                     # When no master is present we remove the override,
@@ -828,7 +828,7 @@
 
         if addedChanges:
             rid = comp1.getRecurrenceIDUTC()
-            rids[rid.getText() if rid is not None else ""] = propsChanged
+            rids[rid] = propsChanged
 
 
     def _logDiffError(self, title):

Modified: CalendarServer/trunk/txdav/caldav/datastore/scheduling/implicit.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/scheduling/implicit.py	2014-01-15 16:21:14 UTC (rev 12348)
+++ CalendarServer/trunk/txdav/caldav/datastore/scheduling/implicit.py	2014-01-15 16:23:30 UTC (rev 12349)
@@ -553,7 +553,7 @@
                 self.calendar.sequenceInSync(self.oldcalendar)
 
             # Significant change
-            no_change, self.changed_rids, self.needs_action_rids, reinvites, recurrence_reschedule = self.isOrganizerChangeInsignificant()
+            no_change, self.changed_rids, self.needs_action_rids, reinvites, recurrence_reschedule, status_cancelled, only_status = self.isOrganizerChangeInsignificant()
             if no_change:
                 if reinvites:
                     log.debug("Implicit - organizer '{organizer}' is re-inviting UID: '{uid}', attendees: {attendees}", organizer=self.organizer, uid=self.uid, attendees=", ".join(reinvites))
@@ -594,6 +594,8 @@
                 else:
                     self.findRemovedAttendeesOnRecurrenceChange()
 
+                self.checkStatusCancelled(status_cancelled, only_status)
+
                 # For now we always bump the sequence number on modifications because we cannot track DTSTAMP on
                 # the Attendee side. But we check the old and the new and only bump if the client did not already do it.
                 self.needs_sequence_change = self.calendar.needsiTIPSequenceChange(self.oldcalendar)
@@ -630,6 +632,8 @@
         date_changed_rids = None
         reinvites = None
         recurrence_reschedule = False
+        status_cancelled = set()
+        only_status = None
         differ = iCalDiff(self.oldcalendar, self.calendar, self.do_smart_merge)
         no_change = differ.organizerDiff()
         if not no_change:
@@ -653,7 +657,7 @@
                     date_changed_rids.add(rid)
 
                 # Check to see whether a change to R-ID's happened
-                if rid == "":
+                if rid is None:
 
                     if "DTSTART" in props and self.calendar.masterComponent().hasProperty("RRULE"):
                         # DTSTART change with RRULE present is always a reschedule
@@ -693,6 +697,16 @@
                             if newrrule == oldrrule:
                                 recurrence_reschedule = False
 
+                # Check for addition of STATUS:CANCELLED
+                if "STATUS" in props:
+                    if only_status is None and len(props) == 1:
+                        only_status = True
+                    instance = self.calendar.overriddenComponent(rid)
+                    if instance and instance.propertyValue("STATUS") == "CANCELLED":
+                        status_cancelled.add(rid)
+                else:
+                    only_status = False
+
             if checkOrganizerValue:
                 oldOrganizer = self.oldcalendar.getOrganizer()
                 newOrganizer = self.calendar.getOrganizer()
@@ -713,7 +727,7 @@
                 except KeyError:
                     pass
 
-        return no_change, rids, date_changed_rids, reinvites, recurrence_reschedule
+        return no_change, rids, date_changed_rids, reinvites, recurrence_reschedule, status_cancelled, only_status
 
 
     def findRemovedAttendees(self):
@@ -816,6 +830,22 @@
                 self.cancelledAttendees.add((attendee, rid,))
 
 
+    def checkStatusCancelled(self, cancelled, only_status):
+        """
+        Check to see whether STATUS:CANCELLED has been added to any/all instances, and if so
+        always trigger a METHOD:CANCEL on those. In the case where only STATUS has changed, we
+        need to only send METHOD:CANCEL and suppress any METHOD:REQUEST.
+        """
+        if cancelled:
+            for attendee, rid in self.calendar.getAttendeesByInstance(onlyScheduleAgentServer=True):
+                if rid in cancelled:
+                    self.cancelledAttendees.add((attendee, rid,))
+
+            # If only a cancel is done, then suppress any METHOD:REQUEST that a normal "modify: would do
+            if only_status:
+                self.action = "modify-cancelled"
+
+
     def coerceAttendeesPartstatOnCreate(self):
         """
         Make sure any attendees handled by the server start off with PARTSTAT=NEEDS-ACTION as

Modified: CalendarServer/trunk/txdav/caldav/datastore/scheduling/processing.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/scheduling/processing.py	2014-01-15 16:21:14 UTC (rev 12348)
+++ CalendarServer/trunk/txdav/caldav/datastore/scheduling/processing.py	2014-01-15 16:23:30 UTC (rev 12349)
@@ -604,10 +604,10 @@
                 update_details = []
                 for rid, props_changed in sorted(rids.iteritems(), key=lambda x: x[0]):
                     recurrence = []
-                    if rid == "":
+                    if rid is None:
                         recurrence.append(customxml.Master())
                     else:
-                        recurrence.append(customxml.RecurrenceID.fromString(rid))
+                        recurrence.append(customxml.RecurrenceID.fromString(rid.getText()))
                     changes = []
                     for propName, paramNames in sorted(props_changed.iteritems(), key=lambda x: x[0]):
                         params = tuple([customxml.ChangedParameter(name=param) for param in paramNames])
@@ -679,7 +679,7 @@
                     # Build the schedule-changes XML element
                     if rids:
                         action = customxml.Cancel(
-                            *[customxml.Recurrence(customxml.RecurrenceID.fromString(rid)) for rid in sorted(rids)]
+                            *[customxml.Recurrence(customxml.RecurrenceID.fromString(rid.getText())) for rid in sorted(rids)]
                         )
                     else:
                         action = customxml.Cancel()

Modified: CalendarServer/trunk/txdav/caldav/datastore/scheduling/test/test_icaldiff.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/scheduling/test/test_icaldiff.py	2014-01-15 16:21:14 UTC (rev 12348)
+++ CalendarServer/trunk/txdav/caldav/datastore/scheduling/test/test_icaldiff.py	2014-01-15 16:23:30 UTC (rev 12349)
@@ -23,6 +23,8 @@
 
 from txdav.caldav.datastore.scheduling.icaldiff import iCalDiff
 
+from pycalendar.datetime import DateTime
+
 import itertools
 import re
 
@@ -1192,6 +1194,9 @@
                     str(diffResult[3]).replace("\r", "").replace("\n ", "")
                 ) if diffResult[3] else None,
             )
+            result = list(result)
+            result[2] = tuple([(DateTime.parseText(dt) if dt else None) for dt in result[2]])
+            result = tuple(result)
             self.assertEqual(diffResult, result, msg="%s: actual result: (%s)" % (description, ", ".join([str(i).replace("\r", "") for i in diffResult]),))
 
 
@@ -1694,6 +1699,9 @@
                     str(diffResult[3]).replace("\r", "").replace("\n ", "")
                 ) if diffResult[3] else None,
             )
+            result = list(result)
+            result[2] = tuple([(DateTime.parseText(dt) if dt else None) for dt in result[2]])
+            result = tuple(result)
             self.assertEqual(diffResult, result, msg="%s: actual result: (%s)" % (description, ", ".join([str(i).replace("\r", "") for i in diffResult]),))
 
 
@@ -2050,6 +2058,9 @@
                 tuple(sorted(diffResult[2])),
                 str(diffResult[3]).replace("\r", "") if diffResult[3] else None,
             )
+            result = list(result)
+            result[2] = tuple([(DateTime.parseText(dt) if dt else None) for dt in result[2]])
+            result = tuple(result)
             self.assertEqual(diffResult, result, msg="%s: actual result: (%s)" % (description, ", ".join([str(i).replace("\r", "") for i in diffResult]),))
 
 
@@ -2415,6 +2426,9 @@
                 tuple(sorted(diffResult[2])),
                 str(diffResult[3]).replace("\r", "") if diffResult[3] else None,
             )
+            result = list(result)
+            result[2] = tuple([(DateTime.parseText(dt) if dt else None) for dt in result[2]])
+            result = tuple(result)
             self.assertEqual(diffResult, result, msg="%s: actual result: (%s)" % (description, ", ".join([str(i).replace("\r", "") for i in diffResult]),))
 
 
@@ -2696,6 +2710,9 @@
                 tuple(sorted(diffResult[2])),
                 str(diffResult[3]).replace("\r", "") if diffResult[3] else None,
             )
+            result = list(result)
+            result[2] = tuple([(DateTime.parseText(dt) if dt else None) for dt in result[2]])
+            result = tuple(result)
             self.assertEqual(diffResult, result, msg="%s: actual result: (%s)" % (description, ", ".join([str(i).replace("\r", "") for i in diffResult]),))
 
 
@@ -3250,6 +3267,9 @@
                     str(diffResult[3]).replace("\r", "").replace("\n ", "")
                 ) if diffResult[3] else None,
             )
+            result = list(result)
+            result[2] = tuple([(DateTime.parseText(dt) if dt else None) for dt in result[2]])
+            result = tuple(result)
             self.assertEqual(diffResult, result, msg="%s: actual result: (%s)" % (description, ", ".join([str(i).replace("\r", "") for i in diffResult]),))
 
 
@@ -4268,6 +4288,7 @@
         for description, calendar1, calendar2, rids in itertools.chain(data1, data2, data3,):
             differ = iCalDiff(Component.fromString(calendar1), Component.fromString(calendar2), False)
             got_rids = differ.whatIsDifferent()
+            rids = dict([(DateTime.parseText(k) if k else None, v) for k, v in rids.items()])
             self.assertEqual(got_rids, rids, msg="%s expected R-IDs: '%s', got: '%s'" % (description, rids, got_rids,))
 
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20140312/e4a398b1/attachment.html>


More information about the calendarserver-changes mailing list