[CalendarServer-changes] [14357] CalendarServer/branches/release/CalendarServer-5.4-dev

source_changes at macosforge.org source_changes at macosforge.org
Mon Feb 2 07:46:19 PST 2015


Revision: 14357
          http://trac.calendarserver.org//changeset/14357
Author:   cdaboo at apple.com
Date:     2015-02-02 07:46:19 -0800 (Mon, 02 Feb 2015)
Log Message:
-----------
Allow client to set the UID for the older resource in a split.

Modified Paths:
--------------
    CalendarServer/branches/release/CalendarServer-5.4-dev/twistedcaldav/storebridge.py
    CalendarServer/branches/release/CalendarServer-5.4-dev/txdav/caldav/datastore/sql.py
    CalendarServer/branches/release/CalendarServer-5.4-dev/txdav/caldav/datastore/test/test_sql.py

Modified: CalendarServer/branches/release/CalendarServer-5.4-dev/twistedcaldav/storebridge.py
===================================================================
--- CalendarServer/branches/release/CalendarServer-5.4-dev/twistedcaldav/storebridge.py	2015-02-02 15:42:51 UTC (rev 14356)
+++ CalendarServer/branches/release/CalendarServer-5.4-dev/twistedcaldav/storebridge.py	2015-02-02 15:46:19 UTC (rev 14357)
@@ -2964,8 +2964,14 @@
                 (caldav_namespace, "valid-rid-parameter",),
                 "The rid parameter in the request-URI contains an invalid value",
             ))
+
+        # Client may provide optional UID for the split-off past component
+        pastUID = request.args.get("uid")
+        if pastUID is not None:
+            pastUID = pastUID[0]
+
         try:
