[CalendarServer-changes] [7236] CalendarServer/branches/users/cdaboo/pycard

source_changes at macosforge.org source_changes at macosforge.org
Tue Mar 22 19:46:32 PDT 2011


Revision: 7236
          http://trac.macosforge.org/projects/calendarserver/changeset/7236
Author:   cdaboo at apple.com
Date:     2011-03-22 19:46:30 -0700 (Tue, 22 Mar 2011)
Log Message:
-----------
Fixes for opendirectorybacker + pycalendar.

Modified Paths:
--------------
    CalendarServer/branches/users/cdaboo/pycard/calendarserver/tap/util.py
    CalendarServer/branches/users/cdaboo/pycard/support/build.sh
    CalendarServer/branches/users/cdaboo/pycard/twistedcaldav/directory/opendirectorybacker.py
    CalendarServer/branches/users/cdaboo/pycard/twistedcaldav/vcard.py

Modified: CalendarServer/branches/users/cdaboo/pycard/calendarserver/tap/util.py
===================================================================
--- CalendarServer/branches/users/cdaboo/pycard/calendarserver/tap/util.py	2011-03-23 02:32:45 UTC (rev 7235)
+++ CalendarServer/branches/users/cdaboo/pycard/calendarserver/tap/util.py	2011-03-23 02:46:30 UTC (rev 7236)
@@ -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/branches/users/cdaboo/pycard/support/build.sh
===================================================================
--- CalendarServer/branches/users/cdaboo/pycard/support/build.sh	2011-03-23 02:32:45 UTC (rev 7235)
+++ CalendarServer/branches/users/cdaboo/pycard/support/build.sh	2011-03-23 02:46:30 UTC (rev 7236)
@@ -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";
 

Modified: CalendarServer/branches/users/cdaboo/pycard/twistedcaldav/directory/opendirectorybacker.py
===================================================================
--- CalendarServer/branches/users/cdaboo/pycard/twistedcaldav/directory/opendirectorybacker.py	2011-03-23 02:32:45 UTC (rev 7235)
+++ CalendarServer/branches/users/cdaboo/pycard/twistedcaldav/directory/opendirectorybacker.py	2011-03-23 02:46:30 UTC (rev 7236)
@@ -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/branches/users/cdaboo/pycard/twistedcaldav/vcard.py
===================================================================
--- CalendarServer/branches/users/cdaboo/pycard/twistedcaldav/vcard.py	2011-03-23 02:32:45 UTC (rev 7235)
+++ CalendarServer/branches/users/cdaboo/pycard/twistedcaldav/vcard.py	2011-03-23 02:46:30 UTC (rev 7236)
@@ -45,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
@@ -63,9 +63,13 @@
 
             self._pycard = pyobj
         else:
-            # Convert params dictionary to list of lists format used by vobject
-            self._pycard = pyProperty(name, value)
+            # 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 str(self._pycard)
@@ -91,6 +95,13 @@
     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 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._pycard.getValue().getValue()
@@ -149,8 +160,9 @@
 
     def removeParameterValue(self, paramname, paramvalue):
         
+        paramname = paramname.upper()
         for attr in tuple(self._pycard.getAttributes()):
-            if attr.getName() == paramname:
+            if attr.getName().upper() == paramname:
                 for value in attr.getValues():
                     if value == paramvalue:
                         if not attr.removeValue(value):
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110322/0cd94170/attachment-0001.html>


More information about the calendarserver-changes mailing list