[CalendarServer-changes] [9216] CalendarServer/trunk/twistedcaldav

source_changes at macosforge.org source_changes at macosforge.org
Tue May 1 08:24:24 PDT 2012


Revision: 9216
          http://trac.macosforge.org/projects/calendarserver/changeset/9216
Author:   cdaboo at apple.com
Date:     2012-05-01 08:24:24 -0700 (Tue, 01 May 2012)
Log Message:
-----------
Don't allow organizer to PUT a lower SEQUENCE number.

Modified Paths:
--------------
    CalendarServer/trunk/twistedcaldav/ical.py
    CalendarServer/trunk/twistedcaldav/scheduling/implicit.py
    CalendarServer/trunk/twistedcaldav/test/test_icalendar.py

Modified: CalendarServer/trunk/twistedcaldav/ical.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/ical.py	2012-05-01 15:23:39 UTC (rev 9215)
+++ CalendarServer/trunk/twistedcaldav/ical.py	2012-05-01 15:24:24 UTC (rev 9216)
@@ -2405,6 +2405,28 @@
         
         self.replacePropertyInAllComponents(Property("DTSTAMP", PyCalendarDateTime.getNowUTC()))
             
+    def sequenceInSync(self, oldcalendar):
+        """
+        Make sure SEQUENCE does not decrease in any components.
+        """
+        
+        
+        def maxSequence(calendar):
+            seqs = calendar.getAllPropertiesInAnyComponent("SEQUENCE", depth=1)
+            return max(seqs, key=lambda x:x.value()).value() if seqs else 0
+
+        def minSequence(calendar):
+            seqs = calendar.getAllPropertiesInAnyComponent("SEQUENCE", depth=1)
+            return min(seqs, key=lambda x:x.value()).value() if seqs else 0
+
+        # Determine value to bump to from old calendar (if exists) or self
+        oldseq = maxSequence(oldcalendar)
+        currentseq = minSequence(self)
+            
+        # Sync all components
+        if oldseq and currentseq < oldseq:
+            self.replacePropertyInAllComponents(Property("SEQUENCE", oldseq))
+            
     def normalizeAll(self):
         
         # Normalize all properties

Modified: CalendarServer/trunk/twistedcaldav/scheduling/implicit.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/scheduling/implicit.py	2012-05-01 15:23:39 UTC (rev 9215)
+++ CalendarServer/trunk/twistedcaldav/scheduling/implicit.py	2012-05-01 15:24:24 UTC (rev 9216)
@@ -532,6 +532,10 @@
             self.oldAttendeesByInstance = self.oldcalendar.getAttendeesByInstance(True, onlyScheduleAgentServer=True)
             self.coerceAttendeesPartstatOnModify()
             
+            # Don't allow any SEQUENCE to decrease
+            if self.oldcalendar:
+                self.calendar.sequenceInSync(self.oldcalendar)
+
             # Significant change
             no_change, self.changed_rids, self.needs_action_rids, reinvites, recurrence_reschedule = self.isOrganizerChangeInsignificant()
             if no_change:

Modified: CalendarServer/trunk/twistedcaldav/test/test_icalendar.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_icalendar.py	2012-05-01 15:23:39 UTC (rev 9215)
+++ CalendarServer/trunk/twistedcaldav/test/test_icalendar.py	2012-05-01 15:24:24 UTC (rev 9216)
@@ -5617,6 +5617,263 @@
             self.assertEqual(len(dtstamps1 & dtstamps2), 0, "Failed comparison: %s\n%s" % (title, diff,))
 
 
