[CalendarServer-changes] [4526] CalendarServer/branches/more-deferreds-3

source_changes at macosforge.org source_changes at macosforge.org
Fri Sep 4 14:03:38 PDT 2009


Revision: 4526
          http://trac.macosforge.org/projects/calendarserver/changeset/4526
Author:   sagen at apple.com
Date:     2009-09-04 14:03:33 -0700 (Fri, 04 Sep 2009)
Log Message:
-----------
Checkpoint: unit tests are passing except for anything relating to upgrade.py, which has to be rewritten to do things in the background.  The server runs and can schedule events, but I haven't run caldavtester yet.

Modified Paths:
--------------
    CalendarServer/branches/more-deferreds-3/calendarserver/sidecar/task.py
    CalendarServer/branches/more-deferreds-3/calendarserver/tap/test/test_caldav.py
    CalendarServer/branches/more-deferreds-3/calendarserver/webadmin/resource.py
    CalendarServer/branches/more-deferreds-3/calendarserver/webcal/resource.py
    CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.resource.patch
    CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.static.patch
    CalendarServer/branches/more-deferreds-3/run
    CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/aggregate.py
    CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/appleopendirectory.py
    CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/calendar.py
    CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/calendaruserproxy.py
    CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/directory.py
    CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/principal.py
    CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/test/test_opendirectory.py
    CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/test/test_proxyprincipalmembers.py
    CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/test/util.py
    CalendarServer/branches/more-deferreds-3/twistedcaldav/extensions.py
    CalendarServer/branches/more-deferreds-3/twistedcaldav/fileops.py
    CalendarServer/branches/more-deferreds-3/twistedcaldav/ical.py
    CalendarServer/branches/more-deferreds-3/twistedcaldav/index.py
    CalendarServer/branches/more-deferreds-3/twistedcaldav/method/put_common.py
    CalendarServer/branches/more-deferreds-3/twistedcaldav/resource.py
    CalendarServer/branches/more-deferreds-3/twistedcaldav/scheduling/implicit.py
    CalendarServer/branches/more-deferreds-3/twistedcaldav/static.py
    CalendarServer/branches/more-deferreds-3/twistedcaldav/test/test_upgrade.py
    CalendarServer/branches/more-deferreds-3/twistedcaldav/upgrade.py

Modified: CalendarServer/branches/more-deferreds-3/calendarserver/sidecar/task.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/calendarserver/sidecar/task.py	2009-09-04 20:54:14 UTC (rev 4525)
+++ CalendarServer/branches/more-deferreds-3/calendarserver/sidecar/task.py	2009-09-04 21:03:33 UTC (rev 4526)
@@ -91,7 +91,7 @@
 def processInboxItem(rootResource, directory, inboxFile, inboxItemFile, uuid):
     log.debug("Processing inbox item %s" % (inboxItemFile,))
 
