[CalendarServer-changes] [6339] CalendarServer/branches/users/glyph/more-deferreds-6

source_changes at macosforge.org source_changes at macosforge.org
Wed Sep 22 16:02:29 PDT 2010


Revision: 6339
          http://trac.macosforge.org/projects/calendarserver/changeset/6339
Author:   glyph at apple.com
Date:     2010-09-22 16:02:28 -0700 (Wed, 22 Sep 2010)
Log Message:
-----------
Thread asynchronization through all of calendarHomeWithUID and addressbookHomeWithUID's callers

Modified Paths:
--------------
    CalendarServer/branches/users/glyph/more-deferreds-6/calendarserver/tools/purge.py
    CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/directory/addressbook.py
    CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/directory/calendar.py
    CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/directory/principal.py
    CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/resource.py
    CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/scheduling/implicit.py
    CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/scheduling/processing.py
    CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/scheduling/utils.py
    CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/sharing.py
    CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/test/test_wrapping.py
    CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/test/util.py
    CalendarServer/branches/users/glyph/more-deferreds-6/txdav/caldav/datastore/sql.py
    CalendarServer/branches/users/glyph/more-deferreds-6/txdav/caldav/datastore/util.py

Added Paths:
-----------
    CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/directory/common.py

Modified: CalendarServer/branches/users/glyph/more-deferreds-6/calendarserver/tools/purge.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-6/calendarserver/tools/purge.py	2010-09-22 19:48:52 UTC (rev 6338)
+++ CalendarServer/branches/users/glyph/more-deferreds-6/calendarserver/tools/purge.py	2010-09-22 23:02:28 UTC (rev 6339)
@@ -270,7 +270,7 @@
         # Get the calendar home
         principalCollection = directory.principalCollection
         principal = principalCollection.principalForRecord(record)
-        calendarHome = principal.calendarHome()
+        calendarHome = yield principal.calendarHome()
 
         if verbose:
             print "%s %-15s :" % (record.uid, record.shortNames[0]),
@@ -367,7 +367,7 @@
 
     principalCollection = directory.principalCollection
     principal = principalCollection.principalForRecord(record)
-    calendarHome = principal.calendarHome()
+    calendarHome = yield principal.calendarHome()
 
     # Anything in the past is left alone
     now = datetime.utcnow().strftime("%Y%m%dT%H%M%SZ")

Modified: CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/directory/addressbook.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/directory/addressbook.py	2010-09-22 19:48:52 UTC (rev 6338)
+++ CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/directory/addressbook.py	2010-09-22 23:02:28 UTC (rev 6339)
@@ -19,7 +19,6 @@
 """
 
 __all__ = [
-    "uidsResourceName",
     "DirectoryAddressBookHomeProvisioningResource",
     "DirectoryAddressBookHomeTypeProvisioningResource",
     "DirectoryAddressBookHomeUIDProvisioningResource",
@@ -32,10 +31,14 @@
 from twext.web2.http import HTTPError
 from twext.web2.http_headers import ETag, MimeType
 
+from twisted.internet.defer import inlineCallbacks, returnValue
+
 from twistedcaldav.config import config
 from twistedcaldav.directory.idirectory import IDirectoryService
-from twistedcaldav.directory.resource import DirectoryReverseProxyResource
-from twistedcaldav.directory.util import transactionFromRequest
+
+from twistedcaldav.directory.common import CommonUIDProvisioningResource,\
+    uidsResourceName, CommonHomeTypeProvisioningResource
+
 from twistedcaldav.extensions import ReadOnlyResourceMixIn, DAVResource,\
     DAVResourceWithChildrenMixin
 from twistedcaldav.resource import AddressBookHomeResource
@@ -44,8 +47,6 @@
 
 log = Logger()
 
-# Use __underbars__ convention to avoid conflicts with directory resource types.
-uidsResourceName = "__uids__"
 
 # FIXME: copied from resource.py to avoid circular dependency
 class CalDAVComplianceMixIn(object):
@@ -71,7 +72,9 @@
         return MimeType("httpd", "unix-directory")
 
 
-class DirectoryAddressBookHomeProvisioningResource (DirectoryAddressBookProvisioningResource):
+class DirectoryAddressBookHomeProvisioningResource (
+        DirectoryAddressBookProvisioningResource
+    ):
     """
     Resource which provisions address book home collections as needed.    
     """
@@ -134,7 +137,10 @@
         return "addressbooks"
 
 
-class DirectoryAddressBookHomeTypeProvisioningResource (DirectoryAddressBookProvisioningResource):
+class DirectoryAddressBookHomeTypeProvisioningResource (
+        CommonHomeTypeProvisioningResource,
+        DirectoryAddressBookProvisioningResource
+    ):
     """
     Resource which provisions address book home collections of a specific
     record type as needed.