+    def test_sequenceInSync(self):
+        """
+        Test Component.sequenceInSync to make sure it bumps SEQUENCE when needed.
+        """
+
+        data = (
+            (
+                "Simple no sequence, no sequence change",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+DTSTAMP:20080601T120000Z
+SUMMARY:Test
+END:VEVENT
+END:VCALENDAR
+""",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+DTSTAMP:20080601T120000Z
+SUMMARY:Test
+END:VEVENT
+END:VCALENDAR
+""",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+DTSTAMP:20080601T120000Z
+SUMMARY:Test
+END:VEVENT
+END:VCALENDAR
+""",
+            ),
+            (
+                "Simple sequence, no sequence change",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+DTSTAMP:20080601T120000Z
+SUMMARY:Test
+SEQUENCE:1
+END:VEVENT
+END:VCALENDAR
+""",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+DTSTAMP:20080601T120000Z
+SUMMARY:Test
+SEQUENCE:1
+END:VEVENT
+END:VCALENDAR
+""",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+DTSTAMP:20080601T120000Z
+SUMMARY:Test
+SEQUENCE:1
+END:VEVENT
+END:VCALENDAR
+""",
+            ),
+            (
+                "Simple no sequence, sequence change up",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+DTSTAMP:20080601T120000Z
+SUMMARY:Test
+END:VEVENT
+END:VCALENDAR
+""",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+DTSTAMP:20080601T120000Z
+SUMMARY:Test
+SEQUENCE:1
+END:VEVENT
+END:VCALENDAR
+""",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+DTSTAMP:20080601T120000Z
+SUMMARY:Test
+SEQUENCE:1
+END:VEVENT
+END:VCALENDAR
+""",
+            ),
+            (
+                "Simple sequence, sequence change down",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+DTSTAMP:20080601T120000Z
+SUMMARY:Test
+SEQUENCE:2
+END:VEVENT
+END:VCALENDAR
+""",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+DTSTAMP:20080601T120000Z
+SUMMARY:Test
+SEQUENCE:1
+END:VEVENT
+END:VCALENDAR
+""",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+DTSTAMP:20080601T120000Z
+SUMMARY:Test
+SEQUENCE:2
+END:VEVENT
+END:VCALENDAR
+""",
+            ),
+            (
+                "Recurrence sequence, sequence change down",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+DTSTAMP:20080601T120000Z
+RRULE:FREQ=DAILY;COUNT=10
+SUMMARY:Test
+SEQUENCE:2
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080602T120000Z
+DTSTART:20080602T120000Z
+DTEND:20080602T130000Z
+DTSTAMP:20080601T120000Z
+SUMMARY:Test
+SEQUENCE:2
+END:VEVENT
+END:VCALENDAR
+""",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+DTSTAMP:20080601T120000Z
+RRULE:FREQ=DAILY;COUNT=10
+SUMMARY:Test
+SEQUENCE:1
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080602T120000Z
+DTSTART:20080602T120000Z
+DTEND:20080602T130000Z
+DTSTAMP:20080601T120000Z
+SUMMARY:Test
+SEQUENCE:2
+END:VEVENT
+END:VCALENDAR
+""",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+DTSTAMP:20080601T120000Z
+RRULE:FREQ=DAILY;COUNT=10
+SUMMARY:Test
+SEQUENCE:2
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080602T120000Z
+DTSTART:20080602T120000Z
+DTEND:20080602T130000Z
+DTSTAMP:20080601T120000Z
+SUMMARY:Test
+SEQUENCE:2
+END:VEVENT
+END:VCALENDAR
+""",
+            ),
+        )
+        
+        for title, old_txt, ical_txt, result_txt in data:
+            old = Component.fromString(old_txt)
+            ical = Component.fromString(ical_txt)
+            result = Component.fromString(result_txt)
+            ical.sequenceInSync(old)
+            
+            ical1 = str(ical).split("\n")
+            ical2 = str(result).split("\n")
+            
+            diff = "\n".join(unified_diff(ical1, ical2))
+            self.assertEqual("\n".join(ical1), "\n".join(ical2), "Failed comparison: %s\n%s" % (title, diff,))
+
+
     def test_hasInstancesAfter(self):
         data = (
             ("In the past (single)", False,
@@ -5986,7 +6243,7 @@
             ),
         )
         cutoff = PyCalendarDateTime(2011, 11, 30, 0, 0, 0)
-        for title, expected, body in data:
+        for _ignore_title, expected, body in data:
             ical = Component.fromString(body)
             self.assertEquals(expected, ical.hasInstancesAfter(cutoff))
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20120501/b7e0515c/attachment.html>


More information about the calendarserver-changes mailing list