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

Leave a Response

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