mirror of
https://github.com/sascha-hemi/hacs_waste_collection_schedule.git
synced 2026-03-21 02:04:22 +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
|
- [BCP Council](/doc/source/bcp_gov_uk.md) / bcpcouncil.gov.uk
|
||||||
- [Bedford Borough Council](/doc/source/bedford_gov_uk.md) / bedford.gov.uk
|
- [Bedford Borough Council](/doc/source/bedford_gov_uk.md) / bedford.gov.uk
|
||||||
- [Binzone](/doc/source/binzone_uk.md) / southoxon.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
|
- [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
|
- [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
|
- [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