uk_bin_collection 0.99.1__py3-none-any.whl → 0.101.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.
@@ -340,6 +340,13 @@
340
340
  "wiki_name": "Dover District Council",
341
341
  "wiki_note": "Replace XXXXXXXXXXXX with your UPRN. To get the UPRN, you can use [FindMyAddress](https://www.findmyaddress.co.uk/search)."
342
342
  },
343
+ "DudleyCouncil": {
344
+ "url": "https://my.dudley.gov.uk",
345
+ "wiki_command_url_override": "https://my.dudley.gov.uk",
346
+ "uprn": "90014244",
347
+ "wiki_name": "Dudley Council",
348
+ "wiki_note": "You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find the UPRN."
349
+ },
343
350
  "DurhamCouncil": {
344
351
  "skip_get_url": true,
345
352
  "uprn": "200003218818",
@@ -712,6 +719,12 @@
712
719
  "wiki_name": "Mid and East Antrim Borough Council",
713
720
  "wiki_note": "Pass the house name/number plus the name of the street with the postcode parameter, wrapped in double quotes. Check the address in the web site first. This version will only pick the first SHOW button returned by the search or if it is fully unique. The search is not very predictable (e.g. house number 4 returns 14,24,4,44 etc.)."
714
721
  },
722
+ "MidlothianCouncil": {
723
+ "url": "https://www.midlothian.gov.uk/directory_record/92551426/glenesk_bonnyrigg_eh19_3je",
724
+ "wiki_command_url_override": "https://www.midlothian.gov.uk/directory_record/XXXXXX/XXXXXX",
725
+ "wiki_name": "Midlothian Council",
726
+ "wiki_note": "Follow the instructions [here](https://www.midlothian.gov.uk/info/1054/bins_and_recycling/343/bin_collection_days) until you get the page that shows the weekly collections for your address then copy the URL and replace the URL in the command."
727
+ },
715
728
  "MidSussexDistrictCouncil": {
716
729
  "house_number": "OAKLANDS, OAKLANDS ROAD RH16 1SS",
717
730
  "postcode": "RH16 1SS",
@@ -860,6 +873,13 @@
860
873
  "url": "https://www.northyorks.gov.uk/bin-calendar/lookup",
861
874
  "wiki_name": "North Yorkshire Council"
862
875
  },
876
+ "NorwichCityCouncil": {
877
+ "url": "https://www.norwich.gov.uk",
878
+ "wiki_command_url_override": "https://www.norwich.gov.uk",
879
+ "uprn": "100090888980",
880
+ "wiki_name": "Norwich City Council",
881
+ "wiki_note": "You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find the UPRN."
882
+ },
863
883
  "NorthumberlandCouncil": {
864
884
  "house_number": "22",
865
885
  "postcode": "NE46 1UQ",
@@ -886,6 +906,13 @@
886
906
  "wiki_name": "Perth and Kinross Council",
887
907
  "wiki_note": "You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find the UPRN."
888
908
  },
909
+ "PlymouthCouncil": {
910
+ "url": "https://www.plymouth.gov.uk",
911
+ "wiki_command_url_override": "https://www.plymouth.gov.uk",
912
+ "uprn": "100040420582",
913
+ "wiki_name": "Plymouth Council",
914
+ "wiki_note": "You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find the UPRN."
915
+ },
889
916
  "PortsmouthCityCouncil": {
890
917
  "postcode": "PO4 0LE",
891
918
  "skip_get_url": true,
@@ -1065,6 +1092,13 @@
1065
1092
  "url": "https://www.southoxon.gov.uk/south-oxfordshire-district-council/recycling-rubbish-and-waste/when-is-your-collection-day/",
1066
1093
  "wiki_name": "South Oxfordshire Council"
1067
1094
  },
