#!/usr/bin/python

# For Python 2.7
from __future__ import print_function

import argparse
from functools import partial
import json
import logging
import requests
import sys
import time

from bs4 import BeautifulSoup

def get_weather(woeid, unit, format):
    url = ('http://weather.yahooapis.com/forecastrss?w={}&u={}'
           ''.format(woeid, unit.lower()))
    logging.info("Fetching %s" % url)
    try:
        r = requests.get(url)
    except requests.exceptions.ConnectionError:
        return ''
    if r.status_code != 200:
        return 'HTTP error: %s' % r.status_code

    s = BeautifulSoup(r.text)
    data = {'unit': unit.upper()}
    data.update(s.find('yweather:location').attrs)
    data.update(s.find('yweather:condition').attrs)
    return args.format.format(**data)

if __name__ == '__main__':
    p = argparse.ArgumentParser()
    p.add_argument('woeid')
    p.add_argument('--format', metavar='F',
                   default=u'{city}, {region}: {text}, {temp}\u00b0{unit}',
                   help="format string for output")
    p.add_argument('--position', metavar='P', type=int, default=-2,
                   help="position of output in JSON when wrapping i3status")
    p.add_argument('--unit', metavar='U', default='f',
                   help="unit for temperature")
    p.add_argument('--update-interval', metavar='I', type=int, default=60*3,
                   help="update interval in seconds")
    p.add_argument('--wrap-i3-status', action='store_true')
    args = p.parse_args()

    _get_weather = partial(get_weather, args.woeid, args.unit, args.format)

    if args.wrap_i3_status:
        stdin = iter(sys.stdin)

        # The first two lines from i3status need to pass through unmodified
        print(next(stdin), end='')
        print(next(stdin), end='')

        last_update = 0
        weather = {'name': 'weather', 'full_text': ''}
        try:
            for line in stdin:
                data = json.loads(line.lstrip(','))
                data.insert(args.position, weather)
                print((',' if line.startswith(',') else '') + json.dumps(data))
                sys.stdout.flush()

                if (time.time() > last_update + args.update_interval or
                        weather['full_text'] == ''):
                    weather['full_text'] = _get_weather()
                    last_update = time.time()
        except KeyboardInterrupt:
            sys.exit()
    else:
        print(_get_weather())

@@ -608,16 +608,17 @@
 r.text)%0A
+%0A
     data
@@ -625,123 +625,1124 @@
  = %7B
-'unit': unit.upper()%7D%0A    data.update(s.find('yweather:location').attrs)%0A    data.update(s.find('yweather:condition
+%7D%0A%0A    # Unit information%0A    # Prefix each unit key with 'unit_' to prevent ambiguity, e.g.%0A    # 'temp' vs. 'temperature'%0A    units = s.find('yweather:units')%0A    data.update(('unit_' + attr, units.attrs%5Battr%5D) for attr in units.attrs)%0A    # Location information%0A    data.update(s.find('yweather:location').attrs)%0A    # Basic conditions - simple description (%22Fair%22, %22Cloudy%22, etc), temperature%0A    data.update(s.find('yweather:condition').attrs)%0A    # Wind conditions - speed, chill, direction (degrees)%0A    # This is a little bit different from the others in that the attributes%0A    # are prefixed with 'wind_'.  The justification for this is that it doesn't really%0A    # make sense to ask %22what direction does the weather have?%22, as opposed to%0A    # %22what wind_direction does the weather have?%22%0A    wind = s.find('yweather:wind')%0A    data.update(('wind_' + attr, wind.attrs%5Battr%5D) for attr in wind.attrs)%0A    # Atmospheric conditions - humidity, visibility, pressure%0A    data.update(s.find('yweather:atmosphere').attrs)%0A    # Astronomical conditions - sunrise / sunset%0A    data.update(s.find('yweather:astronomy
 ').a
@@ -1991,16 +1991,28 @@
 0b0%7Bunit
+_temperature
 %7D',%0A    

Add additional weather data to the dictionary; change "unit" naming scheme I have added support for wind, atmosphere, and astronomy data. This has in turn made it necessary to distinguish between units of speed, temperature, pressure, etc. Instead of {unit}, the format specifier for temperature units is {unit_temperature}; for speed {unit_speed}, etc.