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:

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.
