Skip to content

Commit b934953

Browse files
committed
Port yaml2ics to ics 0.8.0
- Various changes throughout, see #3
1 parent bbe30ba commit b934953

5 files changed

Lines changed: 38 additions & 45 deletions

File tree

example/test_calendar.yaml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
events:
2-
- name: Event of the Century
3-
begin: 2021-09-21 15:00-07:00
4-
end: 2021-09-21 15:30:00-07:00
2+
- summary: Event of the Century
3+
begin: 2021-09-21 15:00:00
4+
end: 2021-09-21 15:30:00
55
description: |
66
Meet the team on the northern side of the field.
77
8-
- name: Half-an-hour meeting
9-
begin: 2021-09-23 15:00-07:00
8+
- summary: Half-an-hour meeting
9+
begin: 2021-09-23 15:00:00
1010
duration:
1111
minutes: 30
1212
location: |
1313
Office 224, Monolith Bldg, Office Block C
1414
15-
- name: Earth Day
15+
- summary: Earth Day
1616
begin: 2021-04-22
1717
url: https://earthday.org
1818
repeat:

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
ics
1+
https://github.com/ics-py/ics-py/archive/refs/heads/main.zip
22
python-dateutil

tests/test_calendar.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22

33

44
def test_calendar_structure():
5-
cal = events_to_calendar_ics(['event0', 'event1'])
5+
cal = events_to_calendar_ics([])
66
assert cal.startswith('BEGIN:VCALENDAR')
77
assert cal.endswith('END:VCALENDAR')

tests/test_events.py

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@ def test_basic_structure():
1515
)
1616

1717
# All lines must be separated by CRLF
18-
lines = event.split('\n')
18+
event_str = event.serialize()
19+
lines = event_str.split('\n')
1920
for line in lines[:-1]:
2021
assert line.endswith('\r')
2122

2223
# All events must have a DTSTAMP
23-
assert 'DTSTAMP' in event
24+
assert 'DTSTAMP' in event_str
2425

2526

2627
def test_all_day_event():
@@ -33,10 +34,12 @@ def test_all_day_event():
3334
'''
3435
)
3536
)
36-
assert event.startswith('BEGIN:VEVENT')
37-
assert event.endswith('END:VEVENT')
38-
assert 'DTSTART;VALUE=DATE:20210422' in event
39-
assert 'DTEND' not in event
37+
event_str = event.serialize()
38+
assert event_str.startswith('BEGIN:VEVENT')
39+
assert event_str.endswith('END:VEVENT')
40+
assert 'DTSTART;VALUE=DATE:20210422' in event_str
41+
# ics 0.8.0 does have DTEND that is the next day.
42+
#assert 'DTEND' not in event_str
4043

4144

4245
def test_rrule():
@@ -53,40 +56,43 @@ def test_rrule():
5356
'''
5457
)
5558
)
56-
assert 'DTEND' not in event
57-
assert 'RRULE:FREQ=YEARLY;UNTIL=20300422T000000Z' in event
59+
event_str = event.serialize()
60+
assert 'DTEND' not in event_str
61+
assert 'RRULE:FREQ=YEARLY;UNTIL=20300422T000000' in event_str
5862

5963

6064
def test_event_with_time_range():
6165
event = event_ics_from_yaml(
6266
parse_yaml(
6367
'''
6468
name: Event of the Century
65-
begin: 2021-09-21 15:00-07:00
66-
end: 2021-09-21 15:30:00-07:00
69+
begin: 2021-09-21 15:00:00 -07:00
70+
end: 2021-09-21 15:30:00 -07:00
6771
description: |
6872
Meet the team on the northern side of the field.
6973
'''
7074
)
7175
)
72-
assert 'DTSTART' in event
73-
assert 'DTEND' in event
76+
event_str = event.serialize()
77+
assert 'DTSTART' in event_str
78+
assert 'DTEND' in event_str
7479

7580

7681
def test_event_with_duration():
7782
event = event_ics_from_yaml(
7883
parse_yaml(
7984
'''
8085
name: Event of the Century
81-
begin: 2021-09-21 15:00-07:00
86+
begin: 2021-09-21 15:00:00 -07:00
8287
duration:
8388
minutes: 30
8489
description: |
8590
Meet the team on the northern side of the field.
8691
'''
8792
)
8893
)
94+
event_str = event.serialize()
95+
assert 'DURATION:PT30M' in event_str
96+
assert 'DTEND' not in event_str
97+
assert 'DTSTART' in event_str
8998

90-
assert 'DURATION:PT30M' in event
91-
assert 'DTEND' not in event
92-
assert 'DTSTART' in event

yaml2ics.py

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@
1919
}
2020

2121

22-
def event_ics_from_yaml(event_yaml: dict) -> str:
22+
def event_ics_from_yaml(event_yaml: dict) -> ics.Event:
2323
d = event_yaml
2424
repeat = d.pop('repeat', None)
25+
if 'name' in d:
26+
d['summary'] = d.pop('name')
2527

2628
# Strip all string values, since they often end on `\n`
2729
for key in d:
@@ -68,32 +70,17 @@ def event_ics_from_yaml(event_yaml: dict) -> str:
6870
rrule_dtstart = rrule_dtstart + 'Z'
6971
rrule_rrule = [line for line in rrule_lines if line.startswith('RRULE')][0]
7072

71-
event_lines = str(event).split('\r\n')
73+
event.extra.append(ics.ContentLine(rrule_rrule))
7274

73-
# Splice in the rrule
74-
out = []
75-
for line in event_lines:
76-
out.append(line)
77-
78-
if line.startswith('DTSTART'):
79-
out.append(rrule_rrule + 'Z')
80-
else:
81-
out = str(event).split('\r\n')
82-
83-
now_utc = datetime.utcnow()
84-
utc_stamp = now_utc.isoformat(
85-
timespec='seconds'
86-
).replace('-', '').replace(':', '') + 'Z'
87-
out.insert(-1, f'DTSTAMP:{utc_stamp}')
88-
89-
return '\r\n'.join(out)
75+
event.dtstamp = datetime.utcnow().replace(tzinfo=dateutil.tz.UTC)
76+
return event
9077

9178

9279
def events_to_calendar_ics(events: dict) -> str:
9380
cal = ics.Calendar()
9481
for event in events:
95-
cal.events.add(event)
96-
return str(cal)
82+
cal.events.append(event)
83+
return cal.serialize()
9784

9885

9986
if __name__ == '__main__':

0 commit comments

Comments
 (0)