Skip to content

Commit

Permalink
Merge pull request #913 from m26dvd/master
Browse files Browse the repository at this point in the history
feat: Council Pack 7
  • Loading branch information
robbrad authored Oct 20, 2024
2 parents d5a402d + a2b35bb commit 4ab7da1
Show file tree
Hide file tree
Showing 7 changed files with 466 additions and 0 deletions.
37 changes: 37 additions & 0 deletions uk_bin_collection/tests/input.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
{
"AberdeenshireCouncil": {
"url": "https://online.aberdeenshire.gov.uk",
"wiki_command_url_override": "https://online.aberdeenshire.gov.uk",
"uprn": "151176430",
"wiki_name": "Aberdeenshire Council",
"wiki_note": "You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find the UPRN."
},
"AdurAndWorthingCouncils": {
"url": "https://www.adur-worthing.gov.uk/bin-day/?brlu-selected-address=100061878829",
"wiki_command_url_override": "https://www.adur-worthing.gov.uk/bin-day/?brlu-selected-address=XXXXXXXX",
Expand Down Expand Up @@ -201,6 +208,13 @@
"wiki_name": "Cannock Chase District Council",
"wiki_note": "To get the UPRN, you can use [FindMyAddress](https://www.findmyaddress.co.uk/search)"
},
"CanterburyCityCouncil": {
"url": "https://www.canterbury.gov.uk",
"wiki_command_url_override": "https://www.canterbury.gov.uk",
"uprn": "10094583181",
"wiki_name": "Canterbury City Council",
"wiki_note": "You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find the UPRN."
},
"CardiffCouncil": {
"skip_get_url": true,
"uprn": "100100112419",
Expand Down Expand Up @@ -681,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",
Expand Down Expand Up @@ -1189,6 +1210,13 @@
"url": "https://www1.swansea.gov.uk/recyclingsearch/",
"wiki_name": "SwanseaCouncil"
},
"SwindonBoroughCouncil": {
"url": "https://www.swindon.gov.uk",
"wiki_command_url_override": "https://www.swindon.gov.uk",
"uprn": "10022793351",
"wiki_name": "Swindon Borough Council",
"wiki_note": "You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find the UPRN."
},
"TamesideMBCouncil": {
"skip_get_url": true,
"uprn": "100012835362",
Expand Down Expand Up @@ -1369,6 +1397,15 @@
"url": "https://www.northampton.gov.uk/info/200084/bins-waste-and-recycling/1602/check-your-collection-day",
"wiki_name": "West Northamptonshire Council"
},
"WestOxfordshireDistrictCouncil": {
"house_number": "24",
"postcode": "OX28 1YA",
"skip_get_url": true,
"url": "https://community.westoxon.gov.uk/s/waste-collection-enquiry",
"web_driver": "http://selenium:4444",
"wiki_name": "West Oxfordshire District Council",
"wiki_note": "Pass the full address in the house number and postcode in"
},
"WestSuffolkCouncil": {
"postcode": "IP28 6DR",
"skip_get_url": true,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
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": []}

URI = f"https://online.aberdeenshire.gov.uk/Apps/Waste-Collections/Routes/Route/{user_uprn}"

# Make the GET request
response = requests.get(URI)

soup = BeautifulSoup(response.content, features="html.parser")
soup.prettify()

for collection in soup.find("table").find("tbody").find_all("tr"):
th = collection.find("th")
if th:
continue
td = collection.find_all("td")
collection_date = datetime.strptime(
td[0].text,
"%d/%m/%Y %A",
)
bin_type = td[1].text.split(" and ")

for bin in bin_type:
dict_data = {
"type": bin,
"collectionDate": collection_date.strftime(date_format),
}
bindata["bins"].append(dict_data)

bindata["bins"].sort(
key=lambda x: datetime.strptime(x.get("collectionDate"), "%d/%m/%Y")
)

return bindata
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import time

import requests

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": []}

data = {"uprn": user_uprn, "usrn": "1"}

URI = (
"https://zbr7r13ke2.execute-api.eu-west-2.amazonaws.com/Beta/get-bin-dates"
)

# Make the GET request
response = requests.post(URI, json=data)
response.raise_for_status()

# Parse the JSON response
bin_collection = json.loads(response.json()["dates"])
collections = {
"General": bin_collection["blackBinDay"],
"Recycling": bin_collection["recyclingBinDay"],
"Food": bin_collection["foodBinDay"],
"Garden": bin_collection["gardenBinDay"],
}
# Loop through each collection in bin_collection
for collection in collections:
print(collection)

if len(collections[collection]) <= 0:
continue
for date in collections[collection]:
date = (
datetime.strptime(date, "%Y-%m-%dT%H:%M:%S").strftime("%d/%m/%Y"),
)
dict_data = {"type": collection, "collectionDate": date[0]}
bindata["bins"].append(dict_data)

return bindata
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
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": []}

URI = f"https://www.swindon.gov.uk/info/20122/rubbish_and_recycling_collection_days?addressList={user_uprn}&uprnSubmit=Yes"

# Make the GET request
response = requests.get(URI)

# Parse the JSON response
soup = BeautifulSoup(response.text, "html.parser")

bin_collection_content = soup.find_all(
"div", {"class": "bin-collection-content"}
)
for content in bin_collection_content:
content_left = content.find("div", {"class": "content-left"})
content_right = content.find("div", {"class": "content-right"})
if content_left and content_right:

bin_types = content_left.find("h3").text.split(" and ")
for bin_type in bin_types:

collection_date = datetime.strptime(
content_right.find(
"span", {"class": "nextCollectionDate"}
).text,
"%A, %d %B %Y",
).strftime(date_format)

dict_data = {
"type": bin_type,
"collectionDate": collection_date,
}
bindata["bins"].append(dict_data)

return bindata
Loading

0 comments on commit 4ab7da1

Please sign in to comment.