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