uk_bin_collection 0.143.5__py3-none-any.whl → 0.144.0__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.
@@ -877,6 +877,15 @@
877
877
  "wiki_name": "Gravesham Borough Council",
878
878
  "wiki_note": "Pass the UPRN. You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/search)."
879
879
  },
880
+ "GreatYarmouthBoroughCouncil": {
881
+ "postcode": "NR31 7EB",
882
+ "skip_get_url": true,
883
+ "uprn": "100090834792",
884
+ "url": "https://myaccount.great-yarmouth.gov.uk/article/6456/Find-my-waste-collection-days",
885
+ "web_driver": "http://selenium:4444",
886
+ "wiki_name": "Great Yarmouth Borough Council",
887
+ "wiki_note": "Pass the postcode, and UPRN in their respective parameters. This parser requires a Selenium webdriver."
888
+ },
880
889
  "GuildfordCouncil": {
881
890
  "house_number": "THE LODGE, PUTTENHAM HILL HOUSE, PUTTENHAM HILL, PUTTENHAM, GUILDFORD, GU3 1AH",
882
891
  "postcode": "GU3 1AH",
@@ -1579,14 +1588,14 @@
1579
1588
  "wiki_note": "To get the UPRN, you can use [FindMyAddress](https://www.findmyaddress.co.uk/search). This parser requires a Selenium webdriver."
1580
1589
  },
1581
1590
  "RenfrewshireCouncil": {
1582
- "house_number": "1",
1583
- "paon": "1",
1584
- "postcode": "PA29ED",
1585
- "skip_get_url": false,
1586
- "url": "https://www.renfrewshire.gov.uk/article/2320/Check-your-bin-collection-day",
1591
+ "house_number": "1, STATIONHOUSE DRIVE, JOHNSTONE, RENFREWSHIRE, PA6 7FJ",
1592
+ "paon": "1, STATIONHOUSE DRIVE, JOHNSTONE, RENFREWSHIRE, PA6 7FJ",
1593
+ "postcode": "PA6 7FJ",
1594
+ "skip_get_url": true,
1595
+ "url": "https://www.renfrewshire.gov.uk/bin-day",
1587
1596
  "web_driver": "http://selenium:4444",
1588
1597
  "wiki_name": "Renfrewshire Council",
1589
- "wiki_note": "Pass the house name/number and postcode in their respective parameters. This parser requires a Selenium webdriver."
1598
+ "wiki_note": "Pass the full address as it appears on the website. This parser requires a Selenium webdriver."
1590
1599
  },