-    principals = rootResource.getChild("principals")
+    principals = (yield rootResource.getChild("principals"))
     ownerPrincipal = (yield principals.principalForUID(uuid))
     cua = "urn:uuid:%s" % (uuid,)
     owner = LocalCalendarUser(cua, ownerPrincipal,
@@ -151,8 +151,8 @@
     @inlineCallbacks
     def task_scheduleinboxes(self):
 
-        calendars = self.service.root.getChild("calendars")
-        uidDir = calendars.getChild("__uids__")
+        calendars = (yield self.service.root.getChild("calendars"))
+        uidDir = (yield calendars.getChild("__uids__"))
 
         inboxItems = set()
         with open(self.taskFile) as input:
@@ -164,15 +164,15 @@
             log.info("Processing inbox item: %s" % (inboxItem,))
             ignore, uuid, ignore, fileName = inboxItem.rsplit("/", 3)
 
-            homeFile = uidDir.getChild(uuid)
+            homeFile = (yield uidDir.getChild(uuid))
             if not homeFile:
                 continue
 
-            inboxFile = homeFile.getChild("inbox")
+            inboxFile = (yield homeFile.getChild("inbox"))
             if not inboxFile:
                 continue
 
-            inboxItemFile = inboxFile.getChild(fileName)
+            inboxItemFile = (yield inboxFile.getChild(fileName))
 
             yield processInboxItem(
                 self.service.root,

Modified: CalendarServer/branches/more-deferreds-3/calendarserver/tap/test/test_caldav.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/calendarserver/tap/test/test_caldav.py	2009-09-04 20:54:14 UTC (rev 4525)
+++ CalendarServer/branches/more-deferreds-3/calendarserver/tap/test/test_caldav.py	2009-09-04 21:03:33 UTC (rev 4526)
@@ -21,6 +21,7 @@
 from twisted.python.reflect import namedAny
 from twisted.application.service import IService
 from twisted.application import internet
+from twisted.internet.defer import inlineCallbacks
 
 from twisted.web2.dav import auth
 from twisted.web2.log import LogWrapperResource
@@ -533,6 +534,7 @@
 
         self.failUnless(isinstance(root, CalDAVServiceMaker.rootResourceClass))
 
+    @inlineCallbacks
     def test_principalResource(self):
         """
         Test the principal resource
@@ -541,10 +543,11 @@
         root = site.resource.resource.resource
 
         self.failUnless(isinstance(
-            root.getChild("principals"),
+            (yield root.getChild("principals")),
             CalDAVServiceMaker.principalResourceClass
         ))
 
+    @inlineCallbacks
     def test_calendarResource(self):
         """
         Test the calendar resource
@@ -553,7 +556,7 @@
         root = site.resource.resource.resource
 
         self.failUnless(isinstance(
-            root.getChild("calendars"),
+            (yield root.getChild("calendars")),
             CalDAVServiceMaker.calendarResourceClass
         ))
 
@@ -582,28 +585,31 @@
 
     configOptions = {"HTTPPort": 8008}
 
+    @inlineCallbacks
     def test_sameDirectory(self):
         """
         Test that the principal hierarchy has a reference
         to the same DirectoryService as the calendar hierarchy
         """
         site = self.getSite()
-        principals = site.resource.resource.resource.getChild("principals")
-        calendars = site.resource.resource.resource.getChild("calendars")
+        principals = (yield site.resource.resource.resource.getChild("principals"))
+        calendars = (yield site.resource.resource.resource.getChild("calendars"))
 
         self.assertEquals(principals.directory, calendars.directory)
 
+    @inlineCallbacks
     def test_aggregateDirectory(self):
         """
         Assert that the base directory service is actually
         an AggregateDirectoryService
         """
         site = self.getSite()
-        principals = site.resource.resource.resource.getChild("principals")
+        principals = (yield site.resource.resource.resource.getChild("principals"))
         directory = principals.directory
 
         self.failUnless(isinstance(directory, AggregateDirectoryService))
 
+    @inlineCallbacks
     def test_sudoDirectoryService(self):
         """
         Test that a sudo directory service is available if the
@@ -616,7 +622,7 @@
         open(self.config.SudoersFile, "w").write(sudoersFile)
 
         site = self.getSite()
-        principals = site.resource.resource.resource.getChild("principals")
+        principals = (yield site.resource.resource.resource.getChild("principals"))
         directory = principals.directory
 
         self.failUnless(self.config.SudoersFile)
@@ -632,6 +638,7 @@
             in directory.userRecordTypes
         )
 
+    @inlineCallbacks
     def test_sudoDirectoryServiceNoFile(self):
         """
         Test that there is no SudoDirectoryService if
@@ -641,7 +648,7 @@
 
         self.writeConfig()
         site = self.getSite()
-        principals = site.resource.resource.resource.getChild("principals")
+        principals = (yield site.resource.resource.resource.getChild("principals"))
         directory = principals.directory
 
         self.failUnless(self.config.SudoersFile)
@@ -652,13 +659,14 @@
             SudoDirectoryService.recordType_sudoers
         )
 
+    @inlineCallbacks
     def test_sudoDirectoryServiceNotConfigured(self):
         """
         Test that there is no SudoDirectoryService if
         the SudoersFile is not configured
         """
         site = self.getSite()
-        principals = site.resource.resource.resource.getChild("principals")
+        principals = (yield site.resource.resource.resource.getChild("principals"))
         directory = principals.directory
 
         self.failIf(self.config.SudoersFile)
@@ -669,13 +677,14 @@
             SudoDirectoryService.recordType_sudoers
         )
 
+    @inlineCallbacks
     def test_configuredDirectoryService(self):
         """
         Test that the real directory service is the directory service
         set in the configuration file.
         """
         site = self.getSite()
-        principals = site.resource.resource.resource.getChild("principals")
+        principals = (yield site.resource.resource.resource.getChild("principals"))
         directory = principals.directory
 
         realDirectory = directory.serviceForRecordType("users")

Modified: CalendarServer/branches/more-deferreds-3/calendarserver/webadmin/resource.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/calendarserver/webadmin/resource.py	2009-09-04 20:54:14 UTC (rev 4525)
+++ CalendarServer/branches/more-deferreds-3/calendarserver/webadmin/resource.py	2009-09-04 21:03:33 UTC (rev 4526)
@@ -52,7 +52,7 @@
     
     def etag(self):
         # Can't be calculated here
-        return None
+        return succeed(None)
 
     def contentLength(self):
         # Can't be calculated here
@@ -65,7 +65,7 @@
         return True
 
     def displayName(self):
-        return "Web Admin"
+        return succeed("Web Admin")
 
     def contentType(self):
         return MimeType.fromString("text/html; charset=utf-8");

Modified: CalendarServer/branches/more-deferreds-3/calendarserver/webcal/resource.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/calendarserver/webcal/resource.py	2009-09-04 20:54:14 UTC (rev 4525)
+++ CalendarServer/branches/more-deferreds-3/calendarserver/webcal/resource.py	2009-09-04 21:03:33 UTC (rev 4526)
@@ -69,7 +69,7 @@
         return True
 
     def displayName(self):
-        return "Web Calendar"
+        return succeed("Web Calendar")
 
     def contentType(self):
         return MimeType.fromString("text/html; charset=utf-8");

Modified: CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.resource.patch
===================================================================
--- CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.resource.patch	2009-09-04 20:54:14 UTC (rev 4525)
+++ CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.resource.patch	2009-09-04 21:03:33 UTC (rev 4526)
@@ -126,7 +126,7 @@
              if (qname not in qnames) and (qname[0] != twisted_private_namespace):
                  qnames.add(qname)
  