@@ -156,18 +162,7 @@
     def url(self):
         return joinURL(self._parent.url(), self.recordType)
 
-    def locateChild(self, request, segments):
-        name = segments[0]
-        if name == "":
-            return (self, segments[1:])
 
-        record = self.directory.recordWithShortName(self.recordType, name)
-        if record is None:
-            return None, []
-
-        return (self._parent.homeForDirectoryRecord(record, request),
-                segments[1:])
-
     def listChildren(self):
         if config.EnablePrincipalListings:
 
@@ -206,99 +201,33 @@
         return self._parent.principalForRecord(record)
 
 
-class DirectoryAddressBookHomeUIDProvisioningResource (DirectoryAddressBookProvisioningResource):
+class DirectoryAddressBookHomeUIDProvisioningResource (
+        CommonUIDProvisioningResource,
+        DirectoryAddressBookProvisioningResource
+    ):
 
-    def __init__(self, parent):
-        """
-        @param parent: the parent of this resource
-        """
-        assert parent is not None
+    homeResourceTypeName = 'addressbooks'
 
-        super(DirectoryAddressBookHomeUIDProvisioningResource, self).__init__()
+    enabledAttribute = 'enabledForAddressBooks'
 
-        self.directory = parent.directory
-        self.parent = parent
+    def homeResourceCreator(self, record, transaction):
+        return DirectoryAddressBookHomeResource.createHomeResource(
+            self, record, transaction)
 
-    def url(self):
-        return joinURL(self.parent.url(), uidsResourceName)
 
-    def locateChild(self, request, segments):
-
-        name = segments[0]
-        if name == "":
-            return (self, ())
-
-        record = self.directory.recordWithUID(name)
-        if record:
-            return (self.homeResourceForRecord(record, request), segments[1:])
-        else:
-            return (None, ())
-
-    def getChild(self, name, record=None):
-        raise NotImplementedError("DirectoryAddressBookHomeUIDProvisioningResource.getChild no longer exists.")
-
-    def listChildren(self):
-        # Not a listable collection
-        raise HTTPError(responsecode.FORBIDDEN)
-
-    def homeResourceForRecord(self, record, request):
-
-        transaction = transactionFromRequest(request, self.parent._newStore)
-
-        name = record.uid
-
-        if record is None:
-            self.log_msg("No directory record with GUID %r" % (name,))
-            return None
-
-        if not record.enabledForAddressBooks:
-            self.log_msg("Directory record %r is not enabled for address books" % (record,))
-            return None
-
-        assert len(name) > 4, "Directory record has an invalid GUID: %r" % (name,)
-        
-        if record.locallyHosted():
-            child = DirectoryAddressBookHomeResource(self, record, transaction)
-        else:
-            child = DirectoryReverseProxyResource(self, record)
-
-        return child
-
-    ##
-    # DAV
-    ##
-    
-    def isCollection(self):
-        return True
-
-    def displayName(self):
-        return uidsResourceName
-
-    ##
-    # ACL
-    ##
-
-    def principalCollections(self):
-        return self.parent.principalCollections()
-
-    def principalForRecord(self, record):
-        return self.parent.principalForRecord(record)
-
-
 class DirectoryAddressBookHomeResource (AddressBookHomeResource):
     """
     Address book home collection resource.
     """
-    def __init__(self, parent, record, transaction):
-        """
-        @param path: the path to the file which will back the resource.
-        """
-        assert parent is not None
-        assert record is not None
-        assert transaction is not None
 
+    @classmethod
+    @inlineCallbacks
+    def createHomeResource(cls, parent, record, transaction):
+        self = yield super(DirectoryAddressBookHomeResource, cls).createHomeResource(
+            parent, record.uid, transaction)
         self.record = record
-        super(DirectoryAddressBookHomeResource, self).__init__(parent, record.uid, transaction)
+        returnValue(self)
 
+
     def principalForRecord(self):
         return self.parent.principalForRecord(self.record)

