Example #1
0
    def testParseProperty(self):

        # Restore BACKSLASH_IN_URI_VALUE after test
        old_state = ParserContext.BACKSLASH_IN_URI_VALUE
        self.addCleanup(setattr, ParserContext, "BACKSLASH_IN_URI_VALUE", old_state)

        # Test with BACKSLASH_IN_URI_VALUE = PARSER_FIX
        ParserContext.BACKSLASH_IN_URI_VALUE = ParserContext.PARSER_FIX
        items = (
            ("URL:http://example.com", "URL:http://example.com"),
            ("URL:http://example.com&abd\\,def", "URL:http://example.com&abd,def"),
        )

        for item, result in items:
            prop = Property.parseText(item)
            test = prop.getText()
            self.assertEqual(test, result + "\r\n", "Failed to parse and re-generate '%s'" % (item,))

        # Test with BACKSLASH_IN_URI_VALUE = PARSER_ALLOW
        ParserContext.BACKSLASH_IN_URI_VALUE = ParserContext.PARSER_ALLOW
        items = (
            ("URL:http://example.com", "URL:http://example.com"),
            ("URL:http://example.com&abd\\,def", "URL:http://example.com&abd\\,def"),
        )

        for item, result in items:
            prop = Property.parseText(item)
            test = prop.getText()
            self.assertEqual(test, result + "\r\n", "Failed to parse and re-generate '%s'" % (item,))
Example #2
0
    def testNewRegistrationValueRoundtrip(self):

        Property.registerDefaultValue("X-SPECIAL-REGISTRATION", Value.VALUETYPE_TEXT)

        data = "X-SPECIAL-REGISTRATION:Text\\, escaped\\n"
        prop = Property.parseText(data)
        self.assertEqual(str(prop), "X-SPECIAL-REGISTRATION:Text\\, escaped\\n\r\n")

        prop = Property("X-SPECIAL-REGISTRATION", "Text, escaped\n")
        self.assertEqual(str(prop), "X-SPECIAL-REGISTRATION:Text\\, escaped\\n\r\n")
Example #3
0
        def add(self, valarm):
            # Delete existing then add
            self.remove(valarm)

            prop = Property(definitions.cICalProperty_DESCRIPTION, self.mDescription)
            valarm.addProperty(prop)

            prop = Property(definitions.cICalProperty_SUMMARY, self.mSummary)
            valarm.addProperty(prop)

            for iter in self.mAttendees:
                prop = Property(definitions.cICalProperty_ATTENDEE, iter, Value.VALUETYPE_CALADDRESS)
                valarm.addProperty(prop)
Example #4
0
    def editRepeats(self, repeat, interval):
        # Remove existing
        self.removeProperties(definitions.cICalProperty_REPEAT)
        self.removeProperties(definitions.cICalProperty_DURATION)

        # Updated cached values
        self.mRepeats = repeat
        self.mRepeatInterval = interval

        # Add new
        if self.mRepeats > 0:
            self.addProperty(Property(definitions.cICalProperty_REPEAT, repeat))
            self.addProperty(Property(definitions.cICalProperty_DURATION, interval))
    def testUnknownValueRoundtrip(self):

        data = "X-FOO:Text, not escaped"
        prop = Property.parseText(data)
        self.assertEqual(str(prop), data + "\r\n")

        prop = Property("X-FOO", "Text, not escaped")
        self.assertEqual(str(prop), data + "\r\n")

        data = "X-FOO:Text\\, escaped\\n"
        prop = Property.parseText(data)
        self.assertEqual(str(prop), data + "\r\n")

        prop = Property("X-FOO", "Text\\, escaped\\n")
        self.assertEqual(str(prop), data + "\r\n")
Example #6
0
    def testUnknownValueRoundtrip(self):

        data = "X-FOO:Text, not escaped"
        prop = Property.parseText(data)
        self.assertEqual(str(prop), data + "\r\n")

        prop = Property("X-FOO", "Text, not escaped")
        self.assertEqual(str(prop), data + "\r\n")

        data = "X-FOO:Text\\, escaped\\n"
        prop = Property.parseText(data)
        self.assertEqual(str(prop), data + "\r\n")

        prop = Property("X-FOO", "Text\\, escaped\\n")
        self.assertEqual(str(prop), data + "\r\n")
