[CalendarServer-changes] [4644] CalendarServer/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Tue Oct 27 12:16:28 PDT 2009
Revision: 4644
http://trac.macosforge.org/projects/calendarserver/changeset/4644
Author: cdaboo at apple.com
Date: 2009-10-27 12:16:27 -0700 (Tue, 27 Oct 2009)
Log Message:
-----------
Merge deployment changes that reduce file system calls for PROPFINDs (and some other ops). Also adds
some more extended logging.
Modified Paths:
--------------
CalendarServer/trunk/lib-patches/Twisted/twisted.web2.server.patch
CalendarServer/trunk/twistedcaldav/cache.py
CalendarServer/trunk/twistedcaldav/directory/principal.py
CalendarServer/trunk/twistedcaldav/directory/resource.py
CalendarServer/trunk/twistedcaldav/directory/test/test_proxyprincipalmembers.py
CalendarServer/trunk/twistedcaldav/directory/util.py
CalendarServer/trunk/twistedcaldav/method/put.py
CalendarServer/trunk/twistedcaldav/scheduling/caldav.py
CalendarServer/trunk/twistedcaldav/scheduling/implicit.py
CalendarServer/trunk/twistedcaldav/scheduling/scheduler.py
CalendarServer/trunk/twistedcaldav/static.py
Added Paths:
-----------
CalendarServer/trunk/lib-patches/Twisted/twisted.python.filepath.patch
CalendarServer/trunk/lib-patches/Twisted/twisted.web2.dav.fileop.patch
CalendarServer/trunk/lib-patches/Twisted/twisted.web2.static.patch
Added: CalendarServer/trunk/lib-patches/Twisted/twisted.python.filepath.patch
===================================================================
--- CalendarServer/trunk/lib-patches/Twisted/twisted.python.filepath.patch (rev 0)
+++ CalendarServer/trunk/lib-patches/Twisted/twisted.python.filepath.patch 2009-10-27 19:16:27 UTC (rev 4644)
@@ -0,0 +1,91 @@
+Index: twisted/python/filepath.py
+===================================================================
+--- twisted/python/filepath.py (revision 26969)
++++ twisted/python/filepath.py (working copy)
+@@ -326,9 +326,11 @@
+ statinfo = None
+ path = None
+
+- def __init__(self, path, alwaysCreate=False):
++ def __init__(self, path, alwaysCreate=False, existsCached=None, isDirCached=None):
+ self.path = abspath(path)
+ self.alwaysCreate = alwaysCreate
++ self.existsCached = existsCached
++ self.isDirCached = isDirCached
+
+ def __getstate__(self):
+ d = self.__dict__.copy()
+@@ -449,6 +451,11 @@
+
+ # stat methods below
+
++ def changed(self):
++ self.statinfo = None
++ self.existsCached = None
++ self.isDirCached = None
++
+ def restat(self, reraise=True):
+ """
+ Re-calculate cached effects of 'stat'. To refresh information on this path
+@@ -460,12 +467,23 @@
+ """
+ try:
+ self.statinfo = stat(self.path)
++ self.existsCached = True
++ self.isDirCached = S_ISDIR(self.statinfo.st_mode)
+ except OSError:
+ self.statinfo = 0
++ self.existsCached = False
++ self.isDirCached = None
+ if reraise:
+ raise
+
++ def getstatinfo(self):
++ st = self.statinfo
++ if not st:
++ self.restat()
++ st = self.statinfo
++ return st
+
++
+ def chmod(self, mode):
+ """
+ Changes the permissions on self, if possible. Propagates errors from
+@@ -536,7 +554,9 @@
+ C{False} in the other cases.
+ @rtype: C{bool}
+ """
+- if self.statinfo:
++ if self.existsCached is not None:
++ return self.existsCached
++ elif self.statinfo:
+ return True
+ else:
+ self.restat(False)
+@@ -547,6 +567,8 @@
+
+
+ def isdir(self):
++ if self.isDirCached is not None:
++ return self.isDirCached
+ st = self.statinfo
+ if not st:
+ self.restat(False)
+@@ -603,7 +625,7 @@
+ os.rmdir(self.path)
+ else:
+ os.remove(self.path)
+- self.restat(False)
++ self.changed()
+
+
+ def makedirs(self):
+@@ -770,7 +792,7 @@
+ """
+ try:
+ os.rename(self.path, destination.path)
+- self.restat(False)
++ self.changed()
+ except OSError, ose:
+ if ose.errno == errno.EXDEV:
+ # man 2 rename, ubuntu linux 5.10 "breezy":
Added: CalendarServer/trunk/lib-patches/Twisted/twisted.web2.dav.fileop.patch
===================================================================
--- CalendarServer/trunk/lib-patches/Twisted/twisted.web2.dav.fileop.patch (rev 0)
+++ CalendarServer/trunk/lib-patches/Twisted/twisted.web2.dav.fileop.patch 2009-10-27 19:16:27 UTC (rev 4644)
@@ -0,0 +1,48 @@
+Index: twisted/web2/dav/fileop.py
+===================================================================
+--- twisted/web2/dav/fileop.py (revision 26969)
++++ twisted/web2/dav/fileop.py (working copy)
+@@ -162,8 +162,8 @@
+
+ response = responsecode.NO_CONTENT
+
+- # Restat filepath since we deleted the backing file
+- filepath.restat(False)
++ # Remove stat info for filepath since we deleted the backing file
++ filepath.changed()
+
+ return succeed(response)
+
+@@ -371,8 +371,8 @@
+ except OSError:
+ pass
+ else:
+- # Restat source filepath since we moved it
+- source_filepath.restat(False)
++ # Remove stat info from source filepath since we moved it
++ source_filepath.changed()
+ yield success_code
+ return
+
+@@ -462,8 +462,8 @@
+ "writing to file: %s" % (filepath.path,)
+ ))
+
+- # Restat filepath since we modified the backing file
+- filepath.restat(False)
++ # Remove stat info from filepath since we modified the backing file
++ filepath.changed()
+ yield success_code
+
+ put = deferredGenerator(put)
+@@ -480,8 +480,8 @@
+ """
+ try:
+ os.mkdir(filepath.path)
+- # Restat filepath because we modified it
+- filepath.restat(False)
++ # Remove stat info from filepath because we modified it
++ filepath.changed()
+ except:
+ raise HTTPError(statusForFailure(
+ Failure(),
Modified: CalendarServer/trunk/lib-patches/Twisted/twisted.web2.server.patch
===================================================================
--- CalendarServer/trunk/lib-patches/Twisted/twisted.web2.server.patch 2009-10-27 19:11:38 UTC (rev 4643)
+++ CalendarServer/trunk/lib-patches/Twisted/twisted.web2.server.patch 2009-10-27 19:16:27 UTC (rev 4644)
@@ -28,3 +28,50 @@
# This is where CONNECT would go if we wanted it
return None
+@@ -386,6 +396,15 @@
+ # We found a Resource... update the request.prepath and postpath
+ for x in xrange(len(path) - len(newpath)):
+ self.prepath.append(self.postpath.pop(0))
++ url = quote("/" + "/".join(self.prepath) + ("/" if self.prepath and self.prepath[-1] else ""))
++ self._rememberResource(newres, url)
++ else:
++ try:
++ previousURL = self.urlForResource(res)
++ url = quote(previousURL + path[0] + ("/" if path[0] and len(path) > 1 else ""))
++ self._rememberResource(newres, url)
++ except NoURLForResourceError:
++ pass
+
+ child = self._getChild(None, newres, newpath, updatepaths=updatepaths)
+
+@@ -467,13 +486,29 @@
+ segments = unquote(path).split("/")
+ assert segments[0] == "", "URL path didn't begin with '/': %s" % (path,)
+
++ # Walk the segments up to see if we can find a cached resource to start from
++ preSegments = segments[:-1]
++ postSegments = segments[-1:]
++ cachedParent = None
++ while(len(preSegments)):
++ parentPath = "/".join(preSegments) + "/"
++ cachedParent = self._resourcesByURL.get(parentPath, None)
++ if cachedParent is not None:
++ break
++ else:
++ postSegments.insert(0, preSegments.pop())
++
++ if cachedParent is None:
++ cachedParent = self.site.resource
++ postSegments = segments[1:]
++
+ def notFound(f):
+ f.trap(http.HTTPError)
+ if f.value.response.code != responsecode.NOT_FOUND:
+ return f
+ return None
+
+- d = defer.maybeDeferred(self._getChild, None, self.site.resource, segments[1:], updatepaths=False)
++ d = defer.maybeDeferred(self._getChild, None, cachedParent, postSegments, updatepaths=False)
+ d.addCallback(self._rememberResource, path)
+ d.addErrback(notFound)
+ return d
Added: CalendarServer/trunk/lib-patches/Twisted/twisted.web2.static.patch
===================================================================
--- CalendarServer/trunk/lib-patches/Twisted/twisted.web2.static.patch (rev 0)
+++ CalendarServer/trunk/lib-patches/Twisted/twisted.web2.static.patch 2009-10-27 19:16:27 UTC (rev 4644)
@@ -0,0 +1,56 @@
+Index: twisted/web2/static.py
+===================================================================
+--- twisted/web2/static.py (revision 26969)
++++ twisted/web2/static.py (working copy)
+@@ -213,13 +213,20 @@
+ if indexNames is not None:
+ self.indexNames = indexNames
+
++ def comparePath(self, path):
++
++ if isinstance(path, filepath.FilePath):
++ return path.path == self.fp.path
++ else:
++ return path == self.fp.path
++
+ def exists(self):
+ return self.fp.exists()
+
+ def etag(self):
+ if not self.fp.exists(): return None
+
+- st = self.fp.statinfo
++ st = self.fp.getstatinfo()
+
+ #
+ # Mark ETag as weak if it was modified more recently than we can
+@@ -317,8 +324,11 @@
+ if child: return child
+
+ child_fp = self.fp.child(name)
++ if hasattr(self, "knownChildren"):
++ if name in self.knownChildren:
++ child_fp.existsCached = True
+ if child_fp.exists():
+- return self.createSimilarFile(child_fp.path)
++ return self.createSimilarFile(child_fp)
+ else:
+ return None
+
+@@ -329,6 +339,7 @@
+ children = self.putChildren.keys()
+ if self.fp.isdir():
+ children += [c for c in self.fp.listdir() if c not in children]
++ self.knownChildren = set(children)
+ return children
+
+ def locateChild(self, req, segments):
+@@ -371,7 +382,7 @@
+ return self.createSimilarFile(fpath.path), segments[1:]
+
+ def renderHTTP(self, req):
+- self.fp.restat(False)
++ self.fp.changed()
+ return super(File, self).renderHTTP(req)
+
+ def render(self, req):
Modified: CalendarServer/trunk/twistedcaldav/cache.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/cache.py 2009-10-27 19:11:38 UTC (rev 4643)
+++ CalendarServer/trunk/twistedcaldav/cache.py 2009-10-27 19:16:27 UTC (rev 4644)
@@ -319,6 +319,9 @@
self._response = response
def renderHTTP(self, request):
+ if not hasattr(request, "extendedLogItems"):
+ request.extendedLogItems = {}
+ request.extendedLogItems["cached"] = "1"
return self._response
def locateChild(self, request, segments):
Modified: CalendarServer/trunk/twistedcaldav/directory/principal.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/principal.py 2009-10-27 19:11:38 UTC (rev 4643)
+++ CalendarServer/trunk/twistedcaldav/directory/principal.py 2009-10-27 19:16:27 UTC (rev 4644)
@@ -888,11 +888,8 @@
return succeed(inbox)
def calendarHomeURLs(self):
- home = self.calendarHome()
- if home is None:
- return ()
- else:
- return (home.url(),)
+ homeURL = self._homeChildURL(None)
+ return (homeURL,) if homeURL else ()
def scheduleInboxURL(self):
return self._homeChildURL("inbox/")
@@ -907,11 +904,19 @@
return None
def _homeChildURL(self, name):
- home = self.calendarHome()
- if home is None:
+ if not hasattr(self, "calendarHomeURL"):
+ home = self.calendarHome()
+ if home is None:
+ self.calendarHomeURL = None
+ return None
+ else:
+ self.calendarHomeURL = home.url()
+
+ url = self.calendarHomeURL
+ if url is None:
return None
else:
- return joinURL(home.url(), name)
+ return joinURL(url, name) if name else url
def calendarHome(self):
# FIXME: self.record.service.calendarHomesCollection smells like a hack
Modified: CalendarServer/trunk/twistedcaldav/directory/resource.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/resource.py 2009-10-27 19:11:38 UTC (rev 4643)
+++ CalendarServer/trunk/twistedcaldav/directory/resource.py 2009-10-27 19:16:27 UTC (rev 4644)
@@ -20,7 +20,7 @@
__all__ = ["AutoProvisioningResourceMixIn"]
-from twisted.internet.defer import maybeDeferred
+from twisted.internet.defer import maybeDeferred, inlineCallbacks, returnValue
class AutoProvisioningResourceMixIn (object):
"""
@@ -50,16 +50,19 @@
"""
return None
+ @inlineCallbacks
def locateChild(self, request, segments):
"""
This implementation calls L{provision}, then super's L{locateChild}, thereby
ensuring that looked-up resources are provisioned.
"""
- d = maybeDeferred(self.provision)
+ yield maybeDeferred(self.provision)
name = segments[0]
if name != "":
- d.addCallback(lambda _: self.provisionChild(name))
-
- d.addCallback(lambda _: super(AutoProvisioningResourceMixIn, self).locateChild(request, segments))
- return d
+ child = self.provisionChild(name)
+ if child:
+ returnValue((child, segments[1:],))
+
+ result = (yield super(AutoProvisioningResourceMixIn, self).locateChild(request, segments))
+ returnValue(result)
Modified: CalendarServer/trunk/twistedcaldav/directory/test/test_proxyprincipalmembers.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/test_proxyprincipalmembers.py 2009-10-27 19:11:38 UTC (rev 4643)
+++ CalendarServer/trunk/twistedcaldav/directory/test/test_proxyprincipalmembers.py 2009-10-27 19:16:27 UTC (rev 4644)
@@ -91,7 +91,7 @@
proxyPrincipal = self._getPrincipalByShortName(proxyPrincipal[0], proxyPrincipal[1])
members.add(proxyPrincipal)
- principal.setGroupMemberSetPrincipals(members)
+ yield principal.setGroupMemberSetPrincipals(members)
@inlineCallbacks
def _removeProxy(self, recordType, recordName, subPrincipalName, proxyRecordType, proxyRecordName):
@@ -106,14 +106,14 @@
members.remove(p)
break
- principal.setGroupMemberSetPrincipals(members)
+ yield principal.setGroupMemberSetPrincipals(members)
def _clearProxy(self, principal, subPrincipalName):
if isinstance(principal, tuple):
principal = self._getPrincipalByShortName(principal[0], principal[1])
principal = principal.getChild(subPrincipalName)
- principal.setGroupMemberSetPrincipals(set())
+ yield principal.setGroupMemberSetPrincipals(set())
@inlineCallbacks
def _proxyForTest(self, recordType, recordName, expectedProxies, read_write):
@@ -483,7 +483,7 @@
delRec = self.directoryService.recordWithShortName(
DirectoryService.recordType_users, "dreid")
for cache in self.directoryService._recordCaches.itervalues():
- cache.removeRecord(delRec)
+ cache.removeRecord(delRec)
del self.directoryService._accounts()[
DirectoryService.recordType_users]["dreid"]
Modified: CalendarServer/trunk/twistedcaldav/directory/util.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/util.py 2009-10-27 19:11:38 UTC (rev 4643)
+++ CalendarServer/trunk/twistedcaldav/directory/util.py 2009-10-27 19:16:27 UTC (rev 4644)
@@ -104,6 +104,9 @@
def dirname(self):
return ""
+ def changed(self):
+ pass
+
def restat(self, reraise=True):
pass
Modified: CalendarServer/trunk/twistedcaldav/method/put.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/method/put.py 2009-10-27 19:11:38 UTC (rev 4643)
+++ CalendarServer/trunk/twistedcaldav/method/put.py 2009-10-27 19:16:27 UTC (rev 4644)
@@ -40,7 +40,6 @@
parent = (yield request.locateResource(parentURL))
if isPseudoCalendarCollectionResource(parent):
- self.fp.restat(False)
# Content-type check
content_type = request.headers.getHeader("content-type")
@@ -51,6 +50,9 @@
# Read the calendar component from the stream
try:
calendardata = (yield allDataFromStream(request.stream))
+ if not hasattr(request, "extendedLogItems"):
+ request.extendedLogItems = {}
+ request.extendedLogItems["cl"] = str(len(calendardata))
# We must have some data at this point
if calendardata is None:
@@ -74,4 +76,12 @@
else:
result = (yield super(CalDAVFile, self).http_PUT(request))
+
+ if not hasattr(request, "extendedLogItems"):
+ request.extendedLogItems = {}
+ clength = request.headers.getHeader("content-length", 0)
+ if clength == 0:
+ clength = self.fp.getsize()
+ request.extendedLogItems["cl"] = str(clength)
+
returnValue(result)
Modified: CalendarServer/trunk/twistedcaldav/scheduling/caldav.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/scheduling/caldav.py 2009-10-27 19:11:38 UTC (rev 4643)
+++ CalendarServer/trunk/twistedcaldav/scheduling/caldav.py 2009-10-27 19:16:27 UTC (rev 4644)
@@ -96,14 +96,18 @@
organizerProp = self.scheduler.calendar.getOrganizerProperty()
uid = self.scheduler.calendar.resourceUID()
+ organizerPrincipal = None
+ if type(self.scheduler.organizer) in (LocalCalendarUser,):
+ organizerPrincipal = davxml.Principal(davxml.HRef(self.scheduler.organizer.principal.principalURL()))
+
for recipient in self.recipients:
#
# Check access controls
#
- if isinstance(self.scheduler.organizer, LocalCalendarUser):
+ if organizerPrincipal:
try:
- yield recipient.inbox.checkPrivileges(self.scheduler.request, (caldavxml.ScheduleDeliver(),), principal=davxml.Principal(davxml.HRef(self.scheduler.organizer.principal.principalURL())))
+ yield recipient.inbox.checkPrivileges(self.scheduler.request, (caldavxml.ScheduleDeliver(),), principal=organizerPrincipal)
except AccessDeniedError:
log.err("Could not access Inbox for recipient: %s" % (recipient.cuaddr,))
err = HTTPError(ErrorResponse(responsecode.NOT_FOUND, (caldav_namespace, "recipient-permissions")))
@@ -127,8 +131,7 @@
@inlineCallbacks
def generateResponse(self, recipient, responses):
# Hash the iCalendar data for use as the last path element of the URI path
- calendar_str = str(self.scheduler.calendar)
- name = md5(calendar_str + str(time.time()) + recipient.inbox.fp.path).hexdigest() + ".ics"
+ name = md5(self.scheduler.calendardata + str(time.time()) + recipient.inbox.fp.path).hexdigest() + ".ics"
# Get a resource for the new item
childURL = joinURL(recipient.inboxURL, name)
@@ -137,7 +140,7 @@
# Do implicit scheduling message processing.
try:
processor = ImplicitProcessor()
- processed, autoprocessed, changes = (yield processor.doImplicitProcessing(
+ _ignore_processed, autoprocessed, changes = (yield processor.doImplicitProcessing(
self.scheduler.request,
self.scheduler.calendar,
self.scheduler.originator,
@@ -152,6 +155,9 @@
if autoprocessed:
# No need to write the inbox item as it has already been auto-processed
responses.add(recipient.cuaddr, responsecode.OK, reqstatus=iTIPRequestStatus.MESSAGE_DELIVERED)
+ if not hasattr(self.scheduler.request, "extendedLogItems"):
+ self.scheduler.request.extendedLogItems = {}
+ self.scheduler.request.extendedLogItems["itip.auto"] = self.scheduler.request.extendedLogItems.get("itip.auto", 0) + 1
returnValue(True)
else:
# Copy calendar to inbox
@@ -255,7 +261,7 @@
excludeuid = self.scheduler.excludeUID,
organizer = self.scheduler.organizer.cuaddr,
same_calendar_user = same_calendar_user,
- servertoserver=remote
+ servertoserver=remote,
))
# Build VFREEBUSY iTIP reply for this recipient
Modified: CalendarServer/trunk/twistedcaldav/scheduling/implicit.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/scheduling/implicit.py 2009-10-27 19:11:38 UTC (rev 4643)
+++ CalendarServer/trunk/twistedcaldav/scheduling/implicit.py 2009-10-27 19:16:27 UTC (rev 4644)
@@ -36,6 +36,7 @@
from twistedcaldav.scheduling.itip import iTipGenerator
from twistedcaldav.scheduling.scheduler import CalDAVScheduler
from twistedcaldav.scheduling.utils import getCalendarObjectForPrincipals
+from twistedcaldav.directory.principal import DirectoryCalendarPrincipalResource
__all__ = [
"ImplicitScheduler",
@@ -328,6 +329,10 @@
originatorPrincipalURL = str(authz_principal)
if originatorPrincipalURL:
self.originatorPrincipal = (yield self.request.locateResource(originatorPrincipalURL))
+ if not isinstance(self.originatorPrincipal, DirectoryCalendarPrincipalResource):
+ log.error("Originator '%s' is not enabled for calendaring" % (originatorPrincipalURL,))
+ raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (caldav_namespace, "invalid-originator")))
+
if self.originatorPrincipal:
# Pick the first mailto cu address or the first other type
for item in self.originatorPrincipal.calendarUserAddresses():
Modified: CalendarServer/trunk/twistedcaldav/scheduling/scheduler.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/scheduling/scheduler.py 2009-10-27 19:11:38 UTC (rev 4643)
+++ CalendarServer/trunk/twistedcaldav/scheduling/scheduler.py 2009-10-27 19:16:27 UTC (rev 4644)
@@ -95,6 +95,7 @@
if not hasattr(self.request, "extendedLogItems"):
self.request.extendedLogItems = {}
self.request.extendedLogItems["recipients"] = len(self.recipients)
+ self.request.extendedLogItems["cl"] = str(len(self.calendardata))
# Do some extra authorization checks
self.checkAuthorization()
@@ -113,6 +114,7 @@
self.originator = originator
self.recipients = recipients
self.calendar = calendar
+ self.calendardata = str(self.calendar)
self.internal_request = internal_request
# Do some extra authorization checks
@@ -233,6 +235,7 @@
# Parse the calendar object from the HTTP request stream
try:
self.calendar = (yield Component.fromIStream(self.request.stream))
+ self.calendardata = str(self.calendar)
except:
# FIXME: Bare except
log.err("Error while handling %s: %s" % (self.method, Failure(),))
@@ -330,7 +333,7 @@
str("".join([" %s\n" % (recipient,) for recipient in self.recipients])),
str(self.request.serverInstance),
str(self.method),
- str(self.calendar)
+ self.calendardata,
)
)
Modified: CalendarServer/trunk/twistedcaldav/static.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/static.py 2009-10-27 19:11:38 UTC (rev 4643)
+++ CalendarServer/trunk/twistedcaldav/static.py 2009-10-27 19:16:27 UTC (rev 4644)
@@ -43,6 +43,7 @@
from twisted.internet.defer import fail, succeed, inlineCallbacks, returnValue, maybeDeferred
from twisted.python.failure import Failure
+from twisted.python.filepath import FilePath
from twisted.web2 import responsecode, http, http_headers
from twisted.web2.http import HTTPError, StatusResponse
from twisted.web2.dav import davxml
@@ -388,12 +389,19 @@
return self._propertyCollection
def createSimilarFile(self, path):
- if path == self.fp.path:
+ if self.comparePath(path):
return self
similar = super(CalDAVFile, self).createSimilarFile(path)
if isCalendarCollectionResource(self):
+
+ # Short-circuit stat with information we know to be true at this point
+ if isinstance(path, FilePath) and hasattr(self, "knownChildren"):
+ if os.path.basename(path.path) in self.knownChildren:
+ path.existsCached = True
+ path.isDirCached = False
+
#
# Override the dead property store
#
@@ -564,6 +572,13 @@
else:
self._provisioned_file = True
+ # If the file already exists we can just exit here - there is no need to go further
+ if self.fp.exists():
+ return False
+
+ # At this point the original FilePath did not indicate an existing file, but we should
+ # recheck it to see if some other request sneaked in and already created/provisioned it
+
fp = self.fp
fp.restat(False)
@@ -588,10 +603,10 @@
# Check our status again, and re-raise if we're not a collection.
if not self.isCollection():
raise
- fp.restat(False)
+ fp.changed()
else:
fp.open("w").close()
- fp.restat(False)
+ fp.changed()
return True
@@ -678,7 +693,7 @@
responsecode.INTERNAL_SERVER_ERROR,
"Unable to move calendar home."
))
- child.fp.restat(False)
+ child.fp.changed()
break
else:
#
@@ -754,7 +769,7 @@
return self.createSimilarFile(self.fp.child(name).path)
def createSimilarFile(self, path):
- if path == self.fp.path:
+ if self.comparePath(path):
return self
else:
similar = CalDAVFile(path, principalCollections=self.principalCollections())
@@ -831,7 +846,7 @@
return True
def createSimilarFile(self, path):
- if path == self.fp.path:
+ if self.comparePath(path):
return self
else:
return CalDAVFile(path, principalCollections=self.principalCollections())
@@ -927,7 +942,7 @@
return False
def createSimilarFile(self, path):
- if path == self.fp.path:
+ if self.comparePath(path):
return self
else:
return responsecode.NOT_FOUND
@@ -979,7 +994,7 @@
return False
def createSimilarFile(self, path):
- if path == self.fp.path:
+ if self.comparePath(path):
return self
else:
return responsecode.NOT_FOUND
@@ -1010,7 +1025,7 @@
self.parent = parent
def createSimilarFile(self, path):
- if path == self.fp.path:
+ if self.comparePath(path):
return self
else:
return DropBoxCollectionFile(path, self)
@@ -1024,7 +1039,7 @@
CalDAVFile.__init__(self, path, principalCollections=parent.principalCollections())
def createSimilarFile(self, path):
- if path == self.fp.path:
+ if self.comparePath(path):
return self
else:
return DropBoxChildFile(path, self)
@@ -1039,7 +1054,7 @@
assert self.fp.isfile() or not self.fp.exists()
def createSimilarFile(self, path):
- if path == self.fp.path:
+ if self.comparePath(path):
return self
else:
return responsecode.NOT_FOUND
@@ -1052,7 +1067,7 @@
assert self.fp.isfile() or not self.fp.exists()
def createSimilarFile(self, path):
- if path == self.fp.path:
+ if self.comparePath(path):
return self
else:
return responsecode.NOT_FOUND
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20091027/01d07167/attachment-0001.html>
More information about the calendarserver-changes
mailing list