Modified: CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/directory/calendar.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/directory/calendar.py	2010-09-22 19:48:52 UTC (rev 6338)
+++ CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/directory/calendar.py	2010-09-22 23:02:28 UTC (rev 6339)
@@ -20,7 +20,6 @@
 """
 
 __all__ = [
-    "uidsResourceName",
     "DirectoryCalendarHomeProvisioningResource",
     "DirectoryCalendarHomeTypeProvisioningResource",
     "DirectoryCalendarHomeUIDProvisioningResource",
@@ -33,12 +32,13 @@
 from twext.web2.http import HTTPError
 from twext.web2.http_headers import ETag, MimeType
 
-from twisted.internet.defer import succeed
+from twisted.internet.defer import succeed, inlineCallbacks, returnValue
 
 from twistedcaldav.config import config
 from twistedcaldav.directory.idirectory import IDirectoryService
-from twistedcaldav.directory.resource import DirectoryReverseProxyResource
-from twistedcaldav.directory.util import transactionFromRequest
+from twistedcaldav.directory.common import uidsResourceName,\
+    CommonUIDProvisioningResource, CommonHomeTypeProvisioningResource
+
 from twistedcaldav.directory.wiki import getWikiACL
 from twistedcaldav.extensions import ReadOnlyResourceMixIn, DAVResource,\
     DAVResourceWithChildrenMixin
@@ -48,9 +48,6 @@
 
 log = Logger()
 
-# Use __underbars__ convention to avoid conflicts with directory resource types.
-uidsResourceName = "__uids__"
-
 # FIXME: copied from resource.py to avoid circular dependency
 class CalDAVComplianceMixIn(object):
     def davComplianceClasses(self):
@@ -136,7 +133,10 @@
     def displayName(self):
         return "calendars"
 
-class DirectoryCalendarHomeTypeProvisioningResource (DirectoryCalendarProvisioningResource):
+class DirectoryCalendarHomeTypeProvisioningResource(
+        CommonHomeTypeProvisioningResource,
+        DirectoryCalendarProvisioningResource
+    ):
     """
     Resource which provisions calendar home collections of a specific
     record type as needed.
@@ -158,18 +158,7 @@
     def url(self):
         return joinURL(self._parent.url(), self.recordType)
 
-    def locateChild(self, request, segments):
-        name = segments[0]
-        if name == "":
-            return (self, segments[1:])
 
-        record = self.directory.recordWithShortName(self.recordType, name)
-        if record is None:
-            return None, []
-
-        return (self._parent.homeForDirectoryRecord(record, request),
-                segments[1:])
-
     def listChildren(self):
         if config.EnablePrincipalListings:
 
@@ -207,99 +196,35 @@
     def principalForRecord(self, record):
         return self._parent.principalForRecord(record)
 
-class DirectoryCalendarHomeUIDProvisioningResource (DirectoryCalendarProvisioningResource):
+class DirectoryCalendarHomeUIDProvisioningResource (
+        CommonUIDProvisioningResource,
+        DirectoryCalendarProvisioningResource
+    ):
 
-    def __init__(self, parent):
-        """
-        @param parent: the parent of this resource
-        """
-        assert parent is not None
+    homeResourceTypeName = 'calendars'
 
-        super(DirectoryCalendarHomeUIDProvisioningResource, self).__init__()
+    enabledAttribute = 'enabledForCalendaring'
 
-        self.directory = parent.directory
-        self.parent = parent
+    def homeResourceCreator(self, record, transaction):
+        return DirectoryCalendarHomeResource.createHomeResource(
+            self, record, transaction)
 
-    def url(self):
-        return joinURL(self.parent.url(), uidsResourceName)
 
-    def locateChild(self, request, segments):
 
-        name = segments[0]
-        if name == "":
-            return (self, ())
-
-        record = self.directory.recordWithUID(name)
-        if record:
-            return (self.homeResourceForRecord(record, request), segments[1:])
-        else:
-            return (None, ())
-
-    def getChild(self, name, record=None):
-        raise NotImplementedError("DirectoryCalendarProvisioningResource.getChild no longer exists.")
-
-    def listChildren(self):
-        # Not a listable collection
-        raise HTTPError(responsecode.FORBIDDEN)
-
-    def homeResourceForRecord(self, record, request):
-
-        transaction = transactionFromRequest(request, self.parent._newStore)
-        name = record.uid
-
-        if record is None:
-            log.debug("No directory record with GUID %r" % (name,))
-            return None
-
-        if not record.enabledForCalendaring:
-            log.debug("Directory record %r is not enabled for calendaring" % (record,))
-            return None
-
-        assert len(name) > 4, "Directory record has an invalid GUID: %r" % (name,)
-        
-        if record.locallyHosted():
-            child = DirectoryCalendarHomeResource(self, record, transaction)
-        else:
-            child = DirectoryReverseProxyResource(self, record)
-
-        return child
-
-    ##
-    # DAV
-    ##
-    
-    def isCollection(self):
-        return True
-
-    def displayName(self):
-        return uidsResourceName
-
-    ##
-    # ACL
-    ##
-
-    def principalCollections(self):
-        return self.parent.principalCollections()
-
-    def principalForRecord(self, record):
-        return self.parent.principalForRecord(record)
-
-
 class DirectoryCalendarHomeResource (CalendarHomeResource):
     """
     Calendar home collection resource.
     """
