7 from typing import Dict
9 from bs4 import BeautifulSoup # type: ignore
10 from pyutilz import profanity_filter
18 logger = logging.getLogger(__file__)
21 class stranger_events_renderer(renderer.abstaining_renderer):
22 def __init__(self, name_to_timeout_dict: Dict[str, int]):
23 super().__init__(name_to_timeout_dict)
24 self.feed_site = "everout.com"
25 self.events = grab_bag.grab_bag()
26 self.pfilter = profanity_filter.ProfanityFilter()
28 def debug_prefix(self) -> str:
31 def periodic_render(self, key: str) -> bool:
32 logger.debug("called for action %s" % key)
33 if key == "Fetch Events":
34 return self.fetch_events()
35 elif key == "Shuffle Events":
36 return self.shuffle_events()
38 raise Exception("Unknown operaiton")
46 .calendar-post-title a {
47 text-decoration: none;
54 .calendar-post-category {
56 .calendar-post-location {
58 .calendar-post-price {
60 .calendar-touch-link {
63 background-color:lightyellow;
69 .calendar-post-price-mobile {
74 margin: 10px 10px 10px 10px;
78 def shuffle_events(self) -> bool:
79 layout = page_builder.page_builder()
80 layout.set_layout(page_builder.page_builder.LAYOUT_FOUR_ITEMS)
81 layout.set_title("Stranger Events")
82 layout.set_style(self.get_style())
83 subset = self.events.subset(4)
85 logger.debug("Not enough events to build page.")
90 with file_writer.file_writer("stranger-events_2_36000.html") as f:
94 def fetch_events(self) -> bool:
97 now = datetime.datetime.now()
98 ts = now + datetime.timedelta(1)
99 tomorrow = datetime.datetime.strftime(ts, "%Y-%m-%d")
100 feed_uris.append(f"/seattle/events/?start-date={tomorrow}")
101 delta = 5 - now.weekday()
105 ts = now + datetime.timedelta(delta)
106 next_sat = datetime.datetime.strftime(ts, "%Y-%m-%d")
107 feed_uris.append(f"/seattle/events/?start-date={next_sat}&page=1")
108 feed_uris.append(f"/seattle/events/?start-date={next_sat}&page=2")
111 ts = now + datetime.timedelta(delta)
112 next_sun = datetime.datetime.strftime(ts, "%Y-%m-%d")
113 feed_uris.append(f"/seattle/events/?start-date={next_sun}&page=1")
114 feed_uris.append(f"/seattle/events/?start-date={next_sun}&page=2")
116 for uri in feed_uris:
118 logger.debug("fetching 'https://%s%s'" % (self.feed_site, uri))
119 self.conn = http.client.HTTPSConnection(self.feed_site)
120 self.conn.request("GET", uri, None, {"Accept-Charset": "utf-8"})
121 response = self.conn.getresponse()
122 if response.status != 200:
123 logger.debug("Connection failed, status %d" % (response.status))
124 logger.debug(str(response.getheaders()))
126 raw = response.read()
128 logger.debug("Exception talking to the stranger, ignoring.")
131 soup = BeautifulSoup(raw, "html.parser")
132 for x in soup.find_all("div", class_="row event list-item mb-3 py-3"):
134 if self.pfilter.contains_bad_word(text):
137 raw_str = raw_str.replace(
138 'src="/', 'align="left" src="https://www.thestranger.com/'
140 raw_str = raw_str.replace('href="/', 'href="https://www.thestranger.com/')
141 raw_str = raw_str.replace("FREE", "Free")
142 raw_str = raw_str.replace("Save Event", "")
143 raw_str = re.sub("^\s*$", "", raw_str, 0, re.MULTILINE)
145 '<span[^<>]*class="calendar-post-ticket"[^<>]*>.*</#span>',
149 re.DOTALL | re.IGNORECASE,
151 self.events.add(raw_str)
152 logger.debug(f"fetched {self.events.size()} events so far.")
153 return self.events.size() > 0
157 x = stranger_events_renderer({"Test", 123})
158 x.periodic_render("Fetch Events")
159 x.periodic_render("Shuffle Events")