4 from typing import Callable, Dict, Iterable, List, Set
6 import praw # type: ignore
8 from scottutilz import profanity_filter
14 import kiosk_secrets as secrets
17 logger = logging.getLogger(__name__)
20 class reddit_renderer(renderer.abstaining_renderer):
21 """A renderer to pull text content from reddit."""
25 name_to_timeout_dict: Dict[str, int],
26 subreddit_list: List[str],
30 additional_filters: Iterable[Callable[[str], bool]] = [],
32 super().__init__(name_to_timeout_dict)
33 self.subreddit_list = subreddit_list
34 self.praw = praw.Reddit(
35 client_id=secrets.reddit_client_id,
36 client_secret=secrets.reddit_client_secret,
37 user_agent=secrets.reddit_user_agent,
39 self.min_votes = min_votes
40 self.font_size = font_size
41 self.messages = grab_bag.grab_bag()
42 self.filters: List[Callable[..., bool]] = [
43 profanity_filter.ProfanityFilter().contains_bad_word
45 self.filters.extend(additional_filters)
46 self.deduper: Set[str] = set()
48 def periodic_render(self, key: str) -> bool:
49 logger.debug('called for "%s"' % key)
51 return self.scrape_reddit()
52 elif key == "Shuffle":
53 return self.shuffle_messages()
55 raise Exception("Unexpected operation")
57 def append_message(self, messages: List[str]) -> None:
59 title = str(msg.title)
60 if title in self.deduper:
63 for filt in self.filters:
64 if filt(title) is True:
65 filtered = filt.__name__
68 logger.info(f'Filter {filtered} struck down "{title}"')
70 if msg.ups < self.min_votes:
72 f'"{title}" doesn\'t have enough upvotes to be interesting'
76 self.deduper.add(title)
77 content = f"{msg.ups}"
79 msg.thumbnail != "self"
80 and msg.thumbnail != "default"
81 and msg.thumbnail != ""
83 content = f'<IMG SRC="{msg.thumbnail}">'
86 <TABLE STYLE="font-size:{self.font_size}pt;">
88 <!-- The number of upvotes or item image: -->
89 <TD STYLE="font-weight:900; padding:8px;">
90 <FONT COLOR="maroon" SIZE=40>{content}</FONT>
93 <!-- The content and author: -->
95 <B>{title}</B><BR><FONT COLOR=#bbbbbb>({msg.author})</FONT>
101 def scrape_reddit(self) -> bool:
103 self.messages.clear()
104 for subreddit in self.subreddit_list:
106 msg = self.praw.subreddit(subreddit).hot()
107 self.append_message(msg)
111 msg = self.praw.subreddit(subreddit).new()
112 self.append_message(msg)
116 msg = self.praw.subreddit(subreddit).rising()
117 self.append_message(msg)
121 msg = self.praw.subreddit(subreddit).controversial("week")
122 self.append_message(msg)
126 msg = self.praw.subreddit(subreddit).top("day")
127 self.append_message(msg)
130 logger.debug(f"There are now {self.messages.size()} messages")
133 def shuffle_messages(self) -> bool:
134 layout = page_builder.page_builder()
135 layout.set_layout(page_builder.page_builder.LAYOUT_FOUR_ITEMS)
137 for subreddit in self.subreddit_list:
141 x = "[local interests]"
144 layout.set_title("Reddit /r/%s" % x.strip())
145 subset = self.messages.subset(4)
147 logger.debug("Not enough messages to pick from.")
151 with file_writer.file_writer("%s_4_10800.html" % self.subreddit_list[0]) as f:
152 layout.render_html(f)
156 class til_reddit_renderer(reddit_renderer):
157 def __init__(self, name_to_timeout_dict: Dict[str, int]):
159 name_to_timeout_dict, ["todayilearned"], min_votes=100, font_size=20
163 class quotes_reddit_renderer(reddit_renderer):
164 def __init__(self, name_to_timeout_dict: Dict[str, int]):
165 super().__init__(name_to_timeout_dict, ["quotes"], min_votes=100, font_size=20)
168 class showerthoughts_reddit_renderer(reddit_renderer):
170 def dont_tell_me_about_gift_cards(msg: str) -> bool:
171 return "gift card" in msg
173 def __init__(self, name_to_timeout_dict: Dict[str, int]):
175 name_to_timeout_dict,
179 showerthoughts_reddit_renderer.dont_tell_me_about_gift_cards
184 class seattle_reddit_renderer(reddit_renderer):
185 def __init__(self, name_to_timeout_dict: Dict[str, int]):
187 name_to_timeout_dict,
188 ["seattle", "seattleWA", "SeaWA", "bellevue", "kirkland", "CoronavirusWA"],
193 class lifeprotips_reddit_renderer(reddit_renderer):
194 def __init__(self, name_to_timeout_dict: Dict[str, int]):
195 super().__init__(name_to_timeout_dict, ["lifeprotips"], min_votes=50)
198 # x = reddit_renderer({"Test", 1234}, ["seattle","bellevue"], min_votes=50, font_size=24)
199 # x.periodic_render("Scrape")
200 # x.periodic_render("Shuffle")