uk_bin_collection 0.145.0__py3-none-any.whl → 0.146.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.
@@ -37,23 +37,37 @@
37
37
  const coveredLADs = new Set();
38
38
  const integrationByLAD24CD = {};
39
39
 
40
- for (const entry of Object.values(integrationData)) {
41
- const rawCode = entry.LAD24CD;
42
- const code = rawCode?.replace(/[^\x20-\x7E]/g, '').trim(); // Sanitize non-printables
43
- if (code) {
44
- console.log(`✅ Adding LAD24CD: [${code}] from raw: [${rawCode}]`);
45
- coveredLADs.add(code);
46
- integrationByLAD24CD[code] = {
47
- wiki_name: entry.wiki_name || "Unknown Council",
48
- url: `https://github.com/robbrad/UKBinCollectionData/wiki/Councils#${slugify(entry.wiki_name || "unknown-council")}`
49
- };
50
- } else {
51
- console.warn("⚠️ Entry with missing or bad LAD24CD:", entry);
40
+ for (const [moduleName, entry] of Object.entries(integrationData)) {
41
+ const wikiName = entry.wiki_name || moduleName;
42
+ const wikiUrl = `https://github.com/robbrad/UKBinCollectionData/wiki/Councils#${slugify(wikiName)}`;
43
+
44
+ // Case 1: Direct LAD24CD
45
+ if (entry.LAD24CD) {
46
+ const code = entry.LAD24CD?.replace(/[^\x20-\x7E]/g, '').trim();
47
+ if (code) {
48
+ coveredLADs.add(code);
49
+ integrationByLAD24CD[code] = { wiki_name: wikiName, url: wikiUrl };
50
+ } else {
51
+ console.warn("⚠️ Entry with bad LAD24CD:", moduleName, entry);
52
+ }
53
+ }
54
+
55
+ // Case 2: Shared modules with multiple LADs
56
+ if (Array.isArray(entry.supported_councils_LAD24CD)) {
57
+ for (const codeRaw of entry.supported_councils_LAD24CD) {
58
+ const code = codeRaw?.replace(/[^\x20-\x7E]/g, '').trim();
59
+ if (code) {
60
+ coveredLADs.add(code);
61
+ // Only overwrite if not already present (prefer specific match)
62
+ if (!integrationByLAD24CD[code]) {
63
+ integrationByLAD24CD[code] = { wiki_name: wikiName, url: wikiUrl };
64
+ }
65
+ }
66
+ }
52
67
  }
53
68
  }
54
69
 
55
- console.log("🧪 Contains E06000065?", coveredLADs.has("E06000065"));
56
- console.log("📦 Final set of covered LADs:", [...coveredLADs]);
70
+ console.log("📦 Final covered LADs:", [...coveredLADs]);
57
71
 
58
72
  return fetch('Local_Authority_Boundaries.geojson')
59
73
  .then(res => res.json())
@@ -74,7 +88,6 @@
74
88
  const name = feature.properties.LAD24NM;
75
89
  const covered = coveredLADs.has(code);
76
90
 
77
- console.log("🌍 GeoJSON Feature:", code, name);
78
91
  if (!code) console.warn("⚠️ Missing LAD24CD in GeoJSON feature:", feature);
79
92
  if (!covered && code) console.warn("❌ Not covered LAD:", code, name);
80
93
 
@@ -90,14 +103,11 @@
90
103
  }
91
104
  }).addTo(map);
92
105
 
93
- // 🔍 Missing LADs debug block
94
- const missing = [];
95
- geojson.features.forEach(f => {
96
- const code = f.properties.LAD24CD?.trim();
97
- if (!coveredLADs.has(code)) {
98
- missing.push(`${code} - ${f.properties.LAD24NM}`);
99
- }
100
- });
106
+ // Debug missing LADs
107
+ const missing = geojson.features
108
+ .map(f => [f.properties.LAD24CD?.trim(), f.properties.LAD24NM])
109
+ .filter(([code]) => !coveredLADs.has(code))
110
+ .map(([code, name]) => `${code} - ${name}`);
101
111
  console.warn("🛠️ Missing LADs in input.json:", missing);
102
112
  });
103
113
  })
@@ -23,10 +23,14 @@ def get_council_files(repo, branch):
23
23
  name = item["name"]
24
24
  if name.endswith(".py"):
25
25
  council_name = name.replace(".py", "")
26
- councils[council_name] = item["url"] # 'url' gives API-based content URL
26
+ councils[council_name] = item[
27
+ "url"
28
+ ] # 'url' gives API-based content URL
27
29
  return councils
28
30
  else:
29
- raise ValueError("Expected a list from the GitHub response but got something else.")
31
+ raise ValueError(
32
+ "Expected a list from the GitHub response but got something else."
33
+ )
30
34
  else:
