uk_bin_collection 0.127.2__py3-none-any.whl → 0.127.3__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.
@@ -1208,8 +1208,8 @@
1208
1208
  "wiki_note": "Pass the postcode and UPRN. This parser requires a Selenium webdriver."
1209
1209
  },
1210
1210
  "NewarkAndSherwoodDC": {
1211
- "url": "http://app.newark-sherwooddc.gov.uk/bincollection/calendar?pid=200004258529&nc=1",
1212
- "wiki_command_url_override": "http://app.newark-sherwooddc.gov.uk/bincollection/calendar?pid=XXXXXXXX&nc=1",
1211
+ "url": "http://app.newark-sherwooddc.gov.uk/bincollection/calendar?pid=200004258529",
1212
+ "wiki_command_url_override": "http://app.newark-sherwooddc.gov.uk/bincollection/calendar?pid=XXXXXXXX",
1213
1213
  "wiki_name": "Newark and Sherwood District Council",
1214
1214
  "wiki_note": "Replace XXXXXXXX with your UPRN."
1215
1215
  },
@@ -1409,15 +1409,6 @@
1409
1409
  "wiki_name": "Portsmouth City Council",
1410
1410
  "wiki_note": "Pass the postcode and UPRN. This parser requires a Selenium webdriver."
1411
1411
  },
1412
- "PowysCouncil": {
1413
- "house_number": "LANE COTTAGE",
1414
- "postcode": "HR3 5JS",
1415
- "skip_get_url": true,
1416
- "url": "https://www.powys.gov.uk",
1417
- "web_driver": "http://selenium:4444",
1418
- "wiki_name": "Powys Council",
1419
- "wiki_note": "Pass the house name/number and postcode in their respective parameters. This parser requires a Selenium webdriver."
1420
- },
1421
1412
  "PowysCouncil": {
1422
1413
  "house_number": "LANE COTTAGE",
1423
1414
  "postcode": "HR3 5JS",
@@ -1768,6 +1759,14 @@
1768
1759
  "wiki_name": "Sunderland City Council",
1769
1760
  "wiki_note": "Provide your house number (without quotes) and postcode (wrapped in double quotes with a space)."
1770
1761
  },
1762
+ "SurreyHeathBoroughCouncil": {
1763
+ "house_number": "36",
1764
+ "postcode": "GU20 6PN",
1765
+ "skip_get_url": true,
1766
+ "url": "https://asjwsw-wrpsurreyheathmunicipal-live.whitespacews.com/",
1767
+ "wiki_name": "Surrey Heath Borough Council / Joint Waste Solutions",
1768
+ "wiki_note": "Provide your house number in the `house_number` parameter and postcode in the `postcode` parameter."
1769
+ },
1771
1770
  "SwaleBoroughCouncil": {
1772
1771
  "postcode": "ME12 2NQ",
1773
1772
  "skip_get_url": true,
@@ -34,10 +34,10 @@ class CouncilClass(AbstractGetBinDataClass):
34
34
 
35
35
  # Find the next collection date
36
36
  date_tag = container.find(class_="font11 text-center")
37
- if date_tag.text.strip() == "":
38
- continue
39
- else:
37
+ if date_tag:
40
38
  collection_date = date_tag.text.strip()
39
+ else:
40
+ continue
41
41
 
42
42
  dict_data = {
43
43
  "type": bin_type,
@@ -1,3 +1,5 @@
1
+ import datetime
2
+
1
3
  from bs4 import BeautifulSoup
2
4
 
3
5
  from uk_bin_collection.uk_bin_collection.common import *
@@ -32,15 +34,24 @@ class CouncilClass(AbstractGetBinDataClass):
32
34
  for p in ps:
33
35
  collection = p.text.strip().replace("Your next ", "").split(".")[0]
34
36
  bin_type = collection.split(" day is")[0]
35
- collection_date = datetime.strptime(
36
- remove_ordinal_indicator_from_date_string(collection).split("day is ")[
37
- 1
38
- ],
39
- "%A %d %B %Y",
40
- )
37
+ collection_date = remove_ordinal_indicator_from_date_string(
38
+ collection
39
+ ).split("day is ")[1]
40
+ if collection_date == "Today":
41
+ collection_date = datetime.today().strftime(date_format)
42
+ elif collection_date == "Tomorrow":
43
+ collection_date = (datetime.today() + timedelta(days=1)).strftime(
44
+ date_format
45
+ )
46
+ print(collection_date)
47
+ else:
48
+ collection_date = datetime.strptime(
49
+ collection_date,
50
+ "%A %d %B %Y",
51
+ ).strftime(date_format)
41
52
  dict_data = {
42
53
  "type": bin_type,
43
- "collectionDate": collection_date.strftime(date_format),
54
+ "collectionDate": collection_date,
44
55
  }
45
56
  data["bins"].append(dict_data)
46
57
 
@@ -47,10 +47,10 @@ class CouncilClass(AbstractGetBinDataClass):
47
47
  bin_type = cells[0].get_text().strip()
48
48
  # Date is on the second cell, second paragraph, wrapped in p
49
49
  collectionDate = None
50
- for date_format in possible_formats:
50
+ for format in possible_formats:
51
51
  try:
52
52
  collectionDate = datetime.strptime(
53
- cells[1].select("p > b")[2].get_text(strip=True), date_format
53
+ cells[1].select("p > b")[2].get_text(strip=True), format
54
54
  )
55
55
  break # Exit the loop if parsing is successful
56
56
  except ValueError:
@@ -127,12 +127,15 @@ class CouncilClass(AbstractGetBinDataClass):
127
127
  li.text for li in garden_waste_section.find_next("ul").find_all("li")
128
128
  ]
129
129
  for date in garden_waste_dates:
130
- dict_data = {
131
- "type": "Garden Waste",
132
- "collectionDate": datetime.strptime(
133
- remove_ordinal_indicator_from_date_string(date), "%d %B %Y"
134
- ).strftime(date_format),
135
- }
136
- data["bins"].append(dict_data)
130
+ try:
131
+ dict_data = {
132
+ "type": "Garden Waste",
133
+ "collectionDate": datetime.strptime(
134
+ remove_ordinal_indicator_from_date_string(date), "%d %B %Y"
135
+ ).strftime(date_format),
136
+ }
137
+ data["bins"].append(dict_data)
138
+ except:
139
+ continue
137
140
 
138
141
  return data
@@ -1,5 +1,6 @@
1
1
  import requests
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
 
@@ -54,6 +55,9 @@ class CouncilClass(AbstractGetBinDataClass):
54
55
 
55
56
  data = {"bins": []}
56
57
 
58
+ current_year = datetime.now().year
59
+ next_year = current_year + 1
60
+
57
61
  # Page has slider info side by side, which are two instances of this class
58
62
  for bin in soup.find_all("div", {"class": "binextra"}):
59
63
  bin_info = list(bin.stripped_strings)
@@ -62,27 +66,32 @@ class CouncilClass(AbstractGetBinDataClass):
62
66
  if contains_date(bin_info[0]):
63
67
  bin_date = get_next_occurrence_from_day_month(
64
68
  datetime.strptime(
65
- bin_info[0] + " " + datetime.today().strftime("%Y"),
66
- "%A %d %B - %Y",
69
+ bin_info[0],
70
+ "%A %d %B -",
67
71
  )
68
- ).strftime(date_format)
69
- bin_type = str.capitalize(' '.join(bin_info[1:]))
72
+ )
73
+ bin_type = str.capitalize(" ".join(bin_info[1:]))
70
74
  # On exceptional collection schedule (e.g. around English Bank Holidays), date will be contained in the second stripped string
