[CalendarServer-changes] [7239] CalendarServer/trunk

source_changes at macosforge.org source_changes at macosforge.org
Wed Mar 23 06:49:12 PDT 2011


Revision: 7239
          http://trac.macosforge.org/projects/calendarserver/changeset/7239
Author:   cdaboo at apple.com
Date:     2011-03-23 06:49:12 -0700 (Wed, 23 Mar 2011)
Log Message:
-----------
pycalendar vcard support.

Modified Paths:
--------------
    CalendarServer/trunk/calendarserver/tap/util.py
    CalendarServer/trunk/support/build.sh
    CalendarServer/trunk/twistedcaldav/datafilters/__init__.py
    CalendarServer/trunk/twistedcaldav/datafilters/addressdata.py
    CalendarServer/trunk/twistedcaldav/datafilters/calendardata.py
    CalendarServer/trunk/twistedcaldav/datafilters/filter.py
    CalendarServer/trunk/twistedcaldav/datafilters/peruserdata.py
    CalendarServer/trunk/twistedcaldav/datafilters/privateevents.py
    CalendarServer/trunk/twistedcaldav/dateops.py
    CalendarServer/trunk/twistedcaldav/directory/opendirectorybacker.py
    CalendarServer/trunk/twistedcaldav/ical.py
    CalendarServer/trunk/twistedcaldav/query/addressbookqueryfilter.py
    CalendarServer/trunk/twistedcaldav/query/calendarqueryfilter.py
    CalendarServer/trunk/twistedcaldav/scheduling/icaldiff.py
    CalendarServer/trunk/twistedcaldav/scheduling/scheduler.py
    CalendarServer/trunk/twistedcaldav/scheduling/test/test_icaldiff.py
    CalendarServer/trunk/twistedcaldav/test/data/vCards/AFBB77B8-0438-4825-A1DB-A75D76B6C3A8.vcf
    CalendarServer/trunk/twistedcaldav/test/test_icalendar.py
    CalendarServer/trunk/twistedcaldav/timezones.py
    CalendarServer/trunk/twistedcaldav/vcard.py

Removed Paths:
-------------
    CalendarServer/trunk/twext/python/datetime.py
    CalendarServer/trunk/twext/python/test/test_datetime.py

Property Changed:
----------------
    CalendarServer/trunk/
    CalendarServer/trunk/support/build.sh
    CalendarServer/trunk/txdav/caldav/datastore/index_file.py
    CalendarServer/trunk/txdav/caldav/datastore/test/test_index_file.py
    CalendarServer/trunk/txdav/carddav/datastore/index_file.py
    CalendarServer/trunk/txdav/carddav/datastore/test/test_index_file.py


Property changes on: CalendarServer/trunk
___________________________________________________________________
Modified: svn:mergeinfo
   - /CalendarServer/branches/config-separation:4379-4443
/CalendarServer/branches/egg-info-351:4589-4625
/CalendarServer/branches/generic-sqlstore:6167-6191
/CalendarServer/branches/new-store:5594-5934
/CalendarServer/branches/new-store-no-caldavfile:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2:5936-5981
/CalendarServer/branches/users/cdaboo/batchupload-6699:6700-7198
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464:4465-4957
/CalendarServer/branches/users/cdaboo/pycalendar:7085-7206
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187:5188-5440
/CalendarServer/branches/users/glyph/conn-limit:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge:4971-5080
/CalendarServer/branches/users/glyph/dalify:6932-7023
/CalendarServer/branches/users/glyph/db-reconnect:6824-6876
/CalendarServer/branches/users/glyph/dont-start-postgres:6592-6614
/CalendarServer/branches/users/glyph/linux-tests:6893-6900
/CalendarServer/branches/users/glyph/more-deferreds-6:6322-6368
/CalendarServer/branches/users/glyph/more-deferreds-7:6369-6445
/CalendarServer/branches/users/glyph/oracle:7106-7155
/CalendarServer/branches/users/glyph/sendfdport:5388-5424
/CalendarServer/branches/users/glyph/sharedpool:6490-6550
/CalendarServer/branches/users/glyph/sql-store:5929-6073
/CalendarServer/branches/users/glyph/use-system-twisted:5084-5149
/CalendarServer/branches/users/sagen/locations-resources:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2:5052-5061
/CalendarServer/branches/users/sagen/purge_old_events:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066:4068-4075
/CalendarServer/branches/users/sagen/resources-2:5084-5093
/CalendarServer/branches/users/wsanchez/transations:5515-5593
   + /CalendarServer/branches/config-separation:4379-4443
/CalendarServer/branches/egg-info-351:4589-4625
/CalendarServer/branches/generic-sqlstore:6167-6191
/CalendarServer/branches/new-store:5594-5934
/CalendarServer/branches/new-store-no-caldavfile:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2:5936-5981
/CalendarServer/branches/users/cdaboo/batchupload-6699:6700-7198
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464:4465-4957
/CalendarServer/branches/users/cdaboo/pycalendar:7085-7206
/CalendarServer/branches/users/cdaboo/pycard:7227-7237
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187:5188-5440
/CalendarServer/branches/users/glyph/conn-limit:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge:4971-5080
/CalendarServer/branches/users/glyph/dalify:6932-7023
/CalendarServer/branches/users/glyph/db-reconnect:6824-6876
/CalendarServer/branches/users/glyph/dont-start-postgres:6592-6614
/CalendarServer/branches/users/glyph/linux-tests:6893-6900
/CalendarServer/branches/users/glyph/more-deferreds-6:6322-6368
/CalendarServer/branches/users/glyph/more-deferreds-7:6369-6445
/CalendarServer/branches/users/glyph/oracle:7106-7155
/CalendarServer/branches/users/glyph/sendfdport:5388-5424
/CalendarServer/branches/users/glyph/sharedpool:6490-6550
/CalendarServer/branches/users/glyph/sql-store:5929-6073
/CalendarServer/branches/users/glyph/use-system-twisted:5084-5149
/CalendarServer/branches/users/sagen/locations-resources:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2:5052-5061
/CalendarServer/branches/users/sagen/purge_old_events:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066:4068-4075
/CalendarServer/branches/users/sagen/resources-2:5084-5093
/CalendarServer/branches/users/wsanchez/transations:5515-5593

Modified: CalendarServer/trunk/calendarserver/tap/util.py
===================================================================
--- CalendarServer/trunk/calendarserver/tap/util.py	2011-03-23 13:44:50 UTC (rev 7238)
+++ CalendarServer/trunk/calendarserver/tap/util.py	2011-03-23 13:49:12 UTC (rev 7239)
@@ -39,6 +39,7 @@
 
 from twisted.cred.portal import Portal
 from twisted.internet.defer import inlineCallbacks, returnValue
+from twisted.internet import reactor as _reactor
 from twisted.internet.reactor import addSystemEventTrigger
 from twisted.internet.tcp import Connection
 from twisted.python.reflect import namedClass
@@ -440,7 +441,10 @@
             directoryBackedAddressBookCollection = directoryBackedAddressBookResourceClass(
                 principalCollections=(principalCollection,)
             )
-            addSystemEventTrigger("after", "startup", directoryBackedAddressBookCollection.provisionDirectory)
+            if _reactor._started:
+                directoryBackedAddressBookCollection.provisionDirectory()
+            else:
+                addSystemEventTrigger("after", "startup", directoryBackedAddressBookCollection.provisionDirectory)
         else:
             # remove /directory from previous runs that may have created it
             try:

Modified: CalendarServer/trunk/support/build.sh
===================================================================
--- CalendarServer/trunk/support/build.sh	2011-03-23 13:44:50 UTC (rev 7238)
+++ CalendarServer/trunk/support/build.sh	2011-03-23 13:49:12 UTC (rev 7239)
@@ -644,7 +644,7 @@
     "http://svn.osafoundation.org/vobject/trunk";
 
   # XXX actually PyCalendar should be imported in-place.
-  py_dependency -fe -i "src" -r 144 \
+  py_dependency -fe -i "src" -r 147 \
     "pycalendar" "pycalendar" "pycalendar" \
     "http://svn.mulberrymail.com/repos/PyCalendar/branches/server";
 


Property changes on: CalendarServer/trunk/support/build.sh
___________________________________________________________________
Modified: svn:mergeinfo
   - /CalendarServer/branches/config-separation/support/build.sh:4379-4443
/CalendarServer/branches/egg-info-351/support/build.sh:4589-4615
/CalendarServer/branches/generic-sqlstore/support/build.sh:6167-6191
/CalendarServer/branches/new-store-no-caldavfile-2/support/build.sh:5936-5981
/CalendarServer/branches/new-store-no-caldavfile/support/build.sh:5911-5935
/CalendarServer/branches/new-store/support/build.sh:5594-5934
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/support/build.sh:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/support/build.sh:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591/support/build.sh:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/support/build.sh:4465-4957
/CalendarServer/branches/users/cdaboo/pycalendar/support/build.sh:7085-7206
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/support/build.sh:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/support/build.sh:5188-5440
/CalendarServer/branches/users/glyph/conn-limit/support/build.sh:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge/support/build.sh:4971-5080
/CalendarServer/branches/users/glyph/dalify/support/build.sh:6932-7023
/CalendarServer/branches/users/glyph/db-reconnect/support/build.sh:6824-6876
/CalendarServer/branches/users/glyph/dont-start-postgres/support/build.sh:6592-6614
/CalendarServer/branches/users/glyph/linux-tests/support/build.sh:6893-6900
/CalendarServer/branches/users/glyph/more-deferreds-6/support/build.sh:6322-6368
/CalendarServer/branches/users/glyph/more-deferreds-7/support/build.sh:6369-6445
/CalendarServer/branches/users/glyph/sendfdport/support/build.sh:5388-5424
/CalendarServer/branches/users/glyph/sharedpool/support/build.sh:6490-6550
/CalendarServer/branches/users/glyph/sql-store/support/build.sh:5929-6073
/CalendarServer/branches/users/glyph/use-system-twisted/support/build.sh:5084-5149
/CalendarServer/branches/users/sagen/locations-resources-2/support/build.sh:5052-5061
/CalendarServer/branches/users/sagen/locations-resources/support/build.sh:5032-5051
/CalendarServer/branches/users/sagen/purge_old_events/support/build.sh:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038/support/build.sh:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/support/build.sh:4068-4075
/CalendarServer/branches/users/sagen/resources-2/support/build.sh:5084-5093
/CalendarServer/branches/users/wsanchez/transations/support/build.sh:5515-5593
   + /CalendarServer/branches/config-separation/support/build.sh:4379-4443
/CalendarServer/branches/egg-info-351/support/build.sh:4589-4615
/CalendarServer/branches/generic-sqlstore/support/build.sh:6167-6191
/CalendarServer/branches/new-store-no-caldavfile-2/support/build.sh:5936-5981
/CalendarServer/branches/new-store-no-caldavfile/support/build.sh:5911-5935
/CalendarServer/branches/new-store/support/build.sh:5594-5934
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/support/build.sh:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/support/build.sh:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591/support/build.sh:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/support/build.sh:4465-4957
/CalendarServer/branches/users/cdaboo/pycalendar/support/build.sh:7085-7206
/CalendarServer/branches/users/cdaboo/pycard/support/build.sh:7227-7237
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/support/build.sh:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/support/build.sh:5188-5440
/CalendarServer/branches/users/glyph/conn-limit/support/build.sh:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge/support/build.sh:4971-5080
/CalendarServer/branches/users/glyph/dalify/support/build.sh:6932-7023
/CalendarServer/branches/users/glyph/db-reconnect/support/build.sh:6824-6876
/CalendarServer/branches/users/glyph/dont-start-postgres/support/build.sh:6592-6614
/CalendarServer/branches/users/glyph/linux-tests/support/build.sh:6893-6900
/CalendarServer/branches/users/glyph/more-deferreds-6/support/build.sh:6322-6368
/CalendarServer/branches/users/glyph/more-deferreds-7/support/build.sh:6369-6445
/CalendarServer/branches/users/glyph/sendfdport/support/build.sh:5388-5424
/CalendarServer/branches/users/glyph/sharedpool/support/build.sh:6490-6550
/CalendarServer/branches/users/glyph/sql-store/support/build.sh:5929-6073
/CalendarServer/branches/users/glyph/use-system-twisted/support/build.sh:5084-5149
/CalendarServer/branches/users/sagen/locations-resources-2/support/build.sh:5052-5061
/CalendarServer/branches/users/sagen/locations-resources/support/build.sh:5032-5051
/CalendarServer/branches/users/sagen/purge_old_events/support/build.sh:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038/support/build.sh:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/support/build.sh:4068-4075
/CalendarServer/branches/users/sagen/resources-2/support/build.sh:5084-5093
/CalendarServer/branches/users/wsanchez/transations/support/build.sh:5515-5593

