3 import praw # type: ignore
5 from typing import Callable, Dict, Iterable, List, Set
11 import profanity_filter
16 class reddit_renderer(renderer.debuggable_abstaining_renderer):
17 """A renderer to pull text content from reddit."""
21 name_to_timeout_dict: Dict[str, int],
22 subreddit_list: List[str],
26 additional_filters: Iterable[Callable[[str], bool]] = [],
28 super(reddit_renderer, self).__init__(name_to_timeout_dict, True)
29 self.subreddit_list = subreddit_list
30 self.praw = praw.Reddit(
31 client_id=secrets.reddit_client_id,
32 client_secret=secrets.reddit_client_secret,
33 user_agent=secrets.reddit_user_agent,
35 self.min_votes = min_votes
36 self.font_size = font_size
37 self.messages = grab_bag.grab_bag()
38 self.filters: List[Callable[..., bool]] = [
39 profanity_filter.profanity_filter().contains_bad_words
41 self.filters.extend(additional_filters)
42 self.deduper: Set[str] = set()
44 def debug_prefix(self) -> str:
46 for subreddit in self.subreddit_list:
48 return f"reddit({x.strip()})"
50 def periodic_render(self, key: str) -> bool:
51 self.debug_print('called for "%s"' % key)
53 return self.scrape_reddit()
54 elif key == "Shuffle":
55 return self.shuffle_messages()
57 raise Exception("Unexpected operation")
59 def append_message(self, messages: List[str]) -> None:
61 title = str(msg.title)
62 if title in self.deduper:
65 for filt in self.filters:
66 if filt(title) is True:
67 filtered = filt.__name__
70 print(f'Filter {filtered} struck down "{title}"')
72 if msg.ups < self.min_votes:
73 print(f'"{title}" doesn\'t have enough upvotes to be interesting')
77 self.deduper.add(title)
78 content = f"{msg.ups}"
80 msg.thumbnail != "self"
81 and msg.thumbnail != "default"
82 and msg.thumbnail != ""
84 content = f'<IMG SRC="{msg.thumbnail}">'
87 <TABLE STYLE="font-size:{self.font_size}pt;">
89 <!-- The number of upvotes or item image: -->
90 <TD STYLE="font-weight:900; padding:8px;">
91 <FONT COLOR="maroon" SIZE=40>{content}</FONT>
94 <!-- The content and author: -->
96 <B>{title}</B><BR><FONT COLOR=#bbbbbb>({msg.author})</FONT>
102 self.debug_print("Unexpected exception, skipping message.")
104 def scrape_reddit(self) -> bool:
106 self.messages.clear()
107 for subreddit in self.subreddit_list:
109 msg = self.praw.subreddit(subreddit).hot()
110 self.append_message(msg)
114 msg = self.praw.subreddit(subreddit).new()
115 self.append_message(msg)
119 msg = self.praw.subreddit(subreddit).rising()
120 self.append_message(msg)
124 msg = self.praw.subreddit(subreddit).controversial("week")
125 self.append_message(msg)
129 msg = self.praw.subreddit(subreddit).top("day")
130 self.append_message(msg)
133 self.debug_print(f"There are now {self.messages.size()} messages")
136 def shuffle_messages(self) -> bool:
137 layout = page_builder.page_builder()
138 layout.set_layout(page_builder.page_builder.LAYOUT_FOUR_ITEMS)
140 for subreddit in self.subreddit_list:
144 x = "[local interests]"
147 layout.set_title("Reddit /r/%s" % x.strip())
148 subset = self.messages.subset(4)
150 self.debug_print("Not enough messages to pick from.")
154 with file_writer.file_writer("%s_4_10800.html" % self.subreddit_list[0]) as f:
155 layout.render_html(f)
159 class til_reddit_renderer(reddit_renderer):
160 def __init__(self, name_to_timeout_dict: Dict[str, int]):
161 super(til_reddit_renderer, self).__init__(
162 name_to_timeout_dict, ["todayilearned"], min_votes=200, font_size=20
166 class quotes_reddit_renderer(reddit_renderer):
167 def __init__(self, name_to_timeout_dict: Dict[str, int]):
168 super(quotes_reddit_renderer, self).__init__(
169 name_to_timeout_dict, ["quotes"], min_votes=200, font_size=20
173 class showerthoughts_reddit_renderer(reddit_renderer):
175 def dont_tell_me_about_gift_cards(msg: str) -> bool:
176 return not "IMPORTANT PSA: No, you did not win a gift card" in msg
178 def __init__(self, name_to_timeout_dict: Dict[str, int]):
179 super(showerthoughts_reddit_renderer, self).__init__(
180 name_to_timeout_dict,
184 showerthoughts_reddit_renderer.dont_tell_me_about_gift_cards
189 class seattle_reddit_renderer(reddit_renderer):
190 def __init__(self, name_to_timeout_dict: Dict[str, int]):
191 super(seattle_reddit_renderer, self).__init__(
192 name_to_timeout_dict,
193 ["seattle", "seattleWA", "SeaWA", "bellevue", "kirkland", "CoronavirusWA"],
198 class lifeprotips_reddit_renderer(reddit_renderer):
199 def __init__(self, name_to_timeout_dict: Dict[str, int]):
200 super(lifeprotips_reddit_renderer, self).__init__(
201 name_to_timeout_dict, ["lifeprotips"], min_votes=100
205 #x = reddit_renderer({"Test", 1234}, ["seattle","bellevue"], min_votes=50, font_size=24)
206 #x.periodic_render("Scrape")
207 #x.periodic_render("Shuffle")