[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