Importing Windows Mobile contacts

Import how to

To import data, we need a backup file created by the approach mentioned in Importing data, the script mentioned in the end of this page and a N900 (or another Maemo5 device). Power users don't need to follow this precisely, others do:

  1. connect N900 to PC using mass storage mode; from PC, create a directory "datatransfer" on the "flash disk device" - and copy the script (pimbackup2vcf.py) and backup file (e.g. PIMBackup_20091220.pib) to the directory. Unmount and disconnect.
  2. on N900, run xterm
  3. cd /home/user/MyDocs/datatransfer; python pimbackup2vcf.py PIMBackup_20091220.pib contacts.vcf
  4. start addressbook app, from the menu choose Get contacts and Import contacts file in the following popup. Choose the contacts.vcf file in datatransfer directory.
  5. You should have the contacts imported. :)

pimbackup2vcf.py

#!/usr/bin/python2.5
# -*- coding: utf-8 -*-

import zipfile
import csv
import sys,os
import codecs


def unicode_csv_reader(unicode_csv_data, dialect=csv.excel, **kwargs):
	# csv.py doesn't do Unicode; encode temporarily as UTF-8:
	csv_reader = csv.reader(utf_8_encoder(unicode_csv_data), dialect=dialect, **kwargs)
	for row in csv_reader:
		# decode UTF-8 back to Unicode, cell by cell:
		yield [unicode(cell, 'utf-8') for cell in row]

def utf_8_encoder(unicode_csv_data):
	for line in unicode_csv_data:
		yield line.encode('utf-8')
	unicode_csv_data.close()

def csvf(row, f):
	try:
		i=csv_fields.index(f)
	except:
		return ''
	
	return row[i]

def convdate(d):
	if len(d)<8:
		return ''
	return d[0]+d[1]+d[2]+d[3]+'-'+d[4]+d[5]+'-'+d[6]+d[7]

def addne(s, pre, post):
	if post=="":
		return s;
	else:
		return s+pre+post+'\n';

def csvline2vcf(row):
	rv=""
	rv+="BEGIN:VCARD"+'\n'
	rv+="VERSION:3.0"+'\n'
	rv=addne(rv, "N:", csvf(row, "Name"))
	rv=addne(rv, "FN:", csvf(row, "First Name")+" "+csvf(row, "Last Name"))
	rv=addne(rv, "NICKNAME:", csvf(row, "NickName"))
	rv=addne(rv, "TEL;TYPE=CELL,VOICE:", csvf(row, "Mobile Phone"))
	rv=addne(rv, "TEL;TYPE=WORK,VOICE:", csvf(row, "Business Phone"))
	rv=addne(rv, "TEL;TYPE=WORK,VOICE:", csvf(row, "Business Phone 2"))
	rv=addne(rv, "TEL;TYPE=HOME,VOICE:", csvf(row, "Home Phone"))
	rv=addne(rv, "TEL;TYPE=HOME,VOICE:", csvf(row, "Home Phone 2"))
	rv=addne(rv, "EMAIL;TYPE=PREF,INTERNET:", csvf(row, "E-mail Address"))
	rv=addne(rv, "TEL;TYPE=WORK,VOICE:", csvf(row, "Work Phone"))
	rv=addne(rv, "URL:", csvf(row, "Web Page"))
	if csvf(row, "Home City")!="":
		rv=addne(rv, "ADR:;;", csvf(row, "Home Street")+';'+csvf(row, "Home City")+';'+csvf(row, "Home State")+';'+csvf(row, "Home Postal Code")+';'+csvf(row, "Home Country"))
	
	rv=addne(rv, "BDAY:", convdate(csvf(row, "Birthday")))
	rv=addne(rv, "X-ANNIVERSARY:", convdate(csvf(row, "Anniversary")))
	rv+="END:VCARD"+'\n'+'\n'
	
	return rv


TMPFILENAME="/tmp/contacts.csc"

if len(sys.argv)<3:
	print sys.argv[0], " PIMbackupfile.pib output.vcf"
	sys.exit()

print "Processing", sys.argv[1]

zf=zipfile.ZipFile(sys.argv[1])

contactsFN=[fn for fn in zf.namelist() if 'contacts' in fn][0]


tmpfile=open(TMPFILENAME, 'w')

tmpfile.write(zf.read(contactsFN))

tmpfile.close()

cf=unicode_csv_reader(codecs.open(TMPFILENAME, 'r', "utf-16"), delimiter=';', quotechar='"')

vcf=codecs.open(sys.argv[2], 'w', "utf-8")

lineNo=0

for row in cf:
	if lineNo==0:
		csv_fields=row
		lineNo+=1
	else:
		vcf.write(csvline2vcf(row))

vcf.close()

os.remove(TMPFILENAME)

Extending the script

The script would, with little modifications, import contacts data from generally any csv file. The csv file has to contain initial line with columns' titles. Data contained in the output VCF file is defined in the csvline2vcf(row) function - which converts a csv line to a vcf record string.