uk_bin_collection 0.85.0__py3-none-any.whl → 0.85.2__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.
@@ -68,6 +68,13 @@
68
68
  "wiki_name": "Bedfordshire Council",
69
69
  "wiki_note": "In order to use this parser, you must provide a valid postcode and a uprn retrieved from the councils website for your specific address"
70
70
  },
71
+ "BelfastCityCouncil": {
72
+ "skip_get_url": true,
73
+ "url": "https://online.belfastcity.gov.uk/find-bin-collection-day/Default.aspx",
74
+ "wiki_name": "BelfastCityCouncil",
75
+ "postcode": "BT10 0GY",
76
+ "uprn": "185086469"
77
+ },
71
78
  "BexleyCouncil": {
72
79
  "house_number": "1 Dorchester Avenue, Bexley",
73
80
  "postcode": "DA5 3AH",
@@ -415,8 +422,8 @@
415
422
  "wiki_note": "Use [this site](https://www.gbcbincalendars.co.uk/) to find the collections for your address. Use the -n parameter to add them in a comma-separated list inside quotes, such as: 'Friday G4, Friday J'."
416
423
  },
417
424
  "GlasgowCityCouncil": {
418
- "url": "https://www.glasgow.gov.uk/forms/refuseandrecyclingcalendar/PrintCalendar.aspx?UPRN=906700034497",
419
- "wiki_command_url_override": "https://www.glasgow.gov.uk/forms/refuseandrecyclingcalendar/PrintCalendar.aspx?UPRN=XXXXXXXX",
425
+ "url": "https://onlineservices.glasgow.gov.uk/forms/RefuseAndRecyclingWebApplication/CollectionsCalendar.aspx?UPRN=906700034497",
426
+ "wiki_command_url_override": "https://onlineservices.glasgow.gov.uk/forms/RefuseAndRecyclingWebApplication/CollectionsCalendar.aspx?UPRN=XXXXXXXX",
420
427
  "wiki_name": "Glasgow City Council",
421
428
  "wiki_note": "Replace XXXXXXXX with UPRN."
422
429
  },
@@ -0,0 +1,100 @@
1
+ import logging
2
+ from datetime import datetime
3
+
4
+ import requests
5
+ import urllib
6
+
7
+ from bs4 import BeautifulSoup
8
+ from uk_bin_collection.uk_bin_collection.common import *
9
+ from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
10
+
11
+
12
+
13
+ # import the wonderful Beautiful Soup and the URL grabber
14
+ class CouncilClass(AbstractGetBinDataClass):
15
+ """
16
+ Concrete classes have to implement all abstract operations of the
17
+ base class. They can also override some operations with a default
18
+ implementation.
19
+ """
20
+
21
+ def get_session_variable(self, soup, id) -> str:
22
+ """Extract ASP.NET variable from the HTML."""
23
+ element = soup.find("input", {"id": id})
24
+ if element:
25
+ return element.get("value")
26
+ else:
27
+ raise ValueError(f"Unable to find element with id: {id}")
28
+
29
+ def parse_data(self, page: str, **kwargs) -> dict:
30
+ bin_data = {"bins": []}
31
+ headers = {
32
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:129.0) Gecko/20100101 Firefox/119.0"
33
+ }
34
+
35
+ session = requests.Session()
36
+ session.headers.update(headers)
37
+
38
+ user_uprn = kwargs.get("uprn")
39
+ user_postcode = kwargs.get("postcode")
40
+ URL = "https://online.belfastcity.gov.uk/find-bin-collection-day/Default.aspx"
41
+
42
+ # Build initial ASP.NET variables for Postcode Find address
43
+ response = session.get(URL)
44
+ response.raise_for_status()
45
+ soup = BeautifulSoup(response.text, "html.parser")
46
+ form_data = {
47
+ "__EVENTTARGET": "",
48
+ "__EVENTARGUMENT": "",
49
+ "__VIEWSTATE": self.get_session_variable(soup, "__VIEWSTATE"),
50
+ "__VIEWSTATEGENERATOR": self.get_session_variable(soup, "__VIEWSTATEGENERATOR"),
51
+ "__SCROLLPOSITIONX": "0",
52
+ "__SCROLLPOSITIONY": "0",
53
+ "__EVENTVALIDATION": self.get_session_variable(soup, "__EVENTVALIDATION"),
54
+ "ctl00$MainContent$searchBy_radio": "P",
55
+ "ctl00$MainContent$Street_textbox": "",
56
+ "ctl00$MainContent$Postcode_textbox": user_postcode,
57
+ "ctl00$MainContent$AddressLookup_button": "Find address"
58
+ }
59
+
60
+ # Build intermediate ASP.NET variables for uprn Select address
61
+ response = session.post(URL, data=form_data)
62
+ response.raise_for_status()
63
+ soup = BeautifulSoup(response.text, "html.parser")
64
+ form_data = {
65
+ "__EVENTTARGET": "",
66
+ "__EVENTARGUMENT": "",
67
+ "__VIEWSTATE": self.get_session_variable(soup, "__VIEWSTATE"),
68
+ "__VIEWSTATEGENERATOR": self.get_session_variable(soup, "__VIEWSTATEGENERATOR"),
69
+ "__SCROLLPOSITIONX": "0",
70
+ "__SCROLLPOSITIONY": "0",
71
+ "__EVENTVALIDATION": self.get_session_variable(soup, "__EVENTVALIDATION"),
72
+ "ctl00$MainContent$searchBy_radio": "P",
73
+ "ctl00$MainContent$Street_textbox": "",
74
+ "ctl00$MainContent$Postcode_textbox": user_postcode,
75
+ "ctl00$MainContent$lstAddresses": user_uprn,
76
+ "ctl00$MainContent$SelectAddress_button": "Select address"
77
+ }
78
+
79
+ # Actual http call to get Bins Data
80
+ response = session.post(URL, data=form_data)
81
+ response.raise_for_status()
82
+ soup = BeautifulSoup(response.text, "html.parser")
83
+
84
+ # Find Bins table and data
85
+ table = soup.find("div", {"id": "binsGrid"})
86
+ if table:
87
+ rows = table.find_all("tr")
88
+ for row in rows:
89
+ columns = row.find_all("td")
90
+ if len(columns) >= 4:
91
+ collection_type = columns[0].get_text(strip=True)
92
+ collection_date_raw = columns[3].get_text(strip=True)
93
+ # if the month number is a single digit there are 2 spaces, stripping all spaces to make it consistent
94
+ collection_date = datetime.strptime(collection_date_raw.replace(" ", ""),'%a%b%d%Y')
95
+ bin_entry = {
96
+ "type": collection_type,
97
+ "collectionDate": collection_date.strftime(date_format),
98
+ }
99
+ bin_data["bins"].append(bin_entry)
100
+ return bin_data
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: uk_bin_collection
3
- Version: 0.85.0
3
+ Version: 0.85.2
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=540NA9Lt73cWYw8a4mzf0LiN0HbgbA1rcY8t7gvg0eE,59397
5
+ uk_bin_collection/tests/input.json,sha256=VahhxxLYSXAux-pD0P_orlSLSEPyQ-kpcenaeXls0Js,59700
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
@@ -20,6 +20,7 @@ uk_bin_collection/uk_bin_collection/councils/BasingstokeCouncil.py,sha256=VPWGlj
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
22
  uk_bin_collection/uk_bin_collection/councils/BedfordshireCouncil.py,sha256=U1HOr9YLMAlFoZysfw5n04E0bVuCliO5Yj1FMiiwcHA,2549
