uk_bin_collection 0.152.4__py3-none-any.whl → 0.152.6__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.
@@ -79,12 +79,9 @@ class CouncilClass(AbstractGetBinDataClass):
79
79
  next_button.click()
80
80
 
81
81
  # Wait for the bin collection content to load
82
- collection_content = WebDriverWait(driver, 10).until(
83
- EC.presence_of_element_located(
84
- (
85
- By.XPATH,
86
- '//*[@id="mats_content_wrapper"]/div[2]/div[2]/div[2]/div/div[1]/div/div[3]/div/div/div/div',
87
- )
82
+ listing_records = WebDriverWait(driver, 10).until(
83
+ EC.presence_of_all_elements_located(
84
+ (By.CSS_SELECTOR, "#mats_content_wrapper .listing_template_record")
88
85
  )
89
86
  )
90
87
 
@@ -16,6 +16,7 @@ class CouncilClass(AbstractGetBinDataClass):
16
16
  def parse_data(self, page: str, **kwargs) -> dict:
17
17
 
18
18
  user_uprn = kwargs.get("uprn")
19
+ postcode = kwargs.get("postcode")
19
20
  check_uprn(user_uprn)
20
21
  bindata = {"bins": []}
21
22
 
@@ -57,6 +58,7 @@ class CouncilClass(AbstractGetBinDataClass):
57
58
  "TriggerCtl": "",
58
59
  "FF265": f"U{user_uprn}",
59
60
  "FF265lbltxt": "Please select your address",
61
+ "FF265-text": postcode
60
62
  }
61
63
 
62
64
  # print(payload)
@@ -51,7 +51,7 @@ class CouncilClass(AbstractGetBinDataClass):
51
51
  if row.find("dt").get_text().strip().lower() == "next collection":
52
52
  collection_date = remove_ordinal_indicator_from_date_string(
53
53
  row.find("dd").get_text()
54
- ).strip()
54
+ ).strip().replace(" (In progress)", "")
55
55
  # strip out any text inside of the date string
56
56
  collection_date = re.sub(
57
57
  r"\n\s*\(this.*?\)", "", collection_date
@@ -151,7 +151,7 @@ class CouncilClass(AbstractGetBinDataClass):
151
151
 
152
152
  # Looking for bin types in the exact HTML structure
153
153
  bin_type_elements = soup.select(
154
- "div.formatting_bold.formatting_size_bigger.formatting span.value-as-text"
154
+ "div.page_cell.contains_widget:first-of-type div.formatting_bold.formatting_size_bigger.formatting span.value-as-text"
155
155
  )
156
156
  # print(f"Found {len(bin_type_elements)} bin type elements")
157
157
 
@@ -21,8 +21,8 @@ class CouncilClass(AbstractGetBinDataClass):
21
21
  check_postcode(user_postcode)
22
22
  bindata = {"bins": []}
23
23
 
24
- session_uri = "https://www.oxford.gov.uk/mybinday"
25
- URI = "https://www.oxford.gov.uk/xfp/form/142"
24
+ session_uri = "https://www.oxford.gov.uk/xfp/form/142"
25
+ URI = "https://www.oxford.gov.uk/xfp/form/142#q6ad4e3bf432c83230a0347a6eea6c805c672efeb_0"
26
26
 
27
27
  session = requests.Session()
28
28
  token_response = session.get(session_uri)
@@ -40,15 +40,18 @@ class CouncilClass(AbstractGetBinDataClass):
40
40
 
41
41
  collection_response = session.post(URI, data=form_data)
42
42
 
43
- collection_soup = BeautifulSoup(collection_response.text, "html.parser")
44
- for paragraph in collection_soup.find("div", class_="editor").find_all("p"):
45
- matches = re.match(r"^(\w+) Next Collection: (.*)", paragraph.text)
43
+ soup = BeautifulSoup(collection_response.text, "html.parser")
44
+ #print(soup)
45
+
46
+ for paragraph in soup.find("div", class_="editor").find_all("p"):
47
+ matches = re.match(r"^Your next (\w+) collections: (.*)", paragraph.text)
46
48
  if matches:
47
49
  collection_type, date_string = matches.groups()
50
+ parts = date_string.split(', ', 1)
48
51
  try:
49
- date = datetime.strptime(date_string, "%A %d %B %Y").date()
52
+ date = datetime.strptime(parts[0], "%A %d %B %Y").date()
50
53
  except ValueError:
51
- date = datetime.strptime(date_string, "%A %d %b %Y").date()
54
+ date = datetime.strptime(parts[0], "%A %d %b %Y").date()
52
55
 
53
56
  dict_data = {
54
57
  "type": collection_type,
@@ -61,3 +64,5 @@ class CouncilClass(AbstractGetBinDataClass):
61
64
  )
62
65
 
63
66
  return bindata
67
+
68
+
@@ -113,7 +113,7 @@ class CouncilClass(AbstractGetBinDataClass):
113
113
  try:
114
114
  # Convert date from "Friday 09 May 2025" format
115
115
  parsed_date = datetime.strptime(
116
- collection_date, "%A %d %B %Y"
116
+ collection_date, "%A %d %b %Y"
117
117
  )
118
118
  formatted_date = parsed_date.strftime("%d/%m/%Y")
119
119
 
@@ -132,7 +132,7 @@ class CouncilClass(AbstractGetBinDataClass):
132
132
  key=lambda x: datetime.strptime(x["collectionDate"], "%d/%m/%Y")
133
133
  )