31
35
  print(f"Failed to fetch councils from files: {response.content}")
32
36
  return {}
@@ -39,7 +43,9 @@ def get_council_file_content(api_url):
39
43
  We'll use the latter, decode base64, and return the text.
40
44
  """
41
45
  # Example: https://api.github.com/repos/robbrad/UKBinCollectionData/contents/...
42
- response = requests.get(api_url, headers={"Accept": "application/vnd.github.v3+json"})
46
+ response = requests.get(
47
+ api_url, headers={"Accept": "application/vnd.github.v3+json"}
48
+ )
43
49
  if response.status_code == 200:
44
50
  file_json = response.json()
45
51
  # file_json["content"] is base64-encoded
@@ -82,8 +88,8 @@ def council_needs_update(council_name, json_data, council_file_content):
82
88
  # If the council isn't in the JSON at all, we can't do the check
83
89
  # (or we assume no JSON data => no web_driver?).
84
90
  council_data = json_data.get(council_name, {})
85
- web_driver_missing = ("web_driver" not in council_data)
86
- create_webdriver_present = ("create_webdriver" in council_file_content)
91
+ web_driver_missing = "web_driver" not in council_data
92
+ create_webdriver_present = "create_webdriver" in council_file_content
87
93
 
88
94
  return web_driver_missing and create_webdriver_present
89
95
 
@@ -165,20 +171,21 @@ def main(repo="robbrad/UKBinCollectionData", branch="master"):
165
171
  # 4) Print results
166
172
  table_data = []
167
173
  headers = ["Council Name", "In Files", "In JSON", "Needs Update?", "Discrepancies"]
174
+
168
175
  # Sort councils so that ones with the highest discrepancy or update appear first
169
176
  # Then alphabetical if tie:
170
177
  def sort_key(item):
171
178
  # item is (council_name, data_dict)
172
179
  return (
173
- item[1]["needs_update"], # sort by needs_update (False < True)
180
+ item[1]["needs_update"], # sort by needs_update (False < True)
174
181
  item[1]["discrepancies_count"], # then by discrepancies
175
- item[0], # then by name
182
+ item[0], # then by name
176
183
  )
177
184
 
178
185
  # We'll sort descending for "needs_update", so invert the boolean or reverse later
179
186
  sorted_councils = sorted(
180
187
  all_councils_data.items(),
181
- key=lambda x: (not x[1]["needs_update"], x[1]["discrepancies_count"], x[0])
188
+ key=lambda x: (not x[1]["needs_update"], x[1]["discrepancies_count"], x[0]),
182
189
  )
183
190
 
184
191
  for council, presence in sorted_councils:
@@ -985,7 +985,35 @@
985
985
  "wiki_name": "Google Calendar (Public)",
986
986
  "wiki_note": "The URL should be the public ics file URL for the public Google calendar. See https://support.google.com/calendar/answer/37083?sjid=7202815583021446882-EU. Councils that currently need this are Trafford.",
987
987
  "supported_councils": [
988
- "TraffordCouncil"
988
+ "TraffordCouncil",
989
+ "ClackmannanshireCouncil",
990
+ "HavantBoroughCouncil",
991
+ "NorthWarwickshireBoroughCouncil",
992
+ "NewryMourneAndDownDistrictCouncil",
993
+ "EastDunbartonshireCouncil",
994
+ "PendleBoroughCouncil",
995
+ "TorfaenCountyBoroughCouncil",
996
+ "EastHampshireCountyCouncil",
997
+ "RibbleValleyCouncil",
998
+ "BrentwoodBoroughCouncil",
999
+ "IsleOfWightCouncil",
1000
+ "WestmorlAndFurnessCouncil",
1001
+ "DerryAndStrabaneDistrictCouncil",
1002
+ "NorwichCityCouncil"
1003
+ ],
1004
+ "supported_councils_LAD24CD": [
1005
+ "E06000046",
1006
+ "E07000068",
1007
+ "E07000085",
1008
+ "E07000090",
1009
+ "E07000124",
1010
+ "E07000218",
1011
+ "E08000009",
1012
+ "N09000005",
1013
+ "N09000010",
1014
+ "S12000005",
1015
+ "S12000045",
1016
+ "W06000020"
989
1017
  ]
990
1018
  },
991
1019
  "GraveshamBoroughCouncil": {
@@ -177,7 +177,11 @@ def is_working_day(date_to_check: datetime, region: Region = Region.ENG) -> bool
177
177
  :param region: The UK nation to check. Defaults to ENG.
178
178
  :return: Bool - true if a working day (non-holiday, Mon-Fri).
179
179
  """
180
- return False if is_holiday(date_to_check, region) or is_weekend(date_to_check) else True
180
+ return (
181
+ False
182
+ if is_holiday(date_to_check, region) or is_weekend(date_to_check)
183
+ else True
184
+ )
181
185
 
182
186
 
183
187
  def get_next_working_day(date: datetime, region: Region = Region.ENG) -> datetime:
@@ -232,7 +236,7 @@ def get_next_occurrence_from_day_month(date: datetime) -> datetime:
232
236
 
233
237
  # Check if the target date has already occurred this year
234
238
  if (target_month < current_month) or (
235
- target_month == current_month and target_day < current_day
239
+ target_month == current_month and target_day < current_day
236
240
  ):
237
241
  date = pd.to_datetime(date) + pd.DateOffset(years=1)
238
242
 
@@ -315,10 +319,10 @@ def contains_date(string, fuzzy=False) -> bool:
315
319
 
316
320
 
317
321
  def create_webdriver(
318
- web_driver: str = None,
319
- headless: bool = True,
320
- user_agent: str = None,
321
- session_name: str = None,
322
+ web_driver: str = None,
323
+ headless: bool = True,
324
+ user_agent: str = None,
325
+ session_name: str = None,
322
326
  ) -> webdriver.Chrome:
323
327
  """
324
328
  Create and return a Chrome WebDriver configured for optional headless operation.
@@ -29,9 +29,11 @@ class CouncilClass(AbstractGetBinDataClass):
29
29
  if not event.summary or not event.start:
30
30
  continue
31
31
 
32
- bindata["bins"].append({
33
- "type": event.summary,
34
- "collectionDate": event.start.date().strftime(date_format)
35
- })
32
+ bindata["bins"].append(
33
+ {
34
+ "type": event.summary,
35
+ "collectionDate": event.start.date().strftime(date_format),
36
+ }
37
+ )
36
38
 
37
39
  return bindata
@@ -10,6 +10,7 @@ from datetime import datetime
10
10
  from uk_bin_collection.uk_bin_collection.common import *
11
11
  from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
12
12
 
13
+
13
14
  # import the wonderful Beautiful Soup and the URL grabber
14
15
  class CouncilClass(AbstractGetBinDataClass):
15
16
  """
@@ -31,7 +32,7 @@ class CouncilClass(AbstractGetBinDataClass):
31
32
  check_postcode(user_postcode)
32
33
 
33
34
  driver = create_webdriver(web_driver, headless, None, __name__)
34
-
35
+
35
36
  driver.get(url)
36
37
 
37
38
  wait = WebDriverWait(driver, 10)
@@ -78,19 +79,23 @@ class CouncilClass(AbstractGetBinDataClass):
78
79
  time.sleep(5)
79
80
  # Wait for the specified div to be present
80
81
  target_div = WebDriverWait(driver, 10).until(
81
- EC.presence_of_element_located((By.ID, "WASTECOLLECTIONCALENDARV2_LOOKUP_SHOWSCHEDULE"))
82
+ EC.presence_of_element_located(
83
+ (By.ID, "WASTECOLLECTIONCALENDARV2_LOOKUP_SHOWSCHEDULE")
84
+ )
82
85
  )
83
86
 
84
87
  soup = BeautifulSoup(driver.page_source, "html.parser")
85
88
 
86
89
  bin_data = {"bins": []}
87
- next_collections = {} # Dictionary to store the next collection for each bin type
90
+ next_collections = (
91
+ {}
92
+ ) # Dictionary to store the next collection for each bin type
88
93
 
89
94
  bin_types = {
90
95
  "bulky": "Bulky Collection",
91
96
  "green": "Recycling",
92
97
  "black": "General Waste",
93
- "brown": "Garden Waste"
98
+ "brown": "Garden Waste",
94
99
  }
95
100
 
96
101
  for div in soup.select(".collection-area"):
@@ -108,21 +113,26 @@ class CouncilClass(AbstractGetBinDataClass):
108
113
 
109
114
  # Determine bin type from alt or description
110
115
  description = detail.get_text(separator=" ", strip=True).lower()
111
- alt_text = img['alt'].lower()
116
+ alt_text = img["alt"].lower()
112
117
 
113
118
  for key, name in bin_types.items():
114
119
  if key in alt_text or key in description:
115
120
  # Format date as dd/mm/yyyy
116
121
  formatted_date = date_obj.strftime("%d/%m/%Y")
117
- bin_entry = {
118
- "type": name,
119
- "collectionDate": formatted_date
120
- }
121
-
122
+ bin_entry = {"type": name, "collectionDate": formatted_date}
123
+
122
124
  # 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"):
125
+ if (
126
+ name not in next_collections
127
+ or date_obj
128
+ < datetime.strptime(
129
+ next_collections[name]["collectionDate"], "%d/%m/%Y"
130
+ )
131
+ ):
124
132
  next_collections[name] = bin_entry
125
- print(f"Found next collection for {name}: {formatted_date}") # Debug output
133
+ print(
134
+ f"Found next collection for {name}: {formatted_date}"
135
+ ) # Debug output
126
136
  break
127
137
 
128
138
  # Add the next collections to the bin_data
@@ -134,7 +144,7 @@ class CouncilClass(AbstractGetBinDataClass):
134
144
  finally:
135
145
  if driver:
136
146
  driver.quit()
137
-
147
+
138
148
  print("\nFinal bin data:")
139
149
  print(bin_data) # Debug output
140
150
  return bin_data
@@ -26,12 +26,19 @@ class CouncilClass(AbstractGetBinDataClass):
26
26
  driver = create_webdriver(web_driver, headless, None, __name__)
27
27
  driver.set_window_size(1920, 1080) # 👈 ensure full viewport
28
28
 
29
- driver.get("https://www.knowsley.gov.uk/bins-waste-and-recycling/your-household-bins/putting-your-bins-out")
29
+ driver.get(
30
+ "https://www.knowsley.gov.uk/bins-waste-and-recycling/your-household-bins/putting-your-bins-out"
31
+ )
30
32
 
31
33
  # Dismiss cookie popup if it exists
32
34
  try:
33
35
  accept_cookies = WebDriverWait(driver, 10).until(
34
- EC.element_to_be_clickable((By.XPATH, "//a[contains(@class, 'agree-button') and contains(text(), 'Accept all cookies')]"))
36
+ EC.element_to_be_clickable(
37
+ (
38
+ By.XPATH,
39
+ "//a[contains(@class, 'agree-button') and contains(text(), 'Accept all cookies')]",
40
+ )
41
+ )
35
42
  )
36
43
  accept_cookies.click()
37
44
  time.sleep(1)
@@ -41,7 +48,10 @@ class CouncilClass(AbstractGetBinDataClass):
41
48
  # Step 1: Click "Search by postcode"
42
49
  search_btn = WebDriverWait(driver, 60).until(
43
50
  EC.element_to_be_clickable(
44
- (By.XPATH, "//a[contains(text(), 'Search by postcode to find out when your bins are emptied')]")
51
+ (
52
+ By.XPATH,
53
+ "//a[contains(text(), 'Search by postcode to find out when your bins are emptied')]",
54
+ )
45
55
  )
46
56
  )
47
57
  search_btn.send_keys(Keys.RETURN)
@@ -49,14 +59,20 @@ class CouncilClass(AbstractGetBinDataClass):
49
59
  # Step 2: Enter postcode
50
60
  postcode_box = WebDriverWait(driver, 60).until(
51
61
  EC.presence_of_element_located(
52
- (By.XPATH, "//label[contains(text(), 'Please enter the post code')]/following-sibling::input")
62
+ (
63
+ By.XPATH,
64
+ "//label[contains(text(), 'Please enter the post code')]/following-sibling::input",
65
+ )
53
66
  )
54
67
  )
55
68
  postcode_box.send_keys(user_postcode)
56
69
 
57
70
  postcode_search_btn = WebDriverWait(driver, 60).until(
58
71
  EC.element_to_be_clickable(
59
- (By.XPATH, "//label[contains(text(), 'Please enter the post code')]/parent::div/following-sibling::button")
72
+ (
73
+ By.XPATH,
74
+ "//label[contains(text(), 'Please enter the post code')]/parent::div/following-sibling::button",
75
+ )
60
76
  )
61
77
  )
62
78
  postcode_search_btn.send_keys(Keys.RETURN)
@@ -64,7 +80,10 @@ class CouncilClass(AbstractGetBinDataClass):
64
80
  # Step 3: Select address from results
65
81
  address_selection_button = WebDriverWait(driver, 60).until(
66
82
  EC.element_to_be_clickable(
67
- (By.XPATH, f"//span[contains(text(), '{user_paon}')]/ancestor::li//button")
83
+ (
84
+ By.XPATH,
85
+ f"//span[contains(text(), '{user_paon}')]/ancestor::li//button",
86
+ )
68
87
  )
69
88
  )
70
89
  address_selection_button.send_keys(Keys.RETURN)
@@ -77,9 +96,13 @@ class CouncilClass(AbstractGetBinDataClass):
77
96
  )
78
97
 
79
98
  bin_info_container = driver.find_element(
80
- By.XPATH, "//label[contains(text(), 'collection')]/ancestor::div[contains(@class, 'mx-dataview-content')]")
99
+ By.XPATH,
100
+ "//label[contains(text(), 'collection')]/ancestor::div[contains(@class, 'mx-dataview-content')]",
101
+ )
81
102
 
