uk_bin_collection 0.144.3__py3-none-any.whl → 0.145.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.
@@ -126,11 +126,14 @@ class CouncilClass(AbstractGetBinDataClass):
126
126
 
127
127
  collections = []
128
128
  for bin in collection_data:
129
+ if not bin["collection"]:
130
+ continue # Skip if there are no collection dates
131
+
129
132
  bin_type = bin["containerName"]
130
133
  next_collection = datetime.strptime(
131
134
  bin["collection"][0]["nextCollectionDate"], "%Y-%m-%dT%H:%M:%S"
132
135
  ).strftime(date_format)
133
- # Could work out next date using the roundDescription and the is_holiday function in common.py
136
+
134
137
  collections.append((bin_type, next_collection))
135
138
 
136
139
  ordered_data = sorted(collections, key=lambda x: x[1])
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: uk_bin_collection
3
- Version: 0.144.3
3
+ Version: 0.145.0
4
4
  Summary: Python Lib to collect UK Bin Data
5
5
  Author: Robert Bradley
6
6
  Author-email: robbrad182@gmail.com
@@ -1,9 +1,11 @@
1
+ uk_bin_collection/Local_Authority_Boundaries.geojson,sha256=_j-hUiL0--t2ewd_s29-j7_AKRlhagRMmOhXyco-B6I,1175922
1
2
  uk_bin_collection/README.rst,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ uk_bin_collection/map.html,sha256=bBqCQkT4DjBeAL8hrjW5n8UHNxVUqc6XScpGMF60Vzw,3979
2
4
  uk_bin_collection/tests/check_selenium_url_in_input.json.py,sha256=Iecdja0I3XIiY76qmwPgcBqNgYv7n1-b5mg85JpMjg8,7817
3
5
  uk_bin_collection/tests/council_feature_input_parity.py,sha256=DO6Mk4ImYgM5ZCZ-cutwz5RoYYWZRLYx2tr6zIs_9Rc,3843
4
6
  uk_bin_collection/tests/features/environment.py,sha256=VQZjJdJI_kZn08M0j5cUgvKT4k3iTw8icJge1DGOkoA,127
5
7
  uk_bin_collection/tests/features/validate_council_outputs.feature,sha256=SJK-Vc737hrf03tssxxbeg_JIvAH-ddB8f6gU1LTbuQ,251
6
- uk_bin_collection/tests/input.json,sha256=zxDyP74ZRcogEGCcRCGeDj1EOU61mpQJXSsv8z5sznE,122869
8
+ uk_bin_collection/tests/input.json,sha256=iBYOKDe4fNStE1wgAS7Gzq-t1CRgSIGBPlejppkuARQ,132389
7
9
  uk_bin_collection/tests/output.schema,sha256=ZwKQBwYyTDEM4G2hJwfLUVM-5v1vKRvRK9W9SS1sd18,1086
8
10
  uk_bin_collection/tests/step_defs/step_helpers/file_handler.py,sha256=Ygzi4V0S1MIHqbdstUlIqtRIwnynvhu4UtpweJ6-5N8,1474
9
11
  uk_bin_collection/tests/step_defs/test_validate_council.py,sha256=VZ0a81sioJULD7syAYHjvK_-nT_Rd36tUyzPetSA0gk,3475
@@ -50,7 +52,7 @@ uk_bin_collection/uk_bin_collection/councils/BraintreeDistrictCouncil.py,sha256=
50
52
  uk_bin_collection/uk_bin_collection/councils/BrecklandCouncil.py,sha256=PX6A_pDvaN109aSNWmEhm88GFKfkClIkmbwGURWvsks,1744
51
53
  uk_bin_collection/uk_bin_collection/councils/BrentCouncil.py,sha256=ucwokxvASYi_KiOYSOVdaGfC1kfUbII0r6Zl2NE1hnU,4208
52
54
  uk_bin_collection/uk_bin_collection/councils/BrightonandHoveCityCouncil.py,sha256=k6qt4cds-Ejd97Z-__pw2BYvGVbFdc9SUfF73PPrTNA,5823
53
- uk_bin_collection/uk_bin_collection/councils/BristolCityCouncil.py,sha256=kJmmDJz_kQ45DHmG7ocrUpNJonEn0kuXYEDQyZaf9ks,5576
55
+ uk_bin_collection/uk_bin_collection/councils/BristolCityCouncil.py,sha256=nQeRBKrDcZE2m_EzjUBr9dJ5tcUdGcUuA5FcnLkbLr4,5575
54
56
  uk_bin_collection/uk_bin_collection/councils/BroadlandDistrictCouncil.py,sha256=aelqhh503dx6O2EEmC3AT5tnY39Dc53qcouH8T-mek8,7613
