Macs in Chemistry

Insanely great science

 

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.

geektool_cal

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.

geektool_cal_2

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

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.

geektool_tasks_1

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.

geektool_tasks_3

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.

geektool_mail_1

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

geektool_test

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