{"id":394,"date":"2007-11-25T09:15:44","date_gmt":"2007-11-25T13:15:44","guid":{"rendered":"http:\/\/www.dr-chuck.com\/wordpress\/?p=394"},"modified":"2011-12-17T12:24:27","modified_gmt":"2011-12-17T16:24:27","slug":"cleaning-up-my-desktop-sweet-ruby-code-for-meeting-maker-to-vcard","status":"publish","type":"post","link":"https:\/\/www.dr-chuck.com\/csev-blog\/2007\/11\/cleaning-up-my-desktop-sweet-ruby-code-for-meeting-maker-to-vcard\/","title":{"rendered":"Cleaning up my Desktop &#8211; Sweet Ruby Code for Meeting Maker to VCard"},"content":{"rendered":"<p>\nI wrote some Ruby code to convert from Meeting Maker to iCal&#8217;s VCARD format.  Then I sent it to Trek Glowaki and he rewrote it.<\/p>\n<p>\nHere is my<br \/>\n<a href=http:\/\/www.dr-chuck.com\/csev-blog\/000367.html>Original Version<\/a>.  Trek&#8217;s much cleaner version is below &#8211; it shows some pretty Ruby idioms.<\/p>\n<p><!--more--><\/p>\n<pre>\n<code>\n#!\/usr\/bin\/ruby\n# add some magic to Nil objects to simplify .empty? calls below\nclass NilClass\ndef empty?\ntrue\nend\nend\n# ask for a file path and remove \\r \\n and \\s from the end\nputs \"Path to meeting maker export:\"\nf = gets.chomp!.strip!\ncontacts = File.read(f).split(\"\\n\")\n# first two lines are junk\n2.times { contacts.shift }\n# 3rd line is header data. Map to hash of value => position (e.g. \"First Name\" => 1)\nh = {}\ncontacts.shift.split(\"\\t\").each_with_index {|contact,i| h[contact] = i}\ncontacts.each do |contact|\ncontact = contact.split(\"\\t\")\n# skip the nameless ones\nnext if contact.at(h[\"First Name\"]).empty? && contact.at(h[\"Last Name\"]).empty?\n# begin printing vcard\nputs \"BEGIN:VCARD\"\nputs \"VERSION:3.0\"\n# Name, which is a litle oddly formatted because of data presence \/ absence\nprint \"N:\"\nprint contact.at(h[\"Last Name\"]) unless contact.at(h[\"Last Name\"]).empty?\nprint \";\"\nprint contact.at(h[\"First Name\"]) unless contact.at(h[\"First Name\"]).empty?\nprint \";;;\\n\"\nprint \"FN:\"\nprint contact.at(h[\"First Name\"]) unless contact.at(h[\"First Name\"]).empty?\nprint \" \" unless ( contact.at(h[\"First Name\"]).empty? || contact.at(h[\"Last Name\"]).empty? )\nprint contact.at(h[\"Last Name\"]) unless contact.at(h[\"Last Name\"]).empty?\nprint \"\\n\";\n# Address, also a little odd\nunless 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?\nprint \"item1.ADR;type=WORK;type=pref:;;\"\n# Assume they are contiguous\nfor index in h[\"Address\"]..h[\"Country\"] do\nprint contact.at(index) unless contact.at(index).empty?\nprint \";\"\nend\nprint \"\\n\"\nend\n# The one liners, pretty easy\ncontact.each_with_index do |datum, i|\ncase h.index(i)\nwhen \"Company\"\nputs \"ORG:\" + datum + \";\"\nwhen \"Title\"\nputs \"TITLE:\" + datum + \";\"\nwhen \"Email\"\nputs \"EMAIL;type=INTERNET;type=WORK;type=pref:\" + datum\nwhen \"Work Phone\"\nputs \"TEL;type=WORK;type=pref:\" + datum\nwhen \"Home Phone\"\nputs \"TEL;type=HOME;type=pref:\" + datum\nwhen \"Mobile Phone\"\nputs \"TEL;type=CELL;type=pref:\" + datum\nend\nend\nputs \"END:VCARD\"\nprint \"\\n\"\nend\n<\/code>\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>I wrote some Ruby code to convert from Meeting Maker to iCal&#8217;s VCARD format. Then I sent it to Trek Glowaki and he rewrote it. Here is my Original Version. Trek&#8217;s much cleaner version is below &#8211; it shows some pretty Ruby idioms.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-394","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/posts\/394","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/comments?post=394"}],"version-history":[{"count":1,"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/posts\/394\/revisions"}],"predecessor-version":[{"id":2483,"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/posts\/394\/revisions\/2483"}],"wp:attachment":[{"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/media?parent=394"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/categories?post=394"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/tags?post=394"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}