import json
import re
import secrets
-import urllib2
+import urllib.request, urllib.error, urllib.parse
import random
+
class weather_renderer(renderer.debuggable_abstaining_renderer):
"""A renderer to fetch forecast from wunderground."""
- def __init__(self,
- name_to_timeout_dict,
- file_prefix):
+ def __init__(self, name_to_timeout_dict, file_prefix):
super(weather_renderer, self).__init__(name_to_timeout_dict, False)
self.file_prefix = file_prefix
return self.fetch_weather()
def describe_time(self, index):
- if (index <= 1):
+ if index <= 1:
return "overnight"
- elif (index <= 3):
+ elif index <= 3:
return "morning"
- elif (index <= 5):
+ elif index <= 5:
return "afternoon"
else:
return "evening"
return "heavy"
def describe_magnitude(self, mm):
- if (mm < 2):
+ if mm < 2:
return "light"
- elif (mm < 10):
+ elif mm < 10:
return "moderate"
else:
return "heavy"
clear_count = 0
total_snow = 0
count = min(len(conditions), len(rain), len(snow))
- for x in xrange(0, count):
- seen_rain = rain[x] > 0;
- seen_snow = snow[x] > 0;
+ for x in range(0, count):
+ seen_rain = rain[x] > 0
+ seen_snow = snow[x] > 0
total_snow += snow[x]
txt = conditions[x].lower()
- if ("cloud" in txt):
+ if "cloud" in txt:
cloud_count += 1
- if ("clear" in txt or "sun" in txt):
+ if "clear" in txt or "sun" in txt:
clear_count += 1
- if (seen_rain and seen_snow):
- if (total_snow < 10):
+ if seen_rain and seen_snow:
+ if total_snow < 10:
return "sleet.gif"
else:
return "snow.gif"
- if (seen_snow):
- if (total_snow < 10):
+ if seen_snow:
+ if total_snow < 10:
return "flurries.gif"
else:
return "snow.gif"
- if (seen_rain):
+ if seen_rain:
return "rain.gif"
- if (cloud_count >= 6):
+ if cloud_count >= 6:
return "mostlycloudy.gif"
- elif (cloud_count >= 4):
+ elif cloud_count >= 4:
return "partlycloudy.gif"
- if (clear_count >= 7):
+ if clear_count >= 7:
return "sunny.gif"
- elif (clear_count >= 6):
+ elif clear_count >= 6:
return "mostlysunny.gif"
- elif (clear_count >= 4):
+ elif clear_count >= 4:
return "partlysunny.gif"
return "clear.gif"
- def describe_weather(self,
- high, low,
- wind, conditions, rain, snow):
+ def describe_weather(self, high, low, wind, conditions, rain, snow):
# High temp: 65
# Low temp: 44
# -onight------ -morning----- -afternoon-- -evening----
lwind = ""
lprecip = ""
ltime = ""
- for x in xrange(0, count):
+ for x in range(0, count):
time = self.describe_time(x)
current = ""
chunks = 0
elif txt == "Rain":
txt = "rainy"
- if (txt != lcondition):
+ if txt != lcondition:
if txt != "Snow" and txt != "Rain":
current += txt
chunks += 1
lcondition = txt
txt = self.describe_wind(wind[x])
- if (txt != lwind):
- if (len(current) > 0):
+ if txt != lwind:
+ if len(current) > 0:
current += " with "
current += txt + " winds"
lwind = txt
chunks += 1
txt = self.describe_precip(rain[x], snow[x])
- if (txt != lprecip):
- if (len(current) > 0):
- if (chunks > 1):
+ if txt != lprecip:
+ if len(current) > 0:
+ if chunks > 1:
current += " and "
else:
current += " with "
current += txt
lprecip = txt
- if (len(current)):
- if (ltime != time):
- if (random.randint(0, 3) == 0):
- if (time != "overnight"):
+ if len(current):
+ if ltime != time:
+ if random.randint(0, 3) == 0:
+ if time != "overnight":
descr += current + " in the " + time + ". "
descr += current + " overnight. "
else:
- if (time != "overnight"):
+ if time != "overnight":
descr += "In the "
descr += time + ", " + current + ". "
else:
current = current.replace("cloudy", "clouds")
descr += current + " developing. "
ltime = time
- if (ltime == "overnight" or ltime == "morning"):
+ if ltime == "overnight" or ltime == "morning":
descr += "Conditions continuing the rest of the day. "
descr = descr.replace("with breezy winds", "and breezy")
descr = descr.replace("Clear developing", "Skies clearing")
text_location = "Bellevue, WA"
param = "id=5786882"
- www = urllib2.urlopen('http://api.openweathermap.org/data/2.5/forecast?%s&APPID=%s&units=imperial' % (
- param, secrets.openweather_key))
+ www = urllib.request.urlopen(
+ "http://api.openweathermap.org/data/2.5/forecast?%s&APPID=%s&units=imperial"
+ % (param, secrets.openweather_key)
+ )
response = www.read()
www.close()
parsed_json = json.loads(response)
# "dt_txt":"2017-01-30 18:00:00"
# },
# {"dt":1485810000,....
- f = file_writer.file_writer('weather-%s_3_10800.html' % self.file_prefix)
- f.write("""
+ f = file_writer.file_writer("weather-%s_3_10800.html" % self.file_prefix)
+ f.write(
+ """
<h1>Weather at %s:</h1>
<hr>
<center>
<table width=99%% cellspacing=10 border=0>
- <tr>""" % text_location)
- count = parsed_json['cnt']
+ <tr>"""
+ % text_location
+ )
+ count = parsed_json["cnt"]
ts = {}
highs = {}
conditions = {}
rain = {}
snow = {}
- for x in xrange(0, count):
- data = parsed_json['list'][x]
- dt = data['dt_txt'] # 2019-10-07 18:00:00
+ for x in range(0, count):
+ data = parsed_json["list"][x]
+ dt = data["dt_txt"] # 2019-10-07 18:00:00
date = dt.split(" ")[0]
time = dt.split(" ")[1]
wind[date] = []
snow[date] = []
ts[date] = 0
- for x in xrange(0, count):
- data = parsed_json['list'][x]
- dt = data['dt_txt'] # 2019-10-07 18:00:00
+ for x in range(0, count):
+ data = parsed_json["list"][x]
+ dt = data["dt_txt"] # 2019-10-07 18:00:00
date = dt.split(" ")[0]
time = dt.split(" ")[1]
- _ = data['dt']
- if (_ > ts[date]):
+ _ = data["dt"]
+ if _ > ts[date]:
ts[date] = _
temp = data["main"]["temp"]
- if (highs[date] < temp):
+ if highs[date] < temp:
highs[date] = temp
- if (temp < lows[date]):
+ if temp < lows[date]:
lows[date] = temp
wind[date].append(data["wind"]["speed"])
conditions[date].append(data["weather"][0]["main"])
# u'wind': {u'speed': 6.31, u'deg': 10.09}}
# Next 5 half-days
- #for x in xrange(0, 5):
+ # for x in xrange(0, 5):
# fcast = parsed_json['forecast']['txt_forecast']['forecastday'][x]
# text = fcast['fcttext']
# text = re.subn(r' ([0-9]+)F', r' \1°F', text)[0]
# f.write('<td style="vertical-align:top;font-size:75%%"><P STYLE="padding:8px;">%s</P></td>' % text)
- #f.write('</tr></table>')
- #f.close()
- #return True
+ # f.write('</tr></table>')
+ # f.close()
+ # return True
- #f.write("<table border=0 cellspacing=10>\n")
+ # f.write("<table border=0 cellspacing=10>\n")
days_seen = {}
for date in sorted(highs.keys()):
today = datetime.fromtimestamp(ts[date])
- formatted_date = today.strftime('%a %e %b')
- if (formatted_date in days_seen):
- continue;
+ formatted_date = today.strftime("%a %e %b")
+ if formatted_date in days_seen:
+ continue
days_seen[formatted_date] = True
- num_days = len(days_seen.keys())
+ num_days = len(list(days_seen.keys()))
days_seen = {}
for date in sorted(highs.keys()):
precip += _
today = datetime.fromtimestamp(ts[date])
- formatted_date = today.strftime('%a %e %b')
- if (formatted_date in days_seen):
- continue;
+ formatted_date = today.strftime("%a %e %b")
+ if formatted_date in days_seen:
+ continue
days_seen[formatted_date] = True
f.write('<td width=%d%% style="vertical-align:top;">\n' % (100 / num_days))
- f.write('<table border=0>\n')
+ f.write("<table border=0>\n")
# Date
- f.write(' <tr><td colspan=3 height=50><b><center><font size=6>' + formatted_date + '</font></center></b></td></tr>\n')
+ f.write(
+ " <tr><td colspan=3 height=50><b><center><font size=6>"
+ + formatted_date
+ + "</font></center></b></td></tr>\n"
+ )
# Icon
- f.write(' <tr><td colspan=3 height=100><center><img src="/icons/weather/%s" height=125></center></td></tr>\n' %
- self.pick_icon(conditions[date], rain[date], snow[date]))
+ f.write(
+ ' <tr><td colspan=3 height=100><center><img src="/icons/weather/%s" height=125></center></td></tr>\n'
+ % self.pick_icon(conditions[date], rain[date], snow[date])
+ )
# Low temp
color = "#000099"
- if (lows[date] <= 32.5):
+ if lows[date] <= 32.5:
color = "#009999"
- f.write(' <tr><td width=33%% align=left><font color="%s"><b>%d°F </b></font></td>\n' % (
- color, int(lows[date])))
+ f.write(
+ ' <tr><td width=33%% align=left><font color="%s"><b>%d°F </b></font></td>\n'
+ % (color, int(lows[date]))
+ )
# Total precip
precip *= 0.0393701
- if (precip > 0.025):
- f.write(' <td width=33%%><center><b><font style="background-color:#dfdfff; color:#003355">%3.1f"</font></b></center></td>\n' % precip)
+ if precip > 0.025:
+ f.write(
+ ' <td width=33%%><center><b><font style="background-color:#dfdfff; color:#003355">%3.1f"</font></b></center></td>\n'
+ % precip
+ )
else:
- f.write(' <td width=33%> </td>\n')
+ f.write(" <td width=33%> </td>\n")
# High temp
color = "#800000"
- if (highs[date] >= 80):
+ if highs[date] >= 80:
color = "#AA0000"
- f.write(' <td align=right><font color="%s"><b> %d°F</b></font></td></tr>\n' % (
- color, int(highs[date])))
+ f.write(
+ ' <td align=right><font color="%s"><b> %d°F</b></font></td></tr>\n'
+ % (color, int(highs[date]))
+ )
# Text "description"
- f.write('<tr><td colspan=3 style="vertical-align:top;font-size:75%%">%s</td></tr>\n' %
- self.describe_weather(highs[date], lows[date], wind[date], conditions[date], rain[date], snow[date]))
- f.write('</table>\n</td>\n')
+ f.write(
+ '<tr><td colspan=3 style="vertical-align:top;font-size:75%%">%s</td></tr>\n'
+ % self.describe_weather(
+ highs[date],
+ lows[date],
+ wind[date],
+ conditions[date],
+ rain[date],
+ snow[date],
+ )
+ )
+ f.write("</table>\n</td>\n")
f.write("</tr></table></center>")
return True
-#x = weather_renderer({"Stevens": 1000},
+
+# x = weather_renderer({"Stevens": 1000},
# "stevens")
-#x.periodic_render("Stevens")
+# x.periodic_render("Stevens")