12 class chooser(object):
13 """Base class of a thing that chooses pages"""
15 def get_page_list(self):
17 valid_filename = re.compile("([^_]+)_(\d+)_([^\.]+)\.html")
21 for f in os.listdir(constants.pages_dir)
22 if os.path.isfile(os.path.join(constants.pages_dir, f))
25 result = re.match(valid_filename, page)
27 print(('chooser: candidate page: "%s"' % page))
28 if result.group(3) != "none":
29 freshness_requirement = int(result.group(3))
31 os.path.getmtime(os.path.join(constants.pages_dir, page))
33 age = now - last_modified
34 if age > freshness_requirement:
35 print(('chooser: "%s" is too old.' % page))
37 filenames.append(page)
40 def choose_next_page(self):
44 class weighted_random_chooser(chooser):
45 """Chooser that does it via weighted RNG."""
47 def dont_choose_page_twice_in_a_row_filter(self, choice):
48 if choice == self.last_choice:
50 self.last_choice = choice
53 def __init__(self, filter_list):
55 self.valid_filename = re.compile("([^_]+)_(\d+)_([^\.]+)\.html")
58 self.filter_list = filter_list
59 if filter_list is None:
61 self.filter_list.append(self.dont_choose_page_twice_in_a_row_filter)
63 def choose_next_page(self):
64 if self.pages == None or self.count % 100 == 0:
65 self.pages = self.get_page_list()
69 for page in self.pages:
70 result = re.match(self.valid_filename, page)
72 weight = int(result.group(2))
73 weights.append(weight)
74 total_weight += weight
79 random_pick = random.randrange(0, total_weight - 1)
81 for x in range(0, len(weights)):
83 if so_far > random_pick:
85 choice = self.pages[x]
87 # Allow filter list to suppress pages.
88 choice_is_filtered = False
89 for f in self.filter_list:
91 print("chooser: %s filtered by %s" % (choice, f.__name__))
92 choice_is_filtered = True
94 if choice_is_filtered:
102 class weighted_random_chooser_with_triggers(weighted_random_chooser):
103 """Same as WRC but has trigger events"""
105 def __init__(self, trigger_list, filter_list):
106 weighted_random_chooser.__init__(self, filter_list)
107 self.trigger_list = trigger_list
108 if trigger_list is None:
109 self.trigger_list = []
110 self.page_queue = set(())
112 def check_for_triggers(self):
114 for t in self.trigger_list:
115 x = t.get_triggered_page_list()
116 if x != None and len(x) > 0:
118 self.page_queue.add(y)
122 def choose_next_page(self):
123 if self.pages == None or self.count % 100 == 0:
124 self.pages = self.get_page_list()
126 triggered = self.check_for_triggers()
128 # First try to satisfy from the page queue.
129 if len(self.page_queue) > 0:
130 print("chooser: Pulling page from queue...")
133 for t in self.page_queue:
134 if priority == None or t[1] > priority:
137 self.page_queue.remove((page, priority))
138 return page, triggered
140 # Fall back on weighted random choice.
142 return weighted_random_chooser.choose_next_page(self), False
145 class rotating_chooser(chooser):
146 """Chooser that does it in a rotation"""
149 self.valid_filename = re.compile("([^_]+)_(\d+)_([^\.]+)\.html")
154 def choose_next_page(self):
155 if self.pages == None or self.count % 100 == 0:
156 self.pages = self.get_page_list()
158 if len(self.pages) == 0:
161 if self.current >= len(self.pages):
164 page = self.pages[self.current]
171 def filter_news_during_dinnertime(page):
172 now = datetime.datetime.now()
173 is_dinnertime = now.hour >= 17 and now.hour <= 20
174 return not is_dinnertime or not (
177 or "mynorthwest" in page
179 or "stranger" in page
185 # x = weighted_random_chooser_with_triggers([], [ filter_news_during_dinnertime ])
186 # print(x.choose_next_page())