uk_bin_collection 0.149.0__py3-none-any.whl → 0.150.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- uk_bin_collection/tests/input.json +10 -5
- uk_bin_collection/uk_bin_collection/councils/MeltonBoroughCouncil.py +82 -0
- uk_bin_collection/uk_bin_collection/councils/MorayCouncil.py +55 -37
- {uk_bin_collection-0.149.0.dist-info → uk_bin_collection-0.150.1.dist-info}/METADATA +1 -1
- {uk_bin_collection-0.149.0.dist-info → uk_bin_collection-0.150.1.dist-info}/RECORD +8 -7
- {uk_bin_collection-0.149.0.dist-info → uk_bin_collection-0.150.1.dist-info}/LICENSE +0 -0
- {uk_bin_collection-0.149.0.dist-info → uk_bin_collection-0.150.1.dist-info}/WHEEL +0 -0
- {uk_bin_collection-0.149.0.dist-info → uk_bin_collection-0.150.1.dist-info}/entry_points.txt +0 -0
@@ -222,12 +222,10 @@
|
|
222
222
|
"LAD24CD": "E07000129"
|
223
223
|
},
|
224
224
|
"BlackburnCouncil": {
|
225
|
+
"url": "https://www.blaby.gov.uk",
|
225
226
|
"LAD24CD": "E06000008",
|
226
227
|
"skip_get_url": true,
|
227
228
|
"uprn": "100010733027",
|
228
|
-
"url": "https://mybins.blackburn.gov.uk/api/mybins/getbincollectiondays?uprn=100010733027&month=8&year=2022",
|
229
|
-
"web_driver": "http://selenium:4444",
|
230
|
-
"wiki_command_url_override": "https://www.blackburn.gov.uk",
|
231
229
|
"wiki_name": "Blackburn with Darwen",
|
232
230
|
"wiki_note": "You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find the UPRN."
|
233
231
|
},
|
@@ -1436,6 +1434,13 @@
|
|
1436
1434
|
"wiki_note": "Pass the UPRN. You can find it using [FindMyAddress](https://www.findmyaddress.co.uk/search).",
|
1437
1435
|
"LAD24CD": "E06000035"
|
1438
1436
|
},
|
1437
|
+
"MeltonBoroughCouncil": {
|
1438
|
+
"uprn": "100030540956",
|
1439
|
+
"url": "https://my.melton.gov.uk/collections",
|
1440
|
+
"wiki_name": "Melton",
|
1441
|
+
"wiki_note": "To get the UPRN, you can use [FindMyAddress](https://www.findmyaddress.co.uk/search).",
|
1442
|
+
"LAD24CD": "E07000133"
|
1443
|
+
},
|
1439
1444
|
"MertonCouncil": {
|
1440
1445
|
"url": "https://myneighbourhood.merton.gov.uk/wasteservices/WasteServices.aspx?ID=25936129",
|
1441
1446
|
"wiki_command_url_override": "https://myneighbourhood.merton.gov.uk/Wasteservices/WasteServices.aspx?ID=XXXXXXXX",
|
@@ -1483,7 +1488,7 @@
|
|
1483
1488
|
"MiddlesbroughCouncil": {
|
1484
1489
|
"house_number": "12 Constantine Court Park Road North, Middlesbrough",
|
1485
1490
|
"skip_get_url": true,
|
1486
|
-
"url": "https://www.
|
1491
|
+
"url": "https://www.middlesbrough.gov.uk/recycling-and-rubbish/bin-collection-dates/",
|
1487
1492
|
"web_driver": "http://selenium:4444",
|
1488
1493
|
"wiki_name": "Middlesbrough",
|
1489
1494
|
"wiki_note": "Pass the entire address without postcode as it appears when you type it on the website. This parser requires a Selenium webdriver.",
|
@@ -1532,7 +1537,7 @@
|
|
1532
1537
|
"LAD24CD": "W06000021"
|
1533
1538
|
},
|
1534
1539
|
"MorayCouncil": {
|
1535
|
-
"uprn": "
|
1540
|
+
"uprn": "45438",
|
1536
1541
|
"url": "https://bindayfinder.moray.gov.uk/",
|
1537
1542
|
"wiki_name": "Moray",
|
1538
1543
|
"wiki_note": "Find your property ID by going to (https://bindayfinder.moray.gov.uk), search for your property and extracting the ID from the URL. i.e. (https://bindayfinder.moray.gov.uk/disp_bins.php?id=00028841)",
|
@@ -0,0 +1,82 @@
|
|
1
|
+
import json
|
2
|
+
from datetime import datetime, timedelta
|
3
|
+
|
4
|
+
import requests
|
5
|
+
from bs4 import BeautifulSoup
|
6
|
+
|
7
|
+
from uk_bin_collection.uk_bin_collection.common import *
|
8
|
+
from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
|
9
|
+
|
10
|
+
|
11
|
+
# import the wonderful Beautiful Soup and the URL grabber
|
12
|
+
class CouncilClass(AbstractGetBinDataClass):
|
13
|
+
"""
|
14
|
+
Concrete classes have to implement all abstract operations of the
|
15
|
+
base class. They can also override some operations with a default
|
16
|
+
implementation.
|
17
|
+
"""
|
18
|
+
|
19
|
+
def extract_dates(self, date_string: str) -> list:
|
20
|
+
"""
|
21
|
+
Extract dates from strings like "01/05/2025, and then 15/05/2025"
|
22
|
+
Returns list of datetime objects
|
23
|
+
"""
|
24
|
+
date_string = date_string.replace("and then", ",")
|
25
|
+
date_parts = [part.strip() for part in date_string.split(",") if part.strip()]
|
26
|
+
|
27
|
+
dates = []
|
28
|
+
for part in date_parts:
|
29
|
+
try:
|
30
|
+
date_obj = datetime.strptime(part, "%d/%m/%Y")
|
31
|
+
dates.append(date_obj)
|
32
|
+
except ValueError:
|
33
|
+
continue
|
34
|
+
|
35
|
+
return dates
|
36
|
+
|
37
|
+
def parse_data(self, page: str, **kwargs) -> dict:
|
38
|
+
user_uprn = kwargs.get("uprn")
|
39
|
+
check_uprn(user_uprn)
|
40
|
+
|
41
|
+
url = f"https://my.melton.gov.uk/set-location?id={user_uprn}&redirect=collections&rememberloc="
|
42
|
+
response = requests.get(url)
|
43
|
+
soup = BeautifulSoup(response.text, "html.parser")
|
44
|
+
|
45
|
+
collections = []
|
46
|
+
|
47
|
+
# Find all box items
|
48
|
+
box_items = soup.find_all("li", class_=lambda x: x and x.startswith("box-item"))
|
49
|
+
|
50
|
+
for box in box_items:
|
51
|
+
bin_type = box.find("h2")
|
52
|
+
if (
|
53
|
+
bin_type and "Missed bin" not in bin_type.text
|
54
|
+
): # Skip the "Missed bin" section
|
55
|
+
bin_name = bin_type.text.strip()
|
56
|
+
|
57
|
+
# Find the strong tag containing dates
|
58
|
+
dates_element = box.find("strong")
|
59
|
+
if dates_element:
|
60
|
+
dates_text = dates_element.text.strip()
|
61
|
+
# Use self.extract_dates instead of extract_dates
|
62
|
+
collection_dates = self.extract_dates(dates_text)
|
63
|
+
|
64
|
+
# Add each date for this bin type to collections
|
65
|
+
for date in collection_dates:
|
66
|
+
collections.append((bin_name, date))
|
67
|
+
|
68
|
+
# Sort the collections by date
|
69
|
+
ordered_data = sorted(collections, key=lambda x: x[1])
|
70
|
+
|
71
|
+
# Format the data as required
|
72
|
+
data = {"bins": []}
|
73
|
+
for item in ordered_data:
|
74
|
+
dict_data = {
|
75
|
+
"type": item[0],
|
76
|
+
"collectionDate": item[1].strftime(date_format),
|
77
|
+
}
|
78
|
+
data["bins"].append(dict_data)
|
79
|
+
|
80
|
+
print(json.dumps(data, indent=2))
|
81
|
+
|
82
|
+
return data
|
@@ -14,52 +14,70 @@ class CouncilClass(AbstractGetBinDataClass):
|
|
14
14
|
"""
|
15
15
|
|
16
16
|
def parse_data(self, page: str, **kwargs) -> dict:
|
17
|
-
|
18
17
|
user_uprn = kwargs.get("uprn")
|
18
|
+
print(f"Using UPRN: {user_uprn}") # Debug
|
19
19
|
bindata = {"bins": []}
|
20
20
|
|
21
21
|
user_uprn = user_uprn.zfill(8)
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
)
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
23
|
+
url = f"https://bindayfinder.moray.gov.uk/disp_bins.php?id={user_uprn}"
|
24
|
+
|
25
|
+
# year = datetime.today().year
|
26
|
+
# url = f"https://bindayfinder.moray.gov.uk/cal_{year}_view.php"
|
27
|
+
print(f"Trying URL: {url}") # Debug
|
28
|
+
|
29
|
+
response = requests.get(url)
|
30
|
+
print(f"Response status code: {response.status_code}") # Debug
|
31
|
+
|
32
|
+
# if response.status_code != 200:
|
33
|
+
# fallback_url = "https://bindayfinder.moray.gov.uk/cal_2024_view.php"
|
34
|
+
# print(f"Falling back to: {fallback_url}") # Debug
|
35
|
+
# response = requests.get(
|
36
|
+
# fallback_url,
|
37
|
+
# params={"id": user_uprn},
|
38
|
+
# )
|
39
|
+
# print(f"Fallback response status: {response.status_code}") # Debug
|
40
|
+
|
34
41
|
soup = BeautifulSoup(response.text, "html.parser")
|
35
42
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
43
|
+
# Find all container_images divs
|
44
|
+
container_images = soup.find_all("div", class_="container_images")
|
45
|
+
print(f"Found {len(container_images)} container images") # Debug
|
46
|
+
|
47
|
+
for container in container_images:
|
48
|
+
# Get bin type from image alt text
|
49
|
+
img = container.find("img")
|
50
|
+
if img and img.get("alt"):
|
51
|
+
# Use the full alt text as one bin type instead of splitting
|
52
|
+
bin_type = img["alt"]
|
53
|
+
print(f"Found bin type: {bin_type}") # Debug
|
54
|
+
|
55
|
+
# Get collection date from binz_txt
|
56
|
+
date_text = container.find("div", class_="binz_txt")
|
57
|
+
if date_text:
|
58
|
+
date_str = date_text.text
|
59
|
+
print(f"Found date text: {date_str}") # Debug
|
60
|
+
|
61
|
+
# Extract just the date portion
|
62
|
+
import re
|
63
|
+
|
64
|
+
date_match = re.search(r"(\d{1,2}\s+[A-Za-z]+\s+\d{4})", date_str)
|
65
|
+
if date_match:
|
66
|
+
date_portion = date_match.group(1)
|
67
|
+
try:
|
68
|
+
# Convert the date string to the required format
|
69
|
+
parsed_date = datetime.strptime(date_portion, "%d %B %Y")
|
70
|
+
collection_date = parsed_date.strftime("%d/%m/%Y")
|
71
|
+
print(f"Parsed date: {collection_date}") # Debug
|
72
|
+
|
52
73
|
dict_data = {
|
53
|
-
"type":
|
54
|
-
"collectionDate":
|
55
|
-
f"{dom} {month} {year}",
|
56
|
-
"%d %B %Y",
|
57
|
-
).strftime("%d/%m/%Y"),
|
74
|
+
"type": bin_type,
|
75
|
+
"collectionDate": collection_date,
|
58
76
|
}
|
59
77
|
bindata["bins"].append(dict_data)
|
78
|
+
except ValueError as e:
|
79
|
+
print(f"Error parsing date: {e}") # Debug
|
80
|
+
continue
|
60
81
|
|
61
|
-
bindata
|
62
|
-
key=lambda x: datetime.strptime(x.get("collectionDate"), "%d/%m/%Y")
|
63
|
-
)
|
64
|
-
|
82
|
+
print(f"Final bindata: {bindata}") # Debug
|
65
83
|
return bindata
|
@@ -7,7 +7,7 @@ uk_bin_collection/tests/council_feature_input_parity.py,sha256=DO6Mk4ImYgM5ZCZ-c
|
|
7
7
|
uk_bin_collection/tests/features/environment.py,sha256=VQZjJdJI_kZn08M0j5cUgvKT4k3iTw8icJge1DGOkoA,127
|
8
8
|
uk_bin_collection/tests/features/validate_council_outputs.feature,sha256=SJK-Vc737hrf03tssxxbeg_JIvAH-ddB8f6gU1LTbuQ,251
|
9
9
|
uk_bin_collection/tests/generate_map_test_results.py,sha256=CKnGK2ZgiSXomRGkomX90DitgMP-X7wkHhyKORDcL2E,1144
|
10
|
-
uk_bin_collection/tests/input.json,sha256=
|
10
|
+
uk_bin_collection/tests/input.json,sha256=dPgWnCRdDky-incNNaf9iYMI4i9wrkktRs4BZmIwyzE,131794
|
11
11
|
uk_bin_collection/tests/output.schema,sha256=ZwKQBwYyTDEM4G2hJwfLUVM-5v1vKRvRK9W9SS1sd18,1086
|
12
12
|
uk_bin_collection/tests/step_defs/step_helpers/file_handler.py,sha256=Ygzi4V0S1MIHqbdstUlIqtRIwnynvhu4UtpweJ6-5N8,1474
|
13
13
|
uk_bin_collection/tests/step_defs/test_validate_council.py,sha256=VZ0a81sioJULD7syAYHjvK_-nT_Rd36tUyzPetSA0gk,3475
|
@@ -184,6 +184,7 @@ uk_bin_collection/uk_bin_collection/councils/MalvernHillsDC.py,sha256=iQG0EkX2np
|
|
184
184
|
uk_bin_collection/uk_bin_collection/councils/ManchesterCityCouncil.py,sha256=RY301_82z3-xInGai5ocT7rzoV75ATbf0N7uxn8Z9LE,3110
|
185
185
|
uk_bin_collection/uk_bin_collection/councils/MansfieldDistrictCouncil.py,sha256=F5AiTxImrnjE1k3ry96bfstOf5XSNBJS_4qqmymmh3w,1386
|
186
186
|
uk_bin_collection/uk_bin_collection/councils/MedwayCouncil.py,sha256=nBJSv09OUOascrfNu1ek1wNzE9ONu5ZkrBU-1qwDHJ0,1278
|
187
|
+
uk_bin_collection/uk_bin_collection/councils/MeltonBoroughCouncil.py,sha256=Xql_ydrk59nx3dPok6YSVZ7mk8GJT2-IKOGqILgE0xU,2802
|
187
188
|
uk_bin_collection/uk_bin_collection/councils/MertonCouncil.py,sha256=xsOSX4KCcUHHo4BHB5JhFC9r5Q-h586Vk-5-X2VAJl0,2809
|
188
189
|
uk_bin_collection/uk_bin_collection/councils/MidAndEastAntrimBoroughCouncil.py,sha256=oOWwU5FSgGej2Mv7FQ66N-EzS5nZgmGsd0WnfLWUc1I,5238
|
189
190
|
uk_bin_collection/uk_bin_collection/councils/MidDevonCouncil.py,sha256=8MxqGgOJVseMkrTmEMT0EyDW7UMbXMoa5ZcJ2nD55Ew,3367
|
@@ -195,7 +196,7 @@ uk_bin_collection/uk_bin_collection/councils/MidlothianCouncil.py,sha256=-VKvdIh
|
|
195
196
|
uk_bin_collection/uk_bin_collection/councils/MiltonKeynesCityCouncil.py,sha256=7e2pGBLCw24pNItHeI9jkxQ3rEOZ4WC4zVlbvKYGdXE,2600
|
196
197
|
uk_bin_collection/uk_bin_collection/councils/MoleValleyDistrictCouncil.py,sha256=xWR5S0gwQu9gXxjl788Wux1KaC0CT7ZFw0iXuRLZCEM,5599
|
197
198
|
uk_bin_collection/uk_bin_collection/councils/MonmouthshireCountyCouncil.py,sha256=PC2tui10S-DXmiKUqXZun5MInIgqqQjtT5wII1K_9a0,2532
|
198
|
-
uk_bin_collection/uk_bin_collection/councils/MorayCouncil.py,sha256=
|
199
|
+
uk_bin_collection/uk_bin_collection/councils/MorayCouncil.py,sha256=B8unofp2x1HF72QT_3E0Iew78PWMywjzkNDJdWof2Tc,3309
|
199
200
|
uk_bin_collection/uk_bin_collection/councils/NeathPortTalbotCouncil.py,sha256=p95UYogx3_WJ_1kgfeH5kGQdrZ3YyEJjVuZ7WOOPAvs,5710
|
200
201
|
uk_bin_collection/uk_bin_collection/councils/NewForestCouncil.py,sha256=Vdmv_p75OJwSeltWE5wZhE8wy5XW0CIKIn1cKNvI0pQ,5336
|
201
202
|
uk_bin_collection/uk_bin_collection/councils/NewarkAndSherwoodDC.py,sha256=lAleYfCGUWCKOi7Ye_cjgfpI3pWwTcFctlYmh0hjebM,2140
|
@@ -338,8 +339,8 @@ uk_bin_collection/uk_bin_collection/councils/YorkCouncil.py,sha256=I2kBYMlsD4bId
|
|
338
339
|
uk_bin_collection/uk_bin_collection/councils/council_class_template/councilclasstemplate.py,sha256=QD4v4xpsEE0QheR_fGaNOIRMc2FatcUfKkkhAhseyVU,1159
|
339
340
|
uk_bin_collection/uk_bin_collection/create_new_council.py,sha256=m-IhmWmeWQlFsTZC4OxuFvtw5ZtB8EAJHxJTH4O59lQ,1536
|
340
341
|
uk_bin_collection/uk_bin_collection/get_bin_data.py,sha256=YvmHfZqanwrJ8ToGch34x-L-7yPe31nB_x77_Mgl_vo,4545
|
341
|
-
uk_bin_collection-0.
|
342
|
-
uk_bin_collection-0.
|
343
|
-
uk_bin_collection-0.
|
344
|
-
uk_bin_collection-0.
|
345
|
-
uk_bin_collection-0.
|
342
|
+
uk_bin_collection-0.150.1.dist-info/LICENSE,sha256=vABBUOzcrgfaTKpzeo-si9YVEun6juDkndqA8RKdKGs,1071
|
343
|
+
uk_bin_collection-0.150.1.dist-info/METADATA,sha256=5EPNN3fs7XWzZbnRZwzDtpg-L9I_m7TljIQk4ZgjEgc,20914
|
344
|
+
uk_bin_collection-0.150.1.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
345
|
+
uk_bin_collection-0.150.1.dist-info/entry_points.txt,sha256=36WCSGMWSc916S3Hi1ZkazzDKHaJ6CD-4fCEFm5MIao,90
|
346
|
+
uk_bin_collection-0.150.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
{uk_bin_collection-0.149.0.dist-info → uk_bin_collection-0.150.1.dist-info}/entry_points.txt
RENAMED
File without changes
|