Example #7
0
    def editStatus(self, status):
        # Only if it is different
        if self.mStatus != status:
            # Updated cached values
            self.mStatus = status

            # Remove existing STATUS items
            self.removeProperties(definitions.cICalProperty_STATUS)

            # Now create properties
            value = None
            if status == definitions.eStatus_VEvent_None:
                pass
            elif status == definitions.eStatus_VEvent_Tentative:
                value = definitions.cICalProperty_STATUS_TENTATIVE
            elif status == definitions.eStatus_VEvent_Confirmed:
                value = definitions.cICalProperty_STATUS_CONFIRMED
            elif status == definitions.eStatus_VEvent_Cancelled:
                value = definitions.cICalProperty_STATUS_CANCELLED
            else:
                pass

            if value is not None:
                prop = Property(definitions.cICalProperty_STATUS, value)
                self.addProperty(prop)
Example #8
0
        def add(self, valarm):
            # Delete existing then add
            self.remove(valarm)

            prop = Property(definitions.cICalProperty_DESCRIPTION,
                            self.mDescription)
            valarm.addProperty(prop)
Example #9
0
 def check_cardinality_STATUS_Fix(self, fixed, unfixed, doFix):
     """
     Special for bug with STATUS where STATUS:CANCELLED is added alongside
     another STATUS. In this case we want STATUS:CANCELLED to win.
     """
     for propname in self.propertyCardinality_STATUS_Fix:
         if self.countProperty(propname) > 1:
             logProblem = "[%s] Too many properties: %s" % (self.getType(),
                                                            propname)
             if doFix:
                 # Check that one of them is STATUS:CANCELLED
                 for prop in self.getProperties(propname):
                     if prop.getTextValue().getValue().upper(
                     ) == definitions.cICalProperty_STATUS_CANCELLED:
                         self.removeProperties(propname)
                         self.addProperty(
                             Property(
                                 propname, definitions.
                                 cICalProperty_STATUS_CANCELLED))
                         fixed.append(logProblem)
                         break
                 else:
                     unfixed.append(logProblem)
             else:
                 unfixed.append(logProblem)
Example #10
0
    def setSeq(self, seq):
        self.mSeq = seq

        self.removeProperties(definitions.cICalProperty_SEQUENCE)

        prop = Property(definitions.cICalProperty_SEQUENCE, self.mSeq)
        self.addProperty(prop)
Example #11
0
        def add(self, valarm):
            # Delete existing then add
            self.remove(valarm)

            prop = Property(definitions.cICalProperty_ACTION_X_SPEAKTEXT,
                            self.mSpeakText)
            valarm.addProperty(prop)
Example #12
0
    def test_positiveIntegerOrZero(self):

        props = (
            (
                "SUMMARY:Test",
                False,
            ),
            (
                "REPEAT:0",
                True,
            ),
            (
                "REPEAT:100",
                True,
            ),
            (
                "REPEAT:-1",
                False,
            ),
        )

        for prop, result in props:
            property = Property.parseText(prop)
            self.assertEqual(
                PropertyValueChecks.positiveIntegerOrZero(property), result)
Example #13
0
    def testParseGenerate(self):

        for data in TestJSONProperty.test_data:
            prop = Property.parseJSON(data)
            jobject = []
            prop.writeJSON(jobject)
            self.assertEqual(jobject[0], data, "Failed parse/generate: %s to %s" % (data, jobject[0],))
Example #14
0
    def testParameterEncodingDecoding(self):

        prop = Property("X-FOO", "Test")
        prop.addParameter(Parameter("X-BAR", "\"Check\""))
        self.assertEqual(str(prop), "X-FOO;X-BAR=^'Check^':Test\r\n")

        prop.addParameter(Parameter("X-BAR2", "Check\nThis\tOut\n"))
        self.assertEqual(str(prop), "X-FOO;X-BAR=^'Check^';X-BAR2=Check^nThis\tOut^n:Test\r\n")

        data = "X-FOO;X-BAR=^'Check^':Test"
        prop = Property.parseText(data)
        self.assertEqual(prop.getParameterValue("X-BAR"), "\"Check\"")

        data = "X-FOO;X-BAR=^'Check^';X-BAR2=Check^nThis\tOut^n:Test"
        prop = Property.parseText(data)
        self.assertEqual(prop.getParameterValue("X-BAR"), "\"Check\"")
        self.assertEqual(prop.getParameterValue("X-BAR2"), "Check\nThis\tOut\n")
