Geek Tool
February 24th 2009 · Mac ComputerI ran into a line of posts the other day about customizing Mac desktops. There were quite a few interesting ideas but the ones that stuck out for me were the people making use of Geek Tool.
Geek Tool is an OS/X preference pane that allows you to place pretty much anything on the desktop. And what it places on the desktop can be easily formatted. I took one of the designs and extended it slightly to create this:
This time/date/weather display is updated dynamically on the desktop and uses very little CPU.1
Each element in the display is a separate shell command. The elements are:
| Element | Shell Command | Font | Location | Size | Update Period (sec) |
|---|---|---|---|---|---|
| The day | date +%A | Helvetica, Regular, 27point with drop shadow | 10x, 727y | 200w x 40h | 60 |
| The month | date +%B | Helvetica, Regular, 36point with drop shadow | 10x, 750y | 200w x 50h | 60 |
| The day of the month | date +%d | Helvetica, Regular, 64point with drop shadow | 210x, 720y | 100w x 80h | 60 |
| The time | date "+%I:%M" | Helvetica, Bold, 72point with drop shadow | 20x, 780y | 200w x 80h | 10 |
| am/pm | date +%p | Helvetica, Regular, 48point with drop shadow | 210x, 785y | 100w x 70h | 10 |
| The temperature | <bin>/weather.rb -t | Helvetica, Bold, 18point | 20x, 855y | 70w x 25h | 300 |
| The weather | <bin>/weather.rb -d | fmt -w 40 | Helvetica, Regular, 10point | 90x, 855y | 210w x 38h | 300 |
| When the weather was updated | <bin>/weather.rb -w | Helvetica, Regular, 8point | 35x, 878y | 64w x 25h | 300 |
The <bin> in the weather commands is the full path to the directory where you place the weather.rb script. That script is written in Ruby and calls the Weather Underground for the weather information. It needs to be modified so it’s location matches yours. You can download the script from here.
Download the script and replace <your-state> with your two character state, e.g., PA. Replace <your-city> with your Weather Underground recognized city, e.g., West_Chester. You’ll have to play with the Weather Underground site to find your city name. Save the altered script to your bin directory, e.g., /Users//bin. If you don’t have a bin directory, create one. Make the script executable by typing ‘chmod +x /Users/bin/weather.rb’. Test the script by running it – ‘/Users//bin/weather.rb -d’. Once you have it working, you can use it in Geek Tools.
#!/usr/bin/ruby require 'rss/2.0' require 'open-uri' require 'optparse' require 'fileutils' summary = false forecast = false temperature = false today = false weatherdate = false opts = OptionParser.new opts.on("-s") { |val| summary = true } opts.on("-f") { |val| forecast = true } opts.on("-t") { |val| temperature = true } opts.on("-d") { |val| today = true } opts.on("-w") { |val| weatherdate = true } opts.parse! # Check if another process is downloading the weather and block until it's done while File.file?('/tmp/weather.rb.tmp.lck') sleep(0.1) end # Download the weather if it's out of date if !File.file?("/tmp/weather.rb.tmp") || ((Time.now - File.mtime("/tmp/weather.rb.tmp")) > 1800) FileUtils.touch('/tmp/weather.rb.tmp.lck') `curl --silent -m 30 "http://rss.wunderground.com/auto/rss_full//.xml?units=english" > /tmp/weather.rb.tmp` if File.size("/tmp/weather.rb.tmp") == 0 FileUtils.rm("/tmp/weather.rb.tmp") end FileUtils.rm('/tmp/weather.rb.tmp.lck') end # Parse out the weather results File.open('/tmp/weather.rb.tmp') do |f| response = f.read result = RSS::Parser.parse(response, false) result.items.each_with_index do |item, i| puts "#{item.title.gsub(/ - .*/, '')}" if summary == true and i == 0 puts "#{item.description.strip}\n\n" if forecast == true and i > 0 puts "#{item.title.gsub(/Current Conditions : /, '').gsub(/,.*/, '')}" if temperature == true and i == 0 puts "#{item.description.gsub(/Today - /,'').gsub(/Tonight - /,'').gsub(/This Afternoon - /,'').gsub(/[\r\n\t]/, '')}" if today == true and i == 1 hour = item.pubDate.hour() if hour < 12 ampm = "AM" else ampm = "PM" end if hour == 0 hour = 12 end if hour > 12 hour = hour - 12 end puts "#{item.pubDate.mon()}/#{item.pubDate.day()} #{hour}:#{'%02d' % item.pubDate.min()} #{ampm}" if weatherdate == true and i == 0 end end
Again, the URL “http://rss.wunderground.com/auto/rss_full/<your-state>/<your-city>.xml?units=english” portion of the script will need to be modified to match your location. Test the URL in your browser to find the right one for your version of the script.
The weather script stores the information it pulls down for 30 minutes (1800 seconds). Defined on this line:
if !File.file?("/tmp/weather.rb.tmp") || ((Time.now - File.mtime("/tmp/weather.rb.tmp")) > 1800)
The delay is necessary to keep from pulling the information down repeatedly for each element in the display. You don’t need to change this unless you want the delay to be different.
Update: I’ve posted about a new version of the weather script.
[1] There are some limits to Geek Tool formatting. You’ll notice that the weather font looks a little ragged. The only way to get Geek Tool to blend text is to give it a shadow. But a shadow on such a small font looks terrible.








