[CalendarServer-changes] [4513] CalendarServer/branches/more-deferreds-3
source_changes at macosforge.org
source_changes at macosforge.org
Fri Aug 28 13:49:32 PDT 2009
Revision: 4513
http://trac.macosforge.org/projects/calendarserver/changeset/4513
Author: sagen at apple.com
Date: 2009-08-28 13:49:31 -0700 (Fri, 28 Aug 2009)
Log Message:
-----------
Checkpoint -- more methods being deferred
Modified Paths:
--------------
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.dav.static.patch
CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.test_acl.patch
CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.test_copy.patch
CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.test_delete.patch
CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.test_mkcol.patch
CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.test_move.patch
CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.test_prop.patch
CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.test_put.patch
CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.util.patch
CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.static.patch
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/principal.py
CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/test/test_principal.py
CalendarServer/branches/more-deferreds-3/twistedcaldav/dropbox.py
CalendarServer/branches/more-deferreds-3/twistedcaldav/extensions.py
CalendarServer/branches/more-deferreds-3/twistedcaldav/freebusyurl.py
CalendarServer/branches/more-deferreds-3/twistedcaldav/index.py
CalendarServer/branches/more-deferreds-3/twistedcaldav/mail.py
CalendarServer/branches/more-deferreds-3/twistedcaldav/memcacheprops.py
CalendarServer/branches/more-deferreds-3/twistedcaldav/method/copymove.py
CalendarServer/branches/more-deferreds-3/twistedcaldav/method/delete_common.py
CalendarServer/branches/more-deferreds-3/twistedcaldav/method/put.py
CalendarServer/branches/more-deferreds-3/twistedcaldav/method/report_calquery.py
CalendarServer/branches/more-deferreds-3/twistedcaldav/method/report_common.py
CalendarServer/branches/more-deferreds-3/twistedcaldav/method/report_multiget.py
CalendarServer/branches/more-deferreds-3/twistedcaldav/resource.py
CalendarServer/branches/more-deferreds-3/twistedcaldav/schedule.py
CalendarServer/branches/more-deferreds-3/twistedcaldav/scheduling/caldav.py
CalendarServer/branches/more-deferreds-3/twistedcaldav/scheduling/implicit.py
CalendarServer/branches/more-deferreds-3/twistedcaldav/scheduling/processing.py
CalendarServer/branches/more-deferreds-3/twistedcaldav/scheduling/scheduler.py
CalendarServer/branches/more-deferreds-3/twistedcaldav/static.py
CalendarServer/branches/more-deferreds-3/twistedcaldav/test/test_index.py
CalendarServer/branches/more-deferreds-3/twistedcaldav/test/test_resource.py
CalendarServer/branches/more-deferreds-3/twistedcaldav/timezoneservice.py
Added Paths:
-----------
CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.test.test_static.patch
Modified: CalendarServer/branches/more-deferreds-3/calendarserver/webadmin/resource.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/calendarserver/webadmin/resource.py 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/calendarserver/webadmin/resource.py 2009-08-28 20:49:31 UTC (rev 4513)
@@ -31,7 +31,7 @@
from twistedcaldav.config import config
from twistedcaldav.extensions import DAVFile, ReadOnlyResourceMixIn
-from twisted.internet.defer import inlineCallbacks, returnValue
+from twisted.internet.defer import inlineCallbacks, returnValue, succeed
from twisted.web2.http import Response
from twisted.web2.http_headers import MimeType
from twisted.web2.stream import MemoryStream
@@ -74,7 +74,7 @@
return None
def createSimilarFile(self, path):
- return DAVFile(path, principalCollections=self.principalCollections())
+ return succeed(DAVFile(path, principalCollections=self.principalCollections()))
def directoryStyleSheet(self):
return (
Modified: CalendarServer/branches/more-deferreds-3/calendarserver/webcal/resource.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/calendarserver/webcal/resource.py 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/calendarserver/webcal/resource.py 2009-08-28 20:49:31 UTC (rev 4513)
@@ -28,6 +28,7 @@
from urlparse import urlparse
from cgi import parse_qs
+from twisted.internet.defer import succeed
from twisted.web2 import responsecode
from twisted.web2.http import Response
from twisted.web2.http_headers import MimeType
@@ -53,7 +54,7 @@
def etag(self):
# Can't be calculated here
- return None
+ return succeed(None)
def contentLength(self):
# Can't be calculated here
@@ -75,7 +76,7 @@
return None
def createSimilarFile(self, path):
- return DAVFile(path, principalCollections=self.principalCollections())
+ return succeed(DAVFile(path, principalCollections=self.principalCollections()))
_htmlContent_lastCheck = 0
_htmlContent_statInfo = 0
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-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.resource.patch 2009-08-28 20:49:31 UTC (rev 4513)
@@ -330,7 +330,18 @@
def mergeAccessControlList(self, new_acl, request):
"""
-@@ -1089,7 +1142,9 @@
+@@ -926,7 +979,9 @@
+ # FIXME: verify acl is self-consistent
+
+ # Step 11
+- self.writeNewACEs(new_set)
++ d = waitForDeferred(self.writeNewACEs(new_set))
++ yield d
++ d.getResult()
+ yield None
+
+ mergeAccessControlList = deferredGenerator(mergeAccessControlList)
+@@ -1089,7 +1144,9 @@
return url
try:
@@ -341,7 +352,7 @@
except HTTPError, e:
assert e.response.code == responsecode.NOT_FOUND, (
"Expected %s response from readDeadProperty() exception, not %s"
-@@ -1635,7 +1690,9 @@
+@@ -1635,7 +1692,9 @@
# Check this resource first
if self.isCollection():
@@ -352,9 +363,17 @@
if qroot is not None:
used = waitForDeferred(self.currentQuotaUse(request))
yield used
-@@ -1673,7 +1730,10 @@
+@@ -1666,14 +1725,17 @@
+
+ def hasQuota(self, request):
"""
+- Check whether this resource is undre quota control by checking each parent to see if
++ Check whether this resource is under quota control by checking each parent to see if
+ it has a quota root.
+ @return: C{True} if under quota control, C{False} if not.
+ """
+
# Check this one first
- if self.hasQuotaRoot(request):
+ hasQuotaRoot = waitForDeferred(self.hasQuotaRoot(request))
@@ -364,7 +383,7 @@
yield True
return
-@@ -1705,10 +1765,19 @@
+@@ -1705,10 +1767,19 @@
@return: a C{int} containing the maximum allowed bytes if this collection
is quota-controlled, or C{None} if not quota controlled.
"""
@@ -387,7 +406,7 @@
def quotaRootParent(self, request):
"""
-@@ -1724,7 +1793,10 @@
+@@ -1724,7 +1795,10 @@
parent = waitForDeferred(request.locateResource(url))
yield parent
parent = parent.getResult()
@@ -399,7 +418,7 @@
yield parent
return
-@@ -1741,11 +1813,19 @@
+@@ -1741,11 +1815,19 @@
assert maxsize is None or isinstance(maxsize, int), "maxsize must be an int or None"
if maxsize is not None:
@@ -422,7 +441,7 @@
def quotaSize(self, request):
"""
-@@ -1795,7 +1875,10 @@
+@@ -1795,7 +1877,10 @@
# Check this resource first
if self.isCollection():
@@ -434,7 +453,7 @@
d = waitForDeferred(self.updateQuotaUse(request, adjust))
yield d
d.getResult()
-@@ -1825,20 +1908,34 @@
+@@ -1825,20 +1910,34 @@
is quota-controlled, or C{None} if not quota controlled.
"""
assert self.isCollection(), "Only collections can have a quota root"
@@ -478,7 +497,7 @@
def updateQuotaUse(self, request, adjust):
"""
Update the quota used value on this resource.
-@@ -1848,25 +1945,32 @@
+@@ -1848,25 +1947,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.
"""
@@ -528,7 +547,7 @@
##
# HTTP
##
-@@ -1880,7 +1984,7 @@
+@@ -1880,7 +1986,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.dav.static.patch
===================================================================
--- CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.static.patch 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.static.patch 2009-08-28 20:49:31 UTC (rev 4513)
@@ -48,9 +48,46 @@
def davComplianceClasses(self):
return ("1", "access-control") # Add "2" when we have locking
-@@ -192,7 +214,7 @@
- return (self.createSimilarFile(self.fp.child(path).path), segments[1:])
+@@ -169,9 +191,12 @@
+ """
+ # If getChild() finds a child resource, return it
+ try:
+- child = self.getChild(segments[0])
++ child = waitForDeferred(self.getChild(segments[0]))
++ yield child
++ child = child.getResult()
+ if child is not None:
+- return (child, segments[1:])
++ yield (child, segments[1:])
++ return
+ except InsecurePath:
+ raise HTTPError(StatusResponse(responsecode.FORBIDDEN, "Invalid URL path"))
+
+@@ -180,19 +205,26 @@
+ # that the request wants created.
+ self.fp.restat(False)
+ if self.fp.exists() and not self.fp.isdir():
+- return (None, ())
++ yield (None, ())
++ return
+ # OK, we need to return a child corresponding to the first segment
+ path = segments[0]
+
+ if path == "":
+ # Request is for a directory (collection) resource
+- return (self, ())
++ yield (self, ())
++ return
+
+- return (self.createSimilarFile(self.fp.child(path).path), segments[1:])
++ result = waitForDeferred(self.createSimilarFile(self.fp.child(path).path))
++ yield result
++ result = result.getResult()
++ yield (result, segments[1:])
+
++ locateChild = deferredGenerator(locateChild)
++
def createSimilarFile(self, path):
- return self.__class__(
+ return self.__class__.fetch(None,
Modified: CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.test_acl.patch
===================================================================
--- CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.test_acl.patch 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.test_acl.patch 2009-08-28 20:49:31 UTC (rev 4513)
@@ -22,7 +22,18 @@
principalCollection = TestPrincipalsCollection(
"/principals/",
-@@ -118,8 +122,9 @@
+@@ -93,7 +97,9 @@
+ loginInterfaces
+ ))
+
+- rootResource.setAccessControlList(self.grant(davxml.All()))
++ d = waitForDeferred(rootResource.setAccessControlList(self.grant(davxml.All())))
++ yield d
++ d.getResult( )
+
+ for name, acl in (
+ ("none" , self.grant()),
+@@ -118,8 +124,9 @@
os.mkdir(dirname)
resource = self.resource_class(dirname)
resource.setAccessControlList(acl)
@@ -33,26 +44,15 @@
def restore(self):
# Get rid of whatever messed up state the test has now so that we'll
-@@ -134,24 +139,32 @@
- Verify source access controls during COPY and MOVE.
- """
- def work():
-- dst_path = os.path.join(self.docroot, "copy_dst")
-+ docroot = waitForDeferred(self.docroot)
-+ yield docroot
-+ docroot = docroot.getResult()
-+ dst_path = os.path.join(docroot, "copy_dst")
+@@ -137,6 +144,7 @@
+ dst_path = os.path.join(self.docroot, "copy_dst")
dst_uri = "/" + os.path.basename(dst_path)
+ results = []
for src, status in (
("nobind", responsecode.FORBIDDEN),
("bind", responsecode.FORBIDDEN),
- ("unbind", responsecode.CREATED),
- ):
-- src_path = os.path.join(self.docroot, "src_" + src)
-+ src_path = os.path.join(docroot, "src_" + src)
- src_uri = "/" + os.path.basename(src_path)
+@@ -147,11 +155,15 @@
if not os.path.isdir(src_path):
os.mkdir(src_path)
src_resource = self.resource_class(src_path)
@@ -70,7 +70,7 @@
for name, acl in (
("none" , self.grant()),
("read" , self.grant(davxml.Read())),
-@@ -162,8 +175,11 @@
+@@ -162,8 +174,11 @@
filename = os.path.join(src_path, name)
if not os.path.isfile(filename):
file(filename, "w").close()
@@ -83,20 +83,7 @@
for method in ("COPY", "MOVE"):
for name, code in (
("none" , {"COPY": responsecode.FORBIDDEN, "MOVE": status}[method]),
-@@ -175,7 +191,11 @@
- path = os.path.join(src_path, name)
- uri = src_uri + "/" + name
-
-- request = SimpleRequest(self.site, method, uri)
-+ site = waitForDeferred(self.site)
-+ yield site
-+ site = site.getResult()
-+
-+ request = SimpleRequest(site, method, uri)
- request.headers.setHeader("destination", dst_uri)
- _add_auth_header(request)
-
-@@ -184,30 +204,56 @@
+@@ -184,12 +199,30 @@
os.remove(dst_path)
if response.code != code:
@@ -130,36 +117,15 @@
def test_COPY_MOVE_dest(self):
"""
Verify destination access controls during COPY and MOVE.
- """
- def work():
-- src_path = os.path.join(self.docroot, "read")
-+ docroot = waitForDeferred(self.docroot)
-+ yield docroot
-+ docroot = docroot.getResult()
-+ src_path = os.path.join(docroot, "read")
+@@ -198,6 +231,7 @@
+ src_path = os.path.join(self.docroot, "read")
uri = "/" + os.path.basename(src_path)
+ results = []
for method in ("COPY", "MOVE"):
for name, code in (
("nobind" , responsecode.FORBIDDEN),
- ("bind" , responsecode.CREATED),
- ("unbind" , responsecode.CREATED),
- ):
-- dst_parent_path = os.path.join(self.docroot, name)
-+ dst_parent_path = os.path.join(docroot, name)
- dst_path = os.path.join(dst_parent_path, "dst")
-
-- request = SimpleRequest(self.site, method, uri)
-+ site = waitForDeferred(self.site)
-+ yield site
-+ site = site.getResult()
-+
-+ request = SimpleRequest(site, method, uri)
- request.headers.setHeader("destination", "/" + name + "/dst")
- _add_auth_header(request)
-
-@@ -216,39 +262,80 @@
+@@ -216,18 +250,41 @@
os.remove(dst_path)
if response.code != code:
@@ -173,6 +139,11 @@
- yield (request, test)
+ results.append((request, test))
self.restore()
++ # restore( ) blows away _docroot explicitly;
++ # need to repopulate it
++ d = waitForDeferred(self._getDocumentRoot())
++ yield d
++ d.getResult()
- return serialize(self.send, work())
+ yield results
@@ -195,29 +166,12 @@
Verify access controls during DELETE.
"""
def work():
-+ docroot = waitForDeferred(self.docroot)
-+ yield docroot
-+ docroot = docroot.getResult()
+ results = []
for name, code in (
("nobind" , responsecode.FORBIDDEN),
("bind" , responsecode.FORBIDDEN),
- ("unbind" , responsecode.NO_CONTENT),
- ):
-- collection_path = os.path.join(self.docroot, name)
-+ collection_path = os.path.join(docroot, name)
- path = os.path.join(collection_path, "dst")
+@@ -243,12 +300,28 @@
- file(path, "w").close()
-
-- request = SimpleRequest(self.site, "DELETE", "/" + name + "/dst")
-+ site = waitForDeferred(self.site)
-+ yield site
-+ site = site.getResult()
-+
-+ request = SimpleRequest(site, "DELETE", "/" + name + "/dst")
- _add_auth_header(request)
-
def test(response, code=code, path=path):
if response.code != code:
- return self.oops(request, response, code, "DELETE", name)
@@ -248,40 +202,21 @@
def test_UNLOCK(self):
"""
Verify access controls during UNLOCK of unowned lock.
-@@ -261,14 +348,19 @@
+@@ -261,8 +334,10 @@
"""
Verify access controls during MKCOL.
"""
- for method in ("MKCOL", "PUT"):
- def work():
+ def work():
-+ docroot = waitForDeferred(self.docroot)
-+ yield docroot
-+ docroot = docroot.getResult()
+ results = []
+
+ for method in ("MKCOL", "PUT"):
for name, code in (
("nobind" , responsecode.FORBIDDEN),
("bind" , responsecode.CREATED),
- ("unbind" , responsecode.CREATED),
- ):
-- collection_path = os.path.join(self.docroot, name)
-+ collection_path = os.path.join(docroot, name)
- path = os.path.join(collection_path, "dst")
+@@ -281,17 +356,34 @@
- if os.path.isfile(path):
-@@ -276,22 +368,45 @@
- elif os.path.isdir(path):
- os.rmdir(path)
-
-- request = SimpleRequest(self.site, method, "/" + name + "/dst")
-+ site = waitForDeferred(self.site)
-+ yield site
-+ site = site.getResult()
-+ request = SimpleRequest(site, method, "/" + name + "/dst")
- _add_auth_header(request)
-
def test(response, code=code, path=path):
if response.code != code:
- return self.oops(request, response, code, method, name)
@@ -314,27 +249,12 @@
Verify access controls during PUT of existing file.
"""
def work():
-+ docroot = waitForDeferred(self.docroot)
-+ yield docroot
-+ docroot = docroot.getResult()
+ results = []
for name, code in (
("none" , responsecode.FORBIDDEN),
("read" , responsecode.FORBIDDEN),
-@@ -299,19 +414,38 @@
- ("unlock" , responsecode.FORBIDDEN),
- ("all" , responsecode.NO_CONTENT),
- ):
-- path = os.path.join(self.docroot, name)
-+ path = os.path.join(docroot, name)
+@@ -306,12 +398,28 @@
-- request = SimpleRequest(self.site, "PUT", "/" + name)
-+ site = waitForDeferred(self.site)
-+ yield site
-+ site = site.getResult()
-+ request = SimpleRequest(site, "PUT", "/" + name)
- _add_auth_header(request)
-
def test(response, code=code, path=path):
if response.code != code:
- return self.oops(request, response, code, "PUT", name)
@@ -365,34 +285,16 @@
def test_PROPFIND(self):
"""
Verify access controls during PROPFIND.
-@@ -325,6 +459,10 @@
+@@ -325,6 +433,7 @@
Verify access controls during PROPPATCH.
"""
def work():
-+ docroot = waitForDeferred(self.docroot)
-+ yield docroot
-+ docroot = docroot.getResult()
+ results = []
for name, code in (
("none" , responsecode.FORBIDDEN),
("read" , responsecode.FORBIDDEN),
-@@ -332,9 +470,12 @@
- ("unlock" , responsecode.FORBIDDEN),
- ("all" , responsecode.MULTI_STATUS),
- ):
-- path = os.path.join(self.docroot, name)
-+ path = os.path.join(docroot, name)
+@@ -342,17 +451,33 @@
-- request = SimpleRequest(self.site, "PROPPATCH", "/" + name)
-+ site = waitForDeferred(self.site)
-+ yield site
-+ site = site.getResult()
-+ request = SimpleRequest(site, "PROPPATCH", "/" + name)
- request.stream = MemoryStream(
- davxml.WebDAVDocument(davxml.PropertyUpdate()).toxml()
- )
-@@ -342,17 +483,36 @@
-
def test(response, code=code, path=path):
if response.code != code:
- return self.oops(request, response, code, "PROPPATCH", name)
@@ -424,30 +326,12 @@
Verify access controls during GET and REPORT.
"""
def work():
-+ docroot = waitForDeferred(self.docroot)
-+ yield docroot
-+ docroot = docroot.getResult()
+ results = []
for method in ("GET", "REPORT"):
if method == "GET":
ok = responsecode.OK
-@@ -368,9 +528,12 @@
- ("unlock" , responsecode.FORBIDDEN),
- ("all" , ok),
- ):
-- path = os.path.join(self.docroot, name)
-+ path = os.path.join(docroot, name)
+@@ -378,12 +503,27 @@
-- request = SimpleRequest(self.site, method, "/" + name)
-+ site = waitForDeferred(self.site)
-+ yield site
-+ site = site.getResult()
-+ request = SimpleRequest(site, method, "/" + name)
- if method == "REPORT":
- request.stream = MemoryStream(davxml.PrincipalPropertySearch().toxml())
-
-@@ -378,12 +541,27 @@
-
def test(response, code=code, path=path):
if response.code != code:
- return self.oops(request, response, code, method, name)
Modified: CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.test_copy.patch
===================================================================
--- CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.test_copy.patch 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.test_copy.patch 2009-08-28 20:49:31 UTC (rev 4513)
@@ -68,19 +68,15 @@
def test_COPY_no_parent(self):
"""
COPY to resource with no parent.
-@@ -122,18 +151,35 @@
+@@ -122,9 +151,19 @@
# FIXME: Check XML error code (2518bis)
pass
- return serialize(self.send, work(self, test, dst=os.path.join(self.docroot, "elvislives!")))
-+ docroot = waitForDeferred(self.docroot)
-+ yield docroot
-+ docroot = docroot.getResult()
-
-+ d = waitForDeferred(work(self, test, dst=os.path.join(docroot, "elvislives!")))
++ d = waitForDeferred(work(self, test, dst=os.path.join(self.docroot, "elvislives!")))
+ yield d
+ results = d.getResult()
-+
+
+ d = waitForDeferred(serialize(self.send, iter(results)))
+ yield d
+ d = d.getResult()
@@ -89,37 +85,11 @@
+ test_COPY_no_parent = deferredGenerator(test_COPY_no_parent)
+
def work(self, test, overwrite=None, dst=None, depths=("0", "infinity", None)):
-+ docroot = waitForDeferred(self.docroot)
-+ yield docroot
-+ docroot = docroot.getResult()
+ results = []
if dst is None:
-- dst = os.path.join(self.docroot, "dst")
-+ dst = os.path.join(docroot, "dst")
+ dst = os.path.join(self.docroot, "dst")
os.mkdir(dst)
-
-- for basename in os.listdir(self.docroot):
-+ for basename in os.listdir(docroot):
- if basename == "dst": continue
-
- uri = urllib.quote("/" + basename)
-- path = os.path.join(self.docroot, basename)
-+ path = os.path.join(docroot, basename)
- isfile = os.path.isfile(path)
- sum = sumFile(path)
- dst_path = os.path.join(dst, basename)
-@@ -151,15 +197,23 @@
- def do_test(response, path=path, isfile=isfile, sum=sum, uri=uri, depth=depth, dst_path=dst_path):
- test(response, path, isfile, sum, uri, depth, dst_path)
-
-- request = SimpleRequest(self.site, self.__class__.__name__, uri)
-+ site = waitForDeferred(self.site)
-+ yield site
-+ site = site.getResult()
-+ request = SimpleRequest(site, self.__class__.__name__, uri)
- request.headers.setHeader("destination", dst_uri)
- if depth is not None:
- request.headers.setHeader("depth", depth)
+@@ -158,8 +197,13 @@
if overwrite is not None:
request.headers.setHeader("overwrite", overwrite)
Modified: CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.test_delete.patch
===================================================================
--- CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.test_delete.patch 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.test_delete.patch 2009-08-28 20:49:31 UTC (rev 4513)
@@ -10,23 +10,16 @@
from twisted.web2 import responsecode
from twisted.web2.iweb import IResponse
from twisted.web2.test.test_server import SimpleRequest
-@@ -54,8 +55,13 @@
+@@ -54,6 +55,8 @@
self.fail("DELETE did not remove path %s" % (path,))
def work():
-- for filename in os.listdir(self.docroot):
-- path = os.path.join(self.docroot, filename)
-+ docroot = waitForDeferred(self.docroot)
-+ yield docroot
-+ docroot = docroot.getResult()
+ results = []
+
-+ for filename in os.listdir(docroot):
-+ path = os.path.join(docroot, filename)
+ for filename in os.listdir(self.docroot):
+ path = os.path.join(self.docroot, filename)
uri = urllib.quote("/" + filename)
-
- if os.path.isdir(path): uri = uri + "/"
-@@ -63,12 +69,26 @@
+@@ -63,12 +66,26 @@
def do_test(response, path=path):
return check_result(response, path)
Modified: CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.test_mkcol.patch
===================================================================
--- CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.test_mkcol.patch 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.test_mkcol.patch 2009-08-28 20:49:31 UTC (rev 4513)
@@ -18,58 +18,23 @@
# FIXME:
# Try in nonexistant parent collection.
# Try on existing resource.
-@@ -43,7 +45,9 @@
- """
- MKCOL request
- """
-- path, uri = self.mkdtemp("collection")
-+ d = waitForDeferred(self.mkdtemp("collection"))
-+ yield d
-+ path, uri = d.getResult()
+@@ -58,8 +60,13 @@
- rmdir(path)
+ request = SimpleRequest(self.site, "MKCOL", uri)
-@@ -56,17 +60,28 @@
- if not os.path.isdir(path):
- self.fail("MKCOL did not create directory %s" % (path,))
-
-- request = SimpleRequest(self.site, "MKCOL", uri)
-+ site = waitForDeferred(self.site)
-+ yield site
-+ site = site.getResult()
-
- return self.send(request, check_result)
-+ request = SimpleRequest(site, "MKCOL", uri)
-
+ d = waitForDeferred(self.send(request, check_result))
+ yield d
+ d = d.getResult()
+ yield d
-+
+
+ test_MKCOL = deferredGenerator(test_MKCOL)
+
def test_MKCOL_invalid_body(self):
"""
MKCOL request with invalid request body
- (Any body at all is invalid in our implementation; there is no
- such thing as a valid body.)
- """
-- path, uri = self.mkdtemp("collection")
-+ d = waitForDeferred(self.mkdtemp("collection"))
-+ yield d
-+ path, uri = d.getResult()
-
- rmdir(path)
-
-@@ -79,7 +94,15 @@
- if os.path.isdir(path):
- self.fail("MKCOL incorrectly created directory %s" % (path,))
-
-- request = SimpleRequest(self.site, "MKCOL", uri)
-+ site = waitForDeferred(self.site)
-+ yield site
-+ site = site.getResult()
-+ request = SimpleRequest(site, "MKCOL", uri)
+@@ -82,4 +89,9 @@
+ request = SimpleRequest(self.site, "MKCOL", uri)
request.stream = MemoryStream("This is not a valid MKCOL request body.")
- return self.send(request, check_result)
Modified: CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.test_move.patch
===================================================================
--- CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.test_move.patch 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.test_move.patch 2009-08-28 20:49:31 UTC (rev 4513)
@@ -10,14 +10,11 @@
import twisted.web2.dav.test.util
import twisted.web2.dav.test.test_copy
from twisted.web2 import responsecode
-@@ -60,8 +61,21 @@
+@@ -60,8 +61,18 @@
if sum != sumFile(dst_path):
self.fail("isdir %s produced different directory" % (uri,))
- return serialize(self.send, work(self, test))
-+ docroot = waitForDeferred(self.docroot)
-+ yield docroot
-+ docroot = docroot.getResult()
+ d = waitForDeferred(work(self, test))
+ yield d
@@ -33,19 +30,15 @@
def test_MOVE_exists(self):
"""
MOVE to existing resource.
-@@ -74,8 +88,21 @@
+@@ -74,8 +85,17 @@
# FIXME: Check XML error code (2518bis)
pass
- return serialize(self.send, work(self, test, overwrite=False))
-+ docroot = waitForDeferred(self.docroot)
-+ yield docroot
-+ docroot = docroot.getResult()
-
+ d = waitForDeferred(work(self, test, overwrite=False))
+ yield d
+ d = d.getResult()
-+
+
+ d = waitForDeferred(serialize(self.send, iter(d)))
+ yield d
+ d = d.getResult( )
@@ -56,19 +49,15 @@
def test_MOVE_overwrite(self):
"""
MOVE to existing resource with overwrite header.
-@@ -88,8 +115,21 @@
+@@ -88,8 +108,17 @@
# FIXME: Check XML error code (2518bis)
pass
- return serialize(self.send, work(self, test, overwrite=True))
-+ docroot = waitForDeferred(self.docroot)
-+ yield docroot
-+ docroot = docroot.getResult()
-
+ d = waitForDeferred(work(self, test, overwrite=True))
+ yield d
+ d = d.getResult()
-+
+
+ d = waitForDeferred(serialize(self.send, iter(d)))
+ yield d
+ d = d.getResult( )
@@ -79,16 +68,13 @@
def test_MOVE_no_parent(self):
"""
MOVE to resource with no parent.
-@@ -102,7 +142,20 @@
+@@ -102,7 +131,17 @@
# FIXME: Check XML error code (2518bis)
pass
- return serialize(self.send, work(self, test, dst=os.path.join(self.docroot, "elvislives!")))
-+ docroot = waitForDeferred(self.docroot)
-+ yield docroot
-+ docroot = docroot.getResult()
-+ d = waitForDeferred(work(self, test, dst=os.path.join(docroot, "elvislives!")))
++ d = waitForDeferred(work(self, test, dst=os.path.join(self.docroot, "elvislives!")))
+ yield d
+ d = d.getResult()
+
Modified: CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.test_prop.patch
===================================================================
--- CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.test_prop.patch 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.test_prop.patch 2009-08-28 20:49:31 UTC (rev 4513)
@@ -10,19 +10,11 @@
from twisted.trial.unittest import SkipTest
from twisted.web2 import responsecode
from twisted.web2.iweb import IResponse
-@@ -57,6 +58,15 @@
+@@ -57,6 +58,7 @@
PROPFIND, PROPPATCH requests
"""
-+ def setUp(self):
-+ # Pre-fetch site, so the rest of the test doesn't have to defer
-+ twisted.web2.dav.test.util.TestCase.setUp(self)
-+ self._getSite()
+
-+ def _getStoredSite(self):
-+ return self._site
-+ site = property(_getStoredSite)
-+
def liveProperties(self):
return [lookupElement(qname)() for qname in self.resource_class.liveProperties if (qname[0] == dav_namespace) and qname not in dynamicLiveProperties]
Modified: CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.test_put.patch
===================================================================
--- CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.test_put.patch 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.test_put.patch 2009-08-28 20:49:31 UTC (rev 4513)
@@ -10,49 +10,41 @@
from twisted.web2 import responsecode
from twisted.web2.iweb import IResponse
from twisted.web2.stream import FileStream
-@@ -42,27 +43,38 @@
+@@ -44,25 +45,31 @@
"""
- PUT request
- """
-- dst_path = os.path.join(self.docroot, "dst")
-+ docroot = waitForDeferred(self.docroot)
-+ yield docroot
-+ docroot = docroot.getResult()
+ dst_path = os.path.join(self.docroot, "dst")
- def checkResult(response, path):
- response = IResponse(response)
-+ dst_path = os.path.join(docroot, "dst")
++ def makeClosure(path):
- if response.code not in (
- responsecode.CREATED,
- responsecode.NO_CONTENT
- ):
- self.fail("PUT failed: %s" % (response.code,))
-+ def makeClosure(path):
++ # Return a function with 'path' closed
- if not os.path.isfile(dst_path):
- self.fail("PUT failed to create file %s." % (dst_path,))
-+ # Return a function with 'path' closed
-
-- if not filecmp.cmp(path, dst_path):
-- self.fail("PUT failed to preserve data for file %s in file %s." % (path, dst_path))
+ def checkResult(response):
+ response = IResponse(response)
-- etag = response.headers.getHeader("etag")
-- if not etag:
-- self.fail("No etag header in PUT response %r." % (response,))
+- if not filecmp.cmp(path, dst_path):
+- self.fail("PUT failed to preserve data for file %s in file %s." % (path, dst_path))
+ if response.code not in (
+ responsecode.CREATED,
+ responsecode.NO_CONTENT
+ ):
+ self.fail("PUT failed: %s" % (response.code,))
+- etag = response.headers.getHeader("etag")
+- if not etag:
+- self.fail("No etag header in PUT response %r." % (response,))
+ if not os.path.isfile(dst_path):
+ self.fail("PUT failed to create file %s." % (dst_path,))
-+
+
+ if not filecmp.cmp(path, dst_path):
-+ import pdb; pdb.set_trace()
+
+ self.fail("PUT failed to preserve data for file %s in file %s." % (path, dst_path))
+
@@ -64,31 +56,23 @@
#
# We need to serialize these request & test iterations because they can
# interfere with each other.
-@@ -70,52 +82,79 @@
+@@ -70,6 +77,7 @@
def work():
dst_uri = "/dst"
-- for name in os.listdir(self.docroot):
+ results = []
-+ for name in os.listdir(docroot):
+ for name in os.listdir(self.docroot):
if name == "dst":
continue
+@@ -78,38 +86,53 @@
-- path = os.path.join(self.docroot, name)
-+ path = os.path.join(docroot, name)
-
# Can't really PUT something you can't read
if not os.path.isfile(path): continue
-
- def do_test(response): checkResult(response, path)
-
-- request = SimpleRequest(self.site, "PUT", dst_uri)
+
-+ site = waitForDeferred(self.site)
-+ yield site
-+ site = site.getResult()
-+
-+ request = SimpleRequest(site, "PUT", dst_uri)
+ request = SimpleRequest(self.site, "PUT", dst_uri)
request.stream = FileStream(file(path, "rb"))
-
- yield (request, do_test)
@@ -116,12 +100,8 @@
"""
PUT on existing resource with If-None-Match header
"""
-- dst_path = os.path.join(self.docroot, "dst")
-+ docroot = waitForDeferred(self.docroot)
-+ yield docroot
-+ docroot = docroot.getResult()
+
-+ dst_path = os.path.join(docroot, "dst")
+ dst_path = os.path.join(self.docroot, "dst")
dst_uri = "/dst"
def work():
@@ -150,18 +130,7 @@
def onError(f):
f.trap(HTTPError)
- return checkResult(f.value.response)
-
-- request = SimpleRequest(self.site, "PUT", dst_uri)
-+ site = waitForDeferred(self.site)
-+ yield site
-+ site = site.getResult()
-+
-+ request = SimpleRequest(site, "PUT", dst_uri)
- request.stream = FileStream(file(__file__, "rb"))
-
- if code == responsecode.CREATED:
-@@ -125,10 +164,23 @@
+@@ -125,10 +148,23 @@
elif code == responsecode.PRECONDITION_FAILED:
request.headers.setHeader("if-none-match", ("*",))
@@ -187,16 +156,8 @@
def test_PUT_no_parent(self):
"""
PUT with no parent
-@@ -142,7 +194,16 @@
- self.fail("Incorrect response code for PUT with no parent (%s != %s)"
- % (response.code, responsecode.CONFLICT))
-
-- request = SimpleRequest(self.site, "PUT", dst_uri)
-+ site = waitForDeferred(self.site)
-+ yield site
-+ site = site.getResult()
-+
-+ request = SimpleRequest(site, "PUT", dst_uri)
+@@ -145,4 +181,9 @@
+ request = SimpleRequest(self.site, "PUT", dst_uri)
request.stream = FileStream(file(__file__, "rb"))
- return self.send(request, checkResult)
Modified: CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.util.patch
===================================================================
--- CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.util.patch 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.dav.test.util.patch 2009-08-28 20:49:31 UTC (rev 4513)
@@ -50,7 +50,7 @@
dirnames = (
os.path.join(docroot, "dir1"), # 0
-@@ -149,17 +153,23 @@
+@@ -149,37 +153,56 @@
for dirname in (docroot,) + dirnames[3:8+1]:
for filename in filenames[:5]:
copy(filename, dirname)
@@ -69,45 +69,46 @@
+ yield d
+ self._docroot = d.getResult()
-- return self._docroot
+ yield self._docroot
-
++
+ _getDocumentRoot = deferredGenerator(_getDocumentRoot)
+
++ def _getStoredDocumentRoot(self):
+ return self._docroot
+
def _setDocumentRoot(self, value):
self._docroot = value
-@@ -167,10 +177,13 @@
+- docroot = property(_getDocumentRoot, _setDocumentRoot)
++ docroot = property(_getStoredDocumentRoot, _setDocumentRoot)
def _getSite(self):
if not hasattr(self, "_site"):
-- rootresource = self.resource_class(self.docroot)
-+ d = waitForDeferred(self.docroot)
+ rootresource = self.resource_class(self.docroot)
+- rootresource.setAccessControlList(self.grantInherit(davxml.All()))
++ d = waitForDeferred(rootresource.setAccessControlList(self.grantInherit(davxml.All())))
+ yield d
-+ rootresource = self.resource_class(d.getResult())
- rootresource.setAccessControlList(self.grantInherit(davxml.All()))
++ d.getResult()
self._site = Site(rootresource)
-- return self._site
+ yield self._site
+ _getSite = deferredGenerator(_getSite)
++
++ def _getStoredSite(self):
+ return self._site
def _setSite(self, site):
self._site = site
-@@ -191,11 +204,15 @@
- Creates a new directory in the document root and returns its path and
- URI.
- """
-- path = mkdtemp(prefix=prefix + "_", dir=self.docroot)
-+ d = waitForDeferred(self.docroot)
-+ yield d
-+ path = mkdtemp(prefix=prefix + "_", dir=d.getResult())
- uri = joinURL("/", url_quote(os.path.basename(path))) + "/"
-- return (path, uri)
-+ yield (path, uri)
+- site = property(_getSite, _setSite)
++ site = property(_getStoredSite, _setSite)
-+ mkdtemp = deferredGenerator(mkdtemp)
-+
- def send(self, request, callback):
- log.msg("Sending %s request for URI %s" % (request.method, request.uri))
+ def setUp(self):
+ unittest.TestCase.setUp(self)
+ TestFile._cachedPropertyStores = {}
++ d = self._getDocumentRoot()
++ d.addCallback(lambda _: self._getSite())
++ return d
++ # self._getSite()
+ def tearDown(self):
+ unittest.TestCase.tearDown(self)
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-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.static.patch 2009-08-28 20:49:31 UTC (rev 4513)
@@ -49,8 +49,41 @@
def renderHTTP(self, request):
"""
See L{resource.RenderMixIn.renderHTTP}.
-@@ -132,8 +140,8 @@
+@@ -100,16 +108,23 @@
+ # Don't provide additional resource information to error responses
+ if response.code < 400:
+- # Content-* headers refer to the response content, not
+- # (necessarily) to the resource content, so they depend on the
+- # request method, and therefore can't be set here.
+- for (header, value) in (
+- ("etag", self.etag()),
+- ("last-modified", self.lastModified()),
+- ):
+- if value is not None:
+- response.headers.setHeader(header, value)
++ d = self.etag()
++ def _gotEtag(etag):
++ # Content-* headers refer to the response content, not
++ # (necessarily) to the resource content, so they depend on the
++ # request method, and therefore can't be set here.
++ for (header, value) in (
++ ("etag", etag),
++ ("last-modified", self.lastModified()),
++ ):
++ if value is not None:
++ response.headers.setHeader(header, value)
+
++ return response
++
++ d.addCallback(_gotEtag)
++ return d
++
+ return response
+
+ def onError(f):
+@@ -132,8 +147,8 @@
+
def etag(self):
lastModified = self.lastModified()
- return http_headers.ETag("%X-%X" % (lastModified, hash(self.data)),
@@ -60,7 +93,7 @@
def lastModified(self):
return self.creationDate()
-@@ -217,7 +225,7 @@
+@@ -217,7 +232,7 @@
return self.fp.exists()
def etag(self):
@@ -69,7 +102,7 @@
st = self.fp.statinfo
-@@ -228,10 +236,10 @@
+@@ -228,10 +243,10 @@
#
weak = (time.time() - st.st_mtime <= 1)
@@ -82,7 +115,7 @@
def lastModified(self):
if self.fp.exists():
-@@ -291,12 +299,13 @@
+@@ -291,12 +306,13 @@
self.ignoredExts.append(ext)
def directoryListing(self):
@@ -102,7 +135,27 @@
def putChild(self, name, child):
"""
Register a child with the given name with this resource.
-@@ -329,7 +338,7 @@
+@@ -311,16 +327,16 @@
+ @return: the child of this resource with the given name.
+ """
+ if name == "":
+- return self
++ return succeed(self)
+
+ child = self.putChildren.get(name, None)
+- if child: return child
++ if child: return succeed(child)
+
+ child_fp = self.fp.child(name)
+ if child_fp.exists():
+ return self.createSimilarFile(child_fp.path)
+ else:
+- return None
++ return succeed(None)
+
+ def listChildren(self):
+ """
+@@ -329,21 +345,27 @@
children = self.putChildren.keys()
if self.fp.isdir():
children += [c for c in self.fp.listdir() if c not in children]
@@ -111,11 +164,70 @@
def locateChild(self, req, segments):
"""
-@@ -387,17 +396,17 @@
+ See L{IResource}C{.locateChild}.
+ """
+ # If getChild() finds a child resource, return it
+- child = self.getChild(segments[0])
+- if child is not None: return (child, segments[1:])
++ child = waitForDeferred(self.getChild(segments[0]))
++ yield child
++ child = child.getResult()
++ if child is not None:
++ yield (child, segments[1:])
++ return
+
+ # If we're not backed by a directory, we have no children.
+ # But check for existance first; we might be a collection resource
+ # that the request wants created.
+ self.fp.restat(False)
+- if self.fp.exists() and not self.fp.isdir(): return (None, ())
++ if self.fp.exists() and not self.fp.isdir():
++ yield (None, ())
++ return
+
+ # OK, we need to return a child corresponding to the first segment
+ path = segments[0]
+@@ -352,24 +374,29 @@
+ fpath = self.fp.child(path)
+ else:
+ # Request is for a directory (collection) resource
+- return (self, server.StopTraversal)
++ yield (self, server.StopTraversal)
++ return
+
+ # Don't run processors on directories - if someone wants their own
+ # customized directory rendering, subclass File instead.
+ if fpath.isfile():
+ processor = self.processors.get(fpath.splitext()[1].lower())
+ if processor:
+- return (
+- processor(fpath.path),
+- segments[1:])
++ yield (processor(fpath.path), segments[1:])
++ return
+
+ elif not fpath.exists():
+ sibling_fpath = fpath.siblingExtensionSearch(*self.ignoredExts)
+ if sibling_fpath is not None:
+ fpath = sibling_fpath
+
+- return self.createSimilarFile(fpath.path), segments[1:]
++ result = waitForDeferred(self.createSimilarFile(fpath.path), segments[1:])
++ yield result
++ result = result.getResult()
++ yield result
+
++ locateChild = deferredGenerator(locateChild)
++
+ def renderHTTP(self, req):
+ self.fp.restat(False)
+ return super(File, self).renderHTTP(req)
+@@ -387,17 +414,18 @@
ifp = self.fp.childSearchPreauth(*self.indexNames)
if ifp:
# Render from the index file
- standin = self.createSimilarFile(ifp.path)
++ # MOR: What is going on here?
+ standin = self.createSimilarFile(ifp.path).render(req)
else:
# Render from a DirectoryLister
@@ -138,3 +250,14 @@
try:
f = self.fp.open()
+@@ -423,8 +451,8 @@
+ return response
+
+ def createSimilarFile(self, path):
+- return self.__class__(path, self.defaultType, self.ignoredExts,
+- self.processors, self.indexNames[:])
++ return succeed(self.__class__(path, self.defaultType, self.ignoredExts,
++ self.processors, self.indexNames[:]))
+
+
+ class FileSaver(resource.PostableResource):
Added: CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.test.test_static.patch
===================================================================
--- CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.test.test_static.patch (rev 0)
+++ CalendarServer/branches/more-deferreds-3/lib-patches/Twisted/twisted.web2.test.test_static.patch 2009-08-28 20:49:31 UTC (rev 4513)
@@ -0,0 +1,17 @@
+Index: twisted/web2/test/test_static.py
+===================================================================
+--- twisted/web2/test/test_static.py (revision 26969)
++++ twisted/web2/test/test_static.py (working copy)
+@@ -34,7 +34,11 @@
+ """
+ Test that we can get an ETag
+ """
+- self.failUnless(self.data.etag())
++ d = self.data.etag()
++ def _callback(etag):
++ self.failUnless(etag)
++ d.addCallback(_callback)
++ return d
+
+
+ def test_render(self):
Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/calendar.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/calendar.py 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/calendar.py 2009-08-28 20:49:31 UTC (rev 4513)
@@ -151,17 +151,18 @@
def url(self):
return joinURL(self._parent.url(), self.recordType)
+ @inlineCallbacks
def getChild(self, name, record=None):
- self.provision()
+ yield self.provision()
if name == "":
- return self
+ returnValue(self)
if record is None:
record = self.directory.recordWithShortName(self.recordType, name)
if record is None:
- return None
+ returnValue(None)
- return self._parent.homeForDirectoryRecord(record)
+ returnValue((yield self._parent.homeForDirectoryRecord(record)))
def listChildren(self):
if config.EnablePrincipalListings:
@@ -213,17 +214,18 @@
def url(self):
return joinURL(self.parent.url(), uidsResourceName)
+ @inlineCallbacks
def getChild(self, name, record=None):
- self.provision()
+ yield self.provision()
if name == "":
- return self
+ returnValue(self)
if record is None:
record = self.directory.recordWithUID(name)
if record is None:
- return None
+ returnValue(None)
- return self.provisionChild(name)
+ returnValue((yield self.provisionChild(name)))
def listChildren(self):
# Not a listable collection
@@ -311,8 +313,8 @@
# Set calendar-free-busy-set on inbox
inbox = self.getChild("inbox")
- inbox.provision()
- inbox.processFreeBusyCalendar(childURL, True)
+ yield inbox.provision()
+ yield inbox.processFreeBusyCalendar(childURL, True)
# Default calendar is marked as the default for scheduling
yield inbox.writeDeadProperty(caldavxml.ScheduleDefaultCalendarURL(davxml.HRef(childURL)))
@@ -455,7 +457,7 @@
@return: a C{True} if this resource has quota root, C{False} otherwise.
"""
- return config.UserQuota != 0
+ return succeed(config.UserQuota != 0)
def quotaRoot(self, request):
"""
Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/calendaruserproxy.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/calendaruserproxy.py 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/calendaruserproxy.py 2009-08-28 20:49:31 UTC (rev 4513)
@@ -131,9 +131,9 @@
def resourceType(self):
if self.proxyType == "calendar-proxy-read":
- return davxml.ResourceType.calendarproxyread
+ return succeed(davxml.ResourceType.calendarproxyread)
elif self.proxyType == "calendar-proxy-write":
- return davxml.ResourceType.calendarproxywrite
+ return succeed(davxml.ResourceType.calendarproxywrite)
else:
return super(CalendarUserProxyPrincipalResource, self).resourceType()
Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/principal.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/principal.py 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/principal.py 2009-08-28 20:49:31 UTC (rev 4513)
@@ -837,14 +837,14 @@
result = (yield CalendarPrincipalResource.readProperty(self, property, request))
returnValue(result)
+ @inlineCallbacks
def extraDirectoryBodyItems(self, request):
- d = self.calendarHomeURLs()
- def _gotURLs(homeURLs):
- return "".join((
- """\nCalendar homes:\n""" , format_list(format_link(u) for u in homeURLs),
- """\nCalendar user addresses:\n""" , format_list(format_link(a) for a in self.calendarUserAddresses()),
- ))
- return d.addCallbacks(_gotURLs)
+ homeURLs = (yield self.calendarHomeURLs())
+ cuas = (yield self.calendarUserAddresses())
+ returnValue( "".join((
+ """\nCalendar homes:\n""" , format_list(format_link(u) for u in homeURLs),
+ """\nCalendar user addresses:\n""" , format_list(format_link(a) for a in cuas),
+ )))
##
# CalDAV
@@ -865,7 +865,7 @@
# Add a UUID URI based on the record's GUID to the list.
addresses.add("urn:uuid:%s" % (self.record.guid,))
- return addresses
+ return succeed(addresses)
def enabledAsOrganizer(self):
if self.record.recordType == DirectoryService.recordType_users:
Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/test/test_principal.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/test/test_principal.py 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/directory/test/test_principal.py 2009-08-28 20:49:31 UTC (rev 4513)
@@ -317,6 +317,7 @@
for provisioningResource, recordType, recordResource, record in self._allRecords():
self.assertEquals(record.guid, recordResource.principalUID())
+ @inlineCallbacks
def test_calendarUserAddresses(self):
"""
DirectoryPrincipalResource.calendarUserAddresses()
@@ -327,7 +328,7 @@
(
set((recordResource.principalURL(),)) |
set(record.calendarUserAddresses)
- ).issubset(set(recordResource.calendarUserAddresses()))
+ ).issubset(set((yield recordResource.calendarUserAddresses())))
)
def test_calendarHomeURLs(self):
Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/dropbox.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/dropbox.py 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/dropbox.py 2009-08-28 20:49:31 UTC (rev 4513)
@@ -24,6 +24,7 @@
"DropBoxChildResource",
]
+from twisted.internet.defer import succeed
from twext.web2.dav.davxml import ErrorResponse
from twisted.web2 import responsecode
from twisted.web2.dav import davxml
@@ -39,7 +40,7 @@
Drop box collection resource.
"""
def resourceType(self):
- return davxml.ResourceType.dropboxhome
+ return succeed(davxml.ResourceType.dropboxhome)
def isCollection(self):
return True
@@ -52,7 +53,7 @@
Drop box resource.
"""
def resourceType(self):
- return davxml.ResourceType.dropbox
+ return succeed(davxml.ResourceType.dropbox)
def isCollection(self):
return True
Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/extensions.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/extensions.py 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/extensions.py 2009-08-28 20:49:31 UTC (rev 4513)
@@ -700,7 +700,7 @@
if namespace == dav_namespace:
if name == "resourcetype":
- returnValue(self.resourceType())
+ returnValue((yield self.resourceType()))
elif namespace == calendarserver_namespace:
if name == "expanded-group-member-set":
@@ -741,14 +741,15 @@
def expandedGroupMemberships(self):
return succeed(())
+ @inlineCallbacks
def resourceType(self):
# Allow live property to be overridden by dead property
- if self.deadProperties().contains((dav_namespace, "resourcetype")):
- return self.deadProperties().get((dav_namespace, "resourcetype"))
+ if (yield self.deadProperties().contains((dav_namespace, "resourcetype"))):
+ returnValue((yield self.deadProperties().get((dav_namespace, "resourcetype"))))
if self.isCollection():
- return davxml.ResourceType(davxml.Collection(), davxml.Principal())
+ returnValue(davxml.ResourceType(davxml.Collection(), davxml.Principal()))
else:
- return davxml.ResourceType(davxml.Principal())
+ returnValue(davxml.ResourceType(davxml.Principal()))
class DAVFile (SudoSACLMixin, SuperDAVFile, LoggingMixIn):
@@ -762,17 +763,18 @@
qname = property.qname()
if qname == (dav_namespace, "resourcetype"):
- return succeed(self.resourceType())
+ return self.resourceType()
return super(DAVFile, self).readProperty(property, request)
+ @inlineCallbacks
def resourceType(self):
# Allow live property to be overridden by dead property
- if self.deadProperties().contains((dav_namespace, "resourcetype")):
- return self.deadProperties().get((dav_namespace, "resourcetype"))
+ if (yield self.deadProperties().contains((dav_namespace, "resourcetype"))):
+ returnValue((yield self.deadProperties().get((dav_namespace, "resourcetype"))))
if self.isCollection():
- return davxml.ResourceType.collection
- return davxml.ResourceType.empty
+ returnValue(davxml.ResourceType.collection)
+ returnValue(davxml.ResourceType.empty)
def render(self, request):
if not self.fp.exists():
@@ -783,6 +785,9 @@
# Redirect to include trailing '/' in URI
return 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( )
+ # will be a problem...
ifp = self.fp.childSearchPreauth(*self.indexNames)
if ifp:
# Render from the index file
@@ -1091,52 +1096,55 @@
self.propertyStore = propertyStore
self.resource = propertyStore.resource
+ @inlineCallbacks
def get(self, qname):
#self.log_debug("Get: %r, %r" % (self.resource.fp.path, qname))
- cache = self._cache()
+ cache = (yield self._cache())
if qname in cache:
property = cache.get(qname, None)
if property is None:
self.log_debug("Cache miss: %r, %r, %r" % (self, self.resource.fp.path, qname))
try:
- property = self.propertyStore.get(qname)
+ property = (yield self.propertyStore.get(qname))
except HTTPError:
del cache[qname]
raise PropertyNotFoundError(qname)
cache[qname] = property
- return property
+ returnValue(property)
else:
raise PropertyNotFoundError(qname)
+ @inlineCallbacks
def set(self, property):
#self.log_debug("Set: %r, %r" % (self.resource.fp.path, property))
- cache = self._cache()
+ cache = (yield self._cache())
cache[property.qname()] = None
- self.propertyStore.set(property)
+ yield self.propertyStore.set(property)
cache[property.qname()] = property
- return succeed(None)
+ returnValue(None)
+ @inlineCallbacks
def contains(self, qname):
#self.log_debug("Contains: %r, %r" % (self.resource.fp.path, qname))
try:
- cache = self._cache()
+ cache = (yield self._cache())
except HTTPError, e:
if e.response.code == responsecode.NOT_FOUND:
- return False
+ returnValue(False)
else:
raise
if qname in cache:
#self.log_debug("Contains cache hit: %r, %r, %r" % (self, self.resource.fp.path, qname))
- return True
+ returnValue(True)
else:
- return False
+ returnValue(False)
def delete(self, qname):
#self.log_debug("Delete: %r, %r" % (self.resource.fp.path, qname))
@@ -1146,18 +1154,21 @@
self.propertyStore.delete(qname)
+ @inlineCallbacks
def list(self):
#self.log_debug("List: %r" % (self.resource.fp.path,))
- return self._cache().iterkeys()
+ cache = (yield self._cache())
+ returnValue(cache.iterkeys())
+ @inlineCallbacks
def _cache(self):
if not hasattr(self, "_data"):
#self.log_debug("Cache init: %r" % (self.resource.fp.path,))
self._data = dict(
(name, None)
- for name in self.propertyStore.list()
+ for name in (yield self.propertyStore.list())
)
- return self._data
+ returnValue(self._data)
def flushCache(self):
Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/freebusyurl.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/freebusyurl.py 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/freebusyurl.py 2009-08-28 20:49:31 UTC (rev 4513)
@@ -22,7 +22,7 @@
"FreeBusyURLResource",
]
-from twisted.internet.defer import inlineCallbacks, returnValue
+from twisted.internet.defer import inlineCallbacks, returnValue, succeed
from twisted.python import log
from twisted.web2 import responsecode
from twisted.web2.dav import davxml
@@ -96,16 +96,16 @@
return davxml.ACL(*aces)
def resourceType(self):
- return davxml.ResourceType.freebusyurl
+ return succeed(davxml.ResourceType.freebusyurl)
def isCollection(self):
return False
def isCalendarCollection(self):
- return False
+ return succeed(False)
def isPseudoCalendarCollection(self):
- return False
+ return succeed(False)
def render(self, request):
output = """<html>
@@ -203,7 +203,7 @@
# Pick the first mailto cu address or the first other type
cuaddr = None
- for item in principal.calendarUserAddresses():
+ for item in (yield principal.calendarUserAddresses()):
if cuaddr is None:
cuaddr = item
if item.startswith("mailto"):
Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/index.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/index.py 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/index.py 2009-08-28 20:49:31 UTC (rev 4513)
@@ -742,6 +742,7 @@
index. C{resource} must be a calendar collection (i.e.
C{resource.isPseudoCalendarCollection()} returns C{True}.)
"""
+ # MOR: isCalendarCollection( ) is now deferred. What to do here?
assert resource.isCalendarCollection(), "non-calendar collection resource %s has no index." % (resource,)
super(Index, self).__init__(resource)
@@ -844,6 +845,7 @@
index. C{resource} must be a calendar collection (i.e.
C{resource.isPseudoCalendarCollection()} returns C{True}.)
"""
+ # MOR: isCalendarCollection( ) is now deferred. What to do here?
assert resource.isPseudoCalendarCollection() and not resource.isCalendarCollection(), "non-calendar collection resource %s has no index." % (resource,)
super(IndexSchedule, self).__init__(resource)
Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/mail.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/mail.py 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/mail.py 2009-08-28 20:49:31 UTC (rev 4513)
@@ -225,16 +225,16 @@
return succeed(self.iMIPACL)
def resourceType(self):
- return davxml.ResourceType.ischeduleinbox
+ return succeed(davxml.ResourceType.ischeduleinbox)
def isCollection(self):
return False
def isCalendarCollection(self):
- return False
+ return succeed(False)
def isPseudoCalendarCollection(self):
- return False
+ return succeed(False)
def deadProperties(self):
if not hasattr(self, "_dead_properties"):
Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/memcacheprops.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/memcacheprops.py 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/memcacheprops.py 2009-08-28 20:49:31 UTC (rev 4513)
@@ -283,7 +283,7 @@
path = self.child.fp.path
key = self.parentPropertyCollection._keyForPath(path)
parentPropertyCache = (yield self.parentPropertyCollection.propertyCache())
- returnValue(parentPropertyCache.get(key, ({}, None))[0])
+ returnValue((yield parentPropertyCache.get(key, ({}, None)))[0])
def flushCache(self):
self.parentPropertyCollection.flushCache(self.child)
@@ -304,21 +304,23 @@
% (qname, self.childPropertyStore.resource.fp.path))
returnValue((yield self.childPropertyStore.get(qname)))
+ @inlineCallbacks
def set(self, property):
self.log_debug("Write for %s on %s"
% (property.qname(), self.childPropertyStore.resource.fp.path))
- self.parentPropertyCollection.setProperty(self.child, property)
- self.childPropertyStore.set(property)
- return succeed(None)
+ yield self.parentPropertyCollection.setProperty(self.child, property)
+ yield self.childPropertyStore.set(property)
+ returnValue(None)
+ @inlineCallbacks
def delete(self, qname):
self.log_debug("Delete for %s on %s"
% (qname, self.childPropertyStore.resource.fp.path))
- self.parentPropertyCollection.deleteProperty(self.child, qname)
- self.childPropertyStore.delete(qname)
- return succeed(None)
+ yield self.parentPropertyCollection.deleteProperty(self.child, qname)
+ yield self.childPropertyStore.delete(qname)
+ returnValue(None)
@inlineCallbacks
def contains(self, qname, cache=True):
@@ -328,7 +330,7 @@
self.log_debug("Contains for %s"
% (self.childPropertyStore.resource.fp.path,))
- returnValue(self.childPropertyStore.contains(qname))
+ returnValue((yield self.childPropertyStore.contains(qname)))
@inlineCallbacks
def list(self, cache=True):
@@ -338,4 +340,4 @@
self.log_debug("List for %s"
% (self.childPropertyStore.resource.fp.path,))
- returnValue(self.childPropertyStore.list())
+ returnValue((yield self.childPropertyStore.list()))
Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/method/copymove.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/method/copymove.py 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/method/copymove.py 2009-08-28 20:49:31 UTC (rev 4513)
@@ -48,7 +48,7 @@
"""
# Copy of calendar collections isn't allowed.
- if isPseudoCalendarCollectionResource(self):
+ if (yield isPseudoCalendarCollectionResource(self)):
returnValue(responsecode.FORBIDDEN)
result, sourcecal, sourceparent, destination_uri, destination, destinationcal, destinationparent = (yield checkForCalendarAction(self, request))
@@ -79,7 +79,7 @@
)
# Checks for copying a calendar collection
- if self.isCalendarCollection():
+ if (yield self.isCalendarCollection()):
log.err("Attempt to copy a calendar collection into another calendar collection %s" % destination)
raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (caldav_namespace, "calendar-collection-location-ok")))
@@ -118,7 +118,7 @@
"""
result, sourcecal, sourceparent, destination_uri, destination, destinationcal, destinationparent = (yield checkForCalendarAction(self, request))
if not result:
- is_calendar_collection = isPseudoCalendarCollectionResource(self)
+ is_calendar_collection = (yield isPseudoCalendarCollectionResource(self))
defaultCalendar = (yield self.isDefaultCalendar(request)) if is_calendar_collection else False
# Do default WebDAV action
@@ -154,7 +154,7 @@
if destinationcal:
# Checks for copying a calendar collection
- if self.isCalendarCollection():
+ if (yield self.isCalendarCollection()):
log.err("Attempt to move a calendar collection into another calendar collection %s" % destination)
raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (caldav_namespace, "calendar-collection-location-ok")))
@@ -219,7 +219,7 @@
# Check for parent calendar collection
sourceparent = (yield request.locateResource(parentForURL(request.uri)))
- if isCalendarCollectionResource(sourceparent):
+ if (yield isCalendarCollectionResource(sourceparent)):
result = True
sourcecal = True
@@ -238,7 +238,7 @@
# Check for parent calendar collection
destination_uri = urlsplit(destination_uri)[2]
destinationparent = (yield request.locateResource(parentForURL(destination_uri)))
- if isCalendarCollectionResource(destinationparent):
+ if (yield isCalendarCollectionResource(destinationparent)):
result = True
destinationcal = True
Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/method/delete_common.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/method/delete_common.py 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/method/delete_common.py 2009-08-28 20:49:31 UTC (rev 4513)
@@ -105,7 +105,7 @@
yield delresource.quotaSizeAdjust(self.request, -old_size)
if response == responsecode.NO_CONTENT:
- if isPseudoCalendarCollectionResource(parent):
+ if (yield isPseudoCalendarCollectionResource(parent)):
index = parent.index()
index.deleteResource(delresource.fp.basename())
@@ -278,10 +278,10 @@
@inlineCallbacks
def run(self):
- if isCalendarCollectionResource(self.parent):
+ if (yield isCalendarCollectionResource(self.parent)):
response = (yield self.deleteCalendarResource(self.resource, self.resource_uri, self.parent))
- elif isCalendarCollectionResource(self.resource):
+ elif (yield isCalendarCollectionResource(self.resource)):
response = (yield self.deleteCalendar(self.resource, self.resource_uri, self.parent))
elif self.resource.isCollection():
Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/method/put.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/method/put.py 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/method/put.py 2009-08-28 20:49:31 UTC (rev 4513)
@@ -39,7 +39,7 @@
parentURL = parentForURL(request.uri)
parent = (yield request.locateResource(parentURL))
- if isPseudoCalendarCollectionResource(parent):
+ if (yield isPseudoCalendarCollectionResource(parent)):
self.fp.restat(False)
# Content-type check
Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/method/report_calquery.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/method/report_calquery.py 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/method/report_calquery.py 2009-08-28 20:49:31 UTC (rev 4513)
@@ -58,7 +58,7 @@
if not self.isCollection():
parent = (yield self.locateParent(request, request.uri))
- if not parent.isPseudoCalendarCollection():
+ if not (yield parent.isPseudoCalendarCollection()):
log.err("calendar-query report is not allowed on a resource outside of a calendar collection %s" % (self,))
raise HTTPError(StatusResponse(responsecode.FORBIDDEN, "Must be calendar collection or calendar resource"))
@@ -146,12 +146,12 @@
else:
href = davxml.HRef.fromString(uri)
- returnValue(report_common.responseForHref(request, responses, href, resource, calendar, timezone, propertiesForResource, query, isowner))
+ returnValue((yield report_common.responseForHref(request, responses, href, resource, calendar, timezone, propertiesForResource, query, isowner)))
else:
returnValue(None)
# Check whether supplied resource is a calendar or a calendar object resource
- if calresource.isPseudoCalendarCollection():
+ if (yield calresource.isPseudoCalendarCollection()):
# Get the timezone property from the collection if one was not set in the query,
# and store in the query filter for later use
has_prop = (yield calresource.hasProperty((caldav_namespace, "calendar-timezone"), request))
@@ -174,11 +174,11 @@
try:
# Get list of children that match the search and have read
# access
- results = yield calresource.index().indexedSearch(filter)
+ results = (yield calresource.index().indexedSearch(filter))
names = [name for name, ignore_uid, ignore_type
in results]
except IndexedSearchException:
- results = yield calresource.index().bruteForceSearch()
+ results = (yield calresource.index().bruteForceSearch())
names = [name for name, ignore_uid, ignore_type
in results]
index_query_ok = False
@@ -203,7 +203,7 @@
child_path_name = urllib.unquote(child_uri_name)
if generate_calendar_data or not index_query_ok:
- calendar = yield calresource.iCalendar(child_path_name)
+ calendar = (yield calresource.iCalendar(child_path_name))
assert calendar is not None, "Calendar %s is missing from calendar collection %r" % (child_uri_name, self)
else:
calendar = None
@@ -216,7 +216,7 @@
if query_tz is None:
parent = (yield calresource.locateParent(request, uri))
- assert parent is not None and parent.isPseudoCalendarCollection()
+ assert parent is not None and (yield parent.isPseudoCalendarCollection())
has_prop = (yield parent.hasProperty((caldav_namespace, "calendar-timezone"), request))
if has_prop:
@@ -227,7 +227,7 @@
# Check private events access status
isowner = (yield calresource.isOwner(request, adminprincipals=True, readprincipals=True))
- calendar = yield calresource.iCalendar()
+ calendar = (yield calresource.iCalendar())
yield queryCalendarObjectResource(calresource, uri, None, calendar, timezone)
returnValue(True)
Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/method/report_common.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/method/report_common.py 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/method/report_common.py 2009-08-28 20:49:31 UTC (rev 4513)
@@ -85,7 +85,7 @@
return
# When scanning we only go down as far as a calendar collection - not into one
- if resource.isPseudoCalendarCollection():
+ if (yield resource.isPseudoCalendarCollection()):
resources = [(resource, request_uri)]
elif not resource.isCollection():
resources = [(resource, request_uri)]
Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/method/report_multiget.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/method/report_multiget.py 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/method/report_multiget.py 2009-08-28 20:49:31 UTC (rev 4513)
@@ -54,7 +54,7 @@
# Make sure target resource is of the right type
if not self.isCollection():
parent = (yield self.locateParent(request, request.uri))
- if not parent.isPseudoCalendarCollection():
+ if not (yield parent.isPseudoCalendarCollection()):
log.err("calendar-multiget report is not allowed on a resource outside of a calendar collection %s" % (self,))
raise HTTPError(StatusResponse(responsecode.FORBIDDEN, "Must be calendar resource"))
@@ -105,7 +105,7 @@
"""
disabled = False
- if self.isPseudoCalendarCollection():
+ if (yield self.isPseudoCalendarCollection()):
requestURIis = "calendar"
# Do some optimisation of access control calculation by determining any inherited ACLs outside of
@@ -216,7 +216,7 @@
parent = (yield child.locateParent(request, resource_uri))
- if not parent.isCalendarCollection() or not parent.index().resourceExists(name):
+ if not (yield parent.isCalendarCollection()) or not parent.index().resourceExists(name):
responses.append(davxml.StatusResponse(href, davxml.Status.fromResponseCode(responsecode.FORBIDDEN)))
continue
@@ -245,7 +245,7 @@
parent = (yield self.locateParent(request, resource_uri))
- if not parent.isPseudoCalendarCollection() or not parent.index().resourceExists(name):
+ if not (yield parent.isPseudoCalendarCollection()) or not parent.index().resourceExists(name):
responses.append(davxml.StatusResponse(href, davxml.Status.fromResponseCode(responsecode.FORBIDDEN)))
continue
child = self
Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/resource.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/resource.py 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/resource.py 2009-08-28 20:49:31 UTC (rev 4513)
@@ -115,6 +115,7 @@
# HTTP
##
+ @inlineCallbacks
def render(self, request):
if config.EnableMonolithicCalendars:
#
@@ -139,24 +140,20 @@
else:
renderAsHTML = True
- if not renderAsHTML and self.isPseudoCalendarCollection():
+ if not renderAsHTML and (yield self.isPseudoCalendarCollection()):
# Render a monolithic iCalendar file
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=':/')+'/')))
- def _defer(data):
- response = Response()
- response.stream = MemoryStream(str(data))
- response.headers.setHeader("content-type", MimeType.fromString("text/calendar"))
- return response
+ data = (yield self.iCalendarRolledup(request))
+ response = Response()
+ response.stream = MemoryStream(str(data))
+ response.headers.setHeader("content-type", MimeType.fromString("text/calendar"))
+ returnValue(response)
- d = self.iCalendarRolledup(request)
- d.addCallback(_defer)
- return d
+ returnValue((yield super(CalDAVResource, self).render(request)))
- return super(CalDAVResource, self).render(request)
-
def renderHTTP(self, request):
response = maybeDeferred(super(CalDAVResource, self).renderHTTP, request)
@@ -197,6 +194,7 @@
*[caldavxml.CalendarComponent(name=item) for item in allowedComponents]
)
+ @inlineCallbacks
def hasProperty(self, property, request):
"""
Need to special case schedule-calendar-transp for backwards compatability.
@@ -208,10 +206,10 @@
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)
+ if qname == (caldav_namespace, "schedule-calendar-transp") and (yield self.isCalendarCollection()):
+ returnValue(True)
else:
- return super(CalDAVResource, self).hasProperty(property, request)
+ returnValue((yield super(CalDAVResource, self).hasProperty(property, request)))
@inlineCallbacks
def readProperty(self, property, request):
@@ -258,7 +256,7 @@
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 (yield self.hasDeadProperty(property)):
+ if (yield self.isCalendarCollection()) and not (yield 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))
@@ -276,7 +274,7 @@
)
if property.qname() == (caldav_namespace, "supported-calendar-component-set"):
- if not self.isPseudoCalendarCollection():
+ if not (yield self.isPseudoCalendarCollection()):
raise HTTPError(StatusResponse(
responsecode.FORBIDDEN,
"Property %s may only be set on calendar collection." % (property,)
@@ -306,7 +304,7 @@
))
elif property.qname() == (caldav_namespace, "schedule-calendar-transp"):
- if not self.isCalendarCollection():
+ if not (yield self.isCalendarCollection()):
raise HTTPError(StatusResponse(
responsecode.FORBIDDEN,
"Property %s may only be set on calendar collection." % (property,)
@@ -320,7 +318,7 @@
if inboxURL:
inbox = (yield request.locateResource(inboxURL))
myurl = (yield self.canonicalURL(request))
- inbox.processFreeBusyCalendar(myurl, property.children[0] == caldavxml.Opaque())
+ yield inbox.processFreeBusyCalendar(myurl, property.children[0] == caldavxml.Opaque())
result = (yield super(CalDAVResource, self).writeProperty(property, request))
returnValue(result)
@@ -498,6 +496,21 @@
return ca
def gotChild(child, childpath, children):
+ def isCalCallback(result):
+ if result:
+ 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)
+
+ d = child.isCalendarCollection()
+ d.addCallback(isCalCallback)
+ return d
+
+ """ MOR: Remove
if child.isCalendarCollection():
callback(child, childpath)
elif child.isCollection():
@@ -505,8 +518,8 @@
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:
@@ -552,7 +565,7 @@
inboxURL = yield principal.scheduleInboxURL()
if inboxURL:
inbox = (yield request.locateResource(inboxURL))
- inbox.processFreeBusyCalendar(request.path, False)
+ yield inbox.processFreeBusyCalendar(request.path, False)
@inlineCallbacks
def movedCalendar(self, request, defaultCalendar, destination, destination_uri):
@@ -567,8 +580,8 @@
(_ignore_scheme, _ignore_host, destination_path, _ignore_query, _ignore_fragment) = urlsplit(normalizeURL(destination_uri))
inbox = (yield request.locateResource(inboxURL))
- inbox.processFreeBusyCalendar(request.path, False)
- inbox.processFreeBusyCalendar(destination_uri, (yield destination.isCalendarOpaque()))
+ yield inbox.processFreeBusyCalendar(request.path, False)
+ yield inbox.processFreeBusyCalendar(destination_uri, (yield destination.isCalendarOpaque()))
# Adjust the default calendar setting if necessary
if defaultCalendar:
@@ -577,7 +590,7 @@
@inlineCallbacks
def isCalendarOpaque(self):
- assert self.isCalendarCollection()
+ assert (yield self.isCalendarCollection())
if (yield self.hasDeadProperty((caldav_namespace, "schedule-calendar-transp"))):
property = (yield self.readDeadProperty((caldav_namespace, "schedule-calendar-transp")))
@@ -588,7 +601,7 @@
@inlineCallbacks
def isDefaultCalendar(self, request):
- assert self.isCalendarCollection()
+ assert (yield self.isCalendarCollection())
# Not allowed to delete the default calendar
principal = (yield self.ownerPrincipal(request))
@@ -707,7 +720,7 @@
"""
# Do this only for regular calendar collections and Inbox/Outbox
- if self.isPseudoCalendarCollection():
+ if (yield self.isPseudoCalendarCollection()):
edited_aces = []
for ace in newaces:
if TwistedACLInheritable() not in ace.children:
@@ -757,13 +770,13 @@
"""
Quota root only ever set on calendar homes.
"""
- return False
+ return succeed(False)
def quotaRoot(self, request):
"""
Quota root only ever set on calendar homes.
"""
- return None
+ return succeed(None)
class CalendarPrincipalCollectionResource (DAVPrincipalCollectionResource, CalDAVResource):
"""
@@ -775,10 +788,10 @@
return True
def isCalendarCollection(self):
- return False
+ return succeed(False)
def isPseudoCalendarCollection(self):
- return False
+ return succeed(False)
def principalForCalendarUserAddress(self, address):
return None
@@ -855,25 +868,25 @@
if namespace == caldav_namespace:
if name == "calendar-home-set":
- urls = yield self.calendarHomeURLs()
+ urls = (yield self.calendarHomeURLs())
returnValue(caldavxml.CalendarHomeSet(
*[davxml.HRef(url) for url in urls]
))
elif name == "calendar-user-address-set":
returnValue(caldavxml.CalendarUserAddressSet(
- *[davxml.HRef(uri) for uri in self.calendarUserAddresses()]
+ *[davxml.HRef(uri) for uri in (yield self.calendarUserAddresses())]
))
elif name == "schedule-inbox-URL":
- url = yield self.scheduleInboxURL()
+ url = (yield self.scheduleInboxURL())
if url is None:
returnValue(None)
else:
returnValue(caldavxml.ScheduleInboxURL(davxml.HRef(url)))
elif name == "schedule-outbox-URL":
- url = yield self.scheduleOutboxURL()
+ url = (yield self.scheduleOutboxURL())
if url is None:
returnValue(None)
else:
@@ -884,7 +897,7 @@
elif namespace == calendarserver_namespace:
if name == "dropbox-home-URL" and config.EnableDropBox:
- url = yield self.dropboxURL()
+ url = (yield self.dropboxURL())
if url is None:
returnValue(None)
else:
@@ -1004,7 +1017,7 @@
"""
Quota root only ever set on calendar homes.
"""
- return False
+ return succeed(False)
def quotaRoot(self, request):
"""
@@ -1049,7 +1062,7 @@
try:
resource = ICalDAVResource(resource)
except TypeError:
- return False
+ return succeed(False)
else:
return resource.isCalendarCollection()
@@ -1057,7 +1070,7 @@
try:
resource = ICalDAVResource(resource)
except TypeError:
- return False
+ return succeed(False)
else:
return resource.isPseudoCalendarCollection()
Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/schedule.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/schedule.py 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/schedule.py 2009-08-28 20:49:31 UTC (rev 4513)
@@ -26,7 +26,7 @@
from twext.web2.dav.davxml import ErrorResponse
-from twisted.internet.defer import inlineCallbacks, returnValue
+from twisted.internet.defer import inlineCallbacks, returnValue, succeed
from twisted.web2 import responsecode
from twisted.web2.dav import davxml
from twisted.web2.dav.util import joinURL, normalizeURL
@@ -63,10 +63,10 @@
return True
def isCalendarCollection(self):
- return False
+ return succeed(False)
def isPseudoCalendarCollection(self):
- return True
+ return succeed(True)
def supportedReports(self):
result = super(CalDAVResource, self).supportedReports()
@@ -88,7 +88,7 @@
)
def resourceType(self):
- return davxml.ResourceType.scheduleInbox
+ return succeed(davxml.ResourceType.scheduleInbox)
def defaultAccessControlList(self):
@@ -115,18 +115,18 @@
if qname == (caldav_namespace, "calendar-free-busy-set"):
# Always return at least an empty list
- if not self.hasDeadProperty(property):
+ if not (yield self.hasDeadProperty(property)):
returnValue(caldavxml.CalendarFreeBusySet())
elif qname == (caldav_namespace, "schedule-default-calendar-URL"):
# Must have a valid default
try:
- defaultCalendarProperty = self.readDeadProperty(property)
+ defaultCalendarProperty = (yield self.readDeadProperty(property))
except HTTPError:
defaultCalendarProperty = None
if defaultCalendarProperty and len(defaultCalendarProperty.children) == 1:
defaultCalendar = str(defaultCalendarProperty.children[0])
cal = (yield request.locateResource(str(defaultCalendar)))
- if cal is not None and cal.exists() and isCalendarCollectionResource(cal):
+ if cal is not None and cal.exists() and (yield isCalendarCollectionResource(cal)):
returnValue(defaultCalendarProperty)
# Default is not valid - we have to try to pick one
@@ -157,14 +157,14 @@
# whether existing items in the property are still valid - only new ones.
property.children = [davxml.HRef(normalizeURL(str(href))) for href in property.children]
new_calendars = set([str(href) for href in property.children])
- if not self.hasDeadProperty(property):
+ if not (yield self.hasDeadProperty(property)):
old_calendars = set()
else:
- old_calendars = set([str(href) for href in self.readDeadProperty(property).children])
+ old_calendars = set([str(href) for href in (yield self.readDeadProperty(property)).children])
added_calendars = new_calendars.difference(old_calendars)
for href in added_calendars:
cal = (yield request.locateResource(str(href)))
- if cal is None or not cal.exists() or not isCalendarCollectionResource(cal):
+ if cal is None or not cal.exists() or not (yield isCalendarCollectionResource(cal)):
# Validate that href's point to a valid calendar.
raise HTTPError(ErrorResponse(
responsecode.CONFLICT,
@@ -180,7 +180,7 @@
calURI = str(new_calendar[0])
cal = (yield request.locateResource(str(new_calendar[0])))
# TODO: check that owner of the new calendar is the same as owner of this inbox
- if cal is None or not cal.exists() or not isCalendarCollectionResource(cal):
+ if cal is None or not cal.exists() or not (yield isCalendarCollectionResource(cal)):
# Validate that href's point to a valid calendar.
raise HTTPError(ErrorResponse(
responsecode.CONFLICT,
@@ -193,21 +193,22 @@
yield super(ScheduleInboxResource, self).writeProperty(property, request)
+ @inlineCallbacks
def processFreeBusyCalendar(self, uri, addit):
uri = normalizeURL(uri)
- if not self.hasDeadProperty((caldav_namespace, "calendar-free-busy-set")):
+ if not (yield self.hasDeadProperty((caldav_namespace, "calendar-free-busy-set"))):
fbset = set()
else:
- fbset = set([normalizeURL(str(href)) for href in self.readDeadProperty((caldav_namespace, "calendar-free-busy-set")).children])
+ fbset = set([normalizeURL(str(href)) for href in (yield self.readDeadProperty((caldav_namespace, "calendar-free-busy-set"))).children])
if addit:
if uri not in fbset:
fbset.add(uri)
- self.writeDeadProperty(caldavxml.CalendarFreeBusySet(*[davxml.HRef(url) for url in fbset]))
+ yield self.writeDeadProperty(caldavxml.CalendarFreeBusySet(*[davxml.HRef(url) for url in fbset]))
else:
if uri in fbset:
fbset.remove(uri)
- self.writeDeadProperty(caldavxml.CalendarFreeBusySet(*[davxml.HRef(url) for url in fbset]))
+ yield self.writeDeadProperty(caldavxml.CalendarFreeBusySet(*[davxml.HRef(url) for url in fbset]))
@inlineCallbacks
def pickNewDefaultCalendar(self, request):
@@ -222,7 +223,7 @@
if defaultCalendar is None or not defaultCalendar.exists():
self.parent.provisionDefaultCalendars()
else:
- self.writeDeadProperty(caldavxml.ScheduleDefaultCalendarURL(davxml.HRef(defaultCalendarURL)))
+ yield self.writeDeadProperty(caldavxml.ScheduleDefaultCalendarURL(davxml.HRef(defaultCalendarURL)))
returnValue(caldavxml.ScheduleDefaultCalendarURL(davxml.HRef(defaultCalendarURL)))
class ScheduleOutboxResource (CalendarSchedulingCollectionResource):
@@ -254,7 +255,7 @@
return super(ScheduleOutboxResource, self).defaultAccessControlList()
def resourceType(self):
- return davxml.ResourceType.scheduleOutbox
+ return succeed(davxml.ResourceType.scheduleOutbox)
@inlineCallbacks
def http_POST(self, request):
@@ -311,16 +312,16 @@
)
def resourceType(self):
- return davxml.ResourceType.ischeduleinbox
+ return succeed(davxml.ResourceType.ischeduleinbox)
def isCollection(self):
return False
def isCalendarCollection(self):
- return False
+ return succeed(False)
def isPseudoCalendarCollection(self):
- return False
+ return succeed(False)
def render(self, request):
output = """<html>
Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/scheduling/caldav.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/scheduling/caldav.py 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/scheduling/caldav.py 2009-08-28 20:49:31 UTC (rev 4513)
@@ -177,14 +177,14 @@
responses.add(recipient.cuaddr, responsecode.OK, reqstatus=iTIPRequestStatus.MESSAGE_DELIVERED)
# Store CALDAV:originator property
- child.writeDeadProperty(caldavxml.Originator(davxml.HRef(self.scheduler.originator.cuaddr)))
+ yield child.writeDeadProperty(caldavxml.Originator(davxml.HRef(self.scheduler.originator.cuaddr)))
# Store CALDAV:recipient property
- child.writeDeadProperty(caldavxml.Recipient(davxml.HRef(recipient.cuaddr)))
+ yield child.writeDeadProperty(caldavxml.Recipient(davxml.HRef(recipient.cuaddr)))
# Store CS:schedule-changes property if present
if changes:
- child.writeDeadProperty(changes)
+ yield child.writeDeadProperty(changes)
returnValue(True)
@@ -192,7 +192,7 @@
def generateFreeBusyResponse(self, recipient, responses, organizerProp, uid):
# Extract the ATTENDEE property matching current recipient from the calendar data
- cuas = recipient.principal.calendarUserAddresses()
+ cuas = (yield recipient.principal.calendarUserAddresses())
attendeeProp = self.scheduler.calendar.getAttendeeProperty(cuas)
remote = isinstance(self.scheduler.organizer, RemoteCalendarUser)
@@ -241,7 +241,7 @@
matchtotal = 0
for calendarResourceURL in fbset:
calendarResource = (yield self.scheduler.request.locateResource(calendarResourceURL))
- if calendarResource is None or not calendarResource.exists() or not isCalendarCollectionResource(calendarResource):
+ if calendarResource is None or not calendarResource.exists() or not (yield isCalendarCollectionResource(calendarResource)):
# We will ignore missing calendars. If the recipient has failed to
# properly manage the free busy set that should not prevent us from working.
continue
Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/scheduling/implicit.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/scheduling/implicit.py 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/scheduling/implicit.py 2009-08-28 20:49:31 UTC (rev 4513)
@@ -179,7 +179,7 @@
if resource and resource.exists():
try:
- implicit = resource.readDeadProperty(TwistedSchedulingObjectResource)
+ implicit = (yield resource.readDeadProperty(TwistedSchedulingObjectResource))
except HTTPError:
implicit = None
if implicit is not None:
@@ -193,7 +193,7 @@
# We have different ORGANIZERs in the same iCalendar object - this is an error
returnValue(False)
organizerPrincipal = resource.principalForCalendarUserAddress(organizer) if organizer else None
- resource.writeDeadProperty(TwistedSchedulingObjectResource("true" if organizerPrincipal != None else "false"))
+ yield resource.writeDeadProperty(TwistedSchedulingObjectResource("true" if organizerPrincipal != None else "false"))
log.debug("Implicit - checked scheduling object resource state for UID: '%s', result: %s" % (
calendar.resourceUID(),
"true" if organizerPrincipal != None else "false",
@@ -335,7 +335,7 @@
self.originatorPrincipal = (yield self.request.locateResource(originatorPrincipalURL))
if self.originatorPrincipal:
# Pick the first mailto cu address or the first other type
- for item in self.originatorPrincipal.calendarUserAddresses():
+ for item in (yield self.originatorPrincipal.calendarUserAddresses()):
if not self.originator:
self.originator = item
if item.startswith("mailto:"):
@@ -667,7 +667,7 @@
for attendee, rids in aggregated.iteritems():
# Don't send message back to the ORGANIZER
- if attendee in self.organizerPrincipal.calendarUserAddresses():
+ if attendee in (yield self.organizerPrincipal.calendarUserAddresses()):
continue
# Generate an iTIP CANCEL message for this attendee, cancelling
@@ -705,7 +705,7 @@
for attendee in self.attendees:
# Don't send message back to the ORGANIZER
- if attendee in self.organizerPrincipal.calendarUserAddresses():
+ if attendee in (yield self.organizerPrincipal.calendarUserAddresses()):
continue
# Don't send message to specified attendees
Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/scheduling/processing.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/scheduling/processing.py 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/scheduling/processing.py 2009-08-28 20:49:31 UTC (rev 4513)
@@ -508,7 +508,7 @@
all_declined = not any(instance_states.itervalues())
# Do the simple case of all accepted or decline separately
- cuas = self.recipient.principal.calendarUserAddresses()
+ cuas = (yield self.recipient.principal.calendarUserAddresses())
if all_accepted or all_declined:
# Extract the ATTENDEE property matching current recipient from the calendar data
attendeeProps = calendar.getAttendeeProperties(cuas)
Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/scheduling/scheduler.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/scheduling/scheduler.py 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/scheduling/scheduler.py 2009-08-28 20:49:31 UTC (rev 4513)
@@ -164,7 +164,7 @@
originatorPrincipal = (yield self.request.locateResource(originatorPrincipalURL))
if originatorPrincipal:
# Pick the first mailto cu address or the first other type
- for item in originatorPrincipal.calendarUserAddresses():
+ for item in (yield originatorPrincipal.calendarUserAddresses()):
if not originator:
originator = item
if item.startswith("mailto:"):
Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/static.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/static.py 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/static.py 2009-08-28 20:49:31 UTC (rev 4513)
@@ -97,7 +97,8 @@
return succeed(cls(path, *args, **kwargs))
def __repr__(self):
- if self.isCalendarCollection():
+ # MOR: I don't think we can defer __repr__ even though isCalendarCollection( ) now is
+ if False and self.isCalendarCollection():
return "<%s (calendar collection): %s>" % (self.__class__.__name__, self.fp.path)
else:
return super(CalDAVFile, self).__repr__()
@@ -169,11 +170,12 @@
# CalDAV
##
+ @inlineCallbacks
def resourceType(self):
- if self.isCalendarCollection():
- return davxml.ResourceType.calendar
+ if (yield self.isCalendarCollection()):
+ returnValue(davxml.ResourceType.calendar)
else:
- return super(CalDAVFile, self).resourceType()
+ returnValue((yield super(CalDAVFile, self).resourceType()))
def createCalendar(self, request):
#
@@ -254,7 +256,7 @@
@inlineCallbacks
def iCalendarRolledup(self, request):
- if self.isPseudoCalendarCollection():
+ if (yield self.isPseudoCalendarCollection()):
# Generate a monolithic calendar
calendar = iComponent("VCALENDAR")
calendar.addProperty(iProperty("VERSION", "2.0"))
@@ -319,19 +321,20 @@
returnValue(el.calendarData())
returnValue((yield self.iCalendarText()))
+ @inlineCallbacks
def iCalendarText(self, name=None):
- if self.isPseudoCalendarCollection():
+ if (yield self.isPseudoCalendarCollection()):
if name is None:
- return self.iCalendar().addCallback(str)
+ returnValue(self.iCalendar().addCallback(str))
try:
calendar_file = self.fp.child(name).open()
except IOError, e:
- if e[0] == errno.ENOENT: return None
+ if e[0] == errno.ENOENT: returnValue(None)
raise
elif self.isCollection():
- return succeed(None)
+ returnValue(None)
else:
if name is not None:
@@ -345,28 +348,23 @@
finally:
calendar_file.close()
- return succeed(calendar_data)
+ returnValue(calendar_data)
def iCalendarXML(self, name=None):
return self.iCalendarText(name).addCallback(caldavxml.CalendarData.fromCalendar)
+ @inlineCallbacks
def supportedPrivileges(self, request):
# read-free-busy support on calendar collection and calendar object resources
- if self.isCollection():
- return succeed(calendarPrivilegeSet)
+ if (yield self.isCollection()):
+ returnValue(calendarPrivilegeSet)
else:
- def gotParent(parent):
- if parent and isCalendarCollectionResource(parent):
- return succeed(calendarPrivilegeSet)
- else:
- return super(CalDAVFile, self).supportedPrivileges(request)
+ parent = (yield self.locateParent(request, request.urlForResource(self)))
+ if parent and (yield isCalendarCollectionResource(parent)):
+ returnValue(calendarPrivilegeSet)
+ else:
+ returnValue((yield super(CalDAVFile, self).supportedPrivileges(request)))
- d = self.locateParent(request, request.urlForResource(self))
- d.addCallback(gotParent)
- return d
-
- return super(CalDAVFile, self).supportedPrivileges(request)
-
##
# Public additions
##
@@ -399,34 +397,42 @@
return succeed(self)
d = maybeDeferred(super(CalDAVFile, self).createSimilarFile, path)
+
def _gotFile(similar):
- if isCalendarCollectionResource(self):
- #
- # Override DELETE, MOVE
- #
- for method in ("DELETE", "MOVE"):
- method = "http_" + method
- original = getattr(similar, method)
- @inlineCallbacks
- def override(request, original=original):
+ def _isCalCollection(result):
+ if result:
+ #
+ # Override DELETE, MOVE
+ #
+ for method in ("DELETE", "MOVE"):
+ method = "http_" + method
+ original = getattr(similar, method)
- # Call original method (which is deferred)
- response = (yield original(request))
+ @inlineCallbacks
+ def override(request, original=original):
- # Wipe the cache
- yield similar.deadProperties().flushCache()
+ # Call original method (which is deferred)
+ response = (yield original(request))
- returnValue(response)
+ # Wipe the cache
+ yield similar.deadProperties().flushCache()
- setattr(similar, method, override)
+ returnValue(response)
- return similar
+ setattr(similar, method, override)
+
+ return similar
+
+ d = isCalendarCollectionResource(self)
+ d.addCallback(_isCalCollection)
+ return d
+
return d.addCallback(_gotFile)
@inlineCallbacks
def updateCTag(self):
- assert self.isCollection()
+ assert (yield self.isCollection())
try:
yield self.writeDeadProperty(customxml.GETCTag(
str(datetime.datetime.now())))
@@ -441,7 +447,7 @@
% (self,))
if hasattr(self, 'cacheNotifier'):
- returnValue(self.cacheNotifier.changed())
+ returnValue((yield self.cacheNotifier.changed()))
else:
log.debug("%r does not have a cacheNotifier but the CTag changed"
% (self,))
@@ -544,32 +550,35 @@
parent = yield request.locateResource(parent_uri)
- if test(parent):
+ if (yield test(parent)):
returnValue(parent)
class AutoProvisioningFileMixIn (AutoProvisioningResourceMixIn):
+
def provision(self):
+ # MOR: Double check this:
d = self.provisionFile()
- super(AutoProvisioningFileMixIn, self).provision()
+ d.addCallback(super(AutoProvisioningFileMixIn, self).provision)
return d
+ @inlineCallbacks
def provisionFile(self, request=None):
if hasattr(self, "_provisioned_file"):
- return succeed(False)
+ returnValue(False)
else:
self._provisioned_file = True
fp = self.fp
fp.restat(False)
if fp.exists():
- return succeed(False)
+ returnValue(False)
log.msg("Provisioning file: %s" % (self,))
if hasattr(self, "parent"):
parent = self.parent
if not parent.exists() and isinstance(parent, AutoProvisioningFileMixIn):
- parent.provision()
+ yield parent.provision()
assert parent.exists(), "Parent %s of %s does not exist" % (parent, self)
assert parent.isCollection(), "Parent %s of %s is not a collection" % (parent, self)
@@ -587,7 +596,7 @@
fp.open("w").close()
fp.restat(False)
- return succeed(True)
+ returnValue(True)
class CalendarHomeProvisioningFile (AutoProvisioningFileMixIn, DirectoryCalendarHomeProvisioningResource, DAVFile):
"""
@@ -633,70 +642,53 @@
else:
self.homeResourceClass = homeResourceClass
+ @inlineCallbacks
def provisionChild(self, name):
record = self.directory.recordWithUID(name)
if record is None:
log.msg("No directory record with GUID %r" % (name,))
- return None
+ returnValue(None)
if not record.enabledForCalendaring:
log.msg("Directory record %r is not enabled for calendaring" % (record,))
- return None
+ returnValue(None)
assert len(name) > 4, "Directory record has an invalid GUID: %r" % (name,)
childPath = self.fp.child(name[0:2]).child(name[2:4]).child(name)
- d = self.homeResourceClass.fetch(None, childPath.path, self, record)
- def _gotChild(child):
- if not child.exists():
- self.provision()
+ child = (yield self.homeResourceClass.fetch(None, childPath.path, self, record))
+ if not child.exists():
+ yield self.provision()
- if not childPath.parent().isdir():
- childPath.parent().makedirs()
+ if not childPath.parent().isdir():
+ childPath.parent().makedirs()
- for oldPath in (
- # Pre 2.0: All in one directory
- self.fp.child(name),
- # Pre 1.2: In types hierarchy instead of the GUID hierarchy
- self.parent.getChild(record.recordType).fp.child(record.shortNames[0]),
- ):
- if oldPath.exists():
- # The child exists at an old location. Move to new location.
- log.msg("Moving calendar home from old location %r to new location %r." % (oldPath, childPath))
- try:
- oldPath.moveTo(childPath)
- except (OSError, IOError), e:
- log.err("Error moving calendar home %r: %s" % (oldPath, e))
- raise HTTPError(StatusResponse(
- responsecode.INTERNAL_SERVER_ERROR,
- "Unable to move calendar home."
- ))
- child.fp.restat(False)
- break
- else:
- #
- # NOTE: provisionDefaultCalendars() returns a deferred, which we are ignoring.
- # The result being that the default calendars will be present at some point
- # in the future, not necessarily right now, and we don't have a way to wait
- # on that to finish.
- #
- child.provisionDefaultCalendars()
-
- #
- # Try to work around the above a little by telling the client that something
- # when wrong temporarily if the child isn't provisioned right away.
- #
- if not child.exists():
+ for oldPath in (
+ # Pre 2.0: All in one directory
+ self.fp.child(name),
+ # Pre 1.2: In types hierarchy instead of the GUID hierarchy
+ (yield self.parent.getChild(record.recordType).fp.child(record.shortNames[0])),
+ ):
+ if oldPath.exists():
+ # The child exists at an old location. Move to new location.
+ log.msg("Moving calendar home from old location %r to new location %r." % (oldPath, childPath))
+ try:
+ oldPath.moveTo(childPath)
+ except (OSError, IOError), e:
+ log.err("Error moving calendar home %r: %s" % (oldPath, e))
raise HTTPError(StatusResponse(
- responsecode.SERVICE_UNAVAILABLE,
- "Provisioning calendar home."
+ responsecode.INTERNAL_SERVER_ERROR,
+ "Unable to move calendar home."
))
+ child.fp.restat(False)
+ break
+ else:
+ yield child.provisionDefaultCalendars()
- assert child.exists()
+ assert child.exists()
- return child
- return d.addCallback(_gotChild)
+ returnValue(child)
def createSimilarFile(self, path):
raise HTTPError(responsecode.NOT_FOUND)
@@ -765,7 +757,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):
- return None
+ returnValue(None)
return super(CalendarHomeFile, self).getChild(name)
@@ -832,9 +824,9 @@
def createSimilarFile(self, path):
if path == self.fp.path:
- return self
+ return succeed(self)
else:
- return CalDAVFile(path, principalCollections=self.principalCollections())
+ return succeed(CalDAVFile(path, principalCollections=self.principalCollections()))
def index(self):
"""
@@ -864,16 +856,17 @@
ScheduleFile.__init__(self, path, parent)
ScheduleInboxResource.__init__(self, parent)
+ @inlineCallbacks
def provision(self):
- if self.provisionFile():
+ if (yield self.provisionFile()):
# Initialize CTag on the calendar collection
- self.updateCTag()
+ yield self.updateCTag()
# Initialize the index
self.index().create()
- return super(ScheduleInboxFile, self).provision()
+ returnValue((yield super(ScheduleInboxFile, self).provision()))
def __repr__(self):
return "<%s (calendar inbox collection): %s>" % (self.__class__.__name__, self.fp.path)
@@ -894,12 +887,13 @@
ScheduleFile.__init__(self, path, parent)
ScheduleOutboxResource.__init__(self, parent)
+ @inlineCallbacks
def provision(self):
- if self.provisionFile():
+ if (yield self.provisionFile()):
# Initialize CTag on the calendar collection
- self.updateCTag()
+ yield self.updateCTag()
- return super(ScheduleOutboxFile, self).provision()
+ returnValue((yield super(ScheduleOutboxFile, self).provision()))
def __repr__(self):
return "<%s (calendar outbox collection): %s>" % (self.__class__.__name__, self.fp.path)
@@ -928,9 +922,9 @@
def createSimilarFile(self, path):
if path == self.fp.path:
- return self
+ return succeed(self)
else:
- return responsecode.NOT_FOUND
+ return succeed(responsecode.NOT_FOUND)
def http_PUT (self, request): return responsecode.FORBIDDEN
def http_COPY (self, request): return responsecode.FORBIDDEN
@@ -980,9 +974,9 @@
def createSimilarFile(self, path):
if path == self.fp.path:
- return self
+ return succeed(self)
else:
- return responsecode.NOT_FOUND
+ return succeed(responsecode.NOT_FOUND)
def http_PUT (self, request): return responsecode.FORBIDDEN
def http_COPY (self, request): return responsecode.FORBIDDEN
@@ -1011,9 +1005,9 @@
def createSimilarFile(self, path):
if path == self.fp.path:
- return self
+ return succeed(self)
else:
- return DropBoxCollectionFile(path, self)
+ return succeed(DropBoxCollectionFile(path, self))
def __repr__(self):
return "<%s (dropbox home collection): %s>" % (self.__class__.__name__, self.fp.path)
@@ -1025,9 +1019,9 @@
def createSimilarFile(self, path):
if path == self.fp.path:
- return self
+ return succeed(self)
else:
- return DropBoxChildFile(path, self)
+ return succeed(DropBoxChildFile(path, self))
def __repr__(self):
return "<%s (dropbox collection): %s>" % (self.__class__.__name__, self.fp.path)
@@ -1040,9 +1034,9 @@
def createSimilarFile(self, path):
if path == self.fp.path:
- return self
+ return succeed(self)
else:
- return responsecode.NOT_FOUND
+ return succeed(responsecode.NOT_FOUND)
class TimezoneServiceFile (TimezoneServiceResource, CalDAVFile):
def __init__(self, path, parent):
@@ -1053,9 +1047,9 @@
def createSimilarFile(self, path):
if path == self.fp.path:
- return self
+ return succeed(self)
else:
- return responsecode.NOT_FOUND
+ return succeed(responsecode.NOT_FOUND)
def http_PUT (self, request): return responsecode.FORBIDDEN
def http_COPY (self, request): return responsecode.FORBIDDEN
Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/test/test_index.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/test/test_index.py 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/test/test_index.py 2009-08-28 20:49:31 UTC (rev 4513)
@@ -16,6 +16,7 @@
from twisted.internet import reactor
from twisted.internet.task import deferLater
+from twisted.internet.defer import succeed
from twistedcaldav.ical import Component
from twistedcaldav.index import Index, default_future_expansion_duration,\
@@ -40,7 +41,7 @@
def setUp(self):
super(SQLIndexTests, self).setUp()
- self.site.resource.isCalendarCollection = lambda: True
+ self.site.resource.isCalendarCollection = lambda: succeed(True)
self.db = Index(self.site.resource)
Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/test/test_resource.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/test/test_resource.py 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/test/test_resource.py 2009-08-28 20:49:31 UTC (rev 4513)
@@ -15,6 +15,7 @@
##
from twistedcaldav.resource import CalDAVResource
+from twisted.internet.defer import inlineCallbacks
from twistedcaldav.test.util import InMemoryPropertyStore
from twistedcaldav.test.util import TestCase
Modified: CalendarServer/branches/more-deferreds-3/twistedcaldav/timezoneservice.py
===================================================================
--- CalendarServer/branches/more-deferreds-3/twistedcaldav/timezoneservice.py 2009-08-27 19:42:37 UTC (rev 4512)
+++ CalendarServer/branches/more-deferreds-3/twistedcaldav/timezoneservice.py 2009-08-28 20:49:31 UTC (rev 4513)
@@ -24,6 +24,7 @@
from twext.web2.dav.davxml import ErrorResponse
+from twisted.internet.defer import succeed
from twisted.web2 import responsecode
from twisted.web2.dav import davxml
from twisted.web2.http import HTTPError
@@ -73,16 +74,16 @@
)
def resourceType(self):
- return davxml.ResourceType.timezones
+ return succeed(davxml.ResourceType.timezones)
def isCollection(self):
return False
def isCalendarCollection(self):
- return False
+ return succeed(False)
def isPseudoCalendarCollection(self):
- return False
+ return succeed(False)
def render(self, request):
output = """<html>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20090828/ccbc31ff/attachment-0001.html>
More information about the calendarserver-changes
mailing list