[CalendarServer-changes] [130] CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted

source_changes at macosforge.org source_changes at macosforge.org
Wed Sep 13 14:13:25 PDT 2006


Revision: 130
Author:   cdaboo at apple.com
Date:     2006-09-13 14:13:23 -0700 (Wed, 13 Sep 2006)

Log Message:
-----------
Quota checks now work for copy/move and delete.

Modified Paths:
--------------
    CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.davxml.patch
    CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.idav.patch
    CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.method.put_common.patch
    CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.resource.patch
    CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.static.patch

Added Paths:
-----------
    CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.method.__init__.patch
    CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.method.copymove.patch
    CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.method.delete.patch
    CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.method.put.patch

Removed Paths:
-------------
    CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.method.put

Modified: CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.davxml.patch
===================================================================
--- CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.davxml.patch	2006-09-12 21:18:22 UTC (rev 129)
+++ CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.davxml.patch	2006-09-13 21:13:23 UTC (rev 130)
@@ -1,6 +1,6 @@
 Index: twisted/web2/dav/davxml.py
 ===================================================================
---- twisted/web2/dav/davxml.py	(revision 17935)
+--- twisted/web2/dav/davxml.py	(revision 18092)
 +++ twisted/web2/dav/davxml.py	(working copy)
 @@ -45,6 +45,7 @@
  from twisted.web2.dav.element.rfc2518 import *

Modified: CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.idav.patch
===================================================================
--- CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.idav.patch	2006-09-12 21:18:22 UTC (rev 129)
+++ CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.idav.patch	2006-09-13 21:13:23 UTC (rev 130)
@@ -1,8 +1,8 @@
 Index: twisted/web2/dav/idav.py
 ===================================================================
---- twisted/web2/dav/idav.py	(revision 18078)
-+++ twisted/web2/dav/idav.py	(working copy)
-@@ -187,6 +187,72 @@
+--- twisted/web2/dav/idav.py	(revision 18092)
++++twisted/web2/dav/idav.py	(working copy)
+@@ -187,6 +187,64 @@
              the specified principal.
          """
  
@@ -38,7 +38,7 @@
 +    
 +    def quotaSize(request):
 +        """
-+        Get the size of this resource.
++        Get the size of this resource (if its a collection get total for all children as well).
 +        TODO: Take into account size of dead-properties.
 +
 +        @return: a C{int} containing the size of the resource.
@@ -63,15 +63,7 @@
 +        @return: a C{int} containing the current used byte if this collection
 +            is quota-controlled, or C{None} if not quota controlled.
 +        """
-+        
-+    def determineActualQuotaUse(request):
-+        """
-+        Brute force determination of quota used by this collection.
 +
-+        @return: a C{int} containing the current used byte if this collection
-+            is quota-controlled, or C{None} if not quota controlled.
-+        """
-+
  class IDAVPrincipalResource (IDAVResource):
      """
      WebDAV principal resource.  (RFC 3744, section 2)

Added: CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.method.__init__.patch
===================================================================
--- CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.method.__init__.patch	                        (rev 0)
+++ CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.method.__init__.patch	2006-09-13 21:13:23 UTC (rev 130)
@@ -0,0 +1,12 @@
+Index: twisted/web2/dav/method/__init__.py
+===================================================================
+--- twisted/web2/dav/method/__init__.py	(revision 18092)
++++ twisted/web2/dav/method/__init__.py	(working copy)
+@@ -40,6 +40,7 @@
+     "proppatch",
+     "prop_common",
+     "put",
++    "put_common",
+     "report",
+     "report_acl_principal_prop_set",
+     "report_expand",

Added: CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.method.copymove.patch
===================================================================
--- CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.method.copymove.patch	                        (rev 0)
+++ CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.method.copymove.patch	2006-09-13 21:13:23 UTC (rev 130)
@@ -0,0 +1,46 @@
+Index: twisted/web2/dav/method/copymove.py
+===================================================================
+--- twisted/web2/dav/method/copymove.py	(revision 18092)
++++ twisted/web2/dav/method/copymove.py	(working copy)
+@@ -37,7 +37,7 @@
+ from twisted.web2.http import HTTPError, StatusResponse
+ from twisted.web2.dav import davxml
+ from twisted.web2.dav.idav import IDAVResource
+-from twisted.web2.dav.fileop import copy, move
++from twisted.web2.dav.method import put_common
+ from twisted.web2.dav.util import parentForURL
+ 
+ # FIXME: This is circular
+@@ -80,7 +80,15 @@
+         # May need to add a location header
+         addLocation(request, destination_uri)
+ 
+-    x = waitForDeferred(copy(self.fp, destination.fp, destination_uri, depth))
++    #x = waitForDeferred(copy(self.fp, destination.fp, destination_uri, depth))
++    x = waitForDeferred(put_common.storeResource(request,
++                                                 source=self,
++                                                 source_uri=request.uri,
++                                                 destination=destination,
++                                                 destination_uri=destination_uri,
++                                                 deletesource=False,
++                                                 depth=depth
++                                                 ))
+     yield x
+     yield x.getResult()
+ 
+@@ -143,7 +151,14 @@
+     # May need to add a location header
+     addLocation(request, destination_uri)
+ 
+-    x = waitForDeferred(move(self.fp, request.uri, destination.fp, destination_uri, depth))
++    #x = waitForDeferred(move(self.fp, request.uri, destination.fp, destination_uri, depth))
++    x = waitForDeferred(put_common.storeResource(request,
++                                                 source=self,
++                                                 source_uri=request.uri,
++                                                 destination=destination,
++                                                 destination_uri=destination_uri,
++                                                 deletesource=True,
++                                                 depth=depth))
+     yield x
+     yield x.getResult()
+ 