Deleted: CalendarServer/trunk/twext/python/datetime.py
===================================================================
--- CalendarServer/trunk/twext/python/datetime.py	2011-03-23 13:44:50 UTC (rev 7238)
+++ CalendarServer/trunk/twext/python/datetime.py	2011-03-23 13:49:12 UTC (rev 7239)
@@ -1,312 +0,0 @@
-##
-# Copyright (c) 2006-2010 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.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-
-"""
-Date/time Utilities
-"""
-
-__all__ = [
-    "utc",
-    "tzWithID",
-    "dateordatetime",
-    "timerange",
-    "asTimeZone",
-    "iCalendarString",
-]
-
-date     = __import__("datetime").date
-datetime = __import__("datetime").datetime
-
-from vobject.icalendar import dateTimeToString, dateToString
-from vobject.icalendar import utc
-
-
-# FIXME, add constants for begining/end of time
-
-class dateordatetime(object):
-    def __init__(self, dateOrDatetime, defaultTZ=None):
-        """
-        @param dateOrDatetime: a L{date} or L{datetime}.
-        """
-        assert dateOrDatetime is not None, "dateOrDatetime is None"
-
-        self._dateOrDatetime = dateOrDatetime
-        if isinstance(dateOrDatetime, datetime):
-            self._isDatetime = True
-        else:
-            assert isinstance(dateOrDatetime, date)
-            self._isDatetime = False
-        self.defaultTZ = defaultTZ
-
-    def __repr__(self):
-        return "dateordatetime(%r)" % (self._dateOrDatetime,)
-
-    def _comparableDatetimes(self, other):
-        if not isinstance(other, dateordatetime):
-            other = dateordatetime(other)
-
-        dt1, dt2 = self.datetime(), other.datetime()
-
-        def getTZInfo(tz):
-            for defaultTZ in (self.defaultTZ, other.defaultTZ):
-                if defaultTZ is not None:
-                    return defaultTZ
-                return tz
-
-        if dt1.tzinfo is None and dt2.tzinfo is not None:
-            dt1 = dt1.replace(tzinfo=getTZInfo(dt2.tzinfo))
-        elif dt1.tzinfo is not None and dt2.tzinfo is None:
-            dt2 = dt2.replace(tzinfo=getTZInfo(dt1.tzinfo))
-
-        return dt1, dt2
-
-    def __eq__(self, other):
-        if isinstance(other, dateordatetime):
-            other = other.dateOrDatetime()
-        dt1, dt2 = self._comparableDatetimes(other)
-        return dt1 == dt2
-
-    def __ne__(self, other):
-        if isinstance(other, dateordatetime):
-            other = other.dateOrDatetime()
-        dt1, dt2 = self._comparableDatetimes(other)
-        return dt1 != dt2
-
-    def __lt__(self, other):
-        if not isinstance(other, comparableTypes):
-            return NotImplemented
-        dt1, dt2 = self._comparableDatetimes(other)
-        return dt1 < dt2
-
-    def __le__(self, other):
-        if not isinstance(other, comparableTypes):
-            return NotImplemented
-        dt1, dt2 = self._comparableDatetimes(other)
-        return dt1 <= dt2
-
-    def __gt__(self, other):
-        if not isinstance(other, comparableTypes):
-            return NotImplemented
-        dt1, dt2 = self._comparableDatetimes(other)
-        return dt1 > dt2
-
-    def __ge__(self, other):
-        if not isinstance(other, comparableTypes):
-            return NotImplemented
-        dt1, dt2 = self._comparableDatetimes(other)
-        return dt1 >= dt2
-
-    def __hash__(self):
-        return self._dateOrDatetime.__hash__()
-
-    def __sub__(self, other):
-        if not isinstance(other, (date, datetime, dateordatetime)):
-            return NotImplemented
-
-        dt1, dt2 = self._comparableDatetimes(other)
-        return dt1 - dt2
-
-    def timetuple(self):
-        #
-        # This attribute is required in order to allow comparisions
-        # against dates and datetimes in Python 2.x.
-        #
-        # See:
-        #   http://bugs.python.org/issue8005#msg104333
-        #   http://docs.python.org/library/datetime.html#datetime.date.timetuple
-        #
-        return self.datetime().timetuple()
-
-    def date(self):
-        if self._isDatetime:
-            return self._dateOrDatetime.date()
-        else:
-            return self._dateOrDatetime
-
-    def datetime(self):
-        if self._isDatetime:
-            return self._dateOrDatetime
-        else:
-            d = self._dateOrDatetime
-            return datetime(d.year, d.month, d.day, tzinfo=self.defaultTZ)
-
-    def dateOrDatetime(self):
-        return self._dateOrDatetime
-
-    def timetuple(self):
-        #
-        # This is required to make comparison with datetimes work. See:
-        # http://bugs.python.org/issue8005
-        # http://docs.python.org/release/2.6.5/library/datetime.html#datetime.date.day
-        #
-        return self._dateOrDatetime.timetuple()
-
-    def iCalendarString(self):
-        if self._isDatetime:
-            return dateTimeToString(self._dateOrDatetime)
-        else:
-            return dateToString(self._dateOrDatetime)
-
-    def asTimeZone(self, tzinfo):
-        if self._isDatetime:
-            d = self._dateOrDatetime
-            if d.tzinfo is None:
-                return self
-            else:
-                return self.__class__(d.astimezone(tzinfo))
-        else:
-            return self
-
-    def asUTC(self):
-        return self.asTimeZone(utc)
-
-comparableTypes = (date, datetime, dateordatetime)
-
-
-class timerange(object):
-    def __init__(self, start=None, end=None, duration=None):
-        """
-        @param start: a L{dateordatetime}, L{date} or L{datetime}
-        @param end: a L{dateordatetime}, L{date} or L{datetime}
-        @param duration: a L{timedelta}, L{date} or L{datetime}
-        @param tzinfo: a L{tzinfo}
-        """
-        assert end is None or duration is None, "end or duration must be None"
-
-        if start is None or isinstance(start, dateordatetime):
-            self._start = start
-        else:
-            self._start = dateordatetime(start)
-
-        if end is not None:
-            if isinstance(end, dateordatetime):
-                self._end = end
-            else:
-                self._end = dateordatetime(end)
-
-        if duration is not None:
-            self._duration = duration
-
-    def __repr__(self):
-        return "timerange(%r, %s)" % (self.start(), self.end())
-
-    def __eq__(self, other):
-        if not isinstance(other, timerange):
-            return NotImplemented
-        if self.start() != other.start():
-            return False
-        return self.end() == other.end()
-
-    def __ne__(self, other):
-        return not self.__eq__(other)
-
-    def __lt__(self, other):
-        if not isinstance(other, timerange):
-            return NotImplemented
-        if self.start() == other.start():
-            return self.end() < other.end()
-        else:
-            return self.start() < other.start()
-
-    def __le__(self, other):
-        if not isinstance(other, timerange):
-            return NotImplemented
-        if self.start() == other.start():
-            return self.end() <= other.end()
-        else:
-            return self.start() <= other.start()
-
-    def __gt__(self, other):
-        if not isinstance(other, timerange):
-            return NotImplemented
-        if self.start() == other.start():
-            return self.end() > other.end()
-        else:
-            return self.start() > other.start()
-
-    def __ge__(self, other):
-        if not isinstance(other, timerange):
-            return NotImplemented
-        if self.start() == other.start():
-            return self.end() >= other.end()
-        else:
-            return self.start() >= other.start()
-
-    def __hash__(self, other):
-        return hash((self.start(), self.end()))
-
-    def start(self):
-        return self._start
-
-    def end(self):
-        if getattr(self, "_end", None) is None:
-            start = getattr(self, "_start", None)
-            duration = getattr(self, "_duration", None)
-            if start is None or duration is None:
-                self._end = None
-            else:
-                self._end = dateordatetime(self._start.dateOrDatetime() + self._duration)
-        return self._end
-
-    def duration(self):
-        if getattr(self, "_duration", None) is None:
-            start = getattr(self, "_start", None)
-            end = getattr(self, "_end", None)
-            if start is None or end is None:
-                self._duration = None
-            else:
-                self._duration = self._end - self._start
-        return self._duration
-
-    def overlapsWith(self, other):
-        """
-        Determine whether this time range overlaps with another.
-        """
-        if self.start() is not None and other.start() is not None:
-            if self.end() is not None and other.end() is not None:
-                return self.start() < other.end() and self.end() > other.start()
-            elif self.end() is not None:
-                return other.start() < self.end()
-            elif other.end() is not None:
-                return self.start() >= other.start() and self.start() < other.end()
-            else:
-                return False
-        elif self.start() is not None:
-            return self.start() < other.end()
-        elif other.start() is not None:
-            return self.end() < other.end() and self.end() > other.start()
-        else:
-            return False
-
-
-##
-# Convenience functions
-##
-
-def asTimeZone(pydt, pytz):
-    """
-    Convert a L{PyCalendarDateTime} to the given time zone.
-    """
-    dup = pydt.duplicate()
-    dup.adjustTimezone(pytz)
-    return dup
-
-def iCalendarString(pydt):
-    """
-    Convert a L{PyCalendarDateTime} to a string appropriate for use
-    in an iCalendar property.
-    """
-    return pydt.getText()

Deleted: CalendarServer/trunk/twext/python/test/test_datetime.py
===================================================================
--- CalendarServer/trunk/twext/python/test/test_datetime.py	2011-03-23 13:44:50 UTC (rev 7238)
+++ CalendarServer/trunk/twext/python/test/test_datetime.py	2011-03-23 13:49:12 UTC (rev 7239)
@@ -1,445 +0,0 @@
-##
-# Copyright (c) 2006-2010 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.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-
-from datetime import date, datetime, timedelta
-from dateutil.tz import tzstr
-
-from twisted.internet.defer import DeferredList
-
-from twext.python.datetime import dateordatetime, timerange, utc
-
-from twistedcaldav.test.util import TestCase, featureUnimplemented, testUnimplemented
-
-
-tzUSEastern = tzstr("EST5EDT")
-
-
-def timezones(f):
-    """
-    Decorator for a test to be called with multiple timezones.
-    """
-    return lambda self: DeferredList([
-        d for d in (
-            f(self, tz) for tz in (None, utc, tzUSEastern)
-        ) if d is not None
-    ])
-
-def timeSeries(n):
-    now = datetime.now()
-    for i in range(0, n):
-        dodt = dateordatetime(now + timedelta(days=i))
-        dodt.n = "t%d" %(i+1,)
-        yield dodt
-
-
-class DatetimeTests(TestCase):
-    @testUnimplemented
-    def test_timetuple(self):
-        raise NotImplementedError()
-
-    @timezones
-    def test_date_date(self, tz):
-        d = date.today()
-        dodt = dateordatetime(d, defaultTZ=tz)
-        self.assertEquals(dodt.date(), d)
-
-    @timezones
-    def test_date_datetime(self, tz):
-        d = date.today()
-        dodt = dateordatetime(d, defaultTZ=tz)
-        self.assertEquals(dodt.datetime(), datetime(d.year, d.month, d.day, tzinfo=tz))
-
-    def test_datetime_date(self):
-        dt = datetime.now()
-        dodt = dateordatetime(dt)
-        self.assertEquals(dodt.date(), dt.date())
-
-    @timezones
-    def test_datetime_datetime(self, tz):
-        dt = datetime.now()
-        dodt = dateordatetime(dt, defaultTZ=tz)
-        self.assertEquals(dodt.datetime(), dt)
-
-    def test_compare_date_date(self):
-        return self._test_compare(date, date.today())
-
-    @timezones
-    def test_compare_date_datetime(self, tz):
-        return self._test_compare(date, datetime.now(), tz=tz)
-
-    def test_compare_datetime_date(self):
-        return self._test_compare(datetime, date.today())
-
-    @timezones
-    def test_compare_datetime_datetime(self, tz):
-        return self._test_compare(datetime, datetime.now(), tz=tz)
-
-    def _test_compare(self, baseclass, now, tz=None):
-        first  = dateordatetime(now + timedelta(days=0))
-        second = dateordatetime(now + timedelta(days=1))
-        third  = dateordatetime(now + timedelta(days=2))
-
-        def base(dodt):
-            if tz:
-                return dodt.dateOrDatetime().replace(tzinfo=tz)
-            else:
-                return dodt.dateOrDatetime()
-
-        #
-        # date & datetime's comparators do not correctly return
-        # NotImplemented when they should, which breaks comparison
-        # operators if date/datetime is first.  Boo.  Seriously weak.
-        #
-
-        self.assertTrue (first        == base(first) )
-        self.assertTrue (base(first)  == first       ) # Bug in datetime
-        self.assertTrue (first        == base(first) )
-        self.assertTrue (first        != base(second))
-        self.assertTrue (base(first)  != second      )
-        self.assertTrue (first        != second      )
-        self.assertTrue (first        <  second      )
-        self.assertTrue (second       <  third       )
-        self.assertTrue (first        <  base(second))
-        self.assertTrue (base(second) <  third       ) # Bug in datetime
-        self.assertTrue (first        <  second      )
-        self.assertTrue (second       <  third       )
-        self.assertTrue (base(first)  <  second      )
-        self.assertTrue (second       <  base(third) ) # Bug in datetime
-        self.assertTrue (first        <= second      )
-        self.assertTrue (second       <= third       )
-        self.assertTrue (first        <= base(second))
-        self.assertTrue (base(second) <= third       ) # Bug in datetime
-        self.assertTrue (first        <= base(second))
-        self.assertTrue (base(second) <= third       ) # Bug in datetime
-        self.assertTrue (first        <= second      )
-        self.assertTrue (second       <= third       )
-        self.assertTrue (base(first)  <= second      ) # Bug in datetime
-        self.assertTrue (second       <= base(third) )
-        self.assertFalse(first        >  second      )
-        self.assertFalse(second       >  third       )
-        self.assertFalse(first        >  base(second))
-        self.assertFalse(base(second) >  third       ) # Bug in datetime
-        self.assertFalse(first        >  second      )
-        self.assertFalse(second       >  third       )
-        self.assertFalse(base(first)  >  second      ) # Bug in datetime
-        self.assertFalse(second       >  base(third) )
-        self.assertFalse(first        >= second      )
-        self.assertFalse(second       >= third       )
-        self.assertFalse(first        >= base(second))
-        self.assertFalse(base(second) >= third       ) # Bug in datetime
-        self.assertFalse(first        >= second      )
-        self.assertFalse(second       >= third       )
-        self.assertFalse(base(first)  >= second      ) # Bug in datetime
-        self.assertFalse(second       >= base(third) )
-
-    def test_date_iCalendarString(self):
-        d = date(2010, 2, 22)
-        dodt = dateordatetime(d)
-        self.assertEquals(dodt.iCalendarString(), "20100222")
-
-    def test_datetime_iCalendarString(self):
-        dt = datetime(2010, 2, 22, 17, 44, 42, 98303)
-        dodt = dateordatetime(dt)
-        self.assertEquals(dodt.iCalendarString(), "20100222T174442")
-
-    def test_datetime_iCalendarString_utc(self):
-        dt = datetime(2010, 2, 22, 17, 44, 42, 98303, tzinfo=utc)
-        dodt = dateordatetime(dt)
-        self.assertEquals(dodt.iCalendarString(), "20100222T174442Z")
-
-    def test_datetime_iCalendarString_tz(self):
-        dt = datetime(2010, 2, 22, 17, 44, 42, 98303, tzinfo=tzUSEastern)
-        dodt = dateordatetime(dt)
-        self.assertEquals(dodt.iCalendarString(), "20100222T174442")
-
-    def test_asTimeZone(self):
-        dt = datetime(2010, 2, 22, 17, 44, 42, 98303, tzinfo=utc)
-        asUTC = dateordatetime(dt)
-        asEast = asUTC.asTimeZone(tzUSEastern)
-        self.assertEquals(asEast.datetime().tzinfo, tzUSEastern) # tz is changed
-        self.assertEquals(asEast.datetime().hour, 12)            # hour is changed
-        self.assertEquals(asUTC, asEast)                         # still equal
-
-    def test_asUTC(self):
-        dt = datetime(2010, 2, 22, 17, 44, 42, 98303, tzinfo=tzUSEastern)
-        asEast = dateordatetime(dt)
-        asUTC = asEast.asTimeZone(utc)
-        self.assertEquals(asUTC.datetime().tzinfo, utc) # tz is changed
-        self.assertEquals(asUTC.datetime().hour, 22)    # hour is changed
-        self.assertEquals(asEast, asUTC)                # still equal
-
-
-class TimerangeTests(TestCase):
-    def test_start(self):
-        start = datetime.now()
-        tr = timerange(start=start)
-        self.assertEquals(tr.start(), start)
-
-    def test_start_none(self):
-        tr = timerange()
-        self.assertEquals(tr.start(), None)
-
-    def test_end(self):
-        end = datetime.now()
-        tr = timerange(end=end)
-        self.assertEquals(tr.end(), end)
-
-    def test_end_none(self):
-        tr = timerange()
-        self.assertEquals(tr.end(), None)
-
-    def test_end_none_duration(self):
-        duration = timedelta(seconds=8)
-        tr = timerange(duration=duration)
-        self.assertEquals(tr.end(), None)
-
-    def test_end_none_duration_start(self):
-        start = datetime.now()
-        duration = timedelta(seconds=8)
-        tr = timerange(start=start, duration=duration)
-        self.assertEquals(tr.end(), start + duration)
-
-    def test_duration(self):
-        duration = timedelta(seconds=8)
-        tr = timerange(duration=duration)
-        self.assertEquals(tr.duration(), duration)
-
-    def test_duration_none(self):
-        tr = timerange()
-        self.assertEquals(tr.duration(), None)
-
-    def test_duration_none_end(self):
-        end = datetime.now()
-        tr = timerange(end=end)
-        self.assertEquals(tr.duration(), None)
-
-    def test_duration_none_start_end(self):
-        start = datetime.now()
-        duration = timedelta(seconds=8)
-        end = start + duration
-        tr = timerange(start=start, end=end)
-        self.assertEquals(tr.duration(), duration)
-
-    @testUnimplemented
-    def test_compare(self):
-        raise NotImplementedError()
-
-    @featureUnimplemented
-    def test_overlapsWith(self):
-        t1, t2, t3, t4 = timeSeries(4)
-
-        d1 = dateordatetime(t1.date()); d1.n = "d1"
-        d2 = dateordatetime(t2.date()); d2.n = "d2"
-        d3 = dateordatetime(t3.date()); d3.n = "d3"
-        d4 = dateordatetime(t4.date()); d4.n = "d4"
-
-        for start1, end1, start2, end2, overlaps in (
-            # T-T-T-T
-
-            (t1, t2, t1, t2, True ),
-            (t1, t2, t1, t3, True ),
-            (t1, t2, t2, t3, False),
-            (t1, t2, t3, t4, False),
-
-            (t1, t3, t1, t2, True ),
-            (t1, t3, t2, t3, True ),
-
-            (t2, t3, t1, t2, False),
-            (t2, t3, t1, t3, True ),
-            (t2, t3, t1, t4, True ),
-
-            (t2, t4, t1, t3, True ),
-
-            (t3, t4, t1, t2, False),
-
-            # D-T-T-T
-
-            (d1, t2, t1, t2, True ),
-            (d1, t2, t1, t3, True ),
-            (d1, t2, t2, t3, False),
-            (d1, t2, t3, t4, False),
-
-            (d1, t3, t1, t2, True ),
-            (d1, t3, t2, t3, True ),
-
-            (d2, t3, t1, t2, False),
-            (d2, t3, t1, t3, True ),
-            (d2, t3, t1, t4, True ),
-
-            (d2, t4, t1, t3, True ),
-
-            (d3, t4, t1, t2, False),
-
-            # T-D-T-T
-
-            (t1, d2, t1, t2, True ),
-            (t1, d2, t1, t3, True ),
-            (t1, d2, t2, t3, False),
-            (t1, d2, t3, t4, False),
-
-            (t1, d3, t1, t2, True ),
-            (t1, d3, t2, t3, True ),
-
-            (t2, d3, t1, t2, False),
-            (t2, d3, t1, t3, True ),
-            (t2, d3, t1, t4, True ),
-
-            (t2, d4, t1, t3, True ),
-
-            (t3, d4, t1, t2, False),
-
-            # T-T-D-T
-
-            (t1, t2, d1, t2, True ),
-            (t1, t2, d1, t3, True ),
-            (t1, t2, d2, t3, False),
-            (t1, t2, d3, t4, False),
-
-            (t1, t3, d1, t2, True ),
-            (t1, t3, d2, t3, True ),
-
-            (t2, t3, d1, t2, False),
-            (t2, t3, d1, t3, True ),
-            (t2, t3, d1, t4, True ),
-
-            (t2, t4, d1, t3, True ),
-
-            (t3, t4, d1, t2, False),
-
-            # T-T-T-D
-
-            (t1, t2, t1, d2, True ),
-            (t1, t2, t1, d3, True ),
-            (t1, t2, t2, d3, False),
-            (t1, t2, t3, d4, False),
-
-            (t1, t3, t1, d2, True ),
-            (t1, t3, t2, d3, True ),
-
-            (t2, t3, t1, d2, False),
-            (t2, t3, t1, d3, True ),
-            (t2, t3, t1, d4, True ),
-
-            (t2, t4, t1, d3, True ),
-
-            (t3, t4, t1, d2, False),
-
-            # D-D-T-T
-
-            (d1, d2, t1, t2, True ),
-            (d1, d2, t1, t3, True ),
-            (d1, d2, t2, t3, False),
-            (d1, d2, t3, t4, False),
-
-            (d1, d3, t1, t2, True ),
-            (d1, d3, t2, t3, True ),
-
-            (d2, d3, t1, t2, False),
-            (d2, d3, t1, t3, True ),
-            (d2, d3, t1, t4, True ),
-
-            (d2, d4, t1, t3, True ),
-
-            (d3, d4, t1, t2, False),
-
-            # T-D-D-T
-
-            (t1, d2, d1, t2, True ),
-            (t1, d2, d1, t3, True ),
-            (t1, d2, d2, t3, False),
-            (t1, d2, d3, t4, False),
-
-            (t1, d3, d1, t2, True ),
-            (t1, d3, d2, t3, True ),
-
-            (t2, d3, d1, t2, False),
-            (t2, d3, d1, t3, True ),
-            (t2, d3, d1, t4, True ),
-
-            (t2, d4, d1, t3, True ),
-
-            (t3, d4, d1, t2, False),
-
-            # D-T-D-T
-
-            (d1, t2, d1, t2, True ),
-            (d1, t2, d1, t3, True ),
-            (d1, t2, d2, t3, False),
-            (d1, t2, d3, t4, False),
-
-            (d1, t3, d1, t2, True ),
-            (d1, t3, d2, t3, True ),
-
-            (d2, t3, d1, t2, False),
-            (d2, t3, d1, t3, True ),
-            (d2, t3, d1, t4, True ),
-
-            (d2, t4, d1, t3, True ),
-
-            (d3, t4, d1, t2, False),
-
-            # T-T-D-D
-
-            (t1, t2, d1, d2, True ),
-            (t1, t2, d1, d3, True ),
-            (t1, t2, d2, d3, False),
-            (t1, t2, d3, d4, False),
-
-            (t1, t3, d1, d2, True ),
-            (t1, t3, d2, d3, True ),
-
-            (t2, t3, d1, d2, False),
-            (t2, t3, d1, d3, True ),
-            (t2, t3, d1, d4, True ),
-
-            (t2, t4, d1, d3, True ),
-
-            (t3, t4, d1, d2, False),
-
-            # D-D-D-D
-
-            (d1, d2, d1, d2, True ),
-            (d1, d2, d1, d3, True ),
-            (d1, d2, d2, d3, False),
-            (d1, d2, d3, d4, False),
-
-            (d1, d3, d1, d2, True ),
-            (d1, d3, d2, d3, True ),
-
-            (d2, d3, d1, d2, False),
-            (d2, d3, d1, d3, True ),
-            (d2, d3, d1, d4, True ),
-
-            (d2, d4, d1, d3, True ),
-
-            (d3, d4, d1, d2, False),
-        ):
-            #print start1.n, end1.n, start2.n, end2.n, overlaps
-
-            if overlaps:
-                test = self.assertTrue
-                error = "should overlap with"
-            else:
-                test = self.assertFalse
-                error = "should not overlap with"
-
-            tr1 = timerange(start1, end1)
-            tr2 = timerange(start2, end2)
-
-            test(
-                tr1.overlapsWith(tr2),
-                "%r (%s-%s) %s %r (%s-%s)" % (tr1, start1.n, end1.n, error, tr2, start2.n, end2.n)
-            )

Modified: CalendarServer/trunk/twistedcaldav/datafilters/__init__.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/datafilters/__init__.py	2011-03-23 13:44:50 UTC (rev 7238)
+++ CalendarServer/trunk/twistedcaldav/datafilters/__init__.py	2011-03-23 13:49:12 UTC (rev 7239)
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2009 Apple Inc. All rights reserved.
+# Copyright (c) 2009-2011 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.
@@ -13,35 +13,3 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 ##
-
-from vobject.base import registerBehavior
-from vobject.icalendar import VCalendarComponentBehavior, VCalendar2_0
-
-"""
-Data filtering module.
-"""
-
-# This is where we register our special components with vobject
-
-class X_CALENDARSERVER_PERUSER(VCalendarComponentBehavior):
-    name='X-CALENDARSERVER-PERUSER'
-    description='A component used to encapsulate per-user data.'
-    sortFirst = ('uid', 'x-calendarserver-peruser-uid')
-    knownChildren = {
-        'UID':                            (1, 1, None),#min, max, behaviorRegistry id
-        'X-CALENDARSERVER-PERUSER-UID':   (1, 1, None),
-        'X-CALENDARSERVER-PERINSTANCE':   (0, None, None),
-    }
-      
-registerBehavior(X_CALENDARSERVER_PERUSER)
-VCalendar2_0.knownChildren['X-CALENDARSERVER-PERUSER'] = (0, None, None)
-
-class X_CALENDARSERVER_PERINSTANCE(VCalendarComponentBehavior):
-    name='X-CALENDARSERVER-PERINSTANCE'
-    description='A component used to encapsulate per-user instance data.'
-    sortFirst = ('recurrence-id',)
-    knownChildren = {
-        'RECURRENCE-ID':(0, 1, None),#min, max, behaviorRegistry id
-    }
-      
-registerBehavior(X_CALENDARSERVER_PERINSTANCE)

Modified: CalendarServer/trunk/twistedcaldav/datafilters/addressdata.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/datafilters/addressdata.py	2011-03-23 13:44:50 UTC (rev 7238)
+++ CalendarServer/trunk/twistedcaldav/datafilters/addressdata.py	2011-03-23 13:49:12 UTC (rev 7239)
@@ -38,7 +38,7 @@
     
     def filter(self, vcard):
         """
-        Filter the supplied vCard (vobject) data using the request information.
+        Filter the supplied vCard object using the request information.
 
         @param vcard: vCard object
         @type vcard: L{Component} or C{str}

Modified: CalendarServer/trunk/twistedcaldav/datafilters/calendardata.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/datafilters/calendardata.py	2011-03-23 13:44:50 UTC (rev 7238)
+++ CalendarServer/trunk/twistedcaldav/datafilters/calendardata.py	2011-03-23 13:49:12 UTC (rev 7239)
@@ -44,7 +44,7 @@
     
     def filter(self, ical):
         """
-        Filter the supplied iCalendar (vobject) data using the request information.
+        Filter the supplied iCalendar object using the request information.
 
         @param ical: iCalendar object
         @type ical: L{Component} or C{str}

Modified: CalendarServer/trunk/twistedcaldav/datafilters/filter.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/datafilters/filter.py	2011-03-23 13:44:50 UTC (rev 7238)
+++ CalendarServer/trunk/twistedcaldav/datafilters/filter.py	2011-03-23 13:49:12 UTC (rev 7239)
@@ -33,7 +33,7 @@
     
     def filter(self, ical):
         """
-        Filter the supplied iCalendar (vobject) data using the request information.
+        Filter the supplied iCalendar object using the request information.
 
         @param ical: iCalendar object
         @type ical: L{Component}
@@ -44,7 +44,7 @@
     
     def merge(self, icalnew, icalold):
         """
-        Merge the old iCalendar (vobject) data into the new iCalendar data using the request information.
+        Merge the old iCalendar object into the new iCalendar data using the request information.
         
         @param icalnew: new iCalendar object to merge data into
         @type icalnew: L{Component}
@@ -78,7 +78,7 @@
     
     def filter(self, vcard):
         """
-        Filter the supplied vCard (vobject) data using the request information.
+        Filter the supplied vCard object using the request information.
 
         @param vcard: iCalendar object
         @type vcard: L{Component}
@@ -89,7 +89,7 @@
     
     def merge(self, vcardnew, vcardold):
         """
-        Merge the old vcard (vobject) data into the new vcard data using the request information.
+        Merge the old vcard object into the new vcard data using the request information.
         
         @param vcardnew: new vcard object to merge data into
         @type vcardnew: L{Component}

Modified: CalendarServer/trunk/twistedcaldav/datafilters/peruserdata.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/datafilters/peruserdata.py	2011-03-23 13:44:50 UTC (rev 7238)
+++ CalendarServer/trunk/twistedcaldav/datafilters/peruserdata.py	2011-03-23 13:49:12 UTC (rev 7239)
@@ -58,8 +58,7 @@
     Filter per-user data
     """
 
-    # If any of these change also change the vobject behaviors in this module's __init__.py
-    # and update usage in ical.py
+    # If any of these change also update usage in ical.py
     PERUSER_COMPONENT     = "X-CALENDARSERVER-PERUSER"
     PERUSER_UID           = "X-CALENDARSERVER-PERUSER-UID"
     PERINSTANCE_COMPONENT = "X-CALENDARSERVER-PERINSTANCE"
@@ -78,7 +77,7 @@
     
     def filter(self, ical):
         """
-        Filter the supplied iCalendar (vobject) data using the request information.
+        Filter the supplied iCalendar object using the request information.
         Assume that the object is a CalDAV calendar resource.
 
         @param ical: iCalendar object - this will be modified and returned

Modified: CalendarServer/trunk/twistedcaldav/datafilters/privateevents.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/datafilters/privateevents.py	2011-03-23 13:44:50 UTC (rev 7238)
+++ CalendarServer/trunk/twistedcaldav/datafilters/privateevents.py	2011-03-23 13:49:12 UTC (rev 7239)
@@ -45,7 +45,7 @@
     
     def filter(self, ical):
         """
-        Filter the supplied iCalendar (vobject) data using the request information.
+        Filter the supplied iCalendar object using the request information.
 
         @param ical: iCalendar object
         @type ical: L{Component} or C{str}

Modified: CalendarServer/trunk/twistedcaldav/dateops.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/dateops.py	2011-03-23 13:44:50 UTC (rev 7238)
+++ CalendarServer/trunk/twistedcaldav/dateops.py	2011-03-23 13:49:12 UTC (rev 7239)
@@ -17,7 +17,7 @@
 from pycalendar.timezone import PyCalendarTimezone
 from pycalendar.period import PyCalendarPeriod
 import datetime
-from vobject.icalendar import utc
+import dateutil.tz
 
 """
 Date/time Utilities
@@ -240,7 +240,7 @@
             hour=pydt.getHours(),
             minute=pydt.getMinutes(),
             second=pydt.getSeconds(),
-            tzinfo=utc
+            tzinfo=dateutil.tz.tzutc()
         )
 
 SQL_TIMESTAMP_FORMAT = "%Y-%m-%d %H:%M:%S.%f"
@@ -268,6 +268,6 @@
     assert isinstance(dt, datetime.date)
 
     if dt.tzinfo is None:
-        dt.replace(tzinfo=utc)
+        dt.replace(tzinfo=dateutil.tz.tzutc())
     return calendar.timegm(dt.utctimetuple())
 

Modified: CalendarServer/trunk/twistedcaldav/directory/opendirectorybacker.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/opendirectorybacker.py	2011-03-23 13:44:50 UTC (rev 7238)
+++ CalendarServer/trunk/twistedcaldav/directory/opendirectorybacker.py	2011-03-23 13:49:12 UTC (rev 7239)
@@ -35,6 +35,10 @@
 from tempfile import mkstemp, gettempdir
 from random import random
 
+from pycalendar.n import N
+from pycalendar.adr import Adr
+from pycalendar.datetime import PyCalendarDateTime
+
 from socket import getfqdn
 
 from twisted.internet import reactor
@@ -51,13 +55,11 @@
 from twistedcaldav.customxml import calendarserver_namespace
 from twistedcaldav.config import config
 from twistedcaldav.directory.directory import DirectoryService, DirectoryRecord
-from twistedcaldav.ical import iCalendarProductID
 from twistedcaldav.memcachelock import MemcacheLock, MemcacheLockTimeoutError
 from twistedcaldav.query import addressbookqueryfilter
-from twistedcaldav.vcard import Component, Property
+from twistedcaldav.vcard import Component, Property, vCardProductID
 
 from xmlrpclib import datetime
-from vobject.vcard import Name, Address
 
 from calendarserver.platform.darwin.od import dsattributes, dsquery
 from twisted.python.reflect import namedModule
@@ -1208,13 +1210,9 @@
     
     constantProperties = {
         # 3.6.3 PRODID Type Definition
-        # should put version in but twistedcaldav.__version__, is NONE
-        # "PRODID": iCalendarProductID + "//BUILD %s" % twistedcaldav.__version__,
-        "PRODID": iCalendarProductID,
+        "PRODID": vCardProductID,
         # 3.6.9 VERSION Type Definition
         "VERSION": "3.0",
-        # 3.7.1 CLASS Type Definition
-        #"CLASS": "PUBLIC" if config.AnonymousDirectoryAddressBookAccess else "CONFIDENTIAL",
         }
 
     
@@ -1334,7 +1332,7 @@
         
         # ds templates often return empty attribute values
         #     get rid of them here
-        nonEmptyValues = [value for value in values if len(value) > 0 ]
+        nonEmptyValues = [(value.encode("utf-8") if isinstance(value, unicode) else value) for value in values if len(value) > 0 ]
         
         if len(nonEmptyValues) > 0:
             return nonEmptyValues
@@ -1347,9 +1345,9 @@
         if values is None:
             return default_value
         elif isinstance(values, list):
-            return values[0]
+            return values[0].encode("utf_8") if isinstance(values[0], unicode) else values[0]
         else:
-            return values
+            return values.encode("utf_8") if isinstance(values, unicode) else values
 
     def joinedValuesForAttribute(self, attributeName, separator=",", default_string="" ):
         values = self.valuesForAttribute(attributeName, None)
@@ -1376,32 +1374,15 @@
         
         def generateVCard():
             
-            def equalDictWithFilter( dict1, dict2, ignoreDict ):
-                def filteredDict(dict, ignoreDict):
-
-                    if ignoreDict:                
-                        for ignoreDictKey, ignoreDictValues in ignoreDict.items():
-                            dictKeyValues = dict[ignoreDictKey]
-                            if dictKeyValues:
-                                for ignoreDictValue in ignoreDictValues:
-                                    while ignoreDictValue in dictKeyValues:
-                                        # copy dictionary and remove value from copy
-                                        dictKeyValues = list(dictKeyValues)
-                                        dictKeyValues.remove(ignoreDictValue)
-                                        dict = dict.copy()
-                                        dict[ignoreDictKey] = dictKeyValues
-
-                    return dict
-                
-                return filteredDict(dict1, ignoreDict) == filteredDict(dict2, ignoreDict) 
-
-
             def isUniqueProperty(vcard, newProperty, ignoreParams = None):
-                existingProperties = vcard.properties( newProperty.name() )
+                existingProperties = vcard.properties(newProperty.name())
                 for existingProperty in existingProperties:
-                    if existingProperty.value() == newProperty.value():
-                        if equalDictWithFilter( existingProperty.params(), newProperty.params(), ignoreParams):
-                            return False
+                    if ignoreParams:
+                        existingProperty = existingProperty.duplicate()
+                        for paramname, paramvalue in ignoreParams:
+                            existingProperty.removeParameterValue(paramname, paramvalue)
+                    if existingProperty == newProperty:
+                        return False
                 return True
 
             def addUniqueProperty(vcard, newProperty, ignoreParams = None, attrType = None, attrValue = None):
@@ -1414,7 +1395,7 @@
             def addPropertyAndLabel(groupCount, label, propertyName, propertyValue, parameters = None ):
                 groupCount[0] += 1
                 groupPrefix = "item%d" % groupCount[0]
-                vcard.addProperty(Property(propertyName, propertyValue, params = parameters, group=groupPrefix))
+                vcard.addProperty(Property(propertyName, propertyValue, params=parameters, group=groupPrefix))
                 vcard.addProperty(Property("X-ABLabel", label, group=groupPrefix))
 
             # for attributes of the form  param:value
@@ -1448,11 +1429,11 @@
 
                         # only add label prop if needed
                         if paramTypeString in nolabelParamTypes:
-                            addUniqueProperty(vcard, Property(propertyName, attrValue[colonIndex+1:], params = parameters), None, attrValue, attrType)
+                            addUniqueProperty(vcard, Property(propertyName, attrValue[colonIndex+1:], params=parameters), None, attrValue, attrType)
                         else:
                             # use special localizable addressbook labels where possible
                             abLabelString = labelMap.get(labelString, labelString)
-                            addPropertyAndLabel( groupCount, abLabelString, propertyName, propertyValue, parameters)
+                            addPropertyAndLabel(groupCount, abLabelString, propertyName, propertyValue, parameters)
                         preferred = False
 
                     except Exception, e:
@@ -1491,27 +1472,25 @@
                                                         #      dsattributes.kDSStdRecordTypePeople).
                                                         
             # name is required, so make sure we have one