82
- soup = BeautifulSoup(bin_info_container.get_attribute("innerHTML"), "html.parser")
103
+ soup = BeautifulSoup(
104
+ bin_info_container.get_attribute("innerHTML"), "html.parser"
105
+ )
83
106
 
84
107
  for group in soup.find_all("div", class_="form-group"):
85
108
  label = group.find("label")
@@ -93,14 +116,18 @@ class CouncilClass(AbstractGetBinDataClass):
93
116
  if "bin next collection date" in label_text.lower():
94
117
  bin_type = label_text.split(" bin")[0]
95
118
  try:
96
- collection_date = datetime.strptime(value_text, "%A %d/%m/%Y").strftime("%d/%m/%Y")
119
+ collection_date = datetime.strptime(
120
+ value_text, "%A %d/%m/%Y"
121
+ ).strftime("%d/%m/%Y")
97
122
  except ValueError:
98
123
  continue
99
124
 
100
- bindata["bins"].append({
101
- "type": bin_type,
102
- "collectionDate": collection_date,
103
- })
125
+ bindata["bins"].append(
126
+ {
127
+ "type": bin_type,
128
+ "collectionDate": collection_date,
129
+ }
130
+ )
104
131
 
105
132
  bindata["bins"].sort(
106
133
  key=lambda x: datetime.strptime(x["collectionDate"], "%d/%m/%Y")
@@ -5,12 +5,13 @@ from selenium.webdriver.common.by import By
5
5
  from selenium.webdriver.support import expected_conditions as EC
6
6
  from selenium.webdriver.support.ui import Select, WebDriverWait
7
7
 
8
- #import selenium keys
8
+ # import selenium keys
9
9
  from selenium.webdriver.common.keys import Keys
10
10
 
11
11
  from uk_bin_collection.uk_bin_collection.common import *
12
12
  from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
13
13
 
14
+
14
15
  # import the wonderful Beautiful Soup and the URL grabber
15
16
  class CouncilClass(AbstractGetBinDataClass):
16
17
  """
@@ -28,7 +29,7 @@ class CouncilClass(AbstractGetBinDataClass):
28
29
  check_postcode(user_postcode)
29
30
  user_paon = kwargs.get("paon")
30
31
  check_paon(user_paon)
31
-
32
+
32
33
  headless = kwargs.get("headless")
33
34
  web_driver = kwargs.get("web_driver")
34
35
  driver = create_webdriver(web_driver, headless, None, __name__)
@@ -54,13 +55,10 @@ class CouncilClass(AbstractGetBinDataClass):
54
55
  pass
55
56
 
56
57
  postcode_input = wait.until(
57
- EC.presence_of_element_located(
58
- (By.ID, 'postcode-search-input')
59
- )
58
+ EC.presence_of_element_located((By.ID, "postcode-search-input"))
60
59
  )
61
60
  postcode_input.send_keys(user_postcode)
62
61
 
63
-
64
62
  # Wait for the element to be clickable
65
63
  postcode_search_btn = wait.until(
66
64
  EC.element_to_be_clickable(
@@ -101,7 +99,9 @@ class CouncilClass(AbstractGetBinDataClass):
101
99
  date_text = date_span.text.strip()
102
100
  current_year = datetime.now().year
103
101
  full_date = f"{date_text} {current_year}" # e.g., "18 Apr 2025"
104
- collection_date = datetime.strptime(full_date, "%d %b %Y").strftime(date_format)
102
+ collection_date = datetime.strptime(full_date, "%d %b %Y").strftime(
103
+ date_format
104
+ )
105
105
  else:
106
106
  collection_date = None
107
107
  except Exception as e:
@@ -115,13 +115,17 @@ class CouncilClass(AbstractGetBinDataClass):
115
115
  bin_title_div = bin_block.select_one("div.bin-title")
116
116
  if bin_title_div:
117
117
  bin_type = bin_title_div.get_text(strip=True)
118
- data["bins"].append({
119
- "type": bin_type,
120
- "collectionDate": collection_date,
121
- })
118
+ data["bins"].append(
119
+ {
120
+ "type": bin_type,
121
+ "collectionDate": collection_date,
122
+ }
123
+ )
122
124
 
123
125
  # 3. Optional: sort bins by collectionDate
124
- data["bins"].sort(key=lambda x: datetime.strptime(x.get("collectionDate"), date_format))
126
+ data["bins"].sort(
127
+ key=lambda x: datetime.strptime(x.get("collectionDate"), date_format)
128
+ )
125
129
 
126
130
  except Exception as e:
127
131
  # Here you can log the exception if needed
@@ -132,4 +136,4 @@ class CouncilClass(AbstractGetBinDataClass):
132
136
  # This block ensures that the driver is closed regardless of an exception
133
137
  if driver:
134
138
  driver.quit()
135
- return data
139
+ return data
@@ -2,6 +2,7 @@ from bs4 import BeautifulSoup
2
2
  from uk_bin_collection.uk_bin_collection.common import *
3
3
  from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
4
4
 
5
+
5
6
  # import the wonderful Beautiful Soup and the URL grabber
6
7
  class CouncilClass(AbstractGetBinDataClass):
7
8
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: uk_bin_collection
3
- Version: 0.145.0
3
+ Version: 0.146.0
4
4
  Summary: Python Lib to collect UK Bin Data
5
5
  Author: Robert Bradley
6
6
  Author-email: robbrad182@gmail.com
@@ -1,11 +1,11 @@
1
1
  uk_bin_collection/Local_Authority_Boundaries.geojson,sha256=_j-hUiL0--t2ewd_s29-j7_AKRlhagRMmOhXyco-B6I,1175922
2
2
  uk_bin_collection/README.rst,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- uk_bin_collection/map.html,sha256=bBqCQkT4DjBeAL8hrjW5n8UHNxVUqc6XScpGMF60Vzw,3979
4
- uk_bin_collection/tests/check_selenium_url_in_input.json.py,sha256=Iecdja0I3XIiY76qmwPgcBqNgYv7n1-b5mg85JpMjg8,7817
3
+ uk_bin_collection/map.html,sha256=qKc4Lscv1eSIc0M3vDofzZf5w9_eslEYpz1-kK4tup0,4346
4
+ uk_bin_collection/tests/check_selenium_url_in_input.json.py,sha256=lf-JT7vvaSfvgbrfOhzrhfSzJqL82WajlRqo1GqfcMM,7875
5
5
  uk_bin_collection/tests/council_feature_input_parity.py,sha256=DO6Mk4ImYgM5ZCZ-cutwz5RoYYWZRLYx2tr6zIs_9Rc,3843
6
6
  uk_bin_collection/tests/features/environment.py,sha256=VQZjJdJI_kZn08M0j5cUgvKT4k3iTw8icJge1DGOkoA,127
7
7
  uk_bin_collection/tests/features/validate_council_outputs.feature,sha256=SJK-Vc737hrf03tssxxbeg_JIvAH-ddB8f6gU1LTbuQ,251
8
- uk_bin_collection/tests/input.json,sha256=iBYOKDe4fNStE1wgAS7Gzq-t1CRgSIGBPlejppkuARQ,132389
8
+ uk_bin_collection/tests/input.json,sha256=hJ_W7-yiUwGRA2V9WVQVXCV3UfaBFfbdaIbxm3c7hIM,133302
9
9
  uk_bin_collection/tests/output.schema,sha256=ZwKQBwYyTDEM4G2hJwfLUVM-5v1vKRvRK9W9SS1sd18,1086
10
10
  uk_bin_collection/tests/step_defs/step_helpers/file_handler.py,sha256=Ygzi4V0S1MIHqbdstUlIqtRIwnynvhu4UtpweJ6-5N8,1474
11
11
  uk_bin_collection/tests/step_defs/test_validate_council.py,sha256=VZ0a81sioJULD7syAYHjvK_-nT_Rd36tUyzPetSA0gk,3475
@@ -14,7 +14,7 @@ uk_bin_collection/tests/test_common_functions.py,sha256=cCUwXKGijmsvTLz0KoaedXkp
14
14
  uk_bin_collection/tests/test_conftest.py,sha256=qI_zgGjNOnwE9gmZUiuirL1SYz3TFw5yfGFgT4T3aG4,1100
15
15
  uk_bin_collection/tests/test_get_data.py,sha256=sFJz_Fd6o-1r2gdmzY52JGwVi0Of_mDzvYSoc7a3RUw,7239
16
16
  uk_bin_collection/uk_bin_collection/collect_data.py,sha256=dB7wWXsJX4fm5bIf84lexkvHIcO54CZ3JPxqmS-60YY,4654
17
- uk_bin_collection/uk_bin_collection/common.py,sha256=r3hV7HZv-WKr11nYq-99Dpmw_UPK6359MUFD6vDuFLc,11022
17
+ uk_bin_collection/uk_bin_collection/common.py,sha256=izotgwavB08pUWisNL3wqcBrE9E1-bdrq-v6YKyriDE,11034
18
18
  uk_bin_collection/uk_bin_collection/councils/AberdeenCityCouncil.py,sha256=Je8VwVLK9KnYl9vqf2gWJ7ZYDgUq3A7caDiIzk5Xof8,4194
19
19
  uk_bin_collection/uk_bin_collection/councils/AberdeenshireCouncil.py,sha256=aO1CSdyqa8oAD0fB79y1Q9bikAWCP_JFa7CsyTa2j9s,1655
20
20
  uk_bin_collection/uk_bin_collection/councils/AdurAndWorthingCouncils.py,sha256=ppbrmm-MzB1wOulK--CU_0j4P-djNf3ozMhHnmQFqLo,1511
@@ -131,9 +131,9 @@ uk_bin_collection/uk_bin_collection/councils/GatesheadCouncil.py,sha256=SRCgYhYs
131
131
  uk_bin_collection/uk_bin_collection/councils/GedlingBoroughCouncil.py,sha256=XzfFMCwclh9zAJgsbaj4jywjdiH0wPaFicaVsLrN3ms,2297
132
132
  uk_bin_collection/uk_bin_collection/councils/GlasgowCityCouncil.py,sha256=9Rk9KfcglJvRhh4373OfRX-fwywE2xgwx5KejqzV5fE,3399
133
133
  uk_bin_collection/uk_bin_collection/councils/GloucesterCityCouncil.py,sha256=67D8rbhn0t4rsCSJRTXZVtHmph2wT6rJiexNWKOnMok,4625
134
- uk_bin_collection/uk_bin_collection/councils/GooglePublicCalendarCouncil.py,sha256=KiDfL9AVhUlRuY98sbNs_Fb-vUVeo5n1bBShTJHcO8w,1173
134
+ uk_bin_collection/uk_bin_collection/councils/GooglePublicCalendarCouncil.py,sha256=1YLxRgiAyOi6ekPYUMJ_F8dKsx62lAeOi1NmT47E8zo,1216
135
135
  uk_bin_collection/uk_bin_collection/councils/GraveshamBoroughCouncil.py,sha256=ueQ9xFiTxMUBTGV9VjtySHA1EFWliTM0AeNePBIG9ho,4568
136
- uk_bin_collection/uk_bin_collection/councils/GreatYarmouthBoroughCouncil.py,sha256=6NIzcn6iiXHEeBer1TlUAAXRWSJOFiYO1IUDmLkF7R0,5295
136
+ uk_bin_collection/uk_bin_collection/councils/GreatYarmouthBoroughCouncil.py,sha256=lEtV-zxApiWXEJUEedaNiwBA3Oo1x8uM7m7GtRKfT_8,5469
137
137
  uk_bin_collection/uk_bin_collection/councils/GuildfordCouncil.py,sha256=9pVrmQhZcK2AD8gX8mNvP--L4L9KaY6L3B822VX6fec,5695
138
138
  uk_bin_collection/uk_bin_collection/councils/GwyneddCouncil.py,sha256=eK2KkY1NbIxVtBruQYSNPA0J7fuzMik5it02dFbKYV0,1855
139
139
  uk_bin_collection/uk_bin_collection/councils/HackneyCouncil.py,sha256=vO3ugk5fcdkYTslXNKmpJC84-ZHqrdFqW8zfX7TSiTQ,3104
@@ -157,7 +157,7 @@ uk_bin_collection/uk_bin_collection/councils/IslingtonCouncil.py,sha256=xavzL6ZI
157
157
  uk_bin_collection/uk_bin_collection/councils/KingsLynnandWestNorfolkBC.py,sha256=Shj18R-7NW4ivqJJFVJOLmf-EeN6hXP2Of30oI-SeAQ,1932
158
158
  uk_bin_collection/uk_bin_collection/councils/KingstonUponThamesCouncil.py,sha256=iZ7njIxccCGBhUUWWd9Azh7cxUAKaofebCm3lo-TuxA,3543
159
159
  uk_bin_collection/uk_bin_collection/councils/KirkleesCouncil.py,sha256=WPM7koIqK5Wz-iT9Mds6AptihGZtl4KZhkVTcT9cx_c,2762
160
- uk_bin_collection/uk_bin_collection/councils/KnowsleyMBCouncil.py,sha256=DsCVBCprCS2u_2E8IRBGOO_NWo-WC8i9jSxUI-rue_s,4654
160
+ uk_bin_collection/uk_bin_collection/councils/KnowsleyMBCouncil.py,sha256=PDC907dxifFSAuto-vLJLEPBJrxTqNsfoD07__iKiwM,5269
161
161
  uk_bin_collection/uk_bin_collection/councils/LancasterCityCouncil.py,sha256=FmHT6oyD4BwWuhxA80PHnGA7HPrLuyjP_54Cg8hT6k4,2537
162
162
  uk_bin_collection/uk_bin_collection/councils/LeedsCityCouncil.py,sha256=VWdhw6qvCTj3EhFHf046xPWgc6szeFW2Xbt6W2J0e6w,4371
163
163
  uk_bin_collection/uk_bin_collection/councils/LeicesterCityCouncil.py,sha256=o3kE8sjThQa4_AvSK5NH8VH7jWFO9MMPgoqLOTjyh0w,1851
@@ -185,7 +185,7 @@ uk_bin_collection/uk_bin_collection/councils/MidAndEastAntrimBoroughCouncil.py,s
185
185
  uk_bin_collection/uk_bin_collection/councils/MidDevonCouncil.py,sha256=8MxqGgOJVseMkrTmEMT0EyDW7UMbXMoa5ZcJ2nD55Ew,3367
186
186
  uk_bin_collection/uk_bin_collection/councils/MidSuffolkDistrictCouncil.py,sha256=h6M-v5jVYe7OlQ47Vf-0pEgECZLOOacK3_XE6zbpsM4,6329
187
187
  uk_bin_collection/uk_bin_collection/councils/MidSussexDistrictCouncil.py,sha256=AZgC9wmDLEjUOtIFvf0ehF5LHturXTH4DkE3ioPSVBA,6254
188
- uk_bin_collection/uk_bin_collection/councils/MidUlsterDistrictCouncil.py,sha256=dBDZvWQRlOQQDhLJVq0OzQy6iazstQ9NnDb6PIj5NOw,5020
188
+ uk_bin_collection/uk_bin_collection/councils/MidUlsterDistrictCouncil.py,sha256=ev_T8LoI9tZzkymmAD9yEk2leKc4Y0Cqsde56aAJPa8,5114
189
189
  uk_bin_collection/uk_bin_collection/councils/MiddlesbroughCouncil.py,sha256=BiYexiZj-9PxRnB7sYRy0G-72s3L9jfh2vd1Y2NQwtg,4223
190
190
  uk_bin_collection/uk_bin_collection/councils/MidlothianCouncil.py,sha256=-VKvdIhrs859-YqxsNMzRWm2alP1avBR1_J8O9gJnYw,6725
191
191
  uk_bin_collection/uk_bin_collection/councils/MiltonKeynesCityCouncil.py,sha256=7e2pGBLCw24pNItHeI9jkxQ3rEOZ4WC4zVlbvKYGdXE,2600
@@ -329,11 +329,11 @@ uk_bin_collection/uk_bin_collection/councils/WychavonDistrictCouncil.py,sha256=Y
329
329
  uk_bin_collection/uk_bin_collection/councils/WyreCouncil.py,sha256=QpCkmRSQmJo0RLsjXoCYPDcoxuDzG_00qNV0AHTDmXo,3000
330
330
  uk_bin_collection/uk_bin_collection/councils/WyreForestDistrictCouncil.py,sha256=3b7WzBXdYub6j13sqDL3jlqgICKmNyQaF4KxRxOMHWk,2000
331
331
  uk_bin_collection/uk_bin_collection/councils/YorkCouncil.py,sha256=I2kBYMlsD4bIdsvmoSzBjJAvTTi6yPfJa8xjJx1ys2w,1490
332
- uk_bin_collection/uk_bin_collection/councils/council_class_template/councilclasstemplate.py,sha256=EQWRhZ2pEejlvm0fPyOTsOHKvUZmPnxEYO_OWRGKTjs,1158
332
+ uk_bin_collection/uk_bin_collection/councils/council_class_template/councilclasstemplate.py,sha256=QD4v4xpsEE0QheR_fGaNOIRMc2FatcUfKkkhAhseyVU,1159
333
333
  uk_bin_collection/uk_bin_collection/create_new_council.py,sha256=m-IhmWmeWQlFsTZC4OxuFvtw5ZtB8EAJHxJTH4O59lQ,1536
334
334
  uk_bin_collection/uk_bin_collection/get_bin_data.py,sha256=YvmHfZqanwrJ8ToGch34x-L-7yPe31nB_x77_Mgl_vo,4545
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,,
335
+ uk_bin_collection-0.146.0.dist-info/LICENSE,sha256=vABBUOzcrgfaTKpzeo-si9YVEun6juDkndqA8RKdKGs,1071
336
+ uk_bin_collection-0.146.0.dist-info/METADATA,sha256=HDx_ThJ-YHiak_qHaFdhBG4hOT-xeil2DR5LO4V_kAA,19858
337
+ uk_bin_collection-0.146.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
338
+ uk_bin_collection-0.146.0.dist-info/entry_points.txt,sha256=36WCSGMWSc916S3Hi1ZkazzDKHaJ6CD-4fCEFm5MIao,90
339
+ uk_bin_collection-0.146.0.dist-info/RECORD,,