Repository: mampfes/hacs_waste_collection_schedule

Issue:
Auckland Waste Collection Error
Hey,

Not sure when this happened but this does not work with auckland Council any longer, error in the logs below.
`[waste_collection_schedule.scraper] fetch failed for source <waste_collection_schedule.source.aucklandcouncil_govt_nz.Source object at 0x7f6289adc160>: HTTPSConnectionPool(host='www.aucklandcouncil.govt.nz', port=443): Max retries exceeded with url: /rubbish-recycling/rubbish-recycling-collections/Pages/collection-day-detail.aspx?an=12343019066 (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1129)')))`
Any help would be awesome thanks :)

Cheers

Brent


Discussion:
I added this source and just noticed this problem. Must admit I'm a bit stumped 🤔, ssl certs look fine in chrome. @mampfes any ideas what might be up here?
yeah it was working, I only noticed as I am now adding a tablet to the wall and wanted to actually use it in anger LOL, always the way :)
I think there is no matching local root certificate to verify the certificate used by www.aucklandcouncil.govt.nz.
I did some experiments with `certifi` (including update to 2021.10.8), but had no success.
But I found a workaround: add `verify=False` to `requests.get`:

```
        r = requests.get(
            "https://www.aucklandcouncil.govt.nz/rubbish-recycling/rubbish-recycling-collections/Pages/collection-day-detail.aspx",
            params=params,
            verify=False
        )
```

I hope this is a temporary issue, therefore I wouldn't release a new version with this workaround immediately.
Hey, that worked, awesome thanks!
Thanks @mampfes , much appreciated.

Resolving patch:
diff --git a/custom_components/waste_collection_schedule/waste_collection_schedule/source/aucklandcouncil_govt_nz.py b/custom_components/waste_collection_schedule/waste_collection_schedule/source/aucklandcouncil_govt_nz.py
--- a/custom_components/waste_collection_schedule/waste_collection_schedule/source/aucklandcouncil_govt_nz.py
+++ b/custom_components/waste_collection_schedule/waste_collection_schedule/source/aucklandcouncil_govt_nz.py
@@ -1,6 +1,4 @@
 import datetime
-import re
-
 from html.parser import HTMLParser
 
 import requests
@@ -32,9 +30,7 @@
 
 def toDate(formattedDate):
     items = formattedDate.split()
-    return datetime.date(
-        int(items[3]), MONTH[items[2]], int(items[1])
-    )
+    return datetime.date(int(items[3]), MONTH[items[2]], int(items[1]))
 
 
 # Parser for <div> element with class wasteSearchResults
@@ -55,50 +51,51 @@ def entries(self):
 
     def handle_endtag(self, tag):
         if tag == "span" and self._withinWasteDateSpan:
-           self._withinWasteDateSpan = False
+            self._withinWasteDateSpan = False
         if tag == "div" and self._withinRubbishLinks:
-           self._withinRubbishLinks = False
-           self._workingWasteDate = None
-
+            self._withinRubbishLinks = False
+            self._workingWasteDate = None
 
     def handle_starttag(self, tag, attrs):
         if tag == "div":
             d = dict(attrs)
             id = d.get("id", "")
             if id.endswith("HouseholdBlock"):
-               self._withinHouseholdDiv = True
+                self._withinHouseholdDiv = True
             if id.endswith("CommercialBlock"):
-               self._withinHouseholdDiv = False
+                self._withinHouseholdDiv = False
 
         if self._withinHouseholdDiv:
             s = dict(attrs)
             className = s.get("class", "")
             if tag == "div":
-               if className == "links":
-                  self._withinRubbishLinks = True
-               else:
-                  self._withinRubbishLinks = False
+                if className == "links":
+                    self._withinRubbishLinks = True
+                else:
+                    self._withinRubbishLinks = False
 
             if tag == "span":
-               if className.startswith("m-r-1"):
-                  self._withinWasteDateSpan = True
+                if className.startswith("m-r-1"):
+                    self._withinWasteDateSpan = True
 
-               if self._workingWasteDate is not None:
-                   if className.startswith("icon-rubbish") or className.startswith("icon-recycle"):
-                      type = s["class"][5:]  # remove "icon-"
-                      self._entries.append(Collection(self._workingWasteDate, type ))
+                if self._workingWasteDate is not None:
+                    if className.startswith("icon-rubbish") or className.startswith(
+                        "icon-recycle"
+                    ):
+                        type = s["class"][5:]  # remove "icon-"
+                        self._entries.append(Collection(self._workingWasteDate, type))
 
     def handle_data(self, data):
-        ## date span comes first, doesn't have a year 
+        # date span comes first, doesn't have a year
         if self._withinWasteDateSpan:
-           todays_date = datetime.date.today()
-           ## use current year, unless Jan is in data, and we are still in Dec
-           year = todays_date.year
-           if "January" in data and todays_date.month == 12:
-             ## then add 1
-             year = year + 1
-           fullDate = data + " " +  "{}".format(year)
-           self._workingWasteDate = toDate(fullDate) 
+            todays_date = datetime.date.today()
+            # use current year, unless Jan is in data, and we are still in Dec
+            year = todays_date.year
+            if "January" in data and todays_date.month == 12:
+                # then add 1
+                year = year + 1
+            fullDate = data + " " + f"{year}"
+            self._workingWasteDate = toDate(fullDate)
 
 
 class Source:
@@ -114,6 +111,7 @@ def fetch(self):
         r = requests.get(
             "https://www.aucklandcouncil.govt.nz/rubbish-recycling/rubbish-recycling-collections/Pages/collection-day-detail.aspx",
             params=params,
+            verify=False,
         )
         p = WasteSearchResultsParser()
         p.feed(r.text)


Test patch: