diff --git a/README.md b/README.md index bed4763e..cfbb99c9 100644 --- a/README.md +++ b/README.md @@ -190,7 +190,9 @@ Currently the following service providers are supported: ### United Kingdom +- [Bracknell Forest Council - bracknell-forest.gov.uk](./doc/source/bracknell_forest_gov_uk.md) - [Bradford Metropolitan District Council - bradford.gov.uk](./doc/source/bradford_gov_uk.md) +- [Braintree District Council - bracknell-forest.gov.uk](./doc/source/braintree_gov_uk.md) - [Cambridge City Council - cambridge.gov.uk](./doc/source/cambridge_gov_uk.md) - [Canterbury City Council - canterbury.gov.uk](./doc/source/canterbury_gov_uk.md) - [Cheshire East Council - cheshireeast.gov.uk](./doc/source/cheshire_east_gov_uk.md) diff --git a/custom_components/waste_collection_schedule/waste_collection_schedule/source/bracknell_forest_gov_uk.py b/custom_components/waste_collection_schedule/waste_collection_schedule/source/bracknell_forest_gov_uk.py new file mode 100644 index 00000000..720bf7ac --- /dev/null +++ b/custom_components/waste_collection_schedule/waste_collection_schedule/source/bracknell_forest_gov_uk.py @@ -0,0 +1,87 @@ +import json + +import requests +from dateutil import parser +from waste_collection_schedule import Collection + +TITLE = "bracknell-forest.gov.uk" +DESCRIPTION = "Bracknell Forest Council, UK - Waste Collection" +URL = "https://selfservice.mybfc.bracknell-forest.gov.uk" +TEST_CASES = { + "44 Kennel Lane": {"house_number": "44", "post_code": "RG42 2HB"}, + "28 Kennel Lane": {"house_number": "28", "post_code": "RG42 2HB"}, + "32 Ashbourne": {"house_number": "32", "post_code": "RG12 8SG"}, + "1 Acacia Avenue": {"house_number": "1", "post_code": "GU47 0RU"}, +} +ICONS = { + "General Waste": "mdi:trash-can", + "Recycling": "mdi:recycle", + "Garden": "mdi:leaf", + "Food": "mdi:food-apple", +} + + +class Source: + def __init__(self, post_code: str, house_number: str): + self.params = { + "webpage_subpage_id": "PAG0000570FEFFB1", + "webpage_token": "390170046582b0e3d7ca68ef1d6b4829ccff0b1ae9c531047219c6f9b5295738", + "widget_action": "handle_event", + } + self.headers = { + "Accept": "application/json", + "X-Requested-With": "XMLHttpRequest", + } + self.data = { + "action_cell_id": "PCL0003988FEFFB1", + "action_page_id": "PAG0000570FEFFB1", + } + self.url = f"{URL}/w/webpage/waste-collection-days" + self.post_code = post_code + self.house_number = house_number + + def fetch(self): + address_lookup = requests.post( + self.url, + params=self.params, + headers=self.headers, + data={ + "code_action": "find_addresses", + "code_params": json.dumps({"search": self.post_code}), + } + | self.data, + ) + address_lookup.raise_for_status() + addresses = address_lookup.json()["response"]["addresses"]["items"] + id = next(address for address in addresses if address["Description"].startswith(f"{self.house_number} "))["Id"] + + collection_lookup = requests.post( + self.url, + params=self.params, + headers=self.headers, + data={ + "code_action": "find_rounds", + "code_params": json.dumps({"addressId": id}), + } + | self.data, + ) + collection_lookup.raise_for_status() + collections = collection_lookup.json()["response"]["collections"] + entries = [] + for waste_type in ICONS.keys(): + try: + entries.append( + Collection( + date=parser.parse( + next(collection for collection in collections if collection["round"] == waste_type)[ + "firstDate" + ]["date"] + ).date(), + t=waste_type, + icon=ICONS[waste_type], + ) + ) + except (StopIteration, TypeError): + pass + + return entries diff --git a/custom_components/waste_collection_schedule/waste_collection_schedule/source/braintree_gov_uk.py b/custom_components/waste_collection_schedule/waste_collection_schedule/source/braintree_gov_uk.py new file mode 100644 index 00000000..b76826c9 --- /dev/null +++ b/custom_components/waste_collection_schedule/waste_collection_schedule/source/braintree_gov_uk.py @@ -0,0 +1,59 @@ +import requests +from bs4 import BeautifulSoup +from dateutil import parser +from waste_collection_schedule import Collection + +TITLE = "braintree.gov.uk" +DESCRIPTION = "Braintree District Council, UK - Waste Collection" +URL = "https://www.braintree.gov.uk" +TEST_CASES = { + "30 Boars Tye Road": {"house_number": "30", "post_code": "CM8 3QE"}, + "64 Silver Street": {"house_number": "64", "post_code": "CM8 3QG"}, + "18 St Mary's Road": {"house_number": "1", "post_code": "CM8 3PE"}, + "20 Peel Crescent": {"house_number": "20", "post_code": "CM7 2RS"}, +} + +ICONS = { + "Grey Bin": "mdi:trash-can", + "Clear Sack": "mdi:recycle", + "Green Bin": "mdi:leaf", + "Food Bin": "mdi:food-apple", +} + + +class Source: + def __init__(self, post_code: str, house_number: str): + self.post_code = post_code + self.house_number = house_number + self.url = f"{URL}/xfp/form/554" + self.form_data = { + "qe15dda0155d237d1ea161004d1839e3369ed4831_0_0": (None, post_code), + "page": (None, 5730), + } + + def fetch(self): + address_lookup = requests.post("https://www.braintree.gov.uk/xfp/form/554", files=self.form_data) + address_lookup.raise_for_status() + addresses = {} + for address in BeautifulSoup(address_lookup.text, "html.parser").find_all('option'): + if len(address['value']) == 12: + addresses[address['value']] = address.text.strip() + id = next(address for address in addresses if addresses[address].startswith(self.house_number)) + self.form_data["qe15dda0155d237d1ea161004d1839e3369ed4831_1_0"] = (None, id) + self.form_data["next"] = (None, "Next") + collection_lookup = requests.post("https://www.braintree.gov.uk/xfp/form/554", files=self.form_data) + collection_lookup.raise_for_status() + entries = [] + for results in BeautifulSoup(collection_lookup.text, "html.parser").find_all('div', class_="date_display"): + try: + collection_type, collection_date = results.text.strip().split("\n") + entries.append( + Collection( + date=parser.parse(collection_date).date(), + t=collection_type, + icon=ICONS[collection_type] + ) + ) + except (StopIteration, TypeError): + pass + return entries diff --git a/doc/source/bracknell_forest_gov_uk.md b/doc/source/bracknell_forest_gov_uk.md new file mode 100644 index 00000000..49ab4142 --- /dev/null +++ b/doc/source/bracknell_forest_gov_uk.md @@ -0,0 +1,33 @@ +# Bracknell Forest Council + +Support for schedules provided by [Bracknell Forest Council](https://selfservice.mybfc.bracknell-forest.gov.uk/w/webpage/waste-collection-days), serving Bracknell Forest, UK. + +## Configuration via configuration.yaml + +```yaml +waste_collection_schedule: + sources: + - name: bracknell_forest_gov_uk + args: + post_code: Post Code + house_number: House Number +``` + +### Configuration Variables + +**post_code**
+*(string) (required)* + +**house_number**
+*(string) (required)* + +## Example + +```yaml +waste_collection_schedule: + sources: + - name: bracknell_forest_gov_uk + args: + post_code: "RG42 2HB" + house_number: "44" +``` diff --git a/doc/source/braintree_gov_uk.md b/doc/source/braintree_gov_uk.md new file mode 100644 index 00000000..7854e6de --- /dev/null +++ b/doc/source/braintree_gov_uk.md @@ -0,0 +1,33 @@ +# Bracknell Forest Council + +Support for schedules provided by [Braintree District Council](https://www.braintree.gov.uk/xfp/form/554), serving Braintree, UK. + +## Configuration via configuration.yaml + +```yaml +waste_collection_schedule: + sources: + - name: braintree_gov_uk + args: + post_code: Post Code + house_number: House Number +``` + +### Configuration Variables + +**post_code**
+*(string) (required)* + +**house_number**
+*(string) (required)* + +## Example + +```yaml +waste_collection_schedule: + sources: + - name: braintree_gov_uk + args: + post_code: "CM8 3QE" + house_number: "30" +``` diff --git a/info.md b/info.md index 0c67d925..14bd1295 100644 --- a/info.md +++ b/info.md @@ -175,7 +175,9 @@ Currently the following service providers are supported: ### United Kingdom +- [Bracknell Forest Council - bracknell-forest.gov.uk](https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/bracknell_forest_gov_uk.md) - [Bradford Metropolitan District Council - bradford.gov.uk](https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/bradford_gov_uk.md) +- [Braintree District Council - bracknell-forest.gov.uk](https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/braintree_gov_uk.md) - [Cambridge City Council - cambridge.gov.uk](https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/cambridge_gov_uk.md) - [Canterbury City Council - canterbury.gov.uk](https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/canterbury_gov_uk.md) - [Cheshire East Council - cheshireeast.gov.uk](https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/cheshire_east_gov_uk.md)