0916aee9fd694b1a6a1b84e0bb251c6d459b8111
[kiosk.git] / stevens_renderer.py
1 #!/usr/bin/env python3
2
3 import datetime
4 import json
5 import logging
6 import requests
7 from typing import Dict
8
9 import datetime_utils
10 import file_writer
11 import renderer
12
13
14 logger = logging.getLogger(__file__)
15
16
17 class stevens_renderer(renderer.abstaining_renderer):
18     URL = 'https://wsdot.com/Travel/Real-time/Service/api/MountainPass/Details/10'
19
20     def __init__(self, name_to_timeout_dict: Dict[str, int]) -> None:
21         super().__init__(name_to_timeout_dict)
22
23     def render_conditions(mp: Dict[str, str], conditions: Dict[str, str]) -> str:
24         ret = f'''
25 <TABLE>
26 <TR>
27   <TD><B>temperature:</B></TD>
28   <TD>{conditions['temperature']}&deg;{conditions['temperatureUnit'][0]}</TD>
29 </TR>
30 <TR>
31   <TD><B>weather:</B></TD>
32   <TD>{conditions['weather']}</TD>
33 </TR>
34 <TR>
35   <TD><B>road:</B></TD>
36   <TD>{conditions['roadCondition']}</TD>
37 </TR>'''
38         if 'restrictionOne' in conditions or 'restrictionTwo' in conditions:
39             ret += '''
40 <TR>
41   <TD><B>restrictions:</B></TD>
42   <TD>'''
43             if 'restrictionOne' in conditions:
44                 ret += f'''
45   {conditions['restrictionOne']['travelDirectionName']}:
46   {conditions['restrictionOne']['publicPage']}<BR>'''
47             if 'restrictionTwo' in conditions:
48                 ret += f'''
49   {conditions['restrictionTwo']['travelDirectionName']}:
50   {conditions['restrictionTwo']['publicPage']}'''
51         ret += '</TR></TABLE>'
52         return ret
53
54     def render_forecast(forecasts: Dict[str, str]) -> str:
55         ret = '<TABLE>'
56         fc = forecasts['forecast']['forecastData']
57         for n, f in enumerate(fc):
58             color = ''
59             if n % 2 == 0:
60                 color = ' BGCOLOR="#dfefff"'
61             ret += f'''
62 <TR>
63   <TD{color}><B>{f['periodText']}</B></TD>
64   <TD{color}>{f['forecastText']}</TD>
65 </TR>'''
66         ret += '</TABLE>'
67         return ret
68
69     def render_image(cameras: Dict[str, str]) -> str:
70         for camera in cameras:
71             if camera['cameraId'] == 8063:
72                 return f'''
73 <CENTER>
74   <IMG SRC={camera['cameraUrl']} WIDTH={camera['width']}>
75   <BR>
76   <B>{camera['cameraLabel']} ({camera['direction']})</B>
77 </CENTER>'''
78         return ''
79
80     def periodic_render(self, unused: str) -> bool:
81         page = requests.get(stevens_renderer.URL)
82         if page.status_code == 200:
83             contents = json.loads(page.content)
84             mp = contents['mountainPass']
85             conditions = contents['condition']
86             cameras = contents['cameras']
87             forecasts = contents['stationForecasts'][0]
88             now = datetime_utils.now_pacific()
89             tss = conditions['displayDate']
90             tss = tss.replace('Z', '+00:00')
91             ts = datetime.datetime.strptime(tss, '%Y-%m-%dT%H:%M:%S.%f%z')
92             tss = datetime_utils.describe_timedelta_briefly(now - ts)
93             with file_writer.file_writer('stevens-conditions_5_3000.html') as f:
94                 f.write(f'''
95 <H2>Stevens Pass Conditions ~{tss} ago:</H2>
96 <HR>
97 <TABLE WIDTH=90%>
98 <TR>
99   <TD>
100     {stevens_renderer.render_conditions(mp, conditions)}
101   </TD>
102   <TD>
103     {stevens_renderer.render_image(cameras)}
104   </TD>
105 </TR>
106 <TR>
107   <TD COLSPAN=2>
108     {stevens_renderer.render_forecast(forecasts)}
109   </TD>
110 </TR>
111 </TABLE>''')
112             return True
113         return False
114
115 test = stevens_renderer({"Test", 123})
116 test.periodic_render("Test")