[CalendarServer-changes] [4830] CalendarServer/branches/release/CalendarServer-2.4-dev

source_changes at macosforge.org source_changes at macosforge.org
Sat Dec 5 22:39:17 PST 2009


Revision: 4830
          http://trac.macosforge.org/projects/calendarserver/changeset/4830
Author:   glyph at apple.com
Date:     2009-12-05 22:39:17 -0800 (Sat, 05 Dec 2009)
Log Message:
-----------
Pulled up r4823 and r4824 from trunk.

Revision Links:
--------------
    http://trac.macosforge.org/projects/calendarserver/changeset/4823
    http://trac.macosforge.org/projects/calendarserver/changeset/4824

Modified Paths:
--------------
    CalendarServer/branches/release/CalendarServer-2.4-dev/run
    CalendarServer/branches/release/CalendarServer-2.4-dev/twext/web2/channel/http.py
    CalendarServer/branches/release/CalendarServer-2.4-dev/twistedcaldav/accounting.py
    CalendarServer/branches/release/CalendarServer-2.4-dev/twistedcaldav/scheduling/icaldiff.py
    CalendarServer/branches/release/CalendarServer-2.4-dev/twistedcaldav/scheduling/itip.py
    CalendarServer/branches/release/CalendarServer-2.4-dev/twistedcaldav/scheduling/test/test_icaldiff.py

Property Changed:
----------------
    CalendarServer/branches/release/CalendarServer-2.4-dev/
    CalendarServer/branches/release/CalendarServer-2.4-dev/doc/Extensions/caldav-privatecomments.txt
    CalendarServer/branches/release/CalendarServer-2.4-dev/doc/Extensions/caldav-privatecomments.xml
    CalendarServer/branches/release/CalendarServer-2.4-dev/doc/Extensions/caldav-schedulingchanges.txt
    CalendarServer/branches/release/CalendarServer-2.4-dev/doc/Extensions/caldav-schedulingchanges.xml


Property changes on: CalendarServer/branches/release/CalendarServer-2.4-dev
___________________________________________________________________
Modified: svn:mergeinfo
   - /CalendarServer/branches/users/sagen/resource-delegates-4038:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066:4068-4075
/CalendarServer/trunk:4439-4440,4448,4450,4464,4473-4475,4602,4711-4712,4716-4717,4722,4739-4742,4748-4752,4758,4760,4762,4773,4782,4784,4787,4789,4797,4799
   + /CalendarServer/branches/users/sagen/resource-delegates-4038:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066:4068-4075
/CalendarServer/trunk:4439-4440,4448,4450,4464,4473-4475,4602,4711-4712,4716-4717,4722,4739-4742,4748-4752,4758,4760,4762,4773,4782,4784,4787,4789,4797,4799,4823-4824


Property changes on: CalendarServer/branches/release/CalendarServer-2.4-dev/doc/Extensions/caldav-privatecomments.txt
___________________________________________________________________
Modified: svn:mergeinfo
   - /CalendarServer/branches/users/cdaboo/attendee-comments-2886/doc/Extensions/caldav-privatecomments-00.txt:2887-2910
/CalendarServer/branches/users/cdaboo/byebye-serviceslocator-2937/doc/Extensions/caldav-privatecomments-00.txt:2938-3097
/CalendarServer/branches/users/cdaboo/implicit-if-match-3306/doc/Extensions/caldav-privatecomments.txt:3307-3349
/CalendarServer/branches/users/cdaboo/implicitauto-2947/doc/Extensions/caldav-privatecomments-00.txt:2948-2989
/CalendarServer/branches/users/cdaboo/location-partial-accept-3573/doc/Extensions/caldav-privatecomments.txt:3574-3581
/CalendarServer/branches/users/sagen/resource-delegates-4038/doc/Extensions/caldav-privatecomments.txt:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/doc/Extensions/caldav-privatecomments.txt:4068-4075
/CalendarServer/trunk/doc/Extensions/caldav-privatecomments.txt:4439-4440,4448,4450,4464,4473-4475,4717,4758,4773
   + /CalendarServer/branches/users/cdaboo/attendee-comments-2886/doc/Extensions/caldav-privatecomments-00.txt:2887-2910
/CalendarServer/branches/users/cdaboo/byebye-serviceslocator-2937/doc/Extensions/caldav-privatecomments-00.txt:2938-3097
/CalendarServer/branches/users/cdaboo/implicit-if-match-3306/doc/Extensions/caldav-privatecomments.txt:3307-3349
/CalendarServer/branches/users/cdaboo/implicitauto-2947/doc/Extensions/caldav-privatecomments-00.txt:2948-2989
/CalendarServer/branches/users/cdaboo/location-partial-accept-3573/doc/Extensions/caldav-privatecomments.txt:3574-3581
/CalendarServer/branches/users/sagen/resource-delegates-4038/doc/Extensions/caldav-privatecomments.txt:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/doc/Extensions/caldav-privatecomments.txt:4068-4075
/CalendarServer/trunk/doc/Extensions/caldav-privatecomments.txt:4439-4440,4448,4450,4464,4473-4475,4717,4758,4773,4823-4824


Property changes on: CalendarServer/branches/release/CalendarServer-2.4-dev/doc/Extensions/caldav-privatecomments.xml
___________________________________________________________________
Modified: svn:mergeinfo
   - /CalendarServer/branches/users/cdaboo/attendee-comments-2886/doc/Extensions/caldav-privatecomments-00.xml:2887-2910
