[CalendarServer-changes] [2891] CalendarServer/branches/users/cdaboo/attendee-comments-2886/ twistedcaldav

source_changes at macosforge.org source_changes at macosforge.org
Wed Aug 27 12:53:32 PDT 2008


Revision: 2891
          http://trac.macosforge.org/projects/calendarserver/changeset/2891
Author:   cdaboo at apple.com
Date:     2008-08-27 12:53:32 -0700 (Wed, 27 Aug 2008)
Log Message:
-----------
Propagate attendee comments to organizer.

Modified Paths:
--------------
    CalendarServer/branches/users/cdaboo/attendee-comments-2886/twistedcaldav/ical.py
    CalendarServer/branches/users/cdaboo/attendee-comments-2886/twistedcaldav/scheduling/icaldiff.py
    CalendarServer/branches/users/cdaboo/attendee-comments-2886/twistedcaldav/scheduling/itip.py

Modified: CalendarServer/branches/users/cdaboo/attendee-comments-2886/twistedcaldav/ical.py
===================================================================
--- CalendarServer/branches/users/cdaboo/attendee-comments-2886/twistedcaldav/ical.py	2008-08-27 16:15:38 UTC (rev 2890)
+++ CalendarServer/branches/users/cdaboo/attendee-comments-2886/twistedcaldav/ical.py	2008-08-27 19:53:32 UTC (rev 2891)
@@ -1366,9 +1366,9 @@
                     continue
                 [component.removeProperty(p) for p in tuple(component.properties()) if p.name() not in keep_properties]
                 
-    def removeXProperties(self):
+    def removeXProperties(self, keep_properties):
         """
-        Remove all X- properties.
+        Remove all X- properties except the specified ones
         """
 
         assert self.name() == "VCALENDAR", "Not a calendar: %r" % (self,)
@@ -1377,7 +1377,11 @@
             for component in self.subcomponents():
                 if component.name() == "VTIMEZONE":
                     continue
-                [component.removeProperty(p) for p in tuple(component.properties()) if p.name().startswith("X-")]
+                [
+                    component.removeProperty(p)
+                    for p in tuple(component.properties())
+                    if p.name().startswith("X-") and p.name() not in keep_properties
+                ]
             
 ##
 # Dates and date-times

Modified: CalendarServer/branches/users/cdaboo/attendee-comments-2886/twistedcaldav/scheduling/icaldiff.py
===================================================================
--- CalendarServer/branches/users/cdaboo/attendee-comments-2886/twistedcaldav/scheduling/icaldiff.py	2008-08-27 16:15:38 UTC (rev 2890)
+++ CalendarServer/branches/users/cdaboo/attendee-comments-2886/twistedcaldav/scheduling/icaldiff.py	2008-08-27 19:53:32 UTC (rev 2891)
@@ -69,12 +69,12 @@
 
         # Do straight comparison without alarms
         self.calendar1 = self.calendar1.duplicate()
-        self.calendar1.removeXProperties()
+        self.calendar1.removeXProperties(("X-CALENDARSERVER-PRIVATE-COMMENT",))
         self.calendar1.attendeesView((attendee,))
         iTipGenerator.prepareSchedulingMessage(self.calendar1)
 
         self.calendar2 = self.calendar2.duplicate()
-        self.calendar2.removeXProperties()
+        self.calendar2.removeXProperties(("X-CALENDARSERVER-PRIVATE-COMMENT",))
         iTipGenerator.prepareSchedulingMessage(self.calendar2)
 
         if self.calendar1 == self.calendar2:
@@ -189,7 +189,11 @@
             return False, False
         
         # Only accept a change to this attendee's own ATTENDEE property
+        comp1.transformAllFromNative()
+        comp2.transformAllFromNative()
         propdiff = set(comp1.properties()) ^ set(comp2.properties())
+        comp1.transformAllToNative()
+        comp2.transformAllToNative()
         for prop in tuple(propdiff):
             # These ones are OK to change
             if prop.name() in (
@@ -201,10 +205,16 @@
             ):
                 propdiff.remove(prop)
                 continue
-            if prop.name() != "ATTENDEE" or prop.value() != self.attendee:
-                log.debug("Component properties are different: %s" % (propdiff,))
-                return False, False
+            
+            # These ones can change and trigger a reschedule
+            if ((prop.name() == "ATTENDEE" and prop.value() == self.attendee) or
+                prop.name() == "X-CALENDARSERVER-PRIVATE-COMMENT"):
+                continue
 
+            # Change that is not allowed
+            log.debug("Component properties are different: %s" % (propdiff,))
+            return False, False
+
         # Compare subcomponents.
         # NB at this point we assume VALARMS have been removed.
         result = set(comp1.subcomponents()) ^ set(comp2.subcomponents())

