Rework weather segment

Allows more precise icon selection and purges out unicode characters from
configuration.

Note: windy icon needs reworking, I used a trigram for it.

Fixes #203.
This commit is contained in:
ZyX 2013-02-13 09:15:10 +04:00 committed by Kim Silkebækken
parent 9aee288c18
commit ca4466cd83
3 changed files with 100 additions and 25 deletions

View File

@ -44,9 +44,9 @@
"weather": { "fg": "gray8", "bg": "gray0" },
"weather_temp_cold": { "fg": "weather_temp_cold", "bg": "gray0" },
"weather_temp_hot": { "fg": "weather_temp_hot", "bg": "gray0" },
"weather_condition_": { "fg": "weather_condition_hot", "bg": "gray0" },
"weather_condition_": { "fg": "weather_condition_cold", "bg": "gray0" },
"weather_condition_": { "fg": "weather_condition_cold", "bg": "gray0" },
"weather_condition_hot": { "fg": "weather_condition_hot", "bg": "gray0" },
"weather_condition_snowy": { "fg": "weather_condition_cold", "bg": "gray0" },
"weather_condition_rainy": { "fg": "weather_condition_cold", "bg": "gray0" },
"uptime": { "fg": "gray8", "bg": "gray0" },
"external_ip": { "fg": "gray8", "bg": "gray0" },
"network_load": { "fg": "gray8", "bg": "gray0" },

View File

@ -44,9 +44,9 @@
"weather": { "fg": "gray8", "bg": "gray0" },
"weather_temp_cold": { "fg": "weather_temp_cold", "bg": "gray0" },
"weather_temp_hot": { "fg": "weather_temp_hot", "bg": "gray0" },
"weather_condition_": { "fg": "weather_condition_hot", "bg": "gray0" },
"weather_condition_": { "fg": "weather_condition_cold", "bg": "gray0" },
"weather_condition_": { "fg": "weather_condition_cold", "bg": "gray0" },
"weather_condition_hot": { "fg": "weather_condition_hot", "bg": "gray0" },
"weather_condition_snowy": { "fg": "weather_condition_cold", "bg": "gray0" },
"weather_condition_rainy": { "fg": "weather_condition_cold", "bg": "gray0" },
"uptime": { "fg": "gray8", "bg": "gray0" },
"external_ip": { "fg": "gray8", "bg": "gray0" },
"network_load": { "fg": "gray8", "bg": "gray0" },

View File

