uk_bin_collection 0.79.0__py3-none-any.whl → 0.80.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.
- uk_bin_collection/tests/input.json +39 -1
- uk_bin_collection/uk_bin_collection/common.py +23 -1
- uk_bin_collection/uk_bin_collection/councils/BedfordshireCouncil.py +2 -1
- uk_bin_collection/uk_bin_collection/councils/BirminghamCityCouncil.py +2 -1
- uk_bin_collection/uk_bin_collection/councils/BracknellForestCouncil.py +4 -4
- uk_bin_collection/uk_bin_collection/councils/BristolCityCouncil.py +2 -1
- uk_bin_collection/uk_bin_collection/councils/CrawleyBoroughCouncil.py +1 -1
- uk_bin_collection/uk_bin_collection/councils/CroydonCouncil.py +5 -4
- uk_bin_collection/uk_bin_collection/councils/DartfordBoroughCouncil.py +7 -9
- uk_bin_collection/uk_bin_collection/councils/EastCambridgeshireCouncil.py +2 -1
- uk_bin_collection/uk_bin_collection/councils/LancasterCityCouncil.py +6 -4
- uk_bin_collection/uk_bin_collection/councils/LisburnCastlereaghCityCouncil.py +1 -0
- uk_bin_collection/uk_bin_collection/councils/ManchesterCityCouncil.py +2 -1
- uk_bin_collection/uk_bin_collection/councils/NewForestCouncil.py +146 -0
- uk_bin_collection/uk_bin_collection/councils/NewportCityCouncil.py +1 -0
- uk_bin_collection/uk_bin_collection/councils/NorthTynesideCouncil.py +2 -1
- uk_bin_collection/uk_bin_collection/councils/SomersetCouncil.py +1 -0
- uk_bin_collection/uk_bin_collection/councils/SouthCambridgeshireCouncil.py +1 -0
- uk_bin_collection/uk_bin_collection/councils/StHelensBC.py +2 -1
- uk_bin_collection/uk_bin_collection/councils/StaffordBoroughCouncil.py +69 -0
- uk_bin_collection/uk_bin_collection/councils/SwanseaCouncil.py +70 -0
- uk_bin_collection/uk_bin_collection/councils/TestValleyBoroughCouncil.py +1 -0
- uk_bin_collection/uk_bin_collection/councils/ThreeRiversDistrictCouncil.py +140 -0
- uk_bin_collection/uk_bin_collection/councils/UttlesfordDistrictCouncil.py +117 -0
- uk_bin_collection/uk_bin_collection/councils/WaverleyBoroughCouncil.py +2 -1
- uk_bin_collection/uk_bin_collection/councils/WiganBoroughCouncil.py +2 -1
- uk_bin_collection/uk_bin_collection/councils/WindsorAndMaidenheadCouncil.py +2 -1
- uk_bin_collection/uk_bin_collection/councils/WokingBoroughCouncil.py +3 -1
- {uk_bin_collection-0.79.0.dist-info → uk_bin_collection-0.80.0.dist-info}/METADATA +1 -1
- {uk_bin_collection-0.79.0.dist-info → uk_bin_collection-0.80.0.dist-info}/RECORD +33 -28
- {uk_bin_collection-0.79.0.dist-info → uk_bin_collection-0.80.0.dist-info}/LICENSE +0 -0
- {uk_bin_collection-0.79.0.dist-info → uk_bin_collection-0.80.0.dist-info}/WHEEL +0 -0
- {uk_bin_collection-0.79.0.dist-info → uk_bin_collection-0.80.0.dist-info}/entry_points.txt +0 -0
@@ -263,9 +263,9 @@
|
|
263
263
|
"wiki_name": "Croydon Council"
|
264
264
|
},
|
265
265
|
"DartfordBoroughCouncil": {
|
266
|
+
"uprn": "010094157511",
|
266
267
|
"url": "https://windmz.dartford.gov.uk/ufs/WS_CHECK_COLLECTIONS.eb?UPRN=010094157511",
|
267
268
|
"wiki_name": "DartfordBoroughCouncil",
|
268
|
-
"uprn": "010094157511",
|
269
269
|
"wiki_note": "Use https://uprn.uk/ to find your UPRN "
|
270
270
|
},
|
271
271
|
"DerbyshireDalesDistrictCouncil": {
|
@@ -602,6 +602,14 @@
|
|
602
602
|
"web_driver": "http://selenium:4444",
|
603
603
|
"wiki_name": "Neath Port Talbot Council"
|
604
604
|
},
|
605
|
+
"NewForestCouncil": {
|
606
|
+
"postcode": "SO41 0GJ",
|
607
|
+
"skip_get_url": true,
|
608
|
+
"uprn": "100060482345",
|
609
|
+
"url": "https://forms.newforest.gov.uk/id/FIND_MY_COLLECTION",
|
610
|
+
"web_driver": "http://selenium:4444",
|
611
|
+
"wiki_name": "New Forest Council"
|
612
|
+
},
|
605
613
|
"NewarkAndSherwoodDC": {
|
606
614
|
"url": "http://app.newark-sherwooddc.gov.uk/bincollection/calendar?pid=200004258529",
|
607
615
|
"wiki_command_url_override": "http://app.newark-sherwooddc.gov.uk/bincollection/calendar?pid=XXXXXXXX",
|
@@ -909,6 +917,12 @@
|
|
909
917
|
"url": "https://www.sthelens.gov.uk/",
|
910
918
|
"wiki_name": "St Helens Borough Council"
|
911
919
|
},
|
920
|
+
"StaffordBoroughCouncil": {
|
921
|
+
"uprn": "100032203010",
|
922
|
+
"url": "https://www.staffordbc.gov.uk/address/100032203010",
|
923
|
+
"wiki_name": "StaffordBoroughCouncil",
|
924
|
+
"wiki_note": "The URL needs to be https://www.staffordbc.gov.uk/address/<Your_UPRN>"
|
925
|
+
},
|
912
926
|
"StaffordshireMoorlandsDistrictCouncil": {
|
913
927
|
"postcode": "ST8 6HN",
|
914
928
|
"skip_get_url": true,
|
@@ -959,6 +973,13 @@
|
|
959
973
|
"url": "https://swale.gov.uk/bins-littering-and-the-environment/bins/collection-days",
|
960
974
|
"wiki_name": "Swale Borough Council"
|
961
975
|
},
|
976
|
+
"SwanseaCouncil": {
|
977
|
+
"postcode": "SA43PQ",
|
978
|
+
"skip_get_url": true,
|
979
|
+
"uprn": "100100324821",
|
980
|
+
"url": "https://www1.swansea.gov.uk/recyclingsearch/",
|
981
|
+
"wiki_name": "SwanseaCouncil"
|
982
|
+
},
|
962
983
|
"TamesideMBCouncil": {
|
963
984
|
"skip_get_url": true,
|
964
985
|
"uprn": "100012835362",
|
@@ -992,6 +1013,14 @@
|
|
992
1013
|
"url": "https://testvalley.gov.uk/wasteandrecycling/when-are-my-bins-collected",
|
993
1014
|
"wiki_name": "Test Valley Borough Council"
|
994
1015
|
},
|
1016
|
+
"ThreeRiversDistrictCouncil": {
|
1017
|
+
"postcode": "WD3 7AZ",
|
1018
|
+
"skip_get_url": true,
|
1019
|
+
"uprn": "100080913662",
|
1020
|
+
"url": "https://my.threerivers.gov.uk/en/AchieveForms/?mode=fill&consentMessage=yes&form_uri=sandbox-publish://AF-Process-52df96e3-992a-4b39-bba3-06cfaabcb42b/AF-Stage-01ee28aa-1584-442c-8d1f-119b6e27114a/definition.json&process=1&process_uri=sandbox-processes://AF-Process-52df96e3-992a-4b39-bba3-06cfaabcb42b&process_id=AF-Process-52df96e3-992a-4b39-bba3-06cfaabcb42b&noLoginPrompt=1",
|
1021
|
+
"web_driver": "http://selenium:4444",
|
1022
|
+
"wiki_name": "Three Rivers District Council"
|
1023
|
+
},
|
995
1024
|
"TonbridgeAndMallingBC": {
|
996
1025
|
"postcode": "ME19 4JS",
|
997
1026
|
"skip_get_url": true,
|
@@ -1011,6 +1040,15 @@
|
|
1011
1040
|
"url": "https://collections-torridge.azurewebsites.net/WebService2.asmx",
|
1012
1041
|
"wiki_name": "Torridge District Council"
|
1013
1042
|
},
|
1043
|
+
"UttlesfordDistrictCouncil": {
|
1044
|
+
"url": "https://bins.uttlesford.gov.uk/",
|
1045
|
+
"wiki_name": "UttlesfordDistrictCouncil",
|
1046
|
+
"skip_get_url": true,
|
1047
|
+
"postcode": "CM23 5QF",
|
1048
|
+
"uprn": "100090643434",
|
1049
|
+
"house_number": "72, Birchanger Lane",
|
1050
|
+
"web_driver": "http://selenium:4444"
|
1051
|
+
},
|
1014
1052
|
"ValeofGlamorganCouncil": {
|
1015
1053
|
"skip_get_url": true,
|
1016
1054
|
"uprn": "64029020",
|
@@ -5,7 +5,7 @@ import os
|
|
5
5
|
import pandas as pd
|
6
6
|
import re
|
7
7
|
import requests
|
8
|
-
from datetime import datetime
|
8
|
+
from datetime import datetime, timedelta
|
9
9
|
from dateutil.parser import parse
|
10
10
|
from enum import Enum
|
11
11
|
from selenium import webdriver
|
@@ -242,6 +242,28 @@ def save_data(file_path, data):
|
|
242
242
|
json.dump(data, file, sort_keys=True, indent=4)
|
243
243
|
|
244
244
|
|
245
|
+
def get_next_day_of_week(day_name):
|
246
|
+
days_of_week = [
|
247
|
+
"Monday",
|
248
|
+
"Tuesday",
|
249
|
+
"Wednesday",
|
250
|
+
"Thursday",
|
251
|
+
"Friday",
|
252
|
+
"Saturday",
|
253
|
+
"Sunday",
|
254
|
+
]
|
255
|
+
today = datetime.now()
|
256
|
+
today_idx = today.weekday() # Monday is 0 and Sunday is 6
|
257
|
+
target_idx = days_of_week.index(day_name)
|
258
|
+
|
259
|
+
days_until_target = (target_idx - today_idx) % 7
|
260
|
+
if days_until_target == 0:
|
261
|
+
days_until_target = 7 # Ensure it's the next instance of the day, not today if today is that day
|
262
|
+
|
263
|
+
next_day = today + timedelta(days=days_until_target)
|
264
|
+
return next_day.strftime(date_format)
|
265
|
+
|
266
|
+
|
245
267
|
def contains_date(string, fuzzy=False) -> bool:
|
246
268
|
"""
|
247
269
|
Return whether the string can be interpreted as a date.
|
@@ -2,6 +2,7 @@ from datetime import datetime
|
|
2
2
|
|
3
3
|
import requests
|
4
4
|
from bs4 import BeautifulSoup
|
5
|
+
|
5
6
|
from uk_bin_collection.uk_bin_collection.common import *
|
6
7
|
from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
|
7
8
|
|
@@ -22,7 +23,7 @@ class CouncilClass(AbstractGetBinDataClass):
|
|
22
23
|
|
23
24
|
# Start a new session to walk through the form
|
24
25
|
requests.packages.urllib3.disable_warnings()
|
25
|
-
s = requests.
|
26
|
+
s = requests.Session()
|
26
27
|
|
27
28
|
headers = {
|
28
29
|
"Origin": "https://www.centralbedfordshire.gov.uk",
|
@@ -1,5 +1,6 @@
|
|
1
|
-
from dateutil.relativedelta import relativedelta
|
2
1
|
from bs4 import BeautifulSoup
|
2
|
+
from dateutil.relativedelta import relativedelta
|
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
|
|
@@ -64,7 +64,7 @@ def get_csrf_token(s: requests.session, base_url: str) -> str:
|
|
64
64
|
"""
|
65
65
|
Gets a CSRF token
|
66
66
|
:rtype: str
|
67
|
-
:param s: requests.
|
67
|
+
:param s: requests.Session() to use
|
68
68
|
:param base_url: Base URL to use
|
69
69
|
:return: CSRF token
|
70
70
|
"""
|
@@ -95,7 +95,7 @@ def get_address_id(
|
|
95
95
|
"""
|
96
96
|
Gets the address ID
|
97
97
|
:rtype: str
|
98
|
-
:param s: requests.
|
98
|
+
:param s: requests.Session() to use
|
99
99
|
:param base_url: Base URL to use
|
100
100
|
:param csrf_token: CSRF token to use
|
101
101
|
:param postcode: Postcode to use
|
@@ -156,7 +156,7 @@ def get_collection_data(
|
|
156
156
|
"""
|
157
157
|
Gets the collection data
|
158
158
|
:rtype: str
|
159
|
-
:param s: requests.
|
159
|
+
:param s: requests.Session() to use
|
160
160
|
:param base_url: Base URL to use
|
161
161
|
:param csrf_token: CSRF token to use
|
162
162
|
:param address_id: Address id to use
|
@@ -203,7 +203,7 @@ class CouncilClass(AbstractGetBinDataClass):
|
|
203
203
|
|
204
204
|
def parse_data(self, page: str, **kwargs) -> dict:
|
205
205
|
requests.packages.urllib3.disable_warnings()
|
206
|
-
s = requests.
|
206
|
+
s = requests.Session()
|
207
207
|
base_url = "https://selfservice.mybfc.bracknell-forest.gov.uk"
|
208
208
|
paon = kwargs.get("paon")
|
209
209
|
postcode = kwargs.get("postcode")
|
@@ -2,6 +2,7 @@ import ast
|
|
2
2
|
|
3
3
|
import requests
|
4
4
|
from bs4 import BeautifulSoup
|
5
|
+
|
5
6
|
from uk_bin_collection.uk_bin_collection.common import *
|
6
7
|
from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
|
7
8
|
|
@@ -19,7 +20,7 @@ class CouncilClass(AbstractGetBinDataClass):
|
|
19
20
|
check_uprn(user_uprn)
|
20
21
|
|
21
22
|
requests.packages.urllib3.disable_warnings()
|
22
|
-
s = requests.
|
23
|
+
s = requests.Session()
|
23
24
|
|
24
25
|
service_type_headers = {
|
25
26
|
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,"
|
@@ -35,7 +35,7 @@ class CouncilClass(AbstractGetBinDataClass):
|
|
35
35
|
|
36
36
|
data = {"bins": []}
|
37
37
|
|
38
|
-
titles = [title.text for title in soup.select(".title")]
|
38
|
+
titles = [title.text for title in soup.select(".block-title")]
|
39
39
|
collection_tag = soup.body.find_all(
|
40
40
|
"div", {"class": "col-md-6 col-sm-6 col-xs-6"}, string="Next collection"
|
41
41
|
)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import time
|
2
2
|
|
3
3
|
from bs4 import BeautifulSoup
|
4
|
+
|
4
5
|
from uk_bin_collection.uk_bin_collection.common import *
|
5
6
|
from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
|
6
7
|
|
@@ -75,7 +76,7 @@ def get_csrf_token(s: requests.session, base_url: str) -> str:
|
|
75
76
|
"""
|
76
77
|
Gets a CSRF token
|
77
78
|
:rtype: str
|
78
|
-
:param s: requests.
|
79
|
+
:param s: requests.Session() to use
|
79
80
|
:param base_url: Base URL to use
|
80
81
|
:return: CSRF token
|
81
82
|
"""
|
@@ -106,7 +107,7 @@ def get_address_id(
|
|
106
107
|
"""
|
107
108
|
Gets the address ID
|
108
109
|
:rtype: str
|
109
|
-
:param s: requests.
|
110
|
+
:param s: requests.Session() to use
|
110
111
|
:param base_url: Base URL to use
|
111
112
|
:param csrf_token: CSRF token to use
|
112
113
|
:param postcode: Postcode to use
|
@@ -171,7 +172,7 @@ def get_collection_data(
|
|
171
172
|
"""
|
172
173
|
Gets the collection data
|
173
174
|
:rtype: str
|
174
|
-
:param s: requests.
|
175
|
+
:param s: requests.Session() to use
|
175
176
|
:param base_url: Base URL to use
|
176
177
|
:param csrf_token: CSRF token to use
|
177
178
|
:param address_id: Address id to use
|
@@ -240,7 +241,7 @@ class CouncilClass(AbstractGetBinDataClass):
|
|
240
241
|
|
241
242
|
def parse_data(self, page: str, **kwargs) -> dict:
|
242
243
|
requests.packages.urllib3.disable_warnings()
|
243
|
-
s = requests.
|
244
|
+
s = requests.Session()
|
244
245
|
base_url = "https://service.croydon.gov.uk"
|
245
246
|
paon = kwargs.get("paon")
|
246
247
|
postcode = kwargs.get("postcode")
|
@@ -17,27 +17,25 @@ class CouncilClass(AbstractGetBinDataClass):
|
|
17
17
|
soup.prettify()
|
18
18
|
|
19
19
|
# Extract data
|
20
|
-
bin_data = {
|
21
|
-
"bins": []
|
22
|
-
}
|
20
|
+
bin_data = {"bins": []}
|
23
21
|
|
24
22
|
# Find the table containing the bin collection data
|
25
|
-
table = soup.find(
|
23
|
+
table = soup.find("table", {"class": "eb-EVDNdR1G-tableContent"})
|
26
24
|
|
27
25
|
if table:
|
28
|
-
rows = table.find_all(
|
29
|
-
|
26
|
+
rows = table.find_all("tr", class_="eb-EVDNdR1G-tableRow")
|
27
|
+
|
30
28
|
for row in rows:
|
31
|
-
columns = row.find_all(
|
29
|
+
columns = row.find_all("td")
|
32
30
|
if len(columns) >= 4:
|
33
31
|
collection_type = columns[1].get_text(strip=True)
|
34
32
|
collection_date = columns[3].get_text(strip=True)
|
35
|
-
|
33
|
+
|
36
34
|
# Validate collection_date format
|
37
35
|
if re.match(r"\d{2}/\d{2}/\d{4}", collection_date):
|
38
36
|
bin_entry = {
|
39
37
|
"type": collection_type,
|
40
|
-
"collectionDate": collection_date
|
38
|
+
"collectionDate": collection_date,
|
41
39
|
}
|
42
40
|
bin_data["bins"].append(bin_entry)
|
43
41
|
|
@@ -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
|
|
@@ -21,7 +22,7 @@ class CouncilClass(AbstractGetBinDataClass):
|
|
21
22
|
|
22
23
|
# Make Request
|
23
24
|
requests.packages.urllib3.disable_warnings()
|
24
|
-
s = requests.
|
25
|
+
s = requests.Session()
|
25
26
|
page = s.get(url)
|
26
27
|
|
27
28
|
# Make a BS4 object
|
@@ -1,8 +1,10 @@
|
|
1
|
-
from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
|
2
|
-
from uk_bin_collection.uk_bin_collection.common import *
|
3
|
-
from bs4 import BeautifulSoup
|
4
1
|
from datetime import datetime
|
2
|
+
|
5
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
|
6
8
|
|
7
9
|
|
8
10
|
class CouncilClass(AbstractGetBinDataClass):
|
@@ -19,7 +21,7 @@ class CouncilClass(AbstractGetBinDataClass):
|
|
19
21
|
# start session
|
20
22
|
# note: this ignores the given url
|
21
23
|
base_url = "https://lcc-wrp.whitespacews.com"
|
22
|
-
session = requests.
|
24
|
+
session = requests.Session()
|
23
25
|
response = session.get(base_url + "/#!")
|
24
26
|
links = [
|
25
27
|
a["href"]
|
@@ -2,6 +2,7 @@ from datetime import datetime
|
|
2
2
|
|
3
3
|
import requests
|
4
4
|
from bs4 import BeautifulSoup
|
5
|
+
|
5
6
|
from uk_bin_collection.uk_bin_collection.common import *
|
6
7
|
from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
|
7
8
|
|
@@ -20,7 +21,7 @@ class CouncilClass(AbstractGetBinDataClass):
|
|
20
21
|
|
21
22
|
# Start a new session to walk through the form
|
22
23
|
requests.packages.urllib3.disable_warnings()
|
23
|
-
s = requests.
|
24
|
+
s = requests.Session()
|
24
25
|
|
25
26
|
# There's a cookie that makes the whole thing valid when you search for a postcode,
|
26
27
|
# but postcode and UPRN is a hassle imo, so this makes a request for the session to get a cookie
|
@@ -0,0 +1,146 @@
|
|
1
|
+
import logging
|
2
|
+
import pickle
|
3
|
+
import time
|
4
|
+
|
5
|
+
import requests
|
6
|
+
from bs4 import BeautifulSoup
|
7
|
+
from selenium import webdriver
|
8
|
+
from selenium.webdriver.common.by import By
|
9
|
+
from selenium.webdriver.common.keys import Keys
|
10
|
+
from selenium.webdriver.support import expected_conditions as EC
|
11
|
+
from selenium.webdriver.support.ui import Select
|
12
|
+
from selenium.webdriver.support.wait import WebDriverWait
|
13
|
+
from uk_bin_collection.uk_bin_collection.common import *
|
14
|
+
|
15
|
+
from uk_bin_collection.uk_bin_collection.common import *
|
16
|
+
from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
|
17
|
+
|
18
|
+
# Set up logging
|
19
|
+
logging.basicConfig(
|
20
|
+
level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
|
21
|
+
)
|
22
|
+
|
23
|
+
|
24
|
+
class CouncilClass(AbstractGetBinDataClass):
|
25
|
+
|
26
|
+
def parse_data(self, page: str, **kwargs) -> dict:
|
27
|
+
driver = None
|
28
|
+
try:
|
29
|
+
data = {"bins": []}
|
30
|
+
collections = []
|
31
|
+
user_uprn = kwargs.get("uprn")
|
32
|
+
user_postcode = kwargs.get("postcode")
|
33
|
+
web_driver = kwargs.get("web_driver")
|
34
|
+
headless = kwargs.get("headless")
|
35
|
+
check_postcode(user_postcode)
|
36
|
+
url = "https://forms.newforest.gov.uk/ufs/FIND_MY_COLLECTION.eb"
|
37
|
+
|
38
|
+
# Get session cookies using requests
|
39
|
+
|
40
|
+
user_agent = """general.useragent.override", "userAgent=Mozilla/5.0
|
41
|
+
(iPhone; CPU iPhone OS 15_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like
|
42
|
+
Gecko) CriOS/101.0.4951.44 Mobile/15E148 Safari/604.1"""
|
43
|
+
|
44
|
+
# Create Selenium webdriver
|
45
|
+
driver = create_webdriver(web_driver, headless, user_agent, __name__)
|
46
|
+
|
47
|
+
# Navigate to the page first
|
48
|
+
driver.get(url)
|
49
|
+
driver.refresh() # important otherwise it results in too many redirects
|
50
|
+
|
51
|
+
wait = WebDriverWait(driver, 60)
|
52
|
+
|
53
|
+
logging.info("Entering postcode")
|
54
|
+
input_element_postcode = wait.until(
|
55
|
+
EC.presence_of_element_located((By.XPATH, '//input[@id="CTID-1-_-A"]'))
|
56
|
+
)
|
57
|
+
|
58
|
+
input_element_postcode.send_keys(user_postcode)
|
59
|
+
|
60
|
+
logging.info("Searching for postcode")
|
61
|
+
input_element_postcode_btn = wait.until(
|
62
|
+
EC.element_to_be_clickable((By.XPATH, '//input[@type="submit"]'))
|
63
|
+
)
|
64
|
+
|
65
|
+
input_element_postcode_btn.click()
|
66
|
+
|
67
|
+
logging.info("Waiting for address dropdown")
|
68
|
+
input_element_postcode_dropdown = wait.until(
|
69
|
+
EC.presence_of_element_located((By.XPATH, '//select[@id="CTID-6-_-A"]'))
|
70
|
+
)
|
71
|
+
|
72
|
+
logging.info("Selecting address")
|
73
|
+
drop_down_values = Select(input_element_postcode_dropdown)
|
74
|
+
option_element = wait.until(
|
75
|
+
EC.presence_of_element_located(
|
76
|
+
(By.CSS_SELECTOR, f'option[value="{str(user_uprn)}"]')
|
77
|
+
)
|
78
|
+
)
|
79
|
+
|
80
|
+
driver.execute_script("arguments[0].scrollIntoView();", option_element)
|
81
|
+
drop_down_values.select_by_value(str(user_uprn))
|
82
|
+
|
83
|
+
input_element_address_btn = wait.until(
|
84
|
+
EC.element_to_be_clickable((By.XPATH, '//input[@value="Submit"]'))
|
85
|
+
)
|
86
|
+
|
87
|
+
input_element_address_btn.click()
|
88
|
+
|
89
|
+
logging.info("Waiting for bin collection page")
|
90
|
+
h4_element = wait.until(
|
91
|
+
EC.presence_of_element_located(
|
92
|
+
(By.XPATH, "//h1[contains(text(), 'Collections days for')]")
|
93
|
+
)
|
94
|
+
)
|
95
|
+
|
96
|
+
logging.info("Extracting bin collection data")
|
97
|
+
soup = BeautifulSoup(driver.page_source, features="html.parser")
|
98
|
+
bins = []
|
99
|
+
|
100
|
+
# Rubbish and recycling
|
101
|
+
rubbish_recycling = soup.find(
|
102
|
+
"span", class_="CTID-77-_ eb-77-Override-textControl"
|
103
|
+
)
|
104
|
+
if rubbish_recycling:
|
105
|
+
match = re.search(r"collected weekly on (\w+)", rubbish_recycling.text)
|
106
|
+
if match:
|
107
|
+
day_name = match.group(1)
|
108
|
+
next_collection = get_next_day_of_week(day_name)
|
109
|
+
bins.append(
|
110
|
+
{
|
111
|
+
"type": "Rubbish and recycling",
|
112
|
+
"collectionDate": next_collection,
|
113
|
+
}
|
114
|
+
)
|
115
|
+
|
116
|
+
# Glass collection
|
117
|
+
glass_collection = soup.find("span", class_="CTID-78-_ eb-78-textControl")
|
118
|
+
if glass_collection:
|
119
|
+
match = re.search(
|
120
|
+
r"next collection is\s+(\d{2}/\d{2}/\d{4})", glass_collection.text
|
121
|
+
)
|
122
|
+
if match:
|
123
|
+
bins.append(
|
124
|
+
{"type": "Glass collection", "collectionDate": match.group(1)}
|
125
|
+
)
|
126
|
+
|
127
|
+
# Garden waste
|
128
|
+
garden_waste = soup.find("span", class_="CTID-17-_ eb-17-textControl")
|
129
|
+
if garden_waste:
|
130
|
+
match = re.search(
|
131
|
+
r"next collection is\s+(\d{2}/\d{2}/\d{4})", garden_waste.text
|
132
|
+
)
|
133
|
+
if match:
|
134
|
+
bins.append(
|
135
|
+
{"type": "Garden waste", "collectionDate": match.group(1)}
|
136
|
+
)
|
137
|
+
|
138
|
+
return {"bins": bins}
|
139
|
+
|
140
|
+
except Exception as e:
|
141
|
+
logging.error(f"An error occurred: {e}")
|
142
|
+
raise
|
143
|
+
|
144
|
+
finally:
|
145
|
+
if driver:
|
146
|
+
driver.quit()
|
@@ -3,6 +3,7 @@ from datetime import *
|
|
3
3
|
|
4
4
|
import requests
|
5
5
|
from bs4 import BeautifulSoup
|
6
|
+
|
6
7
|
from uk_bin_collection.uk_bin_collection.common import *
|
7
8
|
from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
|
8
9
|
|
@@ -24,7 +25,7 @@ class CouncilClass(AbstractGetBinDataClass):
|
|
24
25
|
check_postcode(user_postcode)
|
25
26
|
|
26
27
|
# Get form data
|
27
|
-
s = requests.
|
28
|
+
s = requests.Session()
|
28
29
|
cookies = {
|
29
30
|
"ntc-cookie-policy": "1",
|
30
31
|
"SSESS6ec6d5d2d471c0357053d5993a839bce": "qBdR7XhmSMd5_PDBIqG0It2R0Fq67igrejRY-WOcskE",
|
@@ -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
|
|
@@ -21,7 +22,7 @@ class CouncilClass(AbstractGetBinDataClass):
|
|
21
22
|
|
22
23
|
# Make Request
|
23
24
|
requests.packages.urllib3.disable_warnings()
|
24
|
-
s = requests.
|
25
|
+
s = requests.Session()
|
25
26
|
page = s.get(url)
|
26
27
|
|
27
28
|
# Make a BS4 object
|
@@ -0,0 +1,69 @@
|
|
1
|
+
from bs4 import BeautifulSoup
|
2
|
+
from uk_bin_collection.uk_bin_collection.common import *
|
3
|
+
from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
|
4
|
+
|
5
|
+
|
6
|
+
# import the wonderful Beautiful Soup and the URL grabber
|
7
|
+
class CouncilClass(AbstractGetBinDataClass):
|
8
|
+
"""
|
9
|
+
Concrete classes have to implement all abstract operations of the
|
10
|
+
base class. They can also override some operations with a default
|
11
|
+
implementation.
|
12
|
+
"""
|
13
|
+
|
14
|
+
def parse_date(self, date_str):
|
15
|
+
months = {
|
16
|
+
"Jan": "01",
|
17
|
+
"Feb": "02",
|
18
|
+
"Mar": "03",
|
19
|
+
"Apr": "04",
|
20
|
+
"May": "05",
|
21
|
+
"Jun": "06",
|
22
|
+
"Jul": "07",
|
23
|
+
"Aug": "08",
|
24
|
+
"Sep": "09",
|
25
|
+
"Oct": "10",
|
26
|
+
"Nov": "11",
|
27
|
+
"Dec": "12",
|
28
|
+
}
|
29
|
+
day, date, month_abbr, year = date_str.split()
|
30
|
+
month = months[month_abbr]
|
31
|
+
return f"{date}/{month}/{year}"
|
32
|
+
|
33
|
+
def parse_data(self, page: str, **kwargs) -> dict:
|
34
|
+
# Make a BS4 object
|
35
|
+
soup = BeautifulSoup(page.text, features="html.parser")
|
36
|
+
soup.prettify()
|
37
|
+
|
38
|
+
# Initialize the bin data structure
|
39
|
+
bin_data = {"bins": []}
|
40
|
+
|
41
|
+
# Find the table with collection dates
|
42
|
+
table = soup.find("table", class_="my-area")
|
43
|
+
|
44
|
+
# Extract the rows containing the bin collection information
|
45
|
+
rows = table.find_all("tr")
|
46
|
+
|
47
|
+
# Loop through the rows and extract bin data
|
48
|
+
for row in rows:
|
49
|
+
cells = row.find_all("td")
|
50
|
+
if len(cells) == 2:
|
51
|
+
bin_type = cells[0].get_text(strip=True)
|
52
|
+
collection_date = cells[1].get_text(strip=True)
|
53
|
+
|
54
|
+
if "Next refuse" in bin_type:
|
55
|
+
bin_data["bins"].append(
|
56
|
+
{
|
57
|
+
"type": "refuse",
|
58
|
+
"collectionDate": self.parse_date(collection_date),
|
59
|
+
}
|
60
|
+
)
|
61
|
+
elif "Next recycling" in bin_type:
|
62
|
+
bin_data["bins"].append(
|
63
|
+
{
|
64
|
+
"type": "recycling",
|
65
|
+
"collectionDate": self.parse_date(collection_date),
|
66
|
+
}
|
67
|
+
)
|
68
|
+
|
69
|
+
return bin_data
|
@@ -0,0 +1,70 @@
|
|
1
|
+
import logging
|
2
|
+
from datetime import datetime
|
3
|
+
|
4
|
+
import requests
|
5
|
+
from bs4 import BeautifulSoup
|
6
|
+
|
7
|
+
from uk_bin_collection.uk_bin_collection.common import *
|
8
|
+
from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
|
9
|
+
|
10
|
+
HEADERS = {
|
11
|
+
"user-agent": "Mozilla/5.0",
|
12
|
+
}
|
13
|
+
|
14
|
+
|
15
|
+
class CouncilClass(AbstractGetBinDataClass):
|
16
|
+
"""
|
17
|
+
Concrete class implementing all abstract operations of the base class.
|
18
|
+
"""
|
19
|
+
|
20
|
+
def get_session_variable(self, soup, id) -> str:
|
21
|
+
"""Extract ASP.NET variable from the HTML."""
|
22
|
+
element = soup.find("input", {"id": id})
|
23
|
+
if element:
|
24
|
+
return element.get("value")
|
25
|
+
else:
|
26
|
+
raise ValueError(f"Unable to find element with id: {id}")
|
27
|
+
|
28
|
+
def parse_data(self, page: str, **kwargs) -> dict:
|
29
|
+
# Create a session to handle cookies and headers
|
30
|
+
session = requests.Session()
|
31
|
+
session.headers.update(HEADERS)
|
32
|
+
user_uprn = kwargs.get("uprn")
|
33
|
+
user_postcode = kwargs.get("postcode")
|
34
|
+
URL = "https://www1.swansea.gov.uk/recyclingsearch/"
|
35
|
+
|
36
|
+
# Get initial ASP.NET variables
|
37
|
+
response = session.get(URL)
|
38
|
+
response.raise_for_status()
|
39
|
+
|
40
|
+
soup = BeautifulSoup(response.text, "html.parser")
|
41
|
+
|
42
|
+
data = {
|
43
|
+
"__VIEWSTATE": self.get_session_variable(soup, "__VIEWSTATE"),
|
44
|
+
"__VIEWSTATEGENERATOR": self.get_session_variable(
|
45
|
+
soup, "__VIEWSTATEGENERATOR"
|
46
|
+
),
|
47
|
+
"__VIEWSTATEENCRYPTED": "",
|
48
|
+
"__EVENTVALIDATION": self.get_session_variable(soup, "__EVENTVALIDATION"),
|
49
|
+
"txtRoadName": user_uprn,
|
50
|
+
"txtPostCode": user_postcode,
|
51
|
+
"btnSearch": "Search",
|
52
|
+
}
|
53
|
+
|
54
|
+
# Get the collection calendar
|
55
|
+
response = session.post(URL, data=data)
|
56
|
+
response.raise_for_status()
|
57
|
+
|
58
|
+
soup = BeautifulSoup(response.text, "html.parser")
|
59
|
+
|
60
|
+
next_refuse_date = soup.find("span", {"id": "lblNextRefuse"}).text.strip()
|
61
|
+
next_recycling_date = soup.find("span", {"id": "lblNextRecycling"}).text.strip()
|
62
|
+
|
63
|
+
bin_data = {
|
64
|
+
"bins": [
|
65
|
+
{"type": "Pink Week", "collectionDate": next_refuse_date},
|
66
|
+
{"type": "Green Week", "collectionDate": next_recycling_date},
|
67
|
+
]
|
68
|
+
}
|
69
|
+
|
70
|
+
return bin_data
|
@@ -0,0 +1,140 @@
|
|
1
|
+
import logging
|
2
|
+
import time
|
3
|
+
|
4
|
+
from bs4 import BeautifulSoup
|
5
|
+
from selenium.webdriver.common.by import By
|
6
|
+
from selenium.webdriver.support import expected_conditions as EC
|
7
|
+
from selenium.webdriver.support.ui import Select
|
8
|
+
from selenium.webdriver.support.wait import WebDriverWait
|
9
|
+
|
10
|
+
from uk_bin_collection.uk_bin_collection.common import *
|
11
|
+
from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
|
12
|
+
|
13
|
+
# Set up logging
|
14
|
+
logging.basicConfig(
|
15
|
+
level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
|
16
|
+
)
|
17
|
+
|
18
|
+
|
19
|
+
class CouncilClass(AbstractGetBinDataClass):
|
20
|
+
def parse_data(self, page: str, **kwargs) -> dict:
|
21
|
+
driver = None
|
22
|
+
try:
|
23
|
+
data = {"bins": []}
|
24
|
+
collections = []
|
25
|
+
user_uprn = kwargs.get("uprn")
|
26
|
+
user_postcode = kwargs.get("postcode")
|
27
|
+
web_driver = kwargs.get("web_driver")
|
28
|
+
headless = kwargs.get("headless")
|
29
|
+
check_postcode(user_postcode)
|
30
|
+
|
31
|
+
# Create Selenium webdriver
|
32
|
+
driver = create_webdriver(web_driver, headless, None, __name__)
|
33
|
+
if headless:
|
34
|
+
driver.set_window_size(1920, 1080)
|
35
|
+
|
36
|
+
driver.get(
|
37
|
+
"https://my.threerivers.gov.uk/en/AchieveForms/?mode=fill&consentMessage=yes&form_uri=sandbox-publish://AF-Process-52df96e3-992a-4b39-bba3-06cfaabcb42b/AF-Stage-01ee28aa-1584-442c-8d1f-119b6e27114a/definition.json&process=1&process_uri=sandbox-processes://AF-Process-52df96e3-992a-4b39-bba3-06cfaabcb42b&process_id=AF-Process-52df96e3-992a-4b39-bba3-06cfaabcb42b&noLoginPrompt=1"
|
38
|
+
)
|
39
|
+
wait = WebDriverWait(driver, 60)
|
40
|
+
|
41
|
+
def click_element(by, value):
|
42
|
+
element = wait.until(EC.element_to_be_clickable((by, value)))
|
43
|
+
driver.execute_script("arguments[0].scrollIntoView();", element)
|
44
|
+
element.click()
|
45
|
+
|
46
|
+
click_element(By.XPATH, "//button[contains(text(), 'Continue')]")
|
47
|
+
|
48
|
+
logging.info("Switching to iframe")
|
49
|
+
iframe_presence = wait.until(
|
50
|
+
EC.presence_of_element_located((By.ID, "fillform-frame-1"))
|
51
|
+
)
|
52
|
+
driver.switch_to.frame(iframe_presence)
|
53
|
+
|
54
|
+
logging.info("Entering postcode")
|
55
|
+
input_element_postcode = wait.until(
|
56
|
+
EC.presence_of_element_located(
|
57
|
+
(By.XPATH, '//input[@id="postcode_search"]')
|
58
|
+
)
|
59
|
+
)
|
60
|
+
input_element_postcode.send_keys(user_postcode)
|
61
|
+
|
62
|
+
logging.info("Selecting address")
|
63
|
+
dropdown = wait.until(EC.element_to_be_clickable((By.ID, "chooseAddress")))
|
64
|
+
dropdown_options = wait.until(
|
65
|
+
EC.presence_of_element_located((By.CLASS_NAME, "lookup-option"))
|
66
|
+
)
|
67
|
+
drop_down_values = Select(dropdown)
|
68
|
+
option_element = wait.until(
|
69
|
+
EC.presence_of_element_located(
|
70
|
+
(By.CSS_SELECTOR, f'option.lookup-option[value="{str(user_uprn)}"]')
|
71
|
+
)
|
72
|
+
)
|
73
|
+
|
74
|
+
driver.execute_script("arguments[0].scrollIntoView();", option_element)
|
75
|
+
drop_down_values.select_by_value(str(user_uprn))
|
76
|
+
|
77
|
+
option_element = wait.until(
|
78
|
+
EC.presence_of_element_located(
|
79
|
+
(By.XPATH, '//div[@class="fieldContent"][1]')
|
80
|
+
)
|
81
|
+
)
|
82
|
+
|
83
|
+
time.sleep(2)
|
84
|
+
|
85
|
+
click_element(By.XPATH, "//button/span[contains(text(), 'Next')]")
|
86
|
+
|
87
|
+
logging.info("Waiting for bin schedule")
|
88
|
+
bin_results = wait.until(
|
89
|
+
EC.presence_of_element_located(
|
90
|
+
(By.XPATH, "//div[@data-field-name='subCollectionCalendar']//table")
|
91
|
+
)
|
92
|
+
)
|
93
|
+
|
94
|
+
logging.info("Extracting bin collection data")
|
95
|
+
soup = BeautifulSoup(driver.page_source, features="html.parser")
|
96
|
+
bin_cards = soup.find_all(
|
97
|
+
"div", {"data-field-name": "subCollectionCalendar"}
|
98
|
+
)
|
99
|
+
|
100
|
+
bins = []
|
101
|
+
|
102
|
+
for bin_card in bin_cards:
|
103
|
+
# Try to find the table within the bin_card
|
104
|
+
table = bin_card.find(
|
105
|
+
"table",
|
106
|
+
{
|
107
|
+
"class": "repeatable-table table table-responsive table-hover table-condensed"
|
108
|
+
},
|
109
|
+
)
|
110
|
+
|
111
|
+
if table:
|
112
|
+
print("Table found")
|
113
|
+
rows = table.select("tr.repeatable-value")
|
114
|
+
for row in rows:
|
115
|
+
cols = row.find_all("td", class_="value")
|
116
|
+
if len(cols) >= 3: # Ensure there are enough columns
|
117
|
+
bin_type = cols[1].find_all("span")[-1].text.strip()
|
118
|
+
collection_date = (
|
119
|
+
cols[2]
|
120
|
+
.find_all("span")[-1]
|
121
|
+
.text.strip()
|
122
|
+
.replace("-", "/")
|
123
|
+
)
|
124
|
+
bins.append(
|
125
|
+
{"type": bin_type, "collectionDate": collection_date}
|
126
|
+
)
|
127
|
+
else:
|
128
|
+
print("Table not found within bin_card")
|
129
|
+
|
130
|
+
bin_data = {"bins": bins}
|
131
|
+
logging.info("Data extraction complete")
|
132
|
+
return bin_data
|
133
|
+
|
134
|
+
except Exception as e:
|
135
|
+
logging.error(f"An error occurred: {e}")
|
136
|
+
raise
|
137
|
+
|
138
|
+
finally:
|
139
|
+
if driver:
|
140
|
+
driver.quit()
|
@@ -0,0 +1,117 @@
|
|
1
|
+
import logging
|
2
|
+
import pickle
|
3
|
+
import time
|
4
|
+
|
5
|
+
import requests
|
6
|
+
from bs4 import BeautifulSoup
|
7
|
+
from selenium import webdriver
|
8
|
+
from selenium.webdriver.common.by import By
|
9
|
+
from selenium.webdriver.common.keys import Keys
|
10
|
+
from selenium.webdriver.support import expected_conditions as EC
|
11
|
+
from selenium.webdriver.support.ui import Select
|
12
|
+
from selenium.webdriver.support.wait import WebDriverWait
|
13
|
+
from uk_bin_collection.uk_bin_collection.common import *
|
14
|
+
|
15
|
+
from uk_bin_collection.uk_bin_collection.common import *
|
16
|
+
from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
|
17
|
+
|
18
|
+
# Set up logging
|
19
|
+
logging.basicConfig(
|
20
|
+
level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
|
21
|
+
)
|
22
|
+
|
23
|
+
|
24
|
+
class CouncilClass(AbstractGetBinDataClass):
|
25
|
+
|
26
|
+
def parse_data(self, page: str, **kwargs) -> dict:
|
27
|
+
driver = None
|
28
|
+
try:
|
29
|
+
user_paon = kwargs.get("paon")
|
30
|
+
user_postcode = kwargs.get("postcode")
|
31
|
+
web_driver = kwargs.get("web_driver")
|
32
|
+
headless = kwargs.get("headless")
|
33
|
+
check_postcode(user_postcode)
|
34
|
+
url = "https://bins.uttlesford.gov.uk/"
|
35
|
+
|
36
|
+
# Get session cookies using requests
|
37
|
+
|
38
|
+
user_agent = """general.useragent.override", "userAgent=Mozilla/5.0
|
39
|
+
(iPhone; CPU iPhone OS 15_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like
|
40
|
+
Gecko) CriOS/101.0.4951.44 Mobile/15E148 Safari/604.1"""
|
41
|
+
|
42
|
+
# Create Selenium webdriver
|
43
|
+
driver = create_webdriver(web_driver, headless, user_agent, __name__)
|
44
|
+
|
45
|
+
# Navigate to the page first
|
46
|
+
driver.get(url)
|
47
|
+
|
48
|
+
wait = WebDriverWait(driver, 60)
|
49
|
+
|
50
|
+
logging.info("Entering postcode")
|
51
|
+
input_element_postcode = wait.until(
|
52
|
+
EC.presence_of_element_located((By.XPATH, '//input[@id="postcode"]'))
|
53
|
+
)
|
54
|
+
|
55
|
+
input_element_postcode.send_keys(user_postcode)
|
56
|
+
input_element_postcode.send_keys(Keys.ENTER)
|
57
|
+
|
58
|
+
logging.info("Searching for postcode")
|
59
|
+
input_element_postcode_dd = wait.until(
|
60
|
+
EC.element_to_be_clickable((By.XPATH, '//select[@id="housenn"]'))
|
61
|
+
)
|
62
|
+
|
63
|
+
logging.info("Selecting address")
|
64
|
+
drop_down_values = Select(input_element_postcode_dd)
|
65
|
+
|
66
|
+
drop_down_values.select_by_visible_text(str(user_paon))
|
67
|
+
|
68
|
+
input_element_address_btn = wait.until(
|
69
|
+
EC.element_to_be_clickable(
|
70
|
+
(By.XPATH, '//input[@alt="View your waste collection days"]')
|
71
|
+
)
|
72
|
+
)
|
73
|
+
|
74
|
+
input_element_address_btn.click()
|
75
|
+
|
76
|
+
logging.info("Waiting for bin collection page")
|
77
|
+
h3_element = wait.until(
|
78
|
+
EC.presence_of_element_located(
|
79
|
+
(By.XPATH, "//h3[contains(text(), 'Future Collection Dates')]")
|
80
|
+
)
|
81
|
+
)
|
82
|
+
|
83
|
+
logging.info("Extracting bin collection data")
|
84
|
+
soup = BeautifulSoup(driver.page_source, features="html.parser")
|
85
|
+
|
86
|
+
bins = []
|
87
|
+
rows = soup.select("div.wrap table tbody tr")
|
88
|
+
|
89
|
+
for row in rows:
|
90
|
+
cols = row.find_all("td")
|
91
|
+
if len(cols) == 2:
|
92
|
+
bin_types = [img["alt"] for img in cols[0].find_all("img")]
|
93
|
+
collection_date_str = cols[1].text
|
94
|
+
collection_date = datetime.strptime(
|
95
|
+
collection_date_str, "%A %dth %B"
|
96
|
+
)
|
97
|
+
collection_date = collection_date.replace(
|
98
|
+
year=2024
|
99
|
+
) # Assuming the year is 2024
|
100
|
+
collection_date_str = collection_date.strftime("%d/%m/%Y")
|
101
|
+
|
102
|
+
for bin_type in bin_types:
|
103
|
+
bins.append(
|
104
|
+
{"type": bin_type, "collectionDate": collection_date_str}
|
105
|
+
)
|
106
|
+
|
107
|
+
bin_data = {"bins": bins}
|
108
|
+
|
109
|
+
return bin_data
|
110
|
+
|
111
|
+
except Exception as e:
|
112
|
+
logging.error(f"An error occurred: {e}")
|
113
|
+
raise
|
114
|
+
|
115
|
+
finally:
|
116
|
+
if driver:
|
117
|
+
driver.quit()
|
@@ -2,6 +2,7 @@ from datetime import date, datetime
|
|
2
2
|
|
3
3
|
import requests
|
4
4
|
from bs4 import BeautifulSoup
|
5
|
+
|
5
6
|
from uk_bin_collection.uk_bin_collection.common import *
|
6
7
|
from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
|
7
8
|
|
@@ -24,7 +25,7 @@ class CouncilClass(AbstractGetBinDataClass):
|
|
24
25
|
# WBC use a url parameter called "Track" that's generated when you start a form session.
|
25
26
|
# So first off, open the page, find the page link and copy it with the Track
|
26
27
|
start_url = "https://wav-wrp.whitespacews.com/"
|
27
|
-
s = requests.
|
28
|
+
s = requests.Session()
|
28
29
|
response = s.get(start_url)
|
29
30
|
soup = BeautifulSoup(response.content, features="html.parser")
|
30
31
|
soup.prettify()
|
@@ -2,6 +2,7 @@ from datetime import datetime
|
|
2
2
|
|
3
3
|
import requests
|
4
4
|
from bs4 import BeautifulSoup
|
5
|
+
|
5
6
|
from uk_bin_collection.uk_bin_collection.common import *
|
6
7
|
from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
|
7
8
|
|
@@ -27,7 +28,7 @@ class CouncilClass(AbstractGetBinDataClass):
|
|
27
28
|
|
28
29
|
# Start a new session to walk through the form
|
29
30
|
requests.packages.urllib3.disable_warnings()
|
30
|
-
s = requests.
|
31
|
+
s = requests.Session()
|
31
32
|
|
32
33
|
# Get our initial session running
|
33
34
|
response = s.get("https://apps.wigan.gov.uk/MyNeighbourhood/")
|
@@ -3,6 +3,7 @@ from urllib.parse import urlparse
|
|
3
3
|
|
4
4
|
import requests
|
5
5
|
from bs4 import BeautifulSoup
|
6
|
+
|
6
7
|
from uk_bin_collection.uk_bin_collection.common import *
|
7
8
|
from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
|
8
9
|
|
@@ -25,7 +26,7 @@ class CouncilClass(AbstractGetBinDataClass):
|
|
25
26
|
data = {"bins": []}
|
26
27
|
|
27
28
|
requests.packages.urllib3.disable_warnings()
|
28
|
-
s = requests.
|
29
|
+
s = requests.Session()
|
29
30
|
# Form start
|
30
31
|
headers = {
|
31
32
|
"authority": "my.rbwm.gov.uk",
|
@@ -2,14 +2,14 @@ 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=-t4WOCeYWUchkdm32IFhOJbufu0rP9vjwlzR43KLw3U,58920
|
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=zDLF5UUBp2n5S3ZlJod7AmYHt92TYQMMhHbX1keNn8U,3424
|
9
9
|
uk_bin_collection/tests/test_collect_data.py,sha256=C5w1qfz_1CU37_T7UPdBk3nisMLobIeVHNl6EXrgfrQ,3316
|
10
10
|
uk_bin_collection/tests/test_common_functions.py,sha256=IvTNmuFKm9u5j2A9PumMB6eScQS165sPknFakc0l-eg,11190
|
11
11
|
uk_bin_collection/uk_bin_collection/collect_data.py,sha256=txdtYoPgWDHLPohGz_Wu9OLXOr8TpXyuIGn0WnsFbZQ,4383
|
12
|
-
uk_bin_collection/uk_bin_collection/common.py,sha256=
|
12
|
+
uk_bin_collection/uk_bin_collection/common.py,sha256=ZvylERlKexeHtqBRb2_fZhYxC8aoEpUtcGo0dzJnWUo,9837
|
13
13
|
uk_bin_collection/uk_bin_collection/councils/AdurAndWorthingCouncils.py,sha256=ppbrmm-MzB1wOulK--CU_0j4P-djNf3ozMhHnmQFqLo,1511
|
14
14
|
uk_bin_collection/uk_bin_collection/councils/ArunCouncil.py,sha256=yfhthv9nuogP19VOZ3TYQrq51qqjiCZcSel4sXhiKjs,4012
|
15
15
|
uk_bin_collection/uk_bin_collection/councils/AylesburyValeCouncil.py,sha256=LouqjspEMt1TkOGqWHs2zkxwOETIy3n7p64uKIlAgUg,2401
|
@@ -19,15 +19,15 @@ uk_bin_collection/uk_bin_collection/councils/BarnsleyMBCouncil.py,sha256=MgF_7Xy
|
|
19
19
|
uk_bin_collection/uk_bin_collection/councils/BasingstokeCouncil.py,sha256=VPWGljnH4C3q8qs5ZmCtqjNjgWQvviALzjk00q3EZeQ,2632
|
20
20
|
uk_bin_collection/uk_bin_collection/councils/BathAndNorthEastSomersetCouncil.py,sha256=N_TPiIv8VBzN3rY0p3JtLlxSEru-6k1wW4UNIhN5X1M,3709
|
21
21
|
uk_bin_collection/uk_bin_collection/councils/BedfordBoroughCouncil.py,sha256=CvGB7w9HMn7XyEtwfd9MWZE_HlZ75pDcaKMsQJz0xhk,1669
|
22
|
-
uk_bin_collection/uk_bin_collection/councils/BedfordshireCouncil.py,sha256=
|
22
|
+
uk_bin_collection/uk_bin_collection/councils/BedfordshireCouncil.py,sha256=U1HOr9YLMAlFoZysfw5n04E0bVuCliO5Yj1FMiiwcHA,2549
|
23
23
|
uk_bin_collection/uk_bin_collection/councils/BexleyCouncil.py,sha256=9MrbpfR17R6DYjDrItQL3CPF7ie1SJkaoNbwQumPgIQ,5399
|
24
|
-
uk_bin_collection/uk_bin_collection/councils/BirminghamCityCouncil.py,sha256=
|
24
|
+
uk_bin_collection/uk_bin_collection/councils/BirminghamCityCouncil.py,sha256=x1LZiPn2C6JMHnj-R9cyrtUMnFb5o-kKtZK4sNuf6hY,4131
|
25
25
|
uk_bin_collection/uk_bin_collection/councils/BlackburnCouncil.py,sha256=jHbCK8sL09vdmdP7Xnh8lIrU5AHTnJLEZfOLephPvWg,4090
|
26
26
|
uk_bin_collection/uk_bin_collection/councils/BoltonCouncil.py,sha256=MrSzfK3EukRVasgP1nxAqg3lTkZzlAkDLJ2Nu5dJJ-0,4023
|
27
|
-
uk_bin_collection/uk_bin_collection/councils/BracknellForestCouncil.py,sha256=
|
27
|
+
uk_bin_collection/uk_bin_collection/councils/BracknellForestCouncil.py,sha256=Llo1rULaAZ8rChVYZqXFFLo7CN6vbT0ULUJD6ActouY,9015
|
28
28
|
uk_bin_collection/uk_bin_collection/councils/BradfordMDC.py,sha256=9EDTdhbGb8BQ5PLEw9eiWZ3BrS0TtoFpYOHQU44wc2k,4308
|
29
29
|
uk_bin_collection/uk_bin_collection/councils/BrightonandHoveCityCouncil.py,sha256=k6qt4cds-Ejd97Z-__pw2BYvGVbFdc9SUfF73PPrTNA,5823
|
30
|
-
uk_bin_collection/uk_bin_collection/councils/BristolCityCouncil.py,sha256=
|
30
|
+
uk_bin_collection/uk_bin_collection/councils/BristolCityCouncil.py,sha256=kJmmDJz_kQ45DHmG7ocrUpNJonEn0kuXYEDQyZaf9ks,5576
|
31
31
|
uk_bin_collection/uk_bin_collection/councils/BromleyBoroughCouncil.py,sha256=h92cM4SQwqFrBd9snnZuRgFjnftyZEoS7XfG3OUWa4k,4758
|
32
32
|
uk_bin_collection/uk_bin_collection/councils/BroxtoweBoroughCouncil.py,sha256=-Facq-ToQkcWUePpKBwq90LZUFxgUSydNL2sYaLX4yw,4473
|
33
33
|
uk_bin_collection/uk_bin_collection/councils/BuckinghamshireCouncil.py,sha256=rMc3lwu8UivbUZBiRedDhT8nBQQ83tvinc0QtmFjJNI,3184
|
@@ -43,15 +43,15 @@ uk_bin_collection/uk_bin_collection/councils/CheshireWestAndChesterCouncil.py,sh
|
|
43
43
|
uk_bin_collection/uk_bin_collection/councils/ChichesterDistrictCouncil.py,sha256=HxrLcJves7ZsE8FbooymeecTUmScY4R7Oi71vwCePPo,4118
|
44
44
|
uk_bin_collection/uk_bin_collection/councils/ChorleyCouncil.py,sha256=M7HjuUaFq8aSnOf_9m1QS4MmPPMmPhF3mLHSrfDPtV0,5194
|
45
45
|
uk_bin_collection/uk_bin_collection/councils/ConwyCountyBorough.py,sha256=el75qv2QyfWZBU09tJLvD8vLQZ9pCg73u1NBFs6ybo8,1034
|
46
|
-
uk_bin_collection/uk_bin_collection/councils/CrawleyBoroughCouncil.py,sha256=
|
47
|
-
uk_bin_collection/uk_bin_collection/councils/CroydonCouncil.py,sha256=
|
48
|
-
uk_bin_collection/uk_bin_collection/councils/DartfordBoroughCouncil.py,sha256=
|
46
|
+
uk_bin_collection/uk_bin_collection/councils/CrawleyBoroughCouncil.py,sha256=_BEKZAjlS5Ad5DjyxqAEFSLn8F-KYox0zmn4BXaAD6A,2367
|
47
|
+
uk_bin_collection/uk_bin_collection/councils/CroydonCouncil.py,sha256=QJH27plySbbmoNcLNUXq-hUiFmZ5zBlRS5mzOJgWSK8,11594
|
48
|
+
uk_bin_collection/uk_bin_collection/councils/DartfordBoroughCouncil.py,sha256=SPirUUoweMwX5Txtsr0ocdcFtKxCQ9LhzTTJN20tM4w,1550
|
49
49
|
uk_bin_collection/uk_bin_collection/councils/DerbyshireDalesDistrictCouncil.py,sha256=MQC1-jXezXczrxTcvPQvkpGgyyAbzSKlX38WsmftHak,4007
|
50
50
|
uk_bin_collection/uk_bin_collection/councils/DoncasterCouncil.py,sha256=b7pxoToXu6dBBYXsXmlwfPXE8BjHxt0hjCOBNlNgvX8,3118
|
51
51
|
uk_bin_collection/uk_bin_collection/councils/DorsetCouncil.py,sha256=sdSR5ryOSWHtK_0OKJ75LGOvMiUAnQCc3uwT3xfqZ_0,2304
|
52
52
|
uk_bin_collection/uk_bin_collection/councils/DoverDistrictCouncil.py,sha256=3Zgap6kaVpDXtRfBKEL1Ms6eb0iFIipYKNtOq3Hrdd4,1891
|
53
53
|
uk_bin_collection/uk_bin_collection/councils/DurhamCouncil.py,sha256=6O8bNsQVYQbrCYQE9Rp0c_rtkcXuxR3s9J6jn4MK4_s,1695
|
54
|
-
uk_bin_collection/uk_bin_collection/councils/EastCambridgeshireCouncil.py,sha256=
|
54
|
+
uk_bin_collection/uk_bin_collection/councils/EastCambridgeshireCouncil.py,sha256=aYUVE5QqTxdj8FHhCB4EiFVDJahWJD9Pq0d1upBEvXg,1501
|
55
55
|
uk_bin_collection/uk_bin_collection/councils/EastDevonDC.py,sha256=U0VwSNIldMv5nUoiXtFgjbE0m6Kb-8W2WZQGVCNF_WI,3261
|
56
56
|
uk_bin_collection/uk_bin_collection/councils/EastLindseyDistrictCouncil.py,sha256=o_HPSFhb2ybmwv32_7T7CO1f2mGDkYCNPfaM5xz6bUI,4356
|
57
57
|
uk_bin_collection/uk_bin_collection/councils/EastRidingCouncil.py,sha256=CsYdkmL-8Ty-Kz7uNdlnJnhiDMgOPah_swYgSKbaFqA,5218
|
@@ -77,15 +77,15 @@ uk_bin_collection/uk_bin_collection/councils/HuntingdonDistrictCouncil.py,sha256
|
|
77
77
|
uk_bin_collection/uk_bin_collection/councils/KingstonUponThamesCouncil.py,sha256=iZ7njIxccCGBhUUWWd9Azh7cxUAKaofebCm3lo-TuxA,3543
|
78
78
|
uk_bin_collection/uk_bin_collection/councils/KirkleesCouncil.py,sha256=gtAtM6FappSZ0-BKid7_pnSrnqPPjHn_UYWqMg9wQlM,4499
|
79
79
|
uk_bin_collection/uk_bin_collection/councils/KnowsleyMBCouncil.py,sha256=VdlWDESoHfr_X0r8-UMaLMUQhKZOa2BnpVPkX-1u3EQ,5605
|
80
|
-
uk_bin_collection/uk_bin_collection/councils/LancasterCityCouncil.py,sha256=
|
80
|
+
uk_bin_collection/uk_bin_collection/councils/LancasterCityCouncil.py,sha256=FmHT6oyD4BwWuhxA80PHnGA7HPrLuyjP_54Cg8hT6k4,2537
|
81
81
|
uk_bin_collection/uk_bin_collection/councils/LeedsCityCouncil.py,sha256=iSZApZ9oSfSatQ6dAxmykSfti91jGuY6n2BwEkVMOiU,5144
|
82
|
-
uk_bin_collection/uk_bin_collection/councils/LisburnCastlereaghCityCouncil.py,sha256=
|
82
|
+
uk_bin_collection/uk_bin_collection/councils/LisburnCastlereaghCityCouncil.py,sha256=vSOzdEwp9ZeUhed7E3eVv9ReD-2XgbSkpyAbVnfc-Gk,3309
|
83
83
|
uk_bin_collection/uk_bin_collection/councils/LiverpoolCityCouncil.py,sha256=n17OqZrCGrPrnxGUfHc-RGkb4oJ9Bx6uUWiLdzxfQlY,2587
|
84
84
|
uk_bin_collection/uk_bin_collection/councils/LondonBoroughHounslow.py,sha256=UOeiOxGMvVMm2UFaqjmQpm7vxzqJNSSN8LM9lAUjs2c,3021
|
85
85
|
uk_bin_collection/uk_bin_collection/councils/LondonBoroughRedbridge.py,sha256=A_6Sis5hsF53Th04KeadHRasGbpAm6aoaWJ6X8eC4Y8,6604
|
86
86
|
uk_bin_collection/uk_bin_collection/councils/MaldonDistrictCouncil.py,sha256=PMVt2XFggttPmbWyrBrHJ-W6R_6-0ux1BkY1kj1IKzg,1997
|
87
87
|
uk_bin_collection/uk_bin_collection/councils/MalvernHillsDC.py,sha256=iQG0EkX2npBicvsGKQRYyBGSBvKVUbKvUvvwrC9xV1A,2100
|
88
|
-
uk_bin_collection/uk_bin_collection/councils/ManchesterCityCouncil.py,sha256=
|
88
|
+
uk_bin_collection/uk_bin_collection/councils/ManchesterCityCouncil.py,sha256=RFXC4bRDYZgeFIzfsOWZXoBEWV7mNiM0HejhcPsP3a0,4920
|
89
89
|
uk_bin_collection/uk_bin_collection/councils/MansfieldDistrictCouncil.py,sha256=F5AiTxImrnjE1k3ry96bfstOf5XSNBJS_4qqmymmh3w,1386
|
90
90
|
uk_bin_collection/uk_bin_collection/councils/MertonCouncil.py,sha256=3Y2Un4xXo1sCcMsudynODSzocV_mMofWkX2JqONDb5o,1997
|
91
91
|
uk_bin_collection/uk_bin_collection/councils/MidAndEastAntrimBoroughCouncil.py,sha256=oOWwU5FSgGej2Mv7FQ66N-EzS5nZgmGsd0WnfLWUc1I,5238
|
@@ -93,10 +93,11 @@ uk_bin_collection/uk_bin_collection/councils/MidSussexDistrictCouncil.py,sha256=
|
|
93
93
|
uk_bin_collection/uk_bin_collection/councils/MiltonKeynesCityCouncil.py,sha256=3olsWa77L34vz-c7NgeGK9xmNuR4Ws_oAk5D4UpIkPw,2005
|
94
94
|
uk_bin_collection/uk_bin_collection/councils/MoleValleyDistrictCouncil.py,sha256=54-autRRGAM4pBxlqmUE6g825rmUF-gRqrcgHL_lkIk,3994
|
95
95
|
uk_bin_collection/uk_bin_collection/councils/NeathPortTalbotCouncil.py,sha256=2DJ0gK385CWTdJzWyDdmNBTTrwX6F5YbIXg7di2oXDQ,5506
|
96
|
+
uk_bin_collection/uk_bin_collection/councils/NewForestCouncil.py,sha256=ylTn9KmWITtaO9_Z8kJCN2w2ALfhrfGt3SeJ78lgw7M,5391
|
96
97
|
uk_bin_collection/uk_bin_collection/councils/NewarkAndSherwoodDC.py,sha256=lAleYfCGUWCKOi7Ye_cjgfpI3pWwTcFctlYmh0hjebM,2140
|
97
98
|
uk_bin_collection/uk_bin_collection/councils/NewcastleCityCouncil.py,sha256=eJMX10CG9QO7FRhHSmUDL-jO_44qoK3_1ztNTAXhkbw,2085
|
98
99
|
uk_bin_collection/uk_bin_collection/councils/NewhamCouncil.py,sha256=klFqr2Km1BuQ4wERmjbXZzOvN1N0jnVmhTGRSVzVOaU,2086
|
99
|
-
uk_bin_collection/uk_bin_collection/councils/NewportCityCouncil.py,sha256=
|
100
|
+
uk_bin_collection/uk_bin_collection/councils/NewportCityCouncil.py,sha256=dAcl5P97bttl2xCPvxof1a18kmqOrMmiElgtn3Ej7zs,8480
|
100
101
|
uk_bin_collection/uk_bin_collection/councils/NorthEastDerbyshireDistrictCouncil.py,sha256=bps_uCFAeUHQla7AE5lZOv6sUkUz1fb6zduZdAcYMuw,4651
|
101
102
|
uk_bin_collection/uk_bin_collection/councils/NorthEastLincs.py,sha256=fYf438VZIaOaqPSwdTTWVjFTdrI0jGfFsxVzOc-QdkA,1817
|
102
103
|
uk_bin_collection/uk_bin_collection/councils/NorthKestevenDistrictCouncil.py,sha256=vYOCerJXr9LTP6F2wm4vpYNYbQaWNZ6yfHEQ33N_hTw,1681
|
@@ -105,7 +106,7 @@ uk_bin_collection/uk_bin_collection/councils/NorthLincolnshireCouncil.py,sha256=
|
|
105
106
|
uk_bin_collection/uk_bin_collection/councils/NorthNorfolkDistrictCouncil.py,sha256=VV_zqVZYv8ekXcUHhrBlTX_W5qLYE9IA3mT2xmrZqoI,4315
|
106
107
|
uk_bin_collection/uk_bin_collection/councils/NorthNorthamptonshireCouncil.py,sha256=kcMN-5GBjYDM9F1BKfHoYeydub8SuDxHamJbSvJRZ68,2337
|
107
108
|
uk_bin_collection/uk_bin_collection/councils/NorthSomersetCouncil.py,sha256=EbFVnPYZIOkru5_Y75kjljM3Cr3HIJgP-SU6hxgf6tk,2754
|
108
|
-
uk_bin_collection/uk_bin_collection/councils/NorthTynesideCouncil.py,sha256=
|
109
|
+
uk_bin_collection/uk_bin_collection/councils/NorthTynesideCouncil.py,sha256=waH6_PyJaiEF-v9HR3C_aUdiPTcdHlxfAuuuKBsvkII,11353
|
109
110
|
uk_bin_collection/uk_bin_collection/councils/NorthWestLeicestershire.py,sha256=gJj0dyQc5QUefqusKGk2LLXfWbG5tlEXUOh8KAPh3RI,4584
|
110
111
|
uk_bin_collection/uk_bin_collection/councils/NorthYorkshire.py,sha256=2wTrr3VrZDp9-YtDPmWd649gXeWH4hbm2-Hw8Vau5Xs,1933
|
111
112
|
uk_bin_collection/uk_bin_collection/councils/NorthumberlandCouncil.py,sha256=KEFsxEvQ159fkuFo-fza67YCnnCZ5ElwE80zTrqDEWI,4990
|
@@ -127,9 +128,9 @@ uk_bin_collection/uk_bin_collection/councils/SevenoaksDistrictCouncil.py,sha256=
|
|
127
128
|
uk_bin_collection/uk_bin_collection/councils/SheffieldCityCouncil.py,sha256=9g9AeiackoWyej9EVlKUzywzAtMuBVD0f93ZryAUha8,2016
|
128
129
|
uk_bin_collection/uk_bin_collection/councils/ShropshireCouncil.py,sha256=6OIEhJmv-zLJiEo8WaJePA7JuhNRGkh2WohFLhzN8Kk,1477
|
129
130
|
uk_bin_collection/uk_bin_collection/councils/SolihullCouncil.py,sha256=gbTHjbdV46evGfLfF8rxVMQIgNZD-XPHgZeuyje7kGY,1609
|
130
|
-
uk_bin_collection/uk_bin_collection/councils/SomersetCouncil.py,sha256=
|
131
|
+
uk_bin_collection/uk_bin_collection/councils/SomersetCouncil.py,sha256=CZJnkCGn4-yH31HH5_ix-8V2_vsjGuKYxgzAPGZdSAw,8480
|
131
132
|
uk_bin_collection/uk_bin_collection/councils/SouthAyrshireCouncil.py,sha256=03eapeXwxneKI4ccKPSHoviIbhmV1m90I-0WQ_s3KsY,2722
|
132
|
-
uk_bin_collection/uk_bin_collection/councils/SouthCambridgeshireCouncil.py,sha256=
|
133
|
+
uk_bin_collection/uk_bin_collection/councils/SouthCambridgeshireCouncil.py,sha256=xGSMcikxjS4UzqKs0X50LJKmn09C-XAAs98SPhNZgkQ,2308
|
133
134
|
uk_bin_collection/uk_bin_collection/councils/SouthGloucestershireCouncil.py,sha256=ytQot0J7i6DTJo6hb9koTB1UpXLATKVeRU4FBF9kHRo,2412
|
134
135
|
uk_bin_collection/uk_bin_collection/councils/SouthKestevenDistrictCouncil.py,sha256=AgycOW-UIAm5_c8QondfKL0n4wUA4cbaN_Jp0e8g494,5587
|
135
136
|
uk_bin_collection/uk_bin_collection/councils/SouthLanarkshireCouncil.py,sha256=fj-eZI0yrvQVCv8GvhcovZ3b9bV6Xv_ws3IunWjnv4U,3126
|
@@ -137,7 +138,8 @@ uk_bin_collection/uk_bin_collection/councils/SouthNorfolkCouncil.py,sha256=ThO-o
|
|
137
138
|
uk_bin_collection/uk_bin_collection/councils/SouthOxfordshireCouncil.py,sha256=zW4bN3hcqNoK_Y0-vPpuZs3K0LTPvApu6_v9K-D7WjE,3879
|
138
139
|
uk_bin_collection/uk_bin_collection/councils/SouthTynesideCouncil.py,sha256=dxXGrJfg_fn2IPTBgq6Duwy0WY8GYLafMuisaCjOnbs,3426
|
139
140
|
uk_bin_collection/uk_bin_collection/councils/StAlbansCityAndDistrictCouncil.py,sha256=mPZz6Za6kTSkrfHnj0OfwtnpRYR1dKvxbuFEKnWsiL8,1451
|
140
|
-
uk_bin_collection/uk_bin_collection/councils/StHelensBC.py,sha256=
|
141
|
+
uk_bin_collection/uk_bin_collection/councils/StHelensBC.py,sha256=c7ZM8gnUkKdz9GYIhFLzTtwN0KAoMEKomTWDVbtJIpM,2069
|
142
|
+
uk_bin_collection/uk_bin_collection/councils/StaffordBoroughCouncil.py,sha256=9Qj4HJI7Dbiqb2mVSG2UtkBe27Y7wvQ5SYFTwGzJ5g0,2292
|
141
143
|
uk_bin_collection/uk_bin_collection/councils/StaffordshireMoorlandsDistrictCouncil.py,sha256=_N8Cg26EbTaKp0RsWvQuELVcZDHbT2BlD2LW8qhkS_Q,4361
|
142
144
|
uk_bin_collection/uk_bin_collection/councils/StockportBoroughCouncil.py,sha256=v0HmioNVRoU1-9OnLJl2V3M5pVR1aVu1BgOLHFR1Sf4,1429
|
143
145
|
uk_bin_collection/uk_bin_collection/councils/StokeOnTrentCityCouncil.py,sha256=KM0EgWeO7mk8lkozX0RCTfMchXdjrfBqIjCiOtB09aM,2884
|
@@ -145,20 +147,23 @@ uk_bin_collection/uk_bin_collection/councils/StratfordUponAvonCouncil.py,sha256=
|
|
145
147
|
uk_bin_collection/uk_bin_collection/councils/StroudDistrictCouncil.py,sha256=9bYWppi7ViLGHL4VEg--nFn28MLYJYbiEntull1uZxU,3561
|
146
148
|
uk_bin_collection/uk_bin_collection/councils/SunderlandCityCouncil.py,sha256=4DnKyyu56_AwuchD6_oL1dvpDStMvkkxQtYN79rUKOs,3825
|
147
149
|
uk_bin_collection/uk_bin_collection/councils/SwaleBoroughCouncil.py,sha256=CCAjclhkCxwf_MkdrIif7MZpLfV5SPy7hyM7BE0TRPc,2048
|
150
|
+
uk_bin_collection/uk_bin_collection/councils/SwanseaCouncil.py,sha256=nmVPoPhnFgVi--vczX2i4Sf3bqM5RWJuwfhioRUr5XE,2303
|
148
151
|
uk_bin_collection/uk_bin_collection/councils/TamesideMBCouncil.py,sha256=k2TAAZG7n2S1BWVyxbE_-4-lZuzhOimCNz4yimUCOGk,1995
|
149
152
|
uk_bin_collection/uk_bin_collection/councils/TandridgeDistrictCouncil.py,sha256=KLVvM2NNq_DQylVe5dwO2l7qPahLHg08jJGLCv1MBQ4,2324
|
150
153
|
uk_bin_collection/uk_bin_collection/councils/TelfordAndWrekinCouncil.py,sha256=p1ZS5R4EGxbEWlRBrkGXgKwE_lkyBT-R60yKFFhVObc,1844
|
151
154
|
uk_bin_collection/uk_bin_collection/councils/TendringDistrictCouncil.py,sha256=DJbYI8m6lIISDrK5h8V5Jo-9kGG7kr9dz7GD8St4nc8,4274
|
152
|
-
uk_bin_collection/uk_bin_collection/councils/TestValleyBoroughCouncil.py,sha256=
|
155
|
+
uk_bin_collection/uk_bin_collection/councils/TestValleyBoroughCouncil.py,sha256=Dtfkyrwt795W7gqFJxVGRR8t3R5WMNQZwTWJckLpZWE,8480
|
156
|
+
uk_bin_collection/uk_bin_collection/councils/ThreeRiversDistrictCouncil.py,sha256=oZSW0Y5QHdqVy2fLys4sdB13tHgeNLha9WCUqG_R-gU,5527
|
153
157
|
uk_bin_collection/uk_bin_collection/councils/TonbridgeAndMallingBC.py,sha256=UlgnHDoi8ecav2H5-HqKNDpqW1J3RN-c___5c08_Q7I,4859
|
154
158
|
uk_bin_collection/uk_bin_collection/councils/TorbayCouncil.py,sha256=JW_BS7wkfxFsmx6taQtPAQWdBp1AfLrxs0XRQ2XZcSw,2029
|
155
159
|
uk_bin_collection/uk_bin_collection/councils/TorridgeDistrictCouncil.py,sha256=6gOO02pYU0cbj3LAHiBVNG4zkFMyIGbkE2jAye3KcGM,6386
|
160
|
+
uk_bin_collection/uk_bin_collection/councils/UttlesfordDistrictCouncil.py,sha256=8CvO-WgdKdvyaOf3TYc4XwME8ogAXojgB40oyGRL8Dw,4129
|
156
161
|
uk_bin_collection/uk_bin_collection/councils/ValeofGlamorganCouncil.py,sha256=Phgb_ECiUOOkqOx6OsfsTHMCW5VQfRmOC2zgYIQhuZA,5044
|
157
162
|
uk_bin_collection/uk_bin_collection/councils/ValeofWhiteHorseCouncil.py,sha256=5nZLbU5YVKNsJ2X_wuybrNLFAzjVAxkazu-bYP4IGXw,4292
|
158
163
|
uk_bin_collection/uk_bin_collection/councils/WakefieldCityCouncil.py,sha256=9zW4C0WKbsDLCKvFyVYFpyvp20JbrWc4G0HzadqF8WQ,4466
|
159
164
|
uk_bin_collection/uk_bin_collection/councils/WalthamForest.py,sha256=P7MMw0EhpRmDbbnHb25tY5_yvYuZUFwJ1br4TOv24sY,4997
|
160
165
|
uk_bin_collection/uk_bin_collection/councils/WarwickDistrictCouncil.py,sha256=3WQrAxzYzKoV4LyOqNTp9xINVsNi1xW9t8etducGeag,1146
|
161
|
-
uk_bin_collection/uk_bin_collection/councils/WaverleyBoroughCouncil.py,sha256=
|
166
|
+
uk_bin_collection/uk_bin_collection/councils/WaverleyBoroughCouncil.py,sha256=tp9l7vdgSGRzNNG0pDfnNuFj4D2bpRJUJmAiTJ6bM0g,4662
|
162
167
|
uk_bin_collection/uk_bin_collection/councils/WealdenDistrictCouncil.py,sha256=SvSSaLkx7iJjzypAwKkaJwegXkSsIQtUOS2V605kz1A,3368
|
163
168
|
uk_bin_collection/uk_bin_collection/councils/WelhatCouncil.py,sha256=ikUft37dYNJghfe-_6Fskiq1JihqpLmLNj38QkKSUUA,2316
|
164
169
|
uk_bin_collection/uk_bin_collection/councils/WestBerkshireCouncil.py,sha256=r90AIUdPgo85VuuvN_NeCDUy3NEJXdO4Ntt93yKo6qI,5110
|
@@ -166,17 +171,17 @@ uk_bin_collection/uk_bin_collection/councils/WestLindseyDistrictCouncil.py,sha25
|
|
166
171
|
uk_bin_collection/uk_bin_collection/councils/WestLothianCouncil.py,sha256=dq0jimtARvRkZiGbVFrXXZgY-BODtz3uYZ5UKn0bf64,4114
|
167
172
|
uk_bin_collection/uk_bin_collection/councils/WestNorthamptonshireCouncil.py,sha256=F1GeJUGND4DN_HuM6N0Elpeb0DAMm9_KeqG6qtIgZf4,1079
|
168
173
|
uk_bin_collection/uk_bin_collection/councils/WestSuffolkCouncil.py,sha256=HMFWxM7VMhBuC7iubNGbZYEoCVWi--gRHDJMVdPPFOM,2633
|
169
|
-
uk_bin_collection/uk_bin_collection/councils/WiganBoroughCouncil.py,sha256=
|
174
|
+
uk_bin_collection/uk_bin_collection/councils/WiganBoroughCouncil.py,sha256=3gqFA4-BVx_In6QOu3KUNqPN4Fkn9iMlZTeopMK9p6A,3746
|
170
175
|
uk_bin_collection/uk_bin_collection/councils/WiltshireCouncil.py,sha256=it2Oh5Kmq3lD30gAZgk2bzZPNCtJcFHyQO1NgOQtfvU,5653
|
171
|
-
uk_bin_collection/uk_bin_collection/councils/WindsorAndMaidenheadCouncil.py,sha256=
|
172
|
-
uk_bin_collection/uk_bin_collection/councils/WokingBoroughCouncil.py,sha256=
|
176
|
+
uk_bin_collection/uk_bin_collection/councils/WindsorAndMaidenheadCouncil.py,sha256=yG5iu294q138Bvk-0IPd4pJDFsOQPDmtU5XXytxnAnA,5554
|
177
|
+
uk_bin_collection/uk_bin_collection/councils/WokingBoroughCouncil.py,sha256=hYC3LRaLM_enYs8KhSgwUB4HhnPOhmYuPDeaREysY9E,5204
|
173
178
|
uk_bin_collection/uk_bin_collection/councils/WyreCouncil.py,sha256=zDDa7n4K_zm5PgDL08A26gD9yOOsOhuexI3x2seaBF4,3511
|
174
179
|
uk_bin_collection/uk_bin_collection/councils/YorkCouncil.py,sha256=I2kBYMlsD4bIdsvmoSzBjJAvTTi6yPfJa8xjJx1ys2w,1490
|
175
180
|
uk_bin_collection/uk_bin_collection/councils/council_class_template/councilclasstemplate.py,sha256=4s9ODGPAwPqwXc8SrTX5Wlfmizs3_58iXUtHc4Ir86o,1162
|
176
181
|
uk_bin_collection/uk_bin_collection/create_new_council.py,sha256=m-IhmWmeWQlFsTZC4OxuFvtw5ZtB8EAJHxJTH4O59lQ,1536
|
177
182
|
uk_bin_collection/uk_bin_collection/get_bin_data.py,sha256=9qppF2oPkhmOoK8-ZkRIU1M6vhBh-yUCWAZEEd07iLk,5414
|
178
|
-
uk_bin_collection-0.
|
179
|
-
uk_bin_collection-0.
|
180
|
-
uk_bin_collection-0.
|
181
|
-
uk_bin_collection-0.
|
182
|
-
uk_bin_collection-0.
|
183
|
+
uk_bin_collection-0.80.0.dist-info/LICENSE,sha256=vABBUOzcrgfaTKpzeo-si9YVEun6juDkndqA8RKdKGs,1071
|
184
|
+
uk_bin_collection-0.80.0.dist-info/METADATA,sha256=k2g8TXLix_QcBSmaj0nFopo0X_ZkiOWk7GBtY_WjmFs,12594
|
185
|
+
uk_bin_collection-0.80.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
186
|
+
uk_bin_collection-0.80.0.dist-info/entry_points.txt,sha256=36WCSGMWSc916S3Hi1ZkazzDKHaJ6CD-4fCEFm5MIao,90
|
187
|
+
uk_bin_collection-0.80.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|