[CalendarServer-changes] [179]
CalendarServer/branches/users/cdaboo/quota
source_changes at macosforge.org
source_changes at macosforge.org
Fri Sep 22 07:25:41 PDT 2006
Revision: 179
http://trac.macosforge.org/projects/calendarserver/changeset/179
Author: cdaboo at apple.com
Date: 2006-09-22 07:25:41 -0700 (Fri, 22 Sep 2006)
Log Message:
-----------
Cleaning-up quota code after review.
Modified Paths:
--------------
CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.idav.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
CalendarServer/branches/users/cdaboo/quota/twistedcaldav/method/put_common.py
CalendarServer/branches/users/cdaboo/quota/twistedcaldav/static.py
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-22 02:49:46 UTC (rev 178)
+++ CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.idav.patch 2006-09-22 14:25:41 UTC (rev 179)
@@ -2,7 +2,7 @@
===================================================================
--- twisted/web2/dav/idav.py (revision 18209)
+++ twisted/web2/dav/idav.py (working copy)
-@@ -180,6 +180,72 @@
+@@ -180,6 +180,80 @@
the specified principal.
"""
@@ -20,6 +20,14 @@
+ C{None} if quota is not defined on the resource.
+ """
+
++ def hasQuota(request):
++ """
++ Check whether this resource is undre 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.
++ """
++
+ def hasQuotaRoot(request):
+ """
+ Determine whether the resource has a quota root.
@@ -49,7 +57,7 @@
+ 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.
++ @return: a L{Deferred} with a C{int} result containing the size of the resource.
+ """
+
+ def currentQuotaUse(request):
@@ -57,8 +65,8 @@
+ Get the cached quota use value, or if not present (or invalid) determine
+ quota use by brute force.
+
-+ @return: a C{int} containing the current used byte if this collection
-+ is quota-controlled, or C{None} if not quota controlled.
++ @return: an L{Deferred} with a C{int} result containing the current used byte count if
++ this collection is quota-controlled, or C{None} if not quota controlled.
+ """
+
+ def updateQuotaUse(request, adjust):
@@ -68,7 +76,7 @@
+
+ @param adjust: a C{int} containing the number of bytes added (positive) or
+ removed (negative) that should be used to adjust the cached total.
-+ @return: a C{int} containing the current used byte if this collection
++ @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.
+ """
+
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-22 02:49:46 UTC (rev 178)
+++ CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.resource.patch 2006-09-22 14:25:41 UTC (rev 179)
@@ -13,20 +13,29 @@
3. Live properties may be acted on specially and are stored in the X{dead
property store}. These are not listed in the L{liveProperties} attribute,
-@@ -129,6 +131,12 @@
+@@ -125,6 +127,8 @@
+ (dav_namespace, "acl-restrictions" ), # RFC 3744, section 5.6
+ (dav_namespace, "inherited-acl-set" ), # RFC 3744, section 5.7
+ (dav_namespace, "principal-collection-set" ), # RFC 3744, section 5.8
++ (dav_namespace, "quota-available-bytes" ), # RFC 4331, section 3
++ (dav_namespace, "quota-used-bytes" ), # RFC 4331, section 4
+
(twisted_dav_namespace, "resource-class"),
)
+@@ -129,6 +133,12 @@
+ (twisted_dav_namespace, "resource-class"),
+ )
+ # These are live (compued) properties that may exist on only certain resources
+ dynamicLiveProperties = (
-+ (dav_namespace, "quota-available-bytes" ), # RFC 4331, section 3
++ (dav_namespace, "quota-available-bytes" ), # RFC 4331, section 3
+ (dav_namespace, "quota-used-bytes" ), # RFC 4331, section 4
+ )
+
def deadProperties(self):
"""
Provides internal access to the WebDAV dead property store. You
-@@ -161,6 +169,20 @@
+@@ -161,6 +171,15 @@
if qname[0] == twisted_private_namespace:
return succeed(False)
@@ -34,20 +43,15 @@
+ if (qname in self.dynamicLiveProperties):
+ namespace, name = qname
+ if namespace == dav_namespace:
-+ if name == "quota-available-bytes":
++ if name in ["quota-available-bytes", "quota-used-bytes"]:
+ d = self.quota(request)
+ d.addCallback(lambda qvalue: qvalue is not None)
+ return d
-+
-+ if name == "quota-used-bytes":
-+ d = self.quota(request)
-+ d.addCallback(lambda qvalue: qvalue is not None)
-+ return d
+
return succeed(qname in self.liveProperties or self.deadProperties().contains(qname))
def readProperty(self, property, request):
-@@ -263,6 +285,32 @@
+@@ -263,6 +282,32 @@
# TODO: Merge change from original patch
lambda: self.safeAccessControlList(request)
)
@@ -80,7 +84,7 @@
if namespace == twisted_dav_namespace:
if name == "resource-class":
-@@ -320,7 +368,8 @@
+@@ -320,7 +365,8 @@
qname = property.qname()
sname = property.sname()
@@ -90,7 +94,7 @@
raise HTTPError(StatusResponse(
responsecode.FORBIDDEN,
"Live property %s cannot be deleted." % (sname,)
-@@ -343,6 +392,14 @@
+@@ -343,6 +389,14 @@
# FIXME: A set would be better here, that that's a python 2.4+ feature.
qnames = list(self.liveProperties)
@@ -105,7 +109,7 @@
for qname in self.deadProperties().list():
if (qname not in qnames) and (qname[0] != twisted_private_namespace):
qnames.append(qname)
-@@ -347,7 +404,9 @@
+@@ -347,7 +401,9 @@
if (qname not in qnames) and (qname[0] != twisted_private_namespace):
qnames.append(qname)
@@ -116,7 +120,7 @@
def listAllprop(self, request):
"""
-@@ -1507,6 +1566,230 @@
+@@ -1507,6 +1563,264 @@
return None
##
@@ -161,7 +165,9 @@
+ if self.isCollection():
+ qroot = self.quotaRoot(request)
+ if qroot is not None:
-+ used = self.currentQuotaUse(request)
++ used = waitForDeferred(self.currentQuotaUse(request))
++ yield used
++ used = used.getResult()
+ available = qroot - used
+ if available < 0:
+ available = 0
@@ -186,6 +192,32 @@
+
+ quota = deferredGenerator(quota)
+
++ def hasQuota(self, request):
++ """
++ Check whether this resource is undre 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):
++ yield True
++
++ # Look at each parent
++ url = request.urlForResource(self)
++ if url != "/":
++ parent = waitForDeferred(request.locateResource(parentForURL(url)))
++ yield parent
++ parent = parent.getResult()
++ d = waitForDeferred(parent.hasQuota(request))
++ yield d
++ yield d.getResult()
++ else:
++ yield False
++
++ hasQuota = deferredGenerator(hasQuota)
++
+ def hasQuotaRoot(self, request):
+ """
+ @return: a C{True} if this resource has quota root, C{False} otherwise.
@@ -282,13 +314,15 @@
+ Update the quota used value on all quota root parents of this resource.
+
+ @param adjust: a C{int} containing the number of bytes added (positive) or
-+ removed (negative) that should be used to adjust the cached total.
++ removed (negative) that should be used to adjust the cached total.
+ """
+
+ # Check this resource first
+ if self.isCollection():
+ if self.hasQuotaRoot(request):
-+ self.updateQuotaUse(request, adjust)
++ d = waitForDeferred(self.updateQuotaUse(request, adjust))
++ yield d
++ d.getResult()
+
+ # Check the next parent
+ url = request.urlForResource(self)
@@ -309,7 +343,7 @@
+ Get the cached quota use value, or if not present (or invalid) determine
+ quota use by brute force.
+
-+ @return: a C{int} containing the current used byte if this collection
++ @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.
+ """
+ assert self.isCollection(), "Only collections can have a quota root"
@@ -317,15 +351,15 @@
+
+ # Try to get the cached value property
+ if self.hasDeadProperty(TwistedQuotaUsedProperty):
-+ return int(str(self.readDeadProperty(TwistedQuotaUsedProperty)))
++ return succeed(int(str(self.readDeadProperty(TwistedQuotaUsedProperty))))
+ else:
-+ # Do brute force size determination
-+ result = self.quotaSize(request)
-+
-+ # Cache the brute force value in the private property
-+ self.writeDeadProperty(TwistedQuotaUsedProperty.fromString(str(result)))
-+
-+ return result
++ # Do brute force size determination and cache the result in the private property
++ def _defer(result):
++ self.writeDeadProperty(TwistedQuotaUsedProperty.fromString(str(result)))
++ return result
++ d = self.quotaSize(request)
++ d.addCallback(_defer)
++ return d
+
+ def updateQuotaUse(self, request, adjust):
+ """
@@ -333,21 +367,25 @@
+
+ @param adjust: a C{int} containing the number of bytes added (positive) or
+ removed (negative) that should be used to adjust the cached total.
-+ @return: a C{int} containing the current used byte if this collection
++ @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.
+ """
+ assert self.isCollection(), "Only collections can have a quota root"
+
+ # Get current value
-+ size = self.currentQuotaUse(request)
-+ size += adjust
-+ self.writeDeadProperty(TwistedQuotaUsedProperty.fromString(str(size)))
++ def _defer(size):
++ size += adjust
++ self.writeDeadProperty(TwistedQuotaUsedProperty.fromString(str(size)))
++
++ d = self.currentQuotaUse(request)
++ d.addCallback(_defer)
++ return d
+
+ ##
# HTTP
##
-@@ -1741,6 +2024,28 @@
+@@ -1741,6 +2055,28 @@
davxml.registerElement(TwistedAccessDisabledProperty)
Modified: CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.static
===================================================================
--- CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.static 2006-09-22 02:49:46 UTC (rev 178)
+++ CalendarServer/branches/users/cdaboo/quota/lib-patches/Twisted/twisted.web2.dav.static 2006-09-22 14:25:41 UTC (rev 179)
@@ -2,7 +2,7 @@
===================================================================
--- twisted/web2/dav/static.py (revision 18209)
+++ twisted/web2/dav/static.py (working copy)
-@@ -98,6 +98,57 @@
+@@ -98,6 +98,61 @@
return succeed(davPrivilegeSet)
##
@@ -15,18 +15,18 @@
+ TODO: Take into account size of dead-properties. Does stat
+ include xattrs size?
+
-+ @return: a C{int} containing the size of the resource.
++ @return: an L{Deferred} with a C{int} result containing the size of the resource.
+ """
+ if self.isCollection():
+ return self.collectionQuotaUse(request)
+ else:
-+ return self.fp.getsize()
++ return succeed(self.fp.getsize())
+
+ def collectionQuotaUse(self, request):
+ """
+ Brute force determination of quota used by this collection.
+
-+ @return: a C{int} containing the current used byte if this collection
++ @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.
+ """
+ assert self.isCollection(), "Only collections can have a quota root"
@@ -44,7 +44,9 @@
+ child = top.child(f)
+ if child.isdir():
+ # It's a directory, recurse into it
-+ total += walktree(child)
++ result = waitForDeferred(walktree(child))
++ yield result
++ total += result.getResult()
+ elif child.isfile():
+ # It's a file, call the callback function
+ total += child.getsize()
@@ -52,8 +54,10 @@
+ # Unknown file type, print a message
+ pass
+
-+ return total
++ yield total
+
++ walktree = deferredGenerator(walktree)
++
+ return walktree(self.fp)
+
+ ##
Modified: CalendarServer/branches/users/cdaboo/quota/twistedcaldav/method/put_common.py
===================================================================
--- CalendarServer/branches/users/cdaboo/quota/twistedcaldav/method/put_common.py 2006-09-22 02:49:46 UTC (rev 178)
+++ CalendarServer/branches/users/cdaboo/quota/twistedcaldav/method/put_common.py 2006-09-22 14:25:41 UTC (rev 179)
@@ -384,7 +384,9 @@
yield destquota
destquota = destquota.getResult()
if destquota is not None and destination.exists():
- old_dest_size = destination.quotaSize(request)
+ old_dest_size = waitForDeferred(destination.quotaSize(request))
+ yield old_dest_size
+ old_dest_size = old_dest_size.getResult()
else:
old_dest_size = 0
@@ -393,7 +395,9 @@
yield sourcequota
sourcequota = sourcequota.getResult()
if sourcequota is not None and source.exists():
- old_source_size = source.quotaSize(request)
+ old_source_size = waitForDeferred(source.quotaSize(request))
+ yield old_source_size
+ old_source_size = old_source_size.getResult()
else:
old_source_size = 0
else:
@@ -531,7 +535,9 @@
# Do quota check on destination
if destquota is not None:
# Get size of new/old resources
- new_dest_size = destination.quotaSize(request)
+ new_dest_size = waitForDeferred(destination.quotaSize(request))
+ yield new_dest_size
+ new_dest_size = new_dest_size.getResult()
diff_size = new_dest_size - old_dest_size
if diff_size >= destquota[0]:
log.err("Over quota: available %d, need %d" % (destquota[0], diff_size))
Modified: CalendarServer/branches/users/cdaboo/quota/twistedcaldav/static.py
===================================================================
--- CalendarServer/branches/users/cdaboo/quota/twistedcaldav/static.py 2006-09-22 02:49:46 UTC (rev 178)
+++ CalendarServer/branches/users/cdaboo/quota/twistedcaldav/static.py 2006-09-22 14:25:41 UTC (rev 179)
@@ -309,47 +309,51 @@
# Quota
##
- def collectionQuotaUse(self, request):
+ def quotaSize(self, request):
"""
- Brute force determination of quota used by this collection.
+ Get the size of this resource.
+ TODO: Take into account size of dead-properties. Does stat
+ include xattrs size?
- @return: a C{int} containing the current used byte if this collection
- is quota-controlled, or C{None} if not quota controlled.
+ @return: an L{Deferred} with a C{int} result containing the size of the resource.
"""
- assert self.isCollection(), "Only collections can have a quota root"
-
- # Do default if not a calendar collection
- if not self.isPseudoCalendarCollection():
- return super(CalDAVFile, self).collectionQuotaUse(request)
-
- def walktree(top, top_level = False):
- """
- Recursively descend the directory tree rooted at top,
- calling the callback function for each regular file
- """
-
- total = 0
- for f in top.listdir():
+ if self.isCollection():
+ def walktree(top, top_level = False):
+ """
+ Recursively descend the directory tree rooted at top,
+ calling the callback function for each regular file
- # Ignore the database
- if top_level and f == db_basename:
- continue
+ @param top: L{FilePath} for the directory to walk.
+ """
+
+ total = 0
+ for f in top.listdir():
+
+ # Ignore the database
+ if top_level and f == db_basename:
+ continue
+
+ child = top.child(f)
+ if child.isdir():
+ # It's a directory, recurse into it
+ result = waitForDeferred(walktree(child))
+ yield result
+ total += result.getResult()
+ elif child.isfile():
+ # It's a file, call the callback function
+ total += child.getsize()
+ else:
+ # Unknown file type, print a message
+ pass
+
+ yield total
+
+ walktree = deferredGenerator(walktree)
+
+ return walktree(self.fp, True)
+ else:
+ return succeed(self.fp.getsize())
- child = top.child(f)
- if child.isdir():
- # It's a directory, recurse into it
- total += walktree(child)
- elif child.isfile():
- # It's a file, call the callback function
- total += child.getsize()
- else:
- # Unknown file type, print a message
- pass
-
- return total
-
- return walktree(self.fp, True)
-
##
# Utilities
##
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20060922/9cde76c8/attachment.html
More information about the calendarserver-changes
mailing list