@ -180,8 +180,83 @@ def uptime(format='{days:02d}d {hours:02d}h {minutes:02d}m'):
return format.format(days=int(days), hours=hours, minutes=minutes)
# Weather condition code descriptions available at
# http://developer.yahoo.com/weather/#codes
weather_conditions_codes = (
('tornado', 'stormy'), # 0
('tropical_storm', 'stormy'), # 1
('hurricane', 'stormy'), # 2
('severe_thunderstorms', 'stormy'), # 3
('thunderstorms', 'stormy'), # 4
('mixed_rain_and_snow', 'rainy' ), # 5
('mixed_rain_and_sleet', 'rainy' ), # 6
('mixed_snow_and_sleet', 'snowy' ), # 7
('freezing_drizzle', 'rainy' ), # 8
('drizzle', 'rainy' ), # 9
('freezing_rain', 'rainy' ), # 10
('showers', 'rainy' ), # 11
('showers', 'rainy' ), # 12
('snow_flurries', 'snowy' ), # 13
('light_snow_showers', 'snowy' ), # 14
('blowing_snow', 'snowy' ), # 15
('snow', 'snowy' ), # 16
('hail', 'snowy' ), # 17
('sleet', 'snowy' ), # 18
('dust', 'foggy' ), # 19
('fog', 'foggy' ), # 20
('haze', 'foggy' ), # 21
('smoky', 'foggy' ), # 22
('blustery', 'foggy' ), # 23
('windy', ), # 24
('cold', 'day' ), # 25
('clouds', 'cloudy'), # 26
('mostly_cloudy_night', 'cloudy'), # 27
('mostly_cloudy_day', 'cloudy'), # 28
('partly_cloudy_night', 'cloudy'), # 29
('partly_cloudy_day', 'cloudy'), # 30
('clear_night', 'night' ), # 31
('sun', 'sunny' ), # 32
('fair_night', 'night' ), # 33
('fair_day', 'day' ), # 34
('mixed_rain_and_hail', 'rainy' ), # 35
('hot', 'sunny' ), # 36
('isolated_thunderstorms', 'stormy'), # 37
('scattered_thunderstorms', 'stormy'), # 38
('scattered_thunderstorms', 'stormy'), # 39
('scattered_showers', 'rainy' ), # 40
('heavy_snow', 'snowy' ), # 41
('scattered_snow_showers', 'snowy' ), # 42
('heavy_snow', 'snowy' ), # 43
('partly_cloudy', 'cloudy'), # 44
('thundershowers', 'rainy' ), # 45
('snow_showers', 'snowy' ), # 46
('isolated_thundershowers', 'rainy' ), # 47
)
# ('day', (25, 34)),
# ('rainy', (5, 6, 8, 9, 10, 11, 12, 35, 40, 45, 47)),
# ('cloudy', (26, 27, 28, 29, 30, 44)),
# ('snowy', (7, 13, 14, 15, 16, 17, 18, 41, 42, 43, 46)),
# ('stormy', (0, 1, 2, 3, 4, 37, 38, 39)),
# ('foggy', (19, 20, 21, 22, 23)),
# ('sunny', (32, 36)),
# ('night', (31, 33))):
weather_conditions_icons = {
'day': u'',
'blustery': u'',
'rainy': u'',
'cloudy': u'',
'snowy': u'',
'stormy': u'',
'foggy': u'',
'sunny': u'',
'night': u'',
'windy': u'',
'not_available': u'',
}
@memoize(1800)
def weather(unit='c', location_query=None):
def weather(unit='c', location_query=None, icons=None):
'''Return weather from Yahoo! Weather.
Uses GeoIP lookup from http://freegeoip.net/ to automatically determine
@ -195,22 +270,11 @@ def weather(unit='c', location_query=None):
temperature unit, can be one of ``F``, ``C`` or ``K``
:param str location_query:
location query for your current location, e.g. ``oslo, norway``
:param dict icons:
dict for overriding default icons, e.g. ``{'heavy_snow' : u''}``
'''
import json
# Weather condition code descriptions available at http://developer.yahoo.com/weather/#codes
weather_conditions_codes = {
u'': [25, 34],
u'': [24],
u'': [5, 6, 8, 9, 10, 11, 12, 35, 40, 45, 47],
u'': [26, 27, 28, 29, 30, 44],
u'': [7, 13, 14, 15, 16, 17, 18, 41, 42, 43, 46],
u'': [0, 1, 2, 3, 4, 37, 38, 39],
u'': [19, 20, 21, 22, 23],
u'': [32, 36],
u'': [31, 33],
}
if not location_query:
try:
location = json.loads(urllib_read('http://freegeoip.net/json/' + external_ip()))
@ -230,14 +294,25 @@ def weather(unit='c', location_query=None):
condition_code = int(condition['code'])
except (KeyError, TypeError, ValueError):
return None
icon = u''
for icon, codes in weather_conditions_codes.items():
if condition_code in codes:
try:
icon_names = weather_conditions_codes[condition_code]
except IndexError:
if condition_code == 3200:
icon_names = ('not_available',)
else:
icon_names = ('unknown')
for icon_name in icon_names:
if icons:
if icon_name in icons:
icon = icons[icon_name]
break
else:
icon = weather_conditions_icons[icon_names[-1]]
groups = ['weather_condition_' + icon_name for icon_name in icon_names] + ['weather_conditions', 'weather']
return [
{
'contents': icon + ' ',
'highlight_group': ['weather_condition_' + icon, 'weather_condition', 'weather'],
'highlight_group': groups,
},
{
'contents': u'{0}°{1}'.format(condition['temp'], unit.upper()),