diff --git a/city_scrapers/spiders/chi_ssa_23.py b/city_scrapers/spiders/chi_ssa_23.py
deleted file mode 100644
index 5fcbad89b..000000000
--- a/city_scrapers/spiders/chi_ssa_23.py
+++ /dev/null
@@ -1,162 +0,0 @@
-import re
-import unicodedata
-from datetime import datetime, timedelta
-
-from city_scrapers_core.constants import COMMISSION
-from city_scrapers_core.items import Meeting
-from city_scrapers_core.spiders import CityScrapersSpider
-
-
-class ChiSsa23Spider(CityScrapersSpider):
- name = "chi_ssa_23"
- agency = "Chicago Special Service Area #23 Clark Street"
- timezone = "America/Chicago"
- start_urls = ["https://www.lincolnparkchamber.com/clark-street-ssa-administration/"]
- location = {
- "name": "Lincoln Park Chamber of Commerce",
- "address": "2468 N. Lincoln Chicago, IL 60614",
- }
- # Each meeting takes place on Wednesday 4 PM
- meeting_day = "Wednesday"
- time = "4:00 pm"
-
- def parse(self, response):
- address_text = response.xpath('//div[@class = "address"][1]/text()').extract()[
- 1
- ]
- self._validate_location(address_text)
-
- h4s = response.xpath("//h4")
-
- # General meeting description is mentioned just after the H4 for current year
- general_desc = h4s.xpath("following-sibling::p[1]//em//text()").extract_first()
-
- # Dictionary containing all meeting dictionaries
- # The dates will be the keys
- meetings = dict()
-
- last_year = datetime.today().replace(year=datetime.today().year - 1)
-
- for entry_cnt, entry in enumerate(h4s, start=1):
- entry_str = entry.xpath("./text()").extract_first()
- test_year = entry_str[0:4]
-
- if "Schedule" in entry_str:
- for item in entry.xpath(
- "following-sibling::ol[1]//li//text()"
- ).getall():
- date, start, end = self._parse_date_start_end(item, test_year)
-
- meetings[date] = {
- "start": start,
- "end": end,
- # Scheduled appointments have no links
- "links": [],
- }
-
- elif "Agendas" in entry_str or "Minutes" in entry_str:
- # Only consider ps between two h4s
- for p in entry.xpath(
- "following-sibling::p[count(preceding-sibling::h4)=" "$entry_cnt]",
- entry_cnt=entry_cnt,
- ):
- # The non-breaking space signals the end of the meeting lists
- if (
- p.xpath("./text()")
- and "\xa0" in p.xpath("./text()").extract_first()
- ):
- break
-
- for item in p.xpath("./a"):
- item_str = item.xpath("./text()").extract_first()
- date, start, end = self._parse_date_start_end(
- item_str, test_year
- )
-
- item_links = item.xpath("@href").extract()
- links = self._parse_links(item_links, entry_str)
-
- if date in meetings:
- meetings[date]["links"].extend(links)
-
- else:
- meetings[date] = {
- "start": start,
- "end": end,
- "links": links,
- }
-
- # Create the meeting objects
- for key, item in meetings.items():
- if item["start"] < last_year and not self.settings.getbool(
- "CITY_SCRAPERS_ARCHIVE"
- ):
- continue
-
- meeting = Meeting(
- title="Commission",
- description=unicodedata.normalize("NFKD", general_desc),
- classification=COMMISSION,
- start=item["start"],
- end=item["end"],
- time_notes="Estimated 90 minutes duration",
- all_day=False,
- location=self.location,
- links=item["links"],
- source=response.url,
- )
-
- meeting["status"] = self._get_status(meeting)
- meeting["id"] = self._get_id(meeting)
- yield meeting
-
- def _parse_date_start_end(self, item, year):
- """
- Parse start date and time.
- """
- # Check for explicit start times in the string
- try:
- start_time = re.search(r"\((.*?)\)", item).group(1)
-
- except AttributeError:
- start_time = self.time
-
- # Split the month day string and make sure to drop the year before that
- dm_str = item.split(",")[0].split()
-
- # Adding a 0 as padding for single-digit days
- if len(dm_str[1]) < 2:
- dm_str[1] = "0" + dm_str[1]
- dt_str = dm_str[0] + " " + dm_str[1]
-
- start = datetime.strptime(
- "{} {} {} {}".format(
- self.meeting_day, re.sub(r"[,\.]", "", dt_str), start_time, year
- ),
- "%A %B %d %I:%M %p %Y",
- )
- date = start.date()
- end = start + timedelta(minutes=90)
-
- return date, start, end
-
- def _parse_links(self, items, entry_str):
- documents = []
- for url in items:
- if url:
- documents.append(self._build_link_dict(url, entry_str))
-
- return documents
-
- def _build_link_dict(self, url, entry_str):
- if "agenda" in entry_str.lower():
- return {"href": url, "title": "Agenda"}
- elif "minutes" in entry_str.lower():
- return {"href": url, "title": "Minutes"}
- else:
- return {"href": url, "title": "Link"}
-
- def _validate_location(self, text):
- """Parse or generate location."""
- if "2468" not in text:
- raise ValueError("Meeting location has changed")
diff --git a/tests/files/chi_ssa_23.html b/tests/files/chi_ssa_23.html
deleted file mode 100644
index 81870e1d5..000000000
--- a/tests/files/chi_ssa_23.html
+++ /dev/null
@@ -1,640 +0,0 @@
-
-
-
-
-
-
- Clark Street SSA Administration - Lincoln Park Chamber of Commerce
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Clark Street SSA Administration
-
-
-
-
-
-
-
-
-
-
-
2020 Clark Street SSA Commission Meeting Schedule
-
All meetings held Wednesdays at 4:00 p.m. Meetings typically run 90 minutes. Please contact the LPCC to confirm meeting locations (773) 880-5200.
-
-- February 5
-- March 24 (9:37 am)
-- April 3 (10:30 am)
-- April 22
-- May 27
-- July 8
-- September 9
-- November 18
-
-
2020 Clark Street SSA Commission Meeting Agendas
-
February 5, 2020
-
March 24, 2020
-
April 3, 2020
-
April 22, 2020
-
2020 Clark Street SSA Commission Meeting Minutes
-
February 5, 2020
-
March 24, 2020
-
April 3, 2020
-
2019 Clark Street SSA Commission Meeting Agendas
-
January 23
-April 24
-May 15
-July 10
-September 4
-November 13
-
2019 Clark Street SSA Commission Meeting Minutes
-
January 23
-April 24
-May 15
-July 10
-September 4
-November 13
-
-
2018 Clark Street SSA Commission Meeting Agendas
-
February 7, 2018
-April 18, 2018
-May 23, 2018
-July 11, 2018
-September 5, 2018
-November 14, 2018
-
-
2018 Clark Street SSA Commission Meeting Minutes
-
February 7, 2018
-April 18, 2018
-May 23, 2018
-July 11, 2018
-September 5, 2018
-November 14, 2018
-
-
2017 Clark Street SSA Commission Meeting Agendas
-
September 27, 2017
-July 12, 2017
-May 24, 2017
-April 12, 2017
-January 25, 2017
-
-
2017 Clark Street SSA Commission Meeting Minutes
-
July 12, 2017
-May 24, 2017
-April 12, 2017
-January 25, 2017
-
-
2016 Clark Street SSA Commission Meeting Minutes
-
November 16, 2016
-September 21, 2016
-July 13, 2016
-April 20, 2017
-January 27, 2016
-
-
To view the 2019 Clark Street Special Service Area #23 Service Provider Agreement, click here.
-
-
-
-
-
Current Request for Proposals
-
The Lincoln Park Chamber of Commerce is not currently accepting bids for services.
-
-
-
-
-
Clark Street SSA #23 Service Area Boundaries
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/tests/test_chi_ssa_23.py b/tests/test_chi_ssa_23.py
deleted file mode 100644
index 7d855948e..000000000
--- a/tests/test_chi_ssa_23.py
+++ /dev/null
@@ -1,152 +0,0 @@
-from datetime import datetime
-from os.path import dirname, join
-
-import pytest
-from city_scrapers_core.constants import COMMISSION, PASSED, TENTATIVE
-from city_scrapers_core.utils import file_response
-from freezegun import freeze_time
-from scrapy.settings import Settings
-
-from city_scrapers.spiders.chi_ssa_23 import ChiSsa23Spider
-
-test_response = file_response(
- join(dirname(__file__), "files", "chi_ssa_23.html"),
- url="https://www.lincolnparkchamber.com/clark-street-ssa-administration/",
-)
-
-spider = ChiSsa23Spider()
-spider.settings = Settings(values={"CITY_SCRAPERS_ARCHIVE": False})
-
-freezer = freeze_time("2020-05-11")
-freezer.start()
-
-parsed_items = sorted(
- [item for item in spider.parse(test_response)],
- key=lambda i: i["start"],
- reverse=True,
-)
-
-freezer.stop()
-
-
-def test_count():
- assert len(parsed_items) == 12
-
-
-@pytest.mark.parametrize("item", parsed_items)
-def test_title(item):
- assert item["title"] == "Commission"
-
-
-@pytest.mark.parametrize("item", parsed_items)
-def test_description(item):
- assert (
- item["description"] == "All meetings held Wednesdays at 4:00 p.m. "
- "Meetings typically run 90 minute"
- "s. Please contact the LPCC to confirm meeting "
- "locations (773) 880-5200. "
- )
-
-
-def test_start():
- expected_starts = [
- datetime(2020, 11, 18, 16, 0),
- datetime(2020, 9, 9, 16, 0),
- datetime(2020, 7, 8, 16, 0),
- datetime(2020, 5, 27, 16, 0),
- datetime(2020, 4, 22, 16, 0),
- datetime(2020, 4, 3, 10, 30),
- datetime(2020, 3, 24, 9, 37),
- datetime(2020, 2, 5, 16, 0),
- datetime(2019, 11, 13, 16, 0),
- datetime(2019, 9, 4, 16, 0),
- datetime(2019, 7, 10, 16, 0),
- datetime(2019, 5, 15, 16, 0),
- ]
- for i in range(len(parsed_items)):
- assert parsed_items[i]["start"] == expected_starts[i]
-
-
-def test_end():
- expected_ends = [
- datetime(2020, 11, 18, 17, 30),
- datetime(2020, 9, 9, 17, 30),
- datetime(2020, 7, 8, 17, 30),
- datetime(2020, 5, 27, 17, 30),
- datetime(2020, 4, 22, 17, 30),
- datetime(2020, 4, 3, 12, 00),
- datetime(2020, 3, 24, 11, 7),
- datetime(2020, 2, 5, 17, 30),
- datetime(2019, 11, 13, 17, 30),
- datetime(2019, 9, 4, 17, 30),
- datetime(2019, 7, 10, 17, 30),
- datetime(2019, 5, 15, 17, 30),
- ]
- for i in range(len(parsed_items)):
- assert parsed_items[i]["end"] == expected_ends[i]
-
-
-@pytest.mark.parametrize("item", parsed_items)
-def test_time_notes(item):
- assert item["time_notes"] == "Estimated 90 minutes duration"
-
-
-def test_id():
- expected_ids = [
- "chi_ssa_23/202011181600/x/commission",
- "chi_ssa_23/202009091600/x/commission",
- "chi_ssa_23/202007081600/x/commission",
- "chi_ssa_23/202005271600/x/commission",
- "chi_ssa_23/202004221600/x/commission",
- "chi_ssa_23/202004031030/x/commission",
- "chi_ssa_23/202003240937/x/commission",
- "chi_ssa_23/202002051600/x/commission",
- "chi_ssa_23/201911131600/x/commission",
- "chi_ssa_23/201909041600/x/commission",
- "chi_ssa_23/201907101600/x/commission",
- "chi_ssa_23/201905151600/x/commission",
- ]
- for i in range(len(parsed_items)):
- assert parsed_items[i]["id"] == expected_ids[i]
-
-
-def test_status():
- expected_status = [
- TENTATIVE,
- TENTATIVE,
- TENTATIVE,
- TENTATIVE,
- PASSED,
- PASSED,
- PASSED,
- PASSED,
- PASSED,
- PASSED,
- PASSED,
- PASSED,
- ]
- for i in range(len(parsed_items)):
- assert parsed_items[i]["status"] == expected_status[i]
-
-
-@pytest.mark.parametrize("item", parsed_items)
-def test_location(item):
- assert item["location"] == {
- "name": "Lincoln Park Chamber of Commerce",
- "address": "2468 N. Lincoln Chicago, IL 60614",
- }
-
-
-@pytest.mark.parametrize("item", parsed_items)
-def test_source(item):
- assert item["source"] == test_response.url
-
-
-@pytest.mark.parametrize("item", parsed_items)
-def test_classification(item):
- assert item["classification"] == COMMISSION
-
-
-def test_all_day():
- for i in range(len(parsed_items)):
- assert parsed_items[i]["all_day"] is False