[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