Example #15
0
    def editTriggerBy(self, duration, trigger_start):
        # Remove existing
        self.removeProperties(definitions.cICalProperty_TRIGGER)

        # Updated cached values
        self.mTriggerAbsolute = False
        self.mTriggerBy = duration
        self.mTriggerOnStart = trigger_start

        # Add new (with parameter)
        prop = Property(definitions.cICalProperty_TRIGGER, duration)
        attr = Parameter(
            definitions.cICalParameter_RELATED,
            (definitions.cICalParameter_RELATED_START,
             definitions.cICalParameter_RELATED_END)[not trigger_start])
        prop.addParameter(attr)
        self.addProperty(prop)
Example #16
0
    def testHash(self):

        hashes = []
        for item in TestProperty.test_data:
            prop = Property.parseText(item)
            hashes.append(hash(prop))
        hashes.sort()
        for i in range(1, len(hashes)):
            self.assertNotEqual(hashes[i - 1], hashes[i])
Example #17
0
        def _doNonEquality(caldata):
            cal1 = Calendar()
            cal1.parse(StringIO.StringIO(caldata))

            cal2 = Calendar()
            cal2.parse(StringIO.StringIO(caldata))
            cal2.addProperty(Property("X-FOO", "BAR"))

            self.assertNotEqual(cal1, cal2)
Example #18
0
    def testHash(self):

        hashes = []
        for item in TestProperty.test_data:
            prop = Property.parseText(item)
            hashes.append(hash(prop))
        hashes.sort()
        for i in range(1, len(hashes)):
            self.assertNotEqual(hashes[i - 1], hashes[i])
Example #19
0
    def sample(self):

        if self._allowRecurrence:
            index = self._helperDistribution.sample()
            rrule = self._rrules[index]
            if rrule:
                prop = Property.parseText(rrule)
                return prop

        return None
Example #20
0
    def excludeFutureRecurrence(self, start):
        # Must have items
        if self.mRecurrences is None:
            return

        # Adjust RRULES to end before start
        self.mRecurrences.excludeFutureRecurrence(start)

        # Remove existing RRULE & RDATE
        self.removeProperties(definitions.cICalProperty_RRULE)
        self.removeProperties(definitions.cICalProperty_RDATE)

        # Now create properties
        for iter in self.mRecurrences.getRules():
            prop = Property(definitions.cICalProperty_RRULE, iter)
            self.addProperty(prop)
        for iter in self.mRecurrences.getDates():
            prop = Property(definitions.cICalProperty_RDATE, iter)
            self.addProperty(prop)
Example #21
0
    def testParseGenerate(self):

        for data in TestProperty.test_data:
            prop = Property.parseText(data)
            propstr = str(prop).replace("\r\n ", "")
            self.assertEqual(
                propstr[:-2], data, "Failed parse/generate: %s to %s" % (
                    data,
                    propstr,
                ))
Example #22
0
    def testParseProperty(self):

        items = (
            ("GEO:-12.345;67.890", "GEO:-12.345;67.89"),
            ("GEO:-12.345\\;67.890", "GEO:-12.345;67.89"),
        )

        for item, result in items:
            prop = Property.parseText(item)
            test = prop.getText()
            self.assertEqual(test, result + "\r\n", "Failed to parse and re-generate '%s'" % (item,))
Example #23
0
    def editName(self, name):
        if self.mName != name:
            # Updated cached value
            self.mName = name

            # Remove existing items
            self.removeProperties(definitions.cICalProperty_XWRCALNAME)

            # Now create properties
            if len(name):
                self.ddProperty(Property(definitions.cICalProperty_XWRCALNAME, name))
Example #24
0
    def editDescription(self, description):
        if self.mDescription != description:
            # Updated cached value
            self.mDescription = description

            # Remove existing items
            self.removeProperties(definitions.cICalProperty_XWRCALDESC)

            # Now create properties
            if len(description):
                self.addProperty(Property(definitions.cICalProperty_XWRCALDESC, description))
Example #25
0
    def editTriggerOn(self, dt):
        # Remove existing
        self.removeProperties(definitions.cICalProperty_TRIGGER)

        # Updated cached values
        self.mTriggerAbsolute = True
        self.mTriggerOn = dt

        # Add new
        prop = Property(definitions.cICalProperty_TRIGGER, dt)
        self.addProperty(prop)
Example #26
0
    def testParseGenerate(self):

        for data in TestJSONProperty.test_data:
            prop = Property.parseJSON(data)
            jobject = []
            prop.writeJSON(jobject)
            self.assertEqual(
                jobject[0], data, "Failed parse/generate: %s to %s" % (
                    data,
                    jobject[0],
                ))
