Changes needed to get the kiosk to run on the rpi.
authorScott Gasch <[email protected]>
Wed, 24 Mar 2021 01:42:06 +0000 (18:42 -0700)
committerScott Gasch <[email protected]>
Wed, 24 Mar 2021 01:42:06 +0000 (18:42 -0700)
chooser.py
constants.py
health_renderer.py
kiosk.py
local_photos_mirror_renderer.py
reddit_renderer.py
renderer_catalog.py

index 743aa3a625aab18e7fbec57ab69c05394cad03d3..3fecc09717ff47c43988d76ac167b79cc2e4ef3d 100644 (file)
@@ -136,6 +136,7 @@ class weighted_random_chooser_with_triggers(weighted_random_chooser):
         triggered = self.check_for_triggers()
 
         # First try to satisfy from the page queue.
         triggered = self.check_for_triggers()
 
         # First try to satisfy from the page queue.
+        now = datetime.datetime.now()
         if len(self.page_queue) > 0:
             print("chooser: Pulling page from queue...")
             page = None
         if len(self.page_queue) > 0:
             print("chooser: Pulling page from queue...")
             page = None
@@ -149,6 +150,12 @@ class weighted_random_chooser_with_triggers(weighted_random_chooser):
             self.page_queue.remove((page, priority))
             return (page, triggered)
 
             self.page_queue.remove((page, priority))
             return (page, triggered)
 
+        # Always show the clock in the middle of the night.
+        elif now.hour < 7:
+            for page in self.pages:
+                if "clock" in page:
+                    return (page, False)
+
         # Fall back on weighted random choice.
         else:
             return (weighted_random_chooser.choose_next_page(self), False)
         # Fall back on weighted random choice.
         else:
             return (weighted_random_chooser.choose_next_page(self), False)
index 3c391d452169a3ed8d06177452f5cf86f95af5d8..3463ea6e2cc6b3d6518dab346724d62dcc8e9cf4 100644 (file)
@@ -4,6 +4,7 @@ hostname = 'kiosk.house'
 pages_dir = "/var/www/kiosk/pages"
 
 refresh_period_sec = 22.0
 pages_dir = "/var/www/kiosk/pages"
 
 refresh_period_sec = 22.0
+refresh_period_night_sec = 600.0
 render_period_sec = 30.0
 
 seconds_per_minute = 60
 render_period_sec = 30.0
 
 seconds_per_minute = 60
index 302e793efda2b5e5ae968a38ffcaa8adab22e1a0..d369630429bb1441f4b1fe3d6dc058cce6d01dbe 100644 (file)
@@ -2,7 +2,7 @@
 
 import os
 import time
 
 import os
 import time
-from typing import Dict
+from typing import Dict, List
 
 import constants
 import file_writer
 
 import constants
 import file_writer
index 7ffce23d6d85a4b65eb465e231a52d87355b78cc..2c75dd09a50e76e895ba003e717600a3804ad97c 100755 (executable)
--- a/kiosk.py
+++ b/kiosk.py
@@ -1,11 +1,14 @@
 #!/usr/bin/env python3
 
 from datetime import datetime
 #!/usr/bin/env python3
 
 from datetime import datetime
+import gc
+import linecache
 import os
 import sys
 from threading import Thread
 import time
 import traceback
 import os
 import sys
 from threading import Thread
 import time
 import traceback
+import tracemalloc
 from typing import Optional
 
 import constants
 from typing import Optional
 
 import constants
@@ -32,6 +35,48 @@ def filter_news_during_dinnertime(page: str) -> bool:
     )
 
 
     )
 
 