-    def __init__(self, parent, record, transaction):
-        """
-        @param path: the path to the file which will back the resource.
-        """
-        assert parent is not None
-        assert record is not None
-        assert transaction is not None
 
+    @classmethod
+    @inlineCallbacks
+    def createHomeResource(cls, parent, record, transaction):
+        self = yield super(DirectoryCalendarHomeResource, cls).createHomeResource(
+            parent, record.uid, transaction)
         self.record = record
-        super(DirectoryCalendarHomeResource, self).__init__(parent, record.uid, transaction)
+        returnValue(self)
 
+
     # Special ACLs for Wiki service
     def accessControlList(self, request, inheritance=True, expanding=False, inherited_aces=None):
         def gotACL(wikiACL):

Added: CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/directory/common.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/directory/common.py	                        (rev 0)
+++ CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/directory/common.py	2010-09-22 23:02:28 UTC (rev 6339)
@@ -0,0 +1,147 @@
+# -*- test-case-name: twistedcaldav.test.test_wrapping,twistedcaldav.directory.test.test_calendar -*-
+##
+# Copyright (c) 2010 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+from twisted.internet.defer import inlineCallbacks, returnValue
+from twext.web2.http import HTTPError
+from twext.web2 import responsecode
+from twext.web2.dav.util import joinURL
+from twistedcaldav.directory.util import transactionFromRequest
+from twistedcaldav.directory.resource import DirectoryReverseProxyResource
+
+__all__ = [
+    'uidsResourceName',
+    'CommonUIDProvisioningResource'
+]
+
+# Use __underbars__ convention to avoid conflicts with directory resource
+# types.
+
+uidsResourceName = "__uids__"
+
+class CommonUIDProvisioningResource(object):
+    """
+    Common ancestor for addressbook/calendar UID provisioning resources.
+
+    Must be mixed in to the hierarchy I{before} the appropriate resource type.
+    
+    @ivar homeResourceTypeName: The name of the home resource type ('calendars'
+        or 'addressbooks').
+
+    @ivar enabledAttribute: The name of the attribute of the directory record
+        which determines whether this should be enabled or not.
+    """
+
+    def __init__(self, parent):
+        """
+        @param parent: the parent of this resource
+        """
+
+        super(CommonUIDProvisioningResource, self).__init__()
+
+        self.directory = parent.directory
+        self.parent = parent
+
+
+    @inlineCallbacks
+    def homeResourceForRecord(self, record, request):
+
+        transaction = transactionFromRequest(request, self.parent._newStore)
+        name = record.uid
+
+        if record is None:
+            self.log_msg("No directory record with GUID %r" % (name,))
+            returnValue(None)
+
+        if not getattr(record, self.enabledAttribute):
+            self.log_msg("Directory record %r is not enabled for %s" % (
+                record, self.homeResourceTypeName))
+            returnValue(None)
+
+        assert len(name) > 4, "Directory record has an invalid GUID: %r" % (
+            name,)
+        
+        if record.locallyHosted():
+            child = yield self.homeResourceCreator(record, transaction)
+        else:
+            child = DirectoryReverseProxyResource(self, record)
+
+        returnValue(child)
+
+
+    @inlineCallbacks
+    def locateChild(self, request, segments):
+
+        name = segments[0]
+        if name == "":
+            returnValue((self, ()))
+
+        record = self.directory.recordWithUID(name)
+        if record:
+            child = yield self.homeResourceForRecord(record, request)
+            returnValue((child, segments[1:]))
+        else:
+            returnValue((None, ()))
+
+
+    def listChildren(self):
+        # Not a listable collection
+        raise HTTPError(responsecode.FORBIDDEN)
+
+    ##
+    # ACL
+    ##
+
+    def principalCollections(self):
+        return self.parent.principalCollections()
+
+    def principalForRecord(self, record):
+        return self.parent.principalForRecord(record)
+    ##
+    # DAV
+    ##
+    
+    def isCollection(self):
+        return True
+
+
+    def getChild(self, name, record=None):
+        raise NotImplementedError(self.__class__.__name__ +
+                                  ".getChild no longer exists.")
+
+    def displayName(self):
+        return uidsResourceName
+
+    def url(self):
+        return joinURL(self.parent.url(), uidsResourceName)
+
+
+
+class CommonHomeTypeProvisioningResource(object):
+
+    @inlineCallbacks
+    def locateChild(self, request, segments):
+        name = segments[0]
+        if name == "":
+            returnValue((self, segments[1:]))
+
+        record = self.directory.recordWithShortName(self.recordType, name)
+        if record is None:
+            returnValue((None, []))
+
+        child = yield self._parent.homeForDirectoryRecord(record, request)
+        returnValue((child, segments[1:]))
+