Example #27
0
    def excludeRecurrence(self, start):
        # Must have items
        if self.mRecurrences is None:
            return

        # Add to recurrence set and clear cache
        self.mRecurrences.subtract(start)

        # Add property
        prop = Property(definitions.cICalProperty_EXDATE, start)
        self.addProperty(prop)
Example #28
0
    def test_stringValue(self):

        props = (
            ("SUMMARY:Test", "Test", True,),
            ("SUMMARY:Test", "TEST", True,),
            ("DTSTART:20110623T174806", "Test", False),
        )

        for prop, test, result in props:
            property = Property.parseText(prop)
            self.assertEqual(PropertyValueChecks.stringValue(test, property), result)
Example #29
0
    def editTriggerBy(self, duration, trigger_start):
        # Remove existing
        self.removeProperties(definitions.cICalProperty_TRIGGER)

        # Updated cached values
        self.mTriggerAbsolute = False
        self.mTriggerBy = duration
        self.mTriggerOnStart = trigger_start

        # Add new (with parameter)
        prop = Property(definitions.cICalProperty_TRIGGER, duration)
        attr = Parameter(
            definitions.cICalParameter_RELATED,
            (
                definitions.cICalParameter_RELATED_START,
                definitions.cICalParameter_RELATED_END
            )[not trigger_start]
        )
        prop.addParameter(attr)
        self.addProperty(prop)
Example #30
0
    def testParseProperty(self):

        items = (
            ("GEO:-12.345;67.890", "GEO:-12.345;67.89"),
            ("GEO:-12.345\\;67.890", "GEO:-12.345;67.89"),
        )

        for item, result in items:
            prop = Property.parseText(item)
            test = prop.getText()
            self.assertEqual(test, result + "\r\n",
                             "Failed to parse and re-generate '%s'" % (item, ))
Example #31
0
    def test_alwaysUTC(self):

        props = (
            ("SUMMARY:Test", False,),
            ("DTSTART:20110623T174806", False),
            ("DTSTART;VALUE=DATE:20110623", False),
            ("DTSTART:20110623T174806Z", True),
        )

        for prop, result in props:
            property = Property.parseText(prop)
            self.assertEqual(PropertyValueChecks.alwaysUTC(property), result)
Example #32
0
    def editCompleted(self, completed):
        # Remove existing COMPLETED item
        self.removeProperties(definitions.cICalProperty_COMPLETED)
        self.mHasCompleted = False

        # Always UTC
        self.mCompleted = completed.duplicate()
        self.mCompleted.adjustToUTC()
        self.mHasCompleted = True
        prop = Property(definitions.cICalProperty_STATUS_COMPLETED,
                        self.mCompleted)
        self.addProperty(prop)
Example #33
0
    def test_positiveIntegerOrZero(self):

        props = (
            ("SUMMARY:Test", False,),
            ("REPEAT:0", True,),
            ("REPEAT:100", True,),
            ("REPEAT:-1", False,),
        )

        for prop, result in props:
            property = Property.parseText(prop)
            self.assertEqual(PropertyValueChecks.positiveIntegerOrZero(property), result)
Example #34
0
    def testDefaultValueCreate(self):

        test_data = (
            ("ATTENDEE", "mailto:[email protected]", "ATTENDEE:mailto:[email protected]\r\n"),
            ("ATTENDEE", u"mailto:[email protected]", "ATTENDEE:mailto:[email protected]\r\n"),
            ("attendee", "mailto:[email protected]", "attendee:mailto:[email protected]\r\n"),
            ("ORGANIZER", "mailto:[email protected]", "ORGANIZER:mailto:[email protected]\r\n"),
            ("ORGANizer", "mailto:[email protected]", "ORGANizer:mailto:[email protected]\r\n"),
            ("URL", "http://example.com/tz1", "URL:http://example.com/tz1\r\n"),
            ("TZURL", "http://example.com/tz2", "TZURL:http://example.com/tz2\r\n"),
        )
        for propname, propvalue, result in test_data:
            prop = Property(name=propname, value=propvalue)
            self.assertEqual(str(prop), result)
    def testParseProperty(self):

        items = (
            "REQUEST-STATUS:2.0;Success",
            "REQUEST-STATUS:2.0;Success\;here",
            "REQUEST-STATUS:2.0;Success;Extra",
            "REQUEST-STATUS:2.0;Success\;here;Extra",
            "REQUEST-STATUS:2.0;Success;Extra\;here",
            "REQUEST-STATUS:2.0;Success\;here;Extra\;here too",
        )

        for item in items:
            req = Property.parseText(item)
            self.assertEqual(req.getText(), item + "\r\n", "Failed to parse and re-generate '%s'" % (item,))
