import file_writer from bs4 import BeautifulSoup import renderer import http.client import re class pollen_count_renderer(renderer.debuggable_abstaining_renderer): def __init__(self, name_to_timeout_dict): super(pollen_count_renderer, self).__init__(name_to_timeout_dict, False) self.site = "www.nwasthma.com" self.uri = "/pollen/pollen-count/" self.trees = [] self.grasses = [] self.weeds = [] def debug_prefix(self): return "pollen" def fetch_html(self): conn = http.client.HTTPConnection(self.site) conn.request("GET", self.uri, None, {}) response = conn.getresponse() if response.status != 200: print( ( "Connection to %s/%s failed, status %d" % (self.site, self.uri, response.status) ) ) return False return response.read() def append_crap(self, text, tc, tr, tcomment, kind, maximum): desc = "" color = "#00d000" if tr != None and tr.string != None: desc = tr.string.encode("utf-8") if "edium" in desc: color = "#a0a000" elif "igh" in desc: color = "#d00000" count = 0 if tc != None and tc.string != None: try: count = int(tc.string.encode("utf-8")) except: count = 0 proportion = float(count) / float(maximum) width = int(proportion * 600.0) comment = "" if tcomment != None and tcomment.string != None: comment = "%s" % (tcomment.string.encode("utf-8")) # Label: text = text + '%s:' % (kind) # Bar graph with text in it (possibly overspilling): text = ( text + '
' % (width, color) ) text = text + "count=%d, %s %s
" % (count, desc, comment) return text def munge(self, raw): soup = BeautifulSoup(raw, "html.parser") text = """

Pollen Count, Seattle


""" date = "
Unknown Date
" for x in soup.find_all("p"): if x == None or x.string == None: continue txt = x.string.encode("utf-8") m = re.match("[0-9][0-9].[0-9][0-9].20[0-9][0-9]", txt) if m != None: date = "
%s
" % (txt) y = x.find_next_sibling("p") if y != None and y.string != None: txt = y.string.encode("utf-8") date = date + "
%s
" % txt text = text + '\n' % (date) trees = soup.find("td", text=re.compile("[Tt]rees:")) if trees != None: tc = trees.find_next_sibling("td") tr = tc.find_next_sibling("td") tcomment = tr.find_next_sibling("td") text = self.append_crap(text, tc, tr, tcomment, "Trees", 650) grasses = soup.find("td", text=re.compile("[Gg]rasses:")) if grasses != None: gc = grasses.find_next_sibling("td") gr = gc.find_next_sibling("td") gcomment = gr.find_next_sibling("td") text = self.append_crap(text, gc, gr, gcomment, "Grasses", 35) weeds = soup.find("td", text=re.compile("[Ww]eeds:")) if weeds != None: wc = weeds.find_next_sibling("td") wr = wc.find_next_sibling("td") wcomment = wr.find_next_sibling("td") text = self.append_crap(text, wc, wr, wcomment, "Weeds", 25) text = ( text + """
%s

Absent: No symptoms.
Low: Only individuals extremely sensitive to these pollens will experience symptoms.
Moderate: Many individuals sensitive to these pollens will experience symptoms
High: Most individuals with any sensitivity to these pollens will experience symptoms.
Very High: Almost all individuals with any sensitivity at all to these pollens will experience symptoms. Extremely sensitive people could have severe problems.
""" ) return text def poll_pollen(self): raw = self.fetch_html() cooked = self.munge(raw) f = file_writer.file_writer("pollen_4_360.html") f.write(cooked) f.close() return True def periodic_render(self, key): self.debug_print("executing action %s" % key) if key == "Poll": return self.poll_pollen() else: raise error("Unknown operaiton") # test = pollen_count_renderer({"Test", 123})