diff --git a/custom_components/waste_collection_schedule/waste_collection_schedule/service/ICS.py b/custom_components/waste_collection_schedule/waste_collection_schedule/service/ICS.py index 6b73387a3..b33849f73 100644 --- a/custom_components/waste_collection_schedule/waste_collection_schedule/service/ICS.py +++ b/custom_components/waste_collection_schedule/waste_collection_schedule/service/ICS.py @@ -14,6 +14,8 @@ def __init__( offset: Optional[int] = None, regex: Optional[str] = None, split_at: Optional[str] = None, + title_fields: Optional[list] = ["summary"], + title_field_seperator: Optional[str] = " ", ): self._offset = offset self._regex = None @@ -25,6 +27,9 @@ def __init__( if split_at is not None: self._split_at = re.compile(split_at) + self._title_fields = title_fields + self._title_field_seperator = title_field_seperator + def convert(self, ics_data: str) -> List[Tuple[datetime.date, str]]: # calculate start- and end-date for recurring events start_date = datetime.datetime.now().replace( @@ -55,17 +60,26 @@ def convert(self, ics_data: str) -> List[Tuple[datetime.date, str]]: if self._offset is not None: dtstart += datetime.timedelta(days=self._offset) - # calculate waste type - summary = str(e.summary) + # combine waste type based on title_field. By default its "summary" but could also contain e.g. "location" + entry_title = "" + for title_field in self._title_fields: + if getattr(e, title_field) != None: + field = str(getattr(e, title_field)) + + if title_field == "summary": + if self._regex is not None: + match = self._regex.match(field) + if match: + field = match.group(1) + + entry_title = entry_title + field + self._title_field_seperator - if self._regex is not None: - if match := self._regex.match(summary): - summary = match.group(1) + entry_title = entry_title.rstrip() if self._split_at is not None: - summary = re.split(self._split_at, summary) - entries.extend((dtstart, t.strip().title()) for t in summary) + entry_title = re.split(self._split_at, entry_title) + entries.extend((dtstart, t.strip().title()) for t in entry_title) else: - entries.append((dtstart, summary)) + entries.append((dtstart, entry_title)) return entries diff --git a/custom_components/waste_collection_schedule/waste_collection_schedule/service/ICS_v1.py b/custom_components/waste_collection_schedule/waste_collection_schedule/service/ICS_v1.py index 765b6c7ba..e0593dea7 100644 --- a/custom_components/waste_collection_schedule/waste_collection_schedule/service/ICS_v1.py +++ b/custom_components/waste_collection_schedule/waste_collection_schedule/service/ICS_v1.py @@ -9,13 +9,23 @@ class ICS_v1: - def __init__(self, offset=None, regex=None, split_at=None): + def __init__( + self, + offset=None, + regex=None, + split_at=None, + title_fields=["summary"], + title_field_seperator=" ", + ): self._offset = offset self._regex = None if regex is not None: self._regex = re.compile(regex) self._split_at = split_at + self._title_fields = title_fields + self._title_field_seperator = title_field_seperator + def convert(self, ics_data): # parse ics file calendar = icalendar.Calendar.from_ical(ics_data) @@ -43,17 +53,28 @@ def convert(self, ics_data): dtstart += datetime.timedelta(days=self._offset) # calculate waste type - summary = str(e.get("summary")) - if self._regex is not None: - match = self._regex.match(summary) - if match: - summary = match.group(1) + + # combine waste type based on title_field. By default its "summary" but could also contain e.g. "location" + entry_title = "" + for title_field in self._title_fields: + if e.get(title_field) != None: + field = str(e.get(title_field)) + + if title_field == "summary": + if self._regex is not None: + match = self._regex.match(field) + if match: + field = match.group(1) + + entry_title = entry_title + field + self._title_field_seperator + + entry_title = entry_title.rstrip() if self._split_at is not None: - summary = re.split(self._split_at, summary) - for t in summary: + entry_title = re.split(self._split_at, entry_title) + for t in entry_title: entries.append((dtstart, t.strip().title())) else: - entries.append((dtstart, summary)) + entries.append((dtstart, entry_title)) return entries diff --git a/custom_components/waste_collection_schedule/waste_collection_schedule/source/ics.py b/custom_components/waste_collection_schedule/waste_collection_schedule/source/ics.py index 8a5b36a4a..cbfbdb2d5 100644 --- a/custom_components/waste_collection_schedule/waste_collection_schedule/source/ics.py +++ b/custom_components/waste_collection_schedule/waste_collection_schedule/source/ics.py @@ -135,6 +135,8 @@ def __init__( year_field=None, method="GET", regex=None, + title_fields=["summary"], + title_field_seperator=" ", split_at=None, version=2, verify_ssl=True, @@ -145,9 +147,21 @@ def __init__( if bool(self._url is not None) == bool(self._file is not None): raise RuntimeError("Specify either url or file") if version == 1: - self._ics = ICS_v1(offset=offset, split_at=split_at, regex=regex) + self._ics = ICS_v1( + offset=offset, + split_at=split_at, + regex=regex, + title_fields=title_fields, + title_field_seperator=title_field_seperator, + ) else: - self._ics = ICS(offset=offset, split_at=split_at, regex=regex) + self._ics = ICS( + offset=offset, + split_at=split_at, + regex=regex, + title_fields=title_fields, + title_field_seperator=title_field_seperator, + ) self._params = params self._year_field = year_field # replace this field in params with current year self._method = method # The method to send the params diff --git a/doc/source/ics.md b/doc/source/ics.md index 1c604f704..7b241fca2 100644 --- a/doc/source/ics.md +++ b/doc/source/ics.md @@ -97,6 +97,8 @@ waste_collection_schedule: version: 2 verify_ssl: VERIFY_SSL headers: HEADERS + title_fields: ["summary"] + title_field_seperator: " " ``` ### Configuration Variables @@ -198,6 +200,17 @@ Add custom headers to HTTP request, e.g. `referer`. By default, the `user-agent` See also [example](#custom-headers) below. +**title_fields** +*(dict) (optional, default: ["summary"])* + +fields in the ical event to select for the event entry name. + +**title_field_seperator** +*(str) (optional, default: " ")* + +seperator to combine fields in `title_fields` for the event entry name. + + ## Examples and Notes *** @@ -855,3 +868,41 @@ waste_collection_schedule: referer: "https://aik.ilm-kreis.de" calendar_title: Abfuhrtermine Witzleben ``` + + +### Münsingen, Canton of Bern, Switzerland + +Go to [Abfallkalender](https://www.muensingen.ch/de/verwaltung/dienstleistungen/detail/detail.php?i=90) to get the url of the ICal file. + +```yaml +waste_collection_schedule: + sources: + - name: ics + args: + url: "https://www.muensingen.ch/de/verwaltung/dokumente/dokumente/Papier-und-Kartonabfuhr-{%Y}.ics" + version: 1 + title_fields: + - summary + - location + calendar_title: "Papier-und-Kartonabfuhr" + customize: + - type: Papier und Karton Gebiet Ost + alias: Gebiet Ost + show: false + icon: mdi:recycle + - type: Papier und Karton Gebiet West + alias: Gebiet West + icon: mdi:recycle + - type: Papier und Karton Gebiet Ost und West + alias: Gebiet Ost und West + icon: mdi:recycle + - name: ics + args: + url: "https://www.muensingen.ch/de/verwaltung/dokumente/dokumente/Gartenabfaelle-{%Y}.ics" + version: 1 + calendar_title: "Gartenabfaelle" + customize: + - type: "Grüngut" + alias: "Grüngut" + icon: mdi:leaf-circle +``` \ No newline at end of file