Various changes including adding new stevens renderer.
[kiosk.git] / stevens_renderer.py
index eca0dcb517dac6f2a71e41734400f93268e44fbb..0916aee9fd694b1a6a1b84e0bb251c6d459b8111 100644 (file)
-import renderer
+#!/usr/bin/env python3
+
+import datetime
+import json
+import logging
+import requests
+from typing import Dict
+
+import datetime_utils
 import file_writer
-import http.client
-import xml.etree.ElementTree as ET
-
-class stevens_pass_conditions_renderer(renderer.debuggable_abstaining_renderer):
-    def __init__(self, name_to_timeout_dict, feed_site, feed_uris):
-        super(stevens_pass_conditions_renderer, self).__init__(
-            name_to_timeout_dict, False)
-        self.feed_site = feed_site
-        self.feed_uris = feed_uris
-
-    def debug_prefix(self):
-        return "stevens"
-
-    def periodic_render(self, key):
-        f = file_writer.file_writer('stevens-conditions_1_none.html')
-        for uri in self.feed_uris:
-            self.conn = http.client.HTTPSConnection(self.feed_site)
-            self.conn.request(
-                "GET",
-                uri,
-                None,
-                {"Accept-Charset": "utf-8"})
-            response = self.conn.getresponse()
-            if response.status == 200:
-                raw = response.read()
-                rss = ET.fromstring(raw)
-                channel = rss[0]
-                for item in channel.getchildren():
-                    if item.tag == "title":
-                        f.write("<h1>%s</h1><hr>" % item.text)
-                        f.write('<IMG WIDTH=512 ALIGN=RIGHT HEIGHT=382 SRC="https://images.wsdot.wa.gov/nc/002vc06430.jpg?t=637059938785646824" style="padding:8px;">')
-                    elif item.tag == "item":
-                        for x in item.getchildren():
-                            if x.tag == "description":
-                                text = x.text
-                                text = text.replace("<strong>Stevens Pass US2</strong><br/>", "")
-                                text = text.replace("<br/><br/>", "<BR>")
-                                text = text.replace("<strong>Elevation Meters:</strong>1238<BR>", "")
-                                f.write('<P>\n%s\n' % text)
-                f.close()
-                return True
-        f.close()
+import renderer
+
+
+logger = logging.getLogger(__file__)
+
+
+class stevens_renderer(renderer.abstaining_renderer):
+    URL = 'https://wsdot.com/Travel/Real-time/Service/api/MountainPass/Details/10'
+
+    def __init__(self, name_to_timeout_dict: Dict[str, int]) -> None:
+        super().__init__(name_to_timeout_dict)
+
+    def render_conditions(mp: Dict[str, str], conditions: Dict[str, str]) -> str:
+        ret = f'''
+<TABLE>
+<TR>
+  <TD><B>temperature:</B></TD>
+  <TD>{conditions['temperature']}&deg;{conditions['temperatureUnit'][0]}</TD>
+</TR>
+<TR>
+  <TD><B>weather:</B></TD>
+  <TD>{conditions['weather']}</TD>
+</TR>
+<TR>
+  <TD><B>road:</B></TD>
+  <TD>{conditions['roadCondition']}</TD>
+</TR>'''
+        if 'restrictionOne' in conditions or 'restrictionTwo' in conditions:
+            ret += '''
+<TR>
+  <TD><B>restrictions:</B></TD>
+  <TD>'''
+            if 'restrictionOne' in conditions:
+                ret += f'''
+  {conditions['restrictionOne']['travelDirectionName']}:
+  {conditions['restrictionOne']['publicPage']}<BR>'''
+            if 'restrictionTwo' in conditions:
+                ret += f'''
+  {conditions['restrictionTwo']['travelDirectionName']}:
+  {conditions['restrictionTwo']['publicPage']}'''
+        ret += '</TR></TABLE>'
+        return ret
+
+    def render_forecast(forecasts: Dict[str, str]) -> str:
+        ret = '<TABLE>'
+        fc = forecasts['forecast']['forecastData']
+        for n, f in enumerate(fc):
+            color = ''
+            if n % 2 == 0:
+                color = ' BGCOLOR="#dfefff"'
+            ret += f'''
+<TR>
+  <TD{color}><B>{f['periodText']}</B></TD>
+  <TD{color}>{f['forecastText']}</TD>
+</TR>'''
+        ret += '</TABLE>'
+        return ret
+
+    def render_image(cameras: Dict[str, str]) -> str:
+        for camera in cameras:
+            if camera['cameraId'] == 8063:
+                return f'''
+<CENTER>
+  <IMG SRC={camera['cameraUrl']} WIDTH={camera['width']}>
+  <BR>
+  <B>{camera['cameraLabel']} ({camera['direction']})</B>
+</CENTER>'''
+        return ''
+
+    def periodic_render(self, unused: str) -> bool:
+        page = requests.get(stevens_renderer.URL)
+        if page.status_code == 200:
+            contents = json.loads(page.content)
+            mp = contents['mountainPass']
+            conditions = contents['condition']
+            cameras = contents['cameras']
+            forecasts = contents['stationForecasts'][0]
+            now = datetime_utils.now_pacific()
+            tss = conditions['displayDate']
+            tss = tss.replace('Z', '+00:00')
+            ts = datetime.datetime.strptime(tss, '%Y-%m-%dT%H:%M:%S.%f%z')
+            tss = datetime_utils.describe_timedelta_briefly(now - ts)
+            with file_writer.file_writer('stevens-conditions_5_3000.html') as f:
+                f.write(f'''
+<H2>Stevens Pass Conditions ~{tss} ago:</H2>
+<HR>
+<TABLE WIDTH=90%>
+<TR>
+  <TD>
+    {stevens_renderer.render_conditions(mp, conditions)}
+  </TD>
+  <TD>
+    {stevens_renderer.render_image(cameras)}
+  </TD>
+</TR>
+<TR>
+  <TD COLSPAN=2>
+    {stevens_renderer.render_forecast(forecasts)}
+  </TD>
+</TR>
+</TABLE>''')
+            return True
         return False
+
+test = stevens_renderer({"Test", 123})
+test.periodic_render("Test")