uk_bin_collection 0.110.0__py3-none-any.whl → 0.111.0__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -745,7 +745,7 @@
745
745
  "wiki_command_url_override": "https://lincoln.gov.uk",
746
746
  "uprn": "000235024846",
747
747
  "postcode": "LN5 7SH",
748
- "wiki_name": "Tunbridge Wells Council",
748
+ "wiki_name": "Lincoln Council",
749
749
  "wiki_note": "You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find the UPRN."
750
750
  },
751
751
  "LisburnCastlereaghCityCouncil": {
@@ -794,6 +794,13 @@
794
794
  "wiki_name": "London Borough Redbridge",
795
795
  "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."
796
796
  },
797
+ "LondonBoroughSutton": {
798
+ "url": "https://waste-services.sutton.gov.uk/waste",
799
+ "wiki_command_url_override": "https://waste-services.sutton.gov.uk/waste",
800
+ "uprn": "4473006",
801
+ "wiki_name": "London Borough Sutton",
802
+ "wiki_note": "You will need to find your unique property reference by going to (https://waste-services.sutton.gov.uk/waste), entering your details and then using the 7 digit reference in the URL as your UPRN"
803
+ },
797
804
  "LutonBoroughCouncil": {
798
805
  "url": "https://myforms.luton.gov.uk",
799
806
  "wiki_command_url_override": "https://myforms.luton.gov.uk",
@@ -839,6 +846,13 @@
839
846
  "wiki_name": "Mid and East Antrim Borough Council",
840
847
  "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.)."
841
848
  },
849
+ "MidDevonCouncil": {
850
+ "url": "https://www.middevon.gov.uk",
851
+ "wiki_command_url_override": "https://www.middevon.gov.uk",
852
+ "uprn": "200003997770",
853
+ "wiki_name": "Mid Devon Council",
854
+ "wiki_note": "You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find the UPRN."
855
+ },
842
856
  "MidlothianCouncil": {
843
857
  "house_number": "52",
844
858
  "postcode": "EH19 2EB",
@@ -1021,6 +1035,14 @@
1021
1035
  "wiki_name": "Oldham Council",
1022
1036
  "wiki_note": "Replace UPRN in URL with your own UPRN."
1023
1037
  },