71
75
  else:
72
76
  bin_date = get_next_occurrence_from_day_month(
73
77
  datetime.strptime(
74
- bin_info[1] + " " + datetime.today().strftime("%Y"),
75
- "%A %d %B - %Y",
78
+ bin_info[1],
79
+ "%A %d %B -",
76
80
  )
77
- ).strftime(date_format)
78
- str.capitalize(' '.join(bin_info[2:]))
79
- except Exception as ex:
80
- raise ValueError(f"Error parsing bin data: {ex}")
81
+ )
82
+ str.capitalize(" ".join(bin_info[2:]))
83
+ except:
84
+ continue
85
+
86
+ if (datetime.now().month == 12) and (bin_date.month == 1):
87
+ bin_date = bin_date.replace(year=next_year)
88
+ else:
89
+ bin_date = bin_date.replace(year=current_year)
81
90
 
82
91
  # Build data dict for each entry
83
92
  dict_data = {
84
93
  "type": bin_type,
85
- "collectionDate": bin_date,
94
+ "collectionDate": bin_date.strftime(date_format),
86
95
  }
87
96
  data["bins"].append(dict_data)
88
97
 
@@ -30,12 +30,12 @@ class CouncilClass(AbstractGetBinDataClass):
30
30
  driver.get("https://www.staffsmoorlands.gov.uk/findyourbinday")
31
31
 
32
32
  # Close cookies banner
33
- cookieAccept = WebDriverWait(driver, 10).until(
34
- EC.presence_of_element_located(
35
- (By.CSS_SELECTOR, ".cookiemessage__link--close")
36
- )
37
- )
38
- cookieAccept.click()
33
+ # cookieAccept = WebDriverWait(driver, 10).until(
34
+ # EC.presence_of_element_located(
35
+ # (By.CSS_SELECTOR, ".cookiemessage__link--close")
36
+ # )
37
+ # )
38
+ # cookieAccept.click()
39
39
 
40
40
  # Wait for the postcode field to appear then populate it
