[CalendarServer-changes] [13350] CalendarServer/trunk

source_changes at macosforge.org source_changes at macosforge.org
Mon Apr 21 12:55:16 PDT 2014


Revision: 13350
          http://trac.calendarserver.org//changeset/13350
Author:   cdaboo at apple.com
Date:     2014-04-21 12:55:16 -0700 (Mon, 21 Apr 2014)
Log Message:
-----------
Allow splitting using client supplied past-UID.

Modified Paths:
--------------
    CalendarServer/trunk/requirements-dev.txt
    CalendarServer/trunk/twistedcaldav/storebridge.py
    CalendarServer/trunk/txdav/caldav/datastore/sql.py
    CalendarServer/trunk/txdav/caldav/datastore/test/test_sql.py

Modified: CalendarServer/trunk/requirements-dev.txt
===================================================================
--- CalendarServer/trunk/requirements-dev.txt	2014-04-21 19:50:13 UTC (rev 13349)
+++ CalendarServer/trunk/requirements-dev.txt	2014-04-21 19:55:16 UTC (rev 13350)
@@ -7,4 +7,4 @@
 mockldap
 q
 --editable svn+http://svn.calendarserver.org/repository/calendarserver/CalDAVClientLibrary/trunk@13311#egg=CalDAVClientLibrary
---editable svn+http://svn.calendarserver.org/repository/calendarserver/CalDAVTester/trunk@13342#egg=CalDAVTester
+--editable svn+http://svn.calendarserver.org/repository/calendarserver/CalDAVTester/trunk@13349#egg=CalDAVTester

Modified: CalendarServer/trunk/twistedcaldav/storebridge.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/storebridge.py	2014-04-21 19:50:13 UTC (rev 13349)
+++ CalendarServer/trunk/twistedcaldav/storebridge.py	2014-04-21 19:55:16 UTC (rev 13350)
@@ -3025,8 +3025,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/trunk/txdav/caldav/datastore/sql.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/sql.py	2014-04-21 19:50:13 UTC (rev 13349)
+++ CalendarServer/trunk/txdav/caldav/datastore/sql.py	2014-04-21 19:55:16 UTC (rev 13350)
@@ -3898,7 +3898,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.
@@ -3906,6 +3906,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
@@ -3927,7 +3929,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)
 
 
@@ -3970,6 +3972,9 @@
         newerUID = calendar.resourceUID()
         if olderUID is None:
             olderUID = str(uuid.uuid4())
+            olderResourceName = 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.
@@ -3986,7 +3991,7 @@
         # Store changed data
         yield self._setComponentInternal(calendar_new, internal_state=ComponentUpdateState.SPLIT_OWNER, split_details=(rid, olderUID, True,))
         olderObject = yield self.calendar()._createCalendarObjectWithNameInternal(
-            "{0}.ics".format(olderUID,),
+            olderResourceName,
             calendar_old,
             ComponentUpdateState.SPLIT_OWNER,
             split_details=(rid, newerUID, False,)

Modified: CalendarServer/trunk/txdav/caldav/datastore/test/test_sql.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/test/test_sql.py	2014-04-21 19:50:13 UTC (rev 13349)
+++ CalendarServer/trunk/txdav/caldav/datastore/test/test_sql.py	2014-04-21 19:55:16 UTC (rev 13350)
@@ -6280,3 +6280,82 @@
         cobjs = yield cal.calendarObjects()
         self.assertEqual(len(cobjs), 1)
         yield self.failUnlessFailure(cobjs[0].splitAt(DateTime.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(DateTime.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,))
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20140421/c04641df/attachment-0001.html>


More information about the calendarserver-changes mailing list