1 from bs4 import BeautifulSoup
7 import profanity_filter
13 class stranger_events_renderer(renderer.debuggable_abstaining_renderer):
14 def __init__(self, name_to_timeout_dict):
15 super(stranger_events_renderer, self).__init__(name_to_timeout_dict, True)
16 self.feed_site = "everout.thestranger.com"
17 self.events = grab_bag.grab_bag()
19 def debug_prefix(self):
22 def periodic_render(self, key):
23 self.debug_print("called for action %s" % key)
24 if key == "Fetch Events":
25 return self.fetch_events()
26 elif key == "Shuffle Events":
27 return self.shuffle_events()
29 raise error("Unknown operaiton")
37 .calendar-post-title a {
38 text-decoration: none;
45 .calendar-post-category {
47 .calendar-post-location {
49 .calendar-post-price {
51 .calendar-touch-link {
54 background-color:lightyellow;
60 .calendar-post-price-mobile {
65 margin: 10px 10px 10px 10px;
69 def shuffle_events(self):
70 layout = page_builder.page_builder()
71 layout.set_layout(page_builder.page_builder.LAYOUT_FOUR_ITEMS)
72 layout.set_title("Stranger Events")
73 layout.set_style(self.get_style())
74 subset = self.events.subset(4)
76 self.debug_print("Not enough events to build page.")
81 f = file_writer.file_writer('stranger-events_2_none.html')
86 def fetch_events(self):
89 "/events/?page=1&picks=true",
90 "/events/?page=2&picks=true",
91 "/events/?page=3&picks=true",
93 now = datetime.datetime.now()
94 ts = now + datetime.timedelta(1)
95 tomorrow = datetime.datetime.strftime(ts, "%Y-%m-%d")
96 feed_uris.append("/events/?start-date=%s&picks=true" % tomorrow)
97 delta = 5 - now.weekday()
101 ts = now + datetime.timedelta(delta)
102 next_sat = datetime.datetime.strftime(ts, "%Y-%m-%d")
103 feed_uris.append("/events/?start-date=%s&page=1&picks=true" % next_sat)
104 feed_uris.append("/events/?start-date=%s&page=2&picks=true" % next_sat)
107 ts = now + datetime.timedelta(delta)
108 next_sun = datetime.datetime.strftime(ts, "%Y-%m-%d")
109 feed_uris.append("/events/?start-date=%s&page=1&picks=true" % next_sun)
110 feed_uris.append("/events/?start-date=%s&page=2&picks=true" % next_sun)
112 for uri in feed_uris:
113 self.debug_print("fetching '%s'" % uri)
114 self.conn = httplib.HTTPSConnection(self.feed_site)
119 {"Accept-Charset": "utf-8"})
120 response = self.conn.getresponse()
121 if response.status != 200:
122 print("stranger: Failed, status %d" % (response.status))
125 raw = response.read()
126 soup = BeautifulSoup(raw, "html.parser")
127 filter = profanity_filter.profanity_filter()
128 for x in soup.find_all('div', class_='row event list-item mb-3 py-3'):
130 if (filter.contains_bad_words(text)):
133 # <div class="row event list-item mb-3 py-3">
134 # <div class="col-12">
135 # <a class="category-tag" href="?category=on-demand">On Demand</a>
137 # <div class="col-md-3 order-1 order-md-3">
138 # <a href="https://everout.thestranger.com/events/spliff-2020-on-demand/e24125/">
139 # <img class="img-responsive" src="https://d2i729k8wyri5w.cloudfront.net/eyJidWNrZXQiOiAiZXZlcm91dC1pbWFnZXMtcHJvZHVjdGlvbiIsICJrZXkiOiAiaW1hZ2UtMTU5MTA2NTQxODU5NzA5My1vcmlnaW5hbC1sb2dvLmpwZWciLCAiZWRpdHMiOiB7InJlc2l6ZSI6IHsiZml0IjogImNvdmVyIiwgIndpZHRoIjogNDAwLCAiaGVpZ2h0IjogMzAwfX19">
141 # </div> // col-md-3 order-1 order-md-3
142 # <div class="col-md-6 order-2 order-md-1 event-details">
143 # <h3 class="mb-0 event-title">
144 # <a href="https://everout.thestranger.com/events/spliff-2020-on-demand/e24125/"><span class="staff-pick fas fa-star" aria-hidden="true"></span></a>
145 # <a href="https://everout.thestranger.com/events/spliff-2020-on-demand/e24125/">
146 # <span class="title-link">SPLIFF 2020 - On Demand</span>
149 # <div class="event-date">
151 # </div> // event-date
152 # <div class="event-time">
153 # </div> // event-time
154 # </div> // col-md-6 order-2 order-md-1 event-details
155 # <div class="col-md-3 order-3 order-md-2 location-column">
156 # <div class="location-name">
157 # <i class="fad fa-map-marker-alt"></i> <a href="https://everout.thestranger.com/locations/the-stranger-online/l27660/">The Stranger (Online)</a>
158 # </div> // location-name
159 # <div class="location-region">
160 # </div> // location-region
161 # <ul class="event-tags">
164 # </div> // col-md-3 order-3 order-md-2 location-colum
165 # </div> // row event list-item mb-3 py-3
168 raw = raw.replace('src="/',
169 'align="left" src="https://www.thestranger.com/')
170 raw = raw.replace('href="/',
171 'href="https://www.thestranger.com/')
172 raw = raw.replace('FREE', 'Free')
173 raw = raw.replace('Save Event', '')
174 raw = re.sub('^\s*$', '', raw, 0, re.MULTILINE)
175 raw = re.sub('\n+', '\n', raw)
176 raw = re.sub('<span[^<>]*class="calendar-post-ticket"[^<>]*>.*</#span>', '', raw, 0, re.DOTALL | re.IGNORECASE)
177 self.events.add(raw.encode('utf-8'))
178 self.debug_print("fetched %d events so far." % self.events.size())
179 return self.events.size() > 0
181 x = stranger_events_renderer({"Test", 123})
182 x.periodic_render("Fetch Events")
183 x.periodic_render("Shuffle Events")