Added: CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.method.delete.patch
===================================================================
--- CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.method.delete.patch	                        (rev 0)
+++ CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.method.delete.patch	2006-09-13 21:13:23 UTC (rev 130)
@@ -0,0 +1,32 @@
+Index: twisted/web2/dav/method/delete.py
+===================================================================
+--- twisted/web2/dav/method/delete.py	(revision 18092)
++++ twisted/web2/dav/method/delete.py	(working copy)
+@@ -58,8 +58,26 @@
+     yield x
+     x.getResult()
+ 
++    # Do quota checks before we start deleting things
++    myquota = waitForDeferred(self.quota(request))
++    yield myquota
++    myquota = myquota.getResult()
++    if myquota is not None:
++        old_size = self.quotaSize(request)
++    else:
++        old_size = 0
++
++    # Do delete
+     x = waitForDeferred(delete(request.uri, self.fp, depth))
+     yield x
+-    yield x.getResult()
++    result = x.getResult()
++
++    # Adjust quota
++    if myquota is not None:
++        d = waitForDeferred(self.quotaSizeAdjust(request, -old_size))
++        yield d
++        d.getResult()
++    
++    yield result
+ 
+ http_DELETE = deferredGenerator(http_DELETE)

Deleted: CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.method.put
===================================================================
--- CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.method.put	2006-09-12 21:18:22 UTC (rev 129)
+++ CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.method.put	2006-09-13 21:13:23 UTC (rev 130)
@@ -1,19 +0,0 @@
-Index: twisted/web2/dav/method/put.py
-===================================================================
---- twisted/web2/dav/method/put.py	(revision 17951)
-+++ twisted/web2/dav/method/put.py	(working copy)
-@@ -22,6 +22,7 @@
- #
- # DRI: Wilfredo Sanchez, wsanchez at apple.com
- ##
-+from twisted.web2.dav.method import put_common
- 
- """
- WebDAV PUT method
-@@ -107,4 +108,5 @@
-     # to return a MULTI_STATUS response, which is WebDAV-specific (and PUT is
-     # not).
-     #
--    return put(request.stream, self.fp)
-+    #return put(request.stream, self.fp)
-+    return put_common.storeResource(request, destination=self, destination_uri=request.uri)

Copied: CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.method.put.patch (from rev 129, CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.method.put)
===================================================================
--- CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.method.put.patch	                        (rev 0)
+++ CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.method.put.patch	2006-09-13 21:13:23 UTC (rev 130)
@@ -0,0 +1,20 @@
+Index: twisted/web2/dav/method/put.py
+===================================================================
+--- twisted/web2/dav/method/put.py	(revision 18092)
++++ twisted/web2/dav/method/put.py	(working copy)
+@@ -34,7 +34,7 @@
+ from twisted.web2 import responsecode
+ from twisted.web2.http import HTTPError, StatusResponse
+ from twisted.web2.dav import davxml
+-from twisted.web2.dav.fileop import put
++from twisted.web2.dav.method import put_common
+ from twisted.web2.dav.util import parentForURL
+ 
+ def preconditions_PUT(self, request):
+@@ -107,4 +107,5 @@
+     # to return a MULTI_STATUS response, which is WebDAV-specific (and PUT is
+     # not).
+     #
+-    return put(request.stream, self.fp)
++    #return put(request.stream, self.fp)
++    return put_common.storeResource(request, destination=self, destination_uri=request.uri)

Modified: CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.method.put_common.patch
===================================================================
--- CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.method.put_common.patch	2006-09-12 21:18:22 UTC (rev 129)
+++ CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.method.put_common.patch	2006-09-13 21:13:23 UTC (rev 130)
@@ -2,7 +2,7 @@
 ===================================================================
 --- twisted/web2/dav/method/put_common.py	(revision 0)
 +++ twisted/web2/dav/method/put_common.py	(revision 0)
-@@ -0,0 +1,232 @@
+@@ -0,0 +1,229 @@
 +##
 +# Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved.
 +#
@@ -20,9 +20,6 @@
 +#
 +# DRI: Cyrus Daboo, cdaboo at apple.com
 +##
-+from twisted.internet.defer import waitForDeferred
-+from twisted.internet.defer import deferredGenerator
-+from twisted.web2.http import StatusResponse
 +
 +"""
 +PUT/COPY/MOVE common behavior.
