Skip to content

Instantly share code, notes, and snippets.

@iwegner
Forked from johnjohndoe/vcard-split.py
Last active April 5, 2021 17:36
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 iwegner/82e0fc08e99d5a444549a1c0e3a11f8f to your computer and use it in GitHub Desktop.
Save iwegner/82e0fc08e99d5a444549a1c0e3a11f8f to your computer and use it in GitHub Desktop.
Python script to split Google contacts into individual VCF files.
#!/usr/bin/python3
# original version taken from https://gist.github.com/johnjohndoe/dada51bb886d419334de6fe13ce6d7bb
# Howto:
#* using python 3 call script, specify file name and add fist and last name if asked for.
#split vcf files
import re
import os #for working dir
import quopri # for utf-8 decodin
print("Welcome!")
print("This script converts a vcf file containing multiple contacts into multiple files.")
fname = input('Please specify the name of the input vcf file: ')
print("Processing file " + fname)
working_dir = os.getcwd()
split_prefix = 'vcard_'
output_name_default = 'contacts-part-'
output_name = output_name_default
charset_string = 'CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:'
vcards_per_file = 1
with open(fname,'r') as f:
count = 0
output_count = 1
results = []
for line in f:
# Read line by line until we reach BEGIN:VCARD again
if ("BEGIN:VCARD" in line):
count += 1
if (count <= vcards_per_file):
## uncomment in case last and first name needs to be switched
# if line.startswith('N:'):
# # LAST;FIRST -> FIRST;LAST Names
# line = re.sub(r'N:([^;]*);([^;]+)(;+)', r'N:\2;\1\3', line)
#In case of a character set, ask user to correct it
if line.startswith('N;' + charset_string):
print("*** Charset for field N detected.")
list = line[42:].split(';')
for item in list:
decoded_string = quopri.decodestring(item)
print (decoded_string.decode('utf-8'))
print("Please enter last and firstname without umlaut.")
correct_last_name = input('lastname: ')
correct_first_name = input('firstname: ')
line = 'N:' + correct_last_name + ';' + correct_first_name + ';;;\n'
if line.startswith('FN;' + charset_string):
print("Charset for field FN detected.")
list = line[43:].split(';')
for item in list:
decoded_string = quopri.decodestring(item)
print (decoded_string.decode('utf-8'))
correct_last_name = input('lastname: ')
correct_first_name = input('firstname: ')
line = 'FN:' + correct_first_name + ' ' + correct_last_name
#In case a field name is contained, use it for the file name
if line.startswith('FN:'):
output_name = line[3:] # cuts off 'FN:'
#remove escapes in names
escapes = ''.join([chr(char) for char in range(1, 32)])
translator = str.maketrans('', '', escapes)
output_name = output_name.translate(translator)
results.append(line)
else:
# We have read over a BEGIN:VCARD for more than vcards_per_file times and need to close the old file and start a new one
# Write file with values stored up to now
with open(os.path.abspath(os.path.join(working_dir, split_prefix + output_name + '_' + str(output_count) + '.vcf')),'w') as oFile:
for item in results:
oFile.write(item)
#increment outputfile count
output_count += 1
#clear results list and append line that we have read just now
del results[:]
results.append(line)
#set counter back to 1
count = 1
# Set filename back to default
output_name = output_name_default
#write the last set of results to a file
with open(os.path.abspath(os.path.join(working_dir, split_prefix + output_name + '_' + str(output_count) + '.vcf')),'w') as oFile:
for item in results:
oFile.write(item)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment