Skip to content

Commit

Permalink
Merge pull request #674 from dp247/366-west-berkshire-council
Browse files Browse the repository at this point in the history
Add support for West Berkshire Council
  • Loading branch information
robbrad authored Apr 27, 2024
2 parents a7dbdaf + f186973 commit 0088ae4
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,11 @@ Feature: Test each council output matches expected results
| council | selenium_url | selenium_mode |
| WelhatCouncil | None | None |

@WestBerkshireCouncil
Examples: WestBerkshireCouncil
| council | selenium_url | selenium_mode |
| WestBerkshireCouncil | http://selenium:4444 | local |

@WestLindseyDistrictCouncil
Examples: WestLindseyDistrictCouncil
| council | selenium_url | selenium_mode |
Expand Down
9 changes: 9 additions & 0 deletions uk_bin_collection/tests/input.json
Original file line number Diff line number Diff line change
Expand Up @@ -971,6 +971,15 @@
"url": "https://www.welhat.gov.uk/xfp/form/214",
"wiki_name": "Welhat Council"
},
"WestBerkshireCouncil": {
"house_number": "8",
"postcode": "RG14 7DP",
"skip_get_url": true,
"url": "https://www.westberks.gov.uk/binday",
"web_driver": "http://selenium:4444",
"wiki_name": "West Berkshire Council",
"wiki_note": "Pass the house name/number in the house number parameter, wrapped in double quotes and the postcode in the postcode parameter"
},
"WestLindseyDistrictCouncil": {
"house_number": "PRIVATE ACCOMODATION",
"postcode": "LN8 2AR",
Expand Down
113 changes: 113 additions & 0 deletions uk_bin_collection/uk_bin_collection/councils/WestBerkshireCouncil.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import time

from bs4 import BeautifulSoup
from dateutil.relativedelta import relativedelta
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import Select
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:
driver = None
try:
data = {"bins": []}
collections = []
user_paon = kwargs.get("paon")
user_postcode = kwargs.get("postcode")
web_driver = kwargs.get("web_driver")
headless = kwargs.get("headless")
check_paon(user_paon)
check_postcode(user_postcode)

# Create Selenium webdriver
# driver = create_webdriver(web_driver, headless)
driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()))
driver.get(
"https://www.westberks.gov.uk/binday"
)

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

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

WebDriverWait(driver, 10).until(
EC.element_to_be_clickable(
(
By.XPATH,
""
"//*[@id='FINDYOURBINDAYS_ADDRESSLOOKUPADDRESS']//option[contains(., '"
+ user_paon
+ "')]",
)
)
).click()

# Wait for the submit button to appear, then click it to get the collection dates
WebDriverWait(driver, 30).until(
EC.presence_of_element_located(
(By.XPATH, '//*[@id="FINDYOURBINDAYS_RUBBISHDATE"]/div')
)
)
time.sleep(2)

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

rubbish_date = datetime.strptime(' '.join(soup.find("div", {"id": "FINDYOURBINDAYS_RUBBISHDATE_OUTERDIV"}).get_text(strip=True).split()[6:8]), "%d %B").replace(year=datetime.now().year)
recycling_date = datetime.strptime(' '.join(soup.find("div", {"id": "FINDYOURBINDAYS_RECYCLINGDATE_OUTERDIV"}).get_text(strip=True).split()[6:8]), "%d %B").replace(year=datetime.now().year)
food_date = datetime.strptime(' '.join(soup.find("div", {"id": "FINDYOURBINDAYS_FOODWASTEDATE_OUTERDIV"}).get_text(strip=True).split()[8:10]), "%d %B").replace(year=datetime.now().year)

if datetime.now().month == 12 and rubbish_date.month == 1:
rubbish_date = rubbish_date + relativedelta(years=1)
if datetime.now().month == 12 and recycling_date.month == 1:
recycling_date = recycling_date + relativedelta(years=1)
if datetime.now().month == 12 and food_date.month == 1:
food_date = food_date + relativedelta(years=1)

collections.append(("Rubbish bin", rubbish_date))
collections.append(("Recycling bin", recycling_date))
collections.append(("Food waste bin", food_date))

ordered_data = sorted(collections, key=lambda x: x[1])
for item in ordered_data:
dict_data = {
"type": item[0].capitalize(),
"collectionDate": item[1].strftime(date_format),
}
data["bins"].append(dict_data)

print()
except Exception as e:
# Here you can log the exception if needed
print(f"An error occurred: {e}")
# Optionally, re-raise the exception if you want it to propagate
raise
finally:
# This block ensures that the driver is closed regardless of an exception
if driver:
driver.quit()
return data

0 comments on commit 0088ae4

Please sign in to comment.