Source code for i3pystatus.weather

from i3pystatus import IntervalModule
from i3pystatus.core.util import internet, require

from urllib.request import urlopen
import re
import xml.etree.ElementTree as ElementTree

WEATHER_COM_URL = 'http://wxdata.weather.com/wxdata/weather/local/%s?unit=%s&dayf=1&cc=*'


[docs]class Weather(IntervalModule): """ This module gets the weather from weather.com. First, you need to get the code for the location from www.weather.com .. rubric:: Available formatters * `{current_temp}` — current temperature including unit (and symbol if colorize is true) * `{min_temp}` — today's minimum temperature including unit * `{max_temp}` — today's maximum temperature including unit * `{current_wind}` — current wind direction, speed including unit * `{humidity}` — current humidity excluding percentage symbol """ interval = 20 settings = ( ("location_code", "Location code from www.weather.com"), ("colorize", "Enable color with temperature and UTF-8 icons."), ("units", "Celsius (metric) or Fahrenheit (imperial)"), "format", ) required = ("location_code",) location_code = None units = "metric" format = "{current_temp}" colorize = False color_icons = { "Fair": (u"\u2600", "#FFCC00"), "Cloudy": (u"\u2601", "#F8F8FF"), "Partly Cloudy": (u"\u2601", "#F8F8FF"), # \u26c5 is not in many fonts "Rainy": (u"\u2614", "#CBD2C0"), "Sunny": (u"\u263C", "#FFFF00"), "Snow": (u"\u2603", "#FFFFFF"), "default": ("", None), }
[docs] def fetch_weather(self): '''Fetches the current weather from wxdata.weather.com service.''' unit = '' if self.units == 'imperial' or self.units == '' else 'm' url = WEATHER_COM_URL % (self.location_code, unit) with urlopen(url) as handler: try: content_type = dict(handler.getheaders())['Content-Type'] charset = re.search(r'charset=(.*)', content_type).group(1) except AttributeError: charset = 'utf-8' xml = handler.read().decode(charset) doc = ElementTree.XML(xml) return dict( current_conditions=dict( text=doc.findtext('cc/t'), temperature=doc.findtext('cc/tmp'), humidity=doc.findtext('cc/hmid'), wind=dict( text=doc.findtext('cc/wind/t'), speed=doc.findtext('cc/wind/s'), ), ), today=dict( min_temperature=doc.findtext('dayf/day[@d="0"]/low'), max_temperature=doc.findtext('dayf/day[@d="0"]/hi'), ), units=dict( temperature=doc.findtext('head/ut'), speed=doc.findtext('head/us'), ), )
@require(internet) def run(self): result = self.fetch_weather() conditions = result["current_conditions"] temperature = conditions["temperature"] humidity = conditions["humidity"] wind = conditions["wind"] units = result["units"] color = None current_temp = "{t}°{d}".format(t=temperature, d=units["temperature"]) min_temp = "{t}°{d}".format(t=result["today"]["min_temperature"], d=units["temperature"]) max_temp = "{t}°{d}".format(t=result["today"]["max_temperature"], d=units["temperature"]) current_wind = "{t} {s}{d}".format(t=wind["text"], s=wind["speed"], d=units["speed"]) if self.colorize: icon, color = self.color_icons.get(conditions["text"], self.color_icons["default"]) current_temp = "{t}°{d} {i}".format(t=temperature, d=units["temperature"], i=icon) color = color self.output = { "full_text": self.format.format( current_temp=current_temp, current_wind=current_wind, humidity=humidity, min_temp=min_temp, max_temp=max_temp, ), "color": color }