pythonvcf-vcardquoted-printablevobject

Error in parsing VCARD file using python VObject package


I am new to python.I am trying to parse VCARD 2.1 file using vobject 0.9.2 python package.
I am trying to parse this VCARD file:

BEGIN:VCARD   
VERSION:2.1  
N;ENCODING=QUOTED-PRINTABLE;CHARSET=UTF-8:I;AM;DUMMY;;  
TEL;CELL:123456789   
END:VCARD  

These are the python commands I used:

import vobject
f=open('sample.vcf','r')
vcf=vobject.readOne(f)  

then I am getting the following error:

Traceback (most recent call last):  
      File "<stdin>", line 1, in <module>  
      File "C:\Program Files\Anaconda3\lib\site-packages\vobject\base.py", line 1129, in readOne  
        allowQP))  
      File "C:\Program Files\Anaconda3\lib\site-packages\vobject\base.py",   line 1073, in readComponents  
        vline = textLineToContentLine(line, n)  
      File "C:\Program Files\Anaconda3\lib\site-packages\vobject\base.py", line 912, in textLineToContentLine
        'lineNumber' : n})
      File "C:\Program Files\Anaconda3\lib\site-packages\vobject\base.py", line 336, in __init__
        self.value = self.value.decode('quoted-printable')
      AttributeError: 'str' object has no attribute 'decode'   

link for error log https://paste.fedoraproject.org/391670/46866724/

Python is showing that str object has no attribute decode.

Here is the code snippet in vobject package source code where error is occurring:

if 'ENCODING' in self.params:  
        if 'QUOTED-PRINTABLE' in self.params['ENCODING']:  
            qp = True  
            self.params['ENCODING'].remove('QUOTED-PRINTABLE')  
            if 0==len(self.params['ENCODING']):  
                del self.params['ENCODING']  
    if 'QUOTED-PRINTABLE' in self.singletonparams:  
        qp = True  
        self.singletonparams.remove('QUOTED-PRINTABLE')  
    if qp:  
        self.value = self.value.decode('quoted-printable')   

By reading similar problems in stackoverflow I understand that vobject package is trying to decode an already decoded string.So i even tried converting vcf file to binary string and giving that as an input to vobject.readOne .

binstr = f.read('sample.vcf','r').encode('utf-8')
x=vobject.readOne(binstr)

but it is not working.

What I have to do to successfully parse VCARD file?
Please somebody help me...

EDIT: Now I understand that this error is due to incompatibility of vobject with python 3. Can I do any little hack to overcome this error?


Solution

  • There are three issues with your question.

    First: in the field N you missed ":"

    Second: vobject seems to require FN eventhough your version of vcard is 2.1 which stricly speaking does not require it.

    Third: instead of readOne I suggest you use vobject.readComponents

    In any case, if you don´t want to use readComponents, your code:

        f=open(vcardfile,'r')
        vcf=vobject.readOne(f)
    

    works with the following file:

        BEGIN:VCARD
        VERSION:2.1
        N:;ENCODING=QUOTED-PRINTABLE;CHARSET=UTF-8:I;AM;DUMMY;;
        FN:;;;;
        TEL;TYPE=CELL:123456789
        END:VCARD
    

    The following code also works with the above file:

        #!/usr/bin/env python3
    
        import vobject
    
        vcardfile='/Users/foo/bar/abovefile.vcf'
    
        with open(vcardfile) as source_file:
            vcardlist = vobject.readComponents(source_file)
            for vcard in vcardlist:
                print vcard
                print vcard.serialize()
                print vcard.prettyPrint
    

    And you should get the output:

        <VCARD| [<VERSION{}2.1>, <FN{};;;;>, <N{}AM ENCODING=QUOTED-PRINTABLE CHARSET=UTF-8:I  DUMMY>, <TEL{'TYPE': ['CELL']}123456789>]>
    
        BEGIN:VCARD
        VERSION:2.1
        FN:\;\;\;\;
        N:;ENCODING=QUOTED-PRINTABLE;CHARSET=UTF-8:I;AM;DUMMY
        TEL;TYPE=CELL:123456789
        END:VCARD
    
        VCARD
          VERSION: 2.1
          TEL: 123456789
             params for  TEL:
             TYPE ['CELL']
          FN: ;;;; 
          N: AM ENCODING=QUOTED-PRINTABLE CHARSET=UTF-8:I  DUMMY