uk_bin_collection 0.124.4__py3-none-any.whl → 0.125.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.
@@ -194,6 +194,15 @@
194
194
  "wiki_name": "Blackburn Council",
195
195
  "wiki_note": "You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find the UPRN."
196
196
  },
197
+ "BlaenauGwentCountyBoroughCouncil": {
198
+ "uprn": "100100471367",
199
+ "postcode": "NP23 7TE",
200
+ "skip_get_url": false,
201
+ "url": "https://www.blaenau-gwent.gov.uk",
202
+ "web_driver": "http://selenium:4444",
203
+ "wiki_name": "Blaenau Gwent County Borough Council",
204
+ "wiki_note": "You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find the UPRN."
205
+ },
197
206
  "BoltonCouncil": {
198
207
  "postcode": "BL1 5PQ",
199
208
  "skip_get_url": true,
@@ -1403,6 +1412,13 @@
1403
1412
  "wiki_name": "Reading Borough Council",
1404
1413
  "wiki_note": "Replace XXXXXXXX with your property's UPRN."
1405
1414
  },
1415
+ "RedditchBoroughCouncil": {
1416
+ "url": "https://redditchbc.gov.uk",
1417
+ "wiki_command_url_override": "https://redditchbc.gov.uk",
1418
+ "uprn": "10094557691",
1419
+ "wiki_name": "Redditch Borough Council",
1420
+ "wiki_note": "You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find the UPRN."
1421
+ },
1406
1422
  "ReigateAndBansteadBoroughCouncil": {
1407
1423
  "skip_get_url": true,
1408
1424
  "uprn": "68134867",
@@ -1904,6 +1920,13 @@
1904
1920
  "wiki_name": "Waltham Forest",
1905
1921
  "wiki_note": "Use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find your UPRN."
1906
1922
  },
1923
+ "WandsworthCouncil": {
1924
+ "url": "https://www.wandsworth.gov.uk",
1925
+ "wiki_command_url_override": "https://www.wandsworth.gov.uk",
1926
+ "uprn": "100022684035",
1927
+ "wiki_name": "Wandsworth Council",
1928
+ "wiki_note": "You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find the UPRN."
1929
+ },
1907
1930
  "WarringtonBoroughCouncil": {
1908
1931
  "url": "https://www.warrington.gov.uk",
1909
1932
  "wiki_command_url_override": "https://www.warrington.gov.uk",
@@ -0,0 +1,113 @@
1
+ from bs4 import BeautifulSoup
2
+ from selenium.webdriver.common.by import By
3
+ from selenium.webdriver.support import expected_conditions as EC
4
+ from selenium.webdriver.support.ui import Select
5
+ from selenium.webdriver.support.wait import WebDriverWait
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 parse_data(self, page: str, **kwargs) -> dict:
20
+ driver = None
21
+ try:
22
+ data = {"bins": []}
23
+ user_uprn = kwargs.get("uprn")
24
+ user_postcode = kwargs.get("postcode")
25
+ web_driver = kwargs.get("web_driver")
26
+ headless = kwargs.get("headless")
27
+ check_uprn(user_uprn)
28
+ check_postcode(user_postcode)
29
+
30
+ # Create Selenium webdriver
31
+ driver = create_webdriver(web_driver, headless, None, __name__)
32
+ driver.get(
33
+ "https://iportal.itouchvision.com/icollectionday/collection-day/?uuid=238D5F9796C12643D190E3505931401A8C003F0D&lang=en"
34
+ )
35
+
36
+ # Wait for the postcode field to appear then populate it
37
+ inputElement_postcode = WebDriverWait(driver, 10).until(
38
+ EC.presence_of_element_located((By.ID, "postcodeSearch"))
39
+ )
40
+ inputElement_postcode.send_keys(user_postcode)
41
+
42
+ # Click search button
43
+ findAddress = WebDriverWait(driver, 10).until(
44
+ EC.presence_of_element_located(
45
+ (By.XPATH, '//button[@class="govuk-button mt-4"]')
46
+ )
47
+ )
48
+ findAddress.click()
49
+
50
+ # Wait for the dropdown to be visible
51
+ WebDriverWait(driver, 10).until(
52
+ EC.presence_of_element_located((By.ID, "addressSelect"))
53
+ )
54
+
55
+ dropdown = Select(driver.find_element(By.ID, "addressSelect"))
56
+ dropdown.select_by_value(user_uprn)
57
+
58
+ # Wait for the collections table to appear
59
+ WebDriverWait(driver, 10).until(
60
+ EC.presence_of_element_located(
61
+ (
62
+ By.XPATH,
63
+ '//div[@class="ant-row d-flex justify-content-between mb-4 mt-2 css-2rgkd4"]',
64
+ )
65
+ )
66
+ )
67
+
68
+ soup = BeautifulSoup(driver.page_source, features="html.parser")
69
+
70
+ recyclingcalendar = soup.find(
71
+ "div",
72
+ {
73
+ "class": "ant-row d-flex justify-content-between mb-4 mt-2 css-2rgkd4"
74
+ },
75
+ )
76
+
77
+ rows = recyclingcalendar.find_all(
78
+ "div",
79
+ {
80
+ "class": "ant-col ant-col-xs-12 ant-col-sm-12 ant-col-md-12 ant-col-lg-12 ant-col-xl-12 css-2rgkd4"
81
+ },
82
+ )
83
+
84
+ current_year = datetime.now().year
85
+ current_month = datetime.now().month
86
+
87
+ for row in rows:
88
+ BinType = row.find("h3").text
89
+ collectiondate = datetime.strptime(
90
+ row.find("div", {"class": "text-white fw-bold"}).text,
91
+ "%A %d %B",
92
+ )
93
+ if (current_month > 10) and (collectiondate.month < 3):
94
+ collectiondate = collectiondate.replace(year=(current_year + 1))
95
+ else:
96
+ collectiondate = collectiondate.replace(year=current_year)
97
+
98
+ dict_data = {
99
+ "type": BinType,
100
+ "collectionDate": collectiondate.strftime("%d/%m/%Y"),
101
+ }
102
+ data["bins"].append(dict_data)
103
+
104
+ except Exception as e:
105
+ # Here you can log the exception if needed
106
+ print(f"An error occurred: {e}")
107
+ # Optionally, re-raise the exception if you want it to propagate
108
+ raise
109
+ finally:
110
+ # This block ensures that the driver is closed regardless of an exception
111
+ if driver:
112
+ driver.quit()
113
+ return data
@@ -43,6 +43,7 @@ class CouncilClass(AbstractGetBinDataClass):
43
43
  rows = table.find_all("tr")
44
44
 
45
45
  current_year = datetime.now().year
46
+ current_month = datetime.now().month
46
47
 
47
48
  # Process each row into a list of dictionaries
48
49
  for row in rows[1:]: # Skip the header row
@@ -56,7 +57,7 @@ class CouncilClass(AbstractGetBinDataClass):
56
57
  if collection_date_text:
57
58
  try:
58
59
  collection_date = datetime.strptime(collection_date_text, "%a %d %b")
59
- if collection_date.month == 1:
60
+ if collection_date.month == 1 and current_month != 1:
60
61
  collection_date = collection_date.replace(year=current_year + 1)
61
62
  else:
62
63
  collection_date = collection_date.replace(year=current_year)
@@ -42,14 +42,18 @@ class CouncilClass(AbstractGetBinDataClass):
42
42
  bin_type = service.get_text(
43
43
  strip=True
44
44
  ) # Bin type name (e.g., 'Food waste', 'Mixed recycling')
45
- if bin_type == "Bulky waste":
45
+ if bin_type == "Bulky Waste":
46
46
  continue
47
47
  service_details = service.find_next("div", class_="govuk-grid-row")
48
48
 
49
49
  next_collection = (
50
- service_details.find("dt", string="Next collection")
51
- .find_next_sibling("dd")
52
- .get_text(strip=True)
50
+ (
51
+ service_details.find("dt", string="Next collection")
52
+ .find_next_sibling("dd")
53
+ .get_text(strip=True)
54
+ )
55
+ .replace("(this collection has been adjusted from its usual time)", "")
56
+ .strip()
53
57
  )
54
58
 
55
59
  next_collection = datetime.strptime(
@@ -1,5 +1,6 @@
1
1
  # This script pulls (in one hit) the data from Merton Council Bins Data
2
2
  from bs4 import BeautifulSoup
3
+
3
4
  from uk_bin_collection.uk_bin_collection.common import *
4
5
  from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
5
6
 
@@ -33,6 +34,11 @@ class CouncilClass(AbstractGetBinDataClass):
33
34
  ),
34
35
  )
