mirror of
https://github.com/sascha-hemi/hacs_waste_collection_schedule.git
synced 2026-03-21 00:04:11 +01:00
Add support for Birmingham City Council (UK), birmingham.gov.uk (#2049)
* Add support for Birmingham City Council (UK), birmingham.gov.uk * Update code logic of `birmingham_gov_uk` to reduce indentation * Update `birmingham_gov_uk` test cases to demonstrate integer UPRN's * Be more resilient to unknown collection types, and still return them, just with an "question mark" icon * reformatting --------- Co-authored-by: 5ila5 <5ila5@users.noreply.github.com>
This commit is contained in:
@@ -1203,6 +1203,7 @@ Waste collection schedules in the following formats and countries are supported.
|
||||
- [BCP Council](/doc/source/bcp_gov_uk.md) / bcpcouncil.gov.uk
|
||||
- [Bedford Borough Council](/doc/source/bedford_gov_uk.md) / bedford.gov.uk
|
||||
- [Binzone](/doc/source/binzone_uk.md) / southoxon.gov.uk
|
||||
- [Birmingham City Council](/doc/source/birmingham_gov_uk.md) / birmingham.gov.uk
|
||||
- [Blackburn with Darwen Borough Council](/doc/source/blackburn_gov_uk.md) / blackburn.gov.uk
|
||||
- [Blackpool Council](/doc/source/blackpool_gov_uk.md) / blackpool.gov.uk
|
||||
- [Borough Council of King's Lynn & West Norfolk](/doc/source/west_norfolk_gov_uk.md) / west-norfolk.gov.uk
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
import re
|
||||
from datetime import datetime
|
||||
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
from dateutil.parser import parse
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from waste_collection_schedule import Collection # type: ignore[attr-defined]
|
||||
|
||||
TITLE = "Birmingham City Council"
|
||||
DESCRIPTION = "Source for birmingham.gov.uk services for Birmingham, UK."
|
||||
URL = "https://birmingham.gov.uk"
|
||||
TEST_CASES = {
|
||||
"Cherry Tree Croft": {"uprn": 100070321799, "postcode": "B27 6TF"},
|
||||
"Ludgate Loft Apartments": {"uprn": 10033389698, "postcode": "B3 1DW"},
|
||||
"Windermere Road": {"uprn": "100070566109", "postcode": "B13 9JP"},
|
||||
"Park Hill": {"uprn": "100070475114", "postcode": "B13 8DS"},
|
||||
}
|
||||
|
||||
HEADERS = {
|
||||
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36",
|
||||
}
|
||||
|
||||
API_URLS = {
|
||||
"get_session": "https://www.birmingham.gov.uk/xfp/form/619",
|
||||
"collection": "https://www.birmingham.gov.uk/xfp/form/619",
|
||||
}
|
||||
ICON_MAP = {
|
||||
"Household Collection": "mdi:trash-can",
|
||||
"Recycling Collection": "mdi:recycle",
|
||||
"Green Recycling Chargeable Collections": "mdi:leaf",
|
||||
}
|
||||
|
||||
|
||||
class Source:
|
||||
def __init__(self, uprn: str, postcode: str):
|
||||
self._uprn = uprn
|
||||
self._postcode = postcode
|
||||
|
||||
def fetch(self):
|
||||
entries: list[Collection] = []
|
||||
|
||||
session = requests.Session()
|
||||
session.headers.update(HEADERS)
|
||||
|
||||
token_response = session.get(API_URLS["get_session"])
|
||||
soup = BeautifulSoup(token_response.text, "html.parser")
|
||||
token = soup.find("input", {"name": "__token"}).attrs["value"]
|
||||
if not token:
|
||||
raise ValueError(
|
||||
"Could not parse CSRF Token from initial response. Won't be able to proceed."
|
||||
)
|
||||
|
||||
form_data = {
|
||||
"__token": token,
|
||||
"page": "491",
|
||||
"locale": "en_GB",
|
||||
"q1f8ccce1d1e2f58649b4069712be6879a839233f_0_0": self._postcode,
|
||||
"q1f8ccce1d1e2f58649b4069712be6879a839233f_1_0": self._uprn,
|
||||
"next": "Next",
|
||||
}
|
||||
|
||||
collection_response = session.post(API_URLS["collection"], data=form_data)
|
||||
|
||||
collection_soup = BeautifulSoup(collection_response.text, "html.parser")
|
||||
|
||||
for table_row in collection_soup.find(
|
||||
"table", class_="data-table"
|
||||
).tbody.find_all("tr"):
|
||||
collection_type = table_row.contents[0].text
|
||||
collection_next = table_row.contents[1].text
|
||||
collection_date = re.findall(r"\(.*?\)", collection_next)
|
||||
|
||||
if len(collection_date) != 1:
|
||||
continue
|
||||
|
||||
collection_date_obj = parse(re.sub("[()]", "", collection_date[0])).date()
|
||||
|
||||
# since we only have the next collection day, if the parsed date is in the past,
|
||||
# assume the day is instead next month
|
||||
if collection_date_obj < datetime.now().date():
|
||||
collection_date_obj += relativedelta(months=1)
|
||||
|
||||
entries.append(
|
||||
Collection(
|
||||
date=collection_date_obj,
|
||||
t=collection_type,
|
||||
icon=ICON_MAP.get(collection_type, "mdi:help"),
|
||||
)
|
||||
)
|
||||
|
||||
if not entries:
|
||||
raise ValueError(
|
||||
"Could not get collections for the given combination of UPRN and Postcode."
|
||||
)
|
||||
|
||||
return entries
|
||||
51
doc/source/birmingham_gov_uk.md
Normal file
51
doc/source/birmingham_gov_uk.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Birmingham City Council
|
||||
|
||||
Support for schedules provided by [Birmingham City Council](https://www.birmingham.gov.uk/), in the UK.
|
||||
|
||||
## Configuration via configuration.yaml
|
||||
|
||||
```yaml
|
||||
waste_collection_schedule:
|
||||
sources:
|
||||
- name: birmingham_gov_uk
|
||||
args:
|
||||
uprn: UNIQUE_PROPERTY_REFERENCE_NUMBER
|
||||
postcode: POSTCODE
|
||||
```
|
||||
|
||||
### Configuration Variables
|
||||
|
||||
**uprn**<br>
|
||||
*(string)*
|
||||
|
||||
The "Unique Property Reference Number" for your address. You can find it by searching for your address at https://www.findmyaddress.co.uk/.
|
||||
|
||||
**postcode**<br>
|
||||
*(string)*
|
||||
|
||||
The Post Code for your address. This needs to match the postcode corresponding to your UPRN.
|
||||
|
||||
## Example
|
||||
```yaml
|
||||
waste_collection_schedule:
|
||||
sources:
|
||||
- name: birmingham_gov_uk
|
||||
args:
|
||||
uprn: 100070321799
|
||||
postcode: B27 6TF
|
||||
```
|
||||
|
||||
## Returned Collections
|
||||
This source will return the next collection date for each container type.
|
||||
|
||||
## Returned collection types
|
||||
|
||||
### Household Collection
|
||||
Grey lid rubbish bin is for general waste.
|
||||
|
||||
### Recycling Collection
|
||||
Green lid recycling bin is for dry recycling (metals, glass and plastics).
|
||||
Blue lid recycling bin is for paper and card.
|
||||
|
||||
### Green Recycling Chargeable Collections
|
||||
Green Recycling (Chargeable Collections).
|
||||
Reference in New Issue
Block a user