1095
+ "SouthRibbleCouncil": {
1096
+ "url": "https://www.southribble.gov.uk",
1097
+ "wiki_command_url_override": "https://www.southribble.gov.uk",
1098
+ "uprn": "010013246384",
1099
+ "wiki_name": "South Ribble Council",
1100
+ "wiki_note": "You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find the UPRN."
1101
+ },
1068
1102
  "SouthTynesideCouncil": {
1069
1103
  "house_number": "1",
1070
1104
  "postcode": "NE33 3JW",
@@ -0,0 +1,81 @@
1
+ import time
2
+
3
+ import requests
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
+ # import the wonderful Beautiful Soup and the URL grabber
10
+ class CouncilClass(AbstractGetBinDataClass):
11
+ """
12
+ Concrete classes have to implement all abstract operations of the
13
+ base class. They can also override some operations with a default
14
+ implementation.
15
+ """
16
+
17
+ def parse_data(self, page: str, **kwargs) -> dict:
18
+
19
+ user_uprn = kwargs.get("uprn")
20
+ check_uprn(user_uprn)
21
+ bindata = {"bins": []}
22
+
23
+ SESSION_URL = "https://my.dudley.gov.uk/authapi/isauthenticated?uri=https%253A%252F%252Fmy.dudley.gov.uk%252Fen%252FAchieveForms%252F%253Fform_uri%253Dsandbox-publish%253A%252F%252FAF-Process-373f5628-9aae-4e9e-ae09-ea7cd0588201%252FAF-Stage-52ec040b-10e6-440f-b964-23f924741496%252Fdefinition.json%2526redirectlink%253D%25252Fen%2526cancelRedirectLink%253D%25252Fen%2526consentMessage%253Dyes&hostname=my.dudley.gov.uk&withCredentials=true"
24
+
25
+ API_URL = "https://my.dudley.gov.uk/apibroker/runLookup"
26
+
27
+ data = {
28
+ "formValues": {
29
+ "My bins": {
30
+ "uprnToCheck": {"value": user_uprn},
31
+ }
32
+ },
33
+ }
34
+
35
+ headers = {
36
+ "Content-Type": "application/json",
37
+ "Accept": "application/json",
38
+ "User-Agent": "Mozilla/5.0",
39
+ "X-Requested-With": "XMLHttpRequest",
40
+ "Referer": "https://my.dudley.gov.uk/fillform/?iframe_id=fillform-frame-1&db_id=",
41
+ }
42
+ s = requests.session()
43
+ r = s.get(SESSION_URL)
44
+ r.raise_for_status()
45
+ session_data = r.json()
46
+ sid = session_data["auth-session"]
47
+ params = {
48
+ "id": "64899d4c2574c",
49
+ "repeat_against": "",
50
+ "noRetry": "true",
51
+ "getOnlyTokens": "undefined",
52
+ "log_id": "",
53
+ "app_name": "AF-Renderer::Self",
54
+ # unix_timestamp
55
+ "_": str(int(time.time() * 1000)),
56
+ "sid": sid,
57
+ }
58
+ r = s.post(API_URL, json=data, headers=headers, params=params)
59
+ r.raise_for_status()
60
+ data = r.json()
61
+ rows_data = data["integration"]["transformed"]["rows_data"]["0"]
62
+ if not isinstance(rows_data, dict):
63
+ raise ValueError("Invalid data returned from API")
64
+ BIN_TYPES = [
65
+ ("refuseDate", "Refuse"),
66
+ ("recyclingDate", "Recycling"),
67
+ ("gardenDate", "Garden Waste"),
68
+ ]
69
+ bin_type_dict = dict(BIN_TYPES)
70
+
71
+ for row in rows_data.items():
72
+ if (row[0].endswith("Date")) and not row[0].endswith("EndDate"):
73
+ if row[1]:
74
+ bin_type = bin_type_dict.get(row[0], row[0])
75
+ collection_date = datetime.strptime(row[1], "%Y-%m-%d").strftime(
76
+ "%d/%m/%Y"
77
+ )
78
+ dict_data = {"type": bin_type, "collectionDate": collection_date}
79
+ bindata["bins"].append(dict_data)
80
+
81
+ return bindata
@@ -0,0 +1,68 @@
1
+ from bs4 import BeautifulSoup
2
+
3
+ from uk_bin_collection.uk_bin_collection.common import *
4
+ from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
5
+
6
+
7
+ # import the wonderful Beautiful Soup and the URL grabber
8
+ class CouncilClass(AbstractGetBinDataClass):
9
+ """
10
+ Concrete classes have to implement all abstract operations of the
11
+ base class. They can also override some operations with a default
12
+ implementation.
13
+ """
14
+
15
+ def parse_data(self, page: str, **kwargs) -> dict:
16
+ # Parse the HTML content using BeautifulSoup
17
+ soup = BeautifulSoup(page.text, features="html.parser")
18
+
19
+ # Initialize a dictionary to store the parsed bin data
20
+ data = {"bins": []}
21
+
22
+ # Define a mapping of bin collection labels to their corresponding types
23
+ bin_types = {
24
+ "Next recycling collection": "Recycling",
25
+ "Next grey bin collection": "Grey Bin",
26
+ "Next brown bin collection": "Brown Bin",
27
+ "Next food bin collection": "Food Bin",
28
+ }
29
+
30
+ # Locate the <ul> element with the class "data-table"
31
+ bin_collections = soup.find("ul", {"class": "data-table"})
32
+
33
+ # Proceed only if the <ul> element is found
34
+ if bin_collections:
35
+ # Retrieve all <li> elements within the <ul>, skipping the first two (not relevant)
36
+ bin_items = bin_collections.find_all("li")[2:]
37
+
38
+ # Iterate through each bin item
39
+ for bin in bin_items:
40
+ bin_type = None
41
+ # Retrieve the bin type from the header if it exists
42
+ if bin.h2 and bin.h2.text.strip() in bin_types:
43
+ bin_type = bin_types[bin.h2.text.strip()]
44
+
45
+ bin_collection_date = None
46
+ # Retrieve the bin collection date from the div if it exists
47
+ if bin.div and bin.div.text.strip():
48
+ try:
49
+ # Parse the collection date from the div text and format it
50
+ bin_collection_date = datetime.strptime(
51
+ bin.div.text.strip(),
52
+ "%A %d/%m/%Y",
53
+ ).strftime(date_format)
54
+ except ValueError:
55
+ # If date parsing fails, keep bin_collection_date as None
56
+ pass
57
+
58
+ # If both bin type and collection date are identified, add to the data
59
+ if bin_type and bin_collection_date:
60
+ data["bins"].append(
61
+ {
62
+ "type": bin_type,
63
+ "collectionDate": bin_collection_date,
64
+ }
65
+ )
66
+
67
+ # Return the parsed data, which may be empty if no bins were found
68
+ return data
@@ -0,0 +1,75 @@
1
+ import time
2
+
3
+ import requests
4
+ from bs4 import BeautifulSoup
5
+
6
+ from uk_bin_collection.uk_bin_collection.common import *
7
+ from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
8
+
9
+
10
+ # import the wonderful Beautiful Soup and the URL grabber
11
+ class CouncilClass(AbstractGetBinDataClass):
12
+ """
13
+ Concrete classes have to implement all abstract operations of the
14
+ base class. They can also override some operations with a default
15
+ implementation.
16
+ """
17
+
18
+ def parse_data(self, page: str, **kwargs) -> dict:
19
+
20
+ user_uprn = kwargs.get("uprn")
21
+ check_uprn(user_uprn)
22
+ bindata = {"bins": []}
23
+
24
+ API_URL = "https://maps.norwich.gov.uk/arcgis/rest/services/MyNorwich/PropertyDetails/FeatureServer/2/query"
25
+
26
+ params = {
27
+ "f": "json",
28
+ "where": f"UPRN='{user_uprn}' or UPRN='0{user_uprn}'",
29
+ "returnGeometry": "true",
30
+ "spatialRel": "esriSpatialRelIntersects",
31
+ "geometryType": "esriGeometryPolygon",
32
+ "inSR": "4326",
33
+ "outFields": "*",
34
+ "outSR": "4326",
35
+ "resultRecordCount": "1000",
36
+ }
37
+
38
+ r = requests.get(API_URL, params=params)
39
+
40
+ data = r.json()
41
+ data = data["features"][0]["attributes"]["WasteCollectionHtml"]
42
+ soup = BeautifulSoup(data, "html.parser")
43
+
44
+ alternateCheck = soup.find("p")
45
+ if alternateCheck.text.__contains__("alternate"):
46
+ alternateCheck = True
47
+ else:
48
+ alternateCheck = False
49
+
50
+ strong = soup.find_all("strong")
51
+
52
+ if alternateCheck:
53
+ bin_types = strong[2].text.strip().replace(".", "").split(" and ")
54
+ for bin in bin_types:
55
+ dict_data = {
56
+ "type": bin,
57
+ "collectionDate": strong[1].text.strip(),
58
+ }
59
+ bindata["bins"].append(dict_data)
60
+ else:
61
+ p_tag = soup.find_all("p")
62
+ i = 1
63
+ for p in p_tag:
64
+ bin_types = (
65
+ p.text.split("Your ")[1].split(" is collected")[0].split(" and ")
66
+ )
67
+ for bin in bin_types:
68
+ dict_data = {
69
+ "type": bin,
70
+ "collectionDate": strong[i].text.strip(),
71
+ }
72
+ bindata["bins"].append(dict_data)
73
+ i += 2
74
+
75
+ return bindata
@@ -0,0 +1,81 @@
1
+ import time
2
+
3
+ import requests
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
+ # import the wonderful Beautiful Soup and the URL grabber
10
+ class CouncilClass(AbstractGetBinDataClass):
11
+ """
12
+ Concrete classes have to implement all abstract operations of the
13
+ base class. They can also override some operations with a default
14
+ implementation.
15
+ """
16
+
17
+ def parse_data(self, page: str, **kwargs) -> dict:
18
+
19
+ user_uprn = kwargs.get("uprn")
20
+ check_uprn(user_uprn)
21
+ bindata = {"bins": []}
22
+
23
+ SESSION_URL = "https://plymouth-self.achieveservice.com/authapi/isauthenticated?uri=https%253A%252F%252Fplymouth-self.achieveservice.com%252Fen%252FAchieveForms%252F%253Fform_uri%253Dsandbox-publish%253A%252F%252FAF-Process-31283f9a-3ae7-4225-af71-bf3884e0ac1b%252FAF-Stagedba4a7d5-e916-46b6-abdb-643d38bec875%252Fdefinition.json%2526redirectlink%253D%25252Fen%2526cancelRedirectLink%253D%25252Fen%2526consentMessage%253Dyes&hostname=plymouth-self.achieveservice.com&withCredentials=true"
24
+
25
+ API_URL = "https://plymouth-self.achieveservice.com/apibroker/runLookup"
26
+
27
+ data = {
28
+ "formValues": {
29
+ "Section 1": {
30
+ "number1": {"value": user_uprn},
31
+ "lastncoll": {"value": "0"},
32
+ "nextncoll": {"value": "9"},
33
+ }
34
+ },
35
+ }
36
+
37
+ headers = {
38
+ "Content-Type": "application/json",
39
+ "Accept": "application/json",
40
+ "User-Agent": "Mozilla/5.0",
41
+ "X-Requested-With": "XMLHttpRequest",
42
+ "Referer": "https://plymouth-self.achieveservice.com/fillform/?iframe_id=fillform-frame-1&db_id=",
43
+ }
44
+ s = requests.session()
45
+ r = s.get(SESSION_URL)
46
+ r.raise_for_status()
47
+ session_data = r.json()
48
+ sid = session_data["auth-session"]
49
+ params = {
50
+ "id": "5c99439d85f83",
51
+ "repeat_against": "",
52
+ "noRetry": "false",
53
+ "getOnlyTokens": "undefined",
54
+ "log_id": "",
55
+ "app_name": "AF-Renderer::Self",
56
+ # unix_timestamp
57
+ "_": str(int(time.time() * 1000)),
58
+ "sid": sid,
59
+ }
60
+ r = s.post(API_URL, json=data, headers=headers, params=params)
61
+ r.raise_for_status()
62
+ data = r.json()
63
+ rows_data = data["integration"]["transformed"]["rows_data"]
64
+ if not isinstance(rows_data, dict):
65
+ raise ValueError("Invalid data returned from API")
66
+ BIN_TYPES = [
67
+ ("OR", "Garden Waste Bin"),
68
+ ("DO", "Brown Domestic Bin"),
69
+ ("RE", "Green Recycling Bin"),
70
+ ]
71
+ bin_type_dict = dict(BIN_TYPES)
72
+
73
+ for row in rows_data.items():
74
+ bin_type = bin_type_dict.get(row[1]["Round_Type"], row[1]["Round_Type"])
75
+ collection_date = datetime.strptime(
76
+ row[1]["Date"].split("T")[0], "%Y-%m-%d"
77
+ ).strftime("%d/%m/%Y")
78
+ dict_data = {"type": bin_type, "collectionDate": collection_date}
79
+ bindata["bins"].append(dict_data)
80
+
81
+ return bindata
@@ -0,0 +1,83 @@
1
+ import time
2
+
3
+ import requests
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
+ # import the wonderful Beautiful Soup and the URL grabber
10
+ class CouncilClass(AbstractGetBinDataClass):
11
+ """
12
+ Concrete classes have to implement all abstract operations of the
13
+ base class. They can also override some operations with a default
14
+ implementation.
15
+ """
16
+
17
+ def parse_data(self, page: str, **kwargs) -> dict:
18
+
19
+ user_uprn = kwargs.get("uprn")
20
+ check_uprn(user_uprn)
21
+ bindata = {"bins": []}
22
+
23
+ SESSION_URL = "https://southribble-ss.achieveservice.com/authapi/isauthenticated?uri=https%253A%252F%252Fsouthribble-ss.achieveservice.com%252FAchieveForms%252F%253Fmode%253Dfill%2526form_uri%253Dsandbox-publish%25253A%252F%252FAF-Process-d3971054-2e93-4a74-8375-494347dd13fd%252FAF-Stage-2693df73-8a5f-4e24-86b8-456ef81dd4a1%252Fdefinition.json%2526process%253D1%2526process_uri%253Dsandbox-processes%25253A%252F%252FAF-Process-d3971054-2e93-4a74-8375-494347dd13fd%2526process_id%253DAF-Process-d3971054-2e93-4a74-8375-494347dd13fd%2526accept%253Dyes%2526consentMessageIds%25255B%25255D%253D3%2526accept%253Dyes%2526consentMessageIds%255B%255D%253D3&hostname=southribble-ss.achieveservice.com&withCredentials=true"
24
+
25
+ API_URL = "https://southribble-ss.achieveservice.com/apibroker/runLookup"
26
+
27
+ data = {
28
+ "formValues": {
29
+ "Your Collections": {
30
+ "PickupDate": {"value": datetime.now().strftime("%Y-%m-%d")},
31
+ },
32
+ "Your details": {
33
+ "LLPGUPRN": {"value": user_uprn},
34
+ },
35
+ },
36
+ }
37
+
38
+ headers = {
39
+ "Content-Type": "application/json",
40
+ "Accept": "application/json",
41
+ "User-Agent": "Mozilla/5.0",
42
+ "X-Requested-With": "XMLHttpRequest",
43
+ "Referer": "https://southribble-ss.achieveservice.com/fillform/?iframe_id=fillform-frame-1&db_id=",
44
+ }
45
+ s = requests.session()
46
+ r = s.get(SESSION_URL)
47
+ r.raise_for_status()
48
+ session_data = r.json()
49
+ sid = session_data["auth-session"]
50
+ params = {
51
+ "id": "58ab44ef078bd",
52
+ "repeat_against": "",
53
+ "noRetry": "false",
54
+ "getOnlyTokens": "undefined",
55
+ "log_id": "",
56
+ "app_name": "AF-Renderer::Self",
57
+ # unix_timestamp
58
+ "_": str(int(time.time() * 1000)),
59
+ "sid": sid,
60
+ }
61
+ r = s.post(API_URL, json=data, headers=headers, params=params)
62
+ r.raise_for_status()
63
+ data = r.json()
64
+ rows_data = data["integration"]["transformed"]["rows_data"]["0"]
65
+ if not isinstance(rows_data, dict):
66
+ raise ValueError("Invalid data returned from API")
67
+ BIN_TYPES = [
68
+ ("RCNextCollectionDate", "Household Waste (Non-Recyclable Waste)"),
69
+ ("RENextCollectionDate", "Blue/Green Recyclable Waste"),
70
+ ("GWNextCollectionDate", "Garden Waste Collection"),
71
+ ("FWNextCollectionDate", "Food Waste"),
72
+ ]
73
+ bin_type_dict = dict(BIN_TYPES)
74
+
75
+ for row in rows_data.items():
76
+ if row[0].endswith("NextCollectionDate"):
77
+ if row[1]:
78
+ bin_type = bin_type_dict.get(row[0], row[0])
79
+ collection_date = row[1]
80
+ dict_data = {"type": bin_type, "collectionDate": collection_date}
81
+ bindata["bins"].append(dict_data)
82
+
83
+ return bindata
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: uk_bin_collection
3
- Version: 0.99.1
3
+ Version: 0.101.0
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=QIGTQrnJfCXvtXazy0-V4dG1VlLY2hOYyvn9An7aBBQ,69217
5
+ uk_bin_collection/tests/input.json,sha256=tzx_1v1h_XLo3-dJHd5vHnX97dIJVHFjjAkC4allAXc,71114
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=LrOSt_loA1Mw3vTqaO2LpaDMu7rYJy6k5Kr-EOBln7s,3424
@@ -58,6 +58,7 @@ uk_bin_collection/uk_bin_collection/councils/DerbyshireDalesDistrictCouncil.py,s
58
58
  uk_bin_collection/uk_bin_collection/councils/DoncasterCouncil.py,sha256=b7pxoToXu6dBBYXsXmlwfPXE8BjHxt0hjCOBNlNgvX8,3118
59
59
  uk_bin_collection/uk_bin_collection/councils/DorsetCouncil.py,sha256=XUWH5BzkjPSFBLczo-Vo-Wly2JMoabm9WtI6_Mf-pO4,1523
60
60
  uk_bin_collection/uk_bin_collection/councils/DoverDistrictCouncil.py,sha256=3Zgap6kaVpDXtRfBKEL1Ms6eb0iFIipYKNtOq3Hrdd4,1891
61
+ uk_bin_collection/uk_bin_collection/councils/DudleyCouncil.py,sha256=tDGfBWD5AVEzHt-XowD4qmmDcdlOLKC0oON8jkARRAI,3134
61
62
  uk_bin_collection/uk_bin_collection/councils/DurhamCouncil.py,sha256=6O8bNsQVYQbrCYQE9Rp0c_rtkcXuxR3s9J6jn4MK4_s,1695
62
63
  uk_bin_collection/uk_bin_collection/councils/EalingCouncil.py,sha256=UhNXGi-_6NYZu50988VEvOzmAVunxOoyJ6mz0OEaUz4,1321
63
64
  uk_bin_collection/uk_bin_collection/councils/EastCambridgeshireCouncil.py,sha256=aYUVE5QqTxdj8FHhCB4EiFVDJahWJD9Pq0d1upBEvXg,1501
@@ -111,6 +112,7 @@ uk_bin_collection/uk_bin_collection/councils/MansfieldDistrictCouncil.py,sha256=
111
112
  uk_bin_collection/uk_bin_collection/councils/MertonCouncil.py,sha256=3Y2Un4xXo1sCcMsudynODSzocV_mMofWkX2JqONDb5o,1997
112
113
  uk_bin_collection/uk_bin_collection/councils/MidAndEastAntrimBoroughCouncil.py,sha256=oOWwU5FSgGej2Mv7FQ66N-EzS5nZgmGsd0WnfLWUc1I,5238
113
114
  uk_bin_collection/uk_bin_collection/councils/MidSussexDistrictCouncil.py,sha256=AZgC9wmDLEjUOtIFvf0ehF5LHturXTH4DkE3ioPSVBA,6254
115
+ uk_bin_collection/uk_bin_collection/councils/MidlothianCouncil.py,sha256=3K3X7kv1oOJkZm2ivnT8Lx0GAzPefgFSHjruwcFgO7I,2821
114
116
  uk_bin_collection/uk_bin_collection/councils/MiltonKeynesCityCouncil.py,sha256=3olsWa77L34vz-c7NgeGK9xmNuR4Ws_oAk5D4UpIkPw,2005
115
117
  uk_bin_collection/uk_bin_collection/councils/MoleValleyDistrictCouncil.py,sha256=bvCrC4Qcg0Uzp9zZGcC7-7-oJcMh2cb1VaXfdkB11oc,5257
116
118
  uk_bin_collection/uk_bin_collection/councils/NeathPortTalbotCouncil.py,sha256=ychYR2nsyk2UIb8tjWaKrLUT4hxSsHN558l3RqZ0mjw,5635
@@ -132,9 +134,11 @@ uk_bin_collection/uk_bin_collection/councils/NorthTynesideCouncil.py,sha256=N_ZR
132
134
  uk_bin_collection/uk_bin_collection/councils/NorthWestLeicestershire.py,sha256=gJj0dyQc5QUefqusKGk2LLXfWbG5tlEXUOh8KAPh3RI,4584
133
135
  uk_bin_collection/uk_bin_collection/councils/NorthYorkshire.py,sha256=2wTrr3VrZDp9-YtDPmWd649gXeWH4hbm2-Hw8Vau5Xs,1933
134
136
  uk_bin_collection/uk_bin_collection/councils/NorthumberlandCouncil.py,sha256=KEFsxEvQ159fkuFo-fza67YCnnCZ5ElwE80zTrqDEWI,4990
137
+ uk_bin_collection/uk_bin_collection/councils/NorwichCityCouncil.py,sha256=At-9dEcKBUZSrtJ2RncwvMnV0OVU3pE6kxEYbLL-Av8,2437
135
138
  uk_bin_collection/uk_bin_collection/councils/NottinghamCityCouncil.py,sha256=panTCjnsBOQ98-TBO9xVZk_jcT_gjMhx3Gg5oWxBRLo,1254
136
139
  uk_bin_collection/uk_bin_collection/councils/OldhamCouncil.py,sha256=9dlesCxNoVXlmQaqZj7QFh00smnJbm1Gnjkr_Uvzurs,1771
137
140
  uk_bin_collection/uk_bin_collection/councils/PerthAndKinrossCouncil.py,sha256=Kos5GzN2co3Ij3tSHOXB9S71Yt78RROCfVRtnh7M1VU,3657
141
+ uk_bin_collection/uk_bin_collection/councils/PlymouthCouncil.py,sha256=FJqpJ0GJhpjYeyZ9ioZPkKGl-zrqMD3y5iKa07e_i30,3202
138
142
  uk_bin_collection/uk_bin_collection/councils/PortsmouthCityCouncil.py,sha256=xogNgVvwM5FljCziiNLgZ_wzkOnrQkifi1dkPMDRMtg,5588
139
143
  uk_bin_collection/uk_bin_collection/councils/PrestonCityCouncil.py,sha256=3Nuin2hQsiEsbJR_kHldtzRhzmnPFctH7C7MFG7thj8,3838
140
144
  uk_bin_collection/uk_bin_collection/councils/ReadingBoroughCouncil.py,sha256=ZlQjU0IeKylGE9VlivSMh4XKwoLgntESPiylSOYkuD4,1009
@@ -161,6 +165,7 @@ uk_bin_collection/uk_bin_collection/councils/SouthKestevenDistrictCouncil.py,sha
161
165
  uk_bin_collection/uk_bin_collection/councils/SouthLanarkshireCouncil.py,sha256=fj-eZI0yrvQVCv8GvhcovZ3b9bV6Xv_ws3IunWjnv4U,3126
162
166
  uk_bin_collection/uk_bin_collection/councils/SouthNorfolkCouncil.py,sha256=ThO-oJ_n7hNRMl_n--rMPWKS6j-hkL_Ab7JBqKaylfg,3971
163
167
  uk_bin_collection/uk_bin_collection/councils/SouthOxfordshireCouncil.py,sha256=zW4bN3hcqNoK_Y0-vPpuZs3K0LTPvApu6_v9K-D7WjE,3879
168
+ uk_bin_collection/uk_bin_collection/councils/SouthRibbleCouncil.py,sha256=OdexbeiI5WsCfjlsnHjAce8oGF5fW-n7q2XOuxcpHzw,3604
164
169
  uk_bin_collection/uk_bin_collection/councils/SouthTynesideCouncil.py,sha256=dxXGrJfg_fn2IPTBgq6Duwy0WY8GYLafMuisaCjOnbs,3426
165
170
  uk_bin_collection/uk_bin_collection/councils/SouthwarkCouncil.py,sha256=Kc9YrevYO4u1EI1r2LV74cmYCpEo5x2c8-WfFHecPCc,4817
166
171
  uk_bin_collection/uk_bin_collection/councils/StAlbansCityAndDistrictCouncil.py,sha256=mPZz6Za6kTSkrfHnj0OfwtnpRYR1dKvxbuFEKnWsiL8,1451
@@ -213,8 +218,8 @@ uk_bin_collection/uk_bin_collection/councils/YorkCouncil.py,sha256=I2kBYMlsD4bId
213
218
  uk_bin_collection/uk_bin_collection/councils/council_class_template/councilclasstemplate.py,sha256=4s9ODGPAwPqwXc8SrTX5Wlfmizs3_58iXUtHc4Ir86o,1162
214
219
  uk_bin_collection/uk_bin_collection/create_new_council.py,sha256=m-IhmWmeWQlFsTZC4OxuFvtw5ZtB8EAJHxJTH4O59lQ,1536
215
220
  uk_bin_collection/uk_bin_collection/get_bin_data.py,sha256=YvmHfZqanwrJ8ToGch34x-L-7yPe31nB_x77_Mgl_vo,4545
216
- uk_bin_collection-0.99.1.dist-info/LICENSE,sha256=vABBUOzcrgfaTKpzeo-si9YVEun6juDkndqA8RKdKGs,1071
217
- uk_bin_collection-0.99.1.dist-info/METADATA,sha256=rvafwYpvDF4f2zFAJgyR4VBVTJdNoRJZj78yK65kfyo,16843
218
- uk_bin_collection-0.99.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
219
- uk_bin_collection-0.99.1.dist-info/entry_points.txt,sha256=36WCSGMWSc916S3Hi1ZkazzDKHaJ6CD-4fCEFm5MIao,90
220
- uk_bin_collection-0.99.1.dist-info/RECORD,,
221
+ uk_bin_collection-0.101.0.dist-info/LICENSE,sha256=vABBUOzcrgfaTKpzeo-si9YVEun6juDkndqA8RKdKGs,1071
222
+ uk_bin_collection-0.101.0.dist-info/METADATA,sha256=fcu_gjSU7JVGJ-O_7ZXo9HUj1YVcS4JeKJQ-zZnhNDA,16844
223
+ uk_bin_collection-0.101.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
224
+ uk_bin_collection-0.101.0.dist-info/entry_points.txt,sha256=36WCSGMWSc916S3Hi1ZkazzDKHaJ6CD-4fCEFm5MIao,90
225
+ uk_bin_collection-0.101.0.dist-info/RECORD,,