The changes necessary to upgrade the kiosk to use python3.7.
[kiosk.git] / pollen_renderer.py
1 import file_writer
2 from bs4 import BeautifulSoup
3 import renderer
4 import http.client
5 import re
6
7 class pollen_count_renderer(renderer.debuggable_abstaining_renderer):
8     def __init__(self, name_to_timeout_dict):
9         super(pollen_count_renderer, self).__init__(name_to_timeout_dict, False)
10         self.site = 'www.nwasthma.com'
11         self.uri = '/pollen/pollen-count/'
12         self.trees = []
13         self.grasses = []
14         self.weeds = []
15
16     def debug_prefix(self):
17         return "pollen"
18
19     def fetch_html(self):
20         conn = http.client.HTTPConnection(self.site)
21         conn.request(
22                 "GET",
23                 self.uri,
24                 None,
25                 {})
26         response = conn.getresponse()
27         if response.status != 200:
28             print(('Connection to %s/%s failed, status %d' % (self.site,
29                                                              self.uri,
30                                                              response.status)))
31             return False
32         return response.read()
33
34     def append_crap(self, text, tc, tr, tcomment, kind, maximum):
35         desc = ""
36         color = "#00d000"
37         if tr != None and tr.string != None:
38             desc = tr.string.encode('utf-8')
39             if "edium" in desc:
40                 color = "#a0a000"
41             elif "igh" in desc:
42                 color = "#d00000"
43
44         count = 0
45         if tc != None and tc.string != None:
46             try:
47                 count = int(tc.string.encode('utf-8'))
48             except:
49                 count = 0
50         proportion = float(count) / float(maximum)
51         width = int(proportion * 600.0)
52
53         comment = ""
54         if tcomment != None and tcomment.string != None:
55             comment = "%s" % (tcomment.string.encode('utf-8'))
56
57         # Label:
58         text = text + '<TR><TD WIDTH=10%% STYLE="font-size: 22pt">%s:</TD>' % (kind)
59
60         # Bar graph with text in it (possibly overspilling):
61         text = text + '<TD HEIGHT=80><DIV STYLE="width: %d; height: 80; overflow: visible; background-color: %s; font-size: 16pt">' % (width, color)
62         text = text + 'count=%d,&nbsp;%s&nbsp;%s</DIV>' % (count, desc, comment)
63         return text
64
65     def munge(self, raw):
66         soup = BeautifulSoup(raw, "html.parser")
67
68         text = """
69 <H1>Pollen Count, Seattle</H1>
70 <HR>
71 <CENTER>
72 <TABLE BODER WIDTH=800>"""
73         date = "<CENTER><B>Unknown Date</B></CENTER>"
74         for x in soup.find_all('p'):
75             if x == None or x.string == None:
76                 continue
77             txt = x.string.encode('utf-8')
78             m = re.match("[0-9][0-9].[0-9][0-9].20[0-9][0-9]", txt)
79             if m != None:
80                 date = "<CENTER><B>%s</B></CENTER>" % (txt)
81                 y = x.find_next_sibling('p')
82                 if y != None and y.string != None:
83                     txt = y.string.encode('utf-8')
84                     date = date + "<BR>%s<HR>" % txt
85         text = text + '<TR><TD COLSPAN=3 STYLE="font-size:16pt">%s</TD></TR>\n' % (
86             date)
87
88         trees = soup.find('td', text=re.compile('[Tt]rees:'))
89         if trees != None:
90             tc = trees.find_next_sibling('td')
91             tr = tc.find_next_sibling('td')
92             tcomment = tr.find_next_sibling('td')
93             text = self.append_crap(text, tc, tr, tcomment, "Trees", 650)
94
95         grasses = soup.find('td', text=re.compile('[Gg]rasses:'))
96         if grasses != None:
97             gc = grasses.find_next_sibling('td')
98             gr = gc.find_next_sibling('td')
99             gcomment = gr.find_next_sibling('td')
100             text = self.append_crap(text, gc, gr, gcomment, "Grasses", 35)
101
102         weeds = soup.find('td', text=re.compile('[Ww]eeds:'))
103         if weeds != None:
104             wc = weeds.find_next_sibling('td')
105             wr = wc.find_next_sibling('td')
106             wcomment = wr.find_next_sibling('td')
107             text = self.append_crap(text, wc, wr, wcomment, "Weeds", 25)
108         text = text + """
109 <TR>
110   <TD COLSPAN=3 STYLE="font-size:16pt">
111 <HR>
112 <B>Absent:</B> No symptoms.<BR>
113 <B>Low:</B> Only individuals extremely sensitive to these pollens will experience symptoms.<BR>
114 <B>Moderate:</B> Many individuals sensitive to these pollens will experience symptoms<BR>
115 <B>High:</B> Most individuals with any sensitivity to these pollens will experience symptoms.<BR>
116 <B>Very High:</B> Almost all individuals with any sensitivity at all to these pollens will experience symptoms. Extremely sensitive people could have severe problems.
117   </TD>
118 </TR>
119 </TABLE>
120 </CENTER>"""
121         return text
122
123     def poll_pollen(self):
124         raw = self.fetch_html()
125         cooked = self.munge(raw)
126         f = file_writer.file_writer('pollen_4_360.html')
127         f.write(cooked)
128         f.close()
129         return True
130
131     def periodic_render(self, key):
132         self.debug_print("executing action %s" % key)
133         if key == "Poll":
134             return self.poll_pollen()
135         else:
136             raise error("Unknown operaiton")
137
138 #test = pollen_count_renderer({"Test", 123})