Revision: 3588 http://trac.macosforge.org/projects/calendarserver/changeset/3588 Author: cdaboo@apple.com Date: 2009-01-12 12:01:27 -0800 (Mon, 12 Jan 2009) Log Message: ----------- Make sure an iTIP implicit CANCEL of an attendee's event properly updates the quota for the attendee's calendar. Modified Paths: -------------- CalendarServer/trunk/twistedcaldav/method/delete.py CalendarServer/trunk/twistedcaldav/method/delete_common.py CalendarServer/trunk/twistedcaldav/scheduling/processing.py Modified: CalendarServer/trunk/twistedcaldav/method/delete.py =================================================================== --- CalendarServer/trunk/twistedcaldav/method/delete.py 2009-01-12 19:58:28 UTC (rev 3587) +++ CalendarServer/trunk/twistedcaldav/method/delete.py 2009-01-12 20:01:27 UTC (rev 3588) @@ -1,5 +1,5 @@ ## -# Copyright (c) 2006-2008 Apple Inc. All rights reserved. +# Copyright (c) 2006-2009 Apple Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -53,7 +53,7 @@ yield parent.authorize(request, (davxml.Unbind(),)) # Do smart delete taking into account the need to do implicit CANCELs etc - deleter = DeleteResource(request, self, parent, depth) + deleter = DeleteResource(request, self, request.uri, parent, depth) response = (yield deleter.run()) returnValue(response) Modified: CalendarServer/trunk/twistedcaldav/method/delete_common.py =================================================================== --- CalendarServer/trunk/twistedcaldav/method/delete_common.py 2009-01-12 19:58:28 UTC (rev 3587) +++ CalendarServer/trunk/twistedcaldav/method/delete_common.py 2009-01-12 20:01:27 UTC (rev 3588) @@ -1,5 +1,5 @@ ## -# Copyright (c) 2006-2008 Apple Inc. All rights reserved. +# Copyright (c) 2006-2009 Apple Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -39,12 +39,14 @@ class DeleteResource(object): - def __init__(self, request, resource, parent, depth): + def __init__(self, request, resource, resource_uri, parent, depth, internal_request=False): self.request = request self.resource = resource + self.resource_uri = resource_uri self.parent = parent self.depth = depth + self.internal_request = internal_request @inlineCallbacks def deleteResource(self, delresource, deluri, parent): @@ -107,15 +109,15 @@ else: old_size = 0 - # Get data we need for implicit scheduling - calendar = delresource.iCalendar() - scheduler = ImplicitScheduler() - do_implicit_action, _ignore = (yield scheduler.testImplicitSchedulingDELETE(self.request, delresource, calendar)) - if do_implicit_action: - lock = MemcacheLock("ImplicitUIDLock", calendar.resourceUID(), timeout=60.0) - else: - scheduler = None - lock = None + scheduler = None + lock = None + if not self.internal_request: + # Get data we need for implicit scheduling + calendar = delresource.iCalendar() + scheduler = ImplicitScheduler() + do_implicit_action, _ignore = (yield scheduler.testImplicitSchedulingDELETE(self.request, delresource, calendar)) + if do_implicit_action: + lock = MemcacheLock("ImplicitUIDLock", calendar.resourceUID(), timeout=60.0) try: if lock: @@ -205,7 +207,7 @@ log.debug("Deleting collection %s" % (self.resource.fp.path,)) - errors = ResponseQueue(self.request.uri, "DELETE", responsecode.NO_CONTENT) + errors = ResponseQueue(self.resource_uri, "DELETE", responsecode.NO_CONTENT) @inlineCallbacks def doDeleteCalendar(delresource, deluri): @@ -220,10 +222,10 @@ returnValue(True) - yield applyToCalendarCollections(self.resource, self.request, self.request.uri, self.depth, doDeleteCalendar, None) + yield applyToCalendarCollections(self.resource, self.request, self.resource_uri, self.depth, doDeleteCalendar, None) # Now do normal delete - more_responses = (yield self.deleteResource(self.resource, self.request.uri, self.parent)) + more_responses = (yield self.deleteResource(self.resource, self.resource_uri, self.parent)) if isinstance(more_responses, MultiStatusResponse): # Merge errors @@ -237,15 +239,15 @@ def run(self): if isCalendarCollectionResource(self.parent): - response = (yield self.deleteCalendarResource(self.resource, self.request.uri, self.parent)) + response = (yield self.deleteCalendarResource(self.resource, self.resource_uri, self.parent)) elif isCalendarCollectionResource(self.resource): - response = (yield self.deleteCalendar(self.resource, self.request.uri, self.parent)) + response = (yield self.deleteCalendar(self.resource, self.resource_uri, self.parent)) elif self.resource.isCollection(): response = (yield self.deleteCollection()) else: - response = (yield self.deleteResource(self.resource, self.request.uri, self.parent)) + response = (yield self.deleteResource(self.resource, self.resource_uri, self.parent)) returnValue(response) Modified: CalendarServer/trunk/twistedcaldav/scheduling/processing.py =================================================================== --- CalendarServer/trunk/twistedcaldav/scheduling/processing.py 2009-01-12 19:58:28 UTC (rev 3587) +++ CalendarServer/trunk/twistedcaldav/scheduling/processing.py 2009-01-12 20:01:27 UTC (rev 3588) @@ -17,7 +17,6 @@ from hashlib import md5 from twisted.internet import reactor from twisted.internet.defer import inlineCallbacks, returnValue, succeed -from twisted.web2.dav.fileop import delete from twisted.web2.dav.method.report import NumberOfMatchesWithinLimits from twisted.web2.dav.util import joinURL from twistedcaldav import customxml, caldavxml @@ -365,7 +364,7 @@ # Delete the attendee's copy of the event log.debug("ImplicitProcessing - originator '%s' to recipient '%s' processing METHOD:CANCEL, UID: '%s' - deleting entire event" % (self.originator.cuaddr, self.recipient.cuaddr, self.uid)) - yield self.deleteCalendarResource(self.recipient_calendar_collection, self.recipient_calendar_name) + yield self.deleteCalendarResource(self.recipient_calendar_collection_uri, self.recipient_calendar_collection, self.recipient_calendar_name) # Build the schedule-changes XML element changes = customxml.ScheduleChanges( @@ -588,24 +587,26 @@ returnValue(newchild) @inlineCallbacks - def deleteCalendarResource(self, collection, name): + def deleteCalendarResource(self, collURL, collection, name): """ Delete the calendar resource in the specified calendar. - @param collection: the L{CalDAVFile} for the calendar collection to store the resource in. - @param name: the C{str} for the resource name to write into, or {None} to write a new resource. - @return: L{Deferred} + @param collURL: the URL of the calendar collection. + @type name: C{str} + @param collection: the calendar collection to delete the resource from. + @type collection: L{CalDAVFile} + @param name: the resource name to write into, or {None} to write a new resource. + @type name: C{str} """ + from twistedcaldav.method.delete_common import DeleteResource delchild = collection.getChild(name) - index = collection.index() - index.deleteResource(delchild.fp.basename()) - - yield delete("", delchild.fp, "0") - - # Change CTag on the parent calendar collection - yield collection.updateCTag() + childURL = joinURL(collURL, name) + self.request._rememberResource(delchild, childURL) + deleter = DeleteResource(self.request, delchild, childURL, collection, "0", internal_request=True) + yield deleter.run() + def changeAttendeePartstat(self, attendees, partstat): """ Change the PARTSTAT on any ATTENDEE properties passed in.