Example #36
0
    def test_numericRange(self):

        props = (
            ("SUMMARY:Test", 0, 100, False,),
            ("PERCENT-COMPLETE:0", 0, 100, True,),
            ("PERCENT-COMPLETE:100", 0, 100, True,),
            ("PERCENT-COMPLETE:50", 0, 100, True,),
            ("PERCENT-COMPLETE:200", 0, 100, False,),
            ("PERCENT-COMPLETE:-1", 0, 100, False,),
        )

        for prop, low, high, result in props:
            property = Property.parseText(prop)
            self.assertEqual(PropertyValueChecks.numericRange(low, high, property), result)
Example #37
0
    def editTimingStartDuration(self, start, duration):
        # Updated cached values
        self.mHasStart = True
        self.mHasEnd = False
        self.mStart = start
        self.mEnd = start + duration
        self.mDuration = True

        # Remove existing DTSTART & DTEND & DURATION & DUE items
        self.removeProperties(definitions.cICalProperty_DTSTART)
        self.removeProperties(definitions.cICalProperty_DTEND)
        self.removeProperties(definitions.cICalProperty_DURATION)
        self.removeProperties(definitions.cICalProperty_DUE)

        # Now create properties
        prop = Property(definitions.cICalProperty_DTSTART, start)
        self.addProperty(prop)

        # If its an all day event and the duration is one day, ignore it
        if (not start.isDateOnly() or (duration.getWeeks() != 0)
                or (duration.getDays() > 1)):
            prop = Property(definitions.cICalProperty_DURATION, duration)
            self.addProperty(prop)
Example #38
0
    def editTimingStartEnd(self, start, end):
        # Updated cached values
        self.mHasStart = self.mHasEnd = True
        self.mStart = start
        self.mEnd = end
        self.mDuration = False
        self.FixStartEnd()
        # Remove existing DTSTART & DTEND & DURATION & DUE items
        self.removeProperties(definitions.cICalProperty_DTSTART)
        self.removeProperties(definitions.cICalProperty_DTEND)
        self.removeProperties(definitions.cICalProperty_DURATION)
        self.removeProperties(definitions.cICalProperty_DUE)

        # Now create properties
        prop = Property(definitions.cICalProperty_DTSTART, start)
        self.addProperty(prop)

        # If its an all day event and the end one day after the start, ignore it
        temp = start.duplicate()
        temp.offsetDay(1)
        if not start.isDateOnly() or end != temp:
            prop = Property(definitions.cICalProperty_DTEND, end)
            self.addProperty(prop)
Example #39
0
    def test_alwaysUTC(self):

        props = (
            (
                "SUMMARY:Test",
                False,
            ),
            ("DTSTART:20110623T174806", False),
            ("DTSTART;VALUE=DATE:20110623", False),
            ("DTSTART:20110623T174806Z", True),
        )

        for prop, result in props:
            property = Property.parseText(prop)
            self.assertEqual(PropertyValueChecks.alwaysUTC(property), result)
Example #40
0
    def editStatus(self, status):
        # Remove existing
        self.removeProperties(definitions.cICalProperty_ALARM_X_ALARMSTATUS)

        # Updated cached values
        self.mAlarmStatus = status

        # Add new
        status_txt = ""
        if self.mAlarmStatus == definitions.eAlarm_Status_Pending:
            status_txt = definitions.cICalProperty_ALARM_X_ALARMSTATUS_PENDING
        elif self.mAlarmStatus == definitions.eAlarm_Status_Completed:
            status_txt = definitions.cICalProperty_ALARM_X_ALARMSTATUS_COMPLETED
        elif self.mAlarmStatus == definitions.eAlarm_Status_Disabled:
            status_txt = definitions.cICalProperty_ALARM_X_ALARMSTATUS_DISABLED
        self.addProperty(Property(definitions.cICalProperty_ALARM_X_ALARMSTATUS, status_txt))
Example #41
0
    def editTimingDue(self, due):
        # Updated cached values
        self.mHasStart = False
        self.mHasEnd = True
        self.mDuration = False
        self.mStart = due
        self.mEnd = due

        # Remove existing DUE & DTSTART & DTEND & DURATION items
        self.removeProperties(definitions.cICalProperty_DUE)
        self.removeProperties(definitions.cICalProperty_DTSTART)
        self.removeProperties(definitions.cICalProperty_DTEND)
        self.removeProperties(definitions.cICalProperty_DURATION)

        # Now create properties
        prop = Property(definitions.cICalProperty_DUE, due)
        self.addProperty(prop)
