The Elegant Chaos Blog
News, thoughts, and other ramblings from the world of Elegant Chaos.

It’s amazing how easily I can get distracted.

Currently my main distraction is playing with Feed Me, my bayesian news filter, which is a thinly veiled excuse to mess about with Python.

However, yesterday I managed to get distracted from that distraction.

I’ve been thinking that I really need to sort out some productivity tools for myself, to deal with the sort of repetitive administrative tasks that I find myself doing again and again.

To that end, I installed FastScripts, and set about writing some trivial scripts to do some simple things.

One of the scripts I wanted was to find all the recent mails received from a particular person, since this is something that I do manually quite often. The script would only save a few keystrokes and mouse clicks, but I figured that if I could link it to a hot key with FastScripts, it would be handy.

Unfortunately, it turns out that Apple Mail’s scripting support doesn’t allow you to perform searches.

Luckily, there is a work around, in the form of the new GUI scripting capabilities of MacOS X.

Essentially, this allows you to ‘fake’ any user interface operation by scripting it in terms of the menus, buttons and or places that you would click, and the keys that you would press.

Presented below, for your delight and delectation, is a little example of how I used this to script a search in Mail.

The hardest part is working out exactly how to specify the interface widget that you’re trying to activate. A valuable helper here is the Prefab UI Browser which allows you to browse another application’s user interface whilst it’s running, so that you can discover the hierarchy of interface widgets.

The bad thing with all of this, of course, is that it’s a very fragile way to program. By relying on the names and layout of particular widgets, the script becomes very likely to break when a new version of Mail comes along with a different user interface. So I wouldn’t recommend it if there is a useable Applescript interface available instead, but it’s bloody handy when there isn’t one!

The key routine here is searchMailboxForMailFrom() which takes the name of a user and a mailbox, and uses them to perform a find in Mail. The assistive devices support that makes all this possible is only available in OS X 10.3 or higher, and the user has to have turned it on in the system preferences, so it’s necessary to check for that if you want to be a well behaved script and fail gracefully when there’s a problem.


on run
	if gotInterfaceScripting() then
		set mailIcon to "/Applications/Mail.app/Contents/Resources/app.icns"
		display dialog "Search for mail from:" with title "Search Inbox" default answer "" with icon POSIX file mailIcon
		if the result's button returned is "OK" then
			searchMailboxForMailFrom("Inbox", the result's text returned)
		end if
	end if
	
end run


on searchMailboxForMailFrom(searchIn, searchFrom)
	tell application "Mail"
		activate
	end tell
	
	tell application "System Events"
		tell process "Mail"
			-- select first mailbox in list - should be the inbox
			select (first row of outline 1 of scroll area 1 of window 1 whose value of static text 1 is searchIn)
			
			-- select the "mailbox search" menu item
			click menu item "Mailbox Search" of menu "Find" of menu item "Find" of menu "Edit" of menu bar item "Edit" of menu bar 1
			
			-- type the search term and hit return
			keystroke searchFrom
			keystroke return
			
			repeat until exists button searchIn of window 1
				-- can get errors if the script runs before the button has been created...
				-- so we wait here
			end repeat
			
			-- click the mailbox button (as opposed to searching in all mailboxes)
			click button searchIn of window 1
			
			-- click the from button to search in the From: field
			click button "From" of window 1
		end tell
	end tell
end searchMailboxForMailFrom


on gotInterfaceScripting()
	if gotPanther() then
		-- check to see if assistive devices is enabled
		tell application "System Events"
			if UI elements enabled then
				return true
			end if
		end tell
		
		tell application "System Preferences"
			activate
			set current pane to ¬
				pane "com.apple.preference.universalaccess"
			set the dialog_message to "This script utilizes " & ¬
				"the built-in Graphic User Interface Scripting " & ¬
				"architecture of Mac OS X " & ¬
				"which is currently disabled." & return & return & ¬
				"You can activate GUI Scripting by selecting the " & ¬
				"checkbox “Enable access for assistive devices” " & ¬
				"in the Universal Access preference pane."
			display dialog dialog_message buttons {"Cancel"} ¬
				default button 1 with icon 1
		end tell
	end if
	return false
end gotInterfaceScripting


on gotPanther()
	-- get the system version
	set the hexData to system attribute "sysv"
	set hexString to {}
	repeat 4 times
		set hexString to ((hexData mod 16) as string) & hexString
		set hexData to hexData div 16
	end repeat
	set the OS_version to the hexString as string
	if the OS_version is less than "1030" then
		display dialog "This script requires the installation of " & ¬
			"Mac OS X 10.3 or higher." buttons {"Cancel"} ¬
			default button 1 with icon 2
		return false
	end if
	
	return true
end gotPanther

Read more

New Theme
June 21, 2005

I’ve been tinkering with CSS and Drupal today, trying to get a better understanding of the theme system.

As a result, I’ve got a new theme as the default on the site. It’s called Heatwave (if you live in London, you’ll understand why I chose that name…) and it’s basically a cleaned up and pared down version of the Croxted theme that I was using before.

I’ve been trying to simplify the design as much as possible, removing duplication in the css and trying to make the whole thing a bit lighter. I’ve also tried to reduce the impact of the tabs (which you generally only see when editing pages).

There are probably still some things wrong or missing, so let me know what you think, especially if you see anything particularly hideous. The old Croxted theme is still available, so if you log in you can switch back to it if you prefer.

Read more

The Importance Of Syntax
June 16, 2005

During a random session searching for Python html generating tools, I came across an interesting article about language syntax.

I wonder if he’s looked at Dylan?

Read more

Koders is a bit handy. It’s a search engine specifically for open source code.

Read more

Open Source Licensing
June 08, 2005

Recently I’ve been working on some odds and ends that I wanted to Open Source, so I had to ponder which license to release them under.

This is a surprisingly gnarly question, and I’m not sure if I’ve got the final answer but right now I’ve gone for the GPL, although I did have some concerns about it.

Read more