1038
+ "OxfordCityCouncil": {
1039
+ "url": "https://www.oxford.gov.uk",
1040
+ "wiki_command_url_override": "https://www.oxford.gov.uk",
1041
+ "uprn": "100120820551",
1042
+ "postcode": "OX3 7QF",
1043
+ "wiki_name": "Oxford City Council",
1044
+ "wiki_note": "You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find the UPRN."
1045
+ },
1024
1046
  "PerthAndKinrossCouncil": {
1025
1047
  "url": "https://www.pkc.gov.uk",
1026
1048
  "wiki_command_url_override": "https://www.pkc.gov.uk",
@@ -38,7 +38,7 @@ class CouncilClass(AbstractGetBinDataClass):
38
38
  for icon in icons:
39
39
  cal_item = icon.find_parent().find_parent()
40
40
  bin_date = datetime.strptime(
41
- cal_item["title"],
41
+ cal_item["title"].replace("today is ", ""),
42
42
  "%A, %d %B %Y",
43
43
  )
44
44
 
@@ -0,0 +1,75 @@
1
+ from time import sleep
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://waste-services.sutton.gov.uk/waste/{user_uprn}"
25
+
26
+ s = requests.Session()
27
+
28
+ r = s.get(URI)
29
+ while "Loading your bin days..." in r.text:
30
+ sleep(2)
31
+ r = s.get(URI)
32
+ r.raise_for_status()
33
+
34
+ soup = BeautifulSoup(r.content, "html.parser")
35
+
36
+ current_year = datetime.now().year
37
+ next_year = current_year + 1
38
+
39
+ services = soup.find_all("h3", class_="govuk-heading-m waste-service-name")
40
+
41
+ for service in services:
42
+ bin_type = service.get_text(
43
+ strip=True
44
+ ) # Bin type name (e.g., 'Food waste', 'Mixed recycling')
45
+ if bin_type == "Bulky waste":
46
+ continue
47
+ service_details = service.find_next("div", class_="govuk-grid-row")
48
+
49
+ next_collection = (
50
+ service_details.find("dt", string="Next collection")
51
+ .find_next_sibling("dd")
52
+ .get_text(strip=True)
53
+ )
54
+
55
+ next_collection = datetime.strptime(
56
+ remove_ordinal_indicator_from_date_string(next_collection),
57
+ "%A, %d %B",
58
+ )
59
+
60
+ if next_collection.month == 1:
61
+ next_collection = next_collection.replace(year=next_year)
62
+ else:
63
+ next_collection = next_collection.replace(year=current_year)
64
+
65
+ dict_data = {
66
+ "type": bin_type,
67
+ "collectionDate": next_collection.strftime("%d/%m/%Y"),
68
+ }
69
+ bindata["bins"].append(dict_data)
70
+
71
+ bindata["bins"].sort(
72
+ key=lambda x: datetime.strptime(x.get("collectionDate"), "%d/%m/%Y")
73
+ )
74
+
75
+ return bindata
@@ -0,0 +1,93 @@
1
+ import time
2
+
3
+ import requests
4
+
5
+ from uk_bin_collection.uk_bin_collection.common import *
6
+ from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
7
+
8
+
9
+ # import the wonderful Beautiful Soup and the URL grabber
10
+ class CouncilClass(AbstractGetBinDataClass):
11
+ """
12
+ Concrete classes have to implement all abstract operations of the
13
+ base class. They can also override some operations with a default
14
+ implementation.
15
+ """
16
+
17
+ def parse_data(self, page: str, **kwargs) -> dict:
18
+
19
+ user_uprn = kwargs.get("uprn")
20
+ check_uprn(user_uprn)
21
+ bindata = {"bins": []}
22
+
23
+ SESSION_URL = "https://my.middevon.gov.uk/authapi/isauthenticated?uri=https%253A%252F%252Fmy.middevon.gov.uk%252Fen%252FAchieveForms%252F%253Fform_uri%253Dsandbox-publish%253A%252F%252FAF-Process-2289dd06-9a12-4202-ba09-857fe756f6bd%252FAF-Stage-eb382015-001c-415d-beda-84f796dbb167%252Fdefinition.json%2526redirectlink%253D%25252Fen%2526cancelRedirectLink%253D%25252Fen%2526consentMessage%253Dyes&hostname=my.middevon.gov.uk&withCredentials=true"
24
+
25
+ API_URL = "https://my.middevon.gov.uk/apibroker/runLookup"
26
+
27
+ payload = {
28
+ "formValues": {
29
+ "Your Address": {
30
+ "listAddress": {"value": user_uprn},
31
+ },
32
+ },
33
+ }
34
+
35
+ headers = {
36
+ "Content-Type": "application/json",
37
+ "Accept": "application/json",
38
+ "User-Agent": "Mozilla/5.0",
39
+ "X-Requested-With": "XMLHttpRequest",
40
+ "Referer": "https://my.middevon.gov.uk/fillform/?iframe_id=fillform-frame-1&db_id=",
41
+ }
42
+
43
+ ids = [
44
+ "6423144f50ec0",
45
+ "641c7ae9b4c96",
46
+ "645e13a01dba1",
47
+ "642315aacb919",
48
+ "64231699483cf",
49
+ "642421bab7478",
50
+ "6424229605d13",
51
+ "645e14020c9cc",
52
+ ]
53
+
54
+ rows_data = []
55
+
56
+ for id in ids:
57
+ s = requests.session()
58
+ r = s.get(SESSION_URL)
59
+ r.raise_for_status()
60
+ session_data = r.json()
61
+ sid = session_data["auth-session"]
62
+
63
+ params = {
64
+ "id": id,
65
+ "repeat_against": "",
66
+ "noRetry": "false",
67
+ "getOnlyTokens": "undefined",
68
+ "log_id": "",
69
+ "app_name": "AF-Renderer::Self",
70
+ # unix_timestamp
71
+ "_": str(int(time.time() * 1000)),
72
+ "sid": sid,
73
+ }
74
+ r = s.post(API_URL, json=payload, headers=headers, params=params)
75
+ r.raise_for_status()
76
+ data = r.json()
77
+ rows_data = data["integration"]["transformed"]["rows_data"]
78
+ if isinstance(rows_data, dict):
79
+ date = datetime.strptime(rows_data["0"]["display"], "%d-%b-%y")
80
+ bin_types = (rows_data["0"]["CollectionItems"]).split(" and ")
81
+
82
+ for bin_type in bin_types:
83
+ dict_data = {
84
+ "type": bin_type,
85
+ "collectionDate": date.strftime(date_format),
86
+ }
87
+ bindata["bins"].append(dict_data)
88
+
89
+ bindata["bins"].sort(
90
+ key=lambda x: datetime.strptime(x.get("collectionDate"), "%d/%m/%Y")
91
+ )
92
+
93
+ return bindata
@@ -0,0 +1,63 @@
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
+ user_postcode = kwargs.get("postcode")
20
+ check_uprn(user_uprn)
21
+ check_postcode(user_postcode)
22
+ bindata = {"bins": []}
23
+
24
+ session_uri = "https://www.oxford.gov.uk/mybinday"
25
+ URI = "https://www.oxford.gov.uk/xfp/form/142"
26
+
27
+ session = requests.Session()
28
+ token_response = session.get(session_uri)
29
+ soup = BeautifulSoup(token_response.text, "html.parser")
30
+ token = soup.find("input", {"name": "__token"}).attrs["value"]
31
+
32
+ form_data = {
33
+ "__token": token,
34
+ "page": "12",
35
+ "locale": "en_GB",
36
+ "q6ad4e3bf432c83230a0347a6eea6c805c672efeb_0_0": user_postcode,
37
+ "q6ad4e3bf432c83230a0347a6eea6c805c672efeb_1_0": user_uprn,
38
+ "next": "Next",
39
+ }
40
+
41
+ collection_response = session.post(URI, data=form_data)
42
+
43
+ collection_soup = BeautifulSoup(collection_response.text, "html.parser")
44
+ for paragraph in collection_soup.find("div", class_="editor").find_all("p"):
45
+ matches = re.match(r"^(\w+) Next Collection: (.*)", paragraph.text)
46
+ if matches:
47
+ collection_type, date_string = matches.groups()
48
+ try:
49
+ date = datetime.strptime(date_string, "%A %d %B %Y").date()
50
+ except ValueError:
51
+ date = datetime.strptime(date_string, "%A %d %b %Y").date()
52
+
53
+ dict_data = {
54
+ "type": collection_type,
55
+ "collectionDate": date.strftime("%d/%m/%Y"),
56
+ }
57
+ bindata["bins"].append(dict_data)
58
+
59
+ bindata["bins"].sort(
60
+ key=lambda x: datetime.strptime(x.get("collectionDate"), "%d/%m/%Y")
61
+ )
62
+
63
+ return bindata
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: uk_bin_collection
3
- Version: 0.110.0
3
+ Version: 0.111.0
4
4
  Summary: Python Lib to collect UK Bin Data
5
5
  Author: Robert Bradley
6
6
  Author-email: robbrad182@gmail.com
@@ -2,7 +2,7 @@ uk_bin_collection/README.rst,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
2
2
  uk_bin_collection/tests/council_feature_input_parity.py,sha256=DO6Mk4ImYgM5ZCZ-cutwz5RoYYWZRLYx2tr6zIs_9Rc,3843
3
3
  uk_bin_collection/tests/features/environment.py,sha256=VQZjJdJI_kZn08M0j5cUgvKT4k3iTw8icJge1DGOkoA,127
4
4
  uk_bin_collection/tests/features/validate_council_outputs.feature,sha256=SJK-Vc737hrf03tssxxbeg_JIvAH-ddB8f6gU1LTbuQ,251
5
- uk_bin_collection/tests/input.json,sha256=XtqiLKudmLmiCcv33foHztpukFgULJ7eXIzQxZ_-HqY,79859
5
+ uk_bin_collection/tests/input.json,sha256=MN87Jdtb1koa8moUh7SW2eJi800CEp-JiwT8G2wV6A8,81028
6
6
  uk_bin_collection/tests/output.schema,sha256=ZwKQBwYyTDEM4G2hJwfLUVM-5v1vKRvRK9W9SS1sd18,1086
7
7
  uk_bin_collection/tests/step_defs/step_helpers/file_handler.py,sha256=Ygzi4V0S1MIHqbdstUlIqtRIwnynvhu4UtpweJ6-5N8,1474
8
8
  uk_bin_collection/tests/step_defs/test_validate_council.py,sha256=VZ0a81sioJULD7syAYHjvK_-nT_Rd36tUyzPetSA0gk,3475
@@ -94,7 +94,7 @@ uk_bin_collection/uk_bin_collection/councils/FlintshireCountyCouncil.py,sha256=R
94
94
  uk_bin_collection/uk_bin_collection/councils/ForestOfDeanDistrictCouncil.py,sha256=YWT2GM2-bQ3Zh9ps1K14XRZfanuJOlV-zHpOOYMXAXY,4893
95
95
  uk_bin_collection/uk_bin_collection/councils/GatesheadCouncil.py,sha256=SRCgYhYs6rv_8C1UEDVORHZgXxcJkoZBjzdYS4Lu-ew,4531
96
96
  uk_bin_collection/uk_bin_collection/councils/GedlingBoroughCouncil.py,sha256=XzfFMCwclh9zAJgsbaj4jywjdiH0wPaFicaVsLrN3ms,2297
97
- uk_bin_collection/uk_bin_collection/councils/GlasgowCityCouncil.py,sha256=i7BympEhCm7D9yR0p5_QQICtWvNcDYNJIWB19SA0g2k,2303
97
+ uk_bin_collection/uk_bin_collection/councils/GlasgowCityCouncil.py,sha256=9N5GXR32gXYBl3i44TITiZ7N73rgqXZmkyenI-kVRQI,2328
98
98
  uk_bin_collection/uk_bin_collection/councils/GloucesterCityCouncil.py,sha256=8Wjvmdvg5blHVrREaEnhhWZaWhYVP4v_KdDVPLIUxaU,4889
99
99
  uk_bin_collection/uk_bin_collection/councils/GuildfordCouncil.py,sha256=9pVrmQhZcK2AD8gX8mNvP--L4L9KaY6L3B822VX6fec,5695
100
100
  uk_bin_collection/uk_bin_collection/councils/HaltonBoroughCouncil.py,sha256=gq_CPqi6qM2oNiHhKKF1lZC86fyKL4lPhh_DN9pJZ04,5971
@@ -121,6 +121,7 @@ uk_bin_collection/uk_bin_collection/councils/LondonBoroughHarrow.py,sha256=kzKwb
121
121
  uk_bin_collection/uk_bin_collection/councils/LondonBoroughHounslow.py,sha256=UOeiOxGMvVMm2UFaqjmQpm7vxzqJNSSN8LM9lAUjs2c,3021
122
122
  uk_bin_collection/uk_bin_collection/councils/LondonBoroughLambeth.py,sha256=r9D5lHe5kIRStCd5lRIax16yhb4KTFzzfYEFv1bacWw,2009
123
123
  uk_bin_collection/uk_bin_collection/councils/LondonBoroughRedbridge.py,sha256=A_6Sis5hsF53Th04KeadHRasGbpAm6aoaWJ6X8eC4Y8,6604
124
+ uk_bin_collection/uk_bin_collection/councils/LondonBoroughSutton.py,sha256=c2haHOwX7Dy1phVUTv3xaQgM9VeHmFuBwdAgqGcGs8Y,2369
124
125
  uk_bin_collection/uk_bin_collection/councils/LutonBoroughCouncil.py,sha256=vScUi_R8FnBddii2_zLlZBLxuh85mKmCm8nKW3zxky0,2758
125
126
  uk_bin_collection/uk_bin_collection/councils/MaldonDistrictCouncil.py,sha256=PMVt2XFggttPmbWyrBrHJ-W6R_6-0ux1BkY1kj1IKzg,1997
126
127
  uk_bin_collection/uk_bin_collection/councils/MalvernHillsDC.py,sha256=iQG0EkX2npBicvsGKQRYyBGSBvKVUbKvUvvwrC9xV1A,2100
@@ -128,6 +129,7 @@ uk_bin_collection/uk_bin_collection/councils/ManchesterCityCouncil.py,sha256=RY3
128
129
  uk_bin_collection/uk_bin_collection/councils/MansfieldDistrictCouncil.py,sha256=F5AiTxImrnjE1k3ry96bfstOf5XSNBJS_4qqmymmh3w,1386
129
130
  uk_bin_collection/uk_bin_collection/councils/MertonCouncil.py,sha256=3Y2Un4xXo1sCcMsudynODSzocV_mMofWkX2JqONDb5o,1997
130
131
  uk_bin_collection/uk_bin_collection/councils/MidAndEastAntrimBoroughCouncil.py,sha256=oOWwU5FSgGej2Mv7FQ66N-EzS5nZgmGsd0WnfLWUc1I,5238
132
+ uk_bin_collection/uk_bin_collection/councils/MidDevonCouncil.py,sha256=RjBZ7R3_Pax9p1d2DCygqryjV1RP4BYvqb-rT_KyOEg,3322
131
133
  uk_bin_collection/uk_bin_collection/councils/MidSussexDistrictCouncil.py,sha256=AZgC9wmDLEjUOtIFvf0ehF5LHturXTH4DkE3ioPSVBA,6254
132
134
  uk_bin_collection/uk_bin_collection/councils/MidlothianCouncil.py,sha256=mM5-itJDNhjsT5UEjSFfWppmfmPFSns4u_1QblewuFU,5605
133
135
  uk_bin_collection/uk_bin_collection/councils/MiltonKeynesCityCouncil.py,sha256=3olsWa77L34vz-c7NgeGK9xmNuR4Ws_oAk5D4UpIkPw,2005
@@ -154,6 +156,7 @@ uk_bin_collection/uk_bin_collection/councils/NorthumberlandCouncil.py,sha256=KEF
154
156
  uk_bin_collection/uk_bin_collection/councils/NorwichCityCouncil.py,sha256=At-9dEcKBUZSrtJ2RncwvMnV0OVU3pE6kxEYbLL-Av8,2437
155
157
  uk_bin_collection/uk_bin_collection/councils/NottinghamCityCouncil.py,sha256=panTCjnsBOQ98-TBO9xVZk_jcT_gjMhx3Gg5oWxBRLo,1254
156
158
  uk_bin_collection/uk_bin_collection/councils/OldhamCouncil.py,sha256=9dlesCxNoVXlmQaqZj7QFh00smnJbm1Gnjkr_Uvzurs,1771
159
+ uk_bin_collection/uk_bin_collection/councils/OxfordCityCouncil.py,sha256=d_bY0cXRDH4kSoWGGCTNN61MNErapSOf2WSTYDJr2r8,2318
157
160
  uk_bin_collection/uk_bin_collection/councils/PerthAndKinrossCouncil.py,sha256=Kos5GzN2co3Ij3tSHOXB9S71Yt78RROCfVRtnh7M1VU,3657
158
161
  uk_bin_collection/uk_bin_collection/councils/PlymouthCouncil.py,sha256=FJqpJ0GJhpjYeyZ9ioZPkKGl-zrqMD3y5iKa07e_i30,3202
159
162
  uk_bin_collection/uk_bin_collection/councils/PortsmouthCityCouncil.py,sha256=xogNgVvwM5FljCziiNLgZ_wzkOnrQkifi1dkPMDRMtg,5588
@@ -243,8 +246,8 @@ uk_bin_collection/uk_bin_collection/councils/YorkCouncil.py,sha256=I2kBYMlsD4bId
243
246
  uk_bin_collection/uk_bin_collection/councils/council_class_template/councilclasstemplate.py,sha256=EQWRhZ2pEejlvm0fPyOTsOHKvUZmPnxEYO_OWRGKTjs,1158
244
247
  uk_bin_collection/uk_bin_collection/create_new_council.py,sha256=m-IhmWmeWQlFsTZC4OxuFvtw5ZtB8EAJHxJTH4O59lQ,1536
245
248
  uk_bin_collection/uk_bin_collection/get_bin_data.py,sha256=YvmHfZqanwrJ8ToGch34x-L-7yPe31nB_x77_Mgl_vo,4545
246
- uk_bin_collection-0.110.0.dist-info/LICENSE,sha256=vABBUOzcrgfaTKpzeo-si9YVEun6juDkndqA8RKdKGs,1071
247
- uk_bin_collection-0.110.0.dist-info/METADATA,sha256=EiPQ2MtYzpzSfVEhSAH5cWZgm7dL3aV324LQjo05YzA,17574
248
- uk_bin_collection-0.110.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
249
- uk_bin_collection-0.110.0.dist-info/entry_points.txt,sha256=36WCSGMWSc916S3Hi1ZkazzDKHaJ6CD-4fCEFm5MIao,90
250
- uk_bin_collection-0.110.0.dist-info/RECORD,,
249
+ uk_bin_collection-0.111.0.dist-info/LICENSE,sha256=vABBUOzcrgfaTKpzeo-si9YVEun6juDkndqA8RKdKGs,1071
250
+ uk_bin_collection-0.111.0.dist-info/METADATA,sha256=post7eciEA6fFebAgkqrkux5HHCUNhh-R4t8n0Z3IpU,17574
251
+ uk_bin_collection-0.111.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
252
+ uk_bin_collection-0.111.0.dist-info/entry_points.txt,sha256=36WCSGMWSc916S3Hi1ZkazzDKHaJ6CD-4fCEFm5MIao,90
253
+ uk_bin_collection-0.111.0.dist-info/RECORD,,