Example #42
0
    def editAction(self, action, data):
        # Remove existing
        self.removeProperties(definitions.cICalProperty_ACTION)
        self.mActionData.remove(self)
        self.mActionData = None

        # Updated cached values
        self.mAction = action
        self.mActionData = data

        # Add new properties to alarm
        action_txt = VAlarm.sActionValueMap.get(self.mAction, definitions.cICalProperty_ACTION_PROCEDURE)

        prop = Property(definitions.cICalProperty_ACTION, action_txt)
        self.addProperty(prop)

        self.mActionData.add(self)
Example #43
0
    def testEquality(self):

        for data in TestProperty.test_data:
            prop1 = Property.parseText(data)
            prop2 = Property.parseText(data)
            self.assertEqual(prop1, prop2, "Failed equality: %s" % (data,))
Example #44
0
import twistedcaldav.customxml
import twistedcaldav.timezonexml

twistedcaldav # Shhh.. pyflakes

#
# DefaultHTTPHandler
#

from txweb2.http_headers import DefaultHTTPHandler, last, singleHeader

DefaultHTTPHandler.updateParsers({
    "If-Schedule-Tag-Match": (last, str),
})
DefaultHTTPHandler.updateGenerators({
    "Schedule-Tag": (str, singleHeader),
})

# Do some PyCalendar init
from pycalendar.icalendar.calendar import Calendar
from pycalendar.icalendar.property import Property
from pycalendar.vcard.card import Card
from pycalendar.value import Value

Calendar.setPRODID("-//CALENDARSERVER.ORG//NONSGML Version 1//EN")
Card.setPRODID("-//CALENDARSERVER.ORG//NONSGML Version 1//EN")

# These are properties we use directly and we want the default value type set for TEXT
Property.registerDefaultValue("X-CALENDARSERVER-PRIVATE-COMMENT", Value.VALUETYPE_TEXT)
Property.registerDefaultValue("X-CALENDARSERVER-ATTENDEE-COMMENT", Value.VALUETYPE_TEXT)
Example #45
0
    def testGEOValueRoundtrip(self):

        data = "GEO:123.456;789.101"
        prop = Property.parseText(data)
        self.assertEqual(str(prop), data + "\r\n")
Example #46
0
    def testParseGenerate(self):

        for data in TestProperty.test_data:
            prop = Property.parseText(data)
            propstr = str(prop).replace("\r\n ", "")
            self.assertEqual(propstr[:-2], data, "Failed parse/generate: %s to %s" % (data, propstr,))
Example #47
0
#
# DefaultHTTPHandler
#

from txweb2.http_headers import DefaultHTTPHandler, last, singleHeader

DefaultHTTPHandler.updateParsers({
    "If-Schedule-Tag-Match": (last, str),
})
DefaultHTTPHandler.updateGenerators({
    "Schedule-Tag": (str, singleHeader),
})

# Do some PyCalendar init
from pycalendar.icalendar.calendar import Calendar
from pycalendar.icalendar.property import Property
from pycalendar.vcard.card import Card
from pycalendar.value import Value

Calendar.setPRODID("-//CALENDARSERVER.ORG//NONSGML Version 1//EN")
Card.setPRODID("-//CALENDARSERVER.ORG//NONSGML Version 1//EN")

# These are properties we use directly and we want the default value type set for TEXT
Property.registerDefaultValue("X-CALENDARSERVER-PRIVATE-COMMENT", Value.VALUETYPE_TEXT)
Property.registerDefaultValue("X-CALENDARSERVER-ATTENDEE-COMMENT", Value.VALUETYPE_TEXT)

Property.registerDefaultValue("X-APPLE-TRAVEL-DURATION", Value.VALUETYPE_DURATION, always_write_value=True)
Property.registerDefaultValue("X-APPLE-TRAVEL-START", Value.VALUETYPE_DATETIME, always_write_value=True)
Property.registerDefaultValue("X-APPLE-TRAVEL-RETURN-DURATION", Value.VALUETYPE_DURATION, always_write_value=True)
Property.registerDefaultValue("X-APPLE-TRAVEL-RETURN", Value.VALUETYPE_DATETIME, always_write_value=True)