Repository: mampfes/hacs_waste_collection_schedule

Issue:
[Bug]: Barnsley MBC. Fails when running with collection date as today
### I Have A Problem With:

A specific source

### What's Your Problem

Barnsley Council source does not work when the bin collection date is 'today'
This attempted to parse the date and then fails.

It looks like something with a check if the date is 'today' could resolve this.
```
if heading[0].text == "Today": 
    bin_date = datetime.today().date()
else:
    bin_date = datetime.strptime(heading[0].text, "%A, %B %d, %Y").date()
```

### Source (if relevant)

barnsley_gov_uk 

### Logs

```Shell
fetch failed for source Barnsley Metropolitan Borough Council: Traceback (most recent call last): File "/config/custom_components/waste_collection_schedule/waste_collection_schedule/source_shell.py", line 134, in fetch entries = self._source.fetch() ^^^^^^^^^^^^^^^^^^^^ File "/config/custom_components/waste_collection_schedule/waste_collection_schedule/source/barnsley_gov_uk.py", line 83, in fetch bin_date = datetime.strptime(heading[0].text, "%A, %B %d, %Y").date() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/_strptime.py", line 554, in _strptime_datetime tt, fraction, gmtoff_fraction = _strptime(data_string, format) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/_strptime.py", line 333, in _strptime raise ValueError("time data %r does not match format %r" % ValueError: time data 'Today' does not match format '%A, %B %d, %Y'
```


### Relevant Configuration

```YAML
waste_collection_schedule:
  sources:
    - name: barnsley_gov_uk
      args:
        postcode: S70 3QU
        uprn: '100050607581'
      calendar_title: Waste Collection
  day_switch_time: '12:00'
```


### Checklist Source Error

- [X] Use the example parameters for your source (often available in the documentation) (don't forget to restart Home Assistant after changing the configuration)
- [X] Checked that the website of your service provider is still working
- [X] Tested my attributes on the service provider website (if possible)
- [X] I have tested with the latest version of the integration (master) (for HACS in the 3 dot menu of the integration click on "Redownload" and choose master as version)

### Checklist Sensor Error

- [X] Checked in the Home Assistant Calendar tab if the event names match the types names (if types argument is used)

### Required

- [X] I have searched past (closed AND opened) issues to see if this bug has already been reported, and it hasn't been.
- [X] I understand that people give their precious time for free, and thus I've done my very best to make this problem as easy as possible to investigate.


Discussion:

Resolving patch:
diff --git a/custom_components/waste_collection_schedule/waste_collection_schedule/source/barnsley_gov_uk.py b/custom_components/waste_collection_schedule/waste_collection_schedule/source/barnsley_gov_uk.py
--- a/custom_components/waste_collection_schedule/waste_collection_schedule/source/barnsley_gov_uk.py
+++ b/custom_components/waste_collection_schedule/waste_collection_schedule/source/barnsley_gov_uk.py
@@ -3,7 +3,7 @@
 # https://github.com/robbrad/UKBinCollectionData
 
 
-from datetime import datetime
+from datetime import date, datetime
 
 import requests
 from bs4 import BeautifulSoup
@@ -15,6 +15,7 @@
 TEST_CASES = {
     "S71 1EE 100050671689": {"postcode": "S71 1EE", "uprn": 100050671689},
     "S75 1QF 10032783992": {"postcode": "S75 1QF", "uprn": "10032783992"},
+    "test": {"postcode": "S70 3QU", "uprn": 100050607581},
 }
 
 
@@ -29,6 +30,12 @@
 API_URL = "https://waste.barnsley.gov.uk/ViewCollection/SelectAddress"
 
 
+def parse_date(d: str) -> date:
+    if d.lower() == "today":
+        return datetime.now().date()
+    return datetime.strptime(d, "%A, %B %d, %Y").date()
+
+
 class Source:
     def __init__(self, postcode: str, uprn: str | int):
         self._postcode: str = postcode
@@ -79,21 +86,10 @@ def fetch(self):
         # Parse the response, getting the top box first and then tabled collections after
         results = soup.find("div", {"class": "panel"}).find_all("fieldset")[0:2]
         heading = results[0].find_all("p")[1:3]
-        bin_text = heading[1].text.strip() + " bin"
-        bin_date = datetime.strptime(heading[0].text, "%A, %B %d, %Y").date()
-        entries.append(
-            Collection(
-                t=bin_text,
-                date=bin_date,
-                icon=ICON_MAP.get(bin_text.split(" ")[0].lower()),
-            )
-        )
 
-        results_table = [row for row in results[1].find_all("tbody")[0] if row != "\n"]
-        for row in results_table:
-            text_list = [item.text.strip() for item in row.contents if item != "\n"]
-            bin_text = text_list[1] + " bin"
-            bin_date = datetime.strptime(text_list[0], "%A, %B %d, %Y").date()
+        for bin in heading[1].text.strip().split(", "):
+            bin_text = bin + " bin"
+            bin_date = parse_date(heading[0].text)
             entries.append(
                 Collection(
                     t=bin_text,
@@ -102,4 +98,18 @@ def fetch(self):
                 )
             )
 
+        results_table = [row for row in results[1].find_all("tbody")[0] if row != "\n"]
+        for row in results_table:
+            text_list = [item.text.strip() for item in row.contents if item != "\n"]
+            for bin in text_list[1].split(", "):
+                bin_text = bin + " bin"
+                bin_date = parse_date(text_list[0])
+                entries.append(
+                    Collection(
+                        t=bin_text,
+                        date=bin_date,
+                        icon=ICON_MAP.get(bin_text.split(" ")[0].lower()),
+                    )
+                )
+
         return entries


Test patch: