Importing Windows Mobile contacts

(initial version of script + usage info)
(Updated script with more fields)
 
(6 intermediate revisions not shown)
Line 1: Line 1:
== Import how to ==
== Import how to ==
-
To import data, we need a backup file created by the approach mentioned in [[Data transfer]], the script mentioned in the end of this page and a N900 (or another Maemo5 device). Powerusers don't need to follow this precisely, others do:
+
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 [[Nokia N900|N900]] (or another Maemo5 device). Power users don't need to follow this precisely, others do:
-
# 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.
+
# connect N900 to PC using mass storage mode; from PC, create a directory "datatransfer" on the "flash disk device" - and copy the script (<code>pimbackup2vcf.py</code>) and backup file (e.g. PIMBackup_20091220.pib) to the directory. Unmount and disconnect.
# on N900, run xterm
# on N900, run xterm
# <pre>cd /home/user/MyDocs/datatransfer; python pimbackup2vcf.py PIMBackup_20091220.pib contacts.vcf</pre>
# <pre>cd /home/user/MyDocs/datatransfer; python pimbackup2vcf.py PIMBackup_20091220.pib contacts.vcf</pre>
# 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.
# 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.
# You should have the contacts imported. :)
# You should have the contacts imported. :)
-
 
== pimbackup2vcf.py ==
== pimbackup2vcf.py ==
-
<pre>
+
<source lang="python">
#!/usr/bin/python2.5
#!/usr/bin/python2.5
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
Line 55: Line 54:
def csvline2vcf(row):
def csvline2vcf(row):
rv=""
rv=""
-
rv=rv+"BEGIN:VCARD"+'\n'
+
rv+="BEGIN:VCARD"+'\n'
-
rv=rv+"VERSION:3.0"+'\n'
+
rv+="VERSION:3.0"+'\n'
rv=addne(rv, "N:", csvf(row, "Name"))
rv=addne(rv, "N:", csvf(row, "Name"))
rv=addne(rv, "FN:", csvf(row, "First Name")+" "+csvf(row, "Last Name"))
rv=addne(rv, "FN:", csvf(row, "First Name")+" "+csvf(row, "Last Name"))
Line 73: Line 72:
rv=addne(rv, "BDAY:", convdate(csvf(row, "Birthday")))
rv=addne(rv, "BDAY:", convdate(csvf(row, "Birthday")))
rv=addne(rv, "X-ANNIVERSARY:", convdate(csvf(row, "Anniversary")))
rv=addne(rv, "X-ANNIVERSARY:", convdate(csvf(row, "Anniversary")))
-
rv=rv+"END:VCARD"+'\n'+'\n'
+
rv+="END:VCARD"+'\n'+'\n'
return rv
return rv
Line 88: Line 87:
zf=zipfile.ZipFile(sys.argv[1])
zf=zipfile.ZipFile(sys.argv[1])
-
contactsFN=[fn for fn in zf.namelist() if (fn.find('contacts')!=-1)][0]
+
contactsFN=[fn for fn in zf.namelist() if 'contacts' in fn][0]
Line 106: Line 105:
if lineNo==0:
if lineNo==0:
csv_fields=row
csv_fields=row
-
lineNo=lineNo+1
+
lineNo+=1
else:
else:
vcf.write(csvline2vcf(row))
vcf.write(csvline2vcf(row))
Line 113: Line 112:
os.remove(TMPFILENAME)
os.remove(TMPFILENAME)
-
</pre>
+
</source>
== Extending the script ==
== 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.
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.
 +
 +
== Updated script with more fields ==
 +
Definition fields are extended, and include both Home and Work address.
 +
More Cell Phone numbers created based on limitation of Windows Mobile that has only one Mobile Number field, but some people has more than one Cellphone number, so user usually utilize Radio, Pager, Car Phone as the subsequent mobile numbers.
 +
 +
The mapping is arbitrary, adjust to each need/usage.
 +
 +
Replace (pay attention to the start and end of the row) above with this code below.
 +
 +
<source lang="python">
 +
def csvline2vcf(row):
 +
    rv=""
 +
    rv+="BEGIN:VCARD"+'\n'
 +
    rv+="VERSION:3.0"+'\n'
 +
    rv=addne(rv, "N:", csvf(row, "Last Name")+";"+csvf(row, "First Name")+" "+csvf(row, "Middle Name"))
 +
    rv=addne(rv, "FN:", csvf(row, "Display 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, "TEL;TYPE=WORK,VOICE:", csvf(row, "Work Phone"))
 +
    rv=addne(rv, "TEL;TYPE=CELL,VOICE:", csvf(row, "Car Phone"))
 +
    rv=addne(rv, "TEL;TYPE=CELL,VOICE:", csvf(row, "Pager"))
 +
    rv=addne(rv, "TEL;TYPE=CELL,VOICE:", csvf(row, "Radio Phone"))
 +
    rv=addne(rv, "TEL;TYPE=CELL,VOICE:", csvf(row, "Assistant's Phone"))
 +
    rv=addne(rv, "TEL;TYPE=WORK,FAX:", csvf(row, "Business Fax"))
 +
    rv=addne(rv, "URL:", csvf(row, "Web Page"))
 +
    rv=addne(rv, "EMAIL;TYPE=PREF,INTERNET:", csvf(row, "E-mail Address"))
 +
    rv=addne(rv, "EMAIL;TYPE=HOME,INTERNET:", csvf(row, "E-mail 2 Address"))
 +
    rv=addne(rv, "EMAIL;TYPE=WORK,INTERNET:", csvf(row, "E-mail 3 Address"))
 +
    rv=addne(rv, "TITLE:", csvf(row, "Job Title"))
 +
    rv=addne(rv, "ROLE:", csvf(row, "Department"))
 +
    rv=addne(rv, "ORG:", csvf(row, "Company"))
 +
    rv=addne(rv, "ADR;TYPE=HOME:", ";"+";"+csvf(row, "Home Street")+';'+csvf(row, "Home City")+';'+csvf(row, "Home State")+';'+csvf(row, "Home Postal Code")+';'+csvf(row, "Home Country"))
 +
    rv=addne(rv, "ADR;TYPE=WORK:", ";"+";"+csvf(row, "Business Street")+';'+csvf(row, "Business City")+';'+csvf(row, "Business State")+';'+csvf(row, "Business Postal Code")+';'+csvf(row, "Business Country"))
 +
    rv=addne(rv, "ADR;TYPE=HOME:", ";"+";"+csvf(row, "Other Street")+';'+csvf(row, "Other City")+';'+csvf(row, "Other State")+';'+csvf(row, "Other Postal Code")+';'+csvf(row, "Other 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
 +
</source>
 +
 +
== Note ==
 +
If on the Windows Mobile (WM 6.5.3) the address has a hard return character, the resulting vcf will have broken address field (hard return instead of one row). User might want to review this using text editor first prior to importing.
 +
   
 +
[[Category:Power users]]
 +
[[Category:HowTo]]

Latest revision as of 10:11, 7 December 2010

Contents

[edit] 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. :)

[edit] 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)

[edit] 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.

[edit] Updated script with more fields

Definition fields are extended, and include both Home and Work address. More Cell Phone numbers created based on limitation of Windows Mobile that has only one Mobile Number field, but some people has more than one Cellphone number, so user usually utilize Radio, Pager, Car Phone as the subsequent mobile numbers.

The mapping is arbitrary, adjust to each need/usage.

Replace (pay attention to the start and end of the row) above with this code below.

def csvline2vcf(row):
    rv=""
    rv+="BEGIN:VCARD"+'\n'
    rv+="VERSION:3.0"+'\n'
    rv=addne(rv, "N:", csvf(row, "Last Name")+";"+csvf(row, "First Name")+" "+csvf(row, "Middle Name"))
    rv=addne(rv, "FN:", csvf(row, "Display 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, "TEL;TYPE=WORK,VOICE:", csvf(row, "Work Phone"))
    rv=addne(rv, "TEL;TYPE=CELL,VOICE:", csvf(row, "Car Phone"))
    rv=addne(rv, "TEL;TYPE=CELL,VOICE:", csvf(row, "Pager"))
    rv=addne(rv, "TEL;TYPE=CELL,VOICE:", csvf(row, "Radio Phone"))
    rv=addne(rv, "TEL;TYPE=CELL,VOICE:", csvf(row, "Assistant's Phone"))
    rv=addne(rv, "TEL;TYPE=WORK,FAX:", csvf(row, "Business Fax"))
    rv=addne(rv, "URL:", csvf(row, "Web Page"))
    rv=addne(rv, "EMAIL;TYPE=PREF,INTERNET:", csvf(row, "E-mail Address"))
    rv=addne(rv, "EMAIL;TYPE=HOME,INTERNET:", csvf(row, "E-mail 2 Address"))
    rv=addne(rv, "EMAIL;TYPE=WORK,INTERNET:", csvf(row, "E-mail 3 Address"))
    rv=addne(rv, "TITLE:", csvf(row, "Job Title"))
    rv=addne(rv, "ROLE:", csvf(row, "Department"))
    rv=addne(rv, "ORG:", csvf(row, "Company"))
    rv=addne(rv, "ADR;TYPE=HOME:", ";"+";"+csvf(row, "Home Street")+';'+csvf(row, "Home City")+';'+csvf(row, "Home State")+';'+csvf(row, "Home Postal Code")+';'+csvf(row, "Home Country"))
    rv=addne(rv, "ADR;TYPE=WORK:", ";"+";"+csvf(row, "Business Street")+';'+csvf(row, "Business City")+';'+csvf(row, "Business State")+';'+csvf(row, "Business Postal Code")+';'+csvf(row, "Business Country"))
    rv=addne(rv, "ADR;TYPE=HOME:", ";"+";"+csvf(row, "Other Street")+';'+csvf(row, "Other City")+';'+csvf(row, "Other State")+';'+csvf(row, "Other Postal Code")+';'+csvf(row, "Other 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

[edit] Note

If on the Windows Mobile (WM 6.5.3) the address has a hard return character, the resulting vcf will have broken address field (hard return instead of one row). User might want to review this using text editor first prior to importing.