-            # vobject.vcard says: Each name attribute can be a string or a list of strings.
+            # vcard says: Each name attribute can be a string or a list of strings.
             if not self.hasAttribute(dsattributes.kDS1AttrFirstName) and not self.hasAttribute(dsattributes.kDS1AttrLastName):
                 familyName = self.firstValueForAttribute(dsattributes.kDS1AttrDistinguishedName)
             else:
                 familyName = self.valuesForAttribute(dsattributes.kDS1AttrLastName, "")
             
-            NameObject = Name(family = familyName, 
-                                                  given = self.valuesForAttribute(dsattributes.kDS1AttrFirstName, ""),
-                                                  additional = self.valuesForAttribute(dsattributes.kDS1AttrMiddleName, ""),
-                                                  prefix = self.valuesForAttribute(dsattributes.kDSNAttrNamePrefix, ""),
-                                                  suffix = self.valuesForAttribute(dsattributes.kDSNAttrNameSuffix, ""),
-                                                  )
-            vcard.addProperty(Property("N", NameObject ))
+            nameObject = N(
+                first = self.valuesForAttribute(dsattributes.kDS1AttrFirstName, ""),
+                last = familyName, 
+                middle = self.valuesForAttribute(dsattributes.kDS1AttrMiddleName, ""),
+                prefix = self.valuesForAttribute(dsattributes.kDSNAttrNamePrefix, ""),
+                suffix = self.valuesForAttribute(dsattributes.kDSNAttrNameSuffix, ""),
+            )
+            vcard.addProperty(Property("N", nameObject))
             
             # set full name to Name with contiguous spaces stripped
             # it turns out that Address Book.app ignores FN and creates it fresh from N in ABRecord
             # so no reason to have FN distinct from N
-            fullName = str(NameObject).strip()
-            while fullName.find("  ") > 0:
-                fullName = " ".join(fullName.split("  "))
-            vcard.addProperty(Property("FN", fullName ))
+            vcard.addProperty(Property("FN", nameObject.getFullName() ))
             
             # 3.1.3 NICKNAME Type Definition
             # dsattributes.kDSNAttrNickName,            # Represents the nickname of a user or person.
@@ -1527,7 +1506,7 @@
             # pyOpenDirectory always returns binary-encoded string                                       
                                                         
             for photo in self.valuesForAttribute(dsattributes.kDSNAttrJPEGPhoto):
-                addUniqueProperty(vcard, Property("PHOTO", photo, params = { "ENCODING": ["b",], "TYPE": ["JPEG",], }, encoded = True), None, dsattributes.kDSNAttrJPEGPhoto, photo)
+                addUniqueProperty(vcard, Property("PHOTO", photo, params={"ENCODING": ["b",], "TYPE": ["JPEG",],}), None, dsattributes.kDSNAttrJPEGPhoto, photo)
     
     
             # 3.1.5 BDAY Type Definition
@@ -1537,7 +1516,7 @@
             
             birthdate = self.isoDateStringForDateAttribute(dsattributes.kDS1AttrBirthday)
             if birthdate:
-                vcard.addProperty(Property("BDAY", birthdate))
+                vcard.addProperty(Property("BDAY", PyCalendarDateTime.parseText(birthdate, fullISO=True)))
     
     
             # 3.2 Delivery Addressing Types http://tools.ietf.org/html/rfc2426#section-3.2
@@ -1545,7 +1524,7 @@
             # 3.2.1 ADR Type Definition
     
             #address
-            # vobject.vcard says: Each address attribute can be a string or a list of strings.
+            # vcard says: Each address attribute can be a string or a list of strings.
             extended = self.valuesForAttribute(dsattributes.kDSNAttrBuilding, "")
             street = self.valuesForAttribute(dsattributes.kDSNAttrStreet, "")
             city = self.valuesForAttribute(dsattributes.kDSNAttrCity, "")
@@ -1554,16 +1533,18 @@
             country = self.valuesForAttribute(dsattributes.kDSNAttrCountry, "")
             
             if len(extended) > 0 or len(street) > 0 or len(city) > 0 or len(region) > 0 or len(code) > 0 or len(country) > 0:
-                vcard.addProperty(Property("ADR", Address(
-                                                           #box = box,
-                                                           extended = extended,
-                                                           street = street,
-                                                           city = city,
-                                                           region = region,
-                                                           code = code,
-                                                           country = country,
-                                                           ),
-                                                           params = { "TYPE": ["WORK", "PREF", "POSTAL", "PARCEL",], }))
+                vcard.addProperty(Property("ADR",
+                    Adr(
+                        #pobox = box,
+                        extended = extended,
+                        street = street,
+                        locality = city,
+                        region = region,
+                        postalcode = code,
+                        country = country,
+                    ),
+                    params = {"TYPE": ["WORK", "PREF", "POSTAL", "PARCEL",],}
+                ))
     
     
             # 3.2.2 LABEL Type Definition
@@ -1576,10 +1557,10 @@
             # dsattributes.kDSNAttrAddressLine3,            # Line three of multiple lines of address data for a user.
             
             for label in self.valuesForAttribute(dsattributes.kDSNAttrPostalAddress):
-                addUniqueProperty(vcard, Property("LABEL", label, params = { "TYPE": ["POSTAL", "PARCEL",]}), None, dsattributes.kDSNAttrPostalAddress, label)
+                addUniqueProperty(vcard, Property("LABEL", label, params={"TYPE": ["POSTAL", "PARCEL",]}), None, dsattributes.kDSNAttrPostalAddress, label)
                 
             for label in self.valuesForAttribute(dsattributes.kDSNAttrPostalAddressContacts):
-                addUniqueProperty(vcard, Property("LABEL", label, params = { "TYPE": ["POSTAL", "PARCEL",]}), None, dsattributes.kDSNAttrPostalAddressContacts, label)
+                addUniqueProperty(vcard, Property("LABEL", label, params={"TYPE": ["POSTAL", "PARCEL",]}), None, dsattributes.kDSNAttrPostalAddressContacts, label)
                 
             address = self.joinedValuesForAttribute(dsattributes.kDSNAttrAddressLine1)
             addressLine2 = self.joinedValuesForAttribute(dsattributes.kDSNAttrAddressLine2)
@@ -1590,7 +1571,7 @@
                 address += "\n" + addressLine3
             
             if len(address) > 0:
-                vcard.addProperty(Property("LABEL", address, params = { "TYPE": ["POSTAL", "PARCEL",]}))
+                vcard.addProperty(Property("LABEL", address, params={"TYPE": ["POSTAL", "PARCEL",]}))
     
             # 3.3 TELECOMMUNICATIONS ADDRESSING TYPES http://tools.ietf.org/html/rfc2426#section-3.3
             # 3.3.1 TEL Type Definition
@@ -1611,29 +1592,29 @@
                                                         #      found in user records (kDSStdRecordTypeUsers). 
                                                         #      Example: home fax:408-555-4444
             
-            params = { "TYPE": ["WORK", "PREF", "VOICE",], }
+            params = {"TYPE": ["WORK", "PREF", "VOICE",],}
             for phone in self.valuesForAttribute(dsattributes.kDSNAttrPhoneNumber):
-                addUniqueProperty(vcard, Property("TEL", phone, params=params), {"TYPE": ["PREF"]}, phone, dsattributes.kDSNAttrPhoneNumber)
-                params = { "TYPE": ["WORK", "VOICE",], }
+                addUniqueProperty(vcard, Property("TEL", phone, params=params), (("TYPE", "PREF"),), phone, dsattributes.kDSNAttrPhoneNumber)
+                params = {"TYPE": ["WORK", "VOICE",],}
     
             params = { "TYPE": ["WORK", "PREF", "CELL",], }
             for phone in self.valuesForAttribute(dsattributes.kDSNAttrMobileNumber):
-                addUniqueProperty(vcard, Property("TEL", phone, params=params), {"TYPE": ["PREF"]}, phone, dsattributes.kDSNAttrMobileNumber)
+                addUniqueProperty(vcard, Property("TEL", phone, params=params), (("TYPE", "PREF"),), phone, dsattributes.kDSNAttrMobileNumber)
                 params = { "TYPE": ["WORK", "CELL",], }
     
             params = { "TYPE": ["WORK", "PREF", "FAX",], }
             for phone in self.valuesForAttribute(dsattributes.kDSNAttrFaxNumber):
-                addUniqueProperty(vcard, Property("TEL", phone, params=params), {"TYPE": ["PREF"]}, phone, dsattributes.kDSNAttrFaxNumber)
+                addUniqueProperty(vcard, Property("TEL", phone, params=params), (("TYPE", "PREF"),), phone, dsattributes.kDSNAttrFaxNumber)
                 params = { "TYPE": ["WORK", "FAX",], }
     
             params = { "TYPE": ["WORK", "PREF", "PAGER",], }
             for phone in self.valuesForAttribute(dsattributes.kDSNAttrPagerNumber):
-                addUniqueProperty(vcard, Property("TEL", phone, params=params), {"TYPE": ["PREF"]}, phone, dsattributes.kDSNAttrPagerNumber)
+                addUniqueProperty(vcard, Property("TEL", phone, params=params), (("TYPE", "PREF"),), phone, dsattributes.kDSNAttrPagerNumber)
                 params = { "TYPE": ["WORK", "PAGER",], }
     
             params = { "TYPE": ["HOME", "PREF", "VOICE",], }
             for phone in self.valuesForAttribute(dsattributes.kDSNAttrHomePhoneNumber):