1591
1600
  "RhonddaCynonTaffCouncil": {
1592
1601
  "skip_get_url": true,
@@ -0,0 +1,140 @@
1
+ import time
2
+
3
+ from bs4 import BeautifulSoup
4
+ from selenium.webdriver.common.by import By
5
+ from selenium.webdriver.support import expected_conditions as EC
6
+ from selenium.webdriver.support.ui import Select, WebDriverWait
7
+ from selenium.webdriver.common.keys import Keys
8
+ from datetime import datetime
9
+
10
+ from uk_bin_collection.uk_bin_collection.common import *
11
+ from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
12
+
13
+ # import the wonderful Beautiful Soup and the URL grabber
14
+ class CouncilClass(AbstractGetBinDataClass):
15
+ """
16
+ Concrete classes have to implement all abstract operations of the
17
+ base class. They can also override some operations with a default
18
+ implementation.
19
+ """
20
+
21
+ def parse_data(self, page: str, **kwargs) -> dict:
22
+ driver = None
23
+ try:
24
+ user_uprn = kwargs.get("uprn")
25
+ user_postcode = kwargs.get("postcode")
26
+ headless = kwargs.get("headless")
27
+ web_driver = kwargs.get("web_driver")
28
+ url = kwargs.get("url")
29
+
30
+ check_uprn(user_uprn)
31
+ check_postcode(user_postcode)
32
+
33
+ driver = create_webdriver(web_driver, headless, None, __name__)
34
+
35
+ driver.get(url)
36
+
37
+ wait = WebDriverWait(driver, 10)
38
+ accept_cookies_button = wait.until(
39
+ EC.element_to_be_clickable(
40
+ (
41
+ By.NAME,
42
+ "acceptall",
43
+ )
44
+ )
45
+ )
46
+ accept_cookies_button.click()
47
+
48
+ postcode_input = WebDriverWait(driver, 10).until(
49
+ EC.element_to_be_clickable(
50
+ (By.ID, "WASTECOLLECTIONCALENDARV2_ADDRESS_ALSF")
51
+ )
52
+ )
53
+
54
+ postcode_input.send_keys(user_postcode)
55
+ postcode_input.send_keys(Keys.TAB + Keys.ENTER)
56
+
57
+ time.sleep(2)
58
+ # Wait for address box to be visible
59
+ select_address_input = WebDriverWait(driver, 10).until(
60
+ EC.presence_of_element_located(
61
+ (
62
+ By.ID,
63
+ "WASTECOLLECTIONCALENDARV2_ADDRESS_ALML",
64
+ )
65
+ )
66
+ )
67
+ select_address_input.click()
68
+
69
+ # Assume select_address_input is already the dropdown <select> element
70
+ select = Select(select_address_input)
71
+
72
+ # Select the option with the matching UPRN
73
+ select.select_by_value(user_uprn)
74
+ select_address_input.click()
75
+
76
+ select_address_input.send_keys(Keys.TAB * 2 + Keys.ENTER)
77
+
78
+ time.sleep(5)
79
+ # Wait for the specified div to be present
80
+ target_div = WebDriverWait(driver, 10).until(
81
+ EC.presence_of_element_located((By.ID, "WASTECOLLECTIONCALENDARV2_LOOKUP_SHOWSCHEDULE"))
82
+ )
83
+
84
+ soup = BeautifulSoup(driver.page_source, "html.parser")
85
+
86
+ bin_data = {"bins": []}
87
+ next_collections = {} # Dictionary to store the next collection for each bin type
88
+
89
+ bin_types = {
90
+ "bulky": "Bulky Collection",
91
+ "green": "Recycling",
92
+ "black": "General Waste",
93
+ "brown": "Garden Waste"
94
+ }
95
+
96
+ for div in soup.select(".collection-area"):
97
+ img = div.select_one("img")
98
+ detail = div.select_one(".collection-detail")
99
+ date_text = detail.select_one("b").get_text(strip=True)
100
+
101
+ try:
102
+ # Parse the date text
103
+ date_obj = datetime.strptime(date_text + " 2025", "%A %d %B %Y")
104
+ if date_obj.date() < datetime.today().date():
105
+ continue # Skip past dates
106
+ except ValueError:
107
+ continue
108
+
109
+ # Determine bin type from alt or description
110
+ description = detail.get_text(separator=" ", strip=True).lower()
111
+ alt_text = img['alt'].lower()
112
+
113
+ for key, name in bin_types.items():
114
+ if key in alt_text or key in description:
115
+ # Format date as dd/mm/yyyy
116
+ formatted_date = date_obj.strftime("%d/%m/%Y")
117
+ bin_entry = {
118
+ "type": name,
119
+ "collectionDate": formatted_date
120
+ }
121
+
122
+ # Only keep the earliest date for each bin type
123
+ if name not in next_collections or date_obj < datetime.strptime(next_collections[name]["collectionDate"], "%d/%m/%Y"):
124
+ next_collections[name] = bin_entry
125
+ print(f"Found next collection for {name}: {formatted_date}") # Debug output
126
+ break
127
+
128
+ # Add the next collections to the bin_data
129
+ bin_data["bins"] = list(next_collections.values())
130
+
131
+ except Exception as e:
132
+ print(f"An error occurred: {e}")
133
+ raise
134
+ finally:
135
+ if driver:
136
+ driver.quit()
137
+
138
+ print("\nFinal bin data:")
139
+ print(bin_data) # Debug output
140
+ return bin_data
@@ -19,6 +19,7 @@ class CouncilClass(AbstractGetBinDataClass):
19
19
  driver = None
20
20
  try:
21
21
  data = {"bins": []}
22
+ url = kwargs.get("url")
22
23
  user_paon = kwargs.get("paon")
23
24
  user_postcode = kwargs.get("postcode")
24
25
  web_driver = kwargs.get("web_driver")
@@ -28,9 +29,7 @@ class CouncilClass(AbstractGetBinDataClass):
28
29
 
29
30
  # Create Selenium webdriver
30
31
  driver = create_webdriver(web_driver, headless, None, __name__)
31
- driver.get(
32
- "https://www.renfrewshire.gov.uk/article/2320/Check-your-bin-collection-day"
33
- )
32
+ driver.get("https://www.renfrewshire.gov.uk/bin-day")
34
33
 
35
34
  accept_button = WebDriverWait(driver, timeout=30).until(
36
35
  EC.element_to_be_clickable((By.ID, "ccc-notify-accept"))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: uk_bin_collection
3
- Version: 0.143.5
3
+ Version: 0.144.0
4
4
  Summary: Python Lib to collect UK Bin Data
5
5
  Author: Robert Bradley
6
6
  Author-email: robbrad182@gmail.com
@@ -3,7 +3,7 @@ uk_bin_collection/tests/check_selenium_url_in_input.json.py,sha256=Iecdja0I3XIiY
3
3
  uk_bin_collection/tests/council_feature_input_parity.py,sha256=DO6Mk4ImYgM5ZCZ-cutwz5RoYYWZRLYx2tr6zIs_9Rc,3843
4
4
  uk_bin_collection/tests/features/environment.py,sha256=VQZjJdJI_kZn08M0j5cUgvKT4k3iTw8icJge1DGOkoA,127
5
5
  uk_bin_collection/tests/features/validate_council_outputs.feature,sha256=SJK-Vc737hrf03tssxxbeg_JIvAH-ddB8f6gU1LTbuQ,251
6
- uk_bin_collection/tests/input.json,sha256=4z5vATpVvx8LyiodZuMe55iTCWalBIRMLsELSFTS_uY,121440
6
+ uk_bin_collection/tests/input.json,sha256=ArQftTY8SVx1lttw69j6vTOydzcq2D-aza_sXwjQq5I,121959
7
7
  uk_bin_collection/tests/output.schema,sha256=ZwKQBwYyTDEM4G2hJwfLUVM-5v1vKRvRK9W9SS1sd18,1086
8
8
  uk_bin_collection/tests/step_defs/step_helpers/file_handler.py,sha256=Ygzi4V0S1MIHqbdstUlIqtRIwnynvhu4UtpweJ6-5N8,1474
9
9
  uk_bin_collection/tests/step_defs/test_validate_council.py,sha256=VZ0a81sioJULD7syAYHjvK_-nT_Rd36tUyzPetSA0gk,3475
@@ -131,6 +131,7 @@ uk_bin_collection/uk_bin_collection/councils/GlasgowCityCouncil.py,sha256=9Rk9Kf
131
131
  uk_bin_collection/uk_bin_collection/councils/GloucesterCityCouncil.py,sha256=67D8rbhn0t4rsCSJRTXZVtHmph2wT6rJiexNWKOnMok,4625
132
132
  uk_bin_collection/uk_bin_collection/councils/GooglePublicCalendarCouncil.py,sha256=KiDfL9AVhUlRuY98sbNs_Fb-vUVeo5n1bBShTJHcO8w,1173
133
133
  uk_bin_collection/uk_bin_collection/councils/GraveshamBoroughCouncil.py,sha256=ueQ9xFiTxMUBTGV9VjtySHA1EFWliTM0AeNePBIG9ho,4568
134
+ uk_bin_collection/uk_bin_collection/councils/GreatYarmouthBoroughCouncil.py,sha256=6NIzcn6iiXHEeBer1TlUAAXRWSJOFiYO1IUDmLkF7R0,5295
134
135
  uk_bin_collection/uk_bin_collection/councils/GuildfordCouncil.py,sha256=9pVrmQhZcK2AD8gX8mNvP--L4L9KaY6L3B822VX6fec,5695
135
136
  uk_bin_collection/uk_bin_collection/councils/GwyneddCouncil.py,sha256=eK2KkY1NbIxVtBruQYSNPA0J7fuzMik5it02dFbKYV0,1855
136
137
  uk_bin_collection/uk_bin_collection/councils/HackneyCouncil.py,sha256=vO3ugk5fcdkYTslXNKmpJC84-ZHqrdFqW8zfX7TSiTQ,3104
@@ -226,7 +227,7 @@ uk_bin_collection/uk_bin_collection/councils/ReadingBoroughCouncil.py,sha256=ZlQ
226
227
  uk_bin_collection/uk_bin_collection/councils/RedcarandClevelandCouncil.py,sha256=MV8CD1sj8fiy6PAVrIHO4TyTHodn45nDZp0rQfs7PiM,2829
227
228
  uk_bin_collection/uk_bin_collection/councils/RedditchBoroughCouncil.py,sha256=8QmcpStCT7c-CLhmiQ8ZeEyvtysU110VDiMQdfQTErk,2469
228
229
  uk_bin_collection/uk_bin_collection/councils/ReigateAndBansteadBoroughCouncil.py,sha256=HMLKdRUO5DdMJe1d1X5qtKtQsf6d5TAPViIZpMzAfes,3251
229
- uk_bin_collection/uk_bin_collection/councils/RenfrewshireCouncil.py,sha256=VlWm-w4d-UchoENe_hCTCGlfSHiMlS4wNEeMvxuNR2U,5109
230
+ uk_bin_collection/uk_bin_collection/councils/RenfrewshireCouncil.py,sha256=VjjolGn0KemgIUnmF-JlB8gxNLyaQB5mP61NonxVJAo,5080
230
231
  uk_bin_collection/uk_bin_collection/councils/RhonddaCynonTaffCouncil.py,sha256=wInyVG_0wRrX_dRO9qbAzPhlXDseXapj2zQhsISw8gg,3233
231
232
  uk_bin_collection/uk_bin_collection/councils/RochdaleCouncil.py,sha256=UTSwSw515VehGn4xkjjRhUlzS4lDj4hgna6y-4VW3uM,2379
232
233
  uk_bin_collection/uk_bin_collection/councils/RochfordCouncil.py,sha256=rfhD66A9HfHL46ldF9sbxvV7fPaaoNxzIJbHjVT6A90,2621
@@ -328,8 +329,8 @@ uk_bin_collection/uk_bin_collection/councils/YorkCouncil.py,sha256=I2kBYMlsD4bId
328
329
  uk_bin_collection/uk_bin_collection/councils/council_class_template/councilclasstemplate.py,sha256=EQWRhZ2pEejlvm0fPyOTsOHKvUZmPnxEYO_OWRGKTjs,1158
329
330
  uk_bin_collection/uk_bin_collection/create_new_council.py,sha256=m-IhmWmeWQlFsTZC4OxuFvtw5ZtB8EAJHxJTH4O59lQ,1536
330
331
  uk_bin_collection/uk_bin_collection/get_bin_data.py,sha256=YvmHfZqanwrJ8ToGch34x-L-7yPe31nB_x77_Mgl_vo,4545
331
- uk_bin_collection-0.143.5.dist-info/LICENSE,sha256=vABBUOzcrgfaTKpzeo-si9YVEun6juDkndqA8RKdKGs,1071
332
- uk_bin_collection-0.143.5.dist-info/METADATA,sha256=gAdCFPPQuB4BwHt34iRKHEYzzhwxjh-ULXZOMU0lMZY,19858
333
- uk_bin_collection-0.143.5.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
334
- uk_bin_collection-0.143.5.dist-info/entry_points.txt,sha256=36WCSGMWSc916S3Hi1ZkazzDKHaJ6CD-4fCEFm5MIao,90
335
- uk_bin_collection-0.143.5.dist-info/RECORD,,
332
+ uk_bin_collection-0.144.0.dist-info/LICENSE,sha256=vABBUOzcrgfaTKpzeo-si9YVEun6juDkndqA8RKdKGs,1071
333
+ uk_bin_collection-0.144.0.dist-info/METADATA,sha256=k-jkQ-brkbppOAbOHd39-gv751ReJOWBS72yj-zZSyI,19858
334
+ uk_bin_collection-0.144.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
335
+ uk_bin_collection-0.144.0.dist-info/entry_points.txt,sha256=36WCSGMWSc916S3Hi1ZkazzDKHaJ6CD-4fCEFm5MIao,90
336
+ uk_bin_collection-0.144.0.dist-info/RECORD,,