From a2b35bb201283309b90dbfa039347e2879d1086a Mon Sep 17 00:00:00 2001 From: m26dvd <31007572+m26dvd@users.noreply.github.com> Date: Sun, 20 Oct 2024 23:51:20 +0100 Subject: [PATCH] feat: Adding Luton Borough Council fix: #697 --- uk_bin_collection/tests/input.json | 7 ++ .../councils/LutonBoroughCouncil.py | 81 +++++++++++++++++++ wiki/Councils.md | 12 +++ 3 files changed, 100 insertions(+) create mode 100644 uk_bin_collection/uk_bin_collection/councils/LutonBoroughCouncil.py diff --git a/uk_bin_collection/tests/input.json b/uk_bin_collection/tests/input.json index 8a7e59b889..957ab622a5 100644 --- a/uk_bin_collection/tests/input.json +++ b/uk_bin_collection/tests/input.json @@ -695,6 +695,13 @@ "wiki_name": "London Borough Redbridge", "wiki_note": "Follow the instructions [here](https://my.redbridge.gov.uk/RecycleRefuse) until you get the page listing your \"Address\" then copy the entire address text and use that in the house number field." }, + "LutonBoroughCouncil": { + "url": "https://myforms.luton.gov.uk", + "wiki_command_url_override": "https://myforms.luton.gov.uk", + "uprn": "100080155778", + "wiki_name": "Luton Borough Council", + "wiki_note": "You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find the UPRN." + }, "MaldonDistrictCouncil": { "skip_get_url": true, "uprn": "100090557253", diff --git a/uk_bin_collection/uk_bin_collection/councils/LutonBoroughCouncil.py b/uk_bin_collection/uk_bin_collection/councils/LutonBoroughCouncil.py new file mode 100644 index 0000000000..7dda0c6d8a --- /dev/null +++ b/uk_bin_collection/uk_bin_collection/councils/LutonBoroughCouncil.py @@ -0,0 +1,81 @@ +import time + +import requests +from bs4 import BeautifulSoup + +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: + + user_uprn = kwargs.get("uprn") + check_uprn(user_uprn) + bindata = {"bins": []} + + SESSION_URL = "https://myforms.luton.gov.uk/authapi/isauthenticated?uri=https%253A%252F%252Fmyforms.luton.gov.uk%252Fservice%252FFind_my_bin_collection_date&hostname=myforms.luton.gov.uk&withCredentials=true" + + API_URL = "https://myforms.luton.gov.uk/apibroker/runLookup" + + data = { + "formValues": { + "Find my bin collection date": { + "id": { + "value": f"1-{user_uprn}", + }, + }, + } + } + + headers = { + "Content-Type": "application/json", + "Accept": "application/json", + "User-Agent": "Mozilla/5.0", + "X-Requested-With": "XMLHttpRequest", + "Referer": "https://myforms.luton.gov.uk/fillform/?iframe_id=fillform-frame-1&db_id=", + } + s = requests.session() + r = s.get(SESSION_URL) + r.raise_for_status() + session_data = r.json() + sid = session_data["auth-session"] + params = { + "id": "65cb710f8d525", + "repeat_against": "", + "noRetry": "true", + "getOnlyTokens": "undefined", + "log_id": "", + "app_name": "AF-Renderer::Self", + # unix_timestamp + "_": str(int(time.time() * 1000)), + "sid": sid, + } + r = s.post(API_URL, json=data, headers=headers, params=params) + r.raise_for_status() + data = r.json() + rows_data = data["integration"]["transformed"]["rows_data"][f"{user_uprn}"] + + soup = BeautifulSoup(rows_data["html"], features="html.parser") + soup.prettify() + for collection in soup.find_all("tr"): + tds = collection.find_all("td") + bin_type = tds[1].text + collection_date = datetime.strptime( + tds[0].text, + "%A %d %b %Y", + ) + dict_data = { + "type": bin_type, + "collectionDate": collection_date.strftime(date_format), + } + bindata["bins"].append(dict_data) + + return bindata diff --git a/wiki/Councils.md b/wiki/Councils.md index 29399e78c7..e0a82f722e 100644 --- a/wiki/Councils.md +++ b/wiki/Councils.md @@ -105,6 +105,7 @@ This document is still a work in progress, don't worry if your council isn't lis - [London Borough Hounslow](#london-borough-hounslow) - [London Borough Lambeth](#london-borough-lambeth) - [London Borough Redbridge](#london-borough-redbridge) +- [Luton Borough Council](#luton-borough-council) - [Maldon District Council](#maldon-district-council) - [Malvern Hills District Council](#malvern-hills-district-council) - [Manchester City Council](#manchester-city-council) @@ -1321,6 +1322,17 @@ Note: Follow the instructions [here](https://my.redbridge.gov.uk/RecycleRefuse) --- +### Luton Borough Council +```commandline +python collect_data.py LutonBoroughCouncil https://myforms.luton.gov.uk -u XXXXXXXX +``` +Additional parameters: +- `-u` - UPRN + +Note: You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find the UPRN. + +--- + ### Maldon District Council ```commandline python collect_data.py MaldonDistrictCouncil https://maldon.suez.co.uk/maldon/ServiceSummary -s -u XXXXXXXX