uk_bin_collection 0.127.2__py3-none-any.whl → 0.127.3__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,,