Getting a Frequent Sender List With Mail.app and rb-appscript

January 10th, 2009  |  Published in ruby

I was in a meeting yesterday morning when the issue of how often an internal mailing list was utilized came up, so this morning’s fiddle-around time was devoted to using rb-appscript with Mail.app. Once I had a simple message count, I got curious about the days of the week the list was most used and the most frequent contributors, so I tossed in a Google chart and top contributor list:


#!/usr/bin/ruby

require 'rubygems'

require 'appscript'

require 'google_chart'

include Appscript



class Array  # http://snippets.dzone.com/posts/show/2161%20%20def%20sum

  def sum 

    inject( nil ) { |sum,x| sum ? sum+x : x }

  end

end



mail = app("Mail")

account = mail.accounts["Jupitermedia"]

pitch_folder = account.mailboxes["pitch"]



messages = pitch_folder.messages.get



messages_count = messages.size



days = Hash.new(0)

senders = Hash.new(0)

dates = Hash.new(0)



count = 0 

messages.each do |m|

  if m.sender.get =~ /@jupitermedia\.com/ && m.subject.get =~ /^social/i

    date = m.date_received.get.strftime("%Y-%m-%d")

    day = m.date_received.get.strftime("%A")

    sender = m.sender.get.gsub(/<.+?>/, "")

    senders[sender] +=1

    days[day] +=1

    dates[date] +=1

    count +=1

  end



end



puts "#{count} total messages sent to the list."

puts "#{dates.values.sum / dates.size} per day average."



dc = GoogleChart::PieChart.new('500x200', "",  false) 

  days.each do |d,c|

    dc.data "#{d} (#{c})", c

  end





puts dc.to_url



senders.sort {|a,b| b[1] <=> a[1]}.each  { |s| puts "#{s[0]}: #{s[1]}"}



The resulting chart:

Message Day of the Week Chart

The IMAP mailbox I was getting the messages from currently has 4,351 messages. My initial whack at it involved using a filter in rb-appscript to get the right messages, since the list’s contributors follow a subject line naming convention:


messages = pitch_folder.messages[its.subject.begins_with("social")].get

That took about 24 seconds to run. When I dropped the filter and added a conditional to the block where I processed the messages, it took about six seconds to run (and it didn’t make my MacBook’s fan spin up, which sometimes means I’m asking a lot of it, or sometimes means TextMate is about to make my life very, very hard).

appscript’s filters are still pretty handy. The reference forms documentation provides a complete list of available filters. I’d like it if there was regexp support, either similar to the way String’s index method works or with a simple “regexp” method.

Leave a Response

© Michael Hall, licensed under a Creative Commons Attribution-ShareAlike 3.0 United States license.