5 from typing import Callable, Dict, List
11 import profanity_filter
13 import renderer_catalog
17 class reddit_renderer(renderer.debuggable_abstaining_renderer):
18 """A renderer to pull text content from reddit."""
22 name_to_timeout_dict: Dict[str, int],
23 subreddit_list: List[str],
27 additional_filters: List[Callable[[str], bool]] = [],
29 super(reddit_renderer, self).__init__(name_to_timeout_dict, True)
30 self.subreddit_list = subreddit_list
31 self.praw = praw.Reddit(
32 client_id=secrets.reddit_client_id,
33 client_secret=secrets.reddit_client_secret,
34 user_agent=secrets.reddit_user_agent,
36 self.min_votes = min_votes
37 self.font_size = font_size
38 self.messages = grab_bag.grab_bag()
39 self.filters = [profanity_filter.profanity_filter().contains_bad_words]
40 self.filters.extend(additional_filters)
43 def debug_prefix(self) -> str:
45 for subreddit in self.subreddit_list:
47 return f"reddit({x.strip()})"
49 def periodic_render(self, key: str) -> bool:
50 self.debug_print('called for "%s"' % key)
52 return self.scrape_reddit()
53 elif key == "Shuffle":
54 return self.shuffle_messages()
56 raise error("Unexpected operation")
58 def append_message(self, messages: List[str]) -> None:
60 if msg.title in self.deduper:
63 for filter in self.filters:
64 if filter(msg.title) is True:
65 filtered = filter.__name__
68 print(f'Filter {filtered} struck down "{msg.title}"')
70 if msg.ups < self.min_votes:
71 print(f'"{msg.title}" doesn\'t have enough upvotes to be interesting')
75 self.deduper.add(msg.title)
76 content = f"{msg.ups}"
78 msg.thumbnail != "self"
79 and msg.thumbnail != "default"
80 and msg.thumbnail != ""
82 content = f'<IMG SRC="{msg.thumbnail}">'
85 <TABLE STYLE="font-size:{self.font_size}pt;">
87 <!-- The number of upvotes or item image: -->
88 <TD STYLE="font-weight:900; padding:8px;">
89 <FONT COLOR="maroon" SIZE=40>{content}</FONT>
92 <!-- The content and author: -->
94 <B>{msg.title}</B><BR><FONT COLOR=#bbbbbb>({msg.author})</FONT>
100 self.debug_print("Unexpected exception, skipping message.")
102 def scrape_reddit(self) -> None:
104 self.messages.clear()
105 for subreddit in self.subreddit_list:
107 msg = self.praw.subreddit(subreddit).hot()
108 self.append_message(msg)
112 msg = self.praw.subreddit(subreddit).new()
113 self.append_message(msg)
117 msg = self.praw.subreddit(subreddit).rising()
118 self.append_message(msg)
122 msg = self.praw.subreddit(subreddit).controversial("week")
123 self.append_message(msg)
127 msg = self.praw.subreddit(subreddit).top("day")
128 self.append_message(msg)
131 self.debug_print(f"There are now {self.messages.size()} messages")
134 def shuffle_messages(self) -> bool:
135 layout = page_builder.page_builder()
136 layout.set_layout(page_builder.page_builder.LAYOUT_FOUR_ITEMS)
138 for subreddit in self.subreddit_list:
142 x = "[local interests]"
145 layout.set_title("Reddit /r/%s" % x.strip())
146 subset = self.messages.subset(4)
148 self.debug_print("Not enough messages to pick from.")
152 with file_writer.file_writer("%s_4_10800.html" % self.subreddit_list[0]) as f:
153 layout.render_html(f)
157 class til_reddit_renderer(reddit_renderer):
158 def __init__(self, name_to_timeout_dict: Dict[str, int]):
159 super(til_reddit_renderer, self).__init__(
160 name_to_timeout_dict, ["todayilearned"], min_votes=200, font_size=20
164 class quotes_reddit_renderer(reddit_renderer):
165 def __init__(self, name_to_timeout_dict: Dict[str, int]):
166 super(quotes_reddit_renderer, self).__init__(
167 name_to_timeout_dict, ["quotes"], min_votes=200, font_size=20
171 class showerthoughts_reddit_renderer(reddit_renderer):
172 def dont_tell_me_about_gift_cards(msg: str) -> bool:
173 return not "IMPORTANT PSA: No, you did not win a gift card" in msg
175 def __init__(self, name_to_timeout_dict: Dict[str, int]):
176 super(showerthoughts_reddit_renderer, self).__init__(
177 name_to_timeout_dict,
181 showerthoughts_reddit_renderer.dont_tell_me_about_gift_cards
186 class seattle_reddit_renderer(reddit_renderer):
187 def __init__(self, name_to_timeout_dict: Dict[str, int]):
188 super(seattle_reddit_renderer, self).__init__(
189 name_to_timeout_dict,
190 ["seattle", "seattleWA", "SeaWA", "bellevue", "kirkland", "CoronavirusWA"],
195 class lifeprotips_reddit_renderer(reddit_renderer):
196 def __init__(self, name_to_timeout_dict: Dict[str, int]):
197 super(lifeprotips_reddit_renderer, self).__init__(
198 name_to_timeout_dict, ["lifeprotips"], min_votes=100
202 # x = reddit_renderer({"Test", 1234}, ["seattle","bellevue"], min_votes=50, font_size=24)
203 # x.periodic_render("Scrape")
204 # x.periodic_render("Shuffle")