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

source_changes at macosforge.org source_changes at macosforge.org
Fri Dec 5 13:30:06 PST 2008


Revision: 3468
          http://trac.macosforge.org/projects/calendarserver/changeset/3468
Author:   cdaboo at apple.com
Date:     2008-12-05 13:30:06 -0800 (Fri, 05 Dec 2008)
Log Message:
-----------
Make sure we have backwards compatibility with old data store's free-busy-set behavior. This means that
existing calendars are "upgraded" on the fly to the new schedule-calendar-transp property.

Modified Paths:
--------------
    CalendarServer/trunk/twistedcaldav/directory/calendar.py
    CalendarServer/trunk/twistedcaldav/directory/test/test_calendar.py
    CalendarServer/trunk/twistedcaldav/resource.py

Modified: CalendarServer/trunk/twistedcaldav/directory/calendar.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/calendar.py	2008-12-05 20:20:08 UTC (rev 3467)
+++ CalendarServer/trunk/twistedcaldav/directory/calendar.py	2008-12-05 21:30:06 UTC (rev 3468)
@@ -337,13 +337,10 @@
 
     def url(self):
         return joinURL(self.parent.url(), self.record.uid)
-        ##
-        ## While the underlying primary location is GUID-based, we want
-        ## the canonical user-facing location to be recordType &
-        ## shortName-based, because that's friendlier.
-        ##
-        #return joinURL(self.parent.parent.getChild(self.record.recordType).url(), self.record.shortName)
 
+    def canonicalURL(self, request):
+        return succeed(self.url())
+
     ##
     # DAV
     ##

Modified: CalendarServer/trunk/twistedcaldav/directory/test/test_calendar.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/test_calendar.py	2008-12-05 20:20:08 UTC (rev 3467)
+++ CalendarServer/trunk/twistedcaldav/directory/test/test_calendar.py	2008-12-05 21:30:06 UTC (rev 3468)
@@ -16,9 +16,11 @@
 
 import os
 
+from twisted.internet.defer import inlineCallbacks
 from twisted.web2.dav import davxml
 from twisted.web2.test.test_server import SimpleRequest
 
+from twistedcaldav import caldavxml
 from twistedcaldav.directory.principal import DirectoryPrincipalProvisioningResource
 from twistedcaldav.directory.test.test_xmlfile import xmlFile
 from twistedcaldav.directory.xmlfile import XMLDirectoryService
@@ -69,3 +71,90 @@
         request = SimpleRequest(self.site, "GET", "/calendars/users/12345/")
         d = request.locateResource(request.uri)
         d.addCallback(_response)
+
+    def test_ExistentCalendarHome(self):
+
+        def _response(resource):
+            if resource is None:
+                self.fail("Incorrect response to GET on existent calendar home.")
+
+        request = SimpleRequest(self.site, "GET", "/calendars/users/wsanchez/")
+        d = request.locateResource(request.uri)
+        d.addCallback(_response)
+
+    def test_ExistentCalendar(self):
+
+        def _response(resource):
+            if resource is None:
+                self.fail("Incorrect response to GET on existent calendar.")
+
+        request = SimpleRequest(self.site, "GET", "/calendars/users/wsanchez/calendar/")
+        d = request.locateResource(request.uri)
+        d.addCallback(_response)
+
+    def test_ExistentInbox(self):
+
+        def _response(resource):
+            if resource is None:
+                self.fail("Incorrect response to GET on existent inbox.")
+
+        request = SimpleRequest(self.site, "GET", "/calendars/users/wsanchez/inbox/")
+        d = request.locateResource(request.uri)
+        d.addCallback(_response)
+
+    @inlineCallbacks
+    def test_CalendarTranspProperty(self):
+
+        request = SimpleRequest(self.site, "GET", "/calendars/users/wsanchez/calendar/")
+
+        # Get calendar first
+        calendar = (yield request.locateResource("/calendars/users/wsanchez/calendar/"))
+        if calendar is None:
+            self.fail("Incorrect response to GET on existent calendar.")
+
+        inbox = (yield request.locateResource("/calendars/users/wsanchez/inbox/"))
+        if inbox is None:
+            self.fail("Incorrect response to GET on existent inbox.")
+        
+        # Provisioned calendar has default opaque property
+        transp = (yield calendar.hasProperty(caldavxml.ScheduleCalendarTransp, request))
+        self.assertTrue(transp)
+
+        transp = (yield calendar.readProperty(caldavxml.ScheduleCalendarTransp, request))
+        self.assertEqual(transp, caldavxml.ScheduleCalendarTransp(caldavxml.Opaque()))
+
+        # Inbox property lists the default calendar
+        fbset = (yield inbox.hasProperty(caldavxml.CalendarFreeBusySet, request))
+        self.assertTrue(fbset)
+
+        fbset = (yield inbox.readProperty(caldavxml.CalendarFreeBusySet, request))
+        self.assertEqual(fbset, caldavxml.CalendarFreeBusySet(
+            davxml.HRef.fromString("/calendars/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/calendar"),
+        ))
+
+        # Now remove the dead property to simulate the old calendar server state with
+        # a calendar listed in the fbset
+        yield calendar.removeDeadProperty(caldavxml.ScheduleCalendarTransp)
+        fbset = (yield inbox.readProperty(caldavxml.CalendarFreeBusySet, request))
+        self.assertEqual(fbset, caldavxml.CalendarFreeBusySet(
+            davxml.HRef.fromString("/calendars/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/calendar"),
+        ))
+
+        # Calendar has opaque property derived from inbox
+        transp = (yield calendar.hasProperty(caldavxml.ScheduleCalendarTransp, request))
+        self.assertTrue(transp)
+
+        transp = (yield calendar.readProperty(caldavxml.ScheduleCalendarTransp, request))
+        self.assertEqual(transp, caldavxml.ScheduleCalendarTransp(caldavxml.Opaque()))
+
+        # Now remove the dead property and the inbox fbset item to simulate the old calendar server state
+        yield calendar.removeDeadProperty(caldavxml.ScheduleCalendarTransp)
+        yield inbox.removeDeadProperty(caldavxml.CalendarFreeBusySet)
+
+        # Calendar has transp property derived from inbox
+        transp = (yield calendar.hasProperty(caldavxml.ScheduleCalendarTransp, request))
+        self.assertTrue(transp)
+
+        transp = (yield calendar.readProperty(caldavxml.ScheduleCalendarTransp, request))
+        self.assertEqual(transp, caldavxml.ScheduleCalendarTransp(caldavxml.Transparent()))
+

