[CalendarServer-changes] [10179] CalendarServer/trunk/twistedcaldav
source_changes at macosforge.org
source_changes at macosforge.org
Mon Dec 17 09:50:55 PST 2012
Revision: 10179
http://trac.calendarserver.org//changeset/10179
Author: cdaboo at apple.com
Date: 2012-12-17 09:50:55 -0800 (Mon, 17 Dec 2012)
Log Message:
-----------
Time stamps added to ATTENDEE properties on PARTSTAT changes.
Modified Paths:
--------------
CalendarServer/trunk/twistedcaldav/customxml.py
CalendarServer/trunk/twistedcaldav/scheduling/icaldiff.py
CalendarServer/trunk/twistedcaldav/scheduling/itip.py
CalendarServer/trunk/twistedcaldav/scheduling/test/test_icaldiff.py
CalendarServer/trunk/twistedcaldav/stdconfig.py
Modified: CalendarServer/trunk/twistedcaldav/customxml.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/customxml.py 2012-12-17 17:50:12 UTC (rev 10178)
+++ CalendarServer/trunk/twistedcaldav/customxml.py 2012-12-17 17:50:55 UTC (rev 10179)
@@ -59,7 +59,6 @@
"calendarserver-principal-search",
)
-
calendarserver_sharing_compliance = (
"calendarserver-sharing",
)
@@ -69,7 +68,11 @@
"calendarserver-sharing-no-scheduling",
)
+calendarserver_partstat_changes_compliance = (
+ "calendarserver-partstat-changes",
+)
+
@registerElement
class TwistedCalendarSupportedComponents (WebDAVTextElement):
"""
Modified: CalendarServer/trunk/twistedcaldav/scheduling/icaldiff.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/scheduling/icaldiff.py 2012-12-17 17:50:12 UTC (rev 10178)
+++ CalendarServer/trunk/twistedcaldav/scheduling/icaldiff.py 2012-12-17 17:50:55 UTC (rev 10179)
@@ -14,17 +14,19 @@
# limitations under the License.
##
+from difflib import unified_diff
+
+from pycalendar.datetime import PyCalendarDateTime
+from pycalendar.period import PyCalendarPeriod
+
from twext.python.log import Logger
+from twistedcaldav import accounting
+from twistedcaldav.config import config
from twistedcaldav.ical import Component, Property
from twistedcaldav.scheduling.cuaddress import normalizeCUAddr
from twistedcaldav.scheduling.itip import iTipGenerator
-from twistedcaldav import accounting
-from difflib import unified_diff
-from pycalendar.period import PyCalendarPeriod
-from pycalendar.datetime import PyCalendarDateTime
-
"""
Class that handles diff'ing two calendar objects.
"""
@@ -483,7 +485,13 @@
if serverAttendee.parameterValue("PARTSTAT", "NEEDS-ACTION") != clientAttendee.parameterValue("PARTSTAT", "NEEDS-ACTION"):
serverAttendee.setParameter("PARTSTAT", clientAttendee.parameterValue("PARTSTAT", "NEEDS-ACTION"))
+
+ # If PARTSTAT was changed by the attendee, add a timestamp if needed
+ if config.Scheduling.Options.TimestampAttendeePartStatChanges:
+ serverAttendee.setParameter("X-CALENDARSERVER-DTSTAMP", PyCalendarDateTime.getNowUTC().getText())
+
replyNeeded = True
+
if serverAttendee.parameterValue("RSVP", "FALSE") != clientAttendee.parameterValue("RSVP", "FALSE"):
if clientAttendee.parameterValue("RSVP", "FALSE") == "FALSE":
try:
Modified: CalendarServer/trunk/twistedcaldav/scheduling/itip.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/scheduling/itip.py 2012-12-17 17:50:12 UTC (rev 10178)
+++ CalendarServer/trunk/twistedcaldav/scheduling/itip.py 2012-12-17 17:50:55 UTC (rev 10179)
@@ -117,12 +117,15 @@
completeds = current_master.properties("COMPLETED")
organizer = current_master.getProperty("ORGANIZER")
organizer_schedule_status = organizer.parameterValue("SCHEDULE-STATUS", None) if organizer else None
+ attendee = current_master.getAttendeeProperty((recipient,))
+ attendee_dtstamp = attendee.parameterValue("X-CALENDARSERVER-DTSTAMP") if attendee else None
else:
master_valarms = ()
private_comments = ()
transps = ()
completeds = ()
organizer_schedule_status = None
+ attendee_dtstamp = None
if itip_message.masterComponent() is not None:
@@ -143,11 +146,15 @@
organizer = master_component.getProperty("ORGANIZER")
if organizer:
organizer.setParameter("SCHEDULE-STATUS", organizer_schedule_status)
+ if attendee_dtstamp:
+ attendee = master_component.getAttendeeProperty((recipient,))
+ if attendee:
+ attendee.setParameter("X-CALENDARSERVER-DTSTAMP", attendee_dtstamp)
# Now try to match recurrences in the new calendar
for component in tuple(new_calendar.subcomponents()):
if component.name() != "VTIMEZONE" and component.getRecurrenceIDUTC() is not None:
- iTipProcessing.transferItems(calendar, master_valarms, private_comments, transps, completeds, organizer_schedule_status, component, recipient)
+ iTipProcessing.transferItems(calendar, master_valarms, private_comments, transps, completeds, organizer_schedule_status, attendee_dtstamp, component, recipient)
# Now try to match recurrences from the old calendar
for component in calendar.subcomponents():
@@ -158,7 +165,7 @@
new_component = new_calendar.deriveInstance(rid, allowCancelled=allowCancelled)
if new_component:
new_calendar.addComponent(new_component)
- iTipProcessing.transferItems(calendar, master_valarms, private_comments, transps, completeds, organizer_schedule_status, new_component, recipient)
+ iTipProcessing.transferItems(calendar, master_valarms, private_comments, transps, completeds, organizer_schedule_status, attendee_dtstamp, new_component, recipient)
# Replace the entire object
return new_calendar, rids
@@ -175,7 +182,7 @@
calendar.addComponent(component)
else:
component = component.duplicate()
- missingDeclined = iTipProcessing.transferItems(calendar, master_valarms, private_comments, transps, completeds, organizer_schedule_status, component, recipient, remove_matched=True)
+ missingDeclined = iTipProcessing.transferItems(calendar, master_valarms, private_comments, transps, completeds, organizer_schedule_status, attendee_dtstamp, component, recipient, remove_matched=True)
if not missingDeclined:
calendar.addComponent(component)
if recipient:
@@ -486,7 +493,7 @@
@staticmethod
- def transferItems(from_calendar, master_valarms, private_comments, transps, completeds, organizer_schedule_status, to_component, recipient, remove_matched=False):
+ def transferItems(from_calendar, master_valarms, private_comments, transps, completeds, organizer_schedule_status, attendee_dtstamp, to_component, recipient, remove_matched=False):
"""
Transfer properties from a calendar to a component by first trying to match the component in the original calendar and
use the properties from that, or use the values provided as arguments (which have been derived from the original calendar's
@@ -524,6 +531,8 @@
if matched.hasProperty(Component.HIDDEN_INSTANCE_PROPERTY):
to_component.addProperty(Property(Component.HIDDEN_INSTANCE_PROPERTY, "T"))
+ if attendee and attendee_dtstamp:
+ attendee.setParameter("X-CALENDARSERVER-DTSTAMP", attendee_dtstamp)
else:
# Check for incoming DECLINED
attendee = to_component.getAttendeeProperty((recipient,))
@@ -540,6 +549,10 @@
organizer = to_component.getProperty("ORGANIZER")
if organizer:
organizer.setParameter("SCHEDULE-STATUS", organizer_schedule_status)
+ if attendee_dtstamp:
+ attendee = to_component.getAttendeeProperty((recipient,))
+ if attendee:
+ attendee.setParameter("X-CALENDARSERVER-DTSTAMP", attendee_dtstamp)
return False
@@ -843,7 +856,7 @@
itip.removeXProperties(keep_properties=keep_properties)
# Property Parameters
- itip.removePropertyParameters("ATTENDEE", ("SCHEDULE-AGENT", "SCHEDULE-STATUS", "SCHEDULE-FORCE-SEND",))
+ itip.removePropertyParameters("ATTENDEE", ("SCHEDULE-AGENT", "SCHEDULE-STATUS", "SCHEDULE-FORCE-SEND", "X-CALENDARSERVER-DTSTAMP",))
itip.removePropertyParameters("ORGANIZER", ("SCHEDULE-AGENT", "SCHEDULE-STATUS", "SCHEDULE-FORCE-SEND",))
Modified: CalendarServer/trunk/twistedcaldav/scheduling/test/test_icaldiff.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/scheduling/test/test_icaldiff.py 2012-12-17 17:50:12 UTC (rev 10178)
+++ CalendarServer/trunk/twistedcaldav/scheduling/test/test_icaldiff.py 2012-12-17 17:50:55 UTC (rev 10179)
@@ -20,6 +20,7 @@
from difflib import unified_diff
import itertools
+import re
class ICalDiff (twistedcaldav.test.util.TestCase):
"""
@@ -558,7 +559,7 @@
DTSTART:20080601T120000Z
DTEND:20080601T130000Z
ATTENDEE:mailto:user1 at example.com
-ATTENDEE;PARTSTAT=ACCEPTED:mailto:user2 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED;X-CALENDARSERVER-DTSTAMP=XXXXXXXXTXXXXXXZ:mailto:user2 at example.com
ORGANIZER;CN=User 01:mailto:user1 at example.com
END:VEVENT
END:VCALENDAR
@@ -1180,7 +1181,11 @@
diffResult[0],
diffResult[1],
tuple(sorted(diffResult[2])),
- str(diffResult[3]).replace("\r", "") if diffResult[3] else None,
+ re.sub(
+ "X-CALENDARSERVER-DTSTAMP=[^Z]+",
+ "X-CALENDARSERVER-DTSTAMP=XXXXXXXXTXXXXXX",
+ str(diffResult[3]).replace("\r", "").replace("\n ", "")
+ ) if diffResult[3] else None,
)
self.assertEqual(diffResult, result, msg="%s: actual result: (%s)" % (description, ", ".join([str(i).replace("\r", "") for i in diffResult]),))
@@ -1566,7 +1571,7 @@
RECURRENCE-ID:20080602T120000Z
DTSTART:20080602T123000Z
DTEND:20080602T130000Z
-ATTENDEE;PARTSTAT=ACCEPTED;RSVP=TRUE:mailto:user2 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED;RSVP=TRUE;X-CALENDARSERVER-DTSTAMP=XXXXXXXXTXXXXXXZ:mailto:user2 at example.com
ORGANIZER:mailto:user1 at example.com
END:VEVENT
BEGIN:VEVENT
@@ -1575,7 +1580,7 @@
DTSTART:20080604T120000Z
DTEND:20080604T130000Z
ATTENDEE:mailto:user1 at example.com
-ATTENDEE;PARTSTAT=DECLINED;RSVP=TRUE:mailto:user2 at example.com
+ATTENDEE;PARTSTAT=DECLINED;RSVP=TRUE;X-CALENDARSERVER-DTSTAMP=XXXXXXXXTXXXXXXZ:mailto:user2 at example.com
ORGANIZER;CN=User 01:mailto:user1 at example.com
END:VEVENT
END:VCALENDAR
@@ -1678,7 +1683,11 @@
diffResult[0],
diffResult[1],
tuple(sorted(diffResult[2])),
- str(diffResult[3]).replace("\r", "") if diffResult[3] else None,
+ re.sub(
+ "X-CALENDARSERVER-DTSTAMP=[^Z]+",
+ "X-CALENDARSERVER-DTSTAMP=XXXXXXXXTXXXXXX",
+ str(diffResult[3]).replace("\r", "").replace("\n ", "")
+ ) if diffResult[3] else None,
)
self.assertEqual(diffResult, result, msg="%s: actual result: (%s)" % (description, ", ".join([str(i).replace("\r", "") for i in diffResult]),))
@@ -2715,7 +2724,7 @@
DTSTART:20080601T120000Z
DTEND:20080601T130000Z
ATTENDEE:mailto:user1 at example.com
-ATTENDEE;PARTSTAT=ACCEPTED:mailto:user2 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED;X-CALENDARSERVER-DTSTAMP=XXXXXXXXTXXXXXXZ:mailto:user2 at example.com
ORGANIZER;CN=User 01:mailto:user1 at example.com
END:VEVENT
END:VCALENDAR
@@ -2760,7 +2769,7 @@
DTSTART:20080601T130000Z
DTEND:20080601T140000Z
ATTENDEE:mailto:user1 at example.com
-ATTENDEE;PARTSTAT=ACCEPTED:mailto:user2 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED;X-CALENDARSERVER-DTSTAMP=XXXXXXXXTXXXXXXZ:mailto:user2 at example.com
ORGANIZER;CN=User 01:mailto:user1 at example.com
END:VEVENT
END:VCALENDAR
@@ -2805,7 +2814,7 @@
DTSTART:20080601T130000Z
DTEND:20080601T140000Z
ATTENDEE:mailto:user1 at example.com
-ATTENDEE;PARTSTAT=ACCEPTED:mailto:user2 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED;X-CALENDARSERVER-DTSTAMP=XXXXXXXXTXXXXXXZ:mailto:user2 at example.com
ORGANIZER;CN=User 01:mailto:user1 at example.com
END:VEVENT
END:VCALENDAR
@@ -2868,7 +2877,7 @@
DTSTART:20080601T120000Z
DTEND:20080601T130000Z
ATTENDEE:mailto:user1 at example.com
-ATTENDEE;PARTSTAT=ACCEPTED:mailto:user2 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED;X-CALENDARSERVER-DTSTAMP=XXXXXXXXTXXXXXXZ:mailto:user2 at example.com
ORGANIZER;CN=User 01:mailto:user1 at example.com
END:VEVENT
BEGIN:VEVENT
@@ -2877,7 +2886,7 @@
DTSTART:20080602T120000Z
DTEND:20080602T130000Z
ATTENDEE:mailto:user1 at example.com
-ATTENDEE;PARTSTAT=ACCEPTED;RSVP=TRUE:mailto:user2 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED;RSVP=TRUE;X-CALENDARSERVER-DTSTAMP=XXXXXXXXTXXXXXXZ:mailto:user2 at example.com
ORGANIZER;CN=User 01:mailto:user1 at example.com
END:VEVENT
END:VCALENDAR
@@ -2940,7 +2949,7 @@
DTSTART:20080601T140000Z
DTEND:20080601T150000Z
ATTENDEE:mailto:user1 at example.com
-ATTENDEE;PARTSTAT=ACCEPTED:mailto:user2 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED;X-CALENDARSERVER-DTSTAMP=XXXXXXXXTXXXXXXZ:mailto:user2 at example.com
ORGANIZER;CN=User 01:mailto:user1 at example.com
END:VEVENT
BEGIN:VEVENT
@@ -2949,7 +2958,7 @@
DTSTART:20080602T120000Z
DTEND:20080602T130000Z
ATTENDEE:mailto:user1 at example.com
-ATTENDEE;PARTSTAT=ACCEPTED:mailto:user2 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED;X-CALENDARSERVER-DTSTAMP=XXXXXXXXTXXXXXXZ:mailto:user2 at example.com
ORGANIZER;CN=User 01:mailto:user1 at example.com
END:VEVENT
END:VCALENDAR
@@ -3066,7 +3075,7 @@
DTSTART:20080601T120000Z
DTEND:20080601T130000Z
ATTENDEE:mailto:user1 at example.com
-ATTENDEE;PARTSTAT=ACCEPTED:mailto:user2 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED;X-CALENDARSERVER-DTSTAMP=XXXXXXXXTXXXXXXZ:mailto:user2 at example.com
ORGANIZER;CN=User 01:mailto:user1 at example.com
END:VEVENT
END:VCALENDAR
@@ -3134,7 +3143,7 @@
DTSTART:20080601T120000Z
DTEND:20080601T130000Z
ATTENDEE:mailto:user1 at example.com
-ATTENDEE;PARTSTAT=ACCEPTED:mailto:user2 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED;X-CALENDARSERVER-DTSTAMP=XXXXXXXXTXXXXXXZ:mailto:user2 at example.com
ORGANIZER;CN=User 01:mailto:user1 at example.com
END:VEVENT
END:VCALENDAR
@@ -3203,7 +3212,7 @@
DTSTART:20080601T120000Z
DTEND:20080601T130000Z
ATTENDEE:mailto:user1 at example.com
-ATTENDEE;PARTSTAT=ACCEPTED:mailto:user2 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED;X-CALENDARSERVER-DTSTAMP=XXXXXXXXTXXXXXXZ:mailto:user2 at example.com
ORGANIZER;CN=User 01:mailto:user1 at example.com
END:VEVENT
END:VCALENDAR
@@ -3218,7 +3227,11 @@
diffResult[0],
diffResult[1],
tuple(sorted(diffResult[2])),
- str(diffResult[3]).replace("\r", "") if diffResult[3] else None,
+ re.sub(
+ "X-CALENDARSERVER-DTSTAMP=[^Z]+",
+ "X-CALENDARSERVER-DTSTAMP=XXXXXXXXTXXXXXX",
+ str(diffResult[3]).replace("\r", "").replace("\n ", "")
+ ) if diffResult[3] else None,
)
self.assertEqual(diffResult, result, msg="%s: actual result: (%s)" % (description, ", ".join([str(i).replace("\r", "") for i in diffResult]),))
Modified: CalendarServer/trunk/twistedcaldav/stdconfig.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/stdconfig.py 2012-12-17 17:50:12 UTC (rev 10178)
+++ CalendarServer/trunk/twistedcaldav/stdconfig.py 2012-12-17 17:50:55 UTC (rev 10179)
@@ -694,7 +694,8 @@
"UIDLockTimeoutSeconds" : 60, # Time for implicit UID lock timeout
"UIDLockExpirySeconds" : 300, # Expiration time for UID lock,
"V1Compatibility" : False, # Allow /path-based CUAs in scheduling replies
- "PrincipalHostAliases" : [], # Hostnames matched in http(s) CUAs
+ "PrincipalHostAliases" : [], # Host names matched in http(s) CUAs
+ "TimestampAttendeePartStatChanges" : True, # Add a time stamp when an Attendee changes their PARTSTAT
"DelegeteRichFreeBusy" : True, # Delegates can get extra info in a freebusy request
"RoomResourceRichFreeBusy" : True, # Any user can get extra info for rooms/resources in a freebusy request
@@ -1536,6 +1537,8 @@
compliance += caldavxml.caldav_default_alarms_compliance
if configDict.EnableManagedAttachments:
compliance += caldavxml.caldav_managed_attachments_compliance
+ if configDict.Scheduling.Options.TimestampAttendeePartStatChanges:
+ compliance += customxml.calendarserver_partstat_changes_compliance
else:
compliance = ()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20121217/b3512f1d/attachment-0001.html>
More information about the calendarserver-changes
mailing list