@@ -32,22 +29,21 @@
 +
 +__all__ = ["storeCalendarObjectResource"]
 +
-+from twisted.internet.defer import maybeDeferred
-+from twisted.python import failure
-+from twisted.python import log
++from twisted.internet.defer import deferredGenerator, maybeDeferred, waitForDeferred
++from twisted.python import failure, log
 +from twisted.python.filepath import FilePath
 +from twisted.web2 import responsecode
-+from twisted.web2.dav.fileop import copy
-+from twisted.web2.dav.fileop import delete
-+from twisted.web2.dav.fileop import put
++from twisted.web2.dav.fileop import copy, delete, put
 +from twisted.web2.http import HTTPError
++from twisted.web2.http import StatusResponse
 +from twisted.web2.iweb import IResponse
 +
 +def storeResource(
 +    request,
 +    source=None, source_uri=None,
 +    destination=None, destination_uri=None,
-+    deletesource=False
++    deletesource=False,
++    depth="0"
 +):
 +    """
 +    Function that does common PUT/COPY/MOVE behaviour.
@@ -59,6 +55,7 @@
 +    @param destination:       the L{DAVFile} for the destination resource to copy into.
 +    @param destination_uri:   the URI for the destination resource.
 +    @param deletesource:      True if the source resource is to be deleted on successful completion, False otherwise.
++    @param depth:             a C{str} containing the COPY/MOVE Depth header value.
 +    @return:                  status response.
 +    """
 +    
@@ -74,6 +71,7 @@
 +        log.err("destination=%s\n" % (destination,))
 +        log.err("destination_uri=%s\n" % (destination_uri,))
 +        log.err("deletesource=%s\n" % (deletesource,))
++        log.err("depth=%s\n" % (depth,))
 +        raise
 +
 +    class RollbackState(object):
@@ -188,7 +186,7 @@
 +
 +        # Do put or copy based on whether source exists
 +        if source is not None:
-+            response = maybeDeferred(copy, source.fp, destination.fp, destination_uri, "0")
++            response = maybeDeferred(copy, source.fp, destination.fp, destination_uri, depth)
 +        else:
 +            response = maybeDeferred(put, request.stream, destination.fp)
 +        response = waitForDeferred(response)
@@ -214,12 +212,11 @@
 +            # Delete the source resource
 +            if sourcequota is not None:
 +                delete_size = 0 - old_source_size
-+                source.updateQuotaUse(request, delete_size)
 +                d = waitForDeferred(source.quotaSizeAdjust(request, delete_size))
 +                yield d
 +                d.getResult()
 +
-+            delete(source_uri, source.fp, "0")
++            delete(source_uri, source.fp, depth)
 +            rollback.source_deleted = True
 +
 +        # Can now commit changes and forget the rollback details

Modified: CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.resource.patch
===================================================================
--- CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.resource.patch	2006-09-12 21:18:22 UTC (rev 129)
+++ CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.resource.patch	2006-09-13 21:13:23 UTC (rev 130)
@@ -1,6 +1,6 @@
 Index: twisted/web2/dav/resource.py
 ===================================================================
---- twisted/web2/dav/resource.py	(revision 18074)
+--- twisted/web2/dav/resource.py	(revision 18092)
 +++ twisted/web2/dav/resource.py	(working copy)
 @@ -125,6 +125,8 @@
          (dav_namespace, "acl-restrictions"          ), # RFC 3744, section 5.6
@@ -53,7 +53,7 @@
  
                  # Try to match principals in each principal collection on 
                  # the resource
-@@ -1526,6 +1554,179 @@
+@@ -1526,6 +1554,219 @@
          return None
  
      ##
@@ -128,12 +128,33 @@
 +        @return: a C{int} containing the maximum allowed bytes if this collection
 +            is quota-controlled, or C{None} if not quota controlled.
 +        """
-+        assert self.isCollection(), "Only collections can have a quota root"
 +        if self.hasDeadProperty(TwistedQuotaRootProperty):
 +            return int(str(self.readDeadProperty(TwistedQuotaRootProperty)))
 +        else:
 +            return None
 +    
++    def quotaRootParent(self, request):
++        """
++        Return the next quota root above this resource.
++        
++        @return: L{DAVResource} or C{None}
++        """
++
++        # Check the next parent
++        url = request.urlForResource(self)
++        while (url != "/"):
++            url = parentForURL(url)
++            parent = waitForDeferred(request.locateResource(url))
++            yield parent
++            parent = parent.getResult()
++            if parent.hasDeadProperty(TwistedQuotaRootProperty):
++                yield parent
++                return
++
++        yield None
++    
++    quotaRootParent = deferredGenerator(quotaRootParent)
++        
 +    def setQuotaRoot(self, request, maxsize):
 +        """
 +        @param maxsize: a C{int} containing the maximum allowed bytes for the contents