-            otherStoreObject = yield self._newStoreObject.splitAt(rid)
+            otherStoreObject = yield self._newStoreObject.splitAt(rid, pastUID)
         except InvalidSplit:
             raise HTTPError(ErrorResponse(
                 FORBIDDEN,

Modified: CalendarServer/branches/release/CalendarServer-5.4-dev/txdav/caldav/datastore/sql.py
===================================================================
--- CalendarServer/branches/release/CalendarServer-5.4-dev/txdav/caldav/datastore/sql.py	2015-02-02 15:42:51 UTC (rev 14356)
+++ CalendarServer/branches/release/CalendarServer-5.4-dev/txdav/caldav/datastore/sql.py	2015-02-02 15:46:19 UTC (rev 14357)
@@ -3435,7 +3435,7 @@
 
 
     @inlineCallbacks
-    def splitAt(self, rid):
+    def splitAt(self, rid, pastUID=None):
         """
         User initiated split. We need to verify it is OK to do so first. We will allow any recurring item to
         be split, but will not allow attendees to split invites.
@@ -3443,6 +3443,8 @@
         @param rid: the date-time where the split should occur. This need not be a specific instance
             date-time - this method will choose the next instance on or after this value.
         @type rid: L{DateTime}
+        @param pastuid: the UID of the new (past) resource to be created
+        @type pastuid: L{str}
         """
 
         # Must be recurring
@@ -3464,7 +3466,7 @@
             raise InvalidSplit()
 
         # Do split and return new resource
-        olderObject = yield self.split(rid=rid)
+        olderObject = yield self.split(rid=rid, olderUID=pastUID)
         returnValue(olderObject)
 
 
@@ -3507,6 +3509,9 @@
         newerUID = calendar.resourceUID()
         if olderUID is None:
             olderUID = str(uuid.uuid4())
+            olderResourceName = "{0}.ics".format(olderUID)
+        else:
+            olderResourceName = "{0}.ics".format(olderUID.encode("base64")[:-1].rstrip("="))
 
         # Now process this resource, but do implicit scheduling for attendees not hosted on this server.
         # We need to do this before processing attendee copies.
@@ -3522,7 +3527,12 @@
 
         # Store changed data
         yield self._setComponentInternal(calendar_new, internal_state=ComponentUpdateState.SPLIT_OWNER, split_details=(rid, olderUID, True,))
-        olderObject = yield self.calendar()._createCalendarObjectWithNameInternal("%s.ics" % (olderUID,), calendar_old, ComponentUpdateState.SPLIT_OWNER, split_details=(rid, newerUID, False,))
+        olderObject = yield self.calendar()._createCalendarObjectWithNameInternal(
+            olderResourceName,
+            calendar_old,
+            ComponentUpdateState.SPLIT_OWNER,
+            split_details=(rid, newerUID, False,)
+        )
 
         # Split each one - but not this resource
         for resource in resources:

Modified: CalendarServer/branches/release/CalendarServer-5.4-dev/txdav/caldav/datastore/test/test_sql.py
===================================================================
--- CalendarServer/branches/release/CalendarServer-5.4-dev/txdav/caldav/datastore/test/test_sql.py	2015-02-02 15:42:51 UTC (rev 14356)
+++ CalendarServer/branches/release/CalendarServer-5.4-dev/txdav/caldav/datastore/test/test_sql.py	2015-02-02 15:46:19 UTC (rev 14357)
@@ -6325,7 +6325,86 @@
         yield self.failUnlessFailure(cobjs[0].splitAt(PyCalendarDateTime.parseText("%(now_fwd25)s" % self.subs)), InvalidSplit)
 
 
+    @inlineCallbacks
+    def test_calendarObjectSplit_splitat_ok_pastuid(self):
+        """
+        Test that user triggered splitting of calendar objects works.
+        """
 
+        pastUID = "XXXX-YYYY-ZZZZ"
+        data_future, data_past, data_future2, data_past2, data_inbox2 = yield self._setupSplitAt()
+
+        # Update it
+        cobj = yield self.calendarObjectUnderTest(name="data1.ics", calendar_name="calendar", home="user01")
+        oldobj = yield cobj.splitAt(PyCalendarDateTime.parseText("%(now_back14)s" % self.subs), pastUID=pastUID)
+        oldname = oldobj.name()
+        self.assertFalse(hasattr(cobj, "_workItems"))
+        yield self.commit()
+
+        w = schema.CALENDAR_OBJECT_SPLITTER_WORK
+        rows = yield Select(
+            [w.RESOURCE_ID, ],
+            From=w
+        ).on(self.transactionUnderTest())
+        self.assertEqual(len(rows), 0)
+        yield self.abort()
+
+        rows = yield Select(
+            [w.RESOURCE_ID, ],
+            From=w
+        ).on(self.transactionUnderTest())
+        self.assertEqual(len(rows), 0)
+        yield self.abort()
+
+        # Get the existing and new object data
+        cobj1 = yield self.calendarObjectUnderTest(name="data1.ics", calendar_name="calendar", home="user01")
+        self.assertTrue(cobj1.isScheduleObject)
+        ical1 = yield cobj1.component()
+        relID = ical1.masterComponent().propertyValue("RELATED-TO")
+
+        cobj2 = yield self.calendarObjectUnderTest(name=oldname, calendar_name="calendar", home="user01")
+        self.assertTrue(cobj2 is not None)
+        self.assertTrue(cobj2.isScheduleObject)
+        ical2 = yield cobj2.component()
+        newUID = ical2.masterComponent().propertyValue("UID")
+
+        self.assertEqual(newUID, pastUID)
+
+        ical_future = yield cobj1.component()
+        ical_past = yield cobj2.component()
+
+        # Verify user01 data
+        title = "user01"
+        relsubs = dict(self.subs)
+        relsubs["uid"] = newUID
+        relsubs["relID"] = relID
+        self.assertEqual(normalize_iCalStr(ical_future), normalize_iCalStr(data_future) % relsubs, "Failed future: %s" % (title,))
+        self.assertEqual(normalize_iCalStr(ical_past), normalize_iCalStr(data_past) % relsubs, "Failed past: %s" % (title,))
+
+        # Get user02 data
+        cal = yield self.calendarUnderTest(name="calendar", home="user02")
+        cobjs = yield cal.calendarObjects()
+        self.assertEqual(len(cobjs), 2)
+        for cobj in cobjs:
+            ical = yield cobj.component()
+            if ical.resourceUID() == "12345-67890":
+                ical_future = ical
+            else:
+                ical_past = ical
+
+        cal = yield self.calendarUnderTest(name="inbox", home="user02")
+        cobjs = yield cal.calendarObjects()
+        self.assertEqual(len(cobjs), 1)
+        ical_inbox = yield cobjs[0].component()
+
+        # Verify user02 data
+        title = "user02"
+        self.assertEqual(normalize_iCalStr(ical_future), normalize_iCalStr(data_future2) % relsubs, "Failed future: %s" % (title,))
+        self.assertEqual(normalize_iCalStr(ical_past), normalize_iCalStr(data_past2) % relsubs, "Failed past: %s" % (title,))
+        self.assertEqual(normalize_iCalStr(ical_inbox), normalize_iCalStr(data_inbox2) % relsubs, "Failed inbox: %s" % (title,))
+
+
+
 class TimeRangeUpdateOptimization(CommonCommonTests, unittest.TestCase):
     """
     CalendarObject splitting tests
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20150202/46a86a24/attachment.html>


More information about the calendarserver-changes mailing list