uk_bin_collection 0.103.0__py3-none-any.whl → 0.105.0__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- uk_bin_collection/tests/input.json +66 -1
- uk_bin_collection/uk_bin_collection/councils/AberdeenshireCouncil.py +52 -0
- uk_bin_collection/uk_bin_collection/councils/CanterburyCityCouncil.py +54 -0
- uk_bin_collection/uk_bin_collection/councils/CoventryCityCouncil.py +51 -0
- uk_bin_collection/uk_bin_collection/councils/HarboroughDistrictCouncil.py +58 -0
- uk_bin_collection/uk_bin_collection/councils/LutonBoroughCouncil.py +81 -0
- uk_bin_collection/uk_bin_collection/councils/SwindonBoroughCouncil.py +56 -0
- uk_bin_collection/uk_bin_collection/councils/TeignbridgeCouncil.py +59 -0
- uk_bin_collection/uk_bin_collection/councils/WatfordBoroughCouncil.py +72 -0
- uk_bin_collection/uk_bin_collection/councils/WestOxfordshireDistrictCouncil.py +113 -0
- {uk_bin_collection-0.103.0.dist-info → uk_bin_collection-0.105.0.dist-info}/METADATA +1 -1
- {uk_bin_collection-0.103.0.dist-info → uk_bin_collection-0.105.0.dist-info}/RECORD +15 -6
- {uk_bin_collection-0.103.0.dist-info → uk_bin_collection-0.105.0.dist-info}/LICENSE +0 -0
- {uk_bin_collection-0.103.0.dist-info → uk_bin_collection-0.105.0.dist-info}/WHEEL +0 -0
- {uk_bin_collection-0.103.0.dist-info → uk_bin_collection-0.105.0.dist-info}/entry_points.txt +0 -0
@@ -1,4 +1,11 @@
|
|
1
1
|
{
|
2
|
+
"AberdeenshireCouncil": {
|
3
|
+
"url": "https://online.aberdeenshire.gov.uk",
|
4
|
+
"wiki_command_url_override": "https://online.aberdeenshire.gov.uk",
|
5
|
+
"uprn": "151176430",
|
6
|
+
"wiki_name": "Aberdeenshire Council",
|
7
|
+
"wiki_note": "You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find the UPRN."
|
8
|
+
},
|
2
9
|
"AdurAndWorthingCouncils": {
|
3
10
|
"url": "https://www.adur-worthing.gov.uk/bin-day/?brlu-selected-address=100061878829",
|
4
11
|
"wiki_command_url_override": "https://www.adur-worthing.gov.uk/bin-day/?brlu-selected-address=XXXXXXXX",
|
@@ -201,6 +208,13 @@
|
|
201
208
|
"wiki_name": "Cannock Chase District Council",
|
202
209
|
"wiki_note": "To get the UPRN, you can use [FindMyAddress](https://www.findmyaddress.co.uk/search)"
|
203
210
|
},
|
211
|
+
"CanterburyCityCouncil": {
|
212
|
+
"url": "https://www.canterbury.gov.uk",
|
213
|
+
"wiki_command_url_override": "https://www.canterbury.gov.uk",
|
214
|
+
"uprn": "10094583181",
|
215
|
+
"wiki_name": "Canterbury City Council",
|
216
|
+
"wiki_note": "You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find the UPRN."
|
217
|
+
},
|
204
218
|
"CardiffCouncil": {
|
205
219
|
"skip_get_url": true,
|
206
220
|
"uprn": "100100112419",
|
@@ -285,6 +299,12 @@
|
|
285
299
|
"wiki_name": "Cornwall Council",
|
286
300
|
"wiki_note": "Use https://uprn.uk/ to find your UPRN."
|
287
301
|
},
|
302
|
+
"CoventryCityCouncil": {
|
303
|
+
"url": "https://www.coventry.gov.uk/directory-record/56384/abberton-way-",
|
304
|
+
"wiki_command_url_override": "https://www.coventry.gov.uk/directory_record/XXXXXX/XXXXXX",
|
305
|
+
"wiki_name": "Coventry City Council",
|
306
|
+
"wiki_note": "Follow the instructions [here](https://www.coventry.gov.uk/bin-collection-calendar) until you get the page that shows the weekly collections for your address then copy the URL and replace the URL in the command."
|
307
|
+
},
|
288
308
|
"CrawleyBoroughCouncil": {
|
289
309
|
"house_number": "9701076",
|
290
310
|
"skip_get_url": true,
|
@@ -523,6 +543,13 @@
|
|
523
543
|
"wiki_name": "Halton Borough Council",
|
524
544
|
"wiki_note": "Pass the House number and post code"
|
525
545
|
},
|
546
|
+
"HarboroughDistrictCouncil": {
|
547
|
+
"url": "https://www.harborough.gov.uk",
|
548
|
+
"wiki_command_url_override": "https://www.harborough.gov.uk",
|
549
|
+
"uprn": "100030489072",
|
550
|
+
"wiki_name": "Harborough District Council",
|
551
|
+
"wiki_note": "You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find the UPRN."
|
552
|
+
},
|
526
553
|
"HaringeyCouncil": {
|
527
554
|
"skip_get_url": true,
|
528
555
|
"uprn": "100021203052",
|
@@ -681,6 +708,13 @@
|
|
681
708
|
"wiki_name": "London Borough Redbridge",
|
682
709
|
"wiki_note": "Follow the instructions [here](https://my.redbridge.gov.uk/RecycleRefuse) until you get the page listing your \"Address\" then copy the entire address text and use that in the house number field."
|
683
710
|
},
|
711
|
+
"LutonBoroughCouncil": {
|
712
|
+
"url": "https://myforms.luton.gov.uk",
|
713
|
+
"wiki_command_url_override": "https://myforms.luton.gov.uk",
|
714
|
+
"uprn": "100080155778",
|
715
|
+
"wiki_name": "Luton Borough Council",
|
716
|
+
"wiki_note": "You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find the UPRN."
|
717
|
+
},
|
684
718
|
"MaldonDistrictCouncil": {
|
685
719
|
"skip_get_url": true,
|
686
720
|
"uprn": "100090557253",
|
@@ -720,7 +754,7 @@
|
|
720
754
|
"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.)."
|
721
755
|
},
|
722
756
|
"MidlothianCouncil": {
|
723
|
-
"url": "https://www.midlothian.gov.uk/directory_record/
|
757
|
+
"url": "https://www.midlothian.gov.uk/directory_record/92594377/glenesk_bonnyrigg_eh19_3je",
|
724
758
|
"wiki_command_url_override": "https://www.midlothian.gov.uk/directory_record/XXXXXX/XXXXXX",
|
725
759
|
"wiki_name": "Midlothian Council",
|
726
760
|
"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."
|
@@ -1189,6 +1223,13 @@
|
|
1189
1223
|
"url": "https://www1.swansea.gov.uk/recyclingsearch/",
|
1190
1224
|
"wiki_name": "SwanseaCouncil"
|
1191
1225
|
},
|
1226
|
+
"SwindonBoroughCouncil": {
|
1227
|
+
"url": "https://www.swindon.gov.uk",
|
1228
|
+
"wiki_command_url_override": "https://www.swindon.gov.uk",
|
1229
|
+
"uprn": "10022793351",
|
1230
|
+
"wiki_name": "Swindon Borough Council",
|
1231
|
+
"wiki_note": "You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find the UPRN."
|
1232
|
+
},
|
1192
1233
|
"TamesideMBCouncil": {
|
1193
1234
|
"skip_get_url": true,
|
1194
1235
|
"uprn": "100012835362",
|
@@ -1201,6 +1242,14 @@
|
|
1201
1242
|
"url": "https://tdcws01.tandridge.gov.uk/TDCWebAppsPublic/tfaBranded/408?utm_source=pressrelease&utm_medium=smposts&utm_campaign=check_my_bin_day",
|
1202
1243
|
"wiki_name": "Tandridge District Council"
|
1203
1244
|
},
|
1245
|
+
"TeignbridgeCouncil": {
|
1246
|
+
"url": "https://www.google.co.uk",
|
1247
|
+
"wiki_command_url_override": "https://www.google.co.uk",
|
1248
|
+
"uprn": "100040338776",
|
1249
|
+
"web_driver": "http://selenium:4444",
|
1250
|
+
"wiki_name": "Teignbridge Council",
|
1251
|
+
"wiki_note": "Provide Google as the URL as the real URL breaks the integration. You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find the UPRN."
|
1252
|
+
},
|
1204
1253
|
"TelfordAndWrekinCouncil": {
|
1205
1254
|
"skip_get_url": true,
|
1206
1255
|
"uprn": "000452015013",
|
@@ -1310,6 +1359,13 @@
|
|
1310
1359
|
"wiki_name": "Warwick District Council",
|
1311
1360
|
"wiki_note": "Replace XXXXXXXX with UPRN."
|
1312
1361
|
},
|
1362
|
+
"WatfordBoroughCouncil": {
|
1363
|
+
"url": "https://www.watford.gov.uk",
|
1364
|
+
"wiki_command_url_override": "https://www.watford.gov.uk",
|
1365
|
+
"uprn": "100080942183",
|
1366
|
+
"wiki_name": "Watford Borough Council",
|
1367
|
+
"wiki_note": "You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find the UPRN."
|
1368
|
+
},
|
1313
1369
|
"WaverleyBoroughCouncil": {
|
1314
1370
|
"house_number": "23",
|
1315
1371
|
"postcode": "GU9 9QG",
|
@@ -1369,6 +1425,15 @@
|
|
1369
1425
|
"url": "https://www.northampton.gov.uk/info/200084/bins-waste-and-recycling/1602/check-your-collection-day",
|
1370
1426
|
"wiki_name": "West Northamptonshire Council"
|
1371
1427
|
},
|
1428
|
+
"WestOxfordshireDistrictCouncil": {
|
1429
|
+
"house_number": "24",
|
1430
|
+
"postcode": "OX28 1YA",
|
1431
|
+
"skip_get_url": true,
|
1432
|
+
"url": "https://community.westoxon.gov.uk/s/waste-collection-enquiry",
|
1433
|
+
"web_driver": "http://selenium:4444",
|
1434
|
+
"wiki_name": "West Oxfordshire District Council",
|
1435
|
+
"wiki_note": "Pass the full address in the house number and postcode in"
|
1436
|
+
},
|
1372
1437
|
"WestSuffolkCouncil": {
|
1373
1438
|
"postcode": "IP28 6DR",
|
1374
1439
|
"skip_get_url": true,
|
@@ -0,0 +1,52 @@
|
|
1
|
+
import requests
|
2
|
+
from bs4 import BeautifulSoup
|
3
|
+
|
4
|
+
from uk_bin_collection.uk_bin_collection.common import *
|
5
|
+
from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
|
6
|
+
|
7
|
+
|
8
|
+
# import the wonderful Beautiful Soup and the URL grabber
|
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
|
+
|
18
|
+
user_uprn = kwargs.get("uprn")
|
19
|
+
check_uprn(user_uprn)
|
20
|
+
bindata = {"bins": []}
|
21
|
+
|
22
|
+
URI = f"https://online.aberdeenshire.gov.uk/Apps/Waste-Collections/Routes/Route/{user_uprn}"
|
23
|
+
|
24
|
+
# Make the GET request
|
25
|
+
response = requests.get(URI)
|
26
|
+
|
27
|
+
soup = BeautifulSoup(response.content, features="html.parser")
|
28
|
+
soup.prettify()
|
29
|
+
|
30
|
+
for collection in soup.find("table").find("tbody").find_all("tr"):
|
31
|
+
th = collection.find("th")
|
32
|
+
if th:
|
33
|
+
continue
|
34
|
+
td = collection.find_all("td")
|
35
|
+
collection_date = datetime.strptime(
|
36
|
+
td[0].text,
|
37
|
+
"%d/%m/%Y %A",
|
38
|
+
)
|
39
|
+
bin_type = td[1].text.split(" and ")
|
40
|
+
|
41
|
+
for bin in bin_type:
|
42
|
+
dict_data = {
|
43
|
+
"type": bin,
|
44
|
+
"collectionDate": collection_date.strftime(date_format),
|
45
|
+
}
|
46
|
+
bindata["bins"].append(dict_data)
|
47
|
+
|
48
|
+
bindata["bins"].sort(
|
49
|
+
key=lambda x: datetime.strptime(x.get("collectionDate"), "%d/%m/%Y")
|
50
|
+
)
|
51
|
+
|
52
|
+
return bindata
|
@@ -0,0 +1,54 @@
|
|
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
|
+
data = {"uprn": user_uprn, "usrn": "1"}
|
24
|
+
|
25
|
+
URI = (
|
26
|
+
"https://zbr7r13ke2.execute-api.eu-west-2.amazonaws.com/Beta/get-bin-dates"
|
27
|
+
)
|
28
|
+
|
29
|
+
# Make the GET request
|
30
|
+
response = requests.post(URI, json=data)
|
31
|
+
response.raise_for_status()
|
32
|
+
|
33
|
+
# Parse the JSON response
|
34
|
+
bin_collection = json.loads(response.json()["dates"])
|
35
|
+
collections = {
|
36
|
+
"General": bin_collection["blackBinDay"],
|
37
|
+
"Recycling": bin_collection["recyclingBinDay"],
|
38
|
+
"Food": bin_collection["foodBinDay"],
|
39
|
+
"Garden": bin_collection["gardenBinDay"],
|
40
|
+
}
|
41
|
+
# Loop through each collection in bin_collection
|
42
|
+
for collection in collections:
|
43
|
+
print(collection)
|
44
|
+
|
45
|
+
if len(collections[collection]) <= 0:
|
46
|
+
continue
|
47
|
+
for date in collections[collection]:
|
48
|
+
date = (
|
49
|
+
datetime.strptime(date, "%Y-%m-%dT%H:%M:%S").strftime("%d/%m/%Y"),
|
50
|
+
)
|
51
|
+
dict_data = {"type": collection, "collectionDate": date[0]}
|
52
|
+
bindata["bins"].append(dict_data)
|
53
|
+
|
54
|
+
return bindata
|
@@ -0,0 +1,51 @@
|
|
1
|
+
import requests
|
2
|
+
from bs4 import BeautifulSoup
|
3
|
+
from dateutil.relativedelta import relativedelta
|
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
|
+
bindata = {"bins": []}
|
20
|
+
curr_date = datetime.today()
|
21
|
+
|
22
|
+
soup = BeautifulSoup(page.content, features="html.parser")
|
23
|
+
button = soup.find("a", text="Find out which bin will be collected when.")
|
24
|
+
|
25
|
+
if button["href"]:
|
26
|
+
URI = button["href"]
|
27
|
+
# Make the GET request
|
28
|
+
response = requests.get(URI)
|
29
|
+
soup = BeautifulSoup(response.content, features="html.parser")
|
30
|
+
divs = soup.find_all("div", {"class": "editor"})
|
31
|
+
for div in divs:
|
32
|
+
lis = div.find_all("li")
|
33
|
+
for li in lis:
|
34
|
+
collection = li.text.split(": ")
|
35
|
+
collection_date = datetime.strptime(
|
36
|
+
collection[0],
|
37
|
+
"%A %d %B",
|
38
|
+
).replace(year=curr_date.year)
|
39
|
+
if curr_date.month == 12 and collection_date.month == 1:
|
40
|
+
collection_date = collection_date + relativedelta(years=1)
|
41
|
+
bin_types = collection[1].split(" and ")
|
42
|
+
for bin_type in bin_types:
|
43
|
+
dict_data = {
|
44
|
+
"type": bin_type,
|
45
|
+
"collectionDate": collection_date.strftime("%d/%m/%Y"),
|
46
|
+
}
|
47
|
+
bindata["bins"].append(dict_data)
|
48
|
+
else:
|
49
|
+
print("Failed to find bin schedule")
|
50
|
+
|
51
|
+
return bindata
|
@@ -0,0 +1,58 @@
|
|
1
|
+
import requests
|
2
|
+
from bs4 import BeautifulSoup
|
3
|
+
|
4
|
+
from uk_bin_collection.uk_bin_collection.common import *
|
5
|
+
from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
|
6
|
+
|
7
|
+
|
8
|
+
# import the wonderful Beautiful Soup and the URL grabber
|
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
|
+
|
18
|
+
user_uprn = kwargs.get("uprn")
|
19
|
+
check_uprn(user_uprn)
|
20
|
+
bindata = {"bins": []}
|
21
|
+
|
22
|
+
URI = "https://harborough.fccenvironment.co.uk/detail-address"
|
23
|
+
|
24
|
+
headers = {
|
25
|
+
"Content-Type": "application/json",
|
26
|
+
"User-Agent": "Mozilla/5.0",
|
27
|
+
"Referer": "https://harborough.fccenvironment.co.uk/",
|
28
|
+
}
|
29
|
+
params = {"Uprn": user_uprn}
|
30
|
+
response = requests.post(URI, headers=headers, json=params)
|
31
|
+
|
32
|
+
soup = BeautifulSoup(response.content, features="html.parser")
|
33
|
+
bin_collection = soup.find(
|
34
|
+
"div", {"class": "blocks block-your-next-scheduled-bin-collection-days"}
|
35
|
+
)
|
36
|
+
lis = bin_collection.find_all("li")
|
37
|
+
for li in lis:
|
38
|
+
try:
|
39
|
+
split = re.match(r"(.+)\s(\d{1,2} \w+ \d{4})$", li.text)
|
40
|
+
bin_type = split.group(1).strip()
|
41
|
+
date = split.group(2)
|
42
|
+
|
43
|
+
dict_data = {
|
44
|
+
"type": bin_type,
|
45
|
+
"collectionDate": datetime.strptime(
|
46
|
+
date,
|
47
|
+
"%d %B %Y",
|
48
|
+
).strftime("%d/%m/%Y"),
|
49
|
+
}
|
50
|
+
bindata["bins"].append(dict_data)
|
51
|
+
except:
|
52
|
+
continue
|
53
|
+
|
54
|
+
bindata["bins"].sort(
|
55
|
+
key=lambda x: datetime.strptime(x.get("collectionDate"), "%d/%m/%Y")
|
56
|
+
)
|
57
|
+
|
58
|
+
return bindata
|
@@ -0,0 +1,81 @@
|
|
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
|
+
SESSION_URL = "https://myforms.luton.gov.uk/authapi/isauthenticated?uri=https%253A%252F%252Fmyforms.luton.gov.uk%252Fservice%252FFind_my_bin_collection_date&hostname=myforms.luton.gov.uk&withCredentials=true"
|
25
|
+
|
26
|
+
API_URL = "https://myforms.luton.gov.uk/apibroker/runLookup"
|
27
|
+
|
28
|
+
data = {
|
29
|
+
"formValues": {
|
30
|
+
"Find my bin collection date": {
|
31
|
+
"id": {
|
32
|
+
"value": f"1-{user_uprn}",
|
33
|
+
},
|
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://myforms.luton.gov.uk/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": "65cb710f8d525",
|
52
|
+
"repeat_against": "",
|
53
|
+
"noRetry": "true",
|
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"][f"{user_uprn}"]
|
65
|
+
|
66
|
+
soup = BeautifulSoup(rows_data["html"], features="html.parser")
|
67
|
+
soup.prettify()
|
68
|
+
for collection in soup.find_all("tr"):
|
69
|
+
tds = collection.find_all("td")
|
70
|
+
bin_type = tds[1].text
|
71
|
+
collection_date = datetime.strptime(
|
72
|
+
tds[0].text,
|
73
|
+
"%A %d %b %Y",
|
74
|
+
)
|
75
|
+
dict_data = {
|
76
|
+
"type": bin_type,
|
77
|
+
"collectionDate": collection_date.strftime(date_format),
|
78
|
+
}
|
79
|
+
bindata["bins"].append(dict_data)
|
80
|
+
|
81
|
+
return bindata
|
@@ -0,0 +1,56 @@
|
|
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
|
+
URI = f"https://www.swindon.gov.uk/info/20122/rubbish_and_recycling_collection_days?addressList={user_uprn}&uprnSubmit=Yes"
|
25
|
+
|
26
|
+
# Make the GET request
|
27
|
+
response = requests.get(URI)
|
28
|
+
|
29
|
+
# Parse the JSON response
|
30
|
+
soup = BeautifulSoup(response.text, "html.parser")
|
31
|
+
|
32
|
+
bin_collection_content = soup.find_all(
|
33
|
+
"div", {"class": "bin-collection-content"}
|
34
|
+
)
|
35
|
+
for content in bin_collection_content:
|
36
|
+
content_left = content.find("div", {"class": "content-left"})
|
37
|
+
content_right = content.find("div", {"class": "content-right"})
|
38
|
+
if content_left and content_right:
|
39
|
+
|
40
|
+
bin_types = content_left.find("h3").text.split(" and ")
|
41
|
+
for bin_type in bin_types:
|
42
|
+
|
43
|
+
collection_date = datetime.strptime(
|
44
|
+
content_right.find(
|
45
|
+
"span", {"class": "nextCollectionDate"}
|
46
|
+
).text,
|
47
|
+
"%A, %d %B %Y",
|
48
|
+
).strftime(date_format)
|
49
|
+
|
50
|
+
dict_data = {
|
51
|
+
"type": bin_type,
|
52
|
+
"collectionDate": collection_date,
|
53
|
+
}
|
54
|
+
bindata["bins"].append(dict_data)
|
55
|
+
|
56
|
+
return bindata
|
@@ -0,0 +1,59 @@
|
|
1
|
+
from bs4 import BeautifulSoup
|
2
|
+
from selenium.webdriver.common.by import By
|
3
|
+
from selenium.webdriver.support import expected_conditions as EC
|
4
|
+
from selenium.webdriver.support.wait import WebDriverWait
|
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
|
+
web_driver = kwargs.get("web_driver")
|
22
|
+
headless = kwargs.get("headless")
|
23
|
+
check_uprn(user_uprn)
|
24
|
+
bindata = {"bins": []}
|
25
|
+
|
26
|
+
URI = f"https://www.teignbridge.gov.uk/repositories/hidden-pages/bin-finder?uprn={user_uprn}"
|
27
|
+
|
28
|
+
driver = create_webdriver(web_driver, headless, None, __name__)
|
29
|
+
driver.get(URI)
|
30
|
+
|
31
|
+
soup = BeautifulSoup(driver.page_source, features="html.parser")
|
32
|
+
|
33
|
+
collection_dates = soup.find_all(
|
34
|
+
"h3"
|
35
|
+
) # Assuming bin types are inside <h3> tags
|
36
|
+
bin_type_headers = soup.find_all(
|
37
|
+
"div", {"class": "binInfoContainer"}
|
38
|
+
) # Assuming collection dates are inside <p> tags
|
39
|
+
|
40
|
+
# Iterate over the results and extract bin type and collection dates
|
41
|
+
for i, date in enumerate(collection_dates):
|
42
|
+
collection_date = date.get_text(strip=True)
|
43
|
+
|
44
|
+
bin_types = bin_type_headers[i].find_all("div")
|
45
|
+
for bin_type in bin_types:
|
46
|
+
dict_data = {
|
47
|
+
"type": bin_type.text.strip(),
|
48
|
+
"collectionDate": datetime.strptime(
|
49
|
+
collection_date,
|
50
|
+
"%d %B %Y%A",
|
51
|
+
).strftime("%d/%m/%Y"),
|
52
|
+
}
|
53
|
+
bindata["bins"].append(dict_data)
|
54
|
+
|
55
|
+
bindata["bins"].sort(
|
56
|
+
key=lambda x: datetime.strptime(x.get("collectionDate"), "%d/%m/%Y")
|
57
|
+
)
|
58
|
+
|
59
|
+
return bindata
|
@@ -0,0 +1,72 @@
|
|
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
|
+
SESSION_URL = "https://watfordbc-self.achieveservice.com/authapi/isauthenticated?uri=https%253A%252F%252Fwatfordbc-self.achieveservice.com%252Fen%252Fservice%252FBin_collections%253Faccept%253Dyes%2526consentMessageIds%255B%255D%253D4&hostname=watfordbc-self.achieveservice.com&withCredentials=true"
|
25
|
+
|
26
|
+
API_URL = "https://watfordbc-self.achieveservice.com/apibroker/runLookup"
|
27
|
+
|
28
|
+
data = {
|
29
|
+
"formValues": {
|
30
|
+
"Address": {
|
31
|
+
"echoUprn": {"value": user_uprn},
|
32
|
+
},
|
33
|
+
},
|
34
|
+
}
|
35
|
+
|
36
|
+
headers = {
|
37
|
+
"Content-Type": "application/json",
|
38
|
+
"Accept": "application/json",
|
39
|
+
"User-Agent": "Mozilla/5.0",
|
40
|
+
"X-Requested-With": "XMLHttpRequest",
|
41
|
+
"Referer": "https://watfordbc-self.achieveservice.com/fillform/?iframe_id=fillform-frame-1&db_id=",
|
42
|
+
}
|
43
|
+
s = requests.session()
|
44
|
+
r = s.get(SESSION_URL)
|
45
|
+
r.raise_for_status()
|
46
|
+
session_data = r.json()
|
47
|
+
sid = session_data["auth-session"]
|
48
|
+
params = {
|
49
|
+
"id": "5e79edf15b2ec",
|
50
|
+
"repeat_against": "",
|
51
|
+
"noRetry": "true",
|
52
|
+
"getOnlyTokens": "undefined",
|
53
|
+
"log_id": "",
|
54
|
+
"app_name": "AF-Renderer::Self",
|
55
|
+
# unix_timestamp
|
56
|
+
"_": str(int(time.time() * 1000)),
|
57
|
+
"sid": sid,
|
58
|
+
}
|
59
|
+
r = s.post(API_URL, json=data, headers=headers, params=params)
|
60
|
+
r.raise_for_status()
|
61
|
+
data = r.json()
|
62
|
+
dispHTML = data["integration"]["transformed"]["rows_data"]["0"]["dispHTML"]
|
63
|
+
soup = BeautifulSoup(dispHTML, features="html.parser")
|
64
|
+
|
65
|
+
collections = soup.find_all("li")
|
66
|
+
for collection in collections:
|
67
|
+
bin_type = collection.find("h3").text
|
68
|
+
collection_date = collection.find("strong").text.strip()
|
69
|
+
dict_data = {"type": bin_type, "collectionDate": collection_date}
|
70
|
+
bindata["bins"].append(dict_data)
|
71
|
+
|
72
|
+
return bindata
|
@@ -0,0 +1,113 @@
|
|
1
|
+
import time
|
2
|
+
from datetime import datetime
|
3
|
+
|
4
|
+
from bs4 import BeautifulSoup
|
5
|
+
from selenium.webdriver.common.by import By
|
6
|
+
from selenium.webdriver.common.keys import Keys
|
7
|
+
from selenium.webdriver.support import expected_conditions as EC
|
8
|
+
from selenium.webdriver.support.ui import Select
|
9
|
+
from selenium.webdriver.support.wait import WebDriverWait
|
10
|
+
|
11
|
+
from uk_bin_collection.uk_bin_collection.common import *
|
12
|
+
from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
|
13
|
+
|
14
|
+
# import the wonderful Beautiful Soup and the URL grabber
|
15
|
+
|
16
|
+
|
17
|
+
class CouncilClass(AbstractGetBinDataClass):
|
18
|
+
"""
|
19
|
+
Concrete classes have to implement all abstract operations of the
|
20
|
+
base class. They can also override some operations with a default
|
21
|
+
implementation.
|
22
|
+
"""
|
23
|
+
|
24
|
+
def parse_data(self, page: str, **kwargs) -> dict:
|
25
|
+
driver = None
|
26
|
+
try:
|
27
|
+
page = "https://community.westoxon.gov.uk/s/waste-collection-enquiry"
|
28
|
+
|
29
|
+
data = {"bins": []}
|
30
|
+
|
31
|
+
house_number = kwargs.get("paon")
|
32
|
+
postcode = kwargs.get("postcode")
|
33
|
+
full_address = f"{house_number}, {postcode}"
|
34
|
+
web_driver = kwargs.get("web_driver")
|
35
|
+
headless = kwargs.get("headless")
|
36
|
+
|
37
|
+
# Create Selenium webdriver
|
38
|
+
driver = create_webdriver(web_driver, headless, None, __name__)
|
39
|
+
driver.get(page)
|
40
|
+
|
41
|
+
# If you bang in the house number (or property name) and postcode in the box it should find your property
|
42
|
+
wait = WebDriverWait(driver, 60)
|
43
|
+
address_entry_field = wait.until(
|
44
|
+
EC.presence_of_element_located(
|
45
|
+
(By.XPATH, '//*[@id="combobox-input-19"]')
|
46
|
+
)
|
47
|
+
)
|
48
|
+
|
49
|
+
address_entry_field.send_keys(str(full_address))
|
50
|
+
|
51
|
+
address_entry_field = wait.until(
|
52
|
+
EC.element_to_be_clickable((By.XPATH, '//*[@id="combobox-input-19"]'))
|
53
|
+
)
|
54
|
+
address_entry_field.click()
|
55
|
+
address_entry_field.send_keys(Keys.BACKSPACE)
|
56
|
+
address_entry_field.send_keys(str(full_address[len(full_address) - 1]))
|
57
|
+
|
58
|
+
first_found_address = wait.until(
|
59
|
+
EC.element_to_be_clickable(
|
60
|
+
(By.XPATH, '//*[@id="dropdown-element-19"]/ul')
|
61
|
+
)
|
62
|
+
)
|
63
|
+
|
64
|
+
first_found_address.click()
|
65
|
+
# Wait for the 'Select your property' dropdown to appear and select the first result
|
66
|
+
next_btn = wait.until(
|
67
|
+
EC.element_to_be_clickable((By.XPATH, "//lightning-button/button"))
|
68
|
+
)
|
69
|
+
next_btn.click()
|
70
|
+
bin_data = wait.until(
|
71
|
+
EC.presence_of_element_located(
|
72
|
+
(By.XPATH, "//span[contains(text(), 'Container')]")
|
73
|
+
)
|
74
|
+
)
|
75
|
+
|
76
|
+
soup = BeautifulSoup(driver.page_source, features="html.parser")
|
77
|
+
|
78
|
+
rows = soup.find_all("tr", class_="slds-hint-parent")
|
79
|
+
current_year = datetime.now().year
|
80
|
+
|
81
|
+
for row in rows:
|
82
|
+
columns = row.find_all("td")
|
83
|
+
if columns:
|
84
|
+
container_type = row.find("th").text.strip()
|
85
|
+
collection_day = re.sub(
|
86
|
+
r"[^a-zA-Z0-9,\s]", "", columns[0].get_text()
|
87
|
+
).strip()
|
88
|
+
|
89
|
+
# Parse the date from the string
|
90
|
+
parsed_date = datetime.strptime(collection_day, "%a, %d %B")
|
91
|
+
if parsed_date < datetime(
|
92
|
+
parsed_date.year, parsed_date.month, parsed_date.day
|
93
|
+
):
|
94
|
+
parsed_date = parsed_date.replace(year=current_year + 1)
|
95
|
+
else:
|
96
|
+
parsed_date = parsed_date.replace(year=current_year)
|
97
|
+
# Format the date as %d/%m/%Y
|
98
|
+
formatted_date = parsed_date.strftime("%d/%m/%Y")
|
99
|
+
|
100
|
+
# Add the bin type and collection date to the 'data' dictionary
|
101
|
+
data["bins"].append(
|
102
|
+
{"type": container_type, "collectionDate": formatted_date}
|
103
|
+
)
|
104
|
+
except Exception as e:
|
105
|
+
# Here you can log the exception if needed
|
106
|
+
print(f"An error occurred: {e}")
|
107
|
+
# Optionally, re-raise the exception if you want it to propagate
|
108
|
+
raise
|
109
|
+
finally:
|
110
|
+
# This block ensures that the driver is closed regardless of an exception
|
111
|
+
if driver:
|
112
|
+
driver.quit()
|
113
|
+
return data
|
@@ -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=
|
5
|
+
uk_bin_collection/tests/input.json,sha256=ld79NcETkx8ngOGsOvYZGgRfxYw1yuiqFAc-Bxc-xxw,74583
|
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
|
@@ -12,6 +12,7 @@ uk_bin_collection/tests/test_conftest.py,sha256=GWqP6-fCv5A2VUYiyXqUO-Dm0hlUOwbF
|
|
12
12
|
uk_bin_collection/tests/test_get_data.py,sha256=tQGyuTR8pZvnwzVsDqFhUrFtBeMP11eRnWD4Xq-mF-U,7181
|
13
13
|
uk_bin_collection/uk_bin_collection/collect_data.py,sha256=dB7wWXsJX4fm5bIf84lexkvHIcO54CZ3JPxqmS-60YY,4654
|
14
14
|
uk_bin_collection/uk_bin_collection/common.py,sha256=oZQW8CYRGfbhNSyq7t7jEhrFl1tjb4H157xSx8QHWSY,10106
|
15
|
+
uk_bin_collection/uk_bin_collection/councils/AberdeenshireCouncil.py,sha256=aO1CSdyqa8oAD0fB79y1Q9bikAWCP_JFa7CsyTa2j9s,1655
|
15
16
|
uk_bin_collection/uk_bin_collection/councils/AdurAndWorthingCouncils.py,sha256=ppbrmm-MzB1wOulK--CU_0j4P-djNf3ozMhHnmQFqLo,1511
|
16
17
|
uk_bin_collection/uk_bin_collection/councils/ArmaghBanbridgeCraigavonCouncil.py,sha256=o9NBbVCTdxKXnpYbP8-zxe1Gh8s57vwfV75Son_sAHE,2863
|
17
18
|
uk_bin_collection/uk_bin_collection/councils/ArunCouncil.py,sha256=yfhthv9nuogP19VOZ3TYQrq51qqjiCZcSel4sXhiKjs,4012
|
@@ -39,6 +40,7 @@ uk_bin_collection/uk_bin_collection/councils/BuckinghamshireCouncil.py,sha256=_E
|
|
39
40
|
uk_bin_collection/uk_bin_collection/councils/BuryCouncil.py,sha256=H7wAxO1nfxkewVoRRolumq8bBJG04siE3jieFH3RGpQ,2632
|
40
41
|
uk_bin_collection/uk_bin_collection/councils/CalderdaleCouncil.py,sha256=OJZcHYlvZDzmBpjjPPm3J8CRK9Twc49vRj7O9c5fyQ4,4971
|
41
42
|
uk_bin_collection/uk_bin_collection/councils/CannockChaseDistrictCouncil.py,sha256=ZamevXN8_Q8mRZOTESWtkb8jVyDXkTczcmhXMAVVSkM,2276
|
43
|
+
uk_bin_collection/uk_bin_collection/councils/CanterburyCityCouncil.py,sha256=2s8OL2H0QlUaNu6gUWcoAKHrRdLuQzfMHjcSZuLYbB0,1771
|
42
44
|
uk_bin_collection/uk_bin_collection/councils/CardiffCouncil.py,sha256=_k3sT_WR-gnjjt3tHQ-L2-keP9sdBV0ZeW7gHDzFPYo,7208
|
43
45
|
uk_bin_collection/uk_bin_collection/councils/CastlepointDistrictCouncil.py,sha256=JVPYUIlU2ISgbUSr5AOOXNK6IFQFtQmhZyYIMAOedD4,3858
|
44
46
|
uk_bin_collection/uk_bin_collection/councils/CharnwoodBoroughCouncil.py,sha256=tXfzMetN6wxahuGGRp2mIyCCDSL4F2aG61HhUxw6COQ,2172
|
@@ -50,6 +52,7 @@ uk_bin_collection/uk_bin_collection/councils/ChorleyCouncil.py,sha256=M7HjuUaFq8
|
|
50
52
|
uk_bin_collection/uk_bin_collection/councils/ColchesterCityCouncil.py,sha256=Mny-q2rQkWe2Tj1gINwEM1L4AkqQl1EDMAaKY0-deD4,3968
|
51
53
|
uk_bin_collection/uk_bin_collection/councils/ConwyCountyBorough.py,sha256=el75qv2QyfWZBU09tJLvD8vLQZ9pCg73u1NBFs6ybo8,1034
|
52
54
|
uk_bin_collection/uk_bin_collection/councils/CornwallCouncil.py,sha256=WZiz50svwyZgO8QKUCLy7hfFuy2HmAx5h-TG3yAweRA,2836
|
55
|
+
uk_bin_collection/uk_bin_collection/councils/CoventryCityCouncil.py,sha256=kfAvA2e4MlO0W9YT70U_mW9gxVPrmr0BOGzV99Tw2Bg,2012
|
53
56
|
uk_bin_collection/uk_bin_collection/councils/CrawleyBoroughCouncil.py,sha256=_BEKZAjlS5Ad5DjyxqAEFSLn8F-KYox0zmn4BXaAD6A,2367
|
54
57
|
uk_bin_collection/uk_bin_collection/councils/CroydonCouncil.py,sha256=QJH27plySbbmoNcLNUXq-hUiFmZ5zBlRS5mzOJgWSK8,11594
|
55
58
|
uk_bin_collection/uk_bin_collection/councils/DacorumBoroughCouncil.py,sha256=Tm_6pvBPj-6qStbe6-02LXaoCOlnnDvVXAAocGVvf_E,3970
|
@@ -83,6 +86,7 @@ uk_bin_collection/uk_bin_collection/councils/GlasgowCityCouncil.py,sha256=i7Bymp
|
|
83
86
|
uk_bin_collection/uk_bin_collection/councils/GloucesterCityCouncil.py,sha256=8Wjvmdvg5blHVrREaEnhhWZaWhYVP4v_KdDVPLIUxaU,4889
|
84
87
|
uk_bin_collection/uk_bin_collection/councils/GuildfordCouncil.py,sha256=9pVrmQhZcK2AD8gX8mNvP--L4L9KaY6L3B822VX6fec,5695
|
85
88
|
uk_bin_collection/uk_bin_collection/councils/HaltonBoroughCouncil.py,sha256=gq_CPqi6qM2oNiHhKKF1lZC86fyKL4lPhh_DN9pJZ04,5971
|
89
|
+
uk_bin_collection/uk_bin_collection/councils/HarboroughDistrictCouncil.py,sha256=uAbCgfrqkIkEKUyLVE8l72s5tzbfMFsw775i0nVRAyc,1934
|
86
90
|
uk_bin_collection/uk_bin_collection/councils/HaringeyCouncil.py,sha256=t_6AkAu4wrv8Q0WlDhWh_82I0djl5tk531Pzs-SjWzg,2647
|
87
91
|
uk_bin_collection/uk_bin_collection/councils/HarrogateBoroughCouncil.py,sha256=_g3fP5Nq-OUjgNrfRf4UEyFKzq0x8QK-4enh5RP1efA,2050
|
88
92
|
uk_bin_collection/uk_bin_collection/councils/HighPeakCouncil.py,sha256=oqF8M0lcT3KsrG6W6I6JJX07E6Sc_-_sr7MybfIMab8,4626
|
@@ -105,6 +109,7 @@ uk_bin_collection/uk_bin_collection/councils/LondonBoroughHarrow.py,sha256=kzKwb
|
|
105
109
|
uk_bin_collection/uk_bin_collection/councils/LondonBoroughHounslow.py,sha256=UOeiOxGMvVMm2UFaqjmQpm7vxzqJNSSN8LM9lAUjs2c,3021
|
106
110
|
uk_bin_collection/uk_bin_collection/councils/LondonBoroughLambeth.py,sha256=r9D5lHe5kIRStCd5lRIax16yhb4KTFzzfYEFv1bacWw,2009
|
107
111
|
uk_bin_collection/uk_bin_collection/councils/LondonBoroughRedbridge.py,sha256=A_6Sis5hsF53Th04KeadHRasGbpAm6aoaWJ6X8eC4Y8,6604
|
112
|
+
uk_bin_collection/uk_bin_collection/councils/LutonBoroughCouncil.py,sha256=vScUi_R8FnBddii2_zLlZBLxuh85mKmCm8nKW3zxky0,2758
|
108
113
|
uk_bin_collection/uk_bin_collection/councils/MaldonDistrictCouncil.py,sha256=PMVt2XFggttPmbWyrBrHJ-W6R_6-0ux1BkY1kj1IKzg,1997
|
109
114
|
uk_bin_collection/uk_bin_collection/councils/MalvernHillsDC.py,sha256=iQG0EkX2npBicvsGKQRYyBGSBvKVUbKvUvvwrC9xV1A,2100
|
110
115
|
uk_bin_collection/uk_bin_collection/councils/ManchesterCityCouncil.py,sha256=RY301_82z3-xInGai5ocT7rzoV75ATbf0N7uxn8Z9LE,3110
|
@@ -179,8 +184,10 @@ uk_bin_collection/uk_bin_collection/councils/StroudDistrictCouncil.py,sha256=9bY
|
|
179
184
|
uk_bin_collection/uk_bin_collection/councils/SunderlandCityCouncil.py,sha256=4DnKyyu56_AwuchD6_oL1dvpDStMvkkxQtYN79rUKOs,3825
|
180
185
|
uk_bin_collection/uk_bin_collection/councils/SwaleBoroughCouncil.py,sha256=ak0zqBJ6UAS8_t5zKGwigMxPMdlQuYXRsGCQJCNERJs,3415
|
181
186
|
uk_bin_collection/uk_bin_collection/councils/SwanseaCouncil.py,sha256=nmVPoPhnFgVi--vczX2i4Sf3bqM5RWJuwfhioRUr5XE,2303
|
187
|
+
uk_bin_collection/uk_bin_collection/councils/SwindonBoroughCouncil.py,sha256=lSIykpkBjVwQSf3rrnrNuh7YRepgnkKQLbf1iErMuJs,1932
|
182
188
|
uk_bin_collection/uk_bin_collection/councils/TamesideMBCouncil.py,sha256=k2TAAZG7n2S1BWVyxbE_-4-lZuzhOimCNz4yimUCOGk,1995
|
183
189
|
uk_bin_collection/uk_bin_collection/councils/TandridgeDistrictCouncil.py,sha256=KLVvM2NNq_DQylVe5dwO2l7qPahLHg08jJGLCv1MBQ4,2324
|
190
|
+
uk_bin_collection/uk_bin_collection/councils/TeignbridgeCouncil.py,sha256=vSnQ7UyKEKozhRg3B6BtUhgv8yo719aqAeoXhRP2CW8,2164
|
184
191
|
uk_bin_collection/uk_bin_collection/councils/TelfordAndWrekinCouncil.py,sha256=p1ZS5R4EGxbEWlRBrkGXgKwE_lkyBT-R60yKFFhVObc,1844
|
185
192
|
uk_bin_collection/uk_bin_collection/councils/TendringDistrictCouncil.py,sha256=DJbYI8m6lIISDrK5h8V5Jo-9kGG7kr9dz7GD8St4nc8,4274
|
186
193
|
uk_bin_collection/uk_bin_collection/councils/TestValleyBoroughCouncil.py,sha256=Dtfkyrwt795W7gqFJxVGRR8t3R5WMNQZwTWJckLpZWE,8480
|
@@ -196,6 +203,7 @@ uk_bin_collection/uk_bin_collection/councils/WakefieldCityCouncil.py,sha256=vRfI
|
|
196
203
|
uk_bin_collection/uk_bin_collection/councils/WalsallCouncil.py,sha256=_anovUnXMr40lZLHyX3opIP73BwauCllKy-Z2SBrzPw,2076
|
197
204
|
uk_bin_collection/uk_bin_collection/councils/WalthamForest.py,sha256=P7MMw0EhpRmDbbnHb25tY5_yvYuZUFwJ1br4TOv24sY,4997
|
198
205
|
uk_bin_collection/uk_bin_collection/councils/WarwickDistrictCouncil.py,sha256=3WQrAxzYzKoV4LyOqNTp9xINVsNi1xW9t8etducGeag,1146
|
206
|
+
uk_bin_collection/uk_bin_collection/councils/WatfordBoroughCouncil.py,sha256=zFkXmF1X5g8pjv7II_jXBdrHJu16gy_PowVWVdaDg7A,2657
|
199
207
|
uk_bin_collection/uk_bin_collection/councils/WaverleyBoroughCouncil.py,sha256=tp9l7vdgSGRzNNG0pDfnNuFj4D2bpRJUJmAiTJ6bM0g,4662
|
200
208
|
uk_bin_collection/uk_bin_collection/councils/WealdenDistrictCouncil.py,sha256=SvSSaLkx7iJjzypAwKkaJwegXkSsIQtUOS2V605kz1A,3368
|
201
209
|
uk_bin_collection/uk_bin_collection/councils/WelhatCouncil.py,sha256=ikUft37dYNJghfe-_6Fskiq1JihqpLmLNj38QkKSUUA,2316
|
@@ -204,6 +212,7 @@ uk_bin_collection/uk_bin_collection/councils/WestLindseyDistrictCouncil.py,sha25
|
|
204
212
|
uk_bin_collection/uk_bin_collection/councils/WestLothianCouncil.py,sha256=dq0jimtARvRkZiGbVFrXXZgY-BODtz3uYZ5UKn0bf64,4114
|
205
213
|
uk_bin_collection/uk_bin_collection/councils/WestMorlandAndFurness.py,sha256=jbqV3460rn9D0yTBGWjpSe1IvWWcdGur5pzgj-hJcQ4,2513
|
206
214
|
uk_bin_collection/uk_bin_collection/councils/WestNorthamptonshireCouncil.py,sha256=F1GeJUGND4DN_HuM6N0Elpeb0DAMm9_KeqG6qtIgZf4,1079
|
215
|
+
uk_bin_collection/uk_bin_collection/councils/WestOxfordshireDistrictCouncil.py,sha256=0JIN_2XCYBGCC-wsYhsWIlKJEtJV3f1eh7eHCn5Id9k,4507
|
207
216
|
uk_bin_collection/uk_bin_collection/councils/WestSuffolkCouncil.py,sha256=9i8AQHh-qIRPZ_5Ad97_h04-qgyLQDPV064obBzab1Y,2587
|
208
217
|
uk_bin_collection/uk_bin_collection/councils/WiganBoroughCouncil.py,sha256=3gqFA4-BVx_In6QOu3KUNqPN4Fkn9iMlZTeopMK9p6A,3746
|
209
218
|
uk_bin_collection/uk_bin_collection/councils/WiltshireCouncil.py,sha256=it2Oh5Kmq3lD30gAZgk2bzZPNCtJcFHyQO1NgOQtfvU,5653
|
@@ -218,8 +227,8 @@ uk_bin_collection/uk_bin_collection/councils/YorkCouncil.py,sha256=I2kBYMlsD4bId
|
|
218
227
|
uk_bin_collection/uk_bin_collection/councils/council_class_template/councilclasstemplate.py,sha256=4s9ODGPAwPqwXc8SrTX5Wlfmizs3_58iXUtHc4Ir86o,1162
|
219
228
|
uk_bin_collection/uk_bin_collection/create_new_council.py,sha256=m-IhmWmeWQlFsTZC4OxuFvtw5ZtB8EAJHxJTH4O59lQ,1536
|
220
229
|
uk_bin_collection/uk_bin_collection/get_bin_data.py,sha256=YvmHfZqanwrJ8ToGch34x-L-7yPe31nB_x77_Mgl_vo,4545
|
221
|
-
uk_bin_collection-0.
|
222
|
-
uk_bin_collection-0.
|
223
|
-
uk_bin_collection-0.
|
224
|
-
uk_bin_collection-0.
|
225
|
-
uk_bin_collection-0.
|
230
|
+
uk_bin_collection-0.105.0.dist-info/LICENSE,sha256=vABBUOzcrgfaTKpzeo-si9YVEun6juDkndqA8RKdKGs,1071
|
231
|
+
uk_bin_collection-0.105.0.dist-info/METADATA,sha256=piPVFSMkpv1tY--WjVgRXiTHDaTPs_F3g9zRg3qb0-Q,17630
|
232
|
+
uk_bin_collection-0.105.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
233
|
+
uk_bin_collection-0.105.0.dist-info/entry_points.txt,sha256=36WCSGMWSc916S3Hi1ZkazzDKHaJ6CD-4fCEFm5MIao,90
|
234
|
+
uk_bin_collection-0.105.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
{uk_bin_collection-0.103.0.dist-info → uk_bin_collection-0.105.0.dist-info}/entry_points.txt
RENAMED
File without changes
|