Modified: CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/directory/principal.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/directory/principal.py	2010-09-22 19:48:52 UTC (rev 6338)
+++ CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/directory/principal.py	2010-09-22 23:02:28 UTC (rev 6339)
@@ -55,6 +55,7 @@
 from twistedcaldav.directory import calendaruserproxy
 from twistedcaldav.directory import augment
 from twistedcaldav.directory.calendaruserproxy import CalendarUserProxyPrincipalResource
+from twistedcaldav.directory.common import uidsResourceName
 from twistedcaldav.directory.directory import DirectoryService, DirectoryRecord
 from twistedcaldav.extensions import ReadOnlyResourceMixIn, DAVPrincipalResource,\
     DAVResourceWithChildrenMixin
@@ -67,9 +68,6 @@
 
 log = Logger()
 
-# Use __underbars__ convention to avoid conflicts with directory resource types.
-uidsResourceName = "__uids__"
-
 class PermissionsMixIn (ReadOnlyResourceMixIn):
     def defaultAccessControlList(self):
         return authReadACL
@@ -867,26 +865,27 @@
         else:
             return False
 
+    @inlineCallbacks
     def scheduleInbox(self, request):
-        home = self.calendarHome(request)
+        home = yield self.calendarHome(request)
         if home is None:
-            return succeed(None)
+            returnValue(None)
 
-        inbox = home.getChild("inbox")
+        inbox = yield home.getChild("inbox")
         if inbox is None:
-            return succeed(None)
+            returnValue(None)
 
-        return succeed(inbox)
+        returnValue(inbox)
 
+    @inlineCallbacks
     def notificationCollection(self, request):
-        
+
         notification = None
         if config.Sharing.Enabled:
-            home = self.calendarHome(request)
+            home = yield self.calendarHome(request)
             if home is not None:    
-                notification = home.getChild("notification")
-    
-        return succeed(notification)
+                notification = yield home.getChild("notification")
+        returnValue(notification)
 
     def calendarHomeURLs(self):
         homeURL = self._homeChildURL(None)
@@ -929,14 +928,16 @@
         else:
             return joinURL(url, name) if name else url
 
+
     def calendarHome(self, request):
         # FIXME: self.record.service.calendarHomesCollection smells like a hack
         service = self.record.service
         if hasattr(service, "calendarHomesCollection"):
             return service.calendarHomesCollection.homeForDirectoryRecord(self.record, request)
         else:
-            return None
+            return succeed(None)
 
+
     def _addressBookHomeChildURL(self, name):
         if not hasattr(self, "addressBookHomeURL"):
             if not hasattr(self.record.service, "addressBookHomesCollection"):

Modified: CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/resource.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/resource.py	2010-09-22 19:48:52 UTC (rev 6338)
+++ CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/resource.py	2010-09-22 23:02:28 UTC (rev 6339)
@@ -1,4 +1,4 @@
-# -*- test-case-name: twistedcaldav.test.test_resource -*-
+# -*- test-case-name: twistedcaldav.test.test_resource,twistedcaldav.test.test_wrapping -*-
 ##
 # Copyright (c) 2005-2010 Apple Inc. All rights reserved.
 #
@@ -1937,35 +1937,51 @@
 
 class CommonHomeResource(SharedHomeMixin, CalDAVResource):
     """
-    Calendar home collection resource.
+    Logic common to Calendar and Addressbook home resources.
     """
