Geektool + Python = Desktop Weather (& moonphase)

I had some free time today and was playing with Geektool, which is like the desktop toys I used to play with years ago on Linux – SuperKaramba comes to mind. I wrote a Python script as an example to do some weather stuff, which can be edited to work behind the scenes or to directly display weather in Geektool. It also will download an animated radar image and gets the weather icon file that you can map to your own icons or, with a minor code edit, download directly from Yahoo. Read the comments to setup in Geektool.

Jan. 1, 2019: Some tools you might find useful.
https://darksky.net/dev Weather API – free 1000 hits per day.
https://pypi.org/project/pylunar/ Moon phase library.

Aug. 2016 update: Be aware that Yahoo no longer offers weather data, at least not free.

Here is the weather service I’m using:

http://openweathermap.org/api

Python library to make consumption of the data fairly simple.

https://github.com/csparpa/pyowm

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">#! /usr/bin/python
# -*- coding: utf-8 -*-
"""
Author: C. Nichols &lt;mohawke@gmail.com>
Site: https://www.darkartistry.com

Weather script to be used with Geektool,
or whatever you like...
Ref: http://developer.yahoo.com/weather/
"""
import subprocess,StringIO
import urllib
from xml.dom import minidom
import re
import shutil

def get_attribute(html, attr):
    res = re.search(r'%%s="(.*?)"' %% attr, html)
    return res.group(1)

def curl(url):
    c = subprocess.Popen(["curl", url], stdout=subprocess.PIPE)
    (out,err) = c.communicate()
    return out

def get_radar(image_out):
    image_url = "http://images.myforecast.com/images/cw/radar/northeast/northeast_anim.gif"
    result = curl(image_url)
    if result:
        open(image_out,'wb').write(result)
    else:
        print 'unable to retrieve image file.'

def weather_for_zip(zip_code):
    WEATHER_URL = 'http://xml.weather.yahoo.com/forecastrss?p=%%s'
    WEATHER_NS  = 'http://xml.weather.yahoo.com/ns/rss/1.0'
    wurl = WEATHER_URL %% zip_code

    results = curl(wurl)
    weather_icon = get_attribute(results, 'src')
    icon = weather_icon.split('/')[-1]

    dom = minidom.parseString(results)
    forecasts = []
    for node in dom.getElementsByTagNameNS(WEATHER_NS, 'forecast'):
        forecasts.append({
            'date': node.getAttribute('date'),
            'low': node.getAttribute('low'),
            'high': node.getAttribute('high'),
            'condition': node.getAttribute('text')
        })
    ycondition = dom.getElementsByTagNameNS(WEATHER_NS, 'condition')[0]
    return {
        'current_condition': ycondition.getAttribute('text'),
        'current_temp': ycondition.getAttribute('temp'),
        'forecasts': forecasts,
        'title': dom.getElementsByTagName('title')[0].firstChild.data,
        'icon': icon
    }
'''
You can now simply build your output from a simple key/val dictionary
including the weather icon buy pointing to your icon set or change
to download from Yahoo. Also, grab the radar if you want one.  

To run in Geektool, open shell and add: python /path/to/your/weather.py 

Don't forget the change the paths to the image files below.
'''
try:
    myWeather = weather_for_zip("43230")
    forcasts = []
    for i in myWeather['forecasts']:
        forcasts.append(i['date']+': '+i['condition']+'\n')

    message = u"%%s°F %%s\n%%s" %%(myWeather['current_temp'],
                               myWeather['current_condition'],
                               forcasts[-1])
    print message.encode('utf-8')

    # Copy yahoo weather icon to weather...
    localIcon = "/Users/mohawke/Geektool/Symbols/%%s.png" %%myWeather['icon'].split('.')[0]
    replaceIcon = "/Users/mohawke/Geektool/weather.png"

    shutil.copyfile(localIcon,replaceIcon)

except Exception, error:
    print "Unable to get weather data"
    #print error&lt;/mohawke@gmail.com></pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p>So how about reading the system log? Even easier.</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">#! /usr/bin/python
# python /path/to/your/syslog.py

sysLogPath = "/var/log/system.log"
limit = 5  # How manyu lines to display.

lineCount = 0
for line in sorted(open(sysLogPath, "r"), reverse=1):
    if lineCount == limit: break

    print line

    lineCount += 1</pre>
<!-- /wp:preformatted -->

So how about reading the system log? Even easier.

#! /usr/bin/python
# python /path/to/your/syslog.py

sysLogPath = "/var/log/system.log"
limit = 5  # How manyu lines to display.

lineCount = 0
for line in sorted(open(sysLogPath, "r"), reverse=1):
    if lineCount == limit: break

    print line

    lineCount += 1

Pretty easy stuff, but if you need assistance give me a shout. I’ve included some cool icons that I found in the download, but I could not find who made them. If you made them let me know and I’ll gladly give you credit.

Download Weather

I’ve been made aware that some countries cannot use a zip code so here is an example to get the weather by longitude and latitude, automated so it will change as you move your laptop.

Download Weather by location example.

and you simply can’t have the weather without the moon phase, right?

Download Moonphase