[CalendarServer-changes] [4699] CalendarServer/branches/users/cdaboo/per-user-icalendar-4669/ twistedcaldav/datafilters
source_changes at macosforge.org
source_changes at macosforge.org
Tue Nov 3 10:44:59 PST 2009
Revision: 4699
http://trac.macosforge.org/projects/calendarserver/changeset/4699
Author: cdaboo at apple.com
Date: 2009-11-03 10:44:59 -0800 (Tue, 03 Nov 2009)
Log Message:
-----------
Basic merge behavior for merging a "new" resource (i.e., just split out the per-user data with no real
merge).
Modified Paths:
--------------
CalendarServer/branches/users/cdaboo/per-user-icalendar-4669/twistedcaldav/datafilters/__init__.py
CalendarServer/branches/users/cdaboo/per-user-icalendar-4669/twistedcaldav/datafilters/peruserdata.py
CalendarServer/branches/users/cdaboo/per-user-icalendar-4669/twistedcaldav/datafilters/test/test_peruserdata.py
Modified: CalendarServer/branches/users/cdaboo/per-user-icalendar-4669/twistedcaldav/datafilters/__init__.py
===================================================================
--- CalendarServer/branches/users/cdaboo/per-user-icalendar-4669/twistedcaldav/datafilters/__init__.py 2009-11-03 18:21:02 UTC (rev 4698)
+++ CalendarServer/branches/users/cdaboo/per-user-icalendar-4669/twistedcaldav/datafilters/__init__.py 2009-11-03 18:44:59 UTC (rev 4699)
@@ -29,7 +29,7 @@
sortFirst = ('uid', 'x-calendarserver-peruser-uid')
knownChildren = {
'UID': (1, 1, None),#min, max, behaviorRegistry id
- 'X-CALENDARSERVER-PERUSER': (1, 1, None),
+ 'X-CALENDARSERVER-PERUSER-UID': (1, 1, None),
'X-CALENDARSERVER-PERINSTANCE': (0, None, None),
}
Modified: CalendarServer/branches/users/cdaboo/per-user-icalendar-4669/twistedcaldav/datafilters/peruserdata.py
===================================================================
--- CalendarServer/branches/users/cdaboo/per-user-icalendar-4669/twistedcaldav/datafilters/peruserdata.py 2009-11-03 18:21:02 UTC (rev 4698)
+++ CalendarServer/branches/users/cdaboo/per-user-icalendar-4669/twistedcaldav/datafilters/peruserdata.py 2009-11-03 18:44:59 UTC (rev 4699)
@@ -15,6 +15,7 @@
##
from twistedcaldav.datafilters.filter import CalendarFilter
+from twistedcaldav.ical import Component, Property
__all__ = [
"PerUserDataFilter",
@@ -57,10 +58,14 @@
Filter per-user data
"""
+ # If any of these change also change the vobject behaviors in this module's __init__.py
PERUSER_COMPONENT = "X-CALENDARSERVER-PERUSER"
PERUSER_UID = "X-CALENDARSERVER-PERUSER-UID"
PERINSTANCE_COMPONENT = "X-CALENDARSERVER-PERINSTANCE"
+ PERUSER_PROPERTIES = ("TRANSP",)
+ PERUSER_SUBCOMPONENTS = ("VALARM",)
+
def __init__(self, uid):
"""
@@ -106,10 +111,27 @@
def merge(self, icalnew, icalold):
"""
- Private event merging does not happen
+ Merge the new data with the old taking per-user information into account.
+
+ @param icalnew: new calendar data
+ @type icalnew: L{Component} or C{str}
+ @param icalold: existing calendar data
+ @type icalold: L{Component} or C{str}
+
+ @return: L{Component} for the merged calendar data
"""
- raise NotImplementedError
+ # Make sure input is valid
+ icalnew = self.validCalendar(icalnew)
+
+ # First split the new data into common and per-user pieces
+ self._splitPerUserData(icalnew)
+ if icalold is None:
+ return icalnew
+
+ # Make sure input is valid
+ icalold = self.validCalendar(icalold)
+
def _mergeBack(self, ical, peruser):
"""
Merge the per-user data back into the main calendar data.
@@ -178,3 +200,90 @@
if property.name() == "RECURRENCE-ID":
continue
ical.addProperty(property)
+
+ def _splitPerUserData(self, ical):
+
+ peruser_component = None
+ perinstance_components = {}
+
+ def init_peruser_component():
+ peruser = Component(PerUserDataFilter.PERUSER_COMPONENT)
+ peruser.addProperty(Property("UID", ical.resourceUID()))
+ peruser.addProperty(Property(PerUserDataFilter.PERUSER_UID, self.uid))
+ ical.addComponent(peruser)
+ return peruser
+
+ for subcomponent in ical.subcomponents():
+ if subcomponent.name() == "VTIMEZONE":
+ continue
+
+ perinstance_component = None
+
+ def init_perinstance_component():
+ peruser = Component(PerUserDataFilter.PERINSTANCE_COMPONENT)
+ rid = subcomponent.getRecurrenceIDUTC()
+ if rid:
+ peruser.addProperty(Property("RECURRENCE-ID", rid))
+ perinstance_components[rid] = peruser
+ return peruser
+
+ # Transfer per-user properties from main component to per-instance component
+ for property in tuple(subcomponent.properties()):
+ if property.name() in PerUserDataFilter.PERUSER_PROPERTIES or property.name().startswith("X-"):
+ if peruser_component is None:
+ peruser_component = init_peruser_component()
+ if perinstance_component is None:
+ perinstance_component = init_perinstance_component()
+ perinstance_component.addProperty(property)
+ subcomponent.removeProperty(property)
+
+ # Transfer per-user components from main component to per-instance component
+ for component in tuple(subcomponent.subcomponents()):
+ if component.name() in PerUserDataFilter.PERUSER_SUBCOMPONENTS or component.name().startswith("X-"):
+ if peruser_component is None:
+ peruser_component = init_peruser_component()
+ if perinstance_component is None:
+ perinstance_component = init_perinstance_component()
+ perinstance_component.addComponent(component)
+ subcomponent.removeComponent(component)
+
+ # Add unique per-instance components into the per-user component
+ master_perinstance = perinstance_components.get(None)
+ master_perinstance_txt = str(master_perinstance)
+ if master_perinstance:
+ peruser_component.addComponent(master_perinstance)
+ for rid, perinstance in perinstance_components.iteritems():
+ if rid is None:
+ continue
+ perinstance_txt = str(perinstance)
+ perinstance_txt = "".join([line for line in perinstance_txt.splitlines(True) if not line.startswith("RECURRENCE-ID:")])
+ if master_perinstance is None or perinstance_txt != master_perinstance_txt:
+ peruser_component.addComponent(perinstance)
+
+ self._compactInstances(ical)
+
+ def _compactInstances(self, ical):
+ """
+ Remove recurrences instances that are the same as their master-derived counterparts. This gives the most
+ compact representation of the calendar data.
+
+ @param ical: calendar data to process
+ @type ical: L{Component}
+ """
+
+ # Must have a master component in order to do this
+ master = ical.masterComponent()
+ if master is None:
+ return
+
+ for subcomponent in tuple(ical.subcomponents()):
+ if subcomponent.name() == "VTIMEZONE" or subcomponent.name().startswith("X-"):
+ continue
+ rid = subcomponent.getRecurrenceIDUTC()
+ if rid is None:
+ continue
+ derived = ical.deriveInstance(rid)
+ if derived:
+ if str(derived) == str(subcomponent):
+ ical.removeComponent(subcomponent)
+
Modified: CalendarServer/branches/users/cdaboo/per-user-icalendar-4669/twistedcaldav/datafilters/test/test_peruserdata.py
===================================================================
--- CalendarServer/branches/users/cdaboo/per-user-icalendar-4669/twistedcaldav/datafilters/test/test_peruserdata.py 2009-11-03 18:21:02 UTC (rev 4698)
+++ CalendarServer/branches/users/cdaboo/per-user-icalendar-4669/twistedcaldav/datafilters/test/test_peruserdata.py 2009-11-03 18:44:59 UTC (rev 4699)
@@ -18,7 +18,7 @@
from twistedcaldav.ical import Component
from twistedcaldav.datafilters.peruserdata import PerUserDataFilter
-class PerUserDataTestNotRecurring (twistedcaldav.test.util.TestCase):
+class PerUserDataFilterTestNotRecurring (twistedcaldav.test.util.TestCase):
def test_public_noperuser(self):
@@ -202,7 +202,7 @@
for item in (data, Component.fromString(data),):
self.assertEqual(str(PerUserDataFilter("user03").filter(item)), result03)
-class PerUserDataTestRecurring (twistedcaldav.test.util.TestCase):
+class PerUserDataFilterTestRecurring (twistedcaldav.test.util.TestCase):
def test_public_noperuser(self):
@@ -835,3 +835,498 @@
for item in (data, Component.fromString(data),):
self.assertEqual(str(PerUserDataFilter("user02").filter(item)), result02)
+class PerUserDataMergeTestNewNotRecurring (twistedcaldav.test.util.TestCase):
+
+ def test_public_noperuser(self):
+
+ data = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n")
+
+ for item in (data, Component.fromString(data),):
+ self.assertEqual(str(PerUserDataFilter("user01").merge(item, None)), data)
+
+ def test_public_oneuser(self):
+
+ data = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+TRANSP:OPAQUE
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:Test
+TRIGGER;RELATED=START:-PT10M
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n")
+ result01 = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+END:VEVENT
+BEGIN:X-CALENDARSERVER-PERUSER
+UID:12345-67890
+X-CALENDARSERVER-PERUSER-UID:user01
+BEGIN:X-CALENDARSERVER-PERINSTANCE
+TRANSP:OPAQUE
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:Test
+TRIGGER;RELATED=START:-PT10M
+END:VALARM
+END:X-CALENDARSERVER-PERINSTANCE
+END:X-CALENDARSERVER-PERUSER
+END:VCALENDAR
+""".replace("\n", "\r\n")
+
+ for item in (data, Component.fromString(data),):
+ self.assertEqual(str(PerUserDataFilter("user01").merge(item, None)), result01)
+
+class PerUserDataMergeTestNewRecurring (twistedcaldav.test.util.TestCase):
+
+ def test_public_noperuser(self):
+
+ data = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+RRULE:FREQ=DAILY
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080602T120000Z
+DTSTART:20080602T130000Z
+DTEND:20080602T140000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n")
+
+ for item in (data, Component.fromString(data),):
+ self.assertEqual(str(PerUserDataFilter("user01").merge(item, None)), data)
+
+ def test_public_oneuser_master(self):
+
+ data = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+RRULE:FREQ=DAILY
+TRANSP:OPAQUE
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:Test
+TRIGGER;RELATED=START:-PT10M
+END:VALARM
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080602T120000Z
+DTSTART:20080602T130000Z
+DTEND:20080602T140000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+TRANSP:OPAQUE
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:Test
+TRIGGER;RELATED=START:-PT10M
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n")
+ result01 = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+RRULE:FREQ=DAILY
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080602T120000Z
+DTSTART:20080602T130000Z
+DTEND:20080602T140000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+END:VEVENT
+BEGIN:X-CALENDARSERVER-PERUSER
+UID:12345-67890
+X-CALENDARSERVER-PERUSER-UID:user01
+BEGIN:X-CALENDARSERVER-PERINSTANCE
+TRANSP:OPAQUE
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:Test
+TRIGGER;RELATED=START:-PT10M
+END:VALARM
+END:X-CALENDARSERVER-PERINSTANCE
+END:X-CALENDARSERVER-PERUSER
+END:VCALENDAR
+""".replace("\n", "\r\n")
+
+ for item in (data, Component.fromString(data),):
+ self.assertEqual(str(PerUserDataFilter("user01").merge(item, None)), result01)
+
+ def test_public_oneuser_master_and_override(self):
+
+ data = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+RRULE:FREQ=DAILY
+TRANSP:OPAQUE
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:Test-master
+TRIGGER;RELATED=START:-PT10M
+END:VALARM
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080602T120000Z
+DTSTART:20080602T130000Z
+DTEND:20080602T140000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+TRANSP:TRANSPARENT
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:Test-override
+TRIGGER;RELATED=START:-PT10M
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n")
+ result01 = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+RRULE:FREQ=DAILY
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080602T120000Z
+DTSTART:20080602T130000Z
+DTEND:20080602T140000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+END:VEVENT
+BEGIN:X-CALENDARSERVER-PERUSER
+UID:12345-67890
+X-CALENDARSERVER-PERUSER-UID:user01
+BEGIN:X-CALENDARSERVER-PERINSTANCE
+TRANSP:OPAQUE
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:Test-master
+TRIGGER;RELATED=START:-PT10M
+END:VALARM
+END:X-CALENDARSERVER-PERINSTANCE
+BEGIN:X-CALENDARSERVER-PERINSTANCE
+RECURRENCE-ID:20080602T120000Z
+TRANSP:TRANSPARENT
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:Test-override
+TRIGGER;RELATED=START:-PT10M
+END:VALARM
+END:X-CALENDARSERVER-PERINSTANCE
+END:X-CALENDARSERVER-PERUSER
+END:VCALENDAR
+""".replace("\n", "\r\n")
+
+ for item in (data, Component.fromString(data),):
+ self.assertEqual(str(PerUserDataFilter("user01").merge(item, None)), result01)
+
+ def test_public_oneuser_override(self):
+
+ data = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+RRULE:FREQ=DAILY
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080602T120000Z
+DTSTART:20080602T130000Z
+DTEND:20080602T140000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+TRANSP:TRANSPARENT
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:Test-override
+TRIGGER;RELATED=START:-PT10M
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n")
+ result01 = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+RRULE:FREQ=DAILY
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080602T120000Z
+DTSTART:20080602T130000Z
+DTEND:20080602T140000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+END:VEVENT
+BEGIN:X-CALENDARSERVER-PERUSER
+UID:12345-67890
+X-CALENDARSERVER-PERUSER-UID:user01
+BEGIN:X-CALENDARSERVER-PERINSTANCE
+RECURRENCE-ID:20080602T120000Z
+TRANSP:TRANSPARENT
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:Test-override
+TRIGGER;RELATED=START:-PT10M
+END:VALARM
+END:X-CALENDARSERVER-PERINSTANCE
+END:X-CALENDARSERVER-PERUSER
+END:VCALENDAR
+""".replace("\n", "\r\n")
+
+ for item in (data, Component.fromString(data),):
+ self.assertEqual(str(PerUserDataFilter("user01").merge(item, None)), result01)
+
+ def test_public_oneuser_master_compact_override(self):
+
+ data = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+RRULE:FREQ=DAILY
+TRANSP:OPAQUE
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:Test-master
+TRIGGER;RELATED=START:-PT10M
+END:VALARM
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080602T120000Z
+DTSTART:20080602T120000Z
+DTEND:20080602T130000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+TRANSP:TRANSPARENT
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:Test-override
+TRIGGER;RELATED=START:-PT10M
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n")
+ result01 = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+RRULE:FREQ=DAILY
+END:VEVENT
+BEGIN:X-CALENDARSERVER-PERUSER
+UID:12345-67890
+X-CALENDARSERVER-PERUSER-UID:user01
+BEGIN:X-CALENDARSERVER-PERINSTANCE
+TRANSP:OPAQUE
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:Test-master
+TRIGGER;RELATED=START:-PT10M
+END:VALARM
+END:X-CALENDARSERVER-PERINSTANCE
+BEGIN:X-CALENDARSERVER-PERINSTANCE
+RECURRENCE-ID:20080602T120000Z
+TRANSP:TRANSPARENT
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:Test-override
+TRIGGER;RELATED=START:-PT10M
+END:VALARM
+END:X-CALENDARSERVER-PERINSTANCE
+END:X-CALENDARSERVER-PERUSER
+END:VCALENDAR
+""".replace("\n", "\r\n")
+
+ for item in (data, Component.fromString(data),):
+ self.assertEqual(str(PerUserDataFilter("user01").merge(item, None)), result01)
+
+ def test_public_oneuser_master_noncompact_override(self):
+
+ data = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+RRULE:FREQ=DAILY
+TRANSP:OPAQUE
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:Test-master
+TRIGGER;RELATED=START:-PT10M
+END:VALARM
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080602T120000Z
+DTSTART:20080602T130000Z
+DTEND:20080602T140000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+TRANSP:TRANSPARENT
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:Test-override
+TRIGGER;RELATED=START:-PT10M
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n")
+ result01 = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+RRULE:FREQ=DAILY
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080602T120000Z
+DTSTART:20080602T130000Z
+DTEND:20080602T140000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+END:VEVENT
+BEGIN:X-CALENDARSERVER-PERUSER
+UID:12345-67890
+X-CALENDARSERVER-PERUSER-UID:user01
+BEGIN:X-CALENDARSERVER-PERINSTANCE
+TRANSP:OPAQUE
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:Test-master
+TRIGGER;RELATED=START:-PT10M
+END:VALARM
+END:X-CALENDARSERVER-PERINSTANCE
+BEGIN:X-CALENDARSERVER-PERINSTANCE
+RECURRENCE-ID:20080602T120000Z
+TRANSP:TRANSPARENT
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:Test-override
+TRIGGER;RELATED=START:-PT10M
+END:VALARM
+END:X-CALENDARSERVER-PERINSTANCE
+END:X-CALENDARSERVER-PERUSER
+END:VCALENDAR
+""".replace("\n", "\r\n")
+
+ for item in (data, Component.fromString(data),):
+ self.assertEqual(str(PerUserDataFilter("user01").merge(item, None)), result01)
+
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20091103/0af84a80/attachment-0001.html>
More information about the calendarserver-changes
mailing list