Skip to content

Instantly share code, notes, and snippets.

@jseifer
Created June 24, 2009 17:37
Show Gist options
  • Save jseifer/135408 to your computer and use it in GitHub Desktop.
Save jseifer/135408 to your computer and use it in GitHub Desktop.
# Export old iphone address book backup to vcards so you can reimport.
# Use a tool like the Backup extractor (http://supercrazyawesome.com/)
# to get the backup created, then grab Library/AddressBook/AddressBook.sqlitedb
# and AddressBookImages.sqlitedb. Put them in this directory.
#
# Requires sqlite3 gem and vpim gem
# Usage: ruby export.rb > filename.vcf
require 'rubygems'
require 'sqlite3'
require 'vpim/vcard'
address_book = SQLite3::Database.new('AddressBook.sqlitedb')
address_book_images = SQLite3::Database.new('AddressBookImages.sqlitedb')
multi_value_entry_keys = Hash.new
multi_value_labels = Hash.new
# The tables dont have a row id column but refer to them some how anyway.
row_id = 1
address_book.execute("select * from ABMultiValueEntryKey") do |ab_multi_value_entry_key|
value = ab_multi_value_entry_key
multi_value_entry_keys[row_id] = value
row_id += 1
end
row_id = 1
address_book.execute("select * from ABMultiValueLabel") do |ab_multi_value_label|
multi_value_labels[row_id] = ab_multi_value_label.first.gsub('_$!<', '').gsub('>!$_', '')
row_id += 1
end
vcards = []
address_book.execute("select * from ABPerson") do |person|
row_id, first, last, middle, first_phonetic, last_phonetic, organization, \
department, note, kind, birthday, jobtitle, nickname, prefix, suffix, \
first_sort, last_sort, creation_date, modification_date, \
composite_name_fallback, external_identifier, store_id, display_name, \
first_sort_selection, last_sort_selection, first_sort_lang_idx, \
last_sort_language_index = person
card = Vpim::Vcard::Maker.make2 do |maker|
maker.add_name do |name|
name.prefix = prefix unless prefix.nil?
name.suffix = suffix unless suffix.nil?
name.family = last unless last.nil?
name.given = first unless first.nil?
end
address_book.execute("select * from ABMultiValue where (record_id = #{row_id})") do |multi_value|
uid, record_id, property, identifier, label, value = multi_value
if !value.nil? # phone or email
if value =~ /\w+\@\w+/ # email?
maker.add_email(value) { |email| email.location = multi_value_labels[label.to_i] }
else # phone..
maker.add_tel(value) { |phone| phone.location = multi_value_labels[label.to_i] }
end
else
# street address, etc
maker.add_addr do |addr|
addr.location = [multi_value_labels[label.to_i]]
address_book.execute("select * from ABMultiValueEntry where (parent_id = #{record_id})") do |multi_value_entry|
parent_id, multi_value_entry_key, multi_value_entry_key_value = multi_value_entry
address_line = multi_value_entry_keys[multi_value_entry_key.to_i].first.downcase
next if address_line == 'countrycode'
address_line = "postalcode" if address_line == 'zip'
address_line = "region" if address_line == 'state'
address_line = "locality" if address_line == "city"
addr.send("#{address_line}=", multi_value_entry_key_value)
end
end
end
end
end
vcards << card
end
vcards.each {|card| puts card.to_s}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment