[CalendarServer-changes] [4368] CalendarServer/trunk/twistedcaldav
source_changes at macosforge.org
source_changes at macosforge.org
Tue Jun 23 08:35:47 PDT 2009
Revision: 4368
http://trac.macosforge.org/projects/calendarserver/changeset/4368
Author: cdaboo at apple.com
Date: 2009-06-23 08:35:47 -0700 (Tue, 23 Jun 2009)
Log Message:
-----------
Don't raise an exception for an invalid instance when we are re-indexing data already on the server,
but do raise when there is incoming invalid data.
Modified Paths:
--------------
CalendarServer/trunk/twistedcaldav/ical.py
CalendarServer/trunk/twistedcaldav/index.py
CalendarServer/trunk/twistedcaldav/instance.py
CalendarServer/trunk/twistedcaldav/test/test_icalendar.py
CalendarServer/trunk/twistedcaldav/test/test_index.py
Modified: CalendarServer/trunk/twistedcaldav/ical.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/ical.py 2009-06-23 00:54:36 UTC (rev 4367)
+++ CalendarServer/trunk/twistedcaldav/ical.py 2009-06-23 15:35:47 UTC (rev 4368)
@@ -956,20 +956,21 @@
self.cachedInstances = self.expandTimeRanges(limit)
return self.cachedInstances
- def expandTimeRanges(self, limit):
+ def expandTimeRanges(self, limit, ignoreInvalidInstances=False):
"""
Expand the set of recurrence instances for the components
contained within this VCALENDAR component. We will assume
that this component has already been validated as a CalDAV resource
(i.e. only one type of component, all with the same UID)
@param limit: datetime.date value representing the end of the expansion.
+ @param ignoreInvalidInstances: C{bool} whether to ignore instance errors.
@return: a set of Instances for each recurrence in the set.
"""
componentSet = self.subcomponents()
- return self.expandSetTimeRanges(componentSet, limit)
+ return self.expandSetTimeRanges(componentSet, limit, ignoreInvalidInstances)
- def expandSetTimeRanges(self, componentSet, limit):
+ def expandSetTimeRanges(self, componentSet, limit, ignoreInvalidInstances=False):
"""
Expand the set of recurrence instances up to the specified date limit.
What we do is first expand the master instance into the set of generate
@@ -983,7 +984,7 @@
"""
# Set of instances to return
- instances = InstanceList()
+ instances = InstanceList(ignoreInvalidInstances=ignoreInvalidInstances)
instances.expandTimeRanges(componentSet, limit)
return instances
Modified: CalendarServer/trunk/twistedcaldav/index.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/index.py 2009-06-23 00:54:36 UTC (rev 4367)
+++ CalendarServer/trunk/twistedcaldav/index.py 2009-06-23 15:35:47 UTC (rev 4368)
@@ -204,7 +204,7 @@
return uid
- def addResource(self, name, calendar, fast=False):
+ def addResource(self, name, calendar, fast=False, reCreate=False):
"""
Adding or updating an existing resource.
To check for an update we attempt to get an existing UID
@@ -218,7 +218,7 @@
oldUID = self.resourceUIDForName(name)
if oldUID is not None:
self._delete_from_db(name, oldUID)
- self._add_to_db(name, calendar)
+ self._add_to_db(name, calendar, reCreate=reCreate)
if not fast:
self._db_commit()
@@ -341,7 +341,7 @@
"""
return schema_version
- def _add_to_db(self, name, calendar, cursor = None, expand_until=None):
+ def _add_to_db(self, name, calendar, cursor = None, expand_until=None, reCreate=False):
"""
Records the given calendar resource in the index with the given name.
Resource names and UIDs must both be unique; only one resource name may
@@ -455,10 +455,10 @@
with a longer expansion.
"""
calendar = self.resource.getChild(name).iCalendar()
- self._add_to_db(name, calendar, expand_until=expand_until)
+ self._add_to_db(name, calendar, expand_until=expand_until, reCreate=True)
self._db_commit()
- def _add_to_db(self, name, calendar, cursor = None, expand_until=None):
+ def _add_to_db(self, name, calendar, cursor = None, expand_until=None, reCreate=False):
"""
Records the given calendar resource in the index with the given name.
Resource names and UIDs must both be unique; only one resource name may
@@ -488,7 +488,7 @@
raise IndexedSearchException
try:
- instances = calendar.expandTimeRanges(expand)
+ instances = calendar.expandTimeRanges(expand, ignoreInvalidInstances=reCreate)
except InvalidOverriddenInstanceError, e:
log.err("Invalid instance %s when indexing %s in %s" % (e.rid, name, self.resource,))
raise
@@ -789,7 +789,7 @@
log.err("Non-calendar resource: %s" % (name,))
else:
#log.msg("Indexing resource: %s" % (name,))
- self.addResource(name, calendar, True)
+ self.addResource(name, calendar, True, reCreate=True)
finally:
stream.close()
@@ -901,7 +901,7 @@
log.err("Non-calendar resource: %s" % (name,))
else:
#log.msg("Indexing resource: %s" % (name,))
- self.addResource(name, calendar, True)
+ self.addResource(name, calendar, True, reCreate=True)
finally:
stream.close()
Modified: CalendarServer/trunk/twistedcaldav/instance.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/instance.py 2009-06-23 00:54:36 UTC (rev 4367)
+++ CalendarServer/trunk/twistedcaldav/instance.py 2009-06-23 15:35:47 UTC (rev 4368)
@@ -96,11 +96,12 @@
class InstanceList(object):
- __slots__ = ["instances", "limit"]
+ __slots__ = ["instances", "limit", "ignoreInvalidInstances",]
- def __init__(self):
+ def __init__(self, ignoreInvalidInstances=False):
self.instances = {}
self.limit = None
+ self.ignoreInvalidInstances = ignoreInvalidInstances
def __iter__(self):
# Return keys in sorted order via iterator
@@ -324,7 +325,10 @@
# Make sure override RECURRENCE-ID is a valid instance of the master
if got_master:
if str(rid) not in self.instances:
- raise InvalidOverriddenInstanceError(str(rid))
+ if self.ignoreInvalidInstances:
+ return
+ else:
+ raise InvalidOverriddenInstanceError(str(rid))
self.addInstance(Instance(component, start, end, rid, True, range))
Modified: CalendarServer/trunk/twistedcaldav/test/test_icalendar.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_icalendar.py 2009-06-23 00:54:36 UTC (rev 4367)
+++ CalendarServer/trunk/twistedcaldav/test/test_icalendar.py 2009-06-23 15:35:47 UTC (rev 4368)
@@ -1656,6 +1656,7 @@
END:VEVENT
END:VCALENDAR
""",
+ False,
(datetime.datetime(2007, 11, 14, 0, 0, 0, tzinfo=tzutc()),)
),
(
@@ -1671,6 +1672,7 @@
END:VEVENT
END:VCALENDAR
""",
+ False,
(
datetime.datetime(2007, 11, 14, 0, 0, 0, tzinfo=tzutc()),
datetime.datetime(2007, 11, 15, 0, 0, 0, tzinfo=tzutc()),
@@ -1690,6 +1692,7 @@
END:VEVENT
END:VCALENDAR
""",
+ False,
(
datetime.datetime(2007, 11, 14, 0, 0, 0, tzinfo=tzutc()),
datetime.datetime(2007, 11, 15, 0, 0, 0, tzinfo=tzutc()),
@@ -1710,6 +1713,7 @@
END:VEVENT
END:VCALENDAR
""",
+ False,
(
datetime.datetime(2007, 11, 14, 0, 0, 0, tzinfo=tzutc()),
datetime.datetime(2007, 11, 16, 0, 0, 0, tzinfo=tzutc()),
@@ -1729,6 +1733,7 @@
END:VEVENT
END:VCALENDAR
""",
+ False,
(
datetime.datetime(2007, 11, 15, 0, 0, 0, tzinfo=tzutc()),
datetime.datetime(2007, 11, 16, 0, 0, 0, tzinfo=tzutc()),
@@ -1753,6 +1758,7 @@
END:VEVENT
END:VCALENDAR
""",
+ False,
(
datetime.datetime(2007, 11, 14, 0, 0, 0, tzinfo=tzutc()),
datetime.datetime(2007, 11, 15, 1, 0, 0, tzinfo=tzutc()),
@@ -1777,16 +1783,42 @@
END:VEVENT
END:VCALENDAR
""",
+ False,
None
),
+ (
+ "Recurring with invalid override",
+ """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890-1
+DTSTART:20071114T000000Z
+DURATION:P1H
+RRULE:FREQ=DAILY;COUNT=2
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890-1
+RECURRENCE-ID:20071115T010000Z
+DTSTART:20071115T000000Z
+DURATION:P1H
+END:VEVENT
+END:VCALENDAR
+""",
+ True,
+ (
+ datetime.datetime(2007, 11, 14, 0, 0, 0, tzinfo=tzutc()),
+ datetime.datetime(2007, 11, 15, 0, 0, 0, tzinfo=tzutc()),
+ )
+ ),
)
- for description, original, results in data:
+ for description, original, ignoreInvalidInstances, results in data:
component = Component.fromString(original)
if results is None:
- self.assertRaises(InvalidOverriddenInstanceError, component.expandTimeRanges, datetime.date(2100, 1, 1))
+ self.assertRaises(InvalidOverriddenInstanceError, component.expandTimeRanges, datetime.date(2100, 1, 1), ignoreInvalidInstances)
else:
- instances = component.expandTimeRanges(datetime.date(2100, 1, 1))
+ instances = component.expandTimeRanges(datetime.date(2100, 1, 1), ignoreInvalidInstances)
self.assertTrue(len(instances.instances) == len(results), "%s: wrong number of instances" % (description,))
for instance in instances:
self.assertTrue(instances[instance].start in results, "%s: %s missing" % (description, instance,))
Modified: CalendarServer/trunk/twistedcaldav/test/test_index.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_index.py 2009-06-23 00:54:36 UTC (rev 4367)
+++ CalendarServer/trunk/twistedcaldav/test/test_index.py 2009-06-23 15:35:47 UTC (rev 4368)
@@ -14,14 +14,19 @@
# limitations under the License.
##
-from twistedcaldav.index import Index
-
-import twistedcaldav.test.util
-from twistedcaldav.test.util import InMemoryMemcacheProtocol
-from twistedcaldav.index import ReservationError, MemcachedUIDReserver
from twisted.internet import reactor
from twisted.internet.task import deferLater
+from twistedcaldav.ical import Component
+from twistedcaldav.index import Index
+from twistedcaldav.index import ReservationError, MemcachedUIDReserver
+from twistedcaldav.instance import InvalidOverriddenInstanceError
+from twistedcaldav.test.util import InMemoryMemcacheProtocol
+import twistedcaldav.test.util
+
+import datetime
+import os
+
class SQLIndexTests (twistedcaldav.test.util.TestCase):
"""
Test abstract SQL DB class
@@ -89,7 +94,163 @@
return d
+ def test_index(self):
+ data = (
+ (
+ "#1.1 Simple component",
+ "1.1",
+ """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890-1.1
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ORGANIZER;CN="User 01":mailto:user1 at example.com
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+END:VEVENT
+END:VCALENDAR
+""",
+ False,
+ True,
+ ),
+ (
+ "#2.1 Recurring component",
+ "2.1",
+ """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890-2.1
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ORGANIZER;CN="User 01":mailto:user1 at example.com
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+RRULE:FREQ=WEEKLY;COUNT=2
+END:VEVENT
+END:VCALENDAR
+""",
+ False,
+ True,
+ ),
+ (
+ "#2.2 Recurring component with override",
+ "2.2",
+ """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890-2.2
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ORGANIZER;CN="User 01":mailto:user1 at example.com
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+RRULE:FREQ=WEEKLY;COUNT=2
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890-2.2
+RECURRENCE-ID:20080608T120000Z
+DTSTART:20080608T120000Z
+DTEND:20080608T130000Z
+ORGANIZER;CN="User 01":mailto:user1 at example.com
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+END:VEVENT
+END:VCALENDAR
+""",
+ False,
+ True,
+ ),
+ (
+ "#2.3 Recurring component with broken override - new",
+ "2.3",
+ """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890-2.3
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ORGANIZER;CN="User 01":mailto:user1 at example.com
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+RRULE:FREQ=WEEKLY;COUNT=2
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890-2.3
+RECURRENCE-ID:20080609T120000Z
+DTSTART:20080608T120000Z
+DTEND:20080608T130000Z
+ORGANIZER;CN="User 01":mailto:user1 at example.com
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+END:VEVENT
+END:VCALENDAR
+""",
+ False,
+ False,
+ ),
+ (
+ "#2.4 Recurring component with broken override - existing",
+ "2.4",
+ """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890-2.4
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ORGANIZER;CN="User 01":mailto:user1 at example.com
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+RRULE:FREQ=WEEKLY;COUNT=2
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890-2.4
+RECURRENCE-ID:20080609T120000Z
+DTSTART:20080608T120000Z
+DTEND:20080608T130000Z
+ORGANIZER;CN="User 01":mailto:user1 at example.com
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+END:VEVENT
+END:VCALENDAR
+""",
+ True,
+ True,
+ ),
+ )
+ for description, name, calendar_txt, reCreate, ok in data:
+ calendar = Component.fromString(calendar_txt)
+ if ok:
+ f = open(os.path.join(self.site.resource.fp.path, name), "w")
+ f.write(calendar_txt)
+ del f
+
+ self.db.addResource(name, calendar, reCreate=reCreate)
+ self.assertTrue(self.db.resourceExists(name), msg=description)
+ else:
+ self.assertRaises(InvalidOverriddenInstanceError, self.db.addResource, name, calendar)
+ self.assertFalse(self.db.resourceExists(name), msg=description)
+
+ self.db._db_recreate()
+ for description, name, calendar_txt, reCreate, ok in data:
+ if ok:
+ self.assertTrue(self.db.resourceExists(name), msg=description)
+ else:
+ self.assertFalse(self.db.resourceExists(name), msg=description)
+
+ self.db.testAndUpdateIndex(datetime.date(2020, 1, 1))
+ for description, name, calendar_txt, reCreate, ok in data:
+ if ok:
+ self.assertTrue(self.db.resourceExists(name), msg=description)
+ else:
+ self.assertFalse(self.db.resourceExists(name), msg=description)
+
class MemcacheTests(SQLIndexTests):
def setUp(self):
super(MemcacheTests, self).setUp()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20090623/aa8ade36/attachment-0001.html>
More information about the calendarserver-changes
mailing list