41
41
  inputElement_postcode = WebDriverWait(driver, 30).until(
@@ -1,8 +1,10 @@
1
+ from datetime import datetime, timedelta
2
+ from typing import Any, Dict
3
+
1
4
  from bs4 import BeautifulSoup
5
+
2
6
  from uk_bin_collection.uk_bin_collection.common import *
3
7
  from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
4
- from datetime import datetime, timedelta
5
- from typing import Dict, Any
6
8
 
7
9
 
8
10
  class CouncilClass(AbstractGetBinDataClass):
@@ -78,7 +80,10 @@ class CouncilClass(AbstractGetBinDataClass):
78
80
  formatted_date = self.get_next_weekday(day_name)
79
81
  else:
80
82
  # Convert date format from "Tuesday 28 May 2024" to "28/05/2024"
81
- date_obj = datetime.strptime(value, "%A %d %B %Y")
83
+ try:
84
+ date_obj = datetime.strptime(value, "%A %d %B %Y")
85
+ except:
86
+ continue
82
87
  formatted_date = date_obj.strftime("%d/%m/%Y")
83
88
 
84
89
  bin_entry = {
@@ -0,0 +1,116 @@
1
+ import urllib
2
+
3
+ from bs4 import BeautifulSoup
4
+
5
+ from uk_bin_collection.uk_bin_collection.common import *
6
+ from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
7
+
8
+
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
+ requests.packages.urllib3.disable_warnings()
18
+ root_url = "https://asjwsw-wrpsurreyheathmunicipal-live.whitespacews.com/"
19
+ # Get the house number and postcode from the commandline
20
+ user_paon = kwargs.get("paon")
21
+ user_postcode = kwargs.get("postcode")
22
+ check_postcode(user_postcode)
23
+
24
+ # Start a new session for the form, and get the chosen URL from the commandline
25
+ session = requests.Session()
26
+ req = session.get(root_url)
27
+
28
+ # Parse the requested URL to get a link to the "View My Collections" portal with a unique service ID
29
+ start = BeautifulSoup(req.text, features="html.parser")
30
+ start.prettify()
31
+ base_link = start.select(
32
+ "#menu-content > div > div:nth-child(1) > p.govuk-body.govuk-\\!-margin-bottom-0.colorblue.lineheight15 > a"
33
+ )[0].attrs.get("href")
34
+
35
+ # We need to reorder the query parts from the unique URL, so split them up to make it easier
36
+ query_parts = urllib.parse.urlparse(base_link).query.split("&")
37
+ parts = base_link.split("?")
38
+ addr_link = (
39
+ parts[0] + "/mop.php?" + query_parts[1] + "&" + query_parts[0] + "&seq=2"
40
+ )
41
+
42
+ # Bring in some headers to emulate a browser, and put the UPRN and postcode into the form data.
43
+ # This is sent in a POST request, emulating browser behaviour.
44
+ headers = {
45
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
46
+ "Accept-Language": "en-GB,en;q=0.9",
47
+ "Cache-Control": "no-cache",
48
+ "Connection": "keep-alive",
49
+ "Content-Type": "application/x-www-form-urlencoded",
50
+ "Origin": "https://asjwsw-wrpsurreyheathmunicipal-live.whitespacews.com",
51
+ "Pragma": "no-cache",
52
+ "Referer": "https://asjwsw-wrpsurreyheathmunicipal-live.whitespacews.com/",
53
+ "Sec-Fetch-Dest": "document",
54
+ "Sec-Fetch-Mode": "navigate",
55
+ "Sec-Fetch-Site": "same-origin",
56
+ "Sec-Fetch-User": "?1",
57
+ "Upgrade-Insecure-Requests": "1",
58
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 OPR/98.0.0.0",
59
+ "sec-ch-ua": '"Chromium";v="112", "Not_A Brand";v="24", "Opera GX";v="98"',
60
+ "sec-ch-ua-mobile": "?0",
61
+ "sec-ch-ua-platform": '"Windows"',
62
+ }
63
+ data = {
64
+ "address_name_number": user_paon,
65
+ "address_street": "",
66
+ "street_town": "",
67
+ "address_postcode": user_postcode,
68
+ }
69
+ addr_page = session.post(addr_link, headers=headers, data=data)
70
+ addr = BeautifulSoup(addr_page.text, features="html.parser")
71
+ addr.prettify()
72
+
73
+ # This page should only have one address, but regardless, select the first one and make a request to load the
74
+ # calendar page.
75
+ cal_link = root_url + addr.select("#property_list > ul > li > a")[0].attrs.get(
76
+ "href"
77
+ )
78
+ cal_page = session.get(cal_link)
79
+
80
+ # Parse the calendar page
81
+ soup = BeautifulSoup(cal_page.text, features="html.parser")
82
+ soup.prettify()
83
+ data = {"bins": []}
84
+
85
+ # For whatever reason, each row contains all the information for that row, and each one after it. This code
86
+ # essentially gets all items from each row, but ignores the whitespace that you get when splitting using \n.
87
+ # This produces a big list of dates then bin types, so we split them up into a list of lists - each pair is
88
+ # a date and the bin type.
89
+ items = [
90
+ i
91
+ for i in soup.find(
92
+ "u1",
93
+ {
94
+ "class": "displayinlineblock justifycontentleft alignitemscenter margin0 padding0"
95
+ },
96
+ ).text.split("\n")
97
+ if i != ""
98
+ ]
99
+ pairs = [items[i : i + 2] for i in range(0, len(items), 2)]
100
+
101
+ # Loop through the paired bin dates and types
102
+ for pair in pairs:
103
+ # This isn't necessary, but better safe than sorry
104
+ collection_date = datetime.strptime(pair[0], date_format).strftime(
105
+ date_format
106
+ )
107
+ # Change the formatting of the purple bins to replace the hyphens with slashes
108
+ if pair[1] == "Batteries-small electricals-textiles":
109
+ bin_type = pair[1].replace("-", "/").strip()
110
+ else:
111
+ bin_type = pair[1]
112
+
113
+ # Add the data into the dictionary
114
+ data["bins"].append({"type": bin_type, "collectionDate": collection_date})
115
+
116
+ return data
@@ -1,4 +1,5 @@
1
1
  from bs4 import BeautifulSoup
2
+
2
3
  from uk_bin_collection.uk_bin_collection.common import *
3
4
  from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
4
5
 
@@ -31,12 +32,12 @@ class CouncilClass(AbstractGetBinDataClass):
31
32
  params = {
32
33
  "RequestType": "LocalInfo",
33
34
  "ms": "ValeOfGlamorgan/AllMaps",
34
- "group": "Community and Living|Refuse HIDE2",
35
- "type": "json",
35
+ "group": "Waste|new_refuse",
36
+ "type": "jsonp",
36
37
  "callback": "AddressInfoCallback",
37
38
  "uid": user_uprn,
38
- "import": "jQuery35108514154283927682_1673022974838",
39
- "_": "1673022974840",
39
+ "import": "jQuery35107288886041176057_1736292844067",
40
+ "_": "1736292844068",
40
41
  }
41
42
 
42
43
  # Get a response from the council
@@ -46,13 +47,15 @@ class CouncilClass(AbstractGetBinDataClass):
46
47
  headers=headers,
47
48
  ).text
48
49
 
50
+ response = response.replace("AddressInfoCallback(", "").rstrip(");")
51
+
49
52
  # Load the JSON and seek out the bin week text, then add it to the calendar URL. Also take the weekly
50
53
  # collection type and generate dates for it. Then make a GET request for the calendar
51
54
  bin_week = str(
52
- json.loads(response)["Results"]["Refuse_HIDE2"]["Your_Refuse_round_is"]
55
+ json.loads(response)["Results"]["waste"]["roundday_residual"]
53
56
  ).replace(" ", "-")
54
57
  weekly_collection = str(
55
- json.loads(response)["Results"]["Refuse_HIDE2"]["Recycling__type"]
58
+ json.loads(response)["Results"]["waste"]["recycling_code"]
56
59
  ).capitalize()
57
60
  weekly_dates = get_weekday_dates_in_period(
58
61
  datetime.now(), days_of_week.get(bin_week.split("-")[0].strip()), amount=48
@@ -53,6 +53,9 @@ class CouncilClass(AbstractGetBinDataClass):
53
53
 
54
54
  data = {"bins": []}
55
55
 
56
+ current_year = datetime.now().year
57
+ next_year = current_year + 1
58
+
56
59
  # Page has slider info side by side, which are two instances of this class
57
60
  for bin in soup.find_all("div", {"class": "bintxt"}):
58
61
  try:
@@ -74,23 +77,31 @@ class CouncilClass(AbstractGetBinDataClass):
74
77
  if contains_date(bin_date_info[0]):
75
78
  bin_date = get_next_occurrence_from_day_month(
76
79
  datetime.strptime(
77
- bin_date_info[0] + " " + datetime.today().strftime("%Y"),
78
- "%A %d %B - %Y",
80
+ bin_date_info[0],
81
+ "%A %d %B -",
79
82
  )
80
- ).strftime(date_format)
83
+ )
81
84
  # On exceptional collection schedule (e.g. around English Bank Holidays), date will be contained in the second stripped string
82
85
  else:
83
86
  bin_date = get_next_occurrence_from_day_month(
84
87
  datetime.strptime(
85
- bin_date_info[1] + " " + datetime.today().strftime("%Y"),
86
- "%A %d %B - %Y",
88
+ bin_date_info[1],
89
+ "%A %d %B -",
87
90
  )
88
- ).strftime(date_format)
91
+ )
89
92
  except Exception as ex:
