[CalendarServer-changes] [762] CalendarServer/trunk/lib-patches/vobject

source_changes at macosforge.org source_changes at macosforge.org
Fri Dec 8 08:38:14 PST 2006


Revision: 762
          http://trac.macosforge.org/projects/calendarserver/changeset/762
Author:   cdaboo at apple.com
Date:     2006-12-08 08:38:13 -0800 (Fri, 08 Dec 2006)

Log Message:
-----------
Fix for utf-8 data in events etc. What now happens is that the serialize() method returns utf-8 encoded data,
rather than unicode. This is reasonable as the default encoding for iCalendar data is utf-8. What's more the line
folding has been changed to fold the utf-8 data and ensure multi-byte sequence are not broken.

Modified Paths:
--------------
    CalendarServer/trunk/lib-patches/vobject/src.vobject.base.patch

Added Paths:
-----------
    CalendarServer/trunk/lib-patches/vobject/README.patch
    CalendarServer/trunk/lib-patches/vobject/tests.tests.patch

Added: CalendarServer/trunk/lib-patches/vobject/README.patch
===================================================================
--- CalendarServer/trunk/lib-patches/vobject/README.patch	                        (rev 0)
+++ CalendarServer/trunk/lib-patches/vobject/README.patch	2006-12-08 16:38:13 UTC (rev 762)
@@ -0,0 +1,13 @@
+Index: README.txt
+===================================================================
+--- README.txt	(revision 164)
++++ README.txt	(working copy)
+@@ -193,7 +193,7 @@
+ serializing will add any required computable attributes (like 'VERSION')
+ 
+ >>> j.serialize()
+-u'BEGIN:VCARD\r\nVERSION:3.0\r\nEMAIL;TYPE=INTERNET:jeffrey at osafoundation.org\r\nFN:Jeffrey Harris\r\nN:Harris;Jeffrey;;;\r\nEND:VCARD\r\n'
++'BEGIN:VCARD\r\nVERSION:3.0\r\nEMAIL;TYPE=INTERNET:jeffrey at osafoundation.org\r\nFN:Jeffrey Harris\r\nN:Harris;Jeffrey;;;\r\nEND:VCARD\r\n'
+ >>> j.prettyPrint()
+  VCARD
+     VERSION: 3.0

Modified: CalendarServer/trunk/lib-patches/vobject/src.vobject.base.patch
===================================================================
--- CalendarServer/trunk/lib-patches/vobject/src.vobject.base.patch	2006-12-08 09:43:17 UTC (rev 761)
+++ CalendarServer/trunk/lib-patches/vobject/src.vobject.base.patch	2006-12-08 16:38:13 UTC (rev 762)
@@ -2,7 +2,90 @@
 ===================================================================
 --- src/vobject/base.py	(revision 164)
 +++ src/vobject/base.py	(working copy)
-@@ -1023,7 +1023,7 @@
+@@ -842,14 +842,36 @@
+     return param
+ 
+ def foldOneLine(outbuf, input, lineLength = 75):
+-    if isinstance(input, basestring): input = StringIO.StringIO(input)
+-    input.seek(0)
+-    outbuf.write(input.read(lineLength) + CRLF)
+-    brokenline = input.read(lineLength - 1)
+-    while brokenline:
+-        outbuf.write(' ' + brokenline + CRLF)
+-        brokenline = input.read(lineLength - 1)
++    # Folding line procedure that ensures multi-byte utf-8 sequences are not broken
++    # across lines
+ 
++    if len(input) < lineLength:
++        # Optimize for unfolded line case
++        outbuf.write(input)
++    else:
++        # Look for valid utf8 range and write that out
++        start = 0
++        written = 0
++        while written < len(input):
++            # Start max length -1 chars on from where we are
++            offset = start + lineLength - 1
++            if offset >= len(input):
++                line = input[start:]
++                outbuf.write(line)
++                written = len(input)
++            else:
++                # Check whether next char is valid utf8 lead byte
++                while (input[offset] > 0x7F) and ((ord(input[offset]) & 0xC0) == 0x80):
++                    # Step back until we have a valid char
++                    offset -= 1
++                
++                line = input[start:offset]
++                outbuf.write(line)
++                outbuf.write("\r\n ")
++                written += offset - start
++                start = offset
++    outbuf.write("\r\n")
++
+ def defaultSerialize(obj, buf, lineLength):
+     """Encode and fold obj and its children, write to buf or return a string."""
+ 
+@@ -861,12 +883,12 @@
+         else:
+             groupString = obj.group + '.'
+         if obj.useBegin:
+-            foldOneLine(outbuf, groupString + u"BEGIN:" + obj.name, lineLength)
++            foldOneLine(outbuf, str(groupString + u"BEGIN:" + obj.name), lineLength)
+         for child in obj.getSortedChildren():
+             #validate is recursive, we only need to validate once
+             child.serialize(outbuf, lineLength, validate=False)
+         if obj.useBegin:
+-            foldOneLine(outbuf, groupString + u"END:" + obj.name, lineLength)
++            foldOneLine(outbuf, str(groupString + u"END:" + obj.name), lineLength)
+         if DEBUG: logger.debug("Finished %s" % obj.name.upper())
+         
+     elif isinstance(obj, ContentLine):
+@@ -875,14 +897,18 @@
+         if obj.behavior and not startedEncoded: obj.behavior.encode(obj)
+         s=StringIO.StringIO() #unfolded buffer
+         if obj.group is not None:
+-            s.write(obj.group + '.')
++            s.write(str(obj.group + '.'))
+         if DEBUG: logger.debug("Serializing line" + str(obj))
+-        s.write(obj.name.upper())
++        s.write(str(obj.name.upper()))
+         for key, paramvals in obj.params.iteritems():
+-            s.write(';' + key + '=' + ','.join(map(dquoteEscape, paramvals)))
+-        s.write(':' + obj.value)
++            s.write(';' + str(key) + '=' + ','.join(map(dquoteEscape, paramvals)).encode("utf-8"))
++        if isinstance(obj.value, unicode):
++            strout = obj.value.encode("utf-8")
++        else:
++            strout = obj.value
++        s.write(':' + strout)
+         if obj.behavior and not startedEncoded: obj.behavior.decode(obj)
+-        foldOneLine(outbuf, s, lineLength)
++        foldOneLine(outbuf, s.getvalue(), lineLength)
+         if DEBUG: logger.debug("Finished %s line" % obj.name.upper())
+     
+     return buf or outbuf.getvalue()
+@@ -1023,7 +1049,7 @@
      else:
          obj = ContentLine(name, [], '')
      obj.behavior = behavior

Added: CalendarServer/trunk/lib-patches/vobject/tests.tests.patch
===================================================================
--- CalendarServer/trunk/lib-patches/vobject/tests.tests.patch	                        (rev 0)
+++ CalendarServer/trunk/lib-patches/vobject/tests.tests.patch	2006-12-08 16:38:13 UTC (rev 762)
@@ -0,0 +1,56 @@
+Index: tests/tests.py
+===================================================================
+--- tests/tests.py	(revision 164)
++++ tests/tests.py	(working copy)
+@@ -1,3 +1,4 @@
++# -*- coding: latin-1 -*-
+ """Long or boring tests for vobjects."""
+ 
+ # add source directory to front of sys path
+@@ -280,7 +281,7 @@
+     >>> silly.stuff
+     <STUFF{}foldedline>
+     >>> original = silly.serialize()
+-    >>> f3 = StringIO.StringIO(original)
++    >>> f3 = StringIO.StringIO(original.decode("utf-8"))
+     >>> silly2 = base.readOne(f3)
+     >>> silly2.serialize()==original
+     True
+@@ -289,7 +290,7 @@
+     >>> ex1
+     <*unnamed*| [<CN{}Babs Jensen>, <CN{}Barbara J Jensen>, <EMAIL{}babs at umich.edu>, <PHONE{}+1 313 747-4454>, <SN{}Jensen>, <X-ID{}1234567890>]>
+     >>> ex1.serialize()
+-    u'CN:Babs Jensen\r\nCN:Barbara J Jensen\r\nEMAIL:babs at umich.edu\r\nPHONE:+1 313 747-4454\r\nSN:Jensen\r\nX-ID:1234567890\r\n'
++    'CN:Babs Jensen\r\nCN:Barbara J Jensen\r\nEMAIL:babs at umich.edu\r\nPHONE:+1 313 747-4454\r\nSN:Jensen\r\nX-ID:1234567890\r\n'
+     """,
+     
+     "Import icaltest" :
+@@ -306,7 +307,7 @@
+     >>> c.vevent.valarm.description.value
+     u'Event reminder, with comma\nand line feed'
+     >>> c.vevent.valarm.description.serialize()
+-    u'DESCRIPTION:Event reminder\\, with comma\\nand line feed\r\n'
++    'DESCRIPTION:Event reminder\\, with comma\\nand line feed\r\n'
+     >>> vevent = c.vevent.transformFromNative()
+     >>> vevent.rrule
+     <RRULE{}FREQ=Weekly;COUNT=10>
+@@ -352,6 +353,7 @@
+     >>> vevent.summary.value
+     u'The title \u3053\u3093\u306b\u3061\u306f\u30ad\u30c6\u30a3'
+     >>> summary = vevent.summary.value
++    >>> test = str(vevent.serialize()),
+     """,
+     
+     # make sure date valued UNTILs in rrules are in a reasonable timezone,
+@@ -690,9 +692,9 @@
+     u'home'
+     >>> card.group = card.tel.group = 'new'
+     >>> card.tel.serialize().strip()
+-    u'new.TEL;TYPE=fax,voice,msg:+49 3581 123456'
++    'new.TEL;TYPE=fax,voice,msg:+49 3581 123456'
+     >>> card.serialize().splitlines()[0]
+-    u'new.BEGIN:VCARD'
++    'new.BEGIN:VCARD'
+     >>> dtstart = base.newFromBehavior('dtstart')
+     >>> dtstart.group = "badgroup"
+     >>> dtstart.serialize()

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20061208/9e6acbec/attachment.html


More information about the calendarserver-changes mailing list