Add a recipe renderer and trigger.
[kiosk.git] / stevens_renderer.py
1 #!/usr/bin/env python3
2
3 import json
4 import logging
5 import requests
6 from typing import Dict
7
8 import file_writer
9 import renderer
10
11
12 logger = logging.getLogger(__file__)
13
14
15 class stevens_renderer(renderer.abstaining_renderer):
16     URL = 'https://wsdot.com/Travel/Real-time/Service/api/MountainPass/Details/10'
17
18     def __init__(self, name_to_timeout_dict: Dict[str, int]) -> None:
19         super().__init__(name_to_timeout_dict)
20
21     def render_conditions(mp: Dict[str, str], conditions: Dict[str, str]) -> str:
22         ret = f'''
23 <TABLE>
24 <TR>
25   <TD WIDTH="150"><FONT SIZE=+2><B>Temp:</B></FONT></TD>
26   <TD><FONT SIZE=+2>{conditions['temperature']}&deg;{conditions['temperatureUnit'][0]}</FONT></TD>
27 </TR>
28 <TR>
29   <TD><FONT SIZE=+2><B>Weather:</B></FONT></TD>
30   <TD><FONT SIZE=+2>{conditions['weather']}</FONT></TD>
31 </TR>
32 <TR>
33   <TD><FONT SIZE=+2><B>Roadway:</B></FONT></TD>
34   <TD><FONT SIZE=+2>{conditions['roadCondition']}</FONT></TD>
35 </TR>'''
36         if 'restrictionOne' in conditions and 'restrictionTwo' in conditions:
37             ret += '''
38 <TR>
39   <TD><FONT SIZE=+2><B>Restrictions:</B></FONT></TD>
40   <TD><FONT SIZE=+2>'''
41             count = 0
42             msg = conditions['restrictionOne'].get('publicPage', 'no restrictions')
43             if msg.lower() != 'no restrictions':
44                 count += 1
45             msg = conditions['restrictionTwo'].get('publicPage', 'no restrictions')
46             if msg.lower() != 'no restrictions':
47                 count += 1
48             if count == 2:
49                 ret += f'''
50     <U>{conditions['restrictionOne']['travelDirectionName']}:</U>
51     {conditions['restrictionOne']['publicPage']} <BR>
52     <U>{conditions['restrictionTwo']['travelDirectionName']}:</U>
53     {conditions['restrictionTwo']['publicPage']}'''
54             elif count == 1:
55                 msg = conditions['restrictionOne'].get('publicPage', 'no restrictions')
56                 if msg.lower() != 'no restrictions':
57                     ret += f'''
58     <U>{conditions['restrictionOne']['travelDirectionName']}:</U>
59     {conditions['restrictionOne']['publicPage']}<BR>'''
60                 else:
61                     ret += f'''
62     <U>{conditions['restrictionTwo']['travelDirectionName']}:</U>
63     {conditions['restrictionTwo']['publicPage']}<BR>'''
64             else:
65                 ret += '''None.<BR>'''
66         ret += '</FONT></TD></TR></TABLE>'
67         return ret
68
69     def render_forecast(forecasts: Dict[str, str]) -> str:
70         ret = '<TABLE>'
71         fc = forecasts['forecast']['forecastData']
72         for n, f in enumerate(fc):
73             color = ''
74             if n % 2 == 0:
75                 color = ' BGCOLOR="#dfefff"'
76             ret += f'''
77 <TR>
78   <TD WIDTH="150" valign="top" {color}><B>{f['periodText']}</B></TD>
79   <TD{color}>{f['forecastText']}</TD>
80 </TR>'''
81         ret += '</TABLE>'
82         return ret
83
84     def render_image(cameras: Dict[str, str]) -> str:
85         for camera in cameras:
86             if camera['cameraId'] == 8063:
87                 return f'''
88 <CENTER>
89   <A HREF='https://wsdot.com/travel/real-time/mountainpasses/Stevens'>
90     <IMG SRC={camera['cameraUrl']} WIDTH={camera['width'] * 1.75}>
91   </A>
92   <BR>
93   <I>{camera['cameraLabel']} ({camera['direction']})</I>
94 </CENTER>'''
95         return ''
96
97     def periodic_render(self, unused: str) -> bool:
98         page = requests.get(stevens_renderer.URL)
99         if page.status_code == 200:
100             contents = json.loads(page.content)
101             mp = contents['mountainPass']
102             conditions = contents['condition']
103             cameras = contents['cameras']
104             forecasts = contents['stationForecasts'][0]
105             with file_writer.file_writer('stevens-conditions_5_3000.html') as f:
106                 f.write(f'''
107 <H1>Stevens Pass Conditions:</H1>
108 <HR>
109 <TABLE WIDTH=90%>
110 <TR>
111   <TD>
112     {stevens_renderer.render_conditions(mp, conditions)}
113   </TD>
114   <TD>
115     {stevens_renderer.render_image(cameras)}
116   </TD>
117 </TR>
118 <TR>
119   <TD COLSPAN=2>
120     {stevens_renderer.render_forecast(forecasts)}
121   </TD>
122 </TR>
123 </TABLE>''')
124             return True
125         return False
126
127 # Test:
128 #test = stevens_renderer({"Test", 123})
129 #test.periodic_render("Test")