#!/usr/bin/env ruby # -*- ruby -*- # # Outputs an HTML version of your Address Book # # -------------------------------------------------- # Types # -------------------------------------------------- # A person with a first/last name, >=0 emails, and >0 phone numbers class Person attr_reader :first_name, :last_name, :emails, :phones def initialize(first_name,last_name) @first_name = first_name @last_name = last_name @emails = [] @phones = [] end def add_email(email) emails.push email if !emails.index(email) end def add_phone(phone) phones.push phone if !phones.index(phone) end end def log(s) STDERR.puts s.to_s + '...' end # -------------------------------------------------- # Functions # -------------------------------------------------- # Exports the contact list to vcards and returns the file def export_to_vcards() outfile = "contacts.vcard" log 'Exporting address book to ' + outfile script = < " + outfile return outfile end # We may want to change this later def output(s) puts s end def html_header() s = '' s += '' s += '' return s end def html_footer() s = '' s += '' return s end def html_page_start() s = '' return s end def html_page_end() s = '
' return s end def html_menu(keys) s = '
' keys.sort.each do |k| s += '' + k.upcase + '' s += ' ' end s += '
' return s end def html_row_header() s = '' s += 'Name' s += 'Phone' s += 'Email' s += '' return s end def html_person_row(p) s = '' s += '' s += p.last_name if p.last_name s += ', ' if p.last_name && p.first_name s += p.first_name if p.first_name s += '' def out_list(lst,prefix) s = '' first = true lst.each do |x| s += '
' if !first s += '' + x + '' first = false end return s end s += '' s += out_list p.phones, 'mailto' s += '' s += '' s += out_list p.emails, 'mailto' s += '' s += '' return s end # Parses the vcards and outputs the results def parse_vcards(vcard_file) output html_header # Collect all the people log 'Parsing vcards from ' + vcard_file names = nil phones = [] emails = [] last_chars2person_lists = {} IO.foreach vcard_file do |line| line = line.strip names = /^N:([^;]+);([^;]+);/.match(line) if !names line.scan /^EMAIL;.*:(.*)/ do |res| emails.push res[0] end line.scan /TEL;.*:(.*)/ do |res| phones.push res[0] end if /^END:VCARD/ =~ line if names && !phones.empty? ln = names[1] fn = names[2] p = Person.new fn, ln phones.map {|x| p.add_phone x} emails.map {|x| p.add_email x} c = nil if ln && ln.length>0 c = ln.downcase[0..0] else c = fn.downcase[0..0] end lst = last_chars2person_lists[c] lst = [] if !lst lst.push p last_chars2person_lists[c] = lst end names = nil phones = [] emails = [] end end output html_menu(last_chars2person_lists.keys) output html_page_start # Output all the people sorted_chars2people = last_chars2person_lists.sort {|a,b| a[0] <=> b[0]} sorted_chars2people.each do |c,lst| next if lst.empty? sorted_lst = lst.sort {|p1,p2| p1.last_name <=> p2.last_name} output '' sorted_lst.map { |p| output html_person_row(p) } end output html_page_end output html_footer log 'Cleaning up' begin File.delete vcard_file rescue Exception => e log e.to_s end end def main(argv) parse_vcards export_to_vcards end main ARGV