90
93
  raise ValueError(f"Error parsing bin data: {ex}")
91
94
 
95
+ if (datetime.now().month == 12) and (bin_date.month == 1):
96
+ bin_date = bin_date.replace(year=next_year)
97
+ else:
98
+ bin_date = bin_date.replace(year=current_year)
99
+
92
100
  # Build data dict for each entry
93
- dict_data = {"type": bin_type, "collectionDate": bin_date}
101
+ dict_data = {
102
+ "type": bin_type,
103
+ "collectionDate": bin_date.strftime(date_format),
104
+ }
94
105
  data["bins"].append(dict_data)
95
106
 
96
107
  data["bins"].sort(
@@ -42,14 +42,14 @@ class CouncilClass(AbstractGetBinDataClass):
42
42
  wait = WebDriverWait(driver, 60)
43
43
  address_entry_field = wait.until(
44
44
  EC.presence_of_element_located(
45
- (By.XPATH, '//*[@id="combobox-input-19"]')
45
+ (By.XPATH, '//*[@id="combobox-input-20"]')
46
46
  )
47
47
  )
48
48
 
49
49
  address_entry_field.send_keys(str(full_address))
50
50
 
51
51
  address_entry_field = wait.until(
52
- EC.element_to_be_clickable((By.XPATH, '//*[@id="combobox-input-19"]'))
52
+ EC.element_to_be_clickable((By.XPATH, '//*[@id="combobox-input-20"]'))
53
53
  )
54
54
  address_entry_field.click()
55
55
  address_entry_field.send_keys(Keys.BACKSPACE)
@@ -57,7 +57,7 @@ class CouncilClass(AbstractGetBinDataClass):
57
57
 
58
58
  first_found_address = wait.until(
59
59
  EC.element_to_be_clickable(
60
- (By.XPATH, '//*[@id="dropdown-element-19"]/ul')
60
+ (By.XPATH, '//*[@id="dropdown-element-20"]/ul')
61
61
  )
62
62
  )
63
63
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: uk_bin_collection
3
- Version: 0.127.2
3
+ Version: 0.127.3
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=rvu_PBl9QXNOcrHuTaHr9a9U40sQtncdI4BgTniJxP8,114370
5
+ uk_bin_collection/tests/input.json,sha256=P1EVRcGMASZCNVTAfhiQntWctYAdxa8nBytUeHLB0vY,114379
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
@@ -57,7 +57,7 @@ uk_bin_collection/uk_bin_collection/councils/CalderdaleCouncil.py,sha256=OJZcHYl
57
57
  uk_bin_collection/uk_bin_collection/councils/CannockChaseDistrictCouncil.py,sha256=ZamevXN8_Q8mRZOTESWtkb8jVyDXkTczcmhXMAVVSkM,2276
58
58
  uk_bin_collection/uk_bin_collection/councils/CanterburyCityCouncil.py,sha256=2s8OL2H0QlUaNu6gUWcoAKHrRdLuQzfMHjcSZuLYbB0,1771
59
59
  uk_bin_collection/uk_bin_collection/councils/CardiffCouncil.py,sha256=_k3sT_WR-gnjjt3tHQ-L2-keP9sdBV0ZeW7gHDzFPYo,7208
60
- uk_bin_collection/uk_bin_collection/councils/CarmarthenshireCountyCouncil.py,sha256=lcZdnARG64NZMn9NxwANaxCk_Uq6pXRBpPXfhbd-3bE,1883
60
+ uk_bin_collection/uk_bin_collection/councils/CarmarthenshireCountyCouncil.py,sha256=viiZprMos_qcD44dki5_RRVZgGE4cH4zSHAzYRKrjHw,1864
61
61
  uk_bin_collection/uk_bin_collection/councils/CastlepointDistrictCouncil.py,sha256=JVPYUIlU2ISgbUSr5AOOXNK6IFQFtQmhZyYIMAOedD4,3858
62
62
  uk_bin_collection/uk_bin_collection/councils/CharnwoodBoroughCouncil.py,sha256=tXfzMetN6wxahuGGRp2mIyCCDSL4F2aG61HhUxw6COQ,2172
63
63
  uk_bin_collection/uk_bin_collection/councils/ChelmsfordCityCouncil.py,sha256=EB88D0MNJwuDZ2GX1ENc5maGYx17mnHTCtNl6s-v11E,5090
@@ -114,7 +114,7 @@ uk_bin_collection/uk_bin_collection/councils/FolkstoneandHytheDistrictCouncil.py
114
114
  uk_bin_collection/uk_bin_collection/councils/ForestOfDeanDistrictCouncil.py,sha256=YWT2GM2-bQ3Zh9ps1K14XRZfanuJOlV-zHpOOYMXAXY,4893
115
115
  uk_bin_collection/uk_bin_collection/councils/GatesheadCouncil.py,sha256=SRCgYhYs6rv_8C1UEDVORHZgXxcJkoZBjzdYS4Lu-ew,4531
116
116
  uk_bin_collection/uk_bin_collection/councils/GedlingBoroughCouncil.py,sha256=XzfFMCwclh9zAJgsbaj4jywjdiH0wPaFicaVsLrN3ms,2297
117
- uk_bin_collection/uk_bin_collection/councils/GlasgowCityCouncil.py,sha256=-QKWlavyDqydJz97WYywvOjBC9fJmS530HyHnnxTe1A,2974
117
+ uk_bin_collection/uk_bin_collection/councils/GlasgowCityCouncil.py,sha256=9Rk9KfcglJvRhh4373OfRX-fwywE2xgwx5KejqzV5fE,3399
118
118
  uk_bin_collection/uk_bin_collection/councils/GloucesterCityCouncil.py,sha256=8Wjvmdvg5blHVrREaEnhhWZaWhYVP4v_KdDVPLIUxaU,4889
119
119
  uk_bin_collection/uk_bin_collection/councils/GraveshamBoroughCouncil.py,sha256=ueQ9xFiTxMUBTGV9VjtySHA1EFWliTM0AeNePBIG9ho,4568
120
120
  uk_bin_collection/uk_bin_collection/councils/GuildfordCouncil.py,sha256=9pVrmQhZcK2AD8gX8mNvP--L4L9KaY6L3B822VX6fec,5695
@@ -157,7 +157,7 @@ uk_bin_collection/uk_bin_collection/councils/MaldonDistrictCouncil.py,sha256=PMV
157
157
  uk_bin_collection/uk_bin_collection/councils/MalvernHillsDC.py,sha256=iQG0EkX2npBicvsGKQRYyBGSBvKVUbKvUvvwrC9xV1A,2100
158
158
  uk_bin_collection/uk_bin_collection/councils/ManchesterCityCouncil.py,sha256=RY301_82z3-xInGai5ocT7rzoV75ATbf0N7uxn8Z9LE,3110
159
159
  uk_bin_collection/uk_bin_collection/councils/MansfieldDistrictCouncil.py,sha256=F5AiTxImrnjE1k3ry96bfstOf5XSNBJS_4qqmymmh3w,1386
160
- uk_bin_collection/uk_bin_collection/councils/MertonCouncil.py,sha256=VGN4L7rq9D_nJ7i15aMioyZsoiA0Bu0RhZToBiajkr0,2350
160
+ uk_bin_collection/uk_bin_collection/councils/MertonCouncil.py,sha256=Dg8CA0d8ox_nE26LnnjBWOKJ1uOdV0w6Hj4Fft4SUQU,2340
161
161
  uk_bin_collection/uk_bin_collection/councils/MidAndEastAntrimBoroughCouncil.py,sha256=oOWwU5FSgGej2Mv7FQ66N-EzS5nZgmGsd0WnfLWUc1I,5238
162
162
  uk_bin_collection/uk_bin_collection/councils/MidDevonCouncil.py,sha256=RjBZ7R3_Pax9p1d2DCygqryjV1RP4BYvqb-rT_KyOEg,3322
163
163
  uk_bin_collection/uk_bin_collection/councils/MidSuffolkDistrictCouncil.py,sha256=h6M-v5jVYe7OlQ47Vf-0pEgECZLOOacK3_XE6zbpsM4,6329
@@ -197,7 +197,7 @@ uk_bin_collection/uk_bin_collection/councils/OxfordCityCouncil.py,sha256=d_bY0cX
197
197
  uk_bin_collection/uk_bin_collection/councils/PerthAndKinrossCouncil.py,sha256=Kos5GzN2co3Ij3tSHOXB9S71Yt78RROCfVRtnh7M1VU,3657
198
198
  uk_bin_collection/uk_bin_collection/councils/PlymouthCouncil.py,sha256=FJqpJ0GJhpjYeyZ9ioZPkKGl-zrqMD3y5iKa07e_i30,3202
199
199
  uk_bin_collection/uk_bin_collection/councils/PortsmouthCityCouncil.py,sha256=xogNgVvwM5FljCziiNLgZ_wzkOnrQkifi1dkPMDRMtg,5588
200
- uk_bin_collection/uk_bin_collection/councils/PowysCouncil.py,sha256=E6AGmbU3GfmScrpS-hrnCz4uOwucmckq4R-hLmq80b8,5004
200
+ uk_bin_collection/uk_bin_collection/councils/PowysCouncil.py,sha256=FYdENaJ1ekGAPxd75b0wrizhlDU0SOu03jXoyon6M7Y,5094
201
201
  uk_bin_collection/uk_bin_collection/councils/PrestonCityCouncil.py,sha256=3Nuin2hQsiEsbJR_kHldtzRhzmnPFctH7C7MFG7thj8,3838
202
202
  uk_bin_collection/uk_bin_collection/councils/ReadingBoroughCouncil.py,sha256=ZlQjU0IeKylGE9VlivSMh4XKwoLgntESPiylSOYkuD4,1009
203
203
  uk_bin_collection/uk_bin_collection/councils/RedditchBoroughCouncil.py,sha256=8QmcpStCT7c-CLhmiQ8ZeEyvtysU110VDiMQdfQTErk,2469
@@ -228,7 +228,7 @@ uk_bin_collection/uk_bin_collection/councils/SouthHamsDistrictCouncil.py,sha256=
228
228
  uk_bin_collection/uk_bin_collection/councils/SouthKestevenDistrictCouncil.py,sha256=_26ouWln5VrKiIFcp2b6ZzuwCKpp3aNcS2n5d4-8NsA,6210
229
229
  uk_bin_collection/uk_bin_collection/councils/SouthLanarkshireCouncil.py,sha256=fj-eZI0yrvQVCv8GvhcovZ3b9bV6Xv_ws3IunWjnv4U,3126
230
230
  uk_bin_collection/uk_bin_collection/councils/SouthNorfolkCouncil.py,sha256=C2qIZjjbl9JnuukX9OH2RbfP0hSdp3uX76APGY33qKs,4622
231
- uk_bin_collection/uk_bin_collection/councils/SouthOxfordshireCouncil.py,sha256=uVvyqQ0jr4VryjY5MU-c5PpYcrZvqt16oxAH3ekMjA4,3890
231
+ uk_bin_collection/uk_bin_collection/councils/SouthOxfordshireCouncil.py,sha256=ulcs75g6vgZ_XHC96badUrI30EIZiWFKtW82swsQ4zA,4020
232
232
  uk_bin_collection/uk_bin_collection/councils/SouthRibbleCouncil.py,sha256=OdexbeiI5WsCfjlsnHjAce8oGF5fW-n7q2XOuxcpHzw,3604
233
233
  uk_bin_collection/uk_bin_collection/councils/SouthStaffordshireDistrictCouncil.py,sha256=ACQMHWyamnj1ag3gNF-8Jhp-DKUok1GhFdnzH4nCzwU,3201
234
234
  uk_bin_collection/uk_bin_collection/councils/SouthTynesideCouncil.py,sha256=dxXGrJfg_fn2IPTBgq6Duwy0WY8GYLafMuisaCjOnbs,3426
@@ -236,14 +236,15 @@ uk_bin_collection/uk_bin_collection/councils/SouthwarkCouncil.py,sha256=Z6JIbUt3
236
236
  uk_bin_collection/uk_bin_collection/councils/StAlbansCityAndDistrictCouncil.py,sha256=mPZz6Za6kTSkrfHnj0OfwtnpRYR1dKvxbuFEKnWsiL8,1451
237
237
  uk_bin_collection/uk_bin_collection/councils/StHelensBC.py,sha256=X9dvnQTNn7QUO8gv1A587e1aDI92TWN4iNLATTn3H3w,4777
238
238
  uk_bin_collection/uk_bin_collection/councils/StaffordBoroughCouncil.py,sha256=9Qj4HJI7Dbiqb2mVSG2UtkBe27Y7wvQ5SYFTwGzJ5g0,2292
239
- uk_bin_collection/uk_bin_collection/councils/StaffordshireMoorlandsDistrictCouncil.py,sha256=_N8Cg26EbTaKp0RsWvQuELVcZDHbT2BlD2LW8qhkS_Q,4361
239
+ uk_bin_collection/uk_bin_collection/councils/StaffordshireMoorlandsDistrictCouncil.py,sha256=vdSnDbiKLQIdvvqVXDi2butZXRBMxv401aIrkLkKgy4,4370
240
240
  uk_bin_collection/uk_bin_collection/councils/StevenageBoroughCouncil.py,sha256=EiDIyOlHhdiJ-YYjo7T5uA5sN2jzNoysu6FctjuAjBI,3549
241
241
  uk_bin_collection/uk_bin_collection/councils/StockportBoroughCouncil.py,sha256=v0HmioNVRoU1-9OnLJl2V3M5pVR1aVu1BgOLHFR1Sf4,1429
242
242
  uk_bin_collection/uk_bin_collection/councils/StocktonOnTeesCouncil.py,sha256=obaBgsmIJ95Ah7KaTNWdU107tZDPVuuJox0mGUoGjNk,6070
243
243
  uk_bin_collection/uk_bin_collection/councils/StokeOnTrentCityCouncil.py,sha256=KM0EgWeO7mk8lkozX0RCTfMchXdjrfBqIjCiOtB09aM,2884
244
244
  uk_bin_collection/uk_bin_collection/councils/StratfordUponAvonCouncil.py,sha256=DMTAcXT_lay8Cl1hBbzf_LN7-GwTDGxT3Ug9QJkaF9Y,3936
245
- uk_bin_collection/uk_bin_collection/councils/StroudDistrictCouncil.py,sha256=9bYWppi7ViLGHL4VEg--nFn28MLYJYbiEntull1uZxU,3561
245
+ uk_bin_collection/uk_bin_collection/councils/StroudDistrictCouncil.py,sha256=Akx80Ve7D8RVdIW1vkWLYp80VrhL6Qc3dMMKnbFWUhY,3653
246
246
  uk_bin_collection/uk_bin_collection/councils/SunderlandCityCouncil.py,sha256=4DnKyyu56_AwuchD6_oL1dvpDStMvkkxQtYN79rUKOs,3825
247
+ uk_bin_collection/uk_bin_collection/councils/SurreyHeathBoroughCouncil.py,sha256=MROVvf7RSRYYjM2ZDD83rAEwf8BSnqXVrasgBiJC92A,5220
247
248
  uk_bin_collection/uk_bin_collection/councils/SwaleBoroughCouncil.py,sha256=LNewGYrRHPforrsyZO7EaAy7Wx7VXi3I_tZ0SO9VcAA,4408
248
249
  uk_bin_collection/uk_bin_collection/councils/SwanseaCouncil.py,sha256=nmVPoPhnFgVi--vczX2i4Sf3bqM5RWJuwfhioRUr5XE,2303
249
250
  uk_bin_collection/uk_bin_collection/councils/SwindonBoroughCouncil.py,sha256=lSIykpkBjVwQSf3rrnrNuh7YRepgnkKQLbf1iErMuJs,1932
@@ -261,8 +262,8 @@ uk_bin_collection/uk_bin_collection/councils/TorbayCouncil.py,sha256=JW_BS7wkfxF
261
262
  uk_bin_collection/uk_bin_collection/councils/TorridgeDistrictCouncil.py,sha256=6gOO02pYU0cbj3LAHiBVNG4zkFMyIGbkE2jAye3KcGM,6386
262
263
  uk_bin_collection/uk_bin_collection/councils/TunbridgeWellsCouncil.py,sha256=s8Nm9Ef-4561mEXPa0ylYHrXyYIulgCcNV2uAnrXyZk,2846
263
264
  uk_bin_collection/uk_bin_collection/councils/UttlesfordDistrictCouncil.py,sha256=GSELWbSn5jtznv6FSLIMxK6CyQ27MW9FoY_m5jhTEBA,4175
264
- uk_bin_collection/uk_bin_collection/councils/ValeofGlamorganCouncil.py,sha256=Phgb_ECiUOOkqOx6OsfsTHMCW5VQfRmOC2zgYIQhuZA,5044
265
- uk_bin_collection/uk_bin_collection/councils/ValeofWhiteHorseCouncil.py,sha256=KBKGHcWAdPC_8-CfKnLOdP7Ww6RIvlxLIJGqBsq_77g,4208
265
+ uk_bin_collection/uk_bin_collection/councils/ValeofGlamorganCouncil.py,sha256=dz3zDJsJKYYqUB-Gxf6twvP6kG_wyENaszxXxK4iJn0,5089
266
+ uk_bin_collection/uk_bin_collection/councils/ValeofWhiteHorseCouncil.py,sha256=fyskrQ4-osGOeCZuB_8m2TpW8iwHr7lpl52nrR06Xpo,4441
266
267
  uk_bin_collection/uk_bin_collection/councils/WakefieldCityCouncil.py,sha256=vRfIU0Uloi1bgXqjOCpdb-EQ4oY-aismcANZRwOIFkc,4914
267
268
  uk_bin_collection/uk_bin_collection/councils/WalsallCouncil.py,sha256=wv-M3zZj0E6EIPoVB9AF_NCg_8XGM9uhqGa-F5yzoc4,2277
268
269
  uk_bin_collection/uk_bin_collection/councils/WalthamForest.py,sha256=_0ucZrZx-x49wxV7DGZsj4zcKv25HT-o2PkPabw8r68,4997
@@ -280,7 +281,7 @@ uk_bin_collection/uk_bin_collection/councils/WestLindseyDistrictCouncil.py,sha25
280
281
  uk_bin_collection/uk_bin_collection/councils/WestLothianCouncil.py,sha256=dq0jimtARvRkZiGbVFrXXZgY-BODtz3uYZ5UKn0bf64,4114
281
282
  uk_bin_collection/uk_bin_collection/councils/WestMorlandAndFurness.py,sha256=jbqV3460rn9D0yTBGWjpSe1IvWWcdGur5pzgj-hJcQ4,2513
282
283
  uk_bin_collection/uk_bin_collection/councils/WestNorthamptonshireCouncil.py,sha256=Se3Cfn_6ADjhsUzEJI_JnGkVcIbXxSTferM4ZC6pZ0g,1166
283
- uk_bin_collection/uk_bin_collection/councils/WestOxfordshireDistrictCouncil.py,sha256=bkE7BUwRIEJQyfOHyXYeaJB1ruGTFu9LHIGursIBEIQ,4859
284
+ uk_bin_collection/uk_bin_collection/councils/WestOxfordshireDistrictCouncil.py,sha256=EaKP1djwJCBb3R_rBkKv1GUphdg7U09xpb58yNgsfHs,4859
284
285
  uk_bin_collection/uk_bin_collection/councils/WestSuffolkCouncil.py,sha256=9i8AQHh-qIRPZ_5Ad97_h04-qgyLQDPV064obBzab1Y,2587
285
286
  uk_bin_collection/uk_bin_collection/councils/WiganBoroughCouncil.py,sha256=3gqFA4-BVx_In6QOu3KUNqPN4Fkn9iMlZTeopMK9p6A,3746
286
287
  uk_bin_collection/uk_bin_collection/councils/WiltshireCouncil.py,sha256=Q0ooHTQb9ynMXpSNBPk7XXEjI7zcHst3id4wxGdmVx4,5698
@@ -298,8 +299,8 @@ uk_bin_collection/uk_bin_collection/councils/YorkCouncil.py,sha256=I2kBYMlsD4bId
298
299
  uk_bin_collection/uk_bin_collection/councils/council_class_template/councilclasstemplate.py,sha256=EQWRhZ2pEejlvm0fPyOTsOHKvUZmPnxEYO_OWRGKTjs,1158
299
300
  uk_bin_collection/uk_bin_collection/create_new_council.py,sha256=m-IhmWmeWQlFsTZC4OxuFvtw5ZtB8EAJHxJTH4O59lQ,1536
300
301
  uk_bin_collection/uk_bin_collection/get_bin_data.py,sha256=YvmHfZqanwrJ8ToGch34x-L-7yPe31nB_x77_Mgl_vo,4545
301
- uk_bin_collection-0.127.2.dist-info/LICENSE,sha256=vABBUOzcrgfaTKpzeo-si9YVEun6juDkndqA8RKdKGs,1071
302
- uk_bin_collection-0.127.2.dist-info/METADATA,sha256=WfUAtwObkc-bC7GPsdxbpgsyrhAUA5yPuf7-6ghAfgc,19549
303
- uk_bin_collection-0.127.2.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
304
- uk_bin_collection-0.127.2.dist-info/entry_points.txt,sha256=36WCSGMWSc916S3Hi1ZkazzDKHaJ6CD-4fCEFm5MIao,90
305
- uk_bin_collection-0.127.2.dist-info/RECORD,,
302
+ uk_bin_collection-0.127.3.dist-info/LICENSE,sha256=vABBUOzcrgfaTKpzeo-si9YVEun6juDkndqA8RKdKGs,1071
303
+ uk_bin_collection-0.127.3.dist-info/METADATA,sha256=N5s90XpaFpVWjIAj1fQVSLB2QnHms0H6nZqXyQNsBww,19549
304
+ uk_bin_collection-0.127.3.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
305
+ uk_bin_collection-0.127.3.dist-info/entry_points.txt,sha256=36WCSGMWSc916S3Hi1ZkazzDKHaJ6CD-4fCEFm5MIao,90
306
+ uk_bin_collection-0.127.3.dist-info/RECORD,,