/CalendarServer/branches/users/cdaboo/byebye-serviceslocator-2937/doc/Extensions/caldav-privatecomments-00.xml:2938-3097
/CalendarServer/branches/users/cdaboo/implicit-if-match-3306/doc/Extensions/caldav-privatecomments.xml:3307-3349
/CalendarServer/branches/users/cdaboo/implicitauto-2947/doc/Extensions/caldav-privatecomments-00.xml:2948-2989
/CalendarServer/branches/users/cdaboo/location-partial-accept-3573/doc/Extensions/caldav-privatecomments.xml:3574-3581
/CalendarServer/branches/users/sagen/resource-delegates-4038/doc/Extensions/caldav-privatecomments.xml:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/doc/Extensions/caldav-privatecomments.xml:4068-4075
/CalendarServer/trunk/doc/Extensions/caldav-privatecomments.xml:4439-4440,4448,4450,4464,4473-4475,4717,4758,4773
   + /CalendarServer/branches/users/cdaboo/attendee-comments-2886/doc/Extensions/caldav-privatecomments-00.xml:2887-2910
/CalendarServer/branches/users/cdaboo/byebye-serviceslocator-2937/doc/Extensions/caldav-privatecomments-00.xml:2938-3097
/CalendarServer/branches/users/cdaboo/implicit-if-match-3306/doc/Extensions/caldav-privatecomments.xml:3307-3349
/CalendarServer/branches/users/cdaboo/implicitauto-2947/doc/Extensions/caldav-privatecomments-00.xml:2948-2989
/CalendarServer/branches/users/cdaboo/location-partial-accept-3573/doc/Extensions/caldav-privatecomments.xml:3574-3581
/CalendarServer/branches/users/sagen/resource-delegates-4038/doc/Extensions/caldav-privatecomments.xml:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/doc/Extensions/caldav-privatecomments.xml:4068-4075
/CalendarServer/trunk/doc/Extensions/caldav-privatecomments.xml:4439-4440,4448,4450,4464,4473-4475,4717,4758,4773,4823-4824


Property changes on: CalendarServer/branches/release/CalendarServer-2.4-dev/doc/Extensions/caldav-schedulingchanges.txt
___________________________________________________________________
Modified: svn:mergeinfo
   - /CalendarServer/branches/users/cdaboo/attendee-comments-2886/doc/Extensions/caldav-schedulingchanges-01.txt:2887-2910
/CalendarServer/branches/users/cdaboo/byebye-serviceslocator-2937/doc/Extensions/caldav-schedulingchanges-01.txt:2938-3097
/CalendarServer/branches/users/cdaboo/implicit-if-match-3306/doc/Extensions/caldav-schedulingchanges.txt:3307-3349
/CalendarServer/branches/users/cdaboo/implicitauto-2947/doc/Extensions/caldav-schedulingchanges-01.txt:2948-2989
/CalendarServer/branches/users/cdaboo/location-partial-accept-3573/doc/Extensions/caldav-schedulingchanges.txt:3574-3581
/CalendarServer/branches/users/sagen/resource-delegates-4038/doc/Extensions/caldav-schedulingchanges.txt:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/doc/Extensions/caldav-schedulingchanges.txt:4068-4075
/CalendarServer/trunk/doc/Extensions/caldav-schedulingchanges.txt:4439-4440,4448,4450,4464,4473-4475,4717,4758,4773
   + /CalendarServer/branches/users/cdaboo/attendee-comments-2886/doc/Extensions/caldav-schedulingchanges-01.txt:2887-2910
/CalendarServer/branches/users/cdaboo/byebye-serviceslocator-2937/doc/Extensions/caldav-schedulingchanges-01.txt:2938-3097
/CalendarServer/branches/users/cdaboo/implicit-if-match-3306/doc/Extensions/caldav-schedulingchanges.txt:3307-3349
/CalendarServer/branches/users/cdaboo/implicitauto-2947/doc/Extensions/caldav-schedulingchanges-01.txt:2948-2989
/CalendarServer/branches/users/cdaboo/location-partial-accept-3573/doc/Extensions/caldav-schedulingchanges.txt:3574-3581
/CalendarServer/branches/users/sagen/resource-delegates-4038/doc/Extensions/caldav-schedulingchanges.txt:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/doc/Extensions/caldav-schedulingchanges.txt:4068-4075
/CalendarServer/trunk/doc/Extensions/caldav-schedulingchanges.txt:4439-4440,4448,4450,4464,4473-4475,4717,4758,4773,4823-4824


Property changes on: CalendarServer/branches/release/CalendarServer-2.4-dev/doc/Extensions/caldav-schedulingchanges.xml
___________________________________________________________________
Modified: svn:mergeinfo
   - /CalendarServer/branches/users/cdaboo/attendee-comments-2886/doc/Extensions/caldav-schedulingchanges-01.xml:2887-2910
/CalendarServer/branches/users/cdaboo/byebye-serviceslocator-2937/doc/Extensions/caldav-schedulingchanges-01.xml:2938-3097
/CalendarServer/branches/users/cdaboo/implicit-if-match-3306/doc/Extensions/caldav-schedulingchanges.xml:3307-3349
/CalendarServer/branches/users/cdaboo/implicitauto-2947/doc/Extensions/caldav-schedulingchanges-01.xml:2948-2989
/CalendarServer/branches/users/cdaboo/location-partial-accept-3573/doc/Extensions/caldav-schedulingchanges.xml:3574-3581
/CalendarServer/branches/users/sagen/resource-delegates-4038/doc/Extensions/caldav-schedulingchanges.xml:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/doc/Extensions/caldav-schedulingchanges.xml:4068-4075
/CalendarServer/trunk/doc/Extensions/caldav-schedulingchanges.xml:4439-4440,4448,4450,4464,4473-4475,4717,4758,4773
   + /CalendarServer/branches/users/cdaboo/attendee-comments-2886/doc/Extensions/caldav-schedulingchanges-01.xml:2887-2910
