Skip to content

Instantly share code, notes, and snippets.

@bl00m
Last active November 25, 2022 15:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bl00m/7311bbc3a9dde9350848b80ea0be7363 to your computer and use it in GitHub Desktop.
Save bl00m/7311bbc3a9dde9350848b80ea0be7363 to your computer and use it in GitHub Desktop.
Read VCF (vCard) contact export file and print phone numbers
#!/bin/env python3
import sys
VCF_FILE = './contacts.vcf'
def main():
alist = []
with open(VCF_FILE, 'r') as f:
vcard = None
for line in f.readlines():
line = line[:-1]
if line == 'BEGIN:VCARD':
vcard = {
'name': None,
'tels': []
}
elif vcard is None:
print(f"File {VCF_FILE} is invalid", file=sys.stderr)
return
elif line == 'END:VCARD':
if vcard['name'] is None or len(vcard['tels']) == 0:
print(f"Invalid VCARD: {repr(vcard)}", file=sys.stderr)
else:
alist.append(vcard)
vcard = None
elif line.startswith('FN:'):
vcard['name'] = line[3:]
elif line.startswith('FN;CHARSET=UTF-8'):
_, val = line.split(':')
vcard['name'] = decode_name(val)
elif line.startswith('TEL;'):
_, num = line[4:].split(':')
vcard['tels'].append(num)
if vcard is not None:
print(f"Unterminated VCARD: {repr(vcard)}", file=sys.stderr)
alist = sorted(alist, key=lambda v: v['name'])
for vcard in alist:
print(f"{vcard['name']}: {', '.join(vcard['tels'])}")
def decode_name(value):
value = value.strip('=').split('=')
out = bytearray([int(char, base=16) for char in value]).decode("UTF-8")
return out
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment