Adding type annotations and fixing up formatting.
[kiosk.git] / chooser.py
index ac8948a9a8df6958b99c32642151ed613baef9f9..d5c6482f331e818f7863eae63087c94f3e1ad077 100644 (file)
@@ -1,18 +1,23 @@
+#!/usr/bin/env python3
+
+from abc import ABC, abstractmethod
 import datetime
+import glob
 import os
 import random
 import re
 import sys
 import time
-import glob
+from typing import Callable, List
+
 import constants
 import trigger
 
 
-class chooser(object):
+class chooser(ABC):
     """Base class of a thing that chooses pages"""
 
-    def get_page_list(self):
+    def get_page_list(self) -> List[str]:
         now = time.time()
         valid_filename = re.compile("([^_]+)_(\d+)_([^\.]+)\.html")
         filenames = []
@@ -24,7 +29,7 @@ class chooser(object):
         for page in pages:
             result = re.match(valid_filename, page)
             if result != None:
-                print(('chooser: candidate page: "%s"' % page))
+                print(f'chooser: candidate page: "{page}"')
                 if result.group(3) != "none":
                     freshness_requirement = int(result.group(3))
                     last_modified = int(
@@ -32,25 +37,20 @@ class chooser(object):
                     )
                     age = now - last_modified
                     if age > freshness_requirement:
-                        print(('chooser: "%s" is too old.' % page))
+                        print(f'chooser: "{page}" is too old.')
                         continue
                 filenames.append(page)
         return filenames
 
-    def choose_next_page(self):
+    @abstractmethod
+    def choose_next_page(self) -> str:
         pass
 
 
 class weighted_random_chooser(chooser):
     """Chooser that does it via weighted RNG."""
 
-    def dont_choose_page_twice_in_a_row_filter(self, choice):
-        if choice == self.last_choice:
-            return False
-        self.last_choice = choice
-        return True
-
-    def __init__(self, filter_list):
+    def __init__(self, filter_list: List[Callable[[str], bool]]) -> None:
         self.last_choice = ""
         self.valid_filename = re.compile("([^_]+)_(\d+)_([^\.]+)\.html")
         self.pages = None
@@ -60,7 +60,13 @@ class weighted_random_chooser(chooser):
             self.filter_list = []
         self.filter_list.append(self.dont_choose_page_twice_in_a_row_filter)
 
-    def choose_next_page(self):
+    def dont_choose_page_twice_in_a_row_filter(self, choice: str) -> bool:
+        if choice == self.last_choice:
+            return False
+        self.last_choice = choice
+        return True
+
+    def choose_next_page(self) -> str:
         if self.pages == None or self.count % 100 == 0:
             self.pages = self.get_page_list()
 
@@ -88,7 +94,7 @@ class weighted_random_chooser(chooser):
             choice_is_filtered = False
             for f in self.filter_list:
                 if not f(choice):
-                    print("chooser: %s filtered by %s" % (choice, f.__name__))
+                    print(f"chooser: {choice} filtered by {f.__name__}")
                     choice_is_filtered = True
                     break
             if choice_is_filtered:
@@ -102,14 +108,18 @@ class weighted_random_chooser(chooser):
 class weighted_random_chooser_with_triggers(weighted_random_chooser):
     """Same as WRC but has trigger events"""
 
-    def __init__(self, trigger_list, filter_list):
+    def __init__(
+        self,
+        trigger_list: List[trigger.trigger],
+        filter_list: List[Callable[[str], bool]],
+    ) -> None:
         weighted_random_chooser.__init__(self, filter_list)
         self.trigger_list = trigger_list
         if trigger_list is None:
             self.trigger_list = []
         self.page_queue = set(())
 
-    def check_for_triggers(self):
+    def check_for_triggers(self) -> bool:
         triggered = False
         for t in self.trigger_list:
             x = t.get_triggered_page_list()
@@ -119,7 +129,7 @@ class weighted_random_chooser_with_triggers(weighted_random_chooser):
                     triggered = True
         return triggered
 
-    def choose_next_page(self):
+    def choose_next_page(self) -> str:
         if self.pages == None or self.count % 100 == 0:
             self.pages = self.get_page_list()
 
@@ -142,45 +152,18 @@ class weighted_random_chooser_with_triggers(weighted_random_chooser):
             return weighted_random_chooser.choose_next_page(self), False
 
 
-class rotating_chooser(chooser):
-    """Chooser that does it in a rotation"""
-
-    def __init__(self):
-        self.valid_filename = re.compile("([^_]+)_(\d+)_([^\.]+)\.html")
-        self.pages = None
-        self.current = 0
-        self.count = 0
-
-    def choose_next_page(self):
-        if self.pages == None or self.count % 100 == 0:
-            self.pages = self.get_page_list()
-
-        if len(self.pages) == 0:
-            raise error
-
-        if self.current >= len(self.pages):
-            self.current = 0
-
-        page = self.pages[self.current]
-        self.current += 1
-        self.count += 1
-        return page
-
-
 # Test
-def filter_news_during_dinnertime(page):
-    now = datetime.datetime.now()
-    is_dinnertime = now.hour >= 17 and now.hour <= 20
-    return not is_dinnertime or not (
-        "cnn" in page
-        or "news" in page
-        or "mynorthwest" in page
-        or "seattle" in page
-        or "stranger" in page
-        or "twitter" in page
-        or "wsj" in page
-    )
-
-
+# def filter_news_during_dinnertime(page):
+#    now = datetime.datetime.now()
+#    is_dinnertime = now.hour >= 17 and now.hour <= 20
+#    return not is_dinnertime or not (
+#        "cnn" in page
+#        or "news" in page
+#        or "mynorthwest" in page
+#        or "seattle" in page
+#        or "stranger" in page
+#        or "twitter" in page
+#        or "wsj" in page
+#    )
 # x = weighted_random_chooser_with_triggers([], [ filter_news_during_dinnertime ])
 # print(x.choose_next_page())