Modified: CalendarServer/trunk/twistedcaldav/resource.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/resource.py	2008-12-05 20:20:08 UTC (rev 3467)
+++ CalendarServer/trunk/twistedcaldav/resource.py	2008-12-05 21:30:06 UTC (rev 3468)
@@ -194,6 +194,23 @@
         *[caldavxml.CalendarComponent(name=item) for item in allowedComponents]
     )
 
+    def hasProperty(self, property, request):
+        """
+        Need to special case schedule-calendar-transp for backwards compatability.
+        """
+        
+        if type(property) is tuple:
+            qname = property
+        else:
+            qname = property.qname()
+
+        # Force calendar collections to always appear to have the property
+        if qname == (caldav_namespace, "schedule-calendar-transp") and self.isCalendarCollection():
+            return succeed(True)
+        else:
+            return super(CalDAVResource, self).hasProperty(property, request)
+
+    @inlineCallbacks
     def readProperty(self, property, request):
         if type(property) is tuple:
             qname = property
@@ -204,19 +221,18 @@
 
         if namespace == dav_namespace:
             if name == "owner":
-                d = self.owner(request)
-                d.addCallback(lambda x: davxml.Owner(x))
-                return d
+                owner = (yield self.owner(request))
+                returnValue(davxml.Owner(owner))
 
         elif namespace == caldav_namespace:
             if name == "supported-calendar-component-set":
                 # CalDAV-access-09, section 5.2.3
                 if self.hasDeadProperty(qname):
-                    return succeed(self.readDeadProperty(qname))
-                return succeed(self.supportedCalendarComponentSet)
+                    returnValue(self.readDeadProperty(qname))
+                returnValue(self.supportedCalendarComponentSet)
             elif name == "supported-calendar-data":
                 # CalDAV-access-09, section 5.2.4
-                return succeed(caldavxml.SupportedCalendarData(
+                returnValue(caldavxml.SupportedCalendarData(
                     caldavxml.CalendarData(**{
                         "content-type": "text/calendar",
                         "version"     : "2.0",
@@ -225,12 +241,24 @@
             elif name == "max-resource-size":
                 # CalDAV-access-15, section 5.2.5
                 if config.MaximumAttachmentSize:
-                    return succeed(caldavxml.MaxResourceSize.fromString(
+                    returnValue(caldavxml.MaxResourceSize.fromString(
                         str(config.MaximumAttachmentSize)
                     ))
 
-        return super(CalDAVResource, self).readProperty(property, request)
+            elif name == "schedule-calendar-transp":
+                # For backwards compatibility, if the property does not exist we need to create
+                # it and default to the old free-busy-set value.
+                if self.isCalendarCollection() and not self.hasDeadProperty(property):
+                    # For backwards compatibility we need to sync this up with the calendar-free-busy-set on the inbox
+                    principal = (yield self.ownerPrincipal(request))
+                    fbset = (yield principal.calendarFreeBusyURIs(request))
+                    url = (yield self.canonicalURL(request))
+                    opaque = url in fbset
+                    self.writeDeadProperty(caldavxml.ScheduleCalendarTransp(caldavxml.Opaque() if opaque else caldavxml.Transparent()))
 
+        result = (yield super(CalDAVResource, self).readProperty(property, request))
+        returnValue(result)
+
     @inlineCallbacks
     def writeProperty(self, property, request):
         assert isinstance(property, davxml.WebDAVElement), (
@@ -280,7 +308,8 @@
             inboxURL = principal.scheduleInboxURL()
             if inboxURL:
                 inbox = (yield request.locateResource(inboxURL))
-                inbox.processFreeBusyCalendar(request.path, property.children[0] == caldavxml.Opaque())
+                myurl = (yield self.canonicalURL(request))
+                inbox.processFreeBusyCalendar(myurl, property.children[0] == caldavxml.Opaque())
 
         result = (yield super(CalDAVResource, self).writeProperty(property, request))
         returnValue(result)
@@ -632,6 +661,21 @@
         """
         return request.locateResource(parentForURL(uri))
 
+    @inlineCallbacks
+    def canonicalURL(self, request):
+        
+        if not hasattr(self, "_canonical_url"):
+    
+            myurl = request.urlForResource(self)
+            _ignore_scheme, _ignore_host, path, _ignore_query, _ignore_fragment = urlsplit(normalizeURL(myurl))
+            lastpath = path.split("/")[-1]
+            
+            parent = (yield request.locateResource(parentForURL(myurl)))
+            canonical_parent = (yield parent.canonicalURL(request))
+            self._canonical_url = joinURL(canonical_parent, lastpath)
+
+        returnValue(self._canonical_url)
+
 class CalendarPrincipalCollectionResource (DAVPrincipalCollectionResource, CalDAVResource):
     """
     CalDAV principal collection.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20081205/7e41227f/attachment-0001.html>


More information about the calendarserver-changes mailing list