35
36
 
37
+ possible_formats = [
38
+ "%d %B %Y",
39
+ "%A %d %B %Y",
40
+ ]
41
+
36
42
  # Loops the Rows
37
43
  for row in rows:
38
44
  # Get all the cells
@@ -40,9 +46,15 @@ class CouncilClass(AbstractGetBinDataClass):
40
46
  # First cell is the bin_type
41
47
  bin_type = cells[0].get_text().strip()
42
48
  # Date is on the second cell, second paragraph, wrapped in p
43
- collectionDate = datetime.strptime(
44
- cells[1].select("p > b")[2].get_text(strip=True), "%d %B %Y"
45
- )
49
+ collectionDate = None
50
+ for date_format in possible_formats:
51
+ try:
52
+ collectionDate = datetime.strptime(
53
+ cells[1].select("p > b")[2].get_text(strip=True), date_format
54
+ )
55
+ break # Exit the loop if parsing is successful
56
+ except ValueError:
57
+ continue
46
58
 
47
59
  # Add each collection to the list as a tuple
48
60
  collections.append((bin_type, collectionDate))
@@ -0,0 +1,73 @@
1
+ import requests
2
+ from bs4 import BeautifulSoup
3
+
4
+ from uk_bin_collection.uk_bin_collection.common import *
5
+ from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
6
+
7
+
8
+ # import the wonderful Beautiful Soup and the URL grabber
9
+ class CouncilClass(AbstractGetBinDataClass):
10
+ """
11
+ Concrete classes have to implement all abstract operations of the
12
+ base class. They can also override some operations with a default
13
+ implementation.
14
+ """
15
+
16
+ def parse_data(self, page: str, **kwargs) -> dict:
17
+
18
+ user_uprn = kwargs.get("uprn")
19
+ check_uprn(user_uprn)
20
+ bindata = {"bins": []}
21
+
22
+ URI = "https://bincollections.redditchbc.gov.uk/BinCollections/Details"
23
+
24
+ data = {"UPRN": user_uprn}
25
+
26
+ # Make the GET request
27
+ response = requests.post(URI, data=data)
28
+
29
+ # Parse the HTML
30
+ soup = BeautifulSoup(response.content, "html.parser")
31
+
32
+ # Find all collection containers
33
+ collection_containers = soup.find_all("div", class_="collection-container")
34
+
35
+ # Parse each collection container
36
+ for container in collection_containers:
37
+ # Extract bin type (from heading or image alt attribute)
38
+ bin_type = container.find("img")["alt"]
39
+
40
+ # Extract the next collection date (from the caption paragraph)
41
+ next_collection = (
42
+ container.find("p", class_="caption")
43
+ .text.replace("Next collection ", "")
44
+ .strip()
45
+ )
46
+
47
+ # Extract additional future collection dates (from the list items)
48
+ future_dates = [li.text.strip() for li in container.find_all("li")]
49
+
50
+ dict_data = {
51
+ "type": bin_type,
52
+ "collectionDate": datetime.strptime(
53
+ next_collection,
54
+ "%A, %d %B %Y",
55
+ ).strftime("%d/%m/%Y"),
56
+ }
57
+ bindata["bins"].append(dict_data)
58
+
59
+ for date in future_dates: # Add to the schedule
60
+ dict_data = {
61
+ "type": bin_type,
62
+ "collectionDate": datetime.strptime(
63
+ date,
64
+ "%A, %d %B %Y",
65
+ ).strftime("%d/%m/%Y"),
66
+ }
67
+ bindata["bins"].append(dict_data)
68
+
69
+ bindata["bins"].sort(
70
+ key=lambda x: datetime.strptime(x.get("collectionDate"), "%d/%m/%Y")
71
+ )
72
+
73
+ return bindata
@@ -1,6 +1,7 @@
1
1
  from datetime import datetime