-                addUniqueProperty(vcard, Property("TEL", phone, params=params), {"TYPE": ["PREF"]}, phone, dsattributes.kDSNAttrHomePhoneNumber)
+                addUniqueProperty(vcard, Property("TEL", phone, params=params), (("TYPE", "PREF"),), phone, dsattributes.kDSNAttrHomePhoneNumber)
                 params = { "TYPE": ["HOME", "VOICE",], }
                     
             addPropertiesAndLabelsForPrefixedAttribute(groupCount, None, "TEL", "work",
@@ -1653,7 +1634,7 @@
             workParams = { "TYPE": ["WORK", "INTERNET",], }
             params = preferredWorkParams
             for emailAddress in self.valuesForAttribute(dsattributes.kDSNAttrEMailAddress):
-                addUniqueProperty(vcard, Property("EMAIL", emailAddress, params=params), {"TYPE": ["PREF"]}, emailAddress, dsattributes.kDSNAttrEMailAddress)
+                addUniqueProperty(vcard, Property("EMAIL", emailAddress, params=params), (("TYPE", "PREF"),), emailAddress, dsattributes.kDSNAttrEMailAddress)
                 params = workParams
                 
             # dsattributes.kDSNAttrEMailContacts,        # multi-valued attribute that defines a record's custom email addresses .
@@ -1681,7 +1662,7 @@
             for coordinate in self.valuesForAttribute(dsattributes.kDSNAttrMapCoordinates):
                 parts = coordinate.split(",")
                 if (len(parts) == 2):
-                    vcard.addProperty(Property("GEO", parts ))
+                    vcard.addProperty(Property("GEO", parts))
                 else:
                     self.log_info("Ignoring malformed attribute %r with value %r. Well-formed example: 7.7,10.6." % (dsattributes.kDSNAttrMapCoordinates, coordinate))
             #
@@ -1721,14 +1702,14 @@
                 addUniqueProperty(vcard, Property("NOTE", note), None, dsattributes.kDS1AttrNote, note)
             
             # 3.6.3 PRODID Type Definition
-            #vcard.addProperty(Property("PRODID", iCalendarProductID + "//BUILD %s" % twistedcaldav.__version__))
-            #vcard.addProperty(Property("PRODID", iCalendarProductID))
+            #vcard.addProperty(Property("PRODID", vCardProductID + "//BUILD %s" % twistedcaldav.__version__))
+            #vcard.addProperty(Property("PRODID", vCardProductID))
             # ADDED WITH CONTSTANT PROPERTIES
             
             # 3.6.4 REV Type Definition
             revDate = self.isoDateStringForDateAttribute(dsattributes.kDS1AttrModificationTimestamp)
             if revDate:
-                vcard.addProperty(Property("REV", revDate))
+                vcard.addProperty(Property("REV", PyCalendarDateTime.parseText(revDate, fullISO=True)))
             
             """
             # UNIMPLEMENTED:
@@ -1748,10 +1729,10 @@
                                                         #     Usually found in user records (kDSStdRecordTypeUsers). 
                                                         #      Example: http://example.com/blog/jsmith
             for url in self.valuesForAttribute(dsattributes.kDS1AttrWeblogURI):
-                addPropertyAndLabel( groupCount, "weblog", "URL", url, parameters = { "TYPE": ["Weblog",] } )
+                addPropertyAndLabel(groupCount, "weblog", "URL", url, parameters = {"TYPE": ["Weblog",]})
     
             for url in self.valuesForAttribute(dsattributes.kDSNAttrURL):
-                addPropertyAndLabel( groupCount, "_$!<HomePage>!$_", "URL", url, parameters = { "TYPE": ["Homepage",] } )
+                addPropertyAndLabel(groupCount, "_$!<HomePage>!$_", "URL", url, parameters = {"TYPE": ["Homepage",]})
     
     
             # 3.6.9 VERSION Type Definition
@@ -1778,16 +1759,16 @@
                                                         #       emails.
     
             for key in self.valuesForAttribute(dsattributes.kDSNAttrPGPPublicKey):
-                addUniqueProperty(vcard, Property("KEY", key, params = { "ENCODING": ["b",], "TYPE": ["PGPPublicKey",] }, encoded=True), None, dsattributes.kDSNAttrPGPPublicKey, key)
+                addUniqueProperty(vcard, Property("KEY", key, params = {"ENCODING": ["b",], "TYPE": ["PGPPublicKey",]}), None, dsattributes.kDSNAttrPGPPublicKey, key)
     
             for key in self.valuesForAttribute(dsattributes.kDS1AttrUserCertificate):
-                addUniqueProperty(vcard, Property("KEY", key, params = { "ENCODING": ["b",], "TYPE": ["UserCertificate",] }, encoded=True), None, dsattributes.kDS1AttrUserCertificate, key)
+                addUniqueProperty(vcard, Property("KEY", key, params = {"ENCODING": ["b",], "TYPE": ["UserCertificate",]}), None, dsattributes.kDS1AttrUserCertificate, key)
     
             for key in self.valuesForAttribute(dsattributes.kDS1AttrUserPKCS12Data):
-                addUniqueProperty(vcard, Property("KEY", key, params = { "ENCODING": ["b",], "TYPE": ["UserPKCS12Data",] }, encoded=True), None, dsattributes.kDS1AttrUserPKCS12Data, key)
+                addUniqueProperty(vcard, Property("KEY", key, params = {"ENCODING": ["b",], "TYPE": ["UserPKCS12Data",]}), None, dsattributes.kDS1AttrUserPKCS12Data, key)
     
             for key in self.valuesForAttribute(dsattributes.kDS1AttrUserSMIMECertificate):
-                addUniqueProperty(vcard, Property("KEY", key, params = { "ENCODING": ["b",], "TYPE": ["UserSMIMECertificate",] }), None, dsattributes.kDS1AttrUserSMIMECertificate, key)
+                addUniqueProperty(vcard, Property("KEY", key, params = {"ENCODING": ["b",], "TYPE": ["UserSMIMECertificate",]}), None, dsattributes.kDS1AttrUserSMIMECertificate, key)
     
             """
             X- attributes, Address Book support
@@ -1834,7 +1815,7 @@
                         managerValue = "%s %s" % (splitManager[0], splitManager[1])
                     else:
                         managerValue = manager
-                    addPropertyAndLabel( groupCount, "_$!<Manager>!$_", "X-ABRELATEDNAMES", managerValue, parameters = { "TYPE": ["Manager",] } )
+                    addPropertyAndLabel( groupCount, "_$!<Manager>!$_", "X-ABRELATEDNAMES", managerValue, parameters={ "TYPE": ["Manager",]} )
             
             """
             # UNIMPLEMENTED: X- attributes

Modified: CalendarServer/trunk/twistedcaldav/ical.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/ical.py	2011-03-23 13:44:50 UTC (rev 7238)
+++ CalendarServer/trunk/twistedcaldav/ical.py	2011-03-23 13:49:12 UTC (rev 7239)
@@ -1369,8 +1369,6 @@
                     "Timezone %s is not referenced by any non-timezone component" % (timezone,)
                 )
 
-        # Arghh - we have to do this AFTER the timezone check because the str(self) call will result in
-        # vobject adding in any missing timezones!
         # Control character check - only HTAB, CR, LF allowed for characters in the range 0x00-0x1F
         s = str(self)
         if len(s.translate(None, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F")) != len(s):

Modified: CalendarServer/trunk/twistedcaldav/query/addressbookqueryfilter.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/query/addressbookqueryfilter.py	2011-03-23 13:44:50 UTC (rev 7238)
+++ CalendarServer/trunk/twistedcaldav/query/addressbookqueryfilter.py	2011-03-23 13:49:12 UTC (rev 7239)
@@ -167,7 +167,7 @@
     def test(self, vcard):
         # At least one property must match (or is-not-defined is set)
         for property in vcard.properties():
-            if property.name() == self.filter_name and self.match(property): break
+            if property.name().upper() == self.filter_name.upper() and self.match(property): break
         else:
             return not self.defined
         return self.defined
@@ -192,8 +192,8 @@
 
         # At least one parameter must match (or is-not-defined is set)
         result = not self.defined
-        for parameterName in property.params().keys():
-            if parameterName == self.filter_name and self.match(property.params()[parameterName]):
+        for parameterName in property.parameterNames():
+            if parameterName.upper() == self.filter_name.upper() and self.match([property.parameterValues(parameterName)]):
                 result = self.defined
                 break
 
@@ -255,7 +255,7 @@
         if item is None: return False
 
         if isinstance(item, Property):
-            values = [item.value()]
+            values = [item.strvalue()]
         else:
             values = item
 
@@ -278,7 +278,7 @@
 
         for value in values:
             # NB Its possible that we have a text list value which appears as a Python list,
-            # so we need to check for that an iterate over the list.
+            # so we need to check for that and iterate over the list.
             if isinstance(value, list):
                 for subvalue in value:
                     if _textCompare(unicode(subvalue)):

Modified: CalendarServer/trunk/twistedcaldav/query/calendarqueryfilter.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/query/calendarqueryfilter.py	2011-03-23 13:44:50 UTC (rev 7238)
+++ CalendarServer/trunk/twistedcaldav/query/calendarqueryfilter.py	2011-03-23 13:49:12 UTC (rev 7239)
@@ -373,9 +373,9 @@
         # At least one property must match (or is-not-defined is set)
         for property in component.properties():
             # Apply access restrictions, if any.
-            if allowedProperties is not None and property.name() not in allowedProperties:
+            if allowedProperties is not None and property.name().upper() not in allowedProperties:
                 continue
-            if property.name() == self.filter_name and self.match(property, access): break
+            if property.name().upper() == self.filter_name.upper() and self.match(property, access): break
         else:
             return not self.defined
         return self.defined
@@ -392,7 +392,7 @@
         timerange = self.qualifier and isinstance(self.qualifier, TimeRange)
         
         # time-range only on COMPLETED, CREATED, DTSTAMP, LAST-MODIFIED
-        if timerange and self.filter_name not in ("COMPLETED", "CREATED", "DTSTAMP", "LAST-MODIFIED"):
+        if timerange and self.filter_name.upper() not in ("COMPLETED", "CREATED", "DTSTAMP", "LAST-MODIFIED"):
             log.msg("time-range cannot be used with property %s" % (self.filter_name,))
             return False
 
@@ -443,7 +443,7 @@
         # At least one parameter must match (or is-not-defined is set)
         result = not self.defined
         for parameterName in property.parameterNames():
-            if parameterName == self.filter_name and self.match([property.parameterValue(parameterName)], access):
+            if parameterName.upper() == self.filter_name.upper() and self.match([property.parameterValue(parameterName)], access):
                 result = self.defined
                 break
 
@@ -502,7 +502,7 @@
         else:
             values = item
 
-        test = self.text
+        test = unicode(self.text, "utf-8")
         if self.caseless:
             test = test.lower()
 
@@ -520,11 +520,11 @@
             # so we need to check for that and iterate over the list.
             if isinstance(value, list):
                 for subvalue in value:
-                    matched, result = _textCompare(subvalue)
+                    matched, result = _textCompare(unicode(subvalue))
                     if matched:
                         return result
             else:
-                matched, result = _textCompare(value)
+                matched, result = _textCompare(unicode(value))
                 if matched:
                     return result
         

Modified: CalendarServer/trunk/twistedcaldav/scheduling/icaldiff.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/scheduling/icaldiff.py	2011-03-23 13:44:50 UTC (rev 7238)
+++ CalendarServer/trunk/twistedcaldav/scheduling/icaldiff.py	2011-03-23 13:49:12 UTC (rev 7239)
@@ -15,7 +15,6 @@
 ##
 
 from twext.python.log import Logger
-#from twext.python.datetime import timerange, asUTC, iCalendarString
 
 from twistedcaldav.config import config
 from twistedcaldav.ical import Component, Property

Modified: CalendarServer/trunk/twistedcaldav/scheduling/scheduler.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/scheduling/scheduler.py	2011-03-23 13:44:50 UTC (rev 7238)
+++ CalendarServer/trunk/twistedcaldav/scheduling/scheduler.py	2011-03-23 13:49:12 UTC (rev 7239)
@@ -23,7 +23,6 @@
 from twisted.python.failure import Failure
 
 from twext.python.log import Logger, LoggingMixIn
-from twext.python.datetime import iCalendarString
 from twext.web2 import responsecode
 from twext.web2.http import HTTPError, Response, StatusResponse
 from twext.web2.http_headers import MimeType
@@ -390,7 +389,7 @@
                         "VFREEBUSY start or end not UTC",
                     ))
 
-                self.timeRange = caldavxml.TimeRange(start=iCalendarString(dtstart), end=iCalendarString(dtend))
+                self.timeRange = caldavxml.TimeRange(start=dtstart.getText(), end=dtend.getText())
                 self.timeRange.start = dtstart
                 self.timeRange.end = dtend
         

Modified: CalendarServer/trunk/twistedcaldav/scheduling/test/test_icaldiff.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/scheduling/test/test_icaldiff.py	2011-03-23 13:44:50 UTC (rev 7238)
+++ CalendarServer/trunk/twistedcaldav/scheduling/test/test_icaldiff.py	2011-03-23 13:49:12 UTC (rev 7239)
@@ -264,7 +264,7 @@
                 """BEGIN:VCALENDAR
 VERSION:2.0
 METHOD:REPLY
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-3
 DTSTART:20071114T000000Z
@@ -289,7 +289,7 @@
                 """BEGIN:VCALENDAR
 VERSION:2.0
 METHOD:REPLY
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890
 RECURRENCE-ID:20081114T000000Z
@@ -318,7 +318,7 @@
                 """BEGIN:VCALENDAR
 VERSION:2.0
 METHOD:REPLY
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-3
 DTSTART:20071114T000000Z
@@ -343,7 +343,7 @@
                 """BEGIN:VCALENDAR
 VERSION:2.0
 METHOD:REPLY
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-3
 DTSTART:20071114T000000Z
@@ -372,7 +372,7 @@
                 """BEGIN:VCALENDAR
 VERSION:2.0
 METHOD:REPLY
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-3
 DTSTART:20071114T000000Z
@@ -397,7 +397,7 @@
                 """BEGIN:VCALENDAR
 VERSION:2.0
 METHOD:REPLY
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890
 RECURRENCE-ID:20081114T000000Z
@@ -431,7 +431,7 @@
                 """BEGIN:VCALENDAR
 VERSION:2.0
 METHOD:REPLY
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-3
 DTSTART:20071114T000000Z
@@ -456,7 +456,7 @@
                 """BEGIN:VCALENDAR
 VERSION:2.0
 METHOD:REPLY
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890
 RECURRENCE-ID:20081114T000000Z

Modified: CalendarServer/trunk/twistedcaldav/test/data/vCards/AFBB77B8-0438-4825-A1DB-A75D76B6C3A8.vcf
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/data/vCards/AFBB77B8-0438-4825-A1DB-A75D76B6C3A8.vcf	2011-03-23 13:44:50 UTC (rev 7238)
+++ CalendarServer/trunk/twistedcaldav/test/data/vCards/AFBB77B8-0438-4825-A1DB-A75D76B6C3A8.vcf	2011-03-23 13:49:12 UTC (rev 7239)
@@ -13,7 +13,7 @@
 NOTE: Many customer fields are added
 item2.URL;type=pref:http://www.example.com/~magic
 item2.X-ABLabel:_$!<HomePage>!$_
-BDAY;value=date:1999-03-18
+BDAY:1999-03-18
 X-AIM;type=WORK;type=pref:custom at example.com
 item3.X-ABDATE;type=pref:1995-05-21
 item3.X-ABLabel:_$!<Anniversary>!$_

Modified: CalendarServer/trunk/twistedcaldav/test/test_icalendar.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_icalendar.py	2011-03-23 13:44:50 UTC (rev 7238)
+++ CalendarServer/trunk/twistedcaldav/test/test_icalendar.py	2011-03-23 13:49:12 UTC (rev 7239)
@@ -757,7 +757,7 @@
             (
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -769,7 +769,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -790,7 +790,7 @@
             (
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -802,7 +802,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -823,7 +823,7 @@
             (
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -835,7 +835,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -856,7 +856,7 @@
             (
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -868,7 +868,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -898,7 +898,7 @@
             (
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -907,7 +907,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -920,7 +920,7 @@
             (
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -935,7 +935,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -965,7 +965,7 @@
                 "1.1 Simple component, no Attendees - no filtering",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -975,7 +975,7 @@
                 False,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -989,7 +989,7 @@
                 "1.2 Simple component, no Attendees - filtering",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-2
 DTSTART:20071114T000000Z
@@ -999,7 +999,7 @@
                 False,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 END:VCALENDAR
 """,
                 ("mailto:user01 at example.com",)
@@ -1009,7 +1009,7 @@
                 "1.3 Simple component, with one attendee - filtering match",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-3
 DTSTART:20071114T000000Z
@@ -1021,7 +1021,7 @@
                 False,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-3
 DTSTART:20071114T000000Z
@@ -1037,7 +1037,7 @@
                 "1.4 Simple component, with one attendee - no filtering match",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-4
 DTSTART:20071114T000000Z
@@ -1049,7 +1049,7 @@
                 False,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 END:VCALENDAR
 """,
                 ("mailto:user3 at example.com",)
@@ -1059,7 +1059,7 @@
                 "2.1 Recurring component with one instance, each with one attendee - filtering match",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-3
 DTSTART:20071114T000000Z
@@ -1079,7 +1079,7 @@
                 False,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-3
 DTSTART:20071114T000000Z
@@ -1103,7 +1103,7 @@
                 "2.2 Recurring component with one instance, each with one attendee - no filtering match",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-4
 DTSTART:20071114T000000Z
@@ -1123,7 +1123,7 @@
                 False,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 END:VCALENDAR
 """,
                 ("mailto:user3 at example.com",)
@@ -1133,7 +1133,7 @@
                 "2.3 Recurring component with one instance, master with one attendee, instance without attendee - filtering match",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-3
 DTSTART:20071114T000000Z
@@ -1152,7 +1152,7 @@
                 False,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-3
 DTSTART:20071114T000000Z
@@ -1170,7 +1170,7 @@
                 "2.4 Recurring component with one instance, master with one attendee, instance without attendee - no filtering match",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-4
 DTSTART:20071114T000000Z
@@ -1189,7 +1189,7 @@
                 False,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 END:VCALENDAR
 """,
                 ("mailto:user3 at example.com",)
@@ -1199,7 +1199,7 @@
                 "2.5 Recurring component with one instance, master without attendee, instance with attendee - filtering match",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-3
 DTSTART:20071114T000000Z
@@ -1218,7 +1218,7 @@
                 False,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890
 RECURRENCE-ID:20081114T000000Z
@@ -1235,7 +1235,7 @@
                 "2.6 Recurring component with one instance, master without attendee, instance with attendee - no filtering match",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-4
 DTSTART:20071114T000000Z
@@ -1254,7 +1254,7 @@
                 False,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 END:VCALENDAR
 """,
                 ("mailto:user3 at example.com",)
@@ -1264,7 +1264,7 @@
                 "3.1 Simple component, no Attendees - no filtering",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -1274,7 +1274,7 @@
                 False,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -1288,7 +1288,7 @@
                 "3.2 Simple component, no Attendees - filtering",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-2
 DTSTART:20071114T000000Z
@@ -1298,7 +1298,7 @@
                 True,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 END:VCALENDAR
 """,
                 ("mailto:user01 at example.com",)
@@ -1308,7 +1308,7 @@
                 "3.3 Simple component, with one attendee - filtering match",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-3
 DTSTART:20071114T000000Z
@@ -1320,7 +1320,7 @@
                 True,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-3
 DTSTART:20071114T000000Z
@@ -1336,7 +1336,7 @@
                 "3.4 Simple component, with one attendee - filtering match",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-3
 DTSTART:20071114T000000Z
@@ -1348,7 +1348,7 @@
                 True,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-3
 DTSTART:20071114T000000Z
@@ -1364,7 +1364,7 @@
                 "3.5 Simple component, with one attendee - filtering match - no schedule-agent match",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-3
 DTSTART:20071114T000000Z
@@ -1376,7 +1376,7 @@
                 True,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 END:VCALENDAR
 """,
                 ("mailto:user2 at example.com",)
@@ -1386,7 +1386,7 @@
                 "3.6 Simple component, with one attendee - filtering match - no schedule-agent match",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-3
 DTSTART:20071114T000000Z
@@ -1398,7 +1398,7 @@
                 True,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 END:VCALENDAR
 """,
                 ("mailto:user2 at example.com",)
@@ -1418,7 +1418,7 @@
             (
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -1427,7 +1427,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -1441,7 +1441,7 @@
             (
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-2
 DTSTART:20071114T000000Z
@@ -1452,7 +1452,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-2
 DTSTART:20071114T000000Z
@@ -1467,7 +1467,7 @@
             (
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-3
 DTSTART:20071114T000000Z
@@ -1478,7 +1478,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-3
 DTSTART:20071114T000000Z
@@ -1494,7 +1494,7 @@
             (
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-4
 DTSTART:20071114T000000Z
@@ -1506,7 +1506,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-4
 DTSTART:20071114T000000Z
@@ -1521,7 +1521,7 @@
             (
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-5
 DTSTART:20071114T000000Z
@@ -1533,7 +1533,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-5
 DTSTART:20071114T000000Z
@@ -1560,7 +1560,7 @@
                 """BEGIN:VCALENDAR
 VERSION:2.0
 METHOD:REPLY
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -1573,7 +1573,7 @@
                 """BEGIN:VCALENDAR
 VERSION:2.0
 METHOD:REPLY
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 ATTENDEE:mailto:user2 at example.com
@@ -1589,7 +1589,7 @@
                 """BEGIN:VCALENDAR
 VERSION:2.0
 METHOD:REPLY
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-3
 DTSTART:20071114T000000Z
@@ -1614,7 +1614,7 @@
                 """BEGIN:VCALENDAR
 VERSION:2.0
 METHOD:REPLY
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-3
 ATTENDEE:mailto:user2 at example.com
@@ -1651,7 +1651,7 @@
                 """BEGIN:VCALENDAR
 VERSION:2.0
 METHOD:REPLY
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -1664,7 +1664,7 @@
                 """BEGIN:VCALENDAR
 VERSION:2.0
 METHOD:REPLY
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 ATTENDEE:mailto:user2 at example.com
@@ -1680,7 +1680,7 @@
                 """BEGIN:VCALENDAR
 VERSION:2.0
 METHOD:REPLY
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-3
 DTSTART:20071114T000000Z
@@ -1705,7 +1705,7 @@
                 """BEGIN:VCALENDAR
 VERSION:2.0
 METHOD:REPLY
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-3
 ATTENDEE:mailto:user2 at example.com
@@ -1742,7 +1742,7 @@
             (
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -1751,7 +1751,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -1764,7 +1764,7 @@
             (
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-2
 DTSTART:20071114T000000Z
@@ -1778,7 +1778,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-2
 DTSTART:20071114T000000Z
@@ -1791,7 +1791,7 @@
             (
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-3
 DTSTART:20071114T000000Z
@@ -1815,7 +1815,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-3
 DTSTART:20071114T000000Z
@@ -1838,7 +1838,7 @@
             (
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-3
 DTSTART:20071114T000000Z
@@ -1867,7 +1867,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-3
 DTSTART:20071114T000000Z
@@ -1899,7 +1899,7 @@
                 "Non recurring",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -1914,7 +1914,7 @@
                 "Simple recurring",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -1933,7 +1933,7 @@
                 "Recurring with RDATE",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -1954,7 +1954,7 @@
                 "Recurring with EXDATE",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -1974,7 +1974,7 @@
                 "Recurring with EXDATE on DTSTART",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -1994,7 +1994,7 @@
                 "Recurring with override",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -2019,7 +2019,7 @@
                 "Recurring with invalid override",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -2041,7 +2041,7 @@
                 "Recurring with invalid override",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -2081,7 +2081,7 @@
                 "Single component - True",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -2096,7 +2096,7 @@
                 "Single component - False",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -2111,7 +2111,7 @@
                 "Multiple components - True in both",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -2133,7 +2133,7 @@
                 "Multiple components - True in one",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -2155,7 +2155,7 @@
                 "Multiple components - False",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -2177,7 +2177,7 @@
                 "Multiple components/propnames - True in both",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -2199,7 +2199,7 @@
                 "Multiple components - True in one",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -2221,7 +2221,7 @@
                 "Multiple components - False",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -2252,7 +2252,7 @@
                 "Non recurring - one property",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -2263,7 +2263,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -2274,7 +2274,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -2290,7 +2290,7 @@
                 "Non recurring - two properties",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -2301,7 +2301,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -2313,7 +2313,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -2330,7 +2330,7 @@
                 "Non recurring - two properties - one overlap",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -2341,7 +2341,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -2353,7 +2353,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -2370,7 +2370,7 @@
                 "Non recurring - one property",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -2389,7 +2389,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -2408,7 +2408,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -2433,7 +2433,7 @@
                 "Non recurring - new override, one property",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -2452,7 +2452,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -2464,7 +2464,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -2501,7 +2501,7 @@
                 "1.1",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART;VALUE=DATE-TIME:20071114T000000Z
@@ -2511,7 +2511,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -2523,7 +2523,7 @@
                 "1.2",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART;VALUE=DATE-TIME:20071114T000000Z
@@ -2538,7 +2538,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -2555,7 +2555,7 @@
                 "1.3",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART;VALUE=DATE-TIME:20071114T000000Z
@@ -2571,7 +2571,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -2589,7 +2589,7 @@
                 "1.4",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VTIMEZONE
 TZID:US/Pacific
 BEGIN:STANDARD
@@ -2622,7 +2622,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VTIMEZONE
 TZID:US/Pacific
 BEGIN:STANDARD
@@ -2671,7 +2671,7 @@
                 "1.1 - no attach",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART;VALUE=DATE-TIME:20071114
@@ -2680,7 +2680,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART;VALUE=DATE-TIME:20071114
@@ -2692,7 +2692,7 @@
                 "1.2 - attach with no dropbox",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART;VALUE=DATE-TIME:20071114
@@ -2702,7 +2702,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART;VALUE=DATE-TIME:20071114
@@ -2715,7 +2715,7 @@
                 "1.3 - attach with dropbox",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART;VALUE=DATE-TIME:20071114
@@ -2726,7 +2726,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART;VALUE=DATE-TIME:20071114
@@ -2739,7 +2739,7 @@
                 "1.4 - attach with different dropbox",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART;VALUE=DATE-TIME:20071114
@@ -2750,7 +2750,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART;VALUE=DATE-TIME:20071114
@@ -2778,7 +2778,7 @@
                 "1.1 - non-recurring",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20090101T000000Z
@@ -2792,7 +2792,7 @@
                 "1.2 - recurring bounded COUNT",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20090101T000000Z
@@ -2807,7 +2807,7 @@
                 "1.3 - recurring bounded UNTIL",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20090101T000000Z
@@ -2822,7 +2822,7 @@
                 "1.4 - recurring unbounded",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20090101T000000Z
@@ -2847,7 +2847,7 @@
                 "1.1 - simple",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20090101T080000Z
@@ -2869,7 +2869,7 @@
                 "1.2 - simple rdate",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20090101T080000Z
@@ -2892,7 +2892,7 @@
                 "1.3 - multiple rdate",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20090101T080000Z
@@ -2916,7 +2916,7 @@
                 "2.1 - invalid simple",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20090101T080000Z
@@ -2932,7 +2932,7 @@
                 "2.2 - invalid simple rdate",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20090101T080000Z
@@ -2949,7 +2949,7 @@
                 "2.3 - invalid multiple rdate",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20090101T080000Z
@@ -2967,7 +2967,7 @@
                 "3.1 - simple all-day",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART;VALUE=DATE:20090101
@@ -2989,7 +2989,7 @@
                 "3.2 - simple all-day rdate",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART;VALUE=DATE:20090101
@@ -3012,7 +3012,7 @@
                 "3.3 - multiple all-day rdate",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART;VALUE=DATE:20090101
@@ -3036,7 +3036,7 @@
                 "4.1 - invalid all-day simple",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART;VALUE=DATE:20090101
@@ -3052,7 +3052,7 @@
                 "4.2 - invalid all-day simple rdate",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART;VALUE=DATE:20090101
@@ -3069,7 +3069,7 @@
                 "4.3 - invalid all-day multiple rdate",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART;VALUE=DATE:20090101
@@ -3098,7 +3098,7 @@
                 "1.1 - simple",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20090101T080000Z
@@ -3132,7 +3132,7 @@
                 "1.2 - simple rdate",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20090101T080000Z
@@ -3167,7 +3167,7 @@
                 "1.3 - multiple rdate",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20090101T080000Z
@@ -3203,7 +3203,7 @@
                 "2.1 - invalid simple",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20090101T080000Z
@@ -3231,7 +3231,7 @@
                 "2.2 - invalid simple rdate",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20090101T080000Z
@@ -3260,7 +3260,7 @@
                 "2.3 - invalid multiple rdate",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20090101T080000Z
@@ -3302,7 +3302,7 @@
                 "1.1 - no recurrence",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -3315,7 +3315,7 @@
                 "1.2 - no truncation - count",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -3329,7 +3329,7 @@
                 "1.3 - no truncation - until",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -3343,7 +3343,7 @@
                 "1.4 - truncation - count",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -3353,7 +3353,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -3366,7 +3366,7 @@
                 "1.5 - truncation - until",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -3376,7 +3376,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -3389,7 +3389,7 @@
                 "1.6 - no truncation - unbounded yearly",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -3403,7 +3403,7 @@
                 "1.7 - truncation - unbounded daily",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -3413,7 +3413,7 @@
 """,
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -3448,7 +3448,7 @@
                 "1.1 - no recurrence",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -3465,7 +3465,7 @@
                 "1.2 - rdate",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -3484,7 +3484,7 @@
                 "1.3 - rrule no overrides",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -3504,7 +3504,7 @@
                 "1.4 - rrule no overrides + rdate",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -3526,7 +3526,7 @@
                 "1.5 - rrule no overrides + rdate + exdate",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -3550,7 +3550,7 @@
                 "1.6 - rrule with override",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -3576,7 +3576,7 @@
                 "1.7 - rrule + rdate with override",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -3604,7 +3604,7 @@
                 "1.8 - override only",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 RECURRENCE-ID:20071115T000000Z
@@ -3623,7 +3623,7 @@
                 "1.9 - no recurrence one test master",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -3638,7 +3638,7 @@
                 "1.10 - no recurrence one test master",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z
@@ -3653,7 +3653,7 @@
                 "1.11 - no recurrence one test missing",
                 """BEGIN:VCALENDAR
 VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
 UID:12345-67890-1
 DTSTART:20071114T000000Z

Modified: CalendarServer/trunk/twistedcaldav/timezones.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/timezones.py	2011-03-23 13:44:50 UTC (rev 7238)
+++ CalendarServer/trunk/twistedcaldav/timezones.py	2011-03-23 13:49:12 UTC (rev 7239)
@@ -26,7 +26,7 @@
 Timezone caching.
 
 We need to use our own full definitions of iCalendar VTIMEZONEs as some clients only
-send partial VTIMEZONE objects. Since vObject caches the first VTIMEZONE TZID it sees,
+send partial VTIMEZONE objects. Since PyCalendar caches the first VTIMEZONE TZID it sees,
 if the cached one is partial that will result in incorrect UTC offsets for events outside
 of the time range covered by that partial VTIMEZONE.
 

Modified: CalendarServer/trunk/twistedcaldav/vcard.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/vcard.py	2011-03-23 13:44:50 UTC (rev 7238)
+++ CalendarServer/trunk/twistedcaldav/vcard.py	2011-03-23 13:49:12 UTC (rev 7239)
@@ -25,15 +25,17 @@
 ]
 
 import cStringIO as StringIO
+import codecs
 
-from vobject import newFromBehavior, readComponents
-from vobject.base import Component as vComponent
-from vobject.base import ContentLine as vContentLine
-from vobject.base import ParseError as vParseError
-
 from twext.web2.stream import IStream
 from twext.web2.dav.util import allDataFromStream
 
+from pycalendar.attribute import PyCalendarAttribute
+from pycalendar.componentbase import PyCalendarComponentBase
+from pycalendar.exceptions import PyCalendarInvalidData
+from pycalendar.vcard.card import Card
+from pycalendar.vcard.property import Property as pyProperty
+
 vCardProductID = "-//CALENDARSERVER.ORG//NONSGML Version 1//EN"
 
 class InvalidVCardDataError(ValueError):
@@ -43,7 +45,7 @@
     """
     vCard Property
     """
-    def __init__(self, name, value, params={}, group=None, encoded=False, **kwargs):
+    def __init__(self, name, value, params={}, group=None, **kwargs):
         """
         @param name: the property's name
         @param value: the property's value
@@ -54,18 +56,23 @@
             assert value  is None
             assert params is None
 
-            vobj = kwargs["vobject"]
+            pyobj = kwargs["pycard"]
 
-            if not isinstance(vobj, vContentLine):
-                raise TypeError("Not a vContentLine: %r" % (property,))
+            if not isinstance(pyobj, pyProperty):
+                raise TypeError("Not a pyProperty: %r" % (property,))
 
-            self._vobject = vobj
+            self._pycard = pyobj
         else:
-            # Convert params dictionary to list of lists format used by vobject
-            lparams = [[key] + lvalue for key, lvalue in params.items()]
-            self._vobject = vContentLine(name, lparams, value, isNative=True, group=group, encoded=encoded )
+            # Convert params dictionary to list of lists format used by pycalendar
+            if isinstance(value, unicode):
+                value = value.encode("utf-8")
+            self._pycard = pyProperty(group=group, name=name, value=value)
+            for attrname, attrvalue in params.items():
+                if isinstance(attrvalue, unicode):
+                    attrvalue = attrvalue.encode("utf-8")
+                self._pycard.addAttribute(PyCalendarAttribute(attrname, attrvalue))
 
-    def __str__ (self): return self._vobject.serialize()
+    def __str__ (self): return str(self._pycard)
     def __repr__(self): return "<%s: %r: %r>" % (self.__class__.__name__, self.name(), self.value())
 
     def __hash__(self): return hash(str(self))
@@ -73,7 +80,7 @@
     def __ne__(self, other): return not self.__eq__(other)
     def __eq__(self, other):
         if not isinstance(other, Property): return False
-        return self.name() == other.name() and self.value() == other.value()
+        return self._pycard == other._pycard
 
     def __gt__(self, other): return not (self.__eq__(other) or self.__lt__(other))
     def __lt__(self, other):
@@ -88,89 +95,152 @@
     def __ge__(self, other): return self.__eq__(other) or self.__gt__(other)
     def __le__(self, other): return self.__eq__(other) or self.__lt__(other)
 
-    def name  (self): return self._vobject.name
+    def duplicate(self):
+        """
+        Duplicate this object and all its contents.
+        @return: the duplicated vcard.
+        """
+        return Property(None, None, params=None, pycard=self._pycard.duplicate())
+        
+    def name  (self): return self._pycard.getName()
 
-    def value (self): return self._vobject.value
+    def value (self): return self._pycard.getValue().getValue()
+
+    def strvalue (self): return str(self._pycard.getValue())
+
     def setValue(self, value):
-        self._vobject.value = value
+        self._pycard.setValue(value)
 
-    def params(self): return self._vobject.params
+    def parameterNames(self):
+        """
+        Returns a set containing parameter names for this property.
+        """
+        result = set()
+        for pyattrlist in self._pycard.getAttributes().values():
+            for pyattr in pyattrlist:
+                result.add(pyattr.getName())
+        return result
 
-    def transformAllFromNative(self):
-        transformed = self._vobject.isNative
-        if transformed:
-            self._vobject = self._vobject.transformFromNative()
-            self._vobject.transformChildrenFromNative()
-        return transformed
+    def parameterValue(self, name, default=None):
+        """
+        Returns a single value for the given parameter.  Raises
+        InvalidICalendarDataError if the parameter has more than one value.
+        """
+        try:
+            return self._pycard.getAttributeValue(name)
+        except KeyError:
+            return default
+
+    def parameterValues(self, name):
+        """
+        Returns a single value for the given parameter.  Raises
+        InvalidICalendarDataError if the parameter has more than one value.
+        """
+        results = []
+        try:
+            attrs = self._pycard.getAttributes()[name.upper()]
+        except KeyError:
+            return []
         
-    def transformAllToNative(self):
-        transformed = not self._vobject.isNative
-        if transformed:
-            self._vobject = self._vobject.transformToNative()
-            self._vobject.transformChildrenToNative()
-        return transformed
+        for attr in attrs:
+            results.extend(attr.getValues())
+        return results
 
+    def hasParameter(self, paramname):
+        return self._pycard.hasAttribute(paramname)
+
+    def setParameter(self, paramname, paramvalue):
+        self._pycard.replaceAttribute(PyCalendarAttribute(paramname, paramvalue))
+
+    def removeParameter(self, paramname):
+        self._pycard.removeAttributes(paramname)
+
+    def removeAllParameters(self):
+        self._pycard.setAttributes({})
+
+    def removeParameterValue(self, paramname, paramvalue):
+        
+        paramname = paramname.upper()
+        for attr in tuple(self._pycard.getAttributes()):
+            if attr.getName().upper() == paramname:
+                for value in attr.getValues():
+                    if value == paramvalue:
+                        if not attr.removeValue(value):
+                            self._pycard.removeAttributes(paramname)
+
+
 class Component (object):
     """
     X{vCard} component.
     """
     @classmethod
-    def fromString(clazz, string):
+    def allFromString(clazz, string):
         """
-        Construct a L{Component} from a string.
-        @param string: a string containing vCard data.
-        @return: a L{Component} representing the first component described by
-            C{string}.
+        FIXME: Just default to reading a single VCARD - actually need more
         """
         if type(string) is unicode:
             string = string.encode("utf-8")
-        return clazz.fromStream(StringIO.StringIO(string))
+        else:
+            # Valid utf-8 please
+            string.decode("utf-8")
+        
+        # No BOMs please
+        if string[:3] == codecs.BOM_UTF8:
+            string = string[3:]
 
+        return clazz.allFromStream(StringIO.StringIO(string))
+
     @classmethod
-    def fromStream(clazz, stream):
+    def allFromStream(clazz, stream):
         """
-        Construct a L{Component} from a stream.
-        @param stream: a C{read()}able stream containing vCard data.
-        @return: a L{Component} representing the first component described by
-            C{stream}.
+        FIXME: Just default to reading a single VCARD - actually need more
         """
         try:
-            return clazz(None, vobject=readComponents(stream).next())
-        except vParseError, e:
-            raise InvalidVCardDataError(e)
-        except StopIteration, e:
-            raise InvalidVCardDataError(e)
+            results = Card.parseMultiple(stream)
+        except PyCalendarInvalidData:
+            results = None
+        if not results:
+            stream.seek(0)
+            raise InvalidVCardDataError("%s" % (stream.read(),))
+        return [clazz(None, pycard=result) for result in results]
 
     @classmethod
-    def allFromString(clazz, string):
+    def fromString(clazz, string):
         """
         Construct a L{Component} from a string.
         @param string: a string containing vCard data.
-        @return: a C{list} of L{Component}s representing the components described by
+        @return: a L{Component} representing the first component described by
             C{string}.
         """
         if type(string) is unicode:
             string = string.encode("utf-8")
-        return clazz.allFromStream(StringIO.StringIO(string))
+        else:
+            # Valid utf-8 please
+            string.decode("utf-8")
+        
+        # No BOMs please
+        if string[:3] == codecs.BOM_UTF8:
+            string = string[3:]
 
+        return clazz.fromStream(StringIO.StringIO(string))
+
     @classmethod
-    def allFromStream(clazz, stream):
+    def fromStream(clazz, stream):
         """
-        Construct possibly multiple L{Component}s from a stream.
+        Construct a L{Component} from a stream.
         @param stream: a C{read()}able stream containing vCard data.
-        @return: a C{list} of L{Component}s representing the components described by
+        @return: a L{Component} representing the first component described by
             C{stream}.
         """
-        
-        results = []
+        cal = Card()
         try:
-            for vobject in readComponents(stream):
-                results.append(clazz(None, vobject=vobject))
-            return results
-        except vParseError, e:
-            raise InvalidVCardDataError(e)
-        except StopIteration, e:
-            raise InvalidVCardDataError(e)
+            result = cal.parse(stream)
+        except PyCalendarInvalidData:
+            result = None
+        if not result:
+            stream.seek(0)
+            raise InvalidVCardDataError("%s" % (stream.read(),))
+        return clazz(None, pycard=cal)
 
     @classmethod
     def fromIStream(clazz, stream):
@@ -198,14 +268,14 @@
             component.
         """
         if name is None:
-            if "vobject" in kwargs:
-                vobj = kwargs["vobject"]
+            if "pycard" in kwargs:
+                pyobj = kwargs["pycard"]
 
-                if vobj is not None:
-                    if not isinstance(vobj, vComponent):
-                        raise TypeError("Not a vComponent: %r" % (vobj,))
+                if pyobj is not None:
+                    if not isinstance(pyobj, PyCalendarComponentBase):
+                        raise TypeError("Not a PyCalendarComponentBase: %r" % (pyobj,))
 
-                self._vobject = vobj
+                self._pycard = pyobj
             else:
                 raise AssertionError("name may not be None")
 
@@ -221,12 +291,14 @@
                 self._parent = parent
             else:
                 self._parent = None
+        elif name == "VCARD":
+            self._pycard = Card(add_defaults=False)
+            self._parent = None
         else:
-            self._vobject = newFromBehavior(name)
-            self._parent = None
+            raise ValueError("VCards have no child components")
 
-    def __str__ (self): return self._vobject.serialize()
-    def __repr__(self): return "<%s: %r>" % (self.__class__.__name__, str(self._vobject))
+    def __str__ (self): return str(self._pycard)
+    def __repr__(self): return "<%s: %r>" % (self.__class__.__name__, str(self._pycard))
 
     def __hash__(self):
         return hash(str(self))
@@ -235,51 +307,31 @@
     def __eq__(self, other):
         if not isinstance(other, Component):
             return False
+        return self._pycard == other._pycard
 
-        my_properties = set(self.properties())
-        for property in other.properties():
-            if property in my_properties:
-                my_properties.remove(property)
-            else:
-                return False
-        if my_properties:
-            return False
-
-        return True
-
     # FIXME: Should this not be in __eq__?
     def same(self, other):
-        return self._vobject == other._vobject
+        return self._pycard == other._pycard
     
     def name(self):
         """
         @return: the name of the iCalendar type of this component.
         """
-        return self._vobject.name
+        return self._pycard.getType()
 
-    def setBehavior(self, behavior):
-        """
-        Set the behavior of the underlying iCal obtecy.
-        @param behavior: the behavior type to set.
-        """
-        self._vobject.setBehavior(behavior)
-
     def duplicate(self):
         """
         Duplicate this object and all its contents.
         @return: the duplicated vcard.
         """
-        return Component(None, vobject=vComponent.duplicate(self._vobject))
+        return Component(None, pycard=self._pycard.duplicate())
         
     def hasProperty(self, name):
         """
         @param name: the name of the property whose existence is being tested.
         @return: True if the named property exists, False otherwise.
         """
-        try:
-            return len(self._vobject.contents[name.lower()]) > 0
-        except KeyError:
-            return False
+        return self._pycard.hasProperty(name)
 
     def getProperty(self, name):
         """
@@ -300,65 +352,52 @@
         @return: an iterable of L{Property} objects, one for each property of
             this component.
         """
+        properties = []
         if name is None:
-            properties = self._vobject.getChildren()
-        else:
-            try:
-                properties = self._vobject.contents[name.lower()]
-            except KeyError:
-                return ()
+            [properties.extend(i) for i in self._pycard.getProperties().values()]
+        elif self._pycard.countProperty(name) > 0:
+            properties = self._pycard.getProperties(name)
 
         return (
-            Property(None, None, None, vobject=p)
+            Property(None, None, None, pycard=p)
             for p in properties
-            if isinstance(p, vContentLine)
         )
 
     def propertyValue(self, name):
         properties = tuple(self.properties(name))
-        if len(properties) == 1: return properties[0].value()
-        if len(properties) > 1: raise InvalidVCardDataError("More than one %s property in component %r" % (name, self))
+        if len(properties) == 1:
+            return properties[0].value()
+        if len(properties) > 1:
+            raise InvalidVCardDataError("More than one %s property in component %r" % (name, self))
         return None
 
 
-    def propertyNativeValue(self, name):
-        """
-        Return the native property value for the named property in the supplied component.
-        NB Assumes a single property exists in the component.
-        @param name: the name of the property whose value is required
-        @return: the native property value
-        """
-        properties = tuple(self.properties(name))
-
-        if len(properties) == 1:
-            transormed = properties[0].transformAllToNative()
-    
-            result = properties[0].value()
-    
-            if transormed:
-                properties[0].transformAllFromNative()
-                
-            return result
-
-        elif len(properties) > 1:
-            raise InvalidVCardDataError("More than one %s property in component %r" % (name, self))
-        else:
-            return None
-
     def addProperty(self, property):
         """
         Adds a property to this component.
         @param property: the L{Property} to add to this component.
         """
-        self._vobject.add(property._vobject)
+        self._pycard.addProperty(property._pycard)
+        self._pycard.finalise()
 
     def removeProperty(self, property):
         """
         Remove a property from this component.
         @param property: the L{Property} to remove from this component.
         """
-        self._vobject.remove(property._vobject)
+        self._pycard.removeProperty(property._pycard)
+        self._pycard.finalise()
 
+    def replaceProperty(self, property):
+        """
+        Add or replace a property in this component.
+        @param property: the L{Property} to add or replace in this component.
+        """
+        
+        # Remove all existing ones first
+        self._pycard.removeProperties(property.name())
+        self.addProperty(property)
+
     def resourceUID(self):
         """
         @return: the UID of the subcomponents in this component.
@@ -388,12 +427,3 @@
         s = str(self)
         if len(s.translate(None, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F")) != len(s):
             raise InvalidVCardDataError("vCard contains illegal control character")
-        
-
-    def transformAllFromNative(self):
-        self._vobject = self._vobject.transformFromNative()
-        self._vobject.transformChildrenFromNative(False)
-        
-    def transformAllToNative(self):
-        self._vobject = self._vobject.transformToNative()
-        self._vobject.transformChildrenToNative()


Property changes on: CalendarServer/trunk/txdav/caldav/datastore/index_file.py
___________________________________________________________________
Modified: svn:mergeinfo
   - /CalendarServer/branches/config-separation/txdav/caldav/datastore/index_file.py:4379-4443
/CalendarServer/branches/egg-info-351/txdav/caldav/datastore/index_file.py:4589-4625
/CalendarServer/branches/generic-sqlstore/txdav/caldav/datastore/index_file.py:6167-6191
/CalendarServer/branches/new-store-no-caldavfile-2/txdav/caldav/datastore/index_file.py:5936-5981
/CalendarServer/branches/new-store-no-caldavfile/txdav/caldav/datastore/index_file.py:5911-5935
/CalendarServer/branches/new-store/txdav/caldav/datastore/index_file.py:5594-5934
/CalendarServer/branches/users/cdaboo/batchupload-6699/txdav/caldav/datastore/index_file.py:6700-7198
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/txdav/caldav/datastore/index_file.py:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/txdav/caldav/datastore/index_file.py:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591/txdav/caldav/datastore/index_file.py:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/txdav/caldav/datastore/index_file.py:4465-4957
/CalendarServer/branches/users/cdaboo/pycalendar/txdav/caldav/datastore/index_file.py:7085-7206
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/txdav/caldav/datastore/index_file.py:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/txdav/caldav/datastore/index_file.py:5188-5440
/CalendarServer/branches/users/glyph/conn-limit/txdav/caldav/datastore/index_file.py:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge/txdav/caldav/datastore/index_file.py:4971-5080
/CalendarServer/branches/users/glyph/dalify/txdav/caldav/datastore/index_file.py:6932-7023
/CalendarServer/branches/users/glyph/dont-start-postgres/txdav/caldav/datastore/index_file.py:6592-6614
/CalendarServer/branches/users/glyph/linux-tests/txdav/caldav/datastore/index_file.py:6893-6900
/CalendarServer/branches/users/glyph/more-deferreds-6/txdav/caldav/datastore/index_file.py:6322-6334
/CalendarServer/branches/users/glyph/more-deferreds-7/txdav/caldav/datastore/index_file.py:6369
/CalendarServer/branches/users/glyph/oracle/txdav/caldav/datastore/index_file.py:7106-7155
/CalendarServer/branches/users/glyph/sendfdport/txdav/caldav/datastore/index_file.py:5388-5424
/CalendarServer/branches/users/glyph/sharedpool/txdav/caldav/datastore/index_file.py:6490-6550
/CalendarServer/branches/users/glyph/sql-store/txdav/caldav/datastore/index_file.py:5929-6073
/CalendarServer/branches/users/glyph/use-system-twisted/txdav/caldav/datastore/index_file.py:5084-5149
/CalendarServer/branches/users/sagen/locations-resources-2/txdav/caldav/datastore/index_file.py:5052-5061
/CalendarServer/branches/users/sagen/locations-resources/txdav/caldav/datastore/index_file.py:5032-5051
/CalendarServer/branches/users/sagen/purge_old_events/txdav/caldav/datastore/index_file.py:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038/txdav/caldav/datastore/index_file.py:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/txdav/caldav/datastore/index_file.py:4068-4075
/CalendarServer/branches/users/sagen/resources-2/txdav/caldav/datastore/index_file.py:5084-5093
/CalendarServer/branches/users/wsanchez/transations/txdav/caldav/datastore/index_file.py:5515-5593
/CalendarServer/trunk/twistedcaldav/index.py:6322-6394
   + /CalendarServer/branches/config-separation/txdav/caldav/datastore/index_file.py:4379-4443
/CalendarServer/branches/egg-info-351/txdav/caldav/datastore/index_file.py:4589-4625
/CalendarServer/branches/generic-sqlstore/txdav/caldav/datastore/index_file.py:6167-6191
/CalendarServer/branches/new-store-no-caldavfile-2/txdav/caldav/datastore/index_file.py:5936-5981
/CalendarServer/branches/new-store-no-caldavfile/txdav/caldav/datastore/index_file.py:5911-5935
/CalendarServer/branches/new-store/txdav/caldav/datastore/index_file.py:5594-5934
/CalendarServer/branches/users/cdaboo/batchupload-6699/txdav/caldav/datastore/index_file.py:6700-7198
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/txdav/caldav/datastore/index_file.py:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/txdav/caldav/datastore/index_file.py:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591/txdav/caldav/datastore/index_file.py:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/txdav/caldav/datastore/index_file.py:4465-4957
/CalendarServer/branches/users/cdaboo/pycalendar/txdav/caldav/datastore/index_file.py:7085-7206
/CalendarServer/branches/users/cdaboo/pycard/txdav/caldav/datastore/index_file.py:7227-7237
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/txdav/caldav/datastore/index_file.py:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/txdav/caldav/datastore/index_file.py:5188-5440
/CalendarServer/branches/users/glyph/conn-limit/txdav/caldav/datastore/index_file.py:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge/txdav/caldav/datastore/index_file.py:4971-5080
/CalendarServer/branches/users/glyph/dalify/txdav/caldav/datastore/index_file.py:6932-7023
/CalendarServer/branches/users/glyph/dont-start-postgres/txdav/caldav/datastore/index_file.py:6592-6614
/CalendarServer/branches/users/glyph/linux-tests/txdav/caldav/datastore/index_file.py:6893-6900
/CalendarServer/branches/users/glyph/more-deferreds-6/txdav/caldav/datastore/index_file.py:6322-6334
/CalendarServer/branches/users/glyph/more-deferreds-7/txdav/caldav/datastore/index_file.py:6369
/CalendarServer/branches/users/glyph/oracle/txdav/caldav/datastore/index_file.py:7106-7155
/CalendarServer/branches/users/glyph/sendfdport/txdav/caldav/datastore/index_file.py:5388-5424
/CalendarServer/branches/users/glyph/sharedpool/txdav/caldav/datastore/index_file.py:6490-6550
/CalendarServer/branches/users/glyph/sql-store/txdav/caldav/datastore/index_file.py:5929-6073
/CalendarServer/branches/users/glyph/use-system-twisted/txdav/caldav/datastore/index_file.py:5084-5149
/CalendarServer/branches/users/sagen/locations-resources-2/txdav/caldav/datastore/index_file.py:5052-5061
/CalendarServer/branches/users/sagen/locations-resources/txdav/caldav/datastore/index_file.py:5032-5051
/CalendarServer/branches/users/sagen/purge_old_events/txdav/caldav/datastore/index_file.py:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038/txdav/caldav/datastore/index_file.py:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/txdav/caldav/datastore/index_file.py:4068-4075
/CalendarServer/branches/users/sagen/resources-2/txdav/caldav/datastore/index_file.py:5084-5093
/CalendarServer/branches/users/wsanchez/transations/txdav/caldav/datastore/index_file.py:5515-5593
/CalendarServer/trunk/twistedcaldav/index.py:6322-6394


Property changes on: CalendarServer/trunk/txdav/caldav/datastore/test/test_index_file.py
___________________________________________________________________
Modified: svn:mergeinfo
   - /CalendarServer/branches/config-separation/txdav/caldav/datastore/test/test_index_file.py:4379-4443
/CalendarServer/branches/egg-info-351/txdav/caldav/datastore/test/test_index_file.py:4589-4625
/CalendarServer/branches/generic-sqlstore/txdav/caldav/datastore/test/test_index_file.py:6167-6191
/CalendarServer/branches/new-store-no-caldavfile-2/txdav/caldav/datastore/test/test_index_file.py:5936-5981
/CalendarServer/branches/new-store-no-caldavfile/txdav/caldav/datastore/test/test_index_file.py:5911-5935
/CalendarServer/branches/new-store/txdav/caldav/datastore/test/test_index_file.py:5594-5934
/CalendarServer/branches/users/cdaboo/batchupload-6699/txdav/caldav/datastore/test/test_index_file.py:6700-7198
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/txdav/caldav/datastore/test/test_index_file.py:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/txdav/caldav/datastore/test/test_index_file.py:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591/txdav/caldav/datastore/test/test_index_file.py:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/txdav/caldav/datastore/test/test_index_file.py:4465-4957
/CalendarServer/branches/users/cdaboo/pycalendar/txdav/caldav/datastore/test/test_index_file.py:7085-7206
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/txdav/caldav/datastore/test/test_index_file.py:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/txdav/caldav/datastore/test/test_index_file.py:5188-5440
/CalendarServer/branches/users/glyph/conn-limit/txdav/caldav/datastore/test/test_index_file.py:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge/txdav/caldav/datastore/test/test_index_file.py:4971-5080
/CalendarServer/branches/users/glyph/dalify/txdav/caldav/datastore/test/test_index_file.py:6932-7023
/CalendarServer/branches/users/glyph/dont-start-postgres/txdav/caldav/datastore/test/test_index_file.py:6592-6614
/CalendarServer/branches/users/glyph/linux-tests/txdav/caldav/datastore/test/test_index_file.py:6893-6900
/CalendarServer/branches/users/glyph/more-deferreds-6/txdav/caldav/datastore/test/test_index_file.py:6322-6334
/CalendarServer/branches/users/glyph/more-deferreds-7/txdav/caldav/datastore/test/test_index_file.py:6369
/CalendarServer/branches/users/glyph/oracle/txdav/caldav/datastore/test/test_index_file.py:7106-7155
/CalendarServer/branches/users/glyph/sendfdport/txdav/caldav/datastore/test/test_index_file.py:5388-5424
/CalendarServer/branches/users/glyph/sharedpool/txdav/caldav/datastore/test/test_index_file.py:6490-6550
/CalendarServer/branches/users/glyph/sql-store/txdav/caldav/datastore/test/test_index_file.py:5929-6073
/CalendarServer/branches/users/glyph/use-system-twisted/txdav/caldav/datastore/test/test_index_file.py:5084-5149
/CalendarServer/branches/users/sagen/locations-resources-2/txdav/caldav/datastore/test/test_index_file.py:5052-5061
/CalendarServer/branches/users/sagen/locations-resources/txdav/caldav/datastore/test/test_index_file.py:5032-5051
/CalendarServer/branches/users/sagen/purge_old_events/txdav/caldav/datastore/test/test_index_file.py:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038/txdav/caldav/datastore/test/test_index_file.py:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/txdav/caldav/datastore/test/test_index_file.py:4068-4075
/CalendarServer/branches/users/sagen/resources-2/txdav/caldav/datastore/test/test_index_file.py:5084-5093
/CalendarServer/branches/users/wsanchez/transations/txdav/caldav/datastore/test/test_index_file.py:5515-5593
/CalendarServer/trunk/twistedcaldav/test/test_index.py:6322-6394
   + /CalendarServer/branches/config-separation/txdav/caldav/datastore/test/test_index_file.py:4379-4443
/CalendarServer/branches/egg-info-351/txdav/caldav/datastore/test/test_index_file.py:4589-4625
/CalendarServer/branches/generic-sqlstore/txdav/caldav/datastore/test/test_index_file.py:6167-6191
/CalendarServer/branches/new-store-no-caldavfile-2/txdav/caldav/datastore/test/test_index_file.py:5936-5981
/CalendarServer/branches/new-store-no-caldavfile/txdav/caldav/datastore/test/test_index_file.py:5911-5935
/CalendarServer/branches/new-store/txdav/caldav/datastore/test/test_index_file.py:5594-5934
/CalendarServer/branches/users/cdaboo/batchupload-6699/txdav/caldav/datastore/test/test_index_file.py:6700-7198
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/txdav/caldav/datastore/test/test_index_file.py:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/txdav/caldav/datastore/test/test_index_file.py:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591/txdav/caldav/datastore/test/test_index_file.py:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/txdav/caldav/datastore/test/test_index_file.py:4465-4957
/CalendarServer/branches/users/cdaboo/pycalendar/txdav/caldav/datastore/test/test_index_file.py:7085-7206
/CalendarServer/branches/users/cdaboo/pycard/txdav/caldav/datastore/test/test_index_file.py:7227-7237
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/txdav/caldav/datastore/test/test_index_file.py:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/txdav/caldav/datastore/test/test_index_file.py:5188-5440
/CalendarServer/branches/users/glyph/conn-limit/txdav/caldav/datastore/test/test_index_file.py:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge/txdav/caldav/datastore/test/test_index_file.py:4971-5080
/CalendarServer/branches/users/glyph/dalify/txdav/caldav/datastore/test/test_index_file.py:6932-7023
/CalendarServer/branches/users/glyph/dont-start-postgres/txdav/caldav/datastore/test/test_index_file.py:6592-6614
/CalendarServer/branches/users/glyph/linux-tests/txdav/caldav/datastore/test/test_index_file.py:6893-6900
/CalendarServer/branches/users/glyph/more-deferreds-6/txdav/caldav/datastore/test/test_index_file.py:6322-6334
/CalendarServer/branches/users/glyph/more-deferreds-7/txdav/caldav/datastore/test/test_index_file.py:6369
/CalendarServer/branches/users/glyph/oracle/txdav/caldav/datastore/test/test_index_file.py:7106-7155
/CalendarServer/branches/users/glyph/sendfdport/txdav/caldav/datastore/test/test_index_file.py:5388-5424
/CalendarServer/branches/users/glyph/sharedpool/txdav/caldav/datastore/test/test_index_file.py:6490-6550
/CalendarServer/branches/users/glyph/sql-store/txdav/caldav/datastore/test/test_index_file.py:5929-6073
/CalendarServer/branches/users/glyph/use-system-twisted/txdav/caldav/datastore/test/test_index_file.py:5084-5149
/CalendarServer/branches/users/sagen/locations-resources-2/txdav/caldav/datastore/test/test_index_file.py:5052-5061
/CalendarServer/branches/users/sagen/locations-resources/txdav/caldav/datastore/test/test_index_file.py:5032-5051
/CalendarServer/branches/users/sagen/purge_old_events/txdav/caldav/datastore/test/test_index_file.py:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038/txdav/caldav/datastore/test/test_index_file.py:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/txdav/caldav/datastore/test/test_index_file.py:4068-4075
/CalendarServer/branches/users/sagen/resources-2/txdav/caldav/datastore/test/test_index_file.py:5084-5093
/CalendarServer/branches/users/wsanchez/transations/txdav/caldav/datastore/test/test_index_file.py:5515-5593
/CalendarServer/trunk/twistedcaldav/test/test_index.py:6322-6394


Property changes on: CalendarServer/trunk/txdav/carddav/datastore/index_file.py
___________________________________________________________________
Modified: svn:mergeinfo
   - /CalendarServer/branches/config-separation/txdav/carddav/datastore/index_file.py:4379-4443
/CalendarServer/branches/egg-info-351/txdav/carddav/datastore/index_file.py:4589-4625
/CalendarServer/branches/generic-sqlstore/txdav/carddav/datastore/index_file.py:6167-6191
/CalendarServer/branches/new-store-no-caldavfile-2/txdav/carddav/datastore/index_file.py:5936-5981
/CalendarServer/branches/new-store-no-caldavfile/txdav/carddav/datastore/index_file.py:5911-5935
/CalendarServer/branches/new-store/txdav/carddav/datastore/index_file.py:5594-5934
/CalendarServer/branches/users/cdaboo/batchupload-6699/txdav/carddav/datastore/index_file.py:6700-7198
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/txdav/carddav/datastore/index_file.py:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/txdav/carddav/datastore/index_file.py:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591/txdav/carddav/datastore/index_file.py:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/txdav/carddav/datastore/index_file.py:4465-4957
/CalendarServer/branches/users/cdaboo/pycalendar/txdav/carddav/datastore/index_file.py:7085-7206
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/txdav/carddav/datastore/index_file.py:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/txdav/carddav/datastore/index_file.py:5188-5440
/CalendarServer/branches/users/glyph/conn-limit/txdav/carddav/datastore/index_file.py:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge/txdav/carddav/datastore/index_file.py:4971-5080
/CalendarServer/branches/users/glyph/dalify/txdav/carddav/datastore/index_file.py:6932-7023
/CalendarServer/branches/users/glyph/dont-start-postgres/txdav/carddav/datastore/index_file.py:6592-6614
/CalendarServer/branches/users/glyph/linux-tests/txdav/carddav/datastore/index_file.py:6893-6900
/CalendarServer/branches/users/glyph/more-deferreds-6/txdav/carddav/datastore/index_file.py:6322-6334
/CalendarServer/branches/users/glyph/more-deferreds-7/txdav/carddav/datastore/index_file.py:6369
/CalendarServer/branches/users/glyph/oracle/txdav/carddav/datastore/index_file.py:7106-7155
/CalendarServer/branches/users/glyph/sendfdport/txdav/carddav/datastore/index_file.py:5388-5424
/CalendarServer/branches/users/glyph/sharedpool/txdav/carddav/datastore/index_file.py:6490-6550
/CalendarServer/branches/users/glyph/sql-store/txdav/carddav/datastore/index_file.py:5929-6073
/CalendarServer/branches/users/glyph/use-system-twisted/txdav/carddav/datastore/index_file.py:5084-5149
/CalendarServer/branches/users/sagen/locations-resources-2/txdav/carddav/datastore/index_file.py:5052-5061
/CalendarServer/branches/users/sagen/locations-resources/txdav/carddav/datastore/index_file.py:5032-5051
/CalendarServer/branches/users/sagen/purge_old_events/txdav/carddav/datastore/index_file.py:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038/txdav/carddav/datastore/index_file.py:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/txdav/carddav/datastore/index_file.py:4068-4075
/CalendarServer/branches/users/sagen/resources-2/txdav/carddav/datastore/index_file.py:5084-5093
/CalendarServer/branches/users/wsanchez/transations/txdav/carddav/datastore/index_file.py:5515-5593
/CalendarServer/trunk/twistedcaldav/vcardindex.py:6322-6394
   + /CalendarServer/branches/config-separation/txdav/carddav/datastore/index_file.py:4379-4443
/CalendarServer/branches/egg-info-351/txdav/carddav/datastore/index_file.py:4589-4625
/CalendarServer/branches/generic-sqlstore/txdav/carddav/datastore/index_file.py:6167-6191
/CalendarServer/branches/new-store-no-caldavfile-2/txdav/carddav/datastore/index_file.py:5936-5981
/CalendarServer/branches/new-store-no-caldavfile/txdav/carddav/datastore/index_file.py:5911-5935
/CalendarServer/branches/new-store/txdav/carddav/datastore/index_file.py:5594-5934
/CalendarServer/branches/users/cdaboo/batchupload-6699/txdav/carddav/datastore/index_file.py:6700-7198
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/txdav/carddav/datastore/index_file.py:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/txdav/carddav/datastore/index_file.py:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591/txdav/carddav/datastore/index_file.py:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/txdav/carddav/datastore/index_file.py:4465-4957
/CalendarServer/branches/users/cdaboo/pycalendar/txdav/carddav/datastore/index_file.py:7085-7206
/CalendarServer/branches/users/cdaboo/pycard/txdav/carddav/datastore/index_file.py:7227-7237
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/txdav/carddav/datastore/index_file.py:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/txdav/carddav/datastore/index_file.py:5188-5440
/CalendarServer/branches/users/glyph/conn-limit/txdav/carddav/datastore/index_file.py:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge/txdav/carddav/datastore/index_file.py:4971-5080
/CalendarServer/branches/users/glyph/dalify/txdav/carddav/datastore/index_file.py:6932-7023
/CalendarServer/branches/users/glyph/dont-start-postgres/txdav/carddav/datastore/index_file.py:6592-6614
/CalendarServer/branches/users/glyph/linux-tests/txdav/carddav/datastore/index_file.py:6893-6900
/CalendarServer/branches/users/glyph/more-deferreds-6/txdav/carddav/datastore/index_file.py:6322-6334
/CalendarServer/branches/users/glyph/more-deferreds-7/txdav/carddav/datastore/index_file.py:6369
/CalendarServer/branches/users/glyph/oracle/txdav/carddav/datastore/index_file.py:7106-7155
/CalendarServer/branches/users/glyph/sendfdport/txdav/carddav/datastore/index_file.py:5388-5424
/CalendarServer/branches/users/glyph/sharedpool/txdav/carddav/datastore/index_file.py:6490-6550
/CalendarServer/branches/users/glyph/sql-store/txdav/carddav/datastore/index_file.py:5929-6073
/CalendarServer/branches/users/glyph/use-system-twisted/txdav/carddav/datastore/index_file.py:5084-5149
/CalendarServer/branches/users/sagen/locations-resources-2/txdav/carddav/datastore/index_file.py:5052-5061
/CalendarServer/branches/users/sagen/locations-resources/txdav/carddav/datastore/index_file.py:5032-5051
/CalendarServer/branches/users/sagen/purge_old_events/txdav/carddav/datastore/index_file.py:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038/txdav/carddav/datastore/index_file.py:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/txdav/carddav/datastore/index_file.py:4068-4075
/CalendarServer/branches/users/sagen/resources-2/txdav/carddav/datastore/index_file.py:5084-5093
/CalendarServer/branches/users/wsanchez/transations/txdav/carddav/datastore/index_file.py:5515-5593
/CalendarServer/trunk/twistedcaldav/vcardindex.py:6322-6394


Property changes on: CalendarServer/trunk/txdav/carddav/datastore/test/test_index_file.py
___________________________________________________________________
Modified: svn:mergeinfo
   - /CalendarServer/branches/config-separation/txdav/carddav/datastore/test/test_index_file.py:4379-4443
/CalendarServer/branches/egg-info-351/txdav/carddav/datastore/test/test_index_file.py:4589-4625
/CalendarServer/branches/generic-sqlstore/txdav/carddav/datastore/test/test_index_file.py:6167-6191
/CalendarServer/branches/new-store-no-caldavfile-2/txdav/carddav/datastore/test/test_index_file.py:5936-5981
/CalendarServer/branches/new-store-no-caldavfile/txdav/carddav/datastore/test/test_index_file.py:5911-5935
/CalendarServer/branches/new-store/txdav/carddav/datastore/test/test_index_file.py:5594-5934
/CalendarServer/branches/users/cdaboo/batchupload-6699/txdav/carddav/datastore/test/test_index_file.py:6700-7198
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/txdav/carddav/datastore/test/test_index_file.py:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/txdav/carddav/datastore/test/test_index_file.py:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591/txdav/carddav/datastore/test/test_index_file.py:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/txdav/carddav/datastore/test/test_index_file.py:4465-4957
/CalendarServer/branches/users/cdaboo/pycalendar/txdav/carddav/datastore/test/test_index_file.py:7085-7206
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/txdav/carddav/datastore/test/test_index_file.py:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/txdav/carddav/datastore/test/test_index_file.py:5188-5440
/CalendarServer/branches/users/glyph/conn-limit/txdav/carddav/datastore/test/test_index_file.py:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge/txdav/carddav/datastore/test/test_index_file.py:4971-5080
/CalendarServer/branches/users/glyph/dalify/txdav/carddav/datastore/test/test_index_file.py:6932-7023
/CalendarServer/branches/users/glyph/dont-start-postgres/txdav/carddav/datastore/test/test_index_file.py:6592-6614
/CalendarServer/branches/users/glyph/linux-tests/txdav/carddav/datastore/test/test_index_file.py:6893-6900
/CalendarServer/branches/users/glyph/more-deferreds-6/txdav/carddav/datastore/test/test_index_file.py:6322-6334
/CalendarServer/branches/users/glyph/more-deferreds-7/txdav/carddav/datastore/test/test_index_file.py:6369
/CalendarServer/branches/users/glyph/oracle/txdav/carddav/datastore/test/test_index_file.py:7106-7155
/CalendarServer/branches/users/glyph/sendfdport/txdav/carddav/datastore/test/test_index_file.py:5388-5424
/CalendarServer/branches/users/glyph/sharedpool/txdav/carddav/datastore/test/test_index_file.py:6490-6550
/CalendarServer/branches/users/glyph/sql-store/txdav/carddav/datastore/test/test_index_file.py:5929-6073
/CalendarServer/branches/users/glyph/use-system-twisted/txdav/carddav/datastore/test/test_index_file.py:5084-5149
/CalendarServer/branches/users/sagen/locations-resources-2/txdav/carddav/datastore/test/test_index_file.py:5052-5061
/CalendarServer/branches/users/sagen/locations-resources/txdav/carddav/datastore/test/test_index_file.py:5032-5051
/CalendarServer/branches/users/sagen/purge_old_events/txdav/carddav/datastore/test/test_index_file.py:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038/txdav/carddav/datastore/test/test_index_file.py:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/txdav/carddav/datastore/test/test_index_file.py:4068-4075
/CalendarServer/branches/users/sagen/resources-2/txdav/carddav/datastore/test/test_index_file.py:5084-5093
/CalendarServer/branches/users/wsanchez/transations/txdav/carddav/datastore/test/test_index_file.py:5515-5593
/CalendarServer/trunk/twistedcaldav/test/test_vcardindex.py:6322-6394
   + /CalendarServer/branches/config-separation/txdav/carddav/datastore/test/test_index_file.py:4379-4443
/CalendarServer/branches/egg-info-351/txdav/carddav/datastore/test/test_index_file.py:4589-4625
/CalendarServer/branches/generic-sqlstore/txdav/carddav/datastore/test/test_index_file.py:6167-6191
/CalendarServer/branches/new-store-no-caldavfile-2/txdav/carddav/datastore/test/test_index_file.py:5936-5981
/CalendarServer/branches/new-store-no-caldavfile/txdav/carddav/datastore/test/test_index_file.py:5911-5935
/CalendarServer/branches/new-store/txdav/carddav/datastore/test/test_index_file.py:5594-5934
/CalendarServer/branches/users/cdaboo/batchupload-6699/txdav/carddav/datastore/test/test_index_file.py:6700-7198
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/txdav/carddav/datastore/test/test_index_file.py:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/txdav/carddav/datastore/test/test_index_file.py:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591/txdav/carddav/datastore/test/test_index_file.py:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/txdav/carddav/datastore/test/test_index_file.py:4465-4957
/CalendarServer/branches/users/cdaboo/pycalendar/txdav/carddav/datastore/test/test_index_file.py:7085-7206
/CalendarServer/branches/users/cdaboo/pycard/txdav/carddav/datastore/test/test_index_file.py:7227-7237
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/txdav/carddav/datastore/test/test_index_file.py:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/txdav/carddav/datastore/test/test_index_file.py:5188-5440
/CalendarServer/branches/users/glyph/conn-limit/txdav/carddav/datastore/test/test_index_file.py:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge/txdav/carddav/datastore/test/test_index_file.py:4971-5080
/CalendarServer/branches/users/glyph/dalify/txdav/carddav/datastore/test/test_index_file.py:6932-7023
/CalendarServer/branches/users/glyph/dont-start-postgres/txdav/carddav/datastore/test/test_index_file.py:6592-6614
/CalendarServer/branches/users/glyph/linux-tests/txdav/carddav/datastore/test/test_index_file.py:6893-6900
/CalendarServer/branches/users/glyph/more-deferreds-6/txdav/carddav/datastore/test/test_index_file.py:6322-6334
/CalendarServer/branches/users/glyph/more-deferreds-7/txdav/carddav/datastore/test/test_index_file.py:6369
/CalendarServer/branches/users/glyph/oracle/txdav/carddav/datastore/test/test_index_file.py:7106-7155
/CalendarServer/branches/users/glyph/sendfdport/txdav/carddav/datastore/test/test_index_file.py:5388-5424
/CalendarServer/branches/users/glyph/sharedpool/txdav/carddav/datastore/test/test_index_file.py:6490-6550
/CalendarServer/branches/users/glyph/sql-store/txdav/carddav/datastore/test/test_index_file.py:5929-6073
/CalendarServer/branches/users/glyph/use-system-twisted/txdav/carddav/datastore/test/test_index_file.py:5084-5149
/CalendarServer/branches/users/sagen/locations-resources-2/txdav/carddav/datastore/test/test_index_file.py:5052-5061
/CalendarServer/branches/users/sagen/locations-resources/txdav/carddav/datastore/test/test_index_file.py:5032-5051
/CalendarServer/branches/users/sagen/purge_old_events/txdav/carddav/datastore/test/test_index_file.py:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038/txdav/carddav/datastore/test/test_index_file.py:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/txdav/carddav/datastore/test/test_index_file.py:4068-4075
/CalendarServer/branches/users/sagen/resources-2/txdav/carddav/datastore/test/test_index_file.py:5084-5093
/CalendarServer/branches/users/wsanchez/transations/txdav/carddav/datastore/test/test_index_file.py:5515-5593
/CalendarServer/trunk/twistedcaldav/test/test_vcardindex.py:6322-6394
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110323/b50d38d2/attachment-0001.html>


More information about the calendarserver-changes mailing list