Repository: mampfes/hacs_waste_collection_schedule

Issue:
Can't configure source without arguments
Hello Team,
I'm trying to configure into HomeAssistant the source that I added Mamirolle info, but I have argument issues.

`args` is marked `required`, so if none is passed, the configuration is invalid.

```
Invalid config for [waste_collection_schedule]: required key not provided @ data['waste_collection_schedule']['sources'][0]['args']. Got None. (See /config/configuration.yaml, line 27). 
```

If a dummy argument is passed. The configuration is valid but the source setup fails.
```
Error during setup of component waste_collection_schedule

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/setup.py", line 288, in _async_setup_component
    result = await task
             ^^^^^^^^^^
  File "/config/custom_components/waste_collection_schedule/__init__.py", line 109, in async_setup
    api.add_source_shell(
  File "/config/custom_components/waste_collection_schedule/__init__.py", line 202, in add_source_shell
    SourceShell.create(
  File "/config/custom_components/waste_collection_schedule/waste_collection_schedule/source_shell.py", line 196, in create
    source = source_module.Source(**source_args)  # type: ignore
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Source() takes no arguments
```
I understand that we want the configuration to fail early but the real error will still be seen only when the source is actually instantiated. Because of that I think the arguments shouldn't be required.

What do you think about this?


Discussion:
A quick fix would be to add an arg that isn't used.

```python
class Source:

    def __init__(self, _ = None):
        self._ = None

    def fetch(self):
       ... rest of the code ...
```
```bash
Testing source mamirolle_info ...
  found 2 entries for TestSource
    2024-10-03 : Poubelle grise [mdi:trash-can]
    2024-09-26 : Poubelle jaune [mdi:recycle]
```
I thought of that too because I think it's important to have the arguments as required in most of the sources.
I can make a PR for that

Resolving patch:
diff --git a/custom_components/waste_collection_schedule/waste_collection_schedule/source/mamirolle_info.py b/custom_components/waste_collection_schedule/waste_collection_schedule/source/mamirolle_info.py
--- a/custom_components/waste_collection_schedule/waste_collection_schedule/source/mamirolle_info.py
+++ b/custom_components/waste_collection_schedule/waste_collection_schedule/source/mamirolle_info.py
@@ -9,7 +9,12 @@
 COUNTRY = "fr"
 URL = "http://mamirolle.info/"
 
-TEST_CASES = {"TestSource": {}}
+TEST_CASES = {
+    "TestSource": {},
+    "IgnoredArgument": {
+        "_": ""
+    }
+}
 
 ICON_MAP = {
     "Poubelle grise": "mdi:trash-can",
@@ -33,6 +38,9 @@
 
 
 class Source:
+    def __init__(self, _=None):
+        pass
+
     def fetch(self):
         now = datetime.datetime.now()
         # get list of regions and weblinks
@@ -40,28 +48,19 @@ def fetch(self):
         # A lenient HTML parser is need
         soup = BeautifulSoup(page.text.replace("<![endif]", ""), "html.parser")
         trash_domestic = soup.find("i", class_="poubelle-grise")
-        _, day, month = trash_domestic.next_sibling.string.split()
-        date_domestic = now.replace(month=MONTH_NAMES.index(month), day=int(day)).date()
-        if date_domestic < now.date():
-            date_domestic = date_domestic.replace(year=date_domestic.year + 1)
-
         trash_recycle = soup.find("i", class_="poubelle-jaune")
-        _, day, month = trash_recycle.next_sibling.string.split()
-        date_recycle = now.replace(month=MONTH_NAMES.index(month), day=int(day)).date()
-        if date_recycle < now.date():
-            date_recycle = date_recycle.replace(year=date_recycle.year + 1)
 
-        entries = [
-            Collection(
-                date=date_domestic,
-                t="Poubelle grise",
-                icon=ICON_MAP.get("Poubelle grise"),
-            ),
-            Collection(
-                date=date_recycle,
-                t="Poubelle jaune",
-                icon=ICON_MAP.get("Poubelle jaune"),
-            ),
-        ]  # List that holds collection schedule
+        entries = []  # List that holds collection schedule
+        for trash, label in [(trash_domestic, "Poubelle grise"), (trash_recycle, "Poubelle jaune")]:
+            _, day, month = trash.next_sibling.string.split()
+            date = now.replace(month=MONTH_NAMES.index(month) + 1, day=int(day)).date()
+            if date < now.date():
+                date = date.replace(year=date.year + 1)
+
+            entries.append(Collection(
+                date=date,
+                t=label,
+                icon=ICON_MAP.get(label),
+            ))
 
         return entries


Test patch: