1
    #!/usr/bin/env python2.7

    import vobject

    abfile='/foo/bar/directory/file.vcf'

    def test_vobject_dot_readOne():
        with open(abfile) as f:
            vcard = vobject.readOne(f)
            vcard = vobject.readOne(f)

    test_vobject_dot_readOne()

The above code does not work but if we remove one of the two repeated statements it does. I would like to read vcards one by one. Is there a way to do this with vobject.readOne(f)? How can I read vcard n from the file?

The vcf file I'm using is taken from google contacts (exporting as vcard format). Here is the file contents that I have used in the test with only two vcards:

    BEGIN:VCARD 
    VERSION:3.0
    FN:Foo_bar1
    N:;Foo_bar1;;;
    EMAIL;TYPE=INTERNET:foobar1@foo.bar.com
    END:VCARD
    BEGIN:VCARD
    VERSION:3.0
    FN:Foo_bar2 
    N:;Foo_bar2;;;
    EMAIL;TYPE=INTERNET:foobar2@foo.bar.com
    END:VCARD

One can then use the Vcard readings to perform comparisons to avoid duplicates as shown in another question:

To remove vcard contact duplicates, comparing if two vcards are equal in .vcf file does not work with simple == vobject comparison

Community
  • 1
  • 1
  • Could you please provide a complete example we can run so that we can see the kind of error you are getting? – EvensF Jan 04 '17 at 01:27
  • this is all the code!!! – Brian Barcelona Jan 04 '17 at 01:30
  • I'm using pycharm. With one call to vobject.readOne(f) the above code works ok but with two it does not. My idea is to read several vcards and select the ones that satisfy a given function. You can test it by simply trying to print the vcard after each readOne call. – Brian Barcelona Jan 04 '17 at 01:35
  • please, let me know if I'm not making any sense with my comments and questions... – Brian Barcelona Jan 04 '17 at 01:36
  • the code should have at the end test_vobject_dot_readOne() ... just forgot to add the call to the function... (I just edited the question to reflect this) – Brian Barcelona Jan 04 '17 at 01:37
  • OK. I will suppose that there is an `import vobject` somewhere. Can you provides us with an example of `file.vcf` ? – EvensF Jan 04 '17 at 01:57
  • I just added the import vobject statement at the beginning and added an example of a vcf file. Thank you for following up on this! – Brian Barcelona Jan 04 '17 at 03:01
  • Add the print statements to your code and provide the output you are getting please – Mad Physicist Jan 04 '17 at 03:06
  • Another suggestion: after the first call to `readOne`, print the remainder of `f` Instead of calling `readOne` again. See if the remainder of the file is actually the second card of if the previous read chopped off too much. – Mad Physicist Jan 04 '17 at 03:14
  • thank you for your inquiry Mad Physicist. There are no print statements! The code crashes... and a question to you... how do you "print the remainder of f" ??? – Brian Barcelona Jan 04 '17 at 21:55

1 Answers1

2

Well let's hope I understood correctly what you were trying to do.

Are you trying to do something like this?

#!/usr/bin/env python2.7

import vobject

test_vcard_information = r"""BEGIN:VCARD
VERSION:3.0
FN:Foo_bar1
N:;Foo_bar1;
EMAIL;TYPE=INTERNET:foobar1@foo.bar.com
END:VCARD
BEGIN:VCARD
VERSION:3.0
FN:Foo_bar2
N:;Foo_bar2;
EMAIL;TYPE=INTERNET:foobar2@foo.bar.com
END:VCARD
"""

for vcard in vobject.readComponents(test_vcard_information):
    print vcard.fn.value

Or if you have the information in a file:

#!/usr/bin/env python2.7

import vobject

test_filename = r'/path/to/Test_addressbook.vcf'

with open(test_filename) as source_file:
    for vcard in vobject.readComponents(source_file):
       print vcard.fn.value

You would probably use .readOne() with a calendar file (.ics) since it would be composed of a single root object like in this example:

#!/usr/bin/env python2.7

import vobject

test_calendar_information = r"""BEGIN:VCALENDAR
PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Toronto
BEGIN:DAYLIGHT
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
TZNAME:EDT
DTSTART:19700308T020000
RRULE:FREQ=YEARLY;BYDAY=2SU;BYMONTH=3
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
TZNAME:EST
DTSTART:19701101T020000
RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=11
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
CREATED:20170104T022518Z
LAST-MODIFIED:20170104T022643Z
DTSTAMP:20170104T022643Z
UID:3fab09d6-59bb-430b-8b21-56c9636871e2
SUMMARY:Write a chapter
CATEGORIES:Projects
DTSTART;TZID=America/Toronto:20170105T140000
DTEND;TZID=America/Toronto:20170105T150000
TRANSP:OPAQUE
X-MOZ-GENERATION:2
LOCATION:At home
DESCRIPTION:One day I will be a great writer but I have to start somewhere...
SEQUENCE:1
END:VEVENT
BEGIN:VEVENT
CREATED:20170104T022346Z
LAST-MODIFIED:20170104T022654Z
DTSTAMP:20170104T022654Z
UID:b304f46a-f533-4aa4-8ee1-3b59649dedfa
SUMMARY:See a movie
CATEGORIES:Entertainment
DTSTART;TZID=America/Toronto:20170103T110000
DTEND;TZID=America/Toronto:20170103T140000
TRANSP:OPAQUE
X-MOZ-GENERATION:4
LOCATION:Somewhere over the rainbow
DESCRIPTION:The Wizard of Oz is movie I haven't seen in a long time.\n\nWe
  should schedule a time to see it
SEQUENCE:1
END:VEVENT
END:VCALENDAR"""

vcalendar = vobject.readOne(test_calendar_information)
for vevent in vcalendar.vevent_list:
    print vevent.summary.value

Or if it is in a file:

#!/usr/bin/env python2.7

import vobject

test_filename = r'/path/to/Test_Calendar.ics'

with open(test_filename) as source_file:
    vcalendar = vobject.readOne(source_file)
    for vevent in vcalendar.vevent_list:
        print vevent.summary.value
EvensF
  • 1,479
  • 1
  • 10
  • 17
  • Hi, this is very helpful! Is there a way to access vcard 54 in a file? (as if vcards were on an array) – Brian Barcelona Jan 04 '17 at 07:52
  • I could copy each of the vcards on an array and then access them but it seems there should be an easier solution... – Brian Barcelona Jan 04 '17 at 07:59
  • I'd like to get documentation on vobject to understand better your code and when to use readOne (and other options), is there a particular link to do so that you can recommend? Why would readOne not work the second time? (Perhaps that's explained by the link you sent for the previous question.) Thank you!!! – Brian Barcelona Jan 04 '17 at 08:00
  • Based on your suggestion, I have posted a follow on question in: http://stackoverflow.com/q/41460013/5965670 . Thank you again! – Brian Barcelona Jan 04 '17 at 10:19
  • I have never worked with `vobject` before so I cannot give you a definitive answer. I have based my answer on the [online documentation](https://eventable.github.io/vobject/#parsing-icalendar-objects) and by experimenting with it. But I don't think you can access directly a vcard in a file, like an array. – EvensF Jan 04 '17 at 11:42
  • Thank you very much for the pointer. I have been able to use it to answer my other question http://stackoverflow.com/q/41460013/5965670 ... the insight being that you can use "serialize()" to compare two vcards... However... I feel like there should be a better way to answer my other question... – Brian Barcelona Jan 04 '17 at 15:35