Various changes
[kiosk.git] / chooser.py
index df662da35a930a83d5d41860b24f44145f023d66..9bf98e303a91d95c7aba32272f0351da4e7c1e0d 100644 (file)
@@ -1,3 +1,4 @@
+import datetime
 import os
 import random
 import re
@@ -34,12 +35,22 @@ class chooser(object):
         pass
 
 class weighted_random_chooser(chooser):
-    """Chooser that does it via weighted RNG"""
-    def __init__(self):
+    """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):
         self.last_choice = ""
         self.valid_filename = re.compile("([^_]+)_(\d+)_([^\.]+)\.html")
         self.pages = None
         self.count = 0
+        self.filter_list = filter_list
+        if filter_list is None:
+            self.filter_list = []
+        self.filter_list.append(self.dont_choose_page_twice_in_a_row_filter)
 
     def choose_next_page(self):
         if (self.pages == None or
@@ -54,26 +65,39 @@ class weighted_random_chooser(chooser):
                 weight = int(result.group(2))
                 weights.append(weight)
                 total_weight += weight
-
         if (total_weight <= 0):
             raise error
 
         while True:
-            pick = random.randrange(0, total_weight - 1)
+            random_pick = random.randrange(0, total_weight - 1)
             so_far = 0
             for x in range(0, len(weights)):
                 so_far += weights[x]
-                if (so_far > pick and
-                    self.pages[x] != self.last_choice):
-                    self.last_choice = self.pages[x]
-                    self.count += 1
-                    return self.pages[x]
+                if so_far > random_pick:
+                    break
+            choice = self.pages[x]
+
+            # Allow filter list to suppress pages.
+            choice_is_filtered = False
+            for f in self.filter_list:
+                if not f(choice):
+                    print("chooser: %s filtered by %s" % (choice, f.__name__))
+                    choice_is_filtered = True
+                    break
+            if choice_is_filtered:
+                continue
+
+            # We're good...
+            self.count += 1
+            return choice
 
 class weighted_random_chooser_with_triggers(weighted_random_chooser):
     """Same as WRC but has trigger events"""
-    def __init__(self, trigger_list):
-        weighted_random_chooser.__init__(self)
+    def __init__(self, trigger_list, filter_list):
+        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):
@@ -93,9 +117,9 @@ class weighted_random_chooser_with_triggers(weighted_random_chooser):
 
         triggered = self.check_for_triggers()
 
-        # First try to satisfy from the page queue
+        # First try to satisfy from the page queue.
         if (len(self.page_queue) > 0):
-            print("Pulling page from queue")
+            print("chooser: Pulling page from queue...")
             page = None
             priority = None
             for t in self.page_queue:
@@ -133,4 +157,18 @@ class rotating_chooser(chooser):
         self.count += 1
         return page
 
-#x = weighted_random_chooser_with_triggers(None)
+# 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))
+
+#x = weighted_random_chooser_with_triggers([], [ filter_news_during_dinnertime ])
+#print(x.choose_next_page())