Skip to content

Commit

Permalink
allow to use other fields than summary in ical source for event title (
Browse files Browse the repository at this point in the history
…#663)

* allow to use other fields than summary in ical source for event title

* add jinja2 to requirements.txt
  • Loading branch information
splattner authored Oct 24, 2023
1 parent f22509c commit 9be0bc9
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import re
from typing import Any, List, Optional, Tuple

import jinja2
from icalevents import icalevents

_LOGGER = logging.getLogger(__name__)
Expand All @@ -14,6 +15,7 @@ def __init__(
offset: Optional[int] = None,
regex: Optional[str] = None,
split_at: Optional[str] = None,
title_template: Optional[str] = "{{date.summary}}",
):
self._offset = offset
self._regex = None
Expand All @@ -25,6 +27,8 @@ def __init__(
if split_at is not None:
self._split_at = re.compile(split_at)

self._title_template = title_template

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(
Expand Down Expand Up @@ -55,17 +59,19 @@ 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)
environment = jinja2.Environment()
title_template = environment.from_string(self._title_template)
entry_title = title_template.render(date=e)

if self._regex is not None:
if match := self._regex.match(summary):
summary = match.group(1)
match = self._regex.match(entry_title)
if match:
entry_title = match.group(1)

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
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,28 @@

import icalendar
import recurring_ical_events
import jinja2


_LOGGER = logging.getLogger(__name__)


class ICS_v1:
def __init__(self, offset=None, regex=None, split_at=None):
def __init__(
self,
offset=None,
regex=None,
split_at=None,
title_template="{{date.summary}}",
):
self._offset = offset
self._regex = None
if regex is not None:
self._regex = re.compile(regex)
self._split_at = split_at

self._title_template = title_template

def convert(self, ics_data):
# parse ics file
calendar = icalendar.Calendar.from_ical(ics_data)
Expand Down Expand Up @@ -43,17 +53,20 @@ def convert(self, ics_data):
dtstart += datetime.timedelta(days=self._offset)

# calculate waste type
summary = str(e.get("summary"))
environment = jinja2.Environment()
title_template = environment.from_string(self._title_template)
entry_title = title_template.render(date=e)

if self._regex is not None:
match = self._regex.match(summary)
match = self._regex.match(entry_title)
if match:
summary = match.group(1)
entry_title = match.group(1)

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
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ def __init__(
year_field=None,
method="GET",
regex=None,
title_template="{{date.summary}}",
split_at=None,
version=2,
verify_ssl=True,
Expand All @@ -125,9 +126,19 @@ 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_template=title_template,
)
else:
self._ics = ICS(offset=offset, split_at=split_at, regex=regex)
self._ics = ICS(
offset=offset,
split_at=split_at,
regex=regex,
title_template=title_template,
)
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
Expand Down
75 changes: 75 additions & 0 deletions doc/source/ics.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ waste_collection_schedule:
version: 2
verify_ssl: VERIFY_SSL
headers: HEADERS
title_template: "{{date.summary}}"
```
### Configuration Variables
Expand Down Expand Up @@ -222,6 +223,11 @@ Add custom headers to HTTP request, e.g. `referer`. By default, the `user-agent`

See also [example](#custom-headers) below.

**title_template**
*(str) (optional, default: `{{date.summary}}`)*

template for the event title. `date` is the event object depending on the selected ICS file parser version.

## Examples and Notes

***
Expand Down Expand Up @@ -295,3 +301,72 @@ waste_collection_schedule:
```

Removes the needless prefix "Abfuhr: " from the waste collection type.
***
### FES Frankfurt
```yaml
waste_collection_schedule:
sources:
- name: ics
args:
url: https://www.fes-frankfurt.de/abfallkalender/<your-id>.ics
split_at: " \/ "
regex: "(.*)\\s+\\|"
```
***
### Abfallwirtschaftsbetrieb Ilm-Kreis
Go to the [service provider website](https://aik.ilm-kreis.de/Abfuhrtermine/) and select location and street. Selection of desired waste types is optional. Afterwards an iCal calendar export is provided. Download it and find the download URL. Some parameters of the URL can be omitted. (e.g. `kat`, `ArtID`, `alarm`)

Important: The base url of the provider's website `https://aik.ilm-kreis.de` needs to be set as a [custom header](#custom-headers) `referer`. Otherwise you'll get an HTTP 403 error.

```yaml
waste_collection_schedule:
sources:
- name: ics
args:
url: "https://aik.ilm-kreis.de/output/options.php?ModID=48&call=ical&=&ArtID[0]=1.1&ArtID[1]=1.4&ArtID[2]=1.2&pois=3053.562&kat=1,&alarm=0"
headers:
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_template: "{{date.summary}} {{date.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
```
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ soupsieve==2.4.1
urllib3==2.0.4
x-wr-timezone==0.0.5
zope.interface==6.0
jinja2=3.1.2

0 comments on commit 9be0bc9

Please sign in to comment.