55
57
  uk_bin_collection/uk_bin_collection/councils/BromleyBoroughCouncil.py,sha256=dii85JLmYU1uMidCEsWVo3stTcq_QqyC65DxG8u1UmE,4302
56
58
  uk_bin_collection/uk_bin_collection/councils/BromsgroveDistrictCouncil.py,sha256=PUfxP8j5Oh9wFHkdjbrJzQli9UzMHZzwrZ2hkThrvhI,1781
@@ -148,7 +150,6 @@ uk_bin_collection/uk_bin_collection/councils/HighPeakCouncil.py,sha256=x7dfy8mdt
148
150
  uk_bin_collection/uk_bin_collection/councils/HighlandCouncil.py,sha256=GNxDU65QuZHV5va2IrKtcJ6TQoDdwmV03JvkVqOauP4,3291
149
151
  uk_bin_collection/uk_bin_collection/councils/Hillingdon.py,sha256=R1enDv5gjwCUT3HKgj8C87xWrwvrutAN6XLu5P7tef8,10532
150
152
  uk_bin_collection/uk_bin_collection/councils/HinckleyandBosworthBoroughCouncil.py,sha256=51vXTKrstfJhb7cLCcrsvA9qKCsptyNMZvy7ML9DasM,2344
151
- uk_bin_collection/uk_bin_collection/councils/HounslowCouncil.py,sha256=LXhJ47rujx7k3naz0tFiTT1l5k6gAYcVdekJN1t_HLY,4564
152
153
  uk_bin_collection/uk_bin_collection/councils/HullCityCouncil.py,sha256=UHcesBoctFVcXDYuwfag43KbcJcopkEDzJ-54NxtK0Q,1851
153
154
  uk_bin_collection/uk_bin_collection/councils/HuntingdonDistrictCouncil.py,sha256=dGyhhG6HRjQ2SPeiRwUPTGlk9dPIslagV2k0GjEOn1s,1587
154
155
  uk_bin_collection/uk_bin_collection/councils/IpswichBoroughCouncil.py,sha256=57lmDl_FprG68gUhKQYpOa1M2pudyb1utfoMhUXNwzs,2802
@@ -331,8 +332,8 @@ uk_bin_collection/uk_bin_collection/councils/YorkCouncil.py,sha256=I2kBYMlsD4bId
331
332
  uk_bin_collection/uk_bin_collection/councils/council_class_template/councilclasstemplate.py,sha256=EQWRhZ2pEejlvm0fPyOTsOHKvUZmPnxEYO_OWRGKTjs,1158
332
333
  uk_bin_collection/uk_bin_collection/create_new_council.py,sha256=m-IhmWmeWQlFsTZC4OxuFvtw5ZtB8EAJHxJTH4O59lQ,1536
333
334
  uk_bin_collection/uk_bin_collection/get_bin_data.py,sha256=YvmHfZqanwrJ8ToGch34x-L-7yPe31nB_x77_Mgl_vo,4545
