[CalendarServer-changes] [2975] CalendarServer/branches/users/cdaboo/implicitauto-2947/twistedcaldav
source_changes at macosforge.org
source_changes at macosforge.org
Wed Sep 10 20:32:19 PDT 2008
Revision: 2975
http://trac.macosforge.org/projects/calendarserver/changeset/2975
Author: cdaboo at apple.com
Date: 2008-09-10 20:32:19 -0700 (Wed, 10 Sep 2008)
Log Message:
-----------
Various fixes for auto-accept behavior including serialization of inbox auto-processing
using a memcache deferred lock.
Modified Paths:
--------------
CalendarServer/branches/users/cdaboo/implicitauto-2947/twistedcaldav/ical.py
CalendarServer/branches/users/cdaboo/implicitauto-2947/twistedcaldav/itip.py
CalendarServer/branches/users/cdaboo/implicitauto-2947/twistedcaldav/scheduling/icaldiff.py
CalendarServer/branches/users/cdaboo/implicitauto-2947/twistedcaldav/scheduling/itip.py
Modified: CalendarServer/branches/users/cdaboo/implicitauto-2947/twistedcaldav/ical.py
===================================================================
--- CalendarServer/branches/users/cdaboo/implicitauto-2947/twistedcaldav/ical.py 2008-09-11 03:30:02 UTC (rev 2974)
+++ CalendarServer/branches/users/cdaboo/implicitauto-2947/twistedcaldav/ical.py 2008-09-11 03:32:19 UTC (rev 2975)
@@ -1349,11 +1349,10 @@
assert self.name() == "VCALENDAR", "Not a calendar: %r" % (self,)
- if self.name() == "VCALENDAR":
- for component in self.subcomponents():
- if component.name() == "VTIMEZONE":
- continue
- [component.removeProperty(p) for p in tuple(component.properties("ATTENDEE")) if p.value() != attendee]
+ for component in self.subcomponents():
+ if component.name() == "VTIMEZONE":
+ continue
+ [component.removeProperty(p) for p in tuple(component.properties("ATTENDEE")) if p.value() != attendee]
def removeAlarms(self):
"""
@@ -1377,14 +1376,13 @@
assert self.name() == "VCALENDAR", "Not a calendar: %r" % (self,)
- if self.name() == "VCALENDAR":
- for component in self.subcomponents():
- if component.name() == "VTIMEZONE":
- continue
- if keep:
- [component.removeProperty(p) for p in tuple(component.properties()) if p.name() not in keep]
- if remove:
- [component.removeProperty(p) for p in tuple(component.properties()) if p.name() in remove]
+ for component in self.subcomponents():
+ if component.name() == "VTIMEZONE":
+ continue
+ if keep:
+ [component.removeProperty(p) for p in tuple(component.properties()) if p.name() not in keep]
+ if remove:
+ [component.removeProperty(p) for p in tuple(component.properties()) if p.name() in remove]
def removeXProperties(self, keep_properties):
"""
@@ -1393,15 +1391,14 @@
assert self.name() == "VCALENDAR", "Not a calendar: %r" % (self,)
- if self.name() == "VCALENDAR":
- for component in self.subcomponents():
- if component.name() == "VTIMEZONE":
- continue
- [
- component.removeProperty(p)
- for p in tuple(component.properties())
- if p.name().startswith("X-") and p.name() not in keep_properties
- ]
+ for component in self.subcomponents():
+ if component.name() == "VTIMEZONE":
+ continue
+ [
+ component.removeProperty(p)
+ for p in tuple(component.properties())
+ if p.name().startswith("X-") and p.name() not in keep_properties
+ ]
def removePropertyParameters(self, property, params):
"""
@@ -1410,18 +1407,34 @@
assert self.name() == "VCALENDAR", "Not a calendar: %r" % (self,)
- if self.name() == "VCALENDAR":
- for component in self.subcomponents():
- if component.name() == "VTIMEZONE":
- continue
- props = component.properties(property)
- for prop in props:
- for param in params:
- try:
- del prop.params()[param]
- except KeyError:
- pass
-
+ for component in self.subcomponents():
+ if component.name() == "VTIMEZONE":
+ continue
+ props = component.properties(property)
+ for prop in props:
+ for param in params:
+ try:
+ del prop.params()[param]
+ except KeyError:
+ pass
+
+ def normalizePropertyValueLists(self, propname):
+ """
+ Convert properties that have a list of values into single properties, to make it easier
+ to do comparisons between two ical objects.
+ """
+
+ assert self.name() == "VCALENDAR", "Not a calendar: %r" % (self,)
+
+ for component in self.subcomponents():
+ if component.name() == "VTIMEZONE":
+ continue
+ for prop in tuple(component.properties(propname)):
+ if type(prop.value()) is list and len(prop.value()) > 1:
+ component.removeProperty(prop)
+ for value in prop.value():
+ component.addProperty(Property(propname, [value,]))
+
##
# Dates and date-times
##
Modified: CalendarServer/branches/users/cdaboo/implicitauto-2947/twistedcaldav/itip.py
===================================================================
--- CalendarServer/branches/users/cdaboo/implicitauto-2947/twistedcaldav/itip.py 2008-09-11 03:30:02 UTC (rev 2974)
+++ CalendarServer/branches/users/cdaboo/implicitauto-2947/twistedcaldav/itip.py 2008-09-11 03:32:19 UTC (rev 2975)
@@ -35,7 +35,8 @@
import time
from twisted.python.failure import Failure
-from twisted.internet.defer import inlineCallbacks, returnValue, maybeDeferred
+from twisted.internet.defer import inlineCallbacks, returnValue, maybeDeferred,\
+ succeed
from twisted.web2.dav import davxml
from twisted.web2.dav.method.report import NumberOfMatchesWithinLimits
from twisted.web2.dav.util import joinURL
@@ -46,6 +47,7 @@
from twistedcaldav.accounting import accountingEnabled, emitAccounting
from twistedcaldav.log import Logger
from twistedcaldav.ical import Property
+from twistedcaldav.memcachelock import MemcacheLock, MemcacheLockTimeoutError
from twistedcaldav.method import report_common
from twistedcaldav.resource import isCalendarCollectionResource
@@ -63,6 +65,7 @@
class iTipProcessor(object):
+ @inlineCallbacks
def handleRequest(self, request, principal, inbox, calendar, child):
"""
Handle an iTIP response automatically.
@@ -93,7 +96,19 @@
else:
self.childname = ""
- return f()
+ # Get a lock on the inbox first
+ _lock = MemcacheLock("iTIPAutoProcess", inbox.fp.path, timeout=60.0, retry_interval=1.0, expire_time=300)
+
+ try:
+ yield _lock.acquire()
+ yield f()
+ yield _lock.release()
+ except MemcacheLockTimeoutError:
+ raise
+ except Exception, e:
+ log.error(e)
+ yield _lock.clean()
+ raise
@inlineCallbacks
def processRequest(self):
@@ -567,9 +582,9 @@
def deleteInboxResource(self, processed_state):
# Remove the now processed incoming request.
try:
+ log.info("Deleting new iTIP message %s in Inbox because it has been %s." %
+ (self.childname, processed_state,))
yield self.deleteResource(self.inbox, self.childname)
- log.info("Deleted new iTIP message %s in Inbox because it has been %s." %
- (self.childname, processed_state,))
except:
# FIXME: bare except
log.err("Error while auto-processing iTIP: %s" % (Failure(),))
@@ -585,6 +600,12 @@
"""
delchild = collection.getChild(name)
+
+ # Sometimes the resource might already be gone...
+ if delchild is None:
+ log.warn("Nothing to delete: %s in %s is missing." % (name, collection))
+ return succeed(None)
+
index = collection.index()
index.deleteResource(delchild.fp.basename())
Modified: CalendarServer/branches/users/cdaboo/implicitauto-2947/twistedcaldav/scheduling/icaldiff.py
===================================================================
--- CalendarServer/branches/users/cdaboo/implicitauto-2947/twistedcaldav/scheduling/icaldiff.py 2008-09-11 03:30:02 UTC (rev 2974)
+++ CalendarServer/branches/users/cdaboo/implicitauto-2947/twistedcaldav/scheduling/icaldiff.py 2008-09-11 03:32:19 UTC (rev 2975)
@@ -85,11 +85,13 @@
# Do straight comparison without alarms
self.calendar1 = self.calendar1.duplicate()
+ self.calendar1.attendeesView((attendee,))
+ self.calendar1.normalizePropertyValueLists("EXDATE")
self.calendar1.removeXProperties(("X-CALENDARSERVER-PRIVATE-COMMENT",))
- self.calendar1.attendeesView((attendee,))
iTipGenerator.prepareSchedulingMessage(self.calendar1)
self.calendar2 = self.calendar2.duplicate()
+ self.calendar2.normalizePropertyValueLists("EXDATE")
self.calendar2.removeXProperties(("X-CALENDARSERVER-PRIVATE-COMMENT",))
iTipGenerator.prepareSchedulingMessage(self.calendar2)
@@ -100,10 +102,12 @@
# Make sure the same VCALENDAR properties match
if not self._checkVCALENDARProperties():
+ log.debug("attendeeMerge: VCALENDAR properties do not match")
return False, False
# Make sure the same VTIMEZONE components appear
if not self._compareVTIMEZONEs():
+ log.debug("attendeeMerge: VTIMEZONEs do not match")
return False, False
# Compare each component instance from the new calendar with each derived
@@ -186,6 +190,7 @@
for key in set2 - set1:
component1 = self.calendar1.deriveInstance(key[2])
if component1 is None:
+ log.debug("_compareComponents: Could not derive instance: %s" % (key[2],))
return False, False
component2 = map2[key]
Modified: CalendarServer/branches/users/cdaboo/implicitauto-2947/twistedcaldav/scheduling/itip.py
===================================================================
--- CalendarServer/branches/users/cdaboo/implicitauto-2947/twistedcaldav/scheduling/itip.py 2008-09-11 03:30:02 UTC (rev 2974)
+++ CalendarServer/branches/users/cdaboo/implicitauto-2947/twistedcaldav/scheduling/itip.py 2008-09-11 03:32:19 UTC (rev 2975)
@@ -376,7 +376,7 @@
instance = original.overriddenComponent(instance_rid)
if instance is None:
instance = original.masterComponent()
- assert instance is not None
+ assert instance is not None, "Need a master component"
# Add some required properties extracted from the original
comp.addProperty(Property("DTSTAMP", datetime.datetime.now(tz=utc)))
@@ -404,7 +404,7 @@
# Extract the matching attendee property
for attendee in attendees:
attendeeProp = instance.getAttendeeProperty((attendee,))
- assert attendeeProp is not None
+ assert attendeeProp is not None, "Must have matching ATTENDEE property"
comp.addProperty(attendeeProp)
tzids.update(comp.timezoneIDs())
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20080910/4563f982/attachment-0001.html
More information about the calendarserver-changes
mailing list