-    def __init__(self, parent, name, transaction):
-        """
-        """
-
+    def __init__(self, parent, name, transaction, home):
         self.parent = parent
         self.name = name
         self.associateWithTransaction(transaction)
         self._provisionedChildren = {}
         self._provisionedLinks = {}
         self._setupProvisions()
-
-        self._newStoreHome, created = self.makeNewStore()
+        self._newStoreHome = home
         CalDAVResource.__init__(self)
 
         from twistedcaldav.storebridge import _NewStorePropertiesWrapper
         self._dead_properties = _NewStorePropertiesWrapper(
             self._newStoreHome.properties()
         )
+
+
+    @classmethod
+    @inlineCallbacks
+    def createHomeResource(cls, parent, name, transaction):
+        home, created = yield cls.homeFromTransaction(
+            transaction, name)
+        resource = cls(parent, name, transaction, home)
         if created:
-            self.postCreateHome()
+            resource.postCreateHome()
+        returnValue(resource)
 
+
+    @classmethod
+    def homeFromTransaction(cls, transaction, uid):
+        """
+        Create or retrieve an appropriate back-end-home object from a
+        transaction and a home UID.
+
+        @return: a L{Deferred} which fires a 2-tuple of C{(created, home)}
+            where C{created} is a boolean indicating whether this call created
+            the home in the back-end, and C{home} is the home object itself.
+        """
+        raise NotImplementedError("Subclasses must implement.")
+
+
     def _setupProvisions(self):
         pass
 
-    def makeNewStore(self):
-        raise NotImplementedError
-
     def postCreateHome(self):
         pass
 
@@ -2224,9 +2240,21 @@
 
 class CalendarHomeResource(CommonHomeResource):
     """
-    Calendar home collection resource.
+    Calendar home collection classmethod.
     """
 
+    @classmethod
+    @inlineCallbacks
+    def homeFromTransaction(cls, transaction, uid):
+        storeHome = yield transaction.calendarHomeWithUID(uid)
+        if storeHome is not None:
+            created = False
+        else:
+            storeHome = yield transaction.calendarHomeWithUID(uid, create=True)
+            created = True
+        returnValue((storeHome, created))
+
+
     def _setupProvisions(self):
 
         # Cache children which must be of a specific type
@@ -2248,18 +2276,7 @@
             from twistedcaldav.notifications import NotificationCollectionResource
             self._provisionedChildren["notification"] = NotificationCollectionResource
 
-    def makeNewStore(self):
-        storeHome = self._associatedTransaction.calendarHomeWithUID(self.name)
-        if storeHome is not None:
-            created = False
-        else:
-            storeHome = self._associatedTransaction.calendarHomeWithUID(
-                self.name, create=True
-            )
-            created = True
 
-        return storeHome, created
-
     def postCreateHome(self):
         # This is a bit of a hack.  Really we ought to be always generating
         # this URL live from a back-end method that tells us what the
@@ -2271,9 +2288,10 @@
     def canShare(self):
         return config.Sharing.Enabled and config.Sharing.Calendars.Enabled and self.exists()
 
+
+    @inlineCallbacks
     def makeRegularChild(self, name):
-
-        newCalendar = self._newStoreHome.calendarWithName(name)
+        newCalendar = yield self._newStoreHome.calendarWithName(name)
         if newCalendar is None:
             # Local imports.due to circular dependency between modules.
             from twistedcaldav.storebridge import (
@@ -2290,8 +2308,9 @@
                 principalCollections=self.principalCollections()
             )
         self.propagateTransaction(similar)
-        return similar
+        returnValue(similar)
 
+
     def defaultAccessControlList(self):
         myPrincipal = self.principalForRecord()
 
@@ -2348,7 +2367,19 @@
     """
     Address book home collection resource.
     """
-    
+
+    @classmethod
+    @inlineCallbacks
+    def homeFromTransaction(cls, transaction, uid):
+        storeHome = yield transaction.addressbookHomeWithUID(uid)
+        if storeHome is not None:
+            created = False
+        else:
+            storeHome = yield transaction.addressbookHomeWithUID(uid, create=True)
+            created = True
+        returnValue((storeHome, created))
+
+
     def _setupProvisions(self):
 
         # Cache children which must be of a specific type
@@ -2365,6 +2396,7 @@
     def canShare(self):
         return config.Sharing.Enabled and config.Sharing.AddressBooks.Enabled and self.exists()
 