-@@ -495,37 +529,62 @@
+@@ -495,37 +529,58 @@
          in the dead property store may or may not be ignored when reading the
          property with L{readProperty}.
          """
@@ -147,7 +147,6 @@
 +                    qname = property
 +                else:
 +                    qname = property.qname()
-+                # MOR: Double check I can return a deferred here
 +                return self.deadProperties().delete(qname)
              else:
 -                qname = property.qname()
@@ -163,19 +162,15 @@
      # Overrides some methods in MetaDataMixin in order to allow DAV properties
      # to override the values of some HTTP metadata.
      #
++    @inlineCallbacks
      def contentType(self):
 -        if self.hasDeadProperty((davxml.dav_namespace, "getcontenttype")):
 -            return self.readDeadProperty((davxml.dav_namespace, "getcontenttype")).mimeType()
--        else:
++        if (yield self.hasDeadProperty((davxml.dav_namespace, "getcontenttype"))):
++            returnValue((yield self.readDeadProperty((davxml.dav_namespace, "getcontenttype"))).mimeType())
+         else:
 -            return super(DAVPropertyMixIn, self).contentType()
-+        def callback(result):
-+            if result:
-+                return self.readDeadProperty((davxml.dav_namespace, "getcontenttype")).mimeType()
-+            else:
-+                return super(DAVPropertyMixIn, self).contentType()
-+        d = self.hasDeadProperty((davxml.dav_namespace, "getcontenttype"))
-+        d.addCallback(callback)
-+        return d
++            returnValue((yield super(DAVPropertyMixIn, self).contentType()))
  
 +    @inlineCallbacks
      def displayName(self):
@@ -202,7 +197,7 @@
  class DAVResource (DAVPropertyMixIn, StaticRenderMixin):
      """
      WebDAV resource.
-@@ -578,11 +637,10 @@
+@@ -578,11 +633,10 @@
  
          completionDeferred = Deferred()
          basepath = request.urlForResource(self)
@@ -216,7 +211,7 @@
  
          def checkPrivileges(child):
              if child is None:
-@@ -595,7 +653,7 @@
+@@ -595,7 +649,7 @@
              d.addCallback(lambda _: child)
              return d
  
@@ -225,7 +220,7 @@
              if child is None:
                  callback(None, childpath + "/")
              else:
-@@ -603,14 +661,15 @@
+@@ -603,14 +657,15 @@
                      callback(child, childpath + "/")
                      if depth == "infinity":
                          d = child.findChildren(depth, request, callback, privileges)
@@ -244,7 +239,7 @@
              try:
                  childname = children.pop()
              except IndexError:
-@@ -619,10 +678,10 @@
+@@ -619,10 +674,10 @@
                  childpath = joinURL(basepath, childname)
                  d = request.locateChildResource(self, childname)
                  d.addCallback(checkPrivileges)
@@ -257,7 +252,7 @@
  
          return completionDeferred
  
-@@ -642,41 +701,43 @@
+@@ -642,41 +697,43 @@
      # Authentication
      ##
  