134
134
 
135
- print(bin_data)
135
+ #print(bin_data)
136
136
 
137
137
  except Exception as e:
138
138
  # Here you can log the exception if needed
@@ -1,76 +1,130 @@
1
- import requests
1
+ from typing import Dict, List, Any, Optional
2
2
  from bs4 import BeautifulSoup
3
-
4
- from uk_bin_collection.uk_bin_collection.common import *
3
+ from dateutil.relativedelta import relativedelta
4
+ import requests
5
+ import re
6
+ from datetime import datetime
7
+ from uk_bin_collection.uk_bin_collection.common import check_uprn, check_postcode, date_format
5
8
  from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
9
+ from dateutil.parser import parse
6
10
 
7
11
 
8
- # import the wonderful Beautiful Soup and the URL grabber
9
12
  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
- """
13
+ def get_data(self, url: str) -> str:
14
+ # This method is not used in the current implementation
15
+ return ""
15
16
 
16
- def parse_data(self, page: str, **kwargs) -> dict:
17
+ def parse_data(self, page: str, **kwargs: Any) -> Dict[str, List[Dict[str, str]]]:
18
+ postcode: Optional[str] = kwargs.get("postcode")
19
+ uprn: Optional[str] = kwargs.get("uprn")
17
20
 
18
- user_uprn = kwargs.get("uprn")
19
- user_postcode = kwargs.get("postcode")
20
- check_uprn(user_uprn)
21
- check_postcode(user_postcode)
22
- bindata = {"bins": []}
21
+ if postcode is None or uprn is None:
22
+ raise ValueError("Both postcode and UPRN are required.")
23
23
 
24
- session_uri = "https://forms.chorleysouthribble.gov.uk/xfp/form/70"
25
- URI = "https://forms.chorleysouthribble.gov.uk/xfp/form/70#qc576c657112a8277ba6f954ebc0490c946168363_0"
24
+ check_postcode(postcode)
25
+ check_uprn(uprn)
26
26
 
27
27
  session = requests.Session()
28
- token_response = session.get(session_uri)
29
- soup = BeautifulSoup(token_response.text, "html.parser")
30
- token = soup.find("input", {"name": "__token"}).attrs["value"]
31
-
32
- form_data = {
33
- "__token": token,
34
- "page": "196",
35
- "locale": "en_GB",
36
- "qc576c657112a8277ba6f954ebc0490c946168363_0_0": user_postcode,
37
- "qc576c657112a8277ba6f954ebc0490c946168363_1_0": user_uprn,
38
- "next": "Next",
28
+ headers = {
29
+ "User-Agent": (
30
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
31
+ "(KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36"
32
+ )
39
33
  }
34
+ session.headers.update(headers)
35
+
36
+ # Step 1: Load form and get token + field names
37
+ initial_url = "https://forms.chorleysouthribble.gov.uk/xfp/form/70"
38
+ get_resp = session.get(initial_url)
39
+ soup = BeautifulSoup(get_resp.text, "html.parser")
40
+
41
+ token = soup.find("input", {"name": "__token"})["value"]
42
+ page_id = soup.find("input", {"name": "page"})["value"]
43
+ postcode_field = soup.find("input", {"type": "text", "name": re.compile(".*_0_0")})["name"]
44
+
45
+ # Step 2: Submit postcode
46
+ post_resp = session.post(
47
+ initial_url,
48
+ data={
49
+ "__token": token,
50
+ "page": page_id,
51
+ "locale": "en_GB",
52
+ postcode_field: postcode,
53
+ "next": "Next",
54
+ },
55
+ )
40
56
 
41
- collection_response = session.post(URI, data=form_data)
57
+ soup = BeautifulSoup(post_resp.text, "html.parser")
58
+ token = soup.find("input", {"name": "__token"})["value"]
59
+ address_field_el = soup.find("select", {"name": re.compile(".*_1_0")})
60
+ if not address_field_el:
61
+ raise ValueError("Failed to find address dropdown after postcode submission.")
42
62
 
43
- #collection_soup = BeautifulSoup(collection_response.text, "html.parser")
44
-
63
+ address_field = address_field_el["name"]
45
64
 
46
- soup = BeautifulSoup(collection_response.text, "html.parser")
47
- #print(soup)
65
+ # Step 3: Submit UPRN and retrieve bin data
66
+ final_resp = session.post(
67
+ initial_url,
68
+ data={
69
+ "__token": token,
70
+ "page": page_id,
71
+ "locale": "en_GB",
72
+ postcode_field: postcode,
73
+ address_field: uprn,
74
+ "next": "Next",
75
+ },
76
+ )
48
77
 
49
- rows = soup.find("table").find_all("tr")
78
+ soup = BeautifulSoup(final_resp.text, "html.parser")
79
+ table = soup.find("table", class_="data-table")
80
+ if not table:
81
+ raise ValueError("Could not find bin collection table.")
50
82
 
51
- # Form a JSON wrapper
83
+ rows = table.find("tbody").find_all("tr")
52
84
  data: Dict[str, List[Dict[str, str]]] = {"bins": []}
53
85
 
54
- # Loops the Rows
86
+ # Extract bin type mapping from JavaScript
87
+ bin_type_map = {}
88
+ scripts = soup.find_all("script", type="text/javascript")
89
+ for script in scripts:
90
+ if script.string and "const bintype = {" in script.string:
91
+ match = re.search(r'const bintype = \{([^}]+)\}', script.string, re.DOTALL)
92
+ if match:
93
+ bintype_content = match.group(1)
94
+ for line in bintype_content.split('\n'):
95
+ line = line.strip()
96
+ if '"' in line and ':' in line:
97
+ parts = line.split(':', 1)
98
+ if len(parts) == 2:
99
+ key = parts[0].strip().strip('"').strip("'")
100
+ value = parts[1].strip().rstrip(',').strip().strip('"').strip("'")
101
+ bin_type_map[key] = value
102
+ break
103
+
55
104
  for row in rows:
56
105
  cells = row.find_all("td")
57
-
58
- if cells:
59
- bin_type = cells[0].get_text(strip=True)
60
- collection_next = cells[1].get_text(strip=True)
61
-
62
- if len(collection_next) != 1:
63
- collection_date_obj = datetime.strptime(collection_next, "%d/%m/%y").date()
64
- # since we only have the next collection day, if the parsed date is in the past,
65
- # assume the day is instead next month
66
- if collection_date_obj < datetime.now().date():
67
- collection_date_obj += relativedelta(months=1)
68
- # Make each Bin element in the JSON
69
- dict_data = {
106
+ if len(cells) >= 2:
107
+ bin_type_cell = cells[0]
108
+ bin_type = bin_type_cell.get_text(strip=True)
109
+ bin_type = bin_type_map.get(bin_type, bin_type)
110
+
111
+ date_text = cells[1].get_text(strip=True)
112
+ date_parts = date_text.split(", ")
113
+ date_str = date_parts[1] if len(date_parts) == 2 else date_text
114
+
115
+ try:
116
+ day, month, year = date_str.split('/')
117
+ year = int(year)
118
+ if year < 100:
119
+ year = 2000 + year
120
+
121
+ date_obj = datetime(year, int(month), int(day)).date()
122
+
123
+ data["bins"].append({
70
124
  "type": bin_type,
71
- "collectionDate": collection_date_obj.strftime("%d/%m/%Y"),
72
- }
73
- # Add data to the main JSON Wrapper
74
- data["bins"].append(dict_data)
75
- continue
125
+ "collectionDate": date_obj.strftime(date_format)
126
+ })
127
+ except Exception:
128
+ continue
129
+
76
130
  return data
@@ -82,7 +82,7 @@ class CouncilClass(AbstractGetBinDataClass):
82
82
  # Get the dates.
83
83
  for bins in soup.find_all("div", {"class": "BinsRecycling"}):
84
84
  bin_type = bins.find("h2").text
85
- binCollection = bins.find("div", {"class": "dateWrapper-next"}).get_text(
85
+ binCollection = bins.find("div", {"class": "dateWrap-next"}).get_text(
86
86
  strip=True
87
87
  )
88
88
  binData = datetime.strptime(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: uk_bin_collection
3
- Version: 0.152.4
3
+ Version: 0.152.6
4
4
  Summary: Python Lib to collect UK Bin Data
5
5
  Author: Robert Bradley
6
6
  Author-email: robbrad182@gmail.com
@@ -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=hy8tlgmuKQWiq3PxNE16kaYHk6XxesuFkBvtpk-9oIw,132590
10
+ uk_bin_collection/tests/input.json,sha256=Xoq9-6sQ5Yc91jPFXx6hJucoyOOc1exTVQ9jS_m-JkY,135599
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
@@ -88,9 +88,9 @@ uk_bin_collection/uk_bin_collection/councils/CornwallCouncil.py,sha256=6zHe_Qu-R
88
88
  uk_bin_collection/uk_bin_collection/councils/CotswoldDistrictCouncil.py,sha256=85MPd1idsil3F-0Y6RQGMHKEcP9VS-z9B8l8ITK4BUU,4854
89
89
  uk_bin_collection/uk_bin_collection/councils/CoventryCityCouncil.py,sha256=YjVSEGxuu92-hcfLtNjzh98To_HSiTfjrfZHF3DHChg,2085
90
90
  uk_bin_collection/uk_bin_collection/councils/CrawleyBoroughCouncil.py,sha256=Oaj5INA3zNjtzBRsfLvRTIxZzcd4E4bJfVF1ULWlrL4,4322
91
- uk_bin_collection/uk_bin_collection/councils/CroydonCouncil.py,sha256=s6zTA-A4lHTkJrB5hEtgsXsMXIX6NNUM8kDP_kVAWj4,5475
91
+ uk_bin_collection/uk_bin_collection/councils/CroydonCouncil.py,sha256=6UCT2Q75NANXPP7kR1ktM65lTKEDI2pDwfc5qnOL1io,5369
92
92
  uk_bin_collection/uk_bin_collection/councils/CumberlandAllerdaleCouncil.py,sha256=bPOmkyzNnHrOtUprbouHdOsgpu7WilUADcaccWTCPFI,2839
93
- uk_bin_collection/uk_bin_collection/councils/CumberlandCouncil.py,sha256=hM0SUXW4k_queqVH0hEx-dmuBHQs0Ds1LEjlsJ8EiCY,3231
93
+ uk_bin_collection/uk_bin_collection/councils/CumberlandCouncil.py,sha256=PwTbTVNDdGZnSkPcIHYf-LHItDyIbR68Avr96T1FrX8,3308
94
94
  uk_bin_collection/uk_bin_collection/councils/DacorumBoroughCouncil.py,sha256=Tm_6pvBPj-6qStbe6-02LXaoCOlnnDvVXAAocGVvf_E,3970
95
95
  uk_bin_collection/uk_bin_collection/councils/DartfordBoroughCouncil.py,sha256=3vuXYhoK3ZkFGtxIDJXCTeY8_kbaXDcKn0C2yk5g1kI,2056
96
96
  uk_bin_collection/uk_bin_collection/councils/DenbighshireCouncil.py,sha256=FtG0LMTY21RBQiBpeX4FihdMCEZ1knpARYyMfyCn9ng,2103
@@ -162,7 +162,7 @@ uk_bin_collection/uk_bin_collection/councils/HyndburnBoroughCouncil.py,sha256=_l
162
162
  uk_bin_collection/uk_bin_collection/councils/IpswichBoroughCouncil.py,sha256=57lmDl_FprG68gUhKQYpOa1M2pudyb1utfoMhUXNwzs,2802
163
163
  uk_bin_collection/uk_bin_collection/councils/IslingtonCouncil.py,sha256=xavzL6ZIU9DG8Xro3vN0CEnYmNU31OGnOvnq78wgpQc,1258
164
164
  uk_bin_collection/uk_bin_collection/councils/KingsLynnandWestNorfolkBC.py,sha256=Shj18R-7NW4ivqJJFVJOLmf-EeN6hXP2Of30oI-SeAQ,1932
165
- uk_bin_collection/uk_bin_collection/councils/KingstonUponThamesCouncil.py,sha256=iZ7njIxccCGBhUUWWd9Azh7cxUAKaofebCm3lo-TuxA,3543
165
+ uk_bin_collection/uk_bin_collection/councils/KingstonUponThamesCouncil.py,sha256=8kKRhvdqs1hCymqmTtbi0FPJp2kd47JVmKTgRaWOGeY,3573
166
166
  uk_bin_collection/uk_bin_collection/councils/KirkleesCouncil.py,sha256=WPM7koIqK5Wz-iT9Mds6AptihGZtl4KZhkVTcT9cx_c,2762
167
167
  uk_bin_collection/uk_bin_collection/councils/KnowsleyMBCouncil.py,sha256=PDC907dxifFSAuto-vLJLEPBJrxTqNsfoD07__iKiwM,5269
168
168
  uk_bin_collection/uk_bin_collection/councils/LancasterCityCouncil.py,sha256=FmHT6oyD4BwWuhxA80PHnGA7HPrLuyjP_54Cg8hT6k4,2537
@@ -213,7 +213,7 @@ uk_bin_collection/uk_bin_collection/councils/NorthAyrshireCouncil.py,sha256=o8zv
213
213
  uk_bin_collection/uk_bin_collection/councils/NorthDevonCountyCouncil.py,sha256=tgJKIvu7nnCAHu_HImfG5SQABD6ygKFqrZU-ZoC6ObY,6260
214
214
  uk_bin_collection/uk_bin_collection/councils/NorthEastDerbyshireDistrictCouncil.py,sha256=BfNpYcjG3z0Yz8OYN6NkfzvZ5k1FI-80D-rv211kPPU,5449
215
215
  uk_bin_collection/uk_bin_collection/councils/NorthEastLincs.py,sha256=fYf438VZIaOaqPSwdTTWVjFTdrI0jGfFsxVzOc-QdkA,1817
216
- uk_bin_collection/uk_bin_collection/councils/NorthHertfordshireDistrictCouncil.py,sha256=Zps52bZroibL1h0h7WKD1aKJzQD7-OLwd9tHXDQkDFg,12263
216
+ uk_bin_collection/uk_bin_collection/councils/NorthHertfordshireDistrictCouncil.py,sha256=vwskZOfnUrSmKiezzt6TgP6_EIym0hDe-qaoLC9hWuU,12307
217
217
  uk_bin_collection/uk_bin_collection/councils/NorthKestevenDistrictCouncil.py,sha256=vYOCerJXr9LTP6F2wm4vpYNYbQaWNZ6yfHEQ33N_hTw,1681
218
218
  uk_bin_collection/uk_bin_collection/councils/NorthLanarkshireCouncil.py,sha256=npK1V8D3SLNTSSKkfEpEPvVgXDFyhH_tAsuGogsVKQY,1763
219
219
  uk_bin_collection/uk_bin_collection/councils/NorthLincolnshireCouncil.py,sha256=MPzrfdo9YQFVlqBUOM-jDQkacz2DXnygLILQ_ojZeJo,2543
@@ -229,7 +229,7 @@ uk_bin_collection/uk_bin_collection/councils/NottinghamCityCouncil.py,sha256=pan
229
229
  uk_bin_collection/uk_bin_collection/councils/NuneatonBedworthBoroughCouncil.py,sha256=PViXaBJ5SeP3inOnqf4PuPahzRCLN06n5Gicqyt3gbM,37781
230
230
  uk_bin_collection/uk_bin_collection/councils/OadbyAndWigstonBoroughCouncil.py,sha256=Kgy5HA0xZ9hR4_cAydPfOfskhGUB4j93AQF2-9Fj-Cg,2179
231
231
  uk_bin_collection/uk_bin_collection/councils/OldhamCouncil.py,sha256=9dlesCxNoVXlmQaqZj7QFh00smnJbm1Gnjkr_Uvzurs,1771
232
- uk_bin_collection/uk_bin_collection/councils/OxfordCityCouncil.py,sha256=d_bY0cXRDH4kSoWGGCTNN61MNErapSOf2WSTYDJr2r8,2318
232
+ uk_bin_collection/uk_bin_collection/councils/OxfordCityCouncil.py,sha256=a6bPDZDh0RKcbyDoidI-PiIM5lw7Tr0AlApP4_hTbxQ,2419
233
233
  uk_bin_collection/uk_bin_collection/councils/PembrokeshireCountyCouncil.py,sha256=GRAxjf_DuO5uZ660kEbZt_yCjP3n2maMxsYTPCTz3GQ,3324
234
234
  uk_bin_collection/uk_bin_collection/councils/PerthAndKinrossCouncil.py,sha256=Kos5GzN2co3Ij3tSHOXB9S71Yt78RROCfVRtnh7M1VU,3657
235
235
  uk_bin_collection/uk_bin_collection/councils/PeterboroughCityCouncil.py,sha256=lOrDD4jfJ-_C5UwCGqRcQ1G-U1F5X6rf255ypzYEBcg,6300
@@ -248,7 +248,7 @@ uk_bin_collection/uk_bin_collection/councils/RochfordCouncil.py,sha256=rfhD66A9H
248
248
  uk_bin_collection/uk_bin_collection/councils/RotherDistrictCouncil.py,sha256=-fdLvtik9ytfwXrrhwWdBxqQOMq2N1pvrIuvShhf8PU,3090
249
249
  uk_bin_collection/uk_bin_collection/councils/RotherhamCouncil.py,sha256=LtMPM8lj5bfReDR4buHEo-aRC_HTBIeo1nf8GE5-R80,1790
250
250
  uk_bin_collection/uk_bin_collection/councils/RoyalBoroughofGreenwich.py,sha256=BZzLmWK_VONOmMpSrLrnKtJaOrrepm6aStfKGVcgf9Y,3487
251
- uk_bin_collection/uk_bin_collection/councils/RugbyBoroughCouncil.py,sha256=q0zMKJk9lEPFBMShqqcCkhw09cFU-CJPgRYCniL9XXA,5686
251
+ uk_bin_collection/uk_bin_collection/councils/RugbyBoroughCouncil.py,sha256=WlmOD-xHJFdowI9fGuGDHOpnAVHGUWxGZqmJ6z4fGXs,5687
252
252
  uk_bin_collection/uk_bin_collection/councils/RunnymedeBoroughCouncil.py,sha256=vmTZfijt9b6sKzRdRwROE94lrMVnqs6kn6tg-xi1jR4,1618
253
253
  uk_bin_collection/uk_bin_collection/councils/RushcliffeBoroughCouncil.py,sha256=nWo8xeER71FEbnMTX8W9bcwZNpLEExWzPvgRT7DmcMc,4221
254
254
  uk_bin_collection/uk_bin_collection/councils/RushmoorCouncil.py,sha256=ZsGnXjoEaOS6U7fI0w7-uqxayAHdNVKsJi2fqIWEls8,3375
@@ -271,7 +271,7 @@ uk_bin_collection/uk_bin_collection/councils/SouthKestevenDistrictCouncil.py,sha
271
271
  uk_bin_collection/uk_bin_collection/councils/SouthLanarkshireCouncil.py,sha256=fj-eZI0yrvQVCv8GvhcovZ3b9bV6Xv_ws3IunWjnv4U,3126
272
272
  uk_bin_collection/uk_bin_collection/councils/SouthNorfolkCouncil.py,sha256=C2qIZjjbl9JnuukX9OH2RbfP0hSdp3uX76APGY33qKs,4622
273
273
  uk_bin_collection/uk_bin_collection/councils/SouthOxfordshireCouncil.py,sha256=f9d2YDGv5hnN7Ul-u_I63h_BbpBU7CJFdgv-lOviRGc,4031
274
- uk_bin_collection/uk_bin_collection/councils/SouthRibbleCouncil.py,sha256=5HSTmrPc-gN3ZzLq6n2VDs_NhtCgXhnGqJkEejDmSHI,2900
274
+ uk_bin_collection/uk_bin_collection/councils/SouthRibbleCouncil.py,sha256=juX7pg7dwqxzZUXHcGeFz8h7SNoUsZWUl8uiEOptE3k,5012
275
275
  uk_bin_collection/uk_bin_collection/councils/SouthStaffordshireDistrictCouncil.py,sha256=ACQMHWyamnj1ag3gNF-8Jhp-DKUok1GhFdnzH4nCzwU,3201
276
276
  uk_bin_collection/uk_bin_collection/councils/SouthTynesideCouncil.py,sha256=dxXGrJfg_fn2IPTBgq6Duwy0WY8GYLafMuisaCjOnbs,3426
277
277
  uk_bin_collection/uk_bin_collection/councils/SouthamptonCityCouncil.py,sha256=exNoI-Vun_C5FowCYhZ_600MBUe_OPR7MdGZEMNLL0I,1542
@@ -329,7 +329,7 @@ uk_bin_collection/uk_bin_collection/councils/WestMorlandAndFurness.py,sha256=jbq
329
329
  uk_bin_collection/uk_bin_collection/councils/WestNorthamptonshireCouncil.py,sha256=Se3Cfn_6ADjhsUzEJI_JnGkVcIbXxSTferM4ZC6pZ0g,1166
330
330
  uk_bin_collection/uk_bin_collection/councils/WestOxfordshireDistrictCouncil.py,sha256=Cicz5ywn7YD-g4yiRxp5TGLuJFPBatw6y4mS_pBkblo,4858
331
331
  uk_bin_collection/uk_bin_collection/councils/WestSuffolkCouncil.py,sha256=9i8AQHh-qIRPZ_5Ad97_h04-qgyLQDPV064obBzab1Y,2587
332
- uk_bin_collection/uk_bin_collection/councils/WiganBoroughCouncil.py,sha256=3gqFA4-BVx_In6QOu3KUNqPN4Fkn9iMlZTeopMK9p6A,3746
332
+ uk_bin_collection/uk_bin_collection/councils/WiganBoroughCouncil.py,sha256=W9FGN47bTHvzARa6UInXEB3X6cToqfgzTkNlROzHgcM,3743
333
333
  uk_bin_collection/uk_bin_collection/councils/WiltshireCouncil.py,sha256=Q0ooHTQb9ynMXpSNBPk7XXEjI7zcHst3id4wxGdmVx4,5698
334
334
  uk_bin_collection/uk_bin_collection/councils/WinchesterCityCouncil.py,sha256=W2k00N5n9-1MzjMEqsNjldsQdOJPEPMjK7OGSinZm5Y,4335
335
335
  uk_bin_collection/uk_bin_collection/councils/WindsorAndMaidenheadCouncil.py,sha256=VWtFgypXL1wKQ63NmV-_O9odOkbDmv3uCQwrv8g9lMI,2294
@@ -346,8 +346,8 @@ uk_bin_collection/uk_bin_collection/councils/YorkCouncil.py,sha256=I2kBYMlsD4bId
346
346
  uk_bin_collection/uk_bin_collection/councils/council_class_template/councilclasstemplate.py,sha256=QD4v4xpsEE0QheR_fGaNOIRMc2FatcUfKkkhAhseyVU,1159
347
347
  uk_bin_collection/uk_bin_collection/create_new_council.py,sha256=m-IhmWmeWQlFsTZC4OxuFvtw5ZtB8EAJHxJTH4O59lQ,1536
348
348
  uk_bin_collection/uk_bin_collection/get_bin_data.py,sha256=YvmHfZqanwrJ8ToGch34x-L-7yPe31nB_x77_Mgl_vo,4545
349
- uk_bin_collection-0.152.4.dist-info/LICENSE,sha256=vABBUOzcrgfaTKpzeo-si9YVEun6juDkndqA8RKdKGs,1071
350
- uk_bin_collection-0.152.4.dist-info/METADATA,sha256=wK9bVaoTAyW9e1hieARhWnIUnlDdpL6b_h0VNvGP4zw,26688
351
- uk_bin_collection-0.152.4.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
352
- uk_bin_collection-0.152.4.dist-info/entry_points.txt,sha256=36WCSGMWSc916S3Hi1ZkazzDKHaJ6CD-4fCEFm5MIao,90
353
- uk_bin_collection-0.152.4.dist-info/RECORD,,
349
+ uk_bin_collection-0.152.6.dist-info/LICENSE,sha256=vABBUOzcrgfaTKpzeo-si9YVEun6juDkndqA8RKdKGs,1071
350
+ uk_bin_collection-0.152.6.dist-info/METADATA,sha256=sNfl9s2XJPOukcSK5-3R-Vf37i8Zi2wOhJnPom0nwq4,26688
351
+ uk_bin_collection-0.152.6.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
352
+ uk_bin_collection-0.152.6.dist-info/entry_points.txt,sha256=36WCSGMWSc916S3Hi1ZkazzDKHaJ6CD-4fCEFm5MIao,90
353
+ uk_bin_collection-0.152.6.dist-info/RECORD,,