+    @inlineCallbacks
     def makeRegularChild(self, name):
 
         # Check for public/global path
@@ -2381,7 +2413,7 @@
                 mainCls = GlobalAddressBookCollectionResource
                 protoCls = ProtoGlobalAddressBookCollectionResource
 
-        newAddressBook = self._newStoreHome.addressbookWithName(name)
+        newAddressBook = yield self._newStoreHome.addressbookWithName(name)
         if newAddressBook is None:
             # Local imports.due to circular dependency between modules.
             similar = protoCls(
@@ -2395,7 +2427,7 @@
                 principalCollections=self.principalCollections()
             )
         self.propagateTransaction(similar)
-        return similar
+        returnValue(similar)
 
 
 class GlobalAddressBookResource (ReadOnlyResourceMixIn, CalDAVResource):

Modified: CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/scheduling/implicit.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/scheduling/implicit.py	2010-09-22 19:48:52 UTC (rev 6338)
+++ CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/scheduling/implicit.py	2010-09-22 23:02:28 UTC (rev 6339)
@@ -383,7 +383,7 @@
 
         # Get owner's calendar-home
         calendar_owner_principal = (yield self.resource.resourceOwnerPrincipal(self.request))
-        calendar_home = calendar_owner_principal.calendarHome(self.request)
+        calendar_home = yield calendar_owner_principal.calendarHome(self.request)
 
         check_parent_uri = parentForURL(check_uri)[:-1] if check_uri else None
 

Modified: CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/scheduling/processing.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/scheduling/processing.py	2010-09-22 19:48:52 UTC (rev 6338)
+++ CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/scheduling/processing.py	2010-09-22 23:02:28 UTC (rev 6339)
@@ -20,6 +20,7 @@
 
 from vobject.icalendar import dateTimeToString, utc
 
+from twisted.python.log import err as log_traceback
 from twext.python.log import Logger
 
 from twisted.internet import reactor
@@ -94,6 +95,7 @@
                 # We attempt to recover from this. That involves trying to re-write the attendee data
                 # to match that of the organizer assuming we have the organizer's full data available, then
                 # we try the processing operation again.
+                log_traceback()
                 log.error("ImplicitProcessing - originator '%s' to recipient '%s' with UID: '%s' - exception raised will try to fix: %s" % (self.originator.cuaddr, self.recipient.cuaddr, self.uid, e))
                 result = (yield self.doImplicitAttendeeEventFix(e))
                 if result:
@@ -101,6 +103,7 @@
                     try:
                         result = (yield self.doImplicitAttendee())
                     except Exception, e:
+                        log_traceback()
                         log.error("ImplicitProcessing - originator '%s' to recipient '%s' with UID: '%s' - exception raised after fix: %s" % (self.originator.cuaddr, self.recipient.cuaddr, self.uid, e))
                         raise ImplicitProcessorException("5.1;Service unavailable")
                 else:

Modified: CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/scheduling/utils.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/scheduling/utils.py	2010-09-22 19:48:52 UTC (rev 6338)
+++ CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/scheduling/utils.py	2010-09-22 23:02:28 UTC (rev 6339)
@@ -33,7 +33,7 @@
 
     if principal and principal.locallyHosted():
         # Get principal's calendar-home
-        calendar_home = principal.calendarHome(request)
+        calendar_home = yield principal.calendarHome(request)
 
         # FIXME: because of the URL->resource request mapping thing, we have to
         # force the request to recognize this resource.

Modified: CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/sharing.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/sharing.py	2010-09-22 19:48:52 UTC (rev 6338)
+++ CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/sharing.py	2010-09-22 23:02:28 UTC (rev 6339)
@@ -174,9 +174,9 @@
         
         # Get the home collection
         if self.isCalendarCollection():
-            home = principal.calendarHome(request)
+            home = yield principal.calendarHome(request)
         elif self.isAddressBookCollection():