+def thread_janitor() -> None:
+    tracemalloc.start()
+    tracemalloc_target = 0.0
+    gc_target = 0.0
+    gc.enable()
+
+    while True:
+        now = time.time()
+        if now > tracemalloc_target:
+            tracemalloc_target = now + 30.0
+            snapshot = tracemalloc.take_snapshot()
+            snapshot = snapshot.filter_traces((
+                tracemalloc.Filter(False, "<frozen importlib._bootstrap>"),
+                tracemalloc.Filter(False, "<unknown>"),
+            ))
+            key_type = 'lineno'
+            limit = 10
+            top_stats = snapshot.statistics(key_type)
+            print("janitor: Top %s lines" % limit)
+            for index, stat in enumerate(top_stats[:limit], 1):
+                frame = stat.traceback[0]
+                # replace "/path/to/module/file.py" with "module/file.py"
+                filename = os.sep.join(frame.filename.split(os.sep)[-2:])
+                print("janitor: #%s: %s:%s: %.1f KiB"
+                      % (index, filename, frame.lineno, stat.size / 1024))
+                line = linecache.getline(frame.filename, frame.lineno).strip()
+                if line:
+                    print('janitor:    %s' % line)
+
+            other = top_stats[limit:]
+            if other:
+                size = sum(stat.size for stat in other)
+                print("janitor: %s other: %.1f KiB" % (len(other), size / 1024))
+            total = sum(stat.size for stat in top_stats)
+            print("janitor: Total allocated size: %.1f KiB" % (total / 1024))
+        if now > gc_target:
+            print("janitor: Running gc operation")
+            gc_target = now + 60.0
+            gc.collect()
+        time.sleep(10.0)
+
+
 def thread_change_current() -> None:
     page_chooser = chooser.weighted_random_chooser_with_triggers(
         trigger_catalog.get_triggers(), [filter_news_during_dinnertime]
 def thread_change_current() -> None:
     page_chooser = chooser.weighted_random_chooser_with_triggers(
         trigger_catalog.get_triggers(), [filter_news_during_dinnertime]
@@ -102,6 +147,13 @@ def emit_wrapped(f, filename) -> None:
         else:
             return "FFFFFF"
 
         else:
             return "FFFFFF"
 
+    def get_refresh_period() -> float:
+        now = datetime.now()
+        if now.hour < 7:
+            return constants.refresh_period_night_sec * 1000
+        else:
+            return constants.refresh_period_sec * 1000
+
     age = utils.describe_age_of_file_briefly(f"pages/{filename}")
     bgcolor = pick_background_color()
     f.write(
     age = utils.describe_age_of_file_briefly(f"pages/{filename}")
     bgcolor = pick_background_color()
     f.write(
@@ -292,7 +344,7 @@ def emit_wrapped(f, filename) -> None:
 </BODY>"""
         % (
             bgcolor,
 </BODY>"""
         % (
             bgcolor,
-            constants.refresh_period_sec * 1000,
+            get_refresh_period(),
             constants.hostname,
             bgcolor,
             filename,
             constants.hostname,
             bgcolor,
             filename,
@@ -329,6 +381,7 @@ if __name__ == "__main__":
     logging.basicConfig()
     changer_thread: Optional[Thread] = None
     renderer_thread: Optional[Thread] = None
     logging.basicConfig()
     changer_thread: Optional[Thread] = None
     renderer_thread: Optional[Thread] = None
+    janitor_thread: Optional[Thread] = None
     while True:
         if changer_thread is None or not changer_thread.is_alive():
             print(
     while True:
         if changer_thread is None or not changer_thread.is_alive():
             print(
@@ -342,4 +395,10 @@ if __name__ == "__main__":
             )
             renderer_thread = Thread(target=thread_invoke_renderers, args=())
             renderer_thread.start()
             )
             renderer_thread = Thread(target=thread_invoke_renderers, args=())
             renderer_thread.start()
+        if janitor_thread is None or not janitor_thread.is_alive():
+            print(
+                f"MAIN[{utils.timestamp()}] - (Re?)initializing janitor thread... (wtf?!)"
+            )
+            janitor_thread = Thread(target=thread_janitor, args=())
+            janitor_thread.start()
         time.sleep(60)
         time.sleep(60)
index b27a7918feba389de82897941806bda83ee6ac99..287bdd697ecdfad96c93e47aa12619463cee54f9 100644 (file)
@@ -5,7 +5,6 @@ import random
 import re
 from typing import Dict, Set
 
 import re
 from typing import Dict, Set
 
-import constants
 import file_writer
 import renderer
 
 import file_writer
 import renderer
 
@@ -13,7 +12,7 @@ import renderer
 class local_photos_mirror_renderer(renderer.debuggable_abstaining_renderer):
     """A renderer that uses a local mirror of Google photos"""
 
 class local_photos_mirror_renderer(renderer.debuggable_abstaining_renderer):
     """A renderer that uses a local mirror of Google photos"""
 
-    ALBUM_ROOT_DIR = "/var/www/kiosk/pages/images/gphotos/albums"
+    album_root_directory = "/var/www/kiosk/pages/images/gphotos/albums"
 
     album_whitelist = frozenset(
         [
 
     album_whitelist = frozenset(
         [
@@ -87,7 +86,7 @@ class local_photos_mirror_renderer(renderer.debuggable_abstaining_renderer):
         """Walk the filesystem looking for photos in whitelisted albums and
         keep their paths in memory.
         """
         """Walk the filesystem looking for photos in whitelisted albums and
         keep their paths in memory.
         """
-        for root, subdirs, files in os.walk(self.ALBUM_ROOT_DIR):
+        for root, subdirs, files in os.walk(self.album_root_directory):
             last_dir = root.rsplit("/", 1)[1]
             if self.album_is_in_whitelist(last_dir):
                 for filename in files:
             last_dir = root.rsplit("/", 1)[1]
             if self.album_is_in_whitelist(last_dir):
                 for filename in files:
@@ -95,7 +94,7 @@ class local_photos_mirror_renderer(renderer.debuggable_abstaining_renderer):
                     if extension in self.extension_whitelist:
                         photo_path = os.path.join(root, filename)
                         photo_url = photo_path.replace(
                     if extension in self.extension_whitelist:
                         photo_path = os.path.join(root, filename)
                         photo_url = photo_path.replace(
-                            "/var/www/", f"http://{constants.hostname}/", 1
+                            "/var/www/", "http://kiosk.house/", 1
                         )
                         self.candidate_photos.add(photo_url)
         return True
                         )
                         self.candidate_photos.add(photo_url)
         return True
index a4050a20f0f47dcd9b2e2ed6ce294c34d2b5411c..74bddaffa1b368e0163232855b400ab08c02be40 100644 (file)
@@ -179,7 +179,7 @@ class showerthoughts_reddit_renderer(reddit_renderer):
         super(showerthoughts_reddit_renderer, self).__init__(
             name_to_timeout_dict,
             ["showerthoughts"],
         super(showerthoughts_reddit_renderer, self).__init__(
             name_to_timeout_dict,
             ["showerthoughts"],
-            min_votes=350,
+            min_votes=250,
             additional_filters=[
                 showerthoughts_reddit_renderer.dont_tell_me_about_gift_cards
             ],
             additional_filters=[
                 showerthoughts_reddit_renderer.dont_tell_me_about_gift_cards
             ],
index 3fa9d2ad61a757cc2fce447ecc25041d692d3c63..6eccb6ebab3fbb8e9b49ba6bac44568f1e7a484b 100644 (file)
@@ -128,12 +128,13 @@ __registry = [
         "Seattle Times Segments",
     ),
     weather_renderer.weather_renderer(
         "Seattle Times Segments",
     ),
     weather_renderer.weather_renderer(
-        {"Fetch Weather (Bellevue)": (hours * 4)}, "home"
+        {"Fetch Weather (Bellevue)": (hours * 6)}, "home"
     ),
     weather_renderer.weather_renderer(
     ),
     weather_renderer.weather_renderer(
-        {"Fetch Weather (Stevens)": (hours * 4)}, "stevens"
+        {"Fetch Weather (Stevens)": (hours * 6)}, "stevens"
     ),
     ),
-    weather_renderer.weather_renderer({"Fetch Weather (Telma)": (hours * 4)}, "telma"),
+    weather_renderer.weather_renderer(
+        {"Fetch Weather (Telma)": (hours * 6)}, "telma"),
     local_photos_mirror_renderer.local_photos_mirror_renderer(
         {"Index Photos": (hours * 24), "Choose Photo": (always)}
     ),
     local_photos_mirror_renderer.local_photos_mirror_renderer(
         {"Index Photos": (hours * 24), "Choose Photo": (always)}
     ),