334
- uk_bin_collection-0.144.3.dist-info/LICENSE,sha256=vABBUOzcrgfaTKpzeo-si9YVEun6juDkndqA8RKdKGs,1071
335
- uk_bin_collection-0.144.3.dist-info/METADATA,sha256=p836krZfbmZyZq_lEotYfXqB6JdLNtK3y6b4lhFIioM,19858
336
- uk_bin_collection-0.144.3.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
337
- uk_bin_collection-0.144.3.dist-info/entry_points.txt,sha256=36WCSGMWSc916S3Hi1ZkazzDKHaJ6CD-4fCEFm5MIao,90
338
- uk_bin_collection-0.144.3.dist-info/RECORD,,
335
+ uk_bin_collection-0.145.0.dist-info/LICENSE,sha256=vABBUOzcrgfaTKpzeo-si9YVEun6juDkndqA8RKdKGs,1071
336
+ uk_bin_collection-0.145.0.dist-info/METADATA,sha256=i1sbhdZWS2y7-LpV8I6K-p0VXiKA2OinNOuSPP-P3NM,19858
337
+ uk_bin_collection-0.145.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
338
+ uk_bin_collection-0.145.0.dist-info/entry_points.txt,sha256=36WCSGMWSc916S3Hi1ZkazzDKHaJ6CD-4fCEFm5MIao,90
339
+ uk_bin_collection-0.145.0.dist-info/RECORD,,
@@ -1,122 +0,0 @@
1
- import time
2
- from datetime import datetime
3
-
4
- from bs4 import BeautifulSoup
5
- from selenium.webdriver.common.by import By
6
- from selenium.webdriver.support import expected_conditions as EC
7
- from selenium.webdriver.support.ui import Select
8
- from selenium.webdriver.support.wait import WebDriverWait
9
- from selenium.webdriver.common.keys import Keys
10
-
11
- from uk_bin_collection.uk_bin_collection.common import *
12
- from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
13
-
14
-
15
- # import the wonderful Beautiful Soup and the URL grabber
16
- class CouncilClass(AbstractGetBinDataClass):
17
- """
18
- Concrete classes have to implement all abstract operations of the
19
- base class. They can also override some operations with a default
20
- implementation.
21
- """
22
-
23
- def parse_date(self, date_str):
24
- date_formats = [
25
- "This %A - %d %b %Y", # Changed %B to %b to accommodate abbreviated month names
26
- "Next %A - %d %b %Y", # Same change here
27
- "%A %d %b %Y", # And here
28
- ]
29
- for format in date_formats:
30
- try:
31
- return datetime.strptime(date_str, format).strftime("%d/%m/%Y")
32
- except ValueError:
33
- continue
34
- raise ValueError(f"Date format not recognized: {date_str}")
35
-
36
- def parse_data(self, page: str, **kwargs) -> dict:
37
- driver = None
38
- try:
39
- # Make a BS4 object
40
-
41
- page = "https://www.hounslow.gov.uk/info/20272/recycling_and_waste_collection_day_finder"
42
-
43
- user_postcode = kwargs.get("postcode")
44
- user_uprn = kwargs.get("uprn")
45
- user_paon = kwargs.get("paon")
46
- web_driver = kwargs.get("web_driver")
47
- headless = kwargs.get("headless")
48
-
49
- driver = create_webdriver(web_driver, headless, None, __name__)
50
- driver.get(page)
51
-
52
- wait = WebDriverWait(driver, 60)
53
-
54
- inputElement_postcodesearch = wait.until(
55
- EC.element_to_be_clickable((By.ID, "Postcode"))
56
- )
57
-
58
- inputElement_postcodesearch.send_keys(user_postcode)
59
-
60
- inputElement_postcodesearch_btn = wait.until(
61
- EC.element_to_be_clickable((By.ID, "findAddress"))
62
- )
63
- inputElement_postcodesearch_btn.click()
64
-
65
- inputElement_select_address = wait.until(
66
- EC.element_to_be_clickable((By.ID, "UPRN"))
67
- )
68
-
69
- select_element = wait.until(
70
- EC.visibility_of_element_located((By.ID, "UPRN"))
71
- ) # Adjust this ID to your element's ID
72
-
73
- # Create a Select object
74
- select = Select(select_element)
75
-
76
- # Fetch all options
77
- options = select.options
78
-
79
- # Loop through options to find the one that starts with the UPRN
80
- for option in options:
81
- if option.get_attribute("value").startswith(f"{user_uprn}|"):
82
- option.click() # Select the matching option
83
- break
84
-
85
- results = wait.until(
86
- EC.element_to_be_clickable((By.CLASS_NAME, "bin_day_main_wrapper"))
87
- )
88
-
89
- soup = BeautifulSoup(driver.page_source, features="html.parser")
90
- soup.prettify()
91
-
92
- # Find all headers which include collection dates
93
- collection_headers = soup.find_all("h4")
94
- bins_data = []
95
-
96
- # Process each collection date and corresponding bins
97
- for header in collection_headers:
98
- date_text = header.get_text(strip=True)
99
- collection_date = self.parse_date(date_text)
100
-
101
- # Get next sibling which should be the list of bins
102
- bin_list = header.find_next_sibling("ul")
103
- if bin_list:
104
- for item in bin_list.find_all("li", class_="list-group-item"):
105
- bin_type = item.get_text(strip=True)
106
- bins_data.append(
107
- {"type": bin_type, "collectionDate": collection_date}
108
- )
109
-
110
- # Construct the final JSON object
111
- json_data = {"bins": bins_data}
112
-
113
- except Exception as e:
114
- # Here you can log the exception if needed
115
- print(f"An error occurred: {e}")
116
- # Optionally, re-raise the exception if you want it to propagate
117
- raise
118
- finally:
119
- # This block ensures that the driver is closed regardless of an exception
120
- if driver:
121
- driver.quit()
122
- return json_data