11 class chooser(object):
12 """Base class of a thing that chooses pages"""
13 def get_page_list(self):
15 valid_filename = re.compile("([^_]+)_(\d+)_([^\.]+)\.html")
17 pages = [ f for f in os.listdir(constants.pages_dir)
18 if os.path.isfile(os.path.join(constants.pages_dir, f))]
20 result = re.match(valid_filename, page)
22 print(('chooser: candidate page: "%s"' % page))
23 if (result.group(3) != "none"):
24 freshness_requirement = int(result.group(3))
25 last_modified = int(os.path.getmtime(
26 os.path.join(constants.pages_dir, page)))
27 age = (now - last_modified)
28 if (age > freshness_requirement):
29 print(('chooser: "%s" is too old.' % page))
31 filenames.append(page)
34 def choose_next_page(self):
37 class weighted_random_chooser(chooser):
38 """Chooser that does it via weighted RNG."""
39 def dont_choose_page_twice_in_a_row_filter(self, choice):
40 if choice == self.last_choice:
42 self.last_choice = choice
45 def __init__(self, filter_list):
47 self.valid_filename = re.compile("([^_]+)_(\d+)_([^\.]+)\.html")
50 self.filter_list = filter_list
51 if filter_list is None:
53 self.filter_list.append(self.dont_choose_page_twice_in_a_row_filter)
55 def choose_next_page(self):
56 if (self.pages == None or
57 self.count % 100 == 0):
58 self.pages = self.get_page_list()
62 for page in self.pages:
63 result = re.match(self.valid_filename, page)
65 weight = int(result.group(2))
66 weights.append(weight)
67 total_weight += weight
68 if (total_weight <= 0):
72 random_pick = random.randrange(0, total_weight - 1)
74 for x in range(0, len(weights)):
76 if so_far > random_pick:
78 choice = self.pages[x]
80 # Allow filter list to suppress pages.
81 choice_is_filtered = False
82 for f in self.filter_list:
84 print("chooser: %s filtered by %s" % (choice, f.__name__))
85 choice_is_filtered = True
87 if choice_is_filtered:
94 class weighted_random_chooser_with_triggers(weighted_random_chooser):
95 """Same as WRC but has trigger events"""
96 def __init__(self, trigger_list, filter_list):
97 weighted_random_chooser.__init__(self, filter_list)
98 self.trigger_list = trigger_list
99 if trigger_list is None:
100 self.trigger_list = []
101 self.page_queue = set(())
103 def check_for_triggers(self):
105 for t in self.trigger_list:
106 x = t.get_triggered_page_list()
107 if x != None and len(x) > 0:
109 self.page_queue.add(y)
113 def choose_next_page(self):
114 if (self.pages == None or
115 self.count % 100 == 0):
116 self.pages = self.get_page_list()
118 triggered = self.check_for_triggers()
120 # First try to satisfy from the page queue.
121 if (len(self.page_queue) > 0):
122 print("chooser: Pulling page from queue...")
125 for t in self.page_queue:
126 if priority == None or t[1] > priority:
129 self.page_queue.remove((page, priority))
130 return page, triggered
132 # Fall back on weighted random choice.
134 return weighted_random_chooser.choose_next_page(self), False
136 class rotating_chooser(chooser):
137 """Chooser that does it in a rotation"""
139 self.valid_filename = re.compile("([^_]+)_(\d+)_([^\.]+)\.html")
144 def choose_next_page(self):
145 if (self.pages == None or
146 self.count % 100 == 0):
147 self.pages = self.get_page_list()
149 if len(self.pages) == 0:
152 if (self.current >= len(self.pages)):
155 page = self.pages[self.current]
161 def filter_news_during_dinnertime(page):
162 now = datetime.datetime.now()
163 is_dinnertime = now.hour >= 17 and now.hour <= 20
164 return (not is_dinnertime or
165 not ("cnn" in page or
167 "mynorthwest" in page or
169 "stranger" in page or
173 #x = weighted_random_chooser_with_triggers([], [ filter_news_during_dinnertime ])
174 #print(x.choose_next_page())