Skip to content

Commit b3279c5

Browse files
authored
Add possibility to add additional dates to recurring events (#45)
* Ignore new line at end of file (it breaks the custom ics parser) * Add possibility to add additional dates to recurring events * Incorporate feedback from @stefanv. Thank you! * Remove YAML whitespace that is actually not needed
1 parent 50e0c70 commit b3279c5

3 files changed

Lines changed: 33 additions & 26 deletions

File tree

example/test_calendar.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ events:
3333
weeks: 1
3434
until: 2022-12-31 # required
3535

36-
- summary: Recurring event with exception
36+
- summary: Recurring event with exception and additional date
3737
begin: 2022-07-01 10:00:00
3838
duration: { minutes: 60 }
3939
repeat:
@@ -44,6 +44,8 @@ events:
4444
except_on:
4545
- 2022-07-13
4646
- 2022-07-14 06:00:00
47+
also_on:
48+
- 2022-12-24 06:00:00
4749

4850
# All-day event
4951
- summary: Earth Day

tests/test_events.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def test_exception():
6969
event = event_from_yaml(
7070
parse_yaml(
7171
"""
72-
summary: Recurring event with exception
72+
summary: Recurring event with exception and additional date
7373
timezone: America/Los_Angeles
7474
begin: 2022-07-01 10:00:00
7575
duration: {minutes: 60}
@@ -80,6 +80,8 @@ def test_exception():
8080
except_on:
8181
- 2022-07-13
8282
- 2022-07-14 06:00:00
83+
also_on:
84+
- 2022-12-24 06:00:00
8385
"""
8486
)
8587
)
@@ -90,6 +92,7 @@ def test_exception():
9092
"EXDATE;TZID=/ics.py/2020.1/America/Los_Angeles:20220713,20220714T060000"
9193
in event_str
9294
)
95+
assert "RDATE;TZID=/ics.py/2020.1/America/Los_Angeles:20221224T060000" in event_str
9396

9497

9598
def test_event_with_time_range():

yaml2ics.py

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,26 @@
2525
}
2626

2727

28-
def strfexception(exdate):
29-
if isinstance(exdate, datetime.datetime):
30-
return datetime.datetime.strftime(exdate, "%Y%m%dT%H%M%S")
31-
elif isinstance(exdate, datetime.date):
32-
return datetime.datetime.strftime(exdate, "%Y%m%d")
28+
def datetime2utc(date):
29+
if isinstance(date, datetime.datetime):
30+
return datetime.datetime.strftime(date, "%Y%m%dT%H%M%S")
31+
elif isinstance(date, datetime.date):
32+
return datetime.datetime.strftime(date, "%Y%m%d")
33+
34+
35+
# See RFC2445, 4.8.5 REcurrence Component Properties
36+
# This function can be used to add a list of e.g. exception dates (EXDATE) or recurrence dates (RDATE)
37+
# to a reoccurring event
38+
def add_recurrence_property(
39+
event: ics.Event, property_name, dates: map, tz: datetime.tzinfo = None
40+
):
41+
event.extra.append(
42+
ics.ContentLine(
43+
name=property_name,
44+
params={"TZID": [str(ics.Timezone.from_tzinfo(tz))]} if tz else None,
45+
value=",".join(dates),
46+
)
47+
)
3348

3449

3550
def event_from_yaml(event_yaml: dict, tz: datetime.tzinfo = None) -> ics.Event:
@@ -100,25 +115,12 @@ def event_from_yaml(event_yaml: dict, tz: datetime.tzinfo = None) -> ics.Event:
100115
)
101116

102117
if "except_on" in repeat:
103-
exdates = map(
104-
lambda exdate: strfexception(exdate),
105-
repeat["except_on"],
106-
)
107-
if tz:
108-
event.extra.append(
109-
ics.ContentLine(
110-
name="EXDATE",
111-
params={"TZID": [str(ics.Timezone.from_tzinfo(tz))]},
112-
value=",".join(exdates),
113-
)
114-
)
115-
else:
116-
event.extra.append(
117-
ics.ContentLine(
118-
name="EXDATE",
119-
value=",".join(exdates),
120-
)
121-
)
118+
exdates = [datetime2utc(rdate) for rdate in repeat["except_on"]]
119+
add_recurrence_property(event, "EXDATE", exdates, tz)
120+
121+
if "also_on" in repeat:
122+
rdates = [datetime2utc(rdate) for rdate in repeat["also_on"]]
123+
add_recurrence_property(event, "RDATE", rdates, tz)
122124

123125
event.dtstamp = datetime.datetime.utcnow().replace(tzinfo=dateutil.tz.UTC)
124126
if tz and event.floating and not event.all_day:

0 commit comments

Comments
 (0)