Applescript Tutorial 11

GeekTool is a Preference Pane (System Preferences module) for Mac OS X. It lets you display various types of information directly on you desktop. The information can be derived from a shell script or using osascript it is possible to call applescripts (or any other OSA language scripts). I first became aware of Geektool when read this tip on Macosxtips and it would certainly be worth looking at to get an idea of what it can be used for. In this tutorial I'll use a couple of simple commands to create desktop content, and then link to Applescripts to create more complex content.

To install GeekTool go to the website, download it and double click to install the preference pane. You can now access it by opening System Preferences and looking in the bottom row of icons, double click it.

To create a new entry click the button at the bottom left and then select "Shell" from the dropdown menu. Now type cal in the box and in a few seconds the calendar for the current month should appear on your desktop at the top left corner. Since this won't need updating that often set the refresh to 5000.

You can modify the font type colour etc to give better contrast with your desktop.

While this is quite interesting it you can obviously use a range of shellscripts to create content, one mentioned in the tip above uses icalbuddy a command-line utility that can be used to get lists of items (i.e. events and tasks/todos) from the OS X calendar database (the same one iCal uses).

Here installation instructions from Macosxtips

"The installation is a little bit complicated. Open up Terminal (located in Applications/Utilities) and type cd followed by a space. Now drag the iCalBuddy folder onto the Terminal window and hit Enter. Finally, type sudo ./install.sh and hit enter. To test if everything is installed properly, try typing in "icalbuddy eventsToday", which should bring up a list of today's events."

Now create another new entry, select "shell" as before then type "/usr/local/bin/icalbuddy uncompletedTasks" into the command box, this should bring up a list of today's events on the desktop. You may have to move the list to avoid overlap with the calendar and adjust the refresh rate to a more appropriate number of seconds.

Whilst this is the easiest option it does limit the options for customisation. An alternative is to create an Applescript and to use the osascript command to access it. Create the following Applescript and save it. I have a "scripts" folder in which I have a "for_geektool" sub-folder

set the_tasks to "Uncompleted tasks" & return

set shell_script to "/usr/local/bin/icalbuddy uncompletedTasks"

set the_tasks to the_tasks & (do shell script shell_script)

the_tasks

Now create another new entry, select "shell" as before then type "osascript " followed the full path to the applescript (an easy way to get the full posix path is to simply drop the script onto a "Terminal" window, you can then copy and paste the path). This should also bring up a list of today's events on the desktop but has the advantage you can add a header "Uncompleted tasks". You can compare the ouput by selecting the "Hide Output" option.

The ability to access applescripts allows you easily put more content on your desktop, I like to keep track of incoming emails and whilst the dock icon shows if any unread messages are present it takes a little time to see who they are from. The Applescript below checks the inbox to see if there are any unread messages, it then gets the sender and the subject of each message and formats them into a list.


set List_Mail to "Unread Mail messages" & return

tell application "Mail"
       set theMessages to (messages of inbox whose read status is false)
	set message_count to number of items in theMessages
	if message_count > 0 then
               set List_Mail to List_Mail & "There are " & message_count & " unread messages" & return
	       repeat with i from 1 to number of items in theMessages
                       set thisMessage to item i of theMessages
	               
	               set the_sender to (sender of thisMessage as string)
	               set the_sub to (subject of thisMessage as string)
	               set List_Mail to List_Mail & the_sender & " " & the_sub & return
	               
               end repeat
       else
               set List_Mail to List_Mail & "There are " & message_count & " unread messages" & return
       end if
end tell
List_Mail

Save this as an applescript and in GeekTool create another new entry, select "shell" as before then type "osascript " followed the full path to the applescript. You will probably need to set the refresh option to something frequent to keep checking for new messages.

If you have used all the options described in the page you should have a desktop looking like the image shown below.

As it stands this script requires Mail to be open and will of course open Mail if it is not open, if you would prefer it to not to run if Mail is closed then modify the scrip[t as shown below.

set List_Mail to "Unread Mail messages" & return
tell application "System Events" to set theCount to the count of (processes whose name is "Mail")

if theCount = 0 then
       set List_Mail to "Mail not Open"
else
       tell application "Mail"
               set theMessages to (messages of inbox whose read status is false)
	       set message_count to number of items in theMessages
	       if message_count > 0 then
                       set List_Mail to List_Mail & "There are " & message_count & " unread messages" & return
	               repeat with i from 1 to number of items in theMessages
                               set thisMessage to item i of theMessages
	                       
	                       set the_sender to (sender of thisMessage as string)
	                       set the_sub to (subject of thisMessage as string)
	                       set List_Mail to List_Mail & "- " & the_sender & " " & the_sub & return
	                       
                       end repeat
               else
                       set List_Mail to List_Mail & "There are " & message_count & " unread messages" & return
               end if
       end tell
end if

List_Mail