@@ -328,7 +323,7 @@
      def authenticate(self, request):
          if not (
              hasattr(request, 'portal') and 
-@@ -761,7 +822,7 @@
+@@ -761,7 +818,7 @@
          # and deny any type of write access (PUT, DELETE, etc.) to
          # everything.
          #
@@ -337,7 +332,7 @@
  
      def defaultAccessControlList(self):
          """
-@@ -772,7 +833,7 @@
+@@ -772,7 +829,7 @@
          # The default behaviour is no ACL; we should inherrit from the parent
          # collection.
          #
@@ -346,7 +341,7 @@
  
      def setAccessControlList(self, acl):
          """
-@@ -781,7 +842,7 @@
+@@ -781,7 +838,7 @@
          This implementation stores the ACL in the private property
          C{(L{twisted_private_namespace}, "acl")}.
          """
@@ -355,7 +350,7 @@
  
      def mergeAccessControlList(self, new_acl, request):
          """
-@@ -926,7 +987,9 @@
+@@ -926,7 +983,9 @@
          # FIXME: verify acl is self-consistent
  
          # Step 11
@@ -366,7 +361,7 @@
          yield None
  
      mergeAccessControlList = deferredGenerator(mergeAccessControlList)
-@@ -1089,7 +1152,9 @@
+@@ -1089,7 +1148,9 @@
              return url
  
          try:
@@ -377,7 +372,7 @@
          except HTTPError, e:
              assert e.response.code == responsecode.NOT_FOUND, (
                  "Expected %s response from readDeadProperty() exception, not %s"
-@@ -1102,9 +1167,11 @@
+@@ -1102,9 +1163,11 @@
  
              if myURL == "/":
                  # If we get to the root without any ACLs, then use the default.
@@ -391,7 +386,7 @@
  
          # Dynamically update privileges for those ace's that are inherited.
          if inheritance:
-@@ -1223,16 +1290,21 @@
+@@ -1223,16 +1286,21 @@
              It will errback with an HTTPError(responsecode.FORBIDDEN) if
              the principal isn't found.
          """
@@ -417,7 +412,7 @@
      def findPrincipalForAuthID(self, authid):
          """
          Return authentication and authoirization prinicipal identifiers for the
-@@ -1247,11 +1319,16 @@
+@@ -1247,11 +1315,16 @@
              If not found return None.
          """
          for collection in self.principalCollections():
@@ -437,7 +432,7 @@
      def authorizationPrincipal(self, request, authid, authnPrincipal):
          """
          Determine the authorization principal for the given request and authentication principal.
-@@ -1635,7 +1712,9 @@
+@@ -1635,7 +1708,9 @@
  
          # Check this resource first
          if self.isCollection():
@@ -448,7 +443,7 @@
              if qroot is not None:
                  used = waitForDeferred(self.currentQuotaUse(request))
                  yield used
-@@ -1666,14 +1745,17 @@
+@@ -1666,14 +1741,17 @@
  
      def hasQuota(self, request):
          """
@@ -468,7 +463,7 @@
              yield True
              return
          
-@@ -1705,10 +1787,19 @@
+@@ -1705,10 +1783,19 @@
          @return: a C{int} containing the maximum allowed bytes if this collection
              is quota-controlled, or C{None} if not quota controlled.
          """
@@ -491,7 +486,7 @@
      
      def quotaRootParent(self, request):
          """
-@@ -1724,7 +1815,10 @@
+@@ -1724,7 +1811,10 @@
              parent = waitForDeferred(request.locateResource(url))
              yield parent
              parent = parent.getResult()
@@ -503,7 +498,7 @@
                  yield parent
                  return
  
-@@ -1741,11 +1835,19 @@
+@@ -1741,11 +1831,19 @@
          assert maxsize is None or isinstance(maxsize, int), "maxsize must be an int or None"
          
          if maxsize is not None:
@@ -526,7 +521,7 @@
      
      def quotaSize(self, request):
          """
-@@ -1795,7 +1897,10 @@
+@@ -1795,7 +1893,10 @@
          
          # Check this resource first
          if self.isCollection():
@@ -538,7 +533,7 @@
                  d = waitForDeferred(self.updateQuotaUse(request, adjust))
                  yield d
                  d.getResult()
-@@ -1825,20 +1930,34 @@
+@@ -1825,20 +1926,34 @@
              is quota-controlled, or C{None} if not quota controlled.
          """
          assert self.isCollection(), "Only collections can have a quota root"
@@ -582,7 +577,7 @@
      def updateQuotaUse(self, request, adjust):
          """
          Update the quota used value on this resource.
-@@ -1848,25 +1967,32 @@
+@@ -1848,25 +1963,32 @@
          @return: an L{Deferred} with a C{int} result containing the current used byte if this collection
              is quota-controlled, or C{None} if not quota controlled.
          """
@@ -632,7 +627,7 @@
      ##
      # HTTP
      ##
-@@ -1880,7 +2006,7 @@
+@@ -1880,7 +2002,7 @@
          # If this is a collection and the URI doesn't end in "/", redirect.
          #
          if self.isCollection() and request.path[-1:] != "/":

Modified: CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.static.patch
===================================================================
--- CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.static.patch	2009-09-04 20:54:14 UTC (rev 4525)
+++ CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.static.patch	2009-09-04 21:03:33 UTC (rev 4526)
@@ -20,6 +20,15 @@
  
      def lastModified(self):
          """
+@@ -64,7 +64,7 @@
+         """
+         @return: The display name of the resource if available, None otherwise.
+         """
+-        return None
++        return succeed(None)
+ 
+     def exists(self):
+         """
 @@ -76,18 +76,26 @@
      def checkPreconditions(self, request):
          # This code replaces the code in resource.RenderMixin
@@ -115,6 +124,18 @@
  
      def lastModified(self):
          if self.fp.exists():
+@@ -279,9 +294,9 @@
+ 
+     def displayName(self):
+         if self.fp.exists():
+-            return self.fp.basename()
++            return succeed(self.fp.basename())
+         else:
+-            return None
++            return succeed(None)
+ 
+     def ignoreExt(self, ext):
+         """Ignore the given extension.
 @@ -291,12 +306,13 @@
          self.ignoredExts.append(ext)
  

Modified: CalendarServer/branches/more-deferreds-3/run
===================================================================
--- CalendarServer/branches/more-deferreds-3/run	2009-09-04 20:54:14 UTC (rev 4525)
+++ CalendarServer/branches/more-deferreds-3/run	2009-09-04 21:03:33 UTC (rev 4526)
@@ -50,7 +50,7 @@
          kill="false";
       restart="false";
   plugin_name="caldav";
- service_type="Single";
+ service_type="Combined";
      read_key="";
       profile="";
       reactor="";

Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/aggregate.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/aggregate.py	2009-09-04 20:54:14 UTC (rev 4525)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/aggregate.py	2009-09-04 21:03:33 UTC (rev 4526)
@@ -168,13 +168,14 @@
         
         raise UnauthorizedLogin("No such user: %s" % (credentials.credentials.username,))
 
+    @inlineCallbacks
     def getResourceInfo(self):
         results = []
         for service in self._recordTypes.values():
-            for result in service.getResourceInfo():
+            for result in (yield service.getResourceInfo()):
                 if result:
                     results.append(result)
-        return results
+        returnValue(results)
 
 class DuplicateRecordTypeError(DirectoryError):
     """

Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/appleopendirectory.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/appleopendirectory.py	2009-09-04 20:54:14 UTC (rev 4525)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/appleopendirectory.py	2009-09-04 21:03:33 UTC (rev 4526)
@@ -896,7 +896,7 @@
     @inlineCallbacks
     def groups(self):
         if self._groupMembershipGUIDs is None:
-            self._groupMembershipGUIDs = self.service.groupsForGUID(self.guid)
+            self._groupMembershipGUIDs = (yield self.service.groupsForGUID(self.guid))
 
         results = []
         for guid in self._groupMembershipGUIDs:

Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/calendar.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/calendar.py	2009-09-04 20:54:14 UTC (rev 4525)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/calendar.py	2009-09-04 21:03:33 UTC (rev 4526)
@@ -469,4 +469,4 @@
         @return: a C{int} containing the maximum allowed bytes if this collection
             is quota-controlled, or C{None} if not quota controlled.
         """
-        return config.UserQuota if config.UserQuota != 0 else None
+        return succeed(config.UserQuota if config.UserQuota != 0 else None)

Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/calendaruserproxy.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/calendaruserproxy.py	2009-09-04 20:54:14 UTC (rev 4525)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/calendaruserproxy.py	2009-09-04 21:03:33 UTC (rev 4526)
@@ -276,7 +276,7 @@
     ##
 
     def displayName(self):
-        return self.proxyType
+        return succeed(self.proxyType)
 
     ##
     # ACL

Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/directory.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/directory.py	2009-09-04 20:54:14 UTC (rev 4525)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/directory.py	2009-09-04 21:03:33 UTC (rev 4526)
@@ -82,6 +82,7 @@
     # For ICredentialsChecker
     credentialInterfaces = (IPrincipalCredentials,)
 
+    # called using maybeDeferred...
     def requestAvatarId(self, credentials):
         credentials = IPrincipalCredentials(credentials)
 

Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/principal.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/principal.py	2009-09-04 20:54:14 UTC (rev 4525)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/principal.py	2009-09-04 21:03:33 UTC (rev 4526)
@@ -410,18 +410,19 @@
         else:
             return self.principalForShortName(self.recordType, name)
 
+    @inlineCallbacks
     def listChildren(self):
         if config.EnablePrincipalListings:
+            results = []
+            for record in (yield self.directory.listRecords(self.recordType)):
+                for shortName in record.shortNames:
+                    results.append(shortName)
+            returnValue(results)
 
-            def _recordShortnameExpand():
-                for record in self.directory.listRecords(self.recordType):
-                    for shortName in record.shortNames:
-                        yield shortName
-
-            return succeed(_recordShortnameExpand())
+            # return succeed(_recordShortnameExpand())
         else:
             # Not a listable collection
-            return fail(HTTPError(responsecode.FORBIDDEN))
+            raise HTTPError(responsecode.FORBIDDEN)
 
     ##
     # ACL
@@ -645,9 +646,9 @@
 
     def displayName(self):
         if self.record.fullName:
-            return self.record.fullName
+            return succeed(self.record.fullName)
         else:
-            return self.record.shortNames[0]
+            return succeed(self.record.shortNames[0])
 
     ##
     # ACL

Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/test/test_opendirectory.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/test/test_opendirectory.py	2009-09-04 20:54:14 UTC (rev 4525)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/test/test_opendirectory.py	2009-09-04 21:03:33 UTC (rev 4526)
@@ -102,6 +102,7 @@
 
             self.assertFalse((yield record.verifyCredentials(digested)))
 
+        @inlineCallbacks
         def test_validODDigest(self):
             record = OpenDirectoryRecord(
                 service               = self.service(),
@@ -141,12 +142,12 @@
             record.digestcache["/"] = response
             digested = twisted.web2.auth.digest.DigestedCredentials("user", "GET", "example.com", digestFields, None)
 
-            self.assertTrue(record.verifyCredentials(digested))
+            self.assertTrue((yield record.verifyCredentials(digested)))
 
             # This should be defaulted
             del digestFields["algorithm"]
 
-            self.assertTrue(record.verifyCredentials(digested))
+            self.assertTrue((yield record.verifyCredentials(digested)))
 
         @inlineCallbacks
         def test_queryDirectorySingleGUID(self):

Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/test/test_proxyprincipalmembers.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/test/test_proxyprincipalmembers.py	2009-09-04 20:54:14 UTC (rev 4525)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/test/test_proxyprincipalmembers.py	2009-09-04 21:03:33 UTC (rev 4526)
@@ -60,7 +60,7 @@
             principal = (yield principal.getChild(subPrincipalName))
 
         members = (yield principal.expandedGroupMembers())
-        memberNames = set([p.displayName() for p in members])
+        memberNames = set([(yield p.displayName()) for p in members])
         self.assertEquals(memberNames, set(expectedMembers))
 
     @inlineCallbacks

Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/test/util.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/test/util.py	2009-09-04 20:54:14 UTC (rev 4525)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/test/util.py	2009-09-04 21:03:33 UTC (rev 4526)
@@ -120,6 +120,7 @@
         if record is None:
             raise SkipTest("No calendar user addresses provided to test")
 
+    @inlineCallbacks
     def test_groupMembers(self):
         """
         IDirectoryRecord.members()
@@ -131,13 +132,14 @@
         for group, info in self.groups.iteritems():
             prefix = info.get("prefix", "")
             groupRecord = (yield service.recordWithShortName(prefix + DirectoryService.recordType_groups, group))
-            result = set((m.recordType, prefix + m.shortNames[0]) for m in groupRecord.members())
+            result = set((m.recordType, prefix + m.shortNames[0]) for m in (yield groupRecord.members()))
             expected = set(self.groups[group]["members"])
             self.assertEquals(
                 result, expected,
                 "Wrong membership for group %r: %s != %s" % (group, result, expected)
             )
 
+    @inlineCallbacks
     def test_groupMemberships(self):
         """
         IDirectoryRecord.groups()
@@ -155,7 +157,7 @@
             for shortName, info in data.iteritems():
                 prefix = info.get("prefix", "")
                 record = (yield service.recordWithShortName(prefix + recordType, shortName))
-                result = set(prefix + g.shortNames[0] for g in record.groups())
+                result = set(prefix + g.shortNames[0] for g in (yield record.groups()))
                 expected = set(g for g in self.groups if (record.recordType, shortName) in self.groups[g]["members"])
                 self.assertEquals(
                     result, expected,

Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/extensions.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/extensions.py	2009-09-04 20:54:14 UTC (rev 4525)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/extensions.py	2009-09-04 21:03:33 UTC (rev 4526)
@@ -779,14 +779,15 @@
             returnValue(davxml.ResourceType.collection)
         returnValue(davxml.ResourceType.empty)
 
+    @inlineCallbacks
     def render(self, request):
         if not self.fp.exists():
-            return responsecode.NOT_FOUND
+            returnValue(responsecode.NOT_FOUND)
 
         if self.fp.isdir():
             if request.path[-1] != "/":
                 # Redirect to include trailing '/' in URI
-                return RedirectResponse(request.unparseURL(path=urllib.quote(urllib.unquote(request.path), safe=':/')+'/'))
+                returnValue(RedirectResponse(request.unparseURL(path=urllib.quote(urllib.unquote(request.path), safe=':/')+'/')))
             else:
                 # MOR: Not sure what to do here -- it may be that render( )
                 # can't easily be deferred, in which case createSimilarFile( )
@@ -794,18 +795,19 @@
                 ifp = self.fp.childSearchPreauth(*self.indexNames)
                 if ifp:
                     # Render from the index file
-                    return self.createSimilarFile(ifp.path).render(request)
+                    returnValue((yield self.createSimilarFile(ifp.path).render(request)))
 
-                return self.renderDirectory(request)
+                # MOR: is renderDirectory deferred?
+                returnValue(self.renderDirectory(request))
 
         try:
             f = self.fp.open()
         except IOError, e:
             import errno
             if e[0] == errno.EACCES:
-                return responsecode.FORBIDDEN
+                returnValue(responsecode.FORBIDDEN)
             elif e[0] == errno.ENOENT:
-                return responsecode.NOT_FOUND
+                returnValue(responsecode.NOT_FOUND)
             else:
                 raise
 
@@ -813,13 +815,13 @@
         response.stream = FileStream(f, 0, self.fp.getsize())
 
         for (header, value) in (
-            ("content-type", self.contentType()),
+            ("content-type", (yield self.contentType())),
             ("content-encoding", self.contentEncoding()),
         ):
             if value is not None:
                 response.headers.setHeader(header, value)
 
-        return response
+        returnValue(response)
 
     def directoryStyleSheet(self):
         return (
@@ -875,6 +877,7 @@
         d.addCallback(gotBody)
         return d
 
+    # MOR: This is not working at the moment -- gotValues( ) isn't getting a sequence
     @printTracebacks
     def renderDirectoryBody(self, request):
         """
@@ -889,9 +892,11 @@
 
         even = Alternator()
         d = self.listChildren()
+
+        @inlineCallbacks
         def _gotChildren(children):
             for name in sorted(children):
-                child = self.getChild(name)
+                child = (yield self.getChild(name))
 
                 url, name, size, lastModified, contentType = self.getChildDirectoryEntry(child, name)
 

Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/fileops.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/fileops.py	2009-09-04 20:54:14 UTC (rev 4525)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/fileops.py	2009-09-04 21:03:33 UTC (rev 4526)
@@ -22,12 +22,15 @@
 from twisted.web2.dav.fileop import put
 from twisted.web2.dav.xattrprops import xattrPropertyStore
 
+from twisted.internet.defer import inlineCallbacks, returnValue
+
 # This class simulates a DAVFile with enough information for use with xattrPropertyStore.
 class FakeXAttrResource(object):
     
     def __init__(self, fp):
         self.fp = fp
 
+ at inlineCallbacks
 def putWithXAttrs(stream, filepath):
     """
     Write a file to a possibly existing path and preserve any xattrs at that path.
@@ -42,26 +45,22 @@
     props = []
     if filepath.exists():
         xold = xattrPropertyStore(FakeXAttrResource(filepath))
-        for item in xold.list():
-            props.append((xold.get(item)))
+        for item in (yield xold.list()):
+            props.append((yield xold.get(item)))
         xold = None
-    
-    # First do the actual file copy
-    def _gotResponse(response):
-    
-        # Restore original xattrs.
-        if props:
-            xnew = xattrPropertyStore(FakeXAttrResource(filepath))
-            for prop in props:
-                xnew.set(prop)
-            xnew = None
-    
-        return response
 
-    d = put(stream, filepath)
-    d.addCallback(_gotResponse)
-    return d
+    response = (yield put(stream, filepath))
 
+    # Restore original xattrs.
+    if props:
+        xnew = xattrPropertyStore(FakeXAttrResource(filepath))
+        for prop in props:
+            yield xnew.set(prop)
+        xnew = None
+
+    returnValue(response)
+
+
 def copyWithXAttrs(source_filepath, destination_filepath, destination_uri):
     """
     Copy a file from one path to another and also copy xattrs we care about.
@@ -102,10 +101,11 @@
     # Now copy over xattrs.
     copyXAttrs(from_fp, to_fp)
 
+ at inlineCallbacks
 def copyXAttrs(from_fp, to_fp):    
     # Create xattr stores for each file and copy over all xattrs.
     xfrom = xattrPropertyStore(FakeXAttrResource(from_fp))
     xto = xattrPropertyStore(FakeXAttrResource(to_fp))
 
-    for item in xfrom.list():
-        xto.set(xfrom.get(item))
+    for item in (yield xfrom.list()):
+        yield xto.set((yield xfrom.get(item)))

Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/ical.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/ical.py	2009-09-04 20:54:14 UTC (rev 4525)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/ical.py	2009-09-04 21:03:33 UTC (rev 4526)
@@ -34,6 +34,7 @@
 
 from twisted.web2.dav.util import allDataFromStream
 from twisted.web2.stream import IStream
+from twisted.internet.defer import inlineCallbacks
 
 from twistedcaldav.dateops import compareDateTime, normalizeToUTC, timeRangesOverlap,\
     normalizeStartEndDuration, toString, normalizeForIndex, differenceDateTime
@@ -2075,11 +2076,12 @@
                     if dataValue.find(dropboxPrefix) != -1:
                         self.removeProperty(attachment)
 
+    @inlineCallbacks
     def normalizeCalendarUserAddresses(self, lookupFunction):
         """
         Do the ORGANIZER/ATTENDEE property normalization.
 
-        @param lookupFunction: function returning full name, guid, CUAs for a given CUA
+        @param lookupFunction: function returning full name, guid, CUAs for a given CUA (Deferred)
         @type lookupFunction: L{Function}
         """
         for component in self.subcomponents():
@@ -2093,7 +2095,7 @@
                 # Check that we can lookup this calendar user address - if not
                 # we cannot do anything with it
                 cuaddr = normalizeCUAddr(prop.value())
-                name, guid, cuaddrs = lookupFunction(cuaddr)
+                name, guid, cuaddrs = (yield lookupFunction(cuaddr))
                 if guid is None:
                     continue
 

Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/index.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/index.py	2009-09-04 20:54:14 UTC (rev 4525)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/index.py	2009-09-04 21:03:33 UTC (rev 4526)
@@ -42,7 +42,7 @@
 
 from vobject.icalendar import utc
 
-from twisted.internet.defer import maybeDeferred, succeed, returnValue
+from twisted.internet.defer import maybeDeferred, succeed, returnValue, inlineCallbacks
 
 from twistedcaldav.ical import Component
 from twistedcaldav.query import calendarquery
@@ -162,6 +162,7 @@
         """
         raise NotImplementedError
 
+    @inlineCallbacks
     def resourceNamesForUID(self, uid):
         """
         Looks up the names of the resources with the given UID.
@@ -177,7 +178,7 @@
         resources = []
         for name in names:
             name_utf8 = name.encode("utf-8")
-            if name is not None and self.resource.getChild(name_utf8) is None:
+            if name is not None and (yield self.resource.getChild(name_utf8)) is None:
                 # Clean up
                 log.err("Stale resource record found for child %s with UID %s in %s" % (name, uid, self.resource))
                 self._delete_from_db(name, uid)
@@ -185,8 +186,9 @@
             else:
                 resources.append(name)
 
-        return resources
+        returnValue(resources)
 
+    @inlineCallbacks
     def resourceNameForUID(self, uid):
         """
         Looks up the name of the resource with the given UID.
@@ -195,11 +197,11 @@
         """
         result = None
 
-        for name in self.resourceNamesForUID(uid):
+        for name in (yield self.resourceNamesForUID(uid)):
             assert result is None, "More than one resource with UID %s in calendar collection %r" % (uid, self)
             result = name
 
-        return succeed(result)
+        returnValue(result)
 
     def resourceUIDForName(self, name):
         """
@@ -274,6 +276,7 @@
             self.log_info("Search falls outside range of index for %s %s" % (name, minDate))
             self.reExpandResource(name, minDate)
 
+    @inlineCallbacks
     def indexedSearch(self, filter, fbtype=False):
         """
         Finds resources matching the given qualifiers.
@@ -324,14 +327,15 @@
         rows = []
         for row in rowiter:
             name = row[0]
-            if self.resource.getChild(name.encode("utf-8")):
+            if (yield self.resource.getChild(name.encode("utf-8"))):
                 rows.append(row)
             else:
                 log.err("Calendar resource %s is missing from %s. Removing from index."
                         % (name, self.resource))
                 self.deleteResource(name)
-        return succeed(rows)
+        returnValue(rows)
 
+    @inlineCallbacks
     def bruteForceSearch(self):
         """
         List the whole index and tests for existence, updating the index
@@ -344,13 +348,13 @@
         rows = []
         for row in rowiter:
             name = row[0]
-            if self.resource.getChild(name.encode("utf-8")):
+            if (yield self.resource.getChild(name.encode("utf-8"))):
                 rows.append(row)
             else:
                 log.err("Calendar resource %s is missing from %s. Removing from index."
                         % (name, self.resource))
                 self.deleteResource(name)
-        return succeed(rows)
+        returnValue(rows)
 
     def _db_version(self):
         """

Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/method/put_common.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/method/put_common.py	2009-09-04 20:54:14 UTC (rev 4525)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/method/put_common.py	2009-09-04 21:03:33 UTC (rev 4526)
@@ -644,6 +644,7 @@
 
         returnValue(None)
 
+    @inlineCallbacks
     def setupRollback(self):
         """
         We may need to restore the original resource data if the PUT/COPY/MOVE fails,
@@ -659,7 +660,7 @@
         self.overwrite = self.destination.exists()
         if self.overwrite:
             self.rollback.destination_copy = FilePath(_createRollbackPath(self.destination.fp.path))
-            copyToWithXAttrs(self.destination.fp, self.rollback.destination_copy)
+            yield copyToWithXAttrs(self.destination.fp, self.rollback.destination_copy)
             log.debug("Rollback: backing up destination %s to %s" % (self.destination.fp.path, self.rollback.destination_copy.path))
         else:
             self.rollback.destination_created = True
@@ -667,7 +668,7 @@
 
         if self.deletesource:
             self.rollback.source_copy = FilePath(_createRollbackPath(self.source.fp.path))
-            copyToWithXAttrs(self.source.fp, self.rollback.source_copy)
+            yield copyToWithXAttrs(self.source.fp, self.rollback.source_copy)
             log.debug("Rollback: backing up source %s to %s" % (self.source.fp.path, self.rollback.source_copy.path))
 
     def truncateRecurrence(self):
@@ -995,7 +996,7 @@
                 is_scheduling_resource, data_changed, did_implicit_action = implicit_result
 
             # Initialize the rollback system
-            self.setupRollback()
+            yield self.setupRollback()
 
             """
             Handle actual store operations here.
@@ -1064,7 +1065,7 @@
                             etags = (yield self.destination.readDeadProperty(TwistedScheduleMatchETags)).children
                         else:
                             etags = ()
-                    etags += (davxml.GETETag.fromString(self.destination.etag().tag),)
+                    etags += (davxml.GETETag.fromString((yield self.destination.etag()).tag),)
                     yield self.destination.writeDeadProperty(TwistedScheduleMatchETags(*etags))
                 else:
                     yield self.destination.removeDeadProperty(TwistedScheduleMatchETags)                

Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/resource.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/resource.py	2009-09-04 20:54:14 UTC (rev 4525)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/resource.py	2009-09-04 21:03:33 UTC (rev 4526)
@@ -436,9 +436,9 @@
     def displayName(self):
         if 'record' in dir(self):
             if self.record.fullName:
-                return self.record.fullName
+                return succeed(self.record.fullName)
             elif self.record.shortNames:
-                return self.record.shortNames[0]
+                return succeed(self.record.shortNames[0])
             else:
                 return super(DAVResource, self).displayName()
         else:
@@ -510,16 +510,6 @@
             d.addCallback(isCalCallback)
             return d
 
-            """ MOR: Remove
-            if child.isCalendarCollection():
-                callback(child, childpath)
-            elif child.isCollection():
-                if depth == "infinity":
-                    fc = child.findCalendarCollections(depth, request, callback, privileges)
-                    fc.addCallback(lambda x: reactor.callLater(0, getChild, children))
-                    return fc
-            reactor.callLater(0, getChild, children)
-            """
 
         def getChild(children):
             try:
@@ -671,7 +661,7 @@
         """
         return self.iCalendar(name).addCallback(caldavxml.CalendarData.fromCalendar)
 
-    # Deferred
+    # Deferred, because the lookup function has to be
     def iCalendarAddressDoNormalization(self, ical):
         """
         Normalize calendar user addresses in the supplied iCalendar object into their
@@ -1026,7 +1016,7 @@
         """
         Quota root only ever set on calendar homes.
         """
-        return None
+        return succeed(None)
 
 
 class AuthenticationWrapper(SuperAuthenticationWrapper):

Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/scheduling/implicit.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/scheduling/implicit.py	2009-09-04 20:54:14 UTC (rev 4525)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/scheduling/implicit.py	2009-09-04 21:03:33 UTC (rev 4526)
@@ -212,7 +212,7 @@
         organizer_scheduling = (yield self.isOrganizerScheduling())
         if organizer_scheduling:
             self.state = "organizer"
-        elif self.isAttendeeScheduling():
+        elif (yield self.isAttendeeScheduling()):
             self.state = "attendee"
         else:
             self.state = None

Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/static.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/static.py	2009-09-04 20:54:14 UTC (rev 4525)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/static.py	2009-09-04 21:03:33 UTC (rev 4526)
@@ -756,7 +756,7 @@
     def getChild(self, name):
         # This avoids finding case variants of put children on case-insensitive filesystems.
         if name not in self.putChildren and name.lower() in (x.lower() for x in self.putChildren):
-            returnValue(None)
+            return succeed(None)
 
         return super(CalendarHomeFile, self).getChild(name)
 

Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/test/test_upgrade.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/test/test_upgrade.py	2009-09-04 20:54:14 UTC (rev 4525)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/test/test_upgrade.py	2009-09-04 21:03:33 UTC (rev 4526)
@@ -1145,7 +1145,7 @@
             results = []
             for guid, info in assignments.iteritems():
                 results.append( (guid, info[0], info[1], info[2]) )
-            return results
+            return succeed(results)
 
         self.setUpInitialStates()
         # Override the normal getResourceInfo method with our own:

Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/upgrade.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/upgrade.py	2009-09-04 20:54:14 UTC (rev 4525)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/upgrade.py	2009-09-04 21:03:33 UTC (rev 4526)
@@ -83,6 +83,7 @@
 
 
 
+    @inlineCallbacks
     def normalizeCUAddrs(data, directory):
         cal = Component.fromString(data)
 
@@ -140,6 +141,7 @@
                     continue
 
                 try:
+                    # MOR: Defer this:
                     data, fixed = normalizeCUAddrs(data, directory)
                     if fixed:
                         log.debug("Normalized CUAddrs in %s" % (resPath,))
@@ -252,11 +254,12 @@
         os.rename(oldHome, newHome)
 
 
+    @inlineCallbacks
     def migrateResourceInfo(config, directory, uid, gid):
         log.info("Fetching delegate assignments and auto-schedule settings from directory")
         resourceInfoDatabase = ResourceInfoDatabase(config.DataRoot)
         calendarUserProxyDatabase = CalendarUserProxyDatabase(config.DataRoot)
-        resourceInfo = directory.getResourceInfo()
+        resourceInfo = (yield directory.getResourceInfo())
         for guid, autoSchedule, proxy, readOnlyProxy in resourceInfo:
             resourceInfoDatabase.setAutoScheduleInDatabase(guid, autoSchedule)
             if proxy:
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20090904/429b7290/attachment-0001.html>


More information about the calendarserver-changes mailing list