23
+ uk_bin_collection/uk_bin_collection/councils/BelfastCityCouncil.py,sha256=mspYVHO8fgoVIwogT6V2Go1tbf3PDbEmr8kZMJug5Gs,4235
23
24
  uk_bin_collection/uk_bin_collection/councils/BexleyCouncil.py,sha256=9MrbpfR17R6DYjDrItQL3CPF7ie1SJkaoNbwQumPgIQ,5399
24
25
  uk_bin_collection/uk_bin_collection/councils/BirminghamCityCouncil.py,sha256=yrO9dnSMdqVTcrzqXXfexFxSuESW01VPxXNAl0_lNOU,4669
25
26
  uk_bin_collection/uk_bin_collection/councils/BlackburnCouncil.py,sha256=jHbCK8sL09vdmdP7Xnh8lIrU5AHTnJLEZfOLephPvWg,4090
@@ -183,8 +184,8 @@ uk_bin_collection/uk_bin_collection/councils/YorkCouncil.py,sha256=I2kBYMlsD4bId
183
184
  uk_bin_collection/uk_bin_collection/councils/council_class_template/councilclasstemplate.py,sha256=4s9ODGPAwPqwXc8SrTX5Wlfmizs3_58iXUtHc4Ir86o,1162
184
185
  uk_bin_collection/uk_bin_collection/create_new_council.py,sha256=m-IhmWmeWQlFsTZC4OxuFvtw5ZtB8EAJHxJTH4O59lQ,1536
185
186
  uk_bin_collection/uk_bin_collection/get_bin_data.py,sha256=YvmHfZqanwrJ8ToGch34x-L-7yPe31nB_x77_Mgl_vo,4545
186
- uk_bin_collection-0.85.0.dist-info/LICENSE,sha256=vABBUOzcrgfaTKpzeo-si9YVEun6juDkndqA8RKdKGs,1071
187
- uk_bin_collection-0.85.0.dist-info/METADATA,sha256=6NrMstgZCRauGjucrc08jacZVh3RdoBwU9z50VW1OTA,16231
188
- uk_bin_collection-0.85.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
189
- uk_bin_collection-0.85.0.dist-info/entry_points.txt,sha256=36WCSGMWSc916S3Hi1ZkazzDKHaJ6CD-4fCEFm5MIao,90
190
- uk_bin_collection-0.85.0.dist-info/RECORD,,
187
+ uk_bin_collection-0.85.2.dist-info/LICENSE,sha256=vABBUOzcrgfaTKpzeo-si9YVEun6juDkndqA8RKdKGs,1071
188
+ uk_bin_collection-0.85.2.dist-info/METADATA,sha256=HRE21jl06q1Y1peCYlfPJabfSWmw0uzP17jILpU9dYs,16231
189
+ uk_bin_collection-0.85.2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
190
+ uk_bin_collection-0.85.2.dist-info/entry_points.txt,sha256=36WCSGMWSc916S3Hi1ZkazzDKHaJ6CD-4fCEFm5MIao,90
191
+ uk_bin_collection-0.85.2.dist-info/RECORD,,