-from bs4 import BeautifulSoup
+#!/usr/bin/env python3
+
import datetime
+import http.client
+import logging
+import re
+from typing import Dict
+
+from bs4 import BeautifulSoup # type: ignore
+
import file_writer
import grab_bag
-import httplib
import page_builder
import profanity_filter
-import random
-import re
import renderer
-import sets
-class stranger_events_renderer(renderer.debuggable_abstaining_renderer):
- def __init__(self, name_to_timeout_dict):
- super(stranger_events_renderer, self).__init__(name_to_timeout_dict, True)
- self.feed_site = "everout.thestranger.com"
+
+logger = logging.getLogger(__file__)
+
+
+class stranger_events_renderer(renderer.abstaining_renderer):
+ def __init__(self, name_to_timeout_dict: Dict[str, int]):
+ super().__init__(name_to_timeout_dict)
+ self.feed_site = "everout.com"
self.events = grab_bag.grab_bag()
+ self.pfilter = profanity_filter.ProfanityFilter()
- def debug_prefix(self):
+ def debug_prefix(self) -> str:
return "stranger"
- def periodic_render(self, key):
- self.debug_print("called for action %s" % key)
+ def periodic_render(self, key: str) -> bool:
+ logger.debug("called for action %s" % key)
if key == "Fetch Events":
return self.fetch_events()
elif key == "Shuffle Events":
return self.shuffle_events()
else:
- raise error("Unknown operaiton")
+ raise Exception("Unknown operaiton")
def get_style(self):
return """
}
</STYLE>"""
- def shuffle_events(self):
+ def shuffle_events(self) -> bool:
layout = page_builder.page_builder()
layout.set_layout(page_builder.page_builder.LAYOUT_FOUR_ITEMS)
layout.set_title("Stranger Events")
layout.set_style(self.get_style())
subset = self.events.subset(4)
if subset is None:
- self.debug_print("Not enough events to build page.")
+ logger.debug("Not enough events to build page.")
return False
for msg in subset:
layout.add_item(msg)
- f = file_writer.file_writer('stranger-events_2_none.html')
- layout.render_html(f)
- f.close()
+ with file_writer.file_writer("stranger-events_2_36000.html") as f:
+ layout.render_html(f)
return True
- def fetch_events(self):
+ def fetch_events(self) -> bool:
self.events.clear()
- feed_uris = [
- "/events/?page=1&picks=true",
- "/events/?page=2&picks=true",
- "/events/?page=3&picks=true",
- ]
+ feed_uris = []
now = datetime.datetime.now()
ts = now + datetime.timedelta(1)
tomorrow = datetime.datetime.strftime(ts, "%Y-%m-%d")
- feed_uris.append("/events/?start-date=%s&picks=true" % tomorrow)
+ feed_uris.append(f"/seattle/events/?start-date={tomorrow}")
delta = 5 - now.weekday()
if delta <= 0:
delta += 7
if delta > 1:
ts = now + datetime.timedelta(delta)
next_sat = datetime.datetime.strftime(ts, "%Y-%m-%d")
- feed_uris.append("/events/?start-date=%s&page=1&picks=true" % next_sat)
- feed_uris.append("/events/?start-date=%s&page=2&picks=true" % next_sat)
+ feed_uris.append(f"/seattle/events/?start-date={next_sat}&page=1")
+ feed_uris.append(f"/seattle/events/?start-date={next_sat}&page=2")
delta += 1
if delta > 1:
ts = now + datetime.timedelta(delta)
next_sun = datetime.datetime.strftime(ts, "%Y-%m-%d")
- feed_uris.append("/events/?start-date=%s&page=1&picks=true" % next_sun)
- feed_uris.append("/events/?start-date=%s&page=2&picks=true" % next_sun)
+ feed_uris.append(f"/seattle/events/?start-date={next_sun}&page=1")
+ feed_uris.append(f"/seattle/events/?start-date={next_sun}&page=2")
for uri in feed_uris:
- self.debug_print("fetching '%s'" % uri)
- self.conn = httplib.HTTPSConnection(self.feed_site)
- self.conn.request(
- "GET",
- uri,
- None,
- {"Accept-Charset": "utf-8"})
- response = self.conn.getresponse()
- if response.status != 200:
- print("stranger: Failed, status %d" % (response.status))
+ try:
+ logger.debug("fetching 'https://%s%s'" % (self.feed_site, uri))
+ self.conn = http.client.HTTPSConnection(self.feed_site)
+ self.conn.request("GET", uri, None, {"Accept-Charset": "utf-8"})
+ response = self.conn.getresponse()
+ if response.status != 200:
+ logger.debug("Connection failed, status %d" % (response.status))
+ logger.debug(str(response.getheaders()))
+ continue
+ raw = response.read()
+ except Exception:
+ logger.debug("Exception talking to the stranger, ignoring.")
continue
- raw = response.read()
soup = BeautifulSoup(raw, "html.parser")
- filter = profanity_filter.profanity_filter()
- for x in soup.find_all('div', class_='row event list-item mb-3 py-3'):
- text = x.get_text();
- if (filter.contains_bad_words(text)):
+ for x in soup.find_all("div", class_="row event list-item mb-3 py-3"):
+ text = x.get_text()
+ if self.pfilter.contains_bad_word(text):
continue
-
-# <div class="row event list-item mb-3 py-3">
-# <div class="col-12">
-# <a class="category-tag" href="?category=on-demand">On Demand</a>
-# </div> // col-12
-# <div class="col-md-3 order-1 order-md-3">
-# <a href="https://everout.thestranger.com/events/spliff-2020-on-demand/e24125/">
-# <img class="img-responsive" src="https://d2i729k8wyri5w.cloudfront.net/eyJidWNrZXQiOiAiZXZlcm91dC1pbWFnZXMtcHJvZHVjdGlvbiIsICJrZXkiOiAiaW1hZ2UtMTU5MTA2NTQxODU5NzA5My1vcmlnaW5hbC1sb2dvLmpwZWciLCAiZWRpdHMiOiB7InJlc2l6ZSI6IHsiZml0IjogImNvdmVyIiwgIndpZHRoIjogNDAwLCAiaGVpZ2h0IjogMzAwfX19">
-# </a>
-# </div> // col-md-3 order-1 order-md-3
-# <div class="col-md-6 order-2 order-md-1 event-details">
-# <h3 class="mb-0 event-title">
-# <a href="https://everout.thestranger.com/events/spliff-2020-on-demand/e24125/"><span class="staff-pick fas fa-star" aria-hidden="true"></span></a>
-# <a href="https://everout.thestranger.com/events/spliff-2020-on-demand/e24125/">
-# <span class="title-link">SPLIFF 2020 - On Demand</span>
-# </a>
-# </h3>
-# <div class="event-date">
-# Every day
-# </div> // event-date
-# <div class="event-time">
-# </div> // event-time
-# </div> // col-md-6 order-2 order-md-1 event-details
-# <div class="col-md-3 order-3 order-md-2 location-column">
-# <div class="location-name">
-# <i class="fad fa-map-marker-alt"></i> <a href="https://everout.thestranger.com/locations/the-stranger-online/l27660/">The Stranger (Online)</a>
-# </div> // location-name
-# <div class="location-region">
-# </div> // location-region
-# <ul class="event-tags">
-# <li>$10 - $20</li>
-# </ul>
-# </div> // col-md-3 order-3 order-md-2 location-colum
-# </div> // row event list-item mb-3 py-3
-
- raw = unicode(x)
- raw = raw.replace('src="/',
- 'align="left" src="https://www.thestranger.com/')
- raw = raw.replace('href="/',
- 'href="https://www.thestranger.com/')
- raw = raw.replace('FREE', 'Free')
- raw = raw.replace('Save Event', '')
- raw = re.sub('^\s*$', '', raw, 0, re.MULTILINE)
- raw = re.sub('\n+', '\n', raw)
- raw = re.sub('<span[^<>]*class="calendar-post-ticket"[^<>]*>.*</#span>', '', raw, 0, re.DOTALL | re.IGNORECASE)
- self.events.add(raw.encode('utf-8'))
- self.debug_print("fetched %d events so far." % self.events.size())
+ raw_str = str(x)
+ raw_str = raw_str.replace(
+ 'src="/', 'align="left" src="https://www.thestranger.com/'
+ )
+ raw_str = raw_str.replace('href="/', 'href="https://www.thestranger.com/')
+ raw_str = raw_str.replace("FREE", "Free")
+ raw_str = raw_str.replace("Save Event", "")
+ raw_str = re.sub("^\s*$", "", raw_str, 0, re.MULTILINE)
+ raw_str = re.sub(
+ '<span[^<>]*class="calendar-post-ticket"[^<>]*>.*</#span>',
+ "",
+ raw_str,
+ 0,
+ re.DOTALL | re.IGNORECASE,
+ )
+ self.events.add(raw_str)
+ logger.debug(f"fetched {self.events.size()} events so far.")
return self.events.size() > 0
-x = stranger_events_renderer({"Test", 123})
-x.periodic_render("Fetch Events")
-x.periodic_render("Shuffle Events")
+
+# Test
+#x = stranger_events_renderer({"Test", 123})
+#x.periodic_render("Fetch Events")
+#x.periodic_render("Shuffle Events")