Skip to content

Commit

Permalink
feat: Add support for Gateshead Council
Browse files Browse the repository at this point in the history
  • Loading branch information
OliverCullimore committed Oct 20, 2023
1 parent 5146d88 commit 916a0b1
Show file tree
Hide file tree
Showing 5 changed files with 209 additions and 0 deletions.
47 changes: 47 additions & 0 deletions uk_bin_collection/tests/council_schemas/GatesheadCouncil.schema
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"$schema": "http://json-schema.org/draft-06/schema#",
"$ref": "#/definitions/Welcome10",
"definitions": {
"Welcome10": {
"type": "object",
"additionalProperties": false,
"properties": {
"bins": {
"type": "array",
"items": {
"$ref": "#/definitions/Bin"
}
}
},
"required": [
"bins"
],
"title": "Welcome10"
},
"Bin": {
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"$ref": "#/definitions/Type"
},
"collectionDate": {
"type": "string"
}
},
"required": [
"collectionDate",
"type"
],
"title": "Bin"
},
"Type": {
"type": "string",
"enum": [
"Recycling",
"Household Waste"
],
"title": "Type"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Feature: Test each council output matches expected results in /outputs
| EastSuffolkCouncil |
| ErewashBoroughCouncil |
| FenlandDistrictCouncil |
| GatesheadCouncil |
| GlasgowCityCouncil |
| GuildfordCouncil |
| HarrogateBoroughCouncil |
Expand Down
8 changes: 8 additions & 0 deletions uk_bin_collection/tests/input.json
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,14 @@
"url": "https://www.fenland.gov.uk/article/13114/",
"wiki_name": "Fenland District Council"
},
"GatesheadCouncil": {
"SKIP_GET_URL": "SKIP_GET_URL",
"postcode": "NE16 5LQ",
"house_number": "Bracken Cottage",
"url": "https://www.gateshead.gov.uk/",
"wiki_name": "Gateshead Council",
"wiki_note": "Pass the house name/number in the house number parameter, wrapped in double quotes"
},
"GlasgowCityCouncil": {
"url": "https://www.glasgow.gov.uk/forms/refuseandrecyclingcalendar/PrintCalendar.aspx?UPRN=906700034497",
"wiki_name": "Glasgow City Council",
Expand Down
68 changes: 68 additions & 0 deletions uk_bin_collection/tests/outputs/GatesheadCouncil.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{
"bins": [
{
"type": "Recycling",
"collectionDate": "02/01/2023"
},
{
"type": "Household Waste",
"collectionDate": "09/01/2023"
},
{
"type": "Recycling",
"collectionDate": "16/01/2023"
},
{
"type": "Household Waste",
"collectionDate": "23/01/2023"
},
{
"type": "Recycling",
"collectionDate": "30/01/2023"
},
{
"type": "Household Waste",
"collectionDate": "06/02/2023"
},
{
"type": "Recycling",
"collectionDate": "24/10/2023"
},
{
"type": "Household Waste",
"collectionDate": "31/10/2023"
},
{
"type": "Recycling",
"collectionDate": "07/11/2023"
},
{
"type": "Household Waste",
"collectionDate": "14/11/2023"
},
{
"type": "Recycling",
"collectionDate": "21/11/2023"
},
{
"type": "Household Waste",
"collectionDate": "28/11/2023"
},
{
"type": "Recycling",
"collectionDate": "05/12/2023"
},
{
"type": "Household Waste",
"collectionDate": "12/12/2023"
},
{
"type": "Recycling",
"collectionDate": "19/12/2023"
},
{
"type": "Household Waste",
"collectionDate": "27/12/2023"
}
]
}
85 changes: 85 additions & 0 deletions uk_bin_collection/uk_bin_collection/councils/GatesheadCouncil.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

from uk_bin_collection.uk_bin_collection.common import *
from uk_bin_collection.uk_bin_collection.get_bin_data import \
AbstractGetBinDataClass


# import the wonderful Beautiful Soup and the URL grabber
class CouncilClass(AbstractGetBinDataClass):
"""
Concrete classes have to implement all abstract operations of the
base class. They can also override some operations with a default
implementation.
"""

def parse_data(self, page: str, **kwargs) -> dict:
data = {"bins": []}
user_paon = kwargs.get("paon")
user_postcode = kwargs.get("postcode")
check_paon(user_paon)
check_postcode(user_postcode)

# Set up Selenium to run 'headless'
options = webdriver.ChromeOptions()
options.add_argument("--headless")
options.add_argument("--no-sandbox")
options.add_argument("--disable-gpu")
options.add_argument("--disable-dev-shm-usage")
options.add_experimental_option("excludeSwitches", ["enable-logging"])

# Create Selenium webdriver
driver = webdriver.Chrome(options=options)
driver.get("https://www.gateshead.gov.uk/article/3150/Bin-collection-day-checker")

# Wait for the postcode field to appear then populate it
inputElement_postcode = WebDriverWait(driver, 30).until(
EC.presence_of_element_located(
(By.ID, "BINCOLLECTIONCHECKER_ADDRESSSEARCH_ADDRESSLOOKUPPOSTCODE"))
)
inputElement_postcode.send_keys(user_postcode)

# Click search button
findAddress = WebDriverWait(driver, 10).until(
EC.presence_of_element_located(
(By.ID, "BINCOLLECTIONCHECKER_ADDRESSSEARCH_ADDRESSLOOKUPSEARCH"))
)
findAddress.click()

# Wait for the 'Select address' dropdown to appear and select option matching the house name/number
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((
By.XPATH,
"//select[@id='BINCOLLECTIONCHECKER_ADDRESSSEARCH_ADDRESSLOOKUPADDRESS']//option[contains(., '" + user_paon + "')]"
))).click()

# Wait for the collections table to appear
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, ".bincollections__table")))

soup = BeautifulSoup(driver.page_source, features="html.parser")

# Get collections table
table = soup.find("table", {"class": "bincollections__table"})

# Get rows
month_year = ""
for row in table.find_all("tr"):
if row.find("th"):
month_year = row.find("th").get_text(strip=True) + " " + datetime.now().strftime("%Y")
elif month_year != "":
collection = row.find_all("td")
bin_date = datetime.strptime(collection[0].get_text(strip=True) + " " + month_year, "%d %B %Y")
dict_data = {
"type": collection[2].get_text().replace("- DAY CHANGE", "").strip(),
"collectionDate": bin_date.strftime(date_format)
}
data["bins"].append(dict_data)

data["bins"].sort(
key=lambda x: datetime.strptime(x.get("collectionDate"), "%d/%m/%Y")
)

return data

0 comments on commit 916a0b1

Please sign in to comment.