-            home = principal.addressBookHome(request)
+            home = yield principal.addressBookHome(request)
         else:
             raise HTTPError(ErrorResponse(
                 responsecode.FORBIDDEN,
@@ -218,15 +218,16 @@
         """ Return True if this is a shared calendar collection """
         return hasattr(self, "_isVirtualShare")
 
+    @inlineCallbacks
     def removeVirtualShare(self, request):
         """ Return True if this is a shared calendar collection """
         
         # Remove from sharee's calendar/address book home
         if self.isCalendarCollection():
-            shareeHome = self._shareePrincipal.calendarHome(request)
+            shareeHome = yield self._shareePrincipal.calendarHome(request)
         elif self.isAddressBookCollection():
-            shareeHome = self._shareePrincipal.addressBookHome(request)
-        return shareeHome.removeShare(request, self._share)
+            shareeHome = yield self._shareePrincipal.addressBookHome(request)
+        returnValue((yield shareeHome.removeShare(request, self._share)))
 
     def resourceType(self):
         superObject = super(SharedCollectionMixin, self)
@@ -495,9 +496,9 @@
         sharee = self.principalForCalendarUserAddress(record.userid)
         if sharee:
             if self.isCalendarCollection():
-                shareeHome = sharee.calendarHome(request)
+                shareeHome = yield sharee.calendarHome(request)
             elif self.isAddressBookCollection():
-                shareeHome = sharee.addressBookHome(request)
+                shareeHome = yield sharee.addressBookHome(request)
             yield shareeHome.removeShareByUID(request, record.inviteuid)
     
             # If current user state is accepted then we send an invite with the new state, otherwise

Modified: CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/test/test_wrapping.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/test/test_wrapping.py	2010-09-22 19:48:52 UTC (rev 6338)
+++ CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/test/test_wrapping.py	2010-09-22 23:02:28 UTC (rev 6339)
@@ -91,6 +91,7 @@
         self.setupCalendars()
 
 
+    @inlineCallbacks
     def populateOneObject(self, objectName, objectText):
         """
         Populate one calendar object in the test user's calendar.
@@ -109,7 +110,7 @@
         except:
             pass
         txn = self.calendarCollection._newStore.newTransaction()
-        home = txn.calendarHomeWithUID(uid, True)
+        home = yield txn.calendarHomeWithUID(uid, True)
         cal = home.calendarWithName("calendar")
         cal.createCalendarObjectWithName(objectName, VComponent.fromString(objectText))
         txn.commit()
@@ -343,7 +344,7 @@
         parallel L{CalendarObject} will be created.  Its principal collections
         and transaction should match.
         """
-        self.populateOneObject("1.ics", event4_text)
+        yield self.populateOneObject("1.ics", event4_text)
         calendarHome = yield self.getResource("calendars/users/wsanchez")
         calDavFileCalendar = yield self.getResource(
             "calendars/users/wsanchez/calendar/1.ics"

Modified: CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/test/util.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/test/util.py	2010-09-22 19:48:52 UTC (rev 6338)
+++ CalendarServer/branches/users/glyph/more-deferreds-6/twistedcaldav/test/util.py	2010-09-22 23:02:28 UTC (rev 6339)
@@ -364,7 +364,7 @@
         self.noRenderCommit()
         if request is None:
             request = norequest()
-        users = self.homeProvisioner.getChild("users")
+        users = yield self.homeProvisioner.getChild("users")
 
         user, ignored = (yield users.locateChild(request, ["wsanchez"]))
 

Modified: CalendarServer/branches/users/glyph/more-deferreds-6/txdav/caldav/datastore/sql.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-6/txdav/caldav/datastore/sql.py	2010-09-22 19:48:52 UTC (rev 6338)
+++ CalendarServer/branches/users/glyph/more-deferreds-6/txdav/caldav/datastore/sql.py	2010-09-22 23:02:28 UTC (rev 6339)
@@ -93,6 +93,8 @@
             Opaque())
         self.createCalendarWithName("inbox")
 
+
+
 class Calendar(CommonHomeChild):
     """
     File-based implementation of L{ICalendar}.

Modified: CalendarServer/branches/users/glyph/more-deferreds-6/txdav/caldav/datastore/util.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-6/txdav/caldav/datastore/util.py	2010-09-22 19:48:52 UTC (rev 6338)
+++ CalendarServer/branches/users/glyph/more-deferreds-6/txdav/caldav/datastore/util.py	2010-09-22 23:02:28 UTC (rev 6339)
@@ -192,7 +192,7 @@
         if name == "outbox":
             continue
         outHome.createCalendarWithName(name)
-        outCalendar = outHome.calendarWithName(name)
+        outCalendar = yield outHome.calendarWithName(name)
         try:
             yield _migrateCalendar(calendar, outCalendar, getComponent)
         except InternalDataStoreError:
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20100922/e8b6e949/attachment-0001.html>


More information about the calendarserver-changes mailing list