Have page builder allow you to inject custom HTML. Make the generic
[kiosk.git] / reddit_renderer.py
1 import constants
2 import file_writer
3 import grab_bag
4 import renderer
5 import secrets
6 import page_builder
7 import praw
8 import profanity_filter
9 import random
10
11 class reddit_renderer(renderer.debuggable_abstaining_renderer):
12     """A renderer to pull text content from reddit."""
13
14     def __init__(self, name_to_timeout_dict, subreddit_list, min_votes, font_size):
15         super(reddit_renderer, self).__init__(name_to_timeout_dict, True)
16         self.subreddit_list = subreddit_list
17         self.praw = praw.Reddit(client_id=secrets.reddit_client_id,
18                                 client_secret=secrets.reddit_client_secret,
19                                 user_agent=secrets.reddit_user_agent)
20         self.min_votes = min_votes
21         self.font_size = font_size
22         self.messages = grab_bag.grab_bag()
23         self.filter = profanity_filter.profanity_filter()
24         self.deduper = set()
25
26     def debug_prefix(self):
27         x = ""
28         for subreddit in self.subreddit_list:
29             x += ("%s " % subreddit)
30         return "reddit(%s)" % x.strip()
31
32     def periodic_render(self, key):
33         self.debug_print('called for "%s"' % key)
34         if key == "Scrape":
35             return self.scrape_reddit()
36         elif key == "Shuffle":
37             return self.shuffle_messages()
38         else:
39             raise error('Unexpected operation')
40
41     def append_message(self, messages):
42         for msg in messages:
43             if (not self.filter.contains_bad_words(msg.title)
44                 and msg.ups > self.min_votes
45                 and not msg.title in self.deduper):
46                 try:
47                     self.deduper.add(msg.title)
48                     content = "%d" % msg.ups
49                     if (msg.thumbnail != "self" and
50                         msg.thumbnail != "default" and
51                         msg.thumbnail != ""):
52                         content = '<IMG SRC="%s">' % msg.thumbnail
53                     x = """
54 <TABLE STYLE="font-size:%dpt;">
55   <TR>
56     <!-- The number of upvotes or item image: -->
57     <TD STYLE="font-weight:900; padding:8px;">
58       <FONT COLOR="maroon" SIZE=40>%s</FONT>
59     </TD>
60
61     <!-- The content and author: -->
62     <TD>
63       <B>%s</B><BR><FONT COLOR=#bbbbbb>(%s)</FONT>
64     </TD>
65   </TR>
66 </TABLE>""" % (self.font_size, content, msg.title, msg.author)
67                     self.messages.add(x)
68                 except:
69                     self.debug_print('Unexpected exception, skipping message.')
70             else:
71                 self.debug_print('skipped message "%s" for profanity or low score' % (
72                     msg.title))
73
74     def scrape_reddit(self):
75         self.deduper.clear()
76         self.messages.clear()
77         for subreddit in self.subreddit_list:
78             try:
79                 msg = self.praw.subreddit(subreddit).hot()
80                 self.append_message(msg)
81             except:
82                 pass
83             try:
84                 msg = self.praw.subreddit(subreddit).new()
85                 self.append_message(msg)
86             except:
87                 pass
88             try:
89                 msg = self.praw.subreddit(subreddit).rising()
90                 self.append_message(msg)
91             except:
92                 pass
93             try:
94                 msg = self.praw.subreddit(subreddit).controversial('week')
95                 self.append_message(msg)
96             except:
97                 pass
98             try:
99                 msg = self.praw.subreddit(subreddit).top('day')
100                 self.append_message(msg)
101             except:
102                 pass
103             self.debug_print("There are now %d messages" % self.messages.size())
104         return True
105
106     def shuffle_messages(self):
107         layout = page_builder.page_builder()
108         layout.set_layout(page_builder.page_builder.LAYOUT_FOUR_ITEMS)
109         x = ""
110         for subreddit in self.subreddit_list:
111             x += ("%s " % subreddit)
112         if len(x) > 30:
113             if "SeaWA" in x:
114                 x = "[local interests]"
115             else:
116                 x = "Unknown, fixme"
117         layout.set_title("Reddit /r/%s" % x.strip())
118         subset = self.messages.subset(4)
119         if subset is None:
120             self.debug_print("Not enough messages to pick from.")
121             return False
122         for msg in subset:
123             layout.add_item(msg)
124         f = file_writer.file_writer("%s_4_10800.html" % self.subreddit_list[0])
125         layout.render_html(f)
126         f.close()
127         return True
128
129 class til_reddit_renderer(reddit_renderer):
130     def __init__(self, name_to_timeout_dict):
131         super(til_reddit_renderer, self).__init__(
132             name_to_timeout_dict, ["todayilearned"], 200, 20)
133
134 class quotes_reddit_renderer(reddit_renderer):
135     def __init__(self, name_to_timeout_dict):
136         super(quotes_reddit_renderer, self).__init__(
137             name_to_timeout_dict, ["quotes"], 200, 20)
138
139 class showerthoughts_reddit_renderer(reddit_renderer):
140     def __init__(self, name_to_timeout_dict):
141         super(showerthoughts_reddit_renderer, self).__init__(
142             name_to_timeout_dict, ["showerthoughts"], 350, 24)
143
144 class seattle_reddit_renderer(reddit_renderer):
145     def __init__(self, name_to_timeout_dict):
146         super(seattle_reddit_renderer, self).__init__(
147             name_to_timeout_dict, ["seattle","seattleWA","SeaWA","bellevue","kirkland", "CoronavirusWA"], 50, 24)
148
149 class lifeprotips_reddit_renderer(reddit_renderer):
150     def __init__(self, name_to_timeout_dict):
151         super(lifeprotips_reddit_renderer, self).__init__(
152             name_to_timeout_dict, ["lifeprotips"], 100, 24)
153
154 #x = reddit_renderer({"Test", 1234}, ["seattle","bellevue"], 50, 24)
155 #x.periodic_render("Scrape")
156 #x.periodic_render("Shuffle")