/CalendarServer/branches/users/cdaboo/byebye-serviceslocator-2937/doc/Extensions/caldav-schedulingchanges-01.xml:2938-3097
/CalendarServer/branches/users/cdaboo/implicit-if-match-3306/doc/Extensions/caldav-schedulingchanges.xml:3307-3349
/CalendarServer/branches/users/cdaboo/implicitauto-2947/doc/Extensions/caldav-schedulingchanges-01.xml:2948-2989
/CalendarServer/branches/users/cdaboo/location-partial-accept-3573/doc/Extensions/caldav-schedulingchanges.xml:3574-3581
/CalendarServer/branches/users/sagen/resource-delegates-4038/doc/Extensions/caldav-schedulingchanges.xml:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/doc/Extensions/caldav-schedulingchanges.xml:4068-4075
/CalendarServer/trunk/doc/Extensions/caldav-schedulingchanges.xml:4439-4440,4448,4450,4464,4473-4475,4717,4758,4773,4823-4824

Modified: CalendarServer/branches/release/CalendarServer-2.4-dev/run
===================================================================
--- CalendarServer/branches/release/CalendarServer-2.4-dev/run	2009-12-06 06:27:08 UTC (rev 4829)
+++ CalendarServer/branches/release/CalendarServer-2.4-dev/run	2009-12-06 06:39:17 UTC (rev 4830)
@@ -727,7 +727,7 @@
 
 caldavtester="${top}/CalDAVTester";
 
-svn_get "CalDAVTester" "${caldavtester}" "${svn_uri_base}/CalDAVTester/trunk" 4783;
+svn_get "CalDAVTester" "${caldavtester}" "${svn_uri_base}/CalDAVTester/trunk" 4822;
 
 #
 # PyFlakes

Modified: CalendarServer/branches/release/CalendarServer-2.4-dev/twext/web2/channel/http.py
===================================================================
--- CalendarServer/branches/release/CalendarServer-2.4-dev/twext/web2/channel/http.py	2009-12-06 06:27:08 UTC (rev 4829)
+++ CalendarServer/branches/release/CalendarServer-2.4-dev/twext/web2/channel/http.py	2009-12-06 06:39:17 UTC (rev 4830)
@@ -160,6 +160,6 @@
         if self.logData is not None:
             doneTime = time.time()
             self.logData.response.append("\r\n\r\n<<<< Response complete at: %.3f (elapsed: %.1f ms)\r\n" % (doneTime, 1000 * (doneTime - self.startTime),))
-            accounting.emitAccounting("HTTP", "all", "".join(self.logData.request) + "".join(self.logData.response))
+            accounting.emitAccounting("HTTP", "", "".join(self.logData.request) + "".join(self.logData.response))
 
 HTTPChannel.chanRequestFactory = HTTPLoggingChannelRequest

Modified: CalendarServer/branches/release/CalendarServer-2.4-dev/twistedcaldav/accounting.py
===================================================================
--- CalendarServer/branches/release/CalendarServer-2.4-dev/twistedcaldav/accounting.py	2009-12-06 06:27:08 UTC (rev 4829)
+++ CalendarServer/branches/release/CalendarServer-2.4-dev/twistedcaldav/accounting.py	2009-12-06 06:39:17 UTC (rev 4830)
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2006-2007 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.
@@ -86,42 +86,51 @@
             principal.record.guid
         )
     else:
-        return
+        return None
 
     try:
         #
         # Obtain the accounting log file name
         #
         logRoot = config.AccountingLogRoot
