Skip to content

Commit

Permalink
feat: Adding Aberdeen City Council
Browse files Browse the repository at this point in the history
  • Loading branch information
m26dvd committed Nov 17, 2024
1 parent db3c6be commit 6dac9f3
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 0 deletions.
6 changes: 6 additions & 0 deletions uk_bin_collection/tests/input.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@
"wiki_name": "Aberdeenshire Council",
"wiki_note": "You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find the UPRN."
},
"AberdeenCityCouncil": {
"url": "https://www.aberdeencity.gov.uk",
"uprn": "9051156186",
"wiki_name": "Aberdeen City 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
122 changes: 122 additions & 0 deletions uk_bin_collection/uk_bin_collection/councils/AberdeenCityCouncil.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
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": []}

SESSION_URL = "https://integration.aberdeencity.gov.uk/authapi/isauthenticated?uri=https%253A%252F%252Fintegration.aberdeencity.gov.uk%252Fservice%252Fbin_collection_calendar___view&hostname=integration.aberdeencity.gov.uk&withCredentials=true"

API_URL = "https://integration.aberdeencity.gov.uk/apibroker/runLookup"

headers = {
"Content-Type": "application/json",
"Accept": "application/json",
"User-Agent": "Mozilla/5.0",
"X-Requested-With": "XMLHttpRequest",
"Referer": "https://integration.aberdeencity.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": "583c08ffc47fe",
"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, headers=headers, params=params)
r.raise_for_status()

data = r.json()
rows_data = data["integration"]["transformed"]["rows_data"]["0"]
if not isinstance(rows_data, dict):
raise ValueError("Invalid data returned from API")
token = rows_data["token"]

data = {
"formValues": {
"Section 1": {
"nauprn": {
"value": user_uprn,
},
"token": {
"value": token,
},
"mindate": {
"value": datetime.now().strftime("%Y-%m-%d"),
},
"maxdate": {
"value": (datetime.now() + timedelta(days=30)).strftime(
"%Y-%m-%d"
),
},
},
},
}

params = {
"id": "5a3141caf4016",
"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"]["0"]
if not isinstance(rows_data, dict):
raise ValueError("Invalid data returned from API")

date_pattern = re.compile(r"^(.*?)(Date\d+)$")
count_pattern = re.compile(r"^Count(.*)$")
for key, value in rows_data.items():
date_match = date_pattern.match(key)
# Match count keys
count_match = count_pattern.match(key)
if count_match:
continue

# Match date keys
date_match = date_pattern.match(key)
if date_match:
bin_type = date_match.group(1)
dict_data = {
"type": bin_type,
"collectionDate": datetime.strptime(value, "%A %d %B %Y").strftime(
date_format
),
}
bindata["bins"].append(dict_data)

return bindata
12 changes: 12 additions & 0 deletions wiki/Councils.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ This document is still a work in progress, don't worry if your council isn't lis

## Contents
- [Aberdeenshire Council](#aberdeenshire-council)
- [Aberdeen City Council](#aberdeen-city-council)
- [Adur and Worthing Councils](#adur-and-worthing-councils)
- [Antrim & Newtonabbey Council](#antrim-&-newtonabbey-council)
- [Ards and North Down Council](#ards-and-north-down-council)
Expand Down Expand Up @@ -274,6 +275,17 @@ Note: You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/searc

---

### Aberdeen City Council
```commandline
python collect_data.py AberdeenCityCouncil https://www.aberdeencity.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.

---

### Adur and Worthing Councils
```commandline
python collect_data.py AdurAndWorthingCouncils https://www.adur-worthing.gov.uk/bin-day/?brlu-selected-address=XXXXXXXX
Expand Down

0 comments on commit 6dac9f3

Please sign in to comment.