Quixotic, Appscript, Mail
January 17th, 2009 | Published in ruby
I don’t know why I get into these things.
Below is a script that takes the selected messages in Mail.app and saves them to Yojimbo, which I like a lot for keeping schtuff.
Some things that might have told me to quit and use someone else’s AppleScript instead of rolling my own:
First, I couldn’t figure out how to make rb-appscript work with references between apps. So the part that grabs the attachment from Mail has no way to say to the part that imports the attachment to Yojimbo, “Hey … this object here is a file. Deal with it.” Instead, the file has to be stowed somewhere then picked up for use by Yojimbo.
Second, Yojimbo can’t import everything … like zip files, for instance. So instead of just doing something to catch exceptions I decided to go and read the MIME types of attachments then check them against an array of legal file types.
On the other hand, I can tag the attachments as they’re imported, and this is much faster than dragging the attachments into Yojimbo, because I can tie it to a Mail Act-On keystroke (and because Mail.app gets really slow with attachment handling sometimes, even if you don’t mind mousing).
And there’s one other good reason to do stuff like this: I’d rather get the practice with Ruby than crib AppleScript from someone else. I’ll take foo.split(',') over set AppleScript's text item delimiters to "," any day of the week.
#!/usr/bin/ruby
require 'rubygems'
require 'appscript'
require 'mime/types'
require 'osax'
include OSAX
include Appscript
mail = app("Mail")
yoj = app("Yojimbo")
tmpdir = "/Users/mph/tmp"
legal_files = ["image/gif", "image/jpeg", "application/pdf", "image/png", "application/word","text/plain", "application/msword", "text/html"]
messages = mail.selection.get
messages.each do |m|
m.mail_attachments.get.each do |a|
tmpfile = "#{tmpdir}/#{a.name.get}"
a.save(:in => tmpfile)
type = MIME::Types.type_for(tmpfile)[0]
if legal_files.include?(type)
yoj.import(tmpfile)
item = yoj.database_items.last
taglist = osax.display_dialog("Enter tags for #{a.name.get}", :default_answer => "", :buttons => ['Cancel', 'Okay'], :default_button => 2, :with_icon => :note).fetch(:text_returned).split(",")
taglist.each {|t| item.add_tags(t)}
else
osax.display_dialog("Yojimbo can't import #{a.name.get} - (filetype: #{type})", :with_icon => :stop)
end
File.delete(tmpfile)
end
end