2
2
 
3
3
  from bs4 import BeautifulSoup
4
+
4
5
  from uk_bin_collection.uk_bin_collection.common import *
5
6
  from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
6
7
 
@@ -14,20 +15,20 @@ class CouncilClass(AbstractGetBinDataClass):
14
15
  """
15
16
 
16
17
  def parse_data(self, page: str, **kwargs) -> dict:
17
- api_url = "https://www.salford.gov.uk/bins-and-recycling/bin-collection-days/your-bin-collections"
18
18
  user_uprn = kwargs.get("uprn")
19
-
20
19
  # Check the UPRN is valid
21
20
  check_uprn(user_uprn)
22
21
 
23
- # Create the form data
24
- params = {
25
- "UPRN": user_uprn,
22
+ api_url = f"https://www.salford.gov.uk/bins-and-recycling/bin-collection-days/your-bin-collections/?UPRN={user_uprn}"
23
+
24
+ headers = {
25
+ "User-Agent": "Mozilla/5.0",
26
+ "Referer": "https://www.salford.gov.uk/bins-and-recycling/bin-collection-days/",
26
27
  }
27
28
 
28
29
  # Make a request to the API
29
30
  requests.packages.urllib3.disable_warnings()
30
- response = requests.get(api_url, params=params)
31
+ response = requests.get(api_url, headers=headers)
31
32
 
32
33
  # Make a BS4 object
33
34
  soup = BeautifulSoup(response.text, features="html.parser")
@@ -26,7 +26,7 @@ class CouncilClass(AbstractGetBinDataClass):
26
26
  check_paon(user_paon)
27
27
 
28
28
  # Build URL to parse
29
- council_url = "https://swale.gov.uk/bins-littering-and-the-environment/bins/my-collection-day"
29
+ council_url = "https://swale.gov.uk/bins-littering-and-the-environment/bins/check-your-bin-day"
30
30
 
31
31
  # Create Selenium webdriver
32
32
  driver = create_webdriver(web_driver, headless, None, __name__)
@@ -35,7 +35,7 @@ class CouncilClass(AbstractGetBinDataClass):
35
35
  # Wait for the postcode field to appear then populate it
36
36
  try:
37
37
  inputElement_postcode = WebDriverWait(driver, 10).until(
38
- EC.presence_of_element_located((By.ID, "q462406_q1"))
38
+ EC.presence_of_element_located((By.ID, "q485476_q1"))
39
39
  )
40
40
  inputElement_postcode.send_keys(user_postcode)
41
41
  except Exception:
@@ -43,7 +43,7 @@ class CouncilClass(AbstractGetBinDataClass):
43
43
 
44
44
  # Click search button
45
45
  findAddress = WebDriverWait(driver, 10).until(
46
- EC.presence_of_element_located((By.ID, "form_email_462397_submit"))
46
+ EC.presence_of_element_located((By.ID, "form_email_485465_submit"))
47
47
  )
48
48
  driver.execute_script("arguments[0].click();", findAddress)
49
49
 
@@ -52,7 +52,7 @@ class CouncilClass(AbstractGetBinDataClass):
52
52
  EC.element_to_be_clickable(
53
53
  (
54
54
  By.XPATH,
55
- "//select[@id='SBCYBDAddressList']//option[contains(., '"
55
+ "//select[@name='q485480:q1']//option[contains(., '"
56
56
  + user_paon
57
57
  + "')]",
58
58
  )
@@ -61,12 +61,12 @@ class CouncilClass(AbstractGetBinDataClass):
61
61
 
62
62
  # Click search button
63
63
  getBins = WebDriverWait(driver, 10).until(
64
- EC.presence_of_element_located((By.ID, "form_email_462397_submit"))
64
+ EC.presence_of_element_located((By.ID, "form_email_485465_submit"))
65
65
  )
66
66
  driver.execute_script("arguments[0].click();", getBins)
67
67
 
68
68
  BinTable = WebDriverWait(driver, 30).until(
69
- EC.presence_of_element_located((By.ID, "SBC-YBD-Main"))
69
+ EC.presence_of_element_located((By.ID, "SBCYBDSummary"))
70
70
  )
71
71
 
72
72
  soup = BeautifulSoup(driver.page_source, features="html.parser")
@@ -74,17 +74,41 @@ class CouncilClass(AbstractGetBinDataClass):
74
74
 
75
75
  data = {"bins": []}
76
76
 
77
- # Get the collection bullet points on the page and parse them
78
- nextCollections = soup.find("div", {"id": "nextCollections"})
79
- for c in nextCollections:
80
- collection = c.find_all("strong")
81
- for bin in collection:
82
- split = (bin.text).split(" on ")
83
- bin_type = split[0]
84
- bin_date = datetime.strptime(split[1], "%A %d %b %Y").strftime(
85
- "%d/%m/%Y"
86
- )
87
- dict_data = {"type": bin_type, "collectionDate": bin_date}
88
- data["bins"].append(dict_data)
77
+ next_collection_date = soup.find(
78
+ "strong", id="SBC-YBD-collectionDate"
79
+ ).text.strip()
80
+
81
+ # Extract bins for the next collection
82
+ next_bins = [li.text.strip() for li in soup.select("#SBCFirstBins ul li")]
83
+
84
+ # Extract future collection details
85
+ future_collection_date_tag = soup.find(
86
+ "p", text=lambda t: t and "starting from" in t
87
+ )
88
+ future_collection_date = (
89
+ future_collection_date_tag.text.split("starting from")[-1].strip()
90
+ if future_collection_date_tag
91
+ else "No future date found"
92
+ )
93
+
94
+ future_bins = [li.text.strip() for li in soup.select("#FirstFutureBins li")]
95
+
96
+ for bin in next_bins:
97
+ dict_data = {
98
+ "type": bin,
99
+ "collectionDate": datetime.strptime(
100
+ next_collection_date, "%A, %d %B"
101
+ ).strftime(date_format),
102
+ }
103
+ data["bins"].append(dict_data)
104
+
105
+ for bin in future_bins:
106
+ dict_data = {
107
+ "type": bin,
108
+ "collectionDate": datetime.strptime(
109
+ future_collection_date, "%A, %d %B"
110
+ ).strftime(date_format),
111
+ }
112
+ data["bins"].append(dict_data)
89
113
 
90
114
  return data
@@ -0,0 +1,74 @@
1
+ import requests
2
+ from bs4 import BeautifulSoup
3
+
4
+ from uk_bin_collection.uk_bin_collection.common import *
5
+ from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
6
+
7
+
8
+ # import the wonderful Beautiful Soup and the URL grabber
9
+ class CouncilClass(AbstractGetBinDataClass):
10
+ """
11
+ Concrete classes have to implement all abstract operations of the
12
+ base class. They can also override some operations with a default
13
+ implementation.
14
+ """
15
+
16
+ def parse_data(self, page: str, **kwargs) -> dict:
17
+
18
+ user_uprn = kwargs.get("uprn")
19
+ check_uprn(user_uprn)
20
+ bindata = {"bins": []}
21
+
22
+ URI = f"https://www.wandsworth.gov.uk/my-property/?UPRN={user_uprn}"
23
+
24
+ # Make the GET request
25
+ response = requests.get(URI)
26
+
27
+ soup = BeautifulSoup(response.content, features="html.parser")
28
+ soup.prettify()
29
+
30
+ # Find all collection types
31
+ collection_types = soup.find_all("h4", class_="collection-heading")
32
+
33
+ # Iterate over each collection type
34
+ for collection_type in collection_types:
35
+ bin_types = collection_type.text.strip().split("/")
36
+ collections = collection_type.find_next_sibling("div", class_="collections")
37
+
38
+ # Extract next and previous collections
39
+ next_collection = collections.find_all("div", class_="collection")
40
+
41
+ # Parse each collection
42
+ for collection in next_collection:
43
+ # Extract the collection type (Next or Previous)
44
+ strong_tag = collection.find("strong")
45
+ collection_type = (
46
+ strong_tag.text.strip(":") if strong_tag else "Unknown"
47
+ )
48
+
49
+ # Extract the date
50
+ date_text = (
51
+ strong_tag.next_sibling.strip()
52
+ if strong_tag and strong_tag.next_sibling
53
+ else "No date found"
54
+ )
55
+
56
+ if date_text == "No date found":
57
+ continue
58
+
59
+ for bin_type in bin_types:
60
+ # Append to the schedule
61
+ dict_data = {
62
+ "type": bin_type,
63
+ "collectionDate": datetime.strptime(
64
+ date_text,
65
+ "%A %d %B %Y",
66
+ ).strftime(date_format),
67
+ }
68
+ bindata["bins"].append(dict_data)
69
+
70
+ bindata["bins"].sort(
71
+ key=lambda x: datetime.strptime(x.get("collectionDate"), date_format)
72
+ )
73
+
74
+ return bindata
@@ -25,6 +25,7 @@ class CouncilClass(AbstractGetBinDataClass):
25
25
  check_postcode(user_postcode)
26
26
  user_uprn = kwargs.get("uprn")
27
27
  check_uprn(user_uprn)
28
+ user_uprn = str(user_uprn).zfill(12)
28
29
 
29
30
  # Some data for the request
30
31
  cookies = {
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: uk_bin_collection
3
- Version: 0.124.4
3
+ Version: 0.125.1
4
4
  Summary: Python Lib to collect UK Bin Data
5
5
  Author: Robert Bradley
6
6
  Author-email: robbrad182@gmail.com
@@ -2,7 +2,7 @@ uk_bin_collection/README.rst,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
2
2
  uk_bin_collection/tests/council_feature_input_parity.py,sha256=DO6Mk4ImYgM5ZCZ-cutwz5RoYYWZRLYx2tr6zIs_9Rc,3843
3
3
  uk_bin_collection/tests/features/environment.py,sha256=VQZjJdJI_kZn08M0j5cUgvKT4k3iTw8icJge1DGOkoA,127
4
4
  uk_bin_collection/tests/features/validate_council_outputs.feature,sha256=SJK-Vc737hrf03tssxxbeg_JIvAH-ddB8f6gU1LTbuQ,251
5
- uk_bin_collection/tests/input.json,sha256=tHHO48XXBiy9Hiu9g30fiYRtaFmF5LGAxxoUT2uMLT4,111879
5
+ uk_bin_collection/tests/input.json,sha256=qDLpDG3LuoOhCLAevSKI4FrALTaLu6IHzmiAv827Jqk,112991
6
6
  uk_bin_collection/tests/output.schema,sha256=ZwKQBwYyTDEM4G2hJwfLUVM-5v1vKRvRK9W9SS1sd18,1086
7
7
  uk_bin_collection/tests/step_defs/step_helpers/file_handler.py,sha256=Ygzi4V0S1MIHqbdstUlIqtRIwnynvhu4UtpweJ6-5N8,1474
8
8
  uk_bin_collection/tests/step_defs/test_validate_council.py,sha256=VZ0a81sioJULD7syAYHjvK_-nT_Rd36tUyzPetSA0gk,3475
@@ -37,6 +37,7 @@ uk_bin_collection/uk_bin_collection/councils/BexleyCouncil.py,sha256=wqqCQZzu_q_
37
37
  uk_bin_collection/uk_bin_collection/councils/BirminghamCityCouncil.py,sha256=now2xgpfshYM33UWC18j6xa6BuBydO5Sl7OrDQOo6b0,4687
38
38
  uk_bin_collection/uk_bin_collection/councils/BlabyDistrictCouncil.py,sha256=xqWkQz3HDLkP5TgxQqVJziHJF2yl-q9PcV3Rv-38xDU,1941
39
39
  uk_bin_collection/uk_bin_collection/councils/BlackburnCouncil.py,sha256=ZLA2V3qPsJTom7SeQdGDhF4tJSfgIV5Qi202QvGKJZ0,4477
40
+ uk_bin_collection/uk_bin_collection/councils/BlaenauGwentCountyBoroughCouncil.py,sha256=C5Fi19t5HJcrOHhWnt_6pttgRL2IWIYnwYlF9MdSPR0,4330
40
41
  uk_bin_collection/uk_bin_collection/councils/BoltonCouncil.py,sha256=WI68r8jB0IHPUT4CgmZMtng899AAMFTxkyTdPg9yLF8,4117
41
42
  uk_bin_collection/uk_bin_collection/councils/BracknellForestCouncil.py,sha256=Llo1rULaAZ8rChVYZqXFFLo7CN6vbT0ULUJD6ActouY,9015
42
43
  uk_bin_collection/uk_bin_collection/councils/BradfordMDC.py,sha256=BEWS2c62cOsf26jqn1AkNUvVmc5AlUADYLaQuPn9RY4,5456
@@ -46,7 +47,7 @@ uk_bin_collection/uk_bin_collection/councils/BrightonandHoveCityCouncil.py,sha25
46
47
  uk_bin_collection/uk_bin_collection/councils/BristolCityCouncil.py,sha256=kJmmDJz_kQ45DHmG7ocrUpNJonEn0kuXYEDQyZaf9ks,5576
47
48
  uk_bin_collection/uk_bin_collection/councils/BromleyBoroughCouncil.py,sha256=_bAFykZWZkEVUB-QKeVLfWO8plG6nRgn71QF2BUN2rk,4329
48
49
  uk_bin_collection/uk_bin_collection/councils/BromsgroveDistrictCouncil.py,sha256=PUfxP8j5Oh9wFHkdjbrJzQli9UzMHZzwrZ2hkThrvhI,1781
49
- uk_bin_collection/uk_bin_collection/councils/BroxbourneCouncil.py,sha256=XCKjkypptrWE-pTkaWekDiZu9BCzDrDa-8he88BopMY,2852
50
+ uk_bin_collection/uk_bin_collection/councils/BroxbourneCouncil.py,sha256=NR1FoxLF0Ne61cJJmlVJhGfxjZ2sj60aLlOHBWWxtrM,2921
50
51
  uk_bin_collection/uk_bin_collection/councils/BroxtoweBoroughCouncil.py,sha256=-Facq-ToQkcWUePpKBwq90LZUFxgUSydNL2sYaLX4yw,4473
51
52
  uk_bin_collection/uk_bin_collection/councils/BuckinghamshireCouncil.py,sha256=_ELVUM5VLp1nwDxRpvpsp6n8SzLJvp_UyMp-i_MXYuo,4383
52
53
  uk_bin_collection/uk_bin_collection/councils/BurnleyBoroughCouncil.py,sha256=GJf1OPvUVj3vqsR3KjG0DFHZrSBu4ogIz_MJeVV8tNA,3192
@@ -145,13 +146,13 @@ uk_bin_collection/uk_bin_collection/councils/LondonBoroughHounslow.py,sha256=UOe
145
146
  uk_bin_collection/uk_bin_collection/councils/LondonBoroughLambeth.py,sha256=r9D5lHe5kIRStCd5lRIax16yhb4KTFzzfYEFv1bacWw,2009
146
147
  uk_bin_collection/uk_bin_collection/councils/LondonBoroughLewisham.py,sha256=d8rlJDTbY3nj-Zjg6iwvwfe-X13Gq86DGGW6QkQAUW0,5310
147
148
  uk_bin_collection/uk_bin_collection/councils/LondonBoroughRedbridge.py,sha256=A_6Sis5hsF53Th04KeadHRasGbpAm6aoaWJ6X8eC4Y8,6604
148
- uk_bin_collection/uk_bin_collection/councils/LondonBoroughSutton.py,sha256=c2haHOwX7Dy1phVUTv3xaQgM9VeHmFuBwdAgqGcGs8Y,2369
149
+ uk_bin_collection/uk_bin_collection/councils/LondonBoroughSutton.py,sha256=GAE51GfLk6lBWBiHzon7Egvlcds63bL_nK2jBlAMzs8,2530
149
150
  uk_bin_collection/uk_bin_collection/councils/LutonBoroughCouncil.py,sha256=vScUi_R8FnBddii2_zLlZBLxuh85mKmCm8nKW3zxky0,2758
150
151
  uk_bin_collection/uk_bin_collection/councils/MaldonDistrictCouncil.py,sha256=PMVt2XFggttPmbWyrBrHJ-W6R_6-0ux1BkY1kj1IKzg,1997
151
152
  uk_bin_collection/uk_bin_collection/councils/MalvernHillsDC.py,sha256=iQG0EkX2npBicvsGKQRYyBGSBvKVUbKvUvvwrC9xV1A,2100
152
153
  uk_bin_collection/uk_bin_collection/councils/ManchesterCityCouncil.py,sha256=RY301_82z3-xInGai5ocT7rzoV75ATbf0N7uxn8Z9LE,3110
153
154
  uk_bin_collection/uk_bin_collection/councils/MansfieldDistrictCouncil.py,sha256=F5AiTxImrnjE1k3ry96bfstOf5XSNBJS_4qqmymmh3w,1386
154
- uk_bin_collection/uk_bin_collection/councils/MertonCouncil.py,sha256=3Y2Un4xXo1sCcMsudynODSzocV_mMofWkX2JqONDb5o,1997
155
+ uk_bin_collection/uk_bin_collection/councils/MertonCouncil.py,sha256=VGN4L7rq9D_nJ7i15aMioyZsoiA0Bu0RhZToBiajkr0,2350
155
156
  uk_bin_collection/uk_bin_collection/councils/MidAndEastAntrimBoroughCouncil.py,sha256=oOWwU5FSgGej2Mv7FQ66N-EzS5nZgmGsd0WnfLWUc1I,5238
156
157
  uk_bin_collection/uk_bin_collection/councils/MidDevonCouncil.py,sha256=RjBZ7R3_Pax9p1d2DCygqryjV1RP4BYvqb-rT_KyOEg,3322
157
158
  uk_bin_collection/uk_bin_collection/councils/MidSuffolkDistrictCouncil.py,sha256=h6M-v5jVYe7OlQ47Vf-0pEgECZLOOacK3_XE6zbpsM4,6329
@@ -193,6 +194,7 @@ uk_bin_collection/uk_bin_collection/councils/PortsmouthCityCouncil.py,sha256=xog
193
194
  uk_bin_collection/uk_bin_collection/councils/PowysCouncil.py,sha256=E6AGmbU3GfmScrpS-hrnCz4uOwucmckq4R-hLmq80b8,5004
194
195
  uk_bin_collection/uk_bin_collection/councils/PrestonCityCouncil.py,sha256=3Nuin2hQsiEsbJR_kHldtzRhzmnPFctH7C7MFG7thj8,3838
195
196
  uk_bin_collection/uk_bin_collection/councils/ReadingBoroughCouncil.py,sha256=ZlQjU0IeKylGE9VlivSMh4XKwoLgntESPiylSOYkuD4,1009
197
+ uk_bin_collection/uk_bin_collection/councils/RedditchBoroughCouncil.py,sha256=8QmcpStCT7c-CLhmiQ8ZeEyvtysU110VDiMQdfQTErk,2469
196
198
  uk_bin_collection/uk_bin_collection/councils/ReigateAndBansteadBoroughCouncil.py,sha256=HMLKdRUO5DdMJe1d1X5qtKtQsf6d5TAPViIZpMzAfes,3251
197
199
  uk_bin_collection/uk_bin_collection/councils/RenfrewshireCouncil.py,sha256=VlWm-w4d-UchoENe_hCTCGlfSHiMlS4wNEeMvxuNR2U,5109
198
200
  uk_bin_collection/uk_bin_collection/councils/RhonddaCynonTaffCouncil.py,sha256=wInyVG_0wRrX_dRO9qbAzPhlXDseXapj2zQhsISw8gg,3233
@@ -204,7 +206,7 @@ uk_bin_collection/uk_bin_collection/councils/RoyalBoroughofGreenwich.py,sha256=B
204
206
  uk_bin_collection/uk_bin_collection/councils/RugbyBoroughCouncil.py,sha256=a5ySLmFvvY56QMA7-bk6MVBxRp5tPBIBg4navH0eYas,4306
205
207
  uk_bin_collection/uk_bin_collection/councils/RushcliffeBoroughCouncil.py,sha256=wMtiYRirT585vtsEOIyXHugk7aEj3pvyVWBaAePdqtE,4005
206
208
  uk_bin_collection/uk_bin_collection/councils/RushmoorCouncil.py,sha256=ZsGnXjoEaOS6U7fI0w7-uqxayAHdNVKsJi2fqIWEls8,3375
207
- uk_bin_collection/uk_bin_collection/councils/SalfordCityCouncil.py,sha256=jJjAH_dM298VIJ4-SEy7agxUe8aFJ_sEPK_ZwmWJ9cE,2506
209
+ uk_bin_collection/uk_bin_collection/councils/SalfordCityCouncil.py,sha256=XUGemp2cdzsvkWjnv2m4YKTMcoKDUfIlVy3YucX-_o4,2601
208
210
  uk_bin_collection/uk_bin_collection/councils/SandwellBoroughCouncil.py,sha256=shJhvqDcha2ypDCSfhss59G95jNaWBuMnVIxJiZXcY8,3110
209
211
  uk_bin_collection/uk_bin_collection/councils/SeftonCouncil.py,sha256=XUEz2li0oHrRhdkls5qzlZNZ0GuwSG7r0dwsL-qdoFA,2480
210
212
  uk_bin_collection/uk_bin_collection/councils/SevenoaksDistrictCouncil.py,sha256=qqrrRaSVm9CYAtm0rB2ZnyH_nLwaReuacoUxZpo597k,4260
@@ -236,7 +238,7 @@ uk_bin_collection/uk_bin_collection/councils/StokeOnTrentCityCouncil.py,sha256=K
236
238
  uk_bin_collection/uk_bin_collection/councils/StratfordUponAvonCouncil.py,sha256=DMTAcXT_lay8Cl1hBbzf_LN7-GwTDGxT3Ug9QJkaF9Y,3936
237
239
  uk_bin_collection/uk_bin_collection/councils/StroudDistrictCouncil.py,sha256=9bYWppi7ViLGHL4VEg--nFn28MLYJYbiEntull1uZxU,3561
238
240
  uk_bin_collection/uk_bin_collection/councils/SunderlandCityCouncil.py,sha256=4DnKyyu56_AwuchD6_oL1dvpDStMvkkxQtYN79rUKOs,3825
239
- uk_bin_collection/uk_bin_collection/councils/SwaleBoroughCouncil.py,sha256=ak0zqBJ6UAS8_t5zKGwigMxPMdlQuYXRsGCQJCNERJs,3415
241
+ uk_bin_collection/uk_bin_collection/councils/SwaleBoroughCouncil.py,sha256=wxoUAaeng1pf9nJ3Q12Xthcz0_LoS7SI86y0Hfv8hsM,4107
240
242
  uk_bin_collection/uk_bin_collection/councils/SwanseaCouncil.py,sha256=nmVPoPhnFgVi--vczX2i4Sf3bqM5RWJuwfhioRUr5XE,2303
241
243
  uk_bin_collection/uk_bin_collection/councils/SwindonBoroughCouncil.py,sha256=lSIykpkBjVwQSf3rrnrNuh7YRepgnkKQLbf1iErMuJs,1932
242
244
  uk_bin_collection/uk_bin_collection/councils/TamesideMBCouncil.py,sha256=k2TAAZG7n2S1BWVyxbE_-4-lZuzhOimCNz4yimUCOGk,1995
@@ -258,6 +260,7 @@ uk_bin_collection/uk_bin_collection/councils/ValeofWhiteHorseCouncil.py,sha256=K
258
260
  uk_bin_collection/uk_bin_collection/councils/WakefieldCityCouncil.py,sha256=vRfIU0Uloi1bgXqjOCpdb-EQ4oY-aismcANZRwOIFkc,4914
259
261
  uk_bin_collection/uk_bin_collection/councils/WalsallCouncil.py,sha256=_anovUnXMr40lZLHyX3opIP73BwauCllKy-Z2SBrzPw,2076
260
262
  uk_bin_collection/uk_bin_collection/councils/WalthamForest.py,sha256=P7MMw0EhpRmDbbnHb25tY5_yvYuZUFwJ1br4TOv24sY,4997
263
+ uk_bin_collection/uk_bin_collection/councils/WandsworthCouncil.py,sha256=aQoJpC7YkhKewQyZlsv5m4__2IPoKRsOrPxjNH5xRNo,2594
261
264
  uk_bin_collection/uk_bin_collection/councils/WarringtonBoroughCouncil.py,sha256=AB9mrV1v4pKKhfsBS8MpjO8XXBifqojSk53J9Q74Guk,1583
262
265
  uk_bin_collection/uk_bin_collection/councils/WarwickDistrictCouncil.py,sha256=DAL_f0BcIxFj7Ngkms5Q80kgSGp9y5zB35wRPudayz8,1644
263
266
  uk_bin_collection/uk_bin_collection/councils/WatfordBoroughCouncil.py,sha256=zFkXmF1X5g8pjv7II_jXBdrHJu16gy_PowVWVdaDg7A,2657
@@ -273,7 +276,7 @@ uk_bin_collection/uk_bin_collection/councils/WestNorthamptonshireCouncil.py,sha2
273
276
  uk_bin_collection/uk_bin_collection/councils/WestOxfordshireDistrictCouncil.py,sha256=bkE7BUwRIEJQyfOHyXYeaJB1ruGTFu9LHIGursIBEIQ,4859
274
277
  uk_bin_collection/uk_bin_collection/councils/WestSuffolkCouncil.py,sha256=9i8AQHh-qIRPZ_5Ad97_h04-qgyLQDPV064obBzab1Y,2587
275
278
  uk_bin_collection/uk_bin_collection/councils/WiganBoroughCouncil.py,sha256=3gqFA4-BVx_In6QOu3KUNqPN4Fkn9iMlZTeopMK9p6A,3746
276
- uk_bin_collection/uk_bin_collection/councils/WiltshireCouncil.py,sha256=it2Oh5Kmq3lD30gAZgk2bzZPNCtJcFHyQO1NgOQtfvU,5653
279
+ uk_bin_collection/uk_bin_collection/councils/WiltshireCouncil.py,sha256=Q0ooHTQb9ynMXpSNBPk7XXEjI7zcHst3id4wxGdmVx4,5698
277
280
  uk_bin_collection/uk_bin_collection/councils/WinchesterCityCouncil.py,sha256=W2k00N5n9-1MzjMEqsNjldsQdOJPEPMjK7OGSinZm5Y,4335
278
281
  uk_bin_collection/uk_bin_collection/councils/WindsorAndMaidenheadCouncil.py,sha256=7Qhznj95ktAQjpWm5C8pbD5UcvfXm7Mwb7_DQxwjGSM,1777
279
282
  uk_bin_collection/uk_bin_collection/councils/WirralCouncil.py,sha256=X_e9zXEZAl_Mp6nPORHc9CTmf3QHdoMY3BCnKrXEr1I,2131
@@ -288,8 +291,8 @@ uk_bin_collection/uk_bin_collection/councils/YorkCouncil.py,sha256=I2kBYMlsD4bId
288
291
  uk_bin_collection/uk_bin_collection/councils/council_class_template/councilclasstemplate.py,sha256=EQWRhZ2pEejlvm0fPyOTsOHKvUZmPnxEYO_OWRGKTjs,1158
289
292
  uk_bin_collection/uk_bin_collection/create_new_council.py,sha256=m-IhmWmeWQlFsTZC4OxuFvtw5ZtB8EAJHxJTH4O59lQ,1536
290
293
  uk_bin_collection/uk_bin_collection/get_bin_data.py,sha256=YvmHfZqanwrJ8ToGch34x-L-7yPe31nB_x77_Mgl_vo,4545
291
- uk_bin_collection-0.124.4.dist-info/LICENSE,sha256=vABBUOzcrgfaTKpzeo-si9YVEun6juDkndqA8RKdKGs,1071
292
- uk_bin_collection-0.124.4.dist-info/METADATA,sha256=DJLmg9nkpSRc5KKaksBtHOjjgTb2kVZUxdsuz0LAKcU,17574
293
- uk_bin_collection-0.124.4.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
294
- uk_bin_collection-0.124.4.dist-info/entry_points.txt,sha256=36WCSGMWSc916S3Hi1ZkazzDKHaJ6CD-4fCEFm5MIao,90
295
- uk_bin_collection-0.124.4.dist-info/RECORD,,
294
+ uk_bin_collection-0.125.1.dist-info/LICENSE,sha256=vABBUOzcrgfaTKpzeo-si9YVEun6juDkndqA8RKdKGs,1071
295
+ uk_bin_collection-0.125.1.dist-info/METADATA,sha256=RqQZJY1B8okVHVvD-cb2gifYlxj1PEc_OoR60DY-LCc,17574
296
+ uk_bin_collection-0.125.1.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
297
+ uk_bin_collection-0.125.1.dist-info/entry_points.txt,sha256=36WCSGMWSc916S3Hi1ZkazzDKHaJ6CD-4fCEFm5MIao,90
298
+ uk_bin_collection-0.125.1.dist-info/RECORD,,