-        logDirectory = os.path.join(
-            logRoot,
-            principalLogPath,
-            category
+        logDirectory = category
+        if principalLogPath:
+            logDirectory = os.path.join(
+                logDirectory,
+                principalLogPath,
+            )
+        logFilename = os.path.join(
+            logDirectory,
+            datetime.datetime.now().isoformat()
         )
-        logFilename = os.path.join(logDirectory, datetime.datetime.now().isoformat())
     
-        if not os.path.isdir(logDirectory):
-            os.makedirs(logDirectory)
+        if not os.path.isdir(os.path.join(logRoot, logDirectory)):
+            os.makedirs(os.path.join(logRoot, logDirectory))
             logFilename = "%s-01" % (logFilename,)
         else:
             index = 1
             while True:
                 path = "%s-%02d" % (logFilename, index)
-                if not os.path.isfile(path):
+                if not os.path.isfile(os.path.join(logRoot, path)):
                     logFilename = path
                     break
                 if index == 1000:
                     log.error("Too many %s accounting files for %s" % (category, principal))
-                    return
+                    return None
+                index += 1
     
         #
         # Now write out the data to the log file
         #
-        logFile = open(logFilename, "a")
+        logFile = open(os.path.join(logRoot, logFilename), "a")
         try:
             logFile.write(data)
         finally:
             logFile.close()
+            
+        return logFilename
+
     except OSError, e:
         # No failures in accounting should propagate out
         log.error("Failed to write accounting data due to: %s" % (str(e),))
+        return None

Modified: CalendarServer/branches/release/CalendarServer-2.4-dev/twistedcaldav/scheduling/icaldiff.py
===================================================================
--- CalendarServer/branches/release/CalendarServer-2.4-dev/twistedcaldav/scheduling/icaldiff.py	2009-12-06 06:27:08 UTC (rev 4829)
+++ CalendarServer/branches/release/CalendarServer-2.4-dev/twistedcaldav/scheduling/icaldiff.py	2009-12-06 06:39:17 UTC (rev 4830)
@@ -21,6 +21,7 @@
 from twistedcaldav.log import Logger
 from twistedcaldav.scheduling.cuaddress import normalizeCUAddr
 from twistedcaldav.scheduling.itip import iTipGenerator
+from twistedcaldav import accounting
 
 from difflib import unified_diff
 
@@ -36,17 +37,17 @@
 
 class iCalDiff(object):
     
-    def __init__(self, calendar1, calendar2, smart_merge):
+    def __init__(self, oldcalendar, newcalendar, smart_merge):
         """
         
-        @param calendar1:
-        @type calendar1:
-        @param calendar2:
-        @type calendar2:
+        @param oldcalendar:
+        @type oldcalendar:
+        @param newcalendar:
+        @type newcalendar:
         """
         
-        self.calendar1 = calendar1
-        self.calendar2 = calendar2
+        self.oldcalendar = oldcalendar
+        self.newcalendar = newcalendar
         self.smart_merge = smart_merge
     
     def organizerDiff(self):
@@ -75,34 +76,32 @@
             return calendar
         
         # Normalize components for comparison
-        self.calendar1 = duplicateAndNormalize(self.calendar1)
-        self.calendar2 = duplicateAndNormalize(self.calendar2)
+        oldcalendar_norm = duplicateAndNormalize(self.oldcalendar)
+        newcalendar_norm = duplicateAndNormalize(self.newcalendar)
 
-        result = self.calendar1 == self.calendar2
-        if not result:
-            self._logDiffError("organizerDiff: Mismatched calendar objects")
+        result = oldcalendar_norm == newcalendar_norm
         return result
 
     def _organizerMerge(self):
         """
-        Merge changes to ATTENDEE properties in calendar1 into calendar2.
+        Merge changes to ATTENDEE properties in oldcalendar into newcalendar.
         """
-        organizer = normalizeCUAddr(self.calendar2.masterComponent().propertyValue("ORGANIZER"))
+        organizer = normalizeCUAddr(self.newcalendar.masterComponent().propertyValue("ORGANIZER"))
         self._doSmartMerge(organizer, True)
 
     def _doSmartMerge(self, ignore_attendee, is_organizer):
         """
-        Merge changes to ATTENDEE properties in calendar1 into calendar2.
+        Merge changes to ATTENDEE properties in oldcalendar into newcalendar.
         """
         
-        old_master = self.calendar1.masterComponent()
-        new_master = self.calendar2.masterComponent()
+        old_master = self.oldcalendar.masterComponent()
+        new_master = self.newcalendar.masterComponent()
         
         # Do master merge first
         self._tryComponentMerge(old_master, new_master, ignore_attendee, is_organizer)
 
         # New check the matching components
-        for old_component in self.calendar1.subcomponents():
+        for old_component in self.oldcalendar.subcomponents():
             
             # Make sure we have an appropriate component
             if old_component.name() == "VTIMEZONE":
@@ -112,17 +111,17 @@
                 continue
 
             # Find matching component in new calendar
-            new_component = self.calendar2.overriddenComponent(rid)
+            new_component = self.newcalendar.overriddenComponent(rid)
             if new_component is None:
                 # If the old component was cancelled ignore when an attendee
                 if not is_organizer and old_component.propertyValue("STATUS") == "CANCELLED":
                     continue
                 
                 # Determine whether the instance is still valid in the new calendar
-                new_component = self.calendar2.deriveInstance(rid)
+                new_component = self.newcalendar.deriveInstance(rid)
                 if new_component:
                     # Derive a new instance from the new calendar and transfer attendee status
-                    self.calendar2.addComponent(new_component)
+                    self.newcalendar.addComponent(new_component)
                     self._tryComponentMerge(old_component, new_component, ignore_attendee, is_organizer)
                 else:
                     # Ignore the old instance as it no longer exists
@@ -131,7 +130,7 @@
                 self._tryComponentMerge(old_component, new_component, ignore_attendee, is_organizer)
 
         # Check the new instances not in the old calendar
-        for new_component in self.calendar2.subcomponents():
+        for new_component in self.newcalendar.subcomponents():
             
             # Make sure we have an appropriate component
             if new_component.name() == "VTIMEZONE":
@@ -141,16 +140,16 @@
                 continue
 
             # Find matching component in old calendar
-            old_component = self.calendar1.overriddenComponent(rid)
+            old_component = self.oldcalendar.overriddenComponent(rid)
             if old_component is None:
                 # If the new component is cancelled ignore when an attendee
                 if not is_organizer and new_component.propertyValue("STATUS") == "CANCELLED":
                     continue
                 
                 # Try to derive a new instance in the client and transfer attendee status
-                old_component = self.calendar1.deriveInstance(rid)
+                old_component = self.oldcalendar.deriveInstance(rid)
                 if old_component:
-                    self.calendar1.addComponent(old_component)
+                    self.oldcalendar.addComponent(old_component)
                     self._tryComponentMerge(old_component, new_component, ignore_attendee, is_organizer)
                 else:
                     # Ignore as we have no state for the new instance
@@ -248,11 +247,11 @@
 
         if config.MaxInstancesForRRULE != 0:
             try:
-                self.calendar1.truncateRecurrence(config.MaxInstancesForRRULE)
+                self.oldcalendar.truncateRecurrence(config.MaxInstancesForRRULE)
             except (ValueError, TypeError), ex:
                 log.err("Cannot truncate calendar resource: %s" % (ex,))
 
-        self.newCalendar = self.calendar1.duplicate()
+        self.newCalendar = self.oldcalendar.duplicate()
         self.newMaster = self.newCalendar.masterComponent()
 
         changeCausesReply = False
@@ -285,60 +284,61 @@
                
             return exdates, map, master
         
-        exdates1, map1, master1 = mapComponents(self.calendar1)
-        set1 = set(map1.keys())
-        exdates2, map2, master2 = mapComponents(self.calendar2)
-        set2 = set(map2.keys())
+        exdatesold, mapold, masterold = mapComponents(self.oldcalendar)
+        setold = set(mapold.keys())
+        exdatesnew, mapnew, masternew = mapComponents(self.newcalendar)
+        setnew = set(mapnew.keys())
 
         # Handle case where iCal breaks events without a master component
-        if master2 is not None and master1 is None:
-            master2Start = master2.getStartDateUTC()
-            key2 = (master2.name(), master2.propertyValue("UID"), master2Start)
-            if key2 not in set1:
+        if masternew is not None and masterold is None:
+            masternewStart = masternew.getStartDateUTC()
+            keynew = (masternew.name(), masternew.propertyValue("UID"), masternewStart)
+            if keynew not in setold:
                 # The DTSTART in the fake master does not match a RECURRENCE-ID in the real data.
                 # We have to do a brute force search for the component that matches based on DTSTART
-                for component1 in self.calendar1.subcomponents():
-                    if component1.name() == "VTIMEZONE":
+                for componentold in self.oldcalendar.subcomponents():
+                    if componentold.name() == "VTIMEZONE":
                         continue
-                    if master2Start == component1.getStartDateUTC():
+                    if masternewStart == componentold.getStartDateUTC():
                         break
                 else:
                     # Nothing matches - this has to be treated as an error
-                    log.debug("attendeeMerge: Unable to match fake master component: %s" % (key2,))
+                    self._logDiffError("attendeeMerge: Unable to match fake master component: %s" % (keynew,))
                     return False, False, (), None
             else:
-                component1 = self.calendar1.overriddenComponent(master2Start)
+                componentold = self.oldcalendar.overriddenComponent(masternewStart)
             
             # Take the recurrence ID from component1 and fix map2/set2
-            key2 = (master2.name(), master2.propertyValue("UID"), None)
-            component2 = map2[key2]
-            del map2[key2]
+            keynew = (masternew.name(), masternew.propertyValue("UID"), None)
+            componentnew = mapnew[keynew]
+            del mapnew[keynew]
             
-            rid1 = component1.getRecurrenceIDUTC()
-            newkey2 = (master2.name(), master2.propertyValue("UID"), rid1)
-            map2[newkey2] = component2
-            set2.remove(key2)
-            set2.add(newkey2)
+            ridold = componentold.getRecurrenceIDUTC()
+            newkeynew = (masternew.name(), masternew.propertyValue("UID"), ridold)
+            mapnew[newkeynew] = componentnew
+            setnew.remove(keynew)
+            setnew.add(newkeynew)
     
-        # All the components in calendar1 must be in calendar2 unless they are CANCELLED
-        result = set1 - set2
-        for key in result:
+        # All the components in oldcalendar must be in newcalendar unless they are CANCELLED
+        for key in setold - setnew:
             _ignore_name, _ignore_uid, rid = key
-            component = map1[key]
+            component = mapold[key]
             if component.propertyValue("STATUS") != "CANCELLED":
                 # Attendee may decline by EXDATE'ing an instance - we need to handle that
-                if exdates2 is None or rid in exdates2:
+                if exdatesnew is None or rid in exdatesnew:
                     # Mark Attendee as DECLINED in the server instance
                     if self._attendeeDecline(self.newCalendar.overriddenComponent(rid)):
                         changeCausesReply = True
                         changedRids.append(toString(rid) if rid else "")
                 else:
-                    log.debug("attendeeMerge: Missing uncancelled component from first calendar: %s" % (key,))
-                    return False, False, (), None
+                    # We used to generate a 403 here - but instead we now ignore this error and let the server data
+                    # override the client
+                    self._logDiffError("attendeeMerge: Missing uncancelled component from first calendar: %s" % (key,))
             else: 
-                if exdates2 is not None and rid not in exdates2:
-                    log.debug("attendeeMerge: Missing EXDATE for cancelled components from first calendar: %s" % (key,))
-                    return False, False, (), None
+                if exdatesnew is not None and rid not in exdatesnew:
+                    # We used to generate a 403 here - but instead we now ignore this error and let the server data
+                    # override the client
+                    self._logDiffError("attendeeMerge: Missing EXDATE for cancelled components from first calendar: %s" % (key,))
                 else:
                     # Remove the CANCELLED component from the new calendar and add an EXDATE
                     overridden = self.newCalendar.overriddenComponent(rid)
@@ -346,52 +346,63 @@
                     if self.newMaster:
                         self.newMaster.addProperty(Property("EXDATE", [rid,]))
         
-        # Derive a new component in the new calendar for each new one in set2
-        for key in set2 - set1:
+        # Derive a new component in the new calendar for each new one in setnew
+        for key in setnew - setold:
             
             # First check if the attendee's copy is cancelled and properly EXDATE'd
             # and skip it if so.
             _ignore_name, _ignore_uid, rid = key
-            component2 = map2[key]
-            if component2.propertyValue("STATUS") == "CANCELLED":
-                if exdates1 is None or rid not in exdates1:
-                    log.debug("attendeeMerge: Cancelled component not found in first calendar (or no EXDATE): %s" % (key,))
-                    return False, False, (), None
+            componentnew = mapnew[key]
+            if componentnew.propertyValue("STATUS") == "CANCELLED":
+                if exdatesold is None or rid not in exdatesold:
+                    # We used to generate a 403 here - but instead we now ignore this error and let the server data
+                    # override the client
+                    self._logDiffError("attendeeMerge: Cancelled component not found in first calendar (or no EXDATE): %s" % (key,))
+                    setnew.remove(key)
                 else:
                     # Derive new component with STATUS:CANCELLED and remove EXDATE
                     newOverride = self.newCalendar.deriveInstance(rid, allowCancelled=True)
                     if newOverride is None:
-                        log.debug("attendeeMerge: Could not derive instance for cancelled component: %s" % (key,))
-                        return False, False, (), None
-                    self.newCalendar.addComponent(newOverride)
+                        # We used to generate a 403 here - but instead we now ignore this error and let the server data
+                        # override the client
+                        self._logDiffError("attendeeMerge: Could not derive instance for cancelled component: %s" % (key,))
+                        setnew.remove(key)
+                    else:
+                        self.newCalendar.addComponent(newOverride)
             else:
                 # Derive new component
                 newOverride = self.newCalendar.deriveInstance(rid)
                 if newOverride is None:
-                    log.debug("attendeeMerge: Could not derive instance for uncancelled component: %s" % (key,))
-                    return False, False, (), None
-                self.newCalendar.addComponent(newOverride)
+                    # We used to generate a 403 here - but instead we now ignore this error and let the server data
+                    # override the client
+                    self._logDiffError("attendeeMerge: Could not derive instance for uncancelled component: %s" % (key,))
+                    setnew.remove(key)
+                else:
+                    self.newCalendar.addComponent(newOverride)
 
         # So now newCalendar has all the same components as set2. Check changes and do transfers.
         
         # Make sure the same VCALENDAR properties match
-        if not self._checkVCALENDARProperties(self.newCalendar, self.calendar2):
+        if not self._checkVCALENDARProperties(self.newCalendar, self.newcalendar):
+            # We used to generate a 403 here - but instead we now ignore this error and let the server data
+            # override the client
             self._logDiffError("attendeeMerge: VCALENDAR properties do not match")
-            return False, False, (), None
 
         # Now we transfer per-Attendee
-        # data from calendar2 into newCalendar to sync up changes, whilst verifying that other
+        # data from newcalendar into newCalendar to sync up changes, whilst verifying that other
         # key properties are unchanged
         declines = []
-        for key in set2:
+        for key in setnew:
             _ignore_name, _ignore_uid, rid = key
             serverData = self.newCalendar.overriddenComponent(rid)
-            clientData = map2[key]
+            clientData = mapnew[key]
             
             allowed, reply = self._transferAttendeeData(serverData, clientData, declines)
             if not allowed:
+                # We used to generate a 403 here - but instead we now ignore this error and let the server data
+                # override the client
                 self._logDiffError("attendeeMerge: Mismatched calendar objects")
-                return False, False, (), None
+                #return False, False, (), None
             changeCausesReply |= reply
             if reply:
                 changedRids.append(toString(rid) if rid else "")
@@ -407,7 +418,7 @@
                         changeCausesReply = True
                         changedRids.append(toString(decline) if decline else "")
                 else:
-                    log.debug("Unable to override and instance to mark as DECLINED: %s" % (decline,))
+                    self._logDiffError("attendeeMerge: Unable to override an instance to mark as DECLINED: %s" % (decline,))
                     return False, False, (), None
 
         return True, changeCausesReply, changedRids, self.newCalendar
@@ -430,9 +441,9 @@
 
     def _transferAttendeeData(self, serverComponent, clientComponent, declines):
         
-        # First check validity of date-time related properties
-        if not self._checkInvalidChanges(serverComponent, clientComponent, declines):
-            return False, False
+        # We are skipping this check now - instead we let the server data override the broken client data
+        # First check validity of date-time related properties and get removed components which are declines
+        self._checkInvalidChanges(serverComponent, clientComponent, declines)
         
         # Now look for items to transfer from one to the other.
         # We care about the ATTENDEE's PARTSTAT, TRANSP, VALARMS, X-APPLE-NEEDS-REPLY,
@@ -462,9 +473,8 @@
         self._transferProperty("LAST-MODIFIED", serverComponent, clientComponent)
         self._transferProperty("X-APPLE-NEEDS-REPLY", serverComponent, clientComponent)
         
-        # Dropbox
-        if not self._transferDropBoxData(serverComponent, clientComponent):
-            return False, False
+        # Dropbox - this now never returns false
+        self._transferDropBoxData(serverComponent, clientComponent)
 
         # Handle VALARMs
         serverComponent.removeAlarms()
@@ -483,14 +493,14 @@
         if not clientDropbox:
             return True
         elif not serverDropbox:
-            # Attendee not allowed to add a dropbox
-            log.debug("Attendee not allowed to add dropbox: %s" % (clientDropbox,))
-            return False
+            # Attendee not allowed to add a dropbox - ignore this
+            self._logDiffError("Attendee not allowed to add dropbox: %s" % (clientDropbox,))
+            return True
         else:
-            # Values must be the same
+            # Values must be the same - ignore this
             if serverDropbox != clientDropbox:
-                log.debug("Attendee not allowed to change dropbox from: %s to: %s" % (serverDropbox, clientDropbox,))
-                return False
+                self._logDiffError("Attendee not allowed to change dropbox from: %s to: %s" % (serverDropbox, clientDropbox,))
+                return True
 
             # Remove existing ATTACH's from server
             for attachment in tuple(serverComponent.properties("ATTACH")):
@@ -622,39 +632,41 @@
         
         rids = {}
 
-        map1 = mapComponents(self.calendar1)
-        set1 = set(map1.keys())
-        map2 = mapComponents(self.calendar2)
-        set2 = set(map2.keys())
+        oldmap = mapComponents(self.oldcalendar)
+        oldset = set(oldmap.keys())
+        newmap = mapComponents(self.newcalendar)
+        newset = set(newmap.keys())
 
-        # Now verify that each component in set1 matches what is in set2
-        for key in (set1 & set2):
-            component1 = map1[key]
-            component2 = map2[key]
+        # Now verify that each component in oldset matches what is in newset
+        for key in (oldset & newset):
+            component1 = oldmap[key]
+            component2 = newmap[key]
             self._diffComponents(component1, component2, rids)
         
-        # Now verify that each additional component in set1 matches a derived component in set2
-        for key in set1 - set2:
-            component1 = map1[key]
-            component2 = self.calendar2.deriveInstance(key[2])
-            if component2 is None:
+        # Now verify that each additional component in oldset matches a derived component in newset
+        for key in oldset - newset:
+            oldcomponent = oldmap[key]
+            newcomponent = self.newcalendar.deriveInstance(key[2])
+            if newcomponent is None:
                 continue
-            self._diffComponents(component1, component2, rids)
+            self._diffComponents(oldcomponent, newcomponent, rids)
         
-        # Now verify that each additional component in set1 matches a derived component in set2
-        for key in set2 - set1:
-            component1 = self.calendar1.deriveInstance(key[2])
-            if component1 is None:
+        # Now verify that each additional component in oldset matches a derived component in newset
+        for key in newset - oldset:
+            oldcomponent = self.oldcalendar.deriveInstance(key[2])
+            if oldcomponent is None:
                 continue
-            component2 = map2[key]
-            self._diffComponents(component1, component2, rids)
+            newcomponent = newmap[key]
+            self._diffComponents(oldcomponent, newcomponent, rids)
         
         return rids
 
-    def _attendeeDuplicateAndNormalize(self, comp):
+    def _componentDuplicateAndNormalize(self, comp):
         comp = comp.duplicate()
         comp.normalizePropertyValueLists("EXDATE")
         comp.removePropertyParameters("ORGANIZER", ("SCHEDULE-STATUS",))
+        comp.removePropertyParameters("ATTENDEE", ("SCHEDULE-STATUS", "SCHEDULE-FORCE-SEND",))
+        comp.removeAlarms()
         comp.normalizeAll()
         comp.normalizeAttachments()
         iTipGenerator.prepareSchedulingMessage(comp, reply=True)
@@ -669,8 +681,8 @@
             return
         
         # Duplicate then normalize for comparison
-        comp1 = self._attendeeDuplicateAndNormalize(comp1)
-        comp2 = self._attendeeDuplicateAndNormalize(comp2)
+        comp1 = self._componentDuplicateAndNormalize(comp1)
+        comp2 = self._componentDuplicateAndNormalize(comp2)
 
         # Diff all the properties
         comp1.transformAllFromNative()
@@ -710,10 +722,30 @@
 
     def _logDiffError(self, title):
 
-        diff = "\n".join(unified_diff(
-            str(self.calendar1).split("\n"),
-            str(self.calendar2).split("\n"),
+        strcal1 = str(self.oldcalendar)
+        strcal2 = str(self.newcalendar)
+        strdiff = "\n".join(unified_diff(
+            strcal1.split("\n"),
+            strcal2.split("\n"),
             fromfile='Existing Calendar Object',
             tofile='New Calendar Object',
         ))
-        log.debug("%s:\n%s" % (title, diff,))
+        
+        logstr = """%s
+
+------ Existing Calendar Data ------
+%s
+------ New Calendar Data ------
+%s
+------ Diff ------
+%s
+""" % (title, strcal1, strcal2, strdiff,)
+
+        loggedUID = self.oldcalendar.resourceUID()
+        if loggedUID:
+            loggedUID = loggedUID.encode("base64")[:-1]
+        else:
+            loggedUID = "Unknown"
+        loggedName = accounting.emitAccounting("Implicit Errors", loggedUID, logstr)
+        if loggedName:
+            log.err("Generating Implicit Error accounting at path: %s" % (loggedName,))

Modified: CalendarServer/branches/release/CalendarServer-2.4-dev/twistedcaldav/scheduling/itip.py
===================================================================
--- CalendarServer/branches/release/CalendarServer-2.4-dev/twistedcaldav/scheduling/itip.py	2009-12-06 06:27:08 UTC (rev 4829)
+++ CalendarServer/branches/release/CalendarServer-2.4-dev/twistedcaldav/scheduling/itip.py	2009-12-06 06:39:17 UTC (rev 4830)
@@ -99,10 +99,13 @@
             master_valarms = [comp for comp in current_master.subcomponents() if comp.name() == "VALARM"]
             private_comments = current_master.properties("X-CALENDARSERVER-PRIVATE-COMMENT")
             transps = current_master.properties("TRANSP")
+            organizer = current_master.getProperty("ORGANIZER")
+            organizer_schedule_status = organizer.params().get("SCHEDULE-STATUS", None) if organizer else None
         else:
             master_valarms = ()
             private_comments = ()
             transps = ()
+            organizer_schedule_status = None
 
         if itip_message.masterComponent() is not None:
             
@@ -117,11 +120,15 @@
                 master_component.addProperty(comment)
             for transp in transps:
                 master_component.replaceProperty(transp)
+            if organizer_schedule_status: 
+                organizer = master_component.getProperty("ORGANIZER")
+                if organizer:
+                    organizer.params()["SCHEDULE-STATUS"] = organizer_schedule_status
                 
             # Now try to match recurrences
             for component in new_calendar.subcomponents():
                 if component.name() != "VTIMEZONE" and component.getRecurrenceIDUTC() is not None:
-                    iTipProcessing.transferItems(calendar, master_valarms, private_comments, transps, component)
+                    iTipProcessing.transferItems(calendar, master_valarms, private_comments, transps, organizer_schedule_status, component)
             
             # Now try to match recurrences
             for component in calendar.subcomponents():
@@ -132,7 +139,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, new_component)
+                            iTipProcessing.transferItems(calendar, master_valarms, private_comments, transps, organizer_schedule_status, new_component)
             
             # Replace the entire object
             return new_calendar, rids
@@ -149,7 +156,7 @@
                         calendar.addComponent(component)
                 else:
                     component = component.duplicate()
-                    iTipProcessing.transferItems(calendar, master_valarms, private_comments, transps, component, remove_matched=True)
+                    iTipProcessing.transferItems(calendar, master_valarms, private_comments, transps, organizer_schedule_status, component, remove_matched=True)
                     calendar.addComponent(component)
                     if recipient and not autoprocessing:
                         iTipProcessing.fixForiCal3((component,), recipient, config.Scheduling.CalDAV.OldDraftCompatibility)
@@ -446,7 +453,7 @@
         return attendee.value(), partstat_changed, private_comment_changed
 
     @staticmethod
-    def transferItems(from_calendar, master_valarms, private_comments, transps, to_component, remove_matched=False):
+    def transferItems(from_calendar, master_valarms, private_comments, transps, organizer_schedule_status, to_component, remove_matched=False):
 
         rid = to_component.getRecurrenceIDUTC()
 
@@ -458,6 +465,13 @@
             [to_component.addProperty(prop) for prop in matched.properties("X-CALENDARSERVER-ATTENDEE-COMMENT")]
             [to_component.replaceProperty(prop) for prop in matched.properties("TRANSP")]
 
+            organizer = matched.getProperty("ORGANIZER")
+            organizer_schedule_status = organizer.params().get("SCHEDULE-STATUS", None) if organizer else None
+            if organizer_schedule_status: 
+                organizer = to_component.getProperty("ORGANIZER")
+                if organizer:
+                    organizer.params()["SCHEDULE-STATUS"] = organizer_schedule_status
+
             # Remove the old one
             if remove_matched:
                 from_calendar.removeComponent(matched)
@@ -468,6 +482,10 @@
             [to_component.addComponent(alarm) for alarm in master_valarms]
             [to_component.addProperty(comment) for comment in private_comments]
             [to_component.replaceProperty(transp) for transp in transps]
+            if organizer_schedule_status: 
+                organizer = to_component.getProperty("ORGANIZER")
+                if organizer:
+                    organizer.params()["SCHEDULE-STATUS"] = organizer_schedule_status
     
     @staticmethod
     def fixForiCal3(components, recipient, compatibilityMode):

Modified: CalendarServer/branches/release/CalendarServer-2.4-dev/twistedcaldav/scheduling/test/test_icaldiff.py
===================================================================
--- CalendarServer/branches/release/CalendarServer-2.4-dev/twistedcaldav/scheduling/test/test_icaldiff.py	2009-12-06 06:27:08 UTC (rev 4829)
+++ CalendarServer/branches/release/CalendarServer-2.4-dev/twistedcaldav/scheduling/test/test_icaldiff.py	2009-12-06 06:39:17 UTC (rev 4830)
@@ -594,7 +594,19 @@
 END:VCALENDAR
 """,
                 "mailto:user2 at example.com",
-                (False, False, (), None)
+                (True, False, (), """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+END:VEVENT
+END:VCALENDAR
+""")
             ),
             (
                 "#1.4 Simple component, valarm change",
@@ -753,7 +765,24 @@
 END:VCALENDAR
 """,
                 "mailto:user2 at example.com",
-                (False, False, (), None)
+                (True, False, (), """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:Test for Attendee
+TRIGGER;RELATED=START:-PT10M
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+""")
             ),
             (
                 "#1.7 Simple component, vtimezone no change",
@@ -917,7 +946,37 @@
 END:VCALENDAR
 """,
                 "mailto:user2 at example.com",
-                (False, False, (), None)
+                (True, False, (), """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VTIMEZONE
+TZID:US-Eastern
+LAST-MODIFIED:20040110T032845Z
+BEGIN:STANDARD
+DTSTART:19901026T060000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:19900404T010000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+END:VTIMEZONE
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART;TZID=US-Eastern:20080601T120000
+DTEND;TZID=US-Eastern:20080601T130000
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+END:VEVENT
+END:VCALENDAR
+""")
             ),
             (
                 "#1.9 Simple component, vtimezone substitute",
@@ -1323,7 +1382,28 @@
 END:VCALENDAR
 """,
                 "mailto:user2 at example.com",
-                (False, False, (), None)
+                (True, False, (), """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+RRULE:COUNT=400;FREQ=DAILY
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080602T120000Z
+DTSTART:20080602T123000Z
+DTEND:20080602T130000Z
+ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE:mailto:user2 at example.com
+ORGANIZER:mailto:user1 at example.com
+END:VEVENT
+END:VCALENDAR
+""")
             ),
             (
                 "#1.4 Complex component, additional override no change ok",
@@ -1557,7 +1637,37 @@
 END:VCALENDAR
 """,
                 "mailto:user2 at example.com",
-                (False, False, (), None)
+                (True, False, (), """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+RRULE:COUNT=400;FREQ=DAILY
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080602T120000Z
+DTSTART:20080602T123000Z
+DTEND:20080602T130000Z
+ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE:mailto:user2 at example.com
+ORGANIZER:mailto:user1 at example.com
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080604T120000Z
+DTSTART:20080604T120000Z
+DTEND:20080604T130000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+END:VEVENT
+END:VCALENDAR
+""")
             ),
         )
 
@@ -2195,7 +2305,20 @@
 END:VCALENDAR
 """,
                 "mailto:user2 at example.com",
-                (False, False, (), None,)
+                (True, False, (), """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080604T120000Z
+DTSTART:20080604T130000Z
+DTEND:20080604T140000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+END:VEVENT
+END:VCALENDAR
+""",)
             ),
             (
                 "#1.6 Add uncancelled component, no master",
@@ -2237,7 +2360,20 @@
 END:VCALENDAR
 """,
                 "mailto:user2 at example.com",
-                (False, False, (), None,)
+                (True, False, (), """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080604T120000Z
+DTSTART:20080604T130000Z
+DTEND:20080604T140000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+END:VEVENT
+END:VCALENDAR
+""",)
             ),
         )
 
@@ -2339,7 +2475,19 @@
 END:VCALENDAR
 """,
                 "mailto:user2 at example.com",
-                (False, False, (), None,)
+                (True, False, (), """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+END:VEVENT
+END:VCALENDAR
+""",)
             ),
             (
                 "#1.3 Different dropbox",
@@ -2378,7 +2526,23 @@
 END:VCALENDAR
 """,
                 "mailto:user2 at example.com",
-                (False, False, (), None,)
+                (True, False, (), """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ATTACH;VALUE=URI:http://localhost/calendars/users/dropbox/6073432E-644B-49
+ 65-B6F7-C3F08E70BBF9.dropbox/caldavd.plist
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+X-APPLE-DROPBOX:/calendars/users/dropbox/6073432E-644B-4965-B6F7-C3F08E70B
+ BF9.dropbox
+END:VEVENT
+END:VCALENDAR
+""",)
             ),
             (
                 "#1.4 Change dropbox - remove ATTACH",
@@ -2627,7 +2791,20 @@
 END:VCALENDAR
 """,
                 "mailto:user2 at example.com",
-                (False, False, (), None,)
+                (True, True, ('20080601T120000Z',), """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080601T120000Z
+DTSTART:20080601T130000Z
+DTEND:20080601T140000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+END:VEVENT
+END:VCALENDAR
+""",)
             ),
             (
                 "#2.1 Two overridden components, partstat change - ok",
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20091205/f59a0b31/attachment-0001.html>


More information about the calendarserver-changes mailing list