Skip to content

Commit 242e57d

Browse files
authored
Add ability to specify custom ICS (#41)
1 parent 79fe543 commit 242e57d

3 files changed

Lines changed: 35 additions & 0 deletions

File tree

example/test_calendar.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,9 @@ events:
5454
# seconds, minutes, hours, days, weeks, months, years
5555
years: 1
5656
until: 2030-04-22
57+
58+
# Event with custom RRULE
59+
- summary: Another day
60+
begin: 2021-04-22
61+
ics: |
62+
RRULE:FREQ=YEARLY;UNTIL=20280422T000000

tests/test_events.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,19 @@ def test_event_with_duration():
126126
assert "DURATION:PT30M" in event_str
127127
assert "DTEND" not in event_str
128128
assert "DTSTART" in event_str
129+
130+
131+
def test_event_with_custom_ics():
132+
event = event_from_yaml(
133+
parse_yaml(
134+
"""
135+
summary: Earth Day
136+
begin: 2021-04-22
137+
url: https://earthday.org
138+
ics: |
139+
RRULE:FREQ=YEARLY;UNTIL=20280422T000000
140+
"""
141+
)
142+
)
143+
event_str = event.serialize()
144+
assert "RRULE:FREQ=YEARLY;UNTIL=20280422T000000" in event_str

yaml2ics.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ def strfexception(exdate):
3535
def event_from_yaml(event_yaml: dict, tz: datetime.tzinfo = None) -> ics.Event:
3636
d = event_yaml
3737
repeat = d.pop("repeat", None)
38+
ics_custom = d.pop("ics", None)
39+
3840
if "timezone" in d:
3941
tz = gettz(d.pop("timezone"))
4042

@@ -121,6 +123,17 @@ def event_from_yaml(event_yaml: dict, tz: datetime.tzinfo = None) -> ics.Event:
121123
event.dtstamp = datetime.datetime.utcnow().replace(tzinfo=dateutil.tz.UTC)
122124
if tz and event.floating and not event.all_day:
123125
event.replace_timezone(tz)
126+
127+
if ics_custom:
128+
for line in ics_custom.split("\n"):
129+
if ":" not in line:
130+
raise RuntimeError(
131+
f"Invalid custom ICS (expected `fieldname:value`):\n {line}"
132+
)
133+
134+
ruletype, content = line.split(":", maxsplit=1)
135+
event.extra.append(ics.ContentLine(name=ruletype, value=content))
136+
124137
return event
125138

126139

0 commit comments

Comments
 (0)