Modified: CalendarServer/branches/users/cdaboo/attendee-comments-2886/twistedcaldav/scheduling/itip.py
===================================================================
--- CalendarServer/branches/users/cdaboo/attendee-comments-2886/twistedcaldav/scheduling/itip.py	2008-08-27 16:15:38 UTC (rev 2890)
+++ CalendarServer/branches/users/cdaboo/attendee-comments-2886/twistedcaldav/scheduling/itip.py	2008-08-27 19:53:32 UTC (rev 2891)
@@ -36,6 +36,7 @@
 from twistedcaldav.ical import Property, iCalendarProductID, Component
 
 from vobject.icalendar import utc
+from vobject.icalendar import dateTimeToString
 
 log = Logger()
 
@@ -219,7 +220,7 @@
         new_master = itip_message.masterComponent()
         attendees = set()
         if new_master:
-            attendees.add(iTipProcessing.updateAttendeePartStat(new_master, old_master))
+            attendees.add(iTipProcessing.updateAttendeeData(new_master, old_master))
 
         # Now do all overridden ones
         for itip_component in itip_message.subcomponents():
@@ -239,15 +240,15 @@
                 match_component = calendar.deriveInstance(rid)
                 calendar.addComponent(match_component)
 
-            attendees.add(iTipProcessing.updateAttendeePartStat(itip_component, match_component))
+            attendees.add(iTipProcessing.updateAttendeeData(itip_component, match_component))
                 
         return True, attendees
 
     @staticmethod
-    def updateAttendeePartStat(from_component, to_component):
+    def updateAttendeeData(from_component, to_component):
         """
         Copy the PARTSTAT of the Attendee in the from_component to the matching ATTENDEE
-        in the to_component. Ignore if no match found.
+        in the to_component. Ignore if no match found. Also update the private comments.
 
         @param from_component:
         @type from_component:
@@ -266,6 +267,64 @@
         if existing_attendee:
             existing_attendee.params().setdefault("PARTSTAT", [partstat])[0] = partstat
             
+            # Handle attendee comments
+            
+            # Look for X-CALENDARSERVER-PRIVATE-COMMENT property in iTIP component (State 1 in spec)
+            attendee_comment = tuple(from_component.properties("X-CALENDARSERVER-PRIVATE-COMMENT"))
+            attendee_comment = attendee_comment[0] if len(attendee_comment) else None
+            
+            # Look for matching X-CALENDARSERVER-ATTENDEE-COMMENT property in existing data (State 2 in spec)
+            private_comments = tuple(to_component.properties("X-CALENDARSERVER-ATTENDEE-COMMENT"))
+            for comment in private_comments:
+                params = comment.params()["X-CALENDARSERVER-ATTENDEE-REF"]
+                assert len(params) == 1, "Must be one and only one X-CALENDARSERVER-ATTENDEE-REF parameter in X-CALENDARSERVER-ATTENDEE-COMMENT"
+                param = params[0]
+                if param == attendee.value():
+                    private_comment = comment
+                    break
+            else:
+                private_comment = None
+                
+            # Now do update logic
+            if attendee_comment is None and private_comment is None:
+                # Nothing to do
+                pass
+ 
+            elif attendee_comment is None and private_comment is not None:
+                # Remove all property parameters
+                private_comment.params().clear()
+                
+                # Add default parameters
+                private_comment.params()["X-CALENDARSERVER-ATTENDEE-REF"] = [attendee.value()]
+                private_comment.params()["X-CALENDARSERVER-DTSTAMP"] = [dateTimeToString(datetime.datetime.now(tz=utc))]
+                
+                # Set value empty
+                private_comment.setValue("")
+                
+            elif attendee_comment is not None and private_comment is None:
+                
+                # Add new property
+                private_comment = Property(
+                    "X-CALENDARSERVER-ATTENDEE-COMMENT",
+                    attendee_comment.value(),
+                    params = {
+                        "X-CALENDARSERVER-ATTENDEE-REF":     [attendee.value()],
+                        "X-CALENDARSERVER-DTSTAMP": [dateTimeToString(datetime.datetime.now(tz=utc))],
+                    }
+                )
+                to_component.addProperty(private_comment)
+            
+            else:
+                # Remove all property parameters
+                private_comment.params().clear()
+                
+                # Add default parameters
+                private_comment.params()["X-CALENDARSERVER-ATTENDEE-REF"] = [attendee.value()]
+                private_comment.params()["X-CALENDARSERVER-DTSTAMP"] = [dateTimeToString(datetime.datetime.now(tz=utc))]
+                
+                # Set new value
+                private_comment.setValue(attendee_comment.value())
+
         return attendee.value()
 
     @staticmethod
@@ -436,7 +495,6 @@
         for component in itip.subcomponents():
             stripSubComponents(component, ("VALARM",))
             stripComponentProperties(component, (
-                "X-CALENDARSERVER-PRIVATE-COMMENT",
                 "X-CALENDARSERVER-ATTENDEE-COMMENT",
             ))
             stripPropertyParameters(component.properties("ATTENDEE"), (
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20080827/d060144c/attachment.html 


More information about the calendarserver-changes mailing list