November 25, 2007

Cleaning up my Desktop - Sweet Ruby Code for Meeting Maker to VCard

I wrote some Ruby code to convert from Meeting Maker to iCal's VCARD format. Then I sent it to Trek Glowaki and he rewrote it.

Here is my Original Version. Trek's much cleaner version is below - it shows some pretty Ruby idioms.


#!/usr/bin/ruby
# add some magic to Nil objects to simplify .empty? calls below
class NilClass
  def empty?
    true
  end
end

# ask for a file path and remove \r \n and \s from the end
puts "Path to meeting maker export:"
f = gets.chomp!.strip!

contacts = File.read(f).split("\n")

# first two lines are junk
2.times { contacts.shift }

# 3rd line is header data. Map to hash of value => position (e.g. "First Name" => 1)
h = {}
contacts.shift.split("\t").each_with_index {|contact,i| h[contact] = i}
contacts.each do |contact|
  contact = contact.split("\t")
  
  # skip the nameless ones
  next if contact.at(h["First Name"]).empty? && contact.at(h["Last Name"]).empty?
  
  # begin printing vcard
  puts "BEGIN:VCARD"
  puts "VERSION:3.0"
  
  # Name, which is a litle oddly formatted because of data presence / absence
  print "N:"
  print contact.at(h["Last Name"]) unless contact.at(h["Last Name"]).empty?
  print ";"
  print contact.at(h["First Name"]) unless contact.at(h["First Name"]).empty?
  print ";;;\n"
  print "FN:"
  print contact.at(h["First Name"]) unless contact.at(h["First Name"]).empty? 
  print " " unless ( contact.at(h["First Name"]).empty? || contact.at(h["Last Name"]).empty? )
  print contact.at(h["Last Name"]) unless contact.at(h["Last Name"]).empty? 
  print "\n";
      
  # Address, also a little odd
  unless contact.at(h["Address"]).empty? && contact.at(h["City"]).empty? && contact.at(h["State"]).empty? && contact.at(h["ZIP"]).empty? && contact.at(h["Country"]).empty?
    print "item1.ADR;type=WORK;type=pref:;;"
    # Assume they are contiguous
    for index in h["Address"]..h["Country"] do
      print contact.at(index) unless contact.at(index).empty?
      print ";"
    end
    print "\n"
  end
  
  # The one liners, pretty easy
  contact.each_with_index do |datum, i|
    case h.index(i)
    when "Company"
      puts "ORG:" + datum + ";"
    when "Title"
      puts "TITLE:" + datum + ";"
    when "Email"
      puts "EMAIL;type=INTERNET;type=WORK;type=pref:" + datum
    when "Work Phone"
      puts "TEL;type=WORK;type=pref:" + datum
    when "Home Phone"
      puts "TEL;type=HOME;type=pref:" + datum
    when "Mobile Phone"
      puts "TEL;type=CELL;type=pref:" + datum
    end
  end
  puts "END:VCARD"
  print "\n"
end

Posted by csev at November 25, 2007 09:15 AM