2012
12.20

A few months ago my N900 (touchscreen) died. Without a working touchscreen it proved to be impossible to operate it. Although I could have logged in via SSH unfortunately my WIFI and 3G were of 🙁 So there was no possibly to create an export of all my data. Fortunately I had a backup. The only problem was that the backup was just a set of zip files:

# ll
totaal 4,0M
-rw-r--r-- 1 lorem ipsum 1,1K sep 25  2011 applications.zip
-rw-r--r-- 1 lorem ipsum  678 sep 25  2011 backup.metadata
-rw-r--r-- 1 lorem ipsum 233K sep 25  2011 bookmarks.zip
-rw-r--r-- 1 lorem ipsum 2,2M sep 25  2011 comm_and_cal.zip
-rw-r--r-- 1 lorem ipsum 1,6M sep 25  2011 settings.zip

containing “raw” dumps of directories. Not particularly useful for transferring to a new phone…

After some searching I found a file called addressbook.db (in comm_and_cal.zip:/home/user/.osso-abook-backup/db/) which should contain my contacts (vcard data). I read that addressbook.db was a Berkeley DB (BDB) database file. Because I was learning Python I wrote a simple script to extract the vcard data from the database and write it as separate vcards (which are easy to import on other devices) to a folder.

I hope it useful for someone else and please comment my python skills 🙂

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import vobject
from bsddb3 import db

if len(sys.argv) != 2:
  print ""
  print "Usage:"
  print "%s [path to addressbook.db]" % sys.argv[0]
  print ""
  sys.exit(1)

fileName = sys.argv[1].strip()

addressBookDb = db.DB()
try:
  # Try to open db file
  addressBookDb.open(fileName, None, db.DB_HASH, db.DB_DIRTY_READ)

  cursor = addressBookDb.cursor()
  record = cursor.first()

  # Fill a list with vcard strings from db 
  vCards = []
  while record:

    # Get vcard string and correct line endings
    vCardString = record[1].replace('\x00', '\r\n')
    vCards.append(vCardString)

    record = cursor.next()

  # Write vcard strings
  for vCard in vCards:

    parsedVCard = vobject.readOne(vCard)
    
    # Not all entries have a n(ame) attribute
    if hasattr(parsedVCard, 'n'):
      vCardName = str(parsedVCard.n.value).strip()
      
      # Open vcard for writing
      with open('vcards/%s.vcf' % vCardName, 'w') as fd:
        fd.write(vCard)
      fd.close()

except db.DBNoSuchFileError:
  print ""
  print "Error:"
  print "Could not open '%s'" % fileName
  print ""
  sys.exit(1)

References:

9 comments so far

Add Your Comment
  1. Mischa ter Smitten

    Pease, can you explain to the average user how to RUN a python script?

  2. Mischa ter Smitten

    Are you a Windows or a Linux user? Linux is a lot simpler…

  3. Mischa ter Smitten

    pls how to run this script in windows i get errors when trying to run it i changed the path of addressbook.db

  4. Mischa ter Smitten

    hi,
    thanks very much for your script. for me it worked on most of the contacts, however it failed if a name contained a ‘/’.
    and as a really minor flaw – if the name contains non-ascii characters, the filename of the vcf gets messed up, however in the vcf itself the characters are preserved (i have some contacts written in mandarin) – so no big deal
    great work, this saved me a lot of time! thanks so much!

  5. Mischa ter Smitten

    You’re welcome. Do you have fixes for the python script?

  6. Mischa ter Smitten

    The scripts are on GitHub now. You can make the changes there.

  7. Mischa ter Smitten

    Now I love you dude!. My N900 usb port broken and I cannot charge it. I have to travel this week, so have no time to repair it. Now I can have my contacts from a not very old backup in another mobile until I repair my loved N900 🙂