Get all values for an attribute in a vcard using python vobject

If I import a vcard with vobject like this:

with open(some_file_containing_a_vcard,
                  "r" , encoding="utf-8") as fd:
            vcard_content = vobject.readOne(fd.read(),
                                            ignoreUnreadable=True)

How fo I get all telephone numbers or emails, if there are more than one provides by the vcard?

I only found:

vcard_content.tel.value
vcard_content.email.value

...but this only returns the first of each.

As I dived into the code, it seems the entities are created as clases. So a vcard's attribute "TEL" gets created as "tel". What, if I have a cell and a work phone number?

I am totally stuck :-)

Upvotes: 2

Views: 1879

Answers (3)

chronospoon
chronospoon

Reputation: 637

There are attributes named tel_list and email_list that should provide the other entries you're looking for.

Elements in these lists act just like "tel" and "email", and each also has a .value and .type_param that you might want to check to disambiguate.

Upvotes: 0

wpercy
wpercy

Reputation: 10090

You can actually achieve this by using the contents attribute, which is a dictionary. So you would access a list of all TEL properties using something like

with open(path_to_vcard) as f:
    text = f.read()

card = vobject.readOne(text)
print card.contents['tel']

which will print the list of all TEL properties (even if there is only one or none).

Upvotes: 3

I solved it with the following code snippet:

stream = io.open(some_file_containing_a_vcard, "r", encoding="utf-8")
vcf = vobject.readComponents(stream, ignoreUnreadable=True)

for child in vcard.getChildren():
    name = child.name.lower()
    value = child.value
    attribs = child.params.get("TYPE", [])

    filtered_type = [x.lower() for x in attribs if x.lower() in (
                        "work", "home", "cell", "fax"
                    )]
    if len(filtered_type) == 0:
        filtered_type = ["unspec"]

    # Do something with it... i.e. adding to a dict()

stream.close()

This works for me :-)

Upvotes: 1

Related Questions