@@ -146,13 +167,42 @@
 +    
 +    def quotaSize(self, request):
 +        """
-+        Get the size of this resource.
++        Get the size of this resource (if its a collection get total for all children as well).
 +        TODO: Take into account size of dead-properties.
 +
 +        @return: a C{int} containing the size of the resource.
 +        """
 +        unimplemented(self)
 +
++    def checkQuota(self, request, available):
++        """
++        Check to see whether all quota roots have sufficient available bytes.
++        We currently do not use hierarchical quota checks - i.e. only the most
++        immediate quota root parent is checked for quota.
++        
++        @param available: a C{int} containing the additional quota required.
++        @return: C{True} if there is sufficient quota remaining on all quota roots,
++            C{False} otherwise.
++        """
++        
++        quotaroot = self
++        while(quotaroot is not None):
++            # Check quota on this root (if it has one)
++            quota = quotaroot.quotaRoot(request)
++            if quota is not None:
++                if available > quota[0]:
++                    yield False
++                    return
++
++            # Check the next parent with a quota root
++            quotaroot = waitForDeferred(quotaroot.quotaRootParent(request))
++            yield quotaroot
++            quotaroot = quotaroot.getResult()
++
++        yield True
++
++    checkQuota = deferredGenerator(checkQuota)
++
 +    def quotaSizeAdjust(self, request, adjust):
 +        """
 +        Update the quota used value on all quota root parents of this resource.
@@ -196,7 +246,7 @@
 +            return int(str(self.readDeadProperty(TwistedQuotaUsedProperty)))
 +        else:
 +            # Do brute force size determination
-+            result = self.determineActualQuotaUse(request)
++            result = self.quotaSize(request)
 +            
 +            # Cache the brute force value in the private property
 +            self.writeDeadProperty(TwistedQuotaUsedProperty.fromString(str(result)))
@@ -218,22 +268,12 @@
 +        size = self.currentQuotaUse(request)
 +        size += adjust
 +        self.writeDeadProperty(TwistedQuotaUsedProperty.fromString(str(size)))
-+
-+    def determineActualQuotaUse(self, request):
-+        """
-+        Brute force determination of quota used by this collection.
-+
-+        @return: a C{int} containing the current used byte if this collection
-+            is quota-controlled, or C{None} if not quota controlled.
-+        """
-+        assert self.isCollection(), "Only collections can have a quota root"
-+        unimplemented(self)
 +        
 +    ##
      # HTTP
      ##
  
-@@ -1631,6 +1832,28 @@
+@@ -1631,6 +1872,28 @@
  
  davxml.registerElement(TwistedAccessDisabledProperty)
  

Modified: CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.static.patch
===================================================================
--- CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.static.patch	2006-09-12 21:18:22 UTC (rev 129)
+++ CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.static.patch	2006-09-13 21:13:23 UTC (rev 130)
@@ -1,6 +1,6 @@
 Index: twisted/web2/dav/static.py
 ===================================================================
---- twisted/web2/dav/static.py	(revision 18074)
+--- twisted/web2/dav/static.py	(revision 18092)
 +++ twisted/web2/dav/static.py	(working copy)
 @@ -29,6 +29,7 @@
  __all__ = ["DAVFile"]
@@ -19,7 +19,7 @@
  from twisted.web2.dav import davxml
  from twisted.web2.dav.idav import IDAVResource
  from twisted.web2.dav.resource import DAVResource
-@@ -145,6 +148,55 @@
+@@ -145,6 +148,58 @@
          return succeed(DAVFile._supportedPrivilegeSet)
  
      ##
@@ -34,10 +34,13 @@
 +
 +        @return: a C{int} containing the size of the resource.
 +        """
-+        result = os.stat(self.fp.path)
-+        return result[stat.ST_SIZE]
++        if self.isCollection():
++            return self.collectionQuotaUse(request)
++        else:
++            result = os.stat(self.fp.path)
++            return result[stat.ST_SIZE]
 +
-+    def determineActualQuotaUse(self, request):
++    def collectionQuotaUse(self, request):
 +        """
 +        Brute force determination of quota used by this collection.
 +

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20060913/16bf59a4/attachment.html


More information about the calendarserver-changes mailing list