Skip to content

Commit cf800da

Browse files
committed
Black and flake8 fixes
1 parent 3fa966d commit cf800da

4 files changed

Lines changed: 107 additions & 95 deletions

File tree

tests/test_calendar.py

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,44 @@
22
import io
33
import textwrap
44

5-
from util import parse_yaml
6-
75
from yaml2ics import events_to_calendar, files_to_calendar
86

97

108
def test_calendar_structure():
119
cal = events_to_calendar([])
1210
cal_str = cal.serialize()
13-
assert cal_str.startswith('BEGIN:VCALENDAR')
14-
assert cal_str.endswith('END:VCALENDAR')
11+
assert cal_str.startswith("BEGIN:VCALENDAR")
12+
assert cal_str.endswith("END:VCALENDAR")
13+
1514

1615
def test_calendar_event():
1716
cal = files_to_calendar(
18-
[io.StringIO(textwrap.dedent(
19-
'''
17+
[
18+
io.StringIO(
19+
textwrap.dedent(
20+
"""
2021
events:
2122
- summary: Earth Day
2223
begin: 2021-04-22
2324
url: https://earthday.org
2425
location: Earth
25-
'''
26-
))]
26+
"""
27+
)
28+
)
29+
]
2730
)
2831
cal_str = cal.serialize()
29-
assert cal_str.startswith('BEGIN:VCALENDAR')
30-
assert 'SUMMARY:Earth Day' in cal_str
31-
assert cal_str.endswith('END:VCALENDAR')
32+
assert cal_str.startswith("BEGIN:VCALENDAR")
33+
assert "SUMMARY:Earth Day" in cal_str
34+
assert cal_str.endswith("END:VCALENDAR")
35+
3236

3337
def test_calendar_default_timezone():
3438
cal = files_to_calendar(
35-
[io.StringIO(textwrap.dedent(
36-
'''
39+
[
40+
io.StringIO(
41+
textwrap.dedent(
42+
"""
3743
meta:
3844
tz: Europe/Helsinki
3945
@@ -48,23 +54,25 @@ def test_calendar_default_timezone():
4854
4955
- summary: Earth day (all day)
5056
begin: 2022-04-22
51-
'''
52-
))]
57+
"""
58+
)
59+
)
60+
]
5361
)
5462
cal_str = cal.serialize()
55-
assert cal_str.startswith('BEGIN:VCALENDAR')
56-
assert 'SUMMARY:New year' in cal_str
63+
assert cal_str.startswith("BEGIN:VCALENDAR")
64+
assert "SUMMARY:New year" in cal_str
5765
# It is possible that the ics-py TZID string changes, but hopefully this
5866
# substring is fairly safe to test against.
59-
assert 'Europe/Helsinki:20220101T000000' in cal_str
67+
assert "Europe/Helsinki:20220101T000000" in cal_str
6068
# Second event: explicit UTC offset specified.
6169
assert '"UTC+02:00":20220201T000000' in cal_str
62-
assert cal_str.endswith('END:VCALENDAR')
70+
assert cal_str.endswith("END:VCALENDAR")
6371

6472
# Test again by normalizing to UTC. Helsinki is two hours ahead, so the
6573
# times should be 22:00:00.
6674
cal.normalize(datetime.timezone.utc)
67-
cal_norm_str = cal.serialize()
75+
cal_norm_str = cal.serialize() # noqa: F841
6876
# 1 Feb midnight
69-
assert 'DTSTART:20211231T220000Z' # 1 jan
70-
assert 'DTSTART:20220131T220000Z' # 1 feb
77+
assert "DTSTART:20211231T220000Z" # 1 jan
78+
assert "DTSTART:20220131T220000Z" # 1 feb

tests/test_events.py

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,97 +6,96 @@
66
def test_basic_structure():
77
event = event_from_yaml(
88
parse_yaml(
9-
'''
9+
"""
1010
summary: Earth Day
1111
begin: 2021-04-22
1212
url: https://earthday.org
1313
location: Earth
14-
'''
14+
"""
1515
)
1616
)
1717

1818
# All lines must be separated by CRLF
1919
event_str = event.serialize()
20-
lines = event_str.split('\n')
20+
lines = event_str.split("\n")
2121
for line in lines[:-1]:
22-
assert line.endswith('\r')
23-
assert 'SUMMARY:Earth Day' in event_str
24-
assert 'URL:https://earthday.org' in event_str
25-
assert 'LOCATION:Earth' in event_str
22+
assert line.endswith("\r")
23+
assert "SUMMARY:Earth Day" in event_str
24+
assert "URL:https://earthday.org" in event_str
25+
assert "LOCATION:Earth" in event_str
2626
# All events must have a DTSTAMP
27-
assert 'DTSTAMP' in event_str
27+
assert "DTSTAMP" in event_str
2828

2929

3030
def test_all_day_event():
3131
event = event_from_yaml(
3232
parse_yaml(
33-
'''
33+
"""
3434
summary: Earth Day
3535
begin: 2021-04-22
3636
url: https://earthday.org
37-
'''
37+
"""
3838
)
3939
)
4040
event_str = event.serialize()
41-
assert event_str.startswith('BEGIN:VEVENT')
42-
assert event_str.endswith('END:VEVENT')
43-
assert 'DTSTART;VALUE=DATE:20210422' in event_str
41+
assert event_str.startswith("BEGIN:VEVENT")
42+
assert event_str.endswith("END:VEVENT")
43+
assert "DTSTART;VALUE=DATE:20210422" in event_str
4444
# ics 0.8.0 does have DTEND that is the next day.
45-
#assert 'DTEND' not in event_str
45+
# assert 'DTEND' not in event_str
4646

4747

4848
def test_rrule():
4949
event = event_from_yaml(
5050
parse_yaml(
51-
'''
51+
"""
5252
summary: Earth Day
5353
begin: 2021-04-22
5454
url: https://earthday.org
5555
repeat:
5656
interval:
5757
years: 1
5858
until: 2030-04-22
59-
'''
59+
"""
6060
)
6161
)
6262
event_str = event.serialize()
6363
# DTEND exists and is the next day, calendar tools import this
6464
# correctly as being a one-day event
65-
assert 'RRULE:FREQ=YEARLY;UNTIL=20300422T000000' in event_str
65+
assert "RRULE:FREQ=YEARLY;UNTIL=20300422T000000" in event_str
6666

6767

6868
def test_event_with_time_range():
6969
event = event_from_yaml(
7070
parse_yaml(
71-
'''
71+
"""
7272
summary: Event of the Century
7373
begin: 2021-09-21 15:00:00 -07:00
7474
end: 2021-09-21 15:30:00 -07:00
7575
description: |
7676
Meet the team on the northern side of the field.
77-
'''
77+
"""
7878
)
7979
)
8080
event_str = event.serialize()
81-
assert 'DTSTART' in event_str
82-
assert 'DTEND' in event_str
81+
assert "DTSTART" in event_str
82+
assert "DTEND" in event_str
8383

8484

8585
def test_event_with_duration():
8686
event = event_from_yaml(
8787
parse_yaml(
88-
'''
88+
"""
8989
summary: Event of the Century
9090
begin: 2021-09-21 15:00:00 -07:00
9191
duration:
9292
minutes: 30
9393
description: |
9494
Meet the team on the northern side of the field.
95-
'''
95+
"""
9696
)
9797
)
9898
event_str = event.serialize()
99-
assert 'DURATION:PT30M' in event_str
100-
assert 'DTEND' not in event_str
101-
assert 'DTSTART' in event_str
102-
99+
assert "DURATION:PT30M" in event_str
100+
assert "DTEND" not in event_str
101+
assert "DTSTART" in event_str

tests/util.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
import yaml
21
import textwrap
32

3+
import yaml
4+
45

56
def parse_yaml(yaml_str):
6-
return yaml.load(
7-
textwrap.dedent(yaml_str).strip(),
8-
Loader=yaml.FullLoader
9-
)
7+
return yaml.load(textwrap.dedent(yaml_str).strip(), Loader=yaml.FullLoader)

yaml2ics.py

Lines changed: 48 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,27 @@
1-
import yaml
2-
import sys
31
import os
2+
import sys
43
from datetime import datetime, tzinfo
54

6-
import ics
75
import dateutil
86
import dateutil.rrule
7+
import ics
8+
import yaml
99
from dateutil.tz import gettz
1010

11-
1211
interval_type = {
13-
'seconds': dateutil.rrule.SECONDLY,
14-
'minutes': dateutil.rrule.MINUTELY,
15-
'hours': dateutil.rrule.HOURLY,
16-
'days': dateutil.rrule.DAILY,
17-
'weeks': dateutil.rrule.WEEKLY,
18-
'months': dateutil.rrule.MONTHLY,
19-
'years': dateutil.rrule.YEARLY
12+
"seconds": dateutil.rrule.SECONDLY,
13+
"minutes": dateutil.rrule.MINUTELY,
14+
"hours": dateutil.rrule.HOURLY,
15+
"days": dateutil.rrule.DAILY,
16+
"weeks": dateutil.rrule.WEEKLY,
17+
"months": dateutil.rrule.MONTHLY,
18+
"years": dateutil.rrule.YEARLY,
2019
}
2120

2221

23-
def event_from_yaml(event_yaml: dict, tz: tzinfo=None) -> ics.Event:
22+
def event_from_yaml(event_yaml: dict, tz: tzinfo = None) -> ics.Event:
2423
d = event_yaml
25-
repeat = d.pop('repeat', None)
24+
repeat = d.pop("repeat", None)
2625

2726
# Strip all string values, since they often end on `\n`
2827
for key in d:
@@ -37,42 +36,50 @@ def event_from_yaml(event_yaml: dict, tz: tzinfo=None) -> ics.Event:
3736
event = ics.Event(**d)
3837

3938
# Handle all-day events
40-
if not ('duration' in d or 'end' in d):
39+
if not ("duration" in d or "end" in d):
4140
event.make_all_day()
4241

4342
if repeat:
44-
interval = repeat['interval']
43+
interval = repeat["interval"]
4544

4645
if not len(interval) == 1:
47-
print('Error: interval must specify seconds, minutes, hours, days, weeks, months, or years only', file=sys.stderr)
46+
print(
47+
"Error: interval must specify seconds, minutes, hours, days, weeks, months, or years only",
48+
file=sys.stderr,
49+
)
4850
sys.exit(-1)
4951

5052
interval_measure = list(interval.keys())[0]
5153
if interval_measure not in interval_type:
52-
print('Error: expected interval to be specified in seconds, minutes, hours, days, weeks, months, or years only', file=sys.stderr)
54+
print(
55+
"Error: expected interval to be specified in seconds, minutes, hours, days, weeks, months, or years only",
56+
file=sys.stderr,
57+
)
5358
sys.exit(-1)
5459

55-
if 'until' not in repeat:
56-
print('Error: must specify end date for repeating events', file=sys.stderr)
60+
if "until" not in repeat:
61+
print("Error: must specify end date for repeating events", file=sys.stderr)
5762
sys.exit(-1)
5863

5964
# This causes zero-length events, I guess overriding whatever duration might have been specified.
60-
#event.end = d.get('end', None)
65+
# event.end = d.get('end', None)
6166

6267
rrule = dateutil.rrule.rrule(
6368
freq=interval_type[interval_measure],
64-
until=repeat.get('until'),
65-
dtstart=d['begin']
69+
until=repeat.get("until"),
70+
dtstart=d["begin"],
6671
)
6772

68-
rrule_lines = str(rrule).split('\n')
69-
rrule_dtstart = [line for line in rrule_lines if line.startswith('DTSTART')][0]
70-
rrule_dtstart = rrule_dtstart + 'Z'
71-
rrule_rrule = [line for line in rrule_lines if line.startswith('RRULE')][0]
72-
event.extra.append(ics.ContentLine(
73-
name=rrule_rrule.split(':', 1)[0],
74-
value=rrule_rrule.split(':', 1)[1],
75-
))
73+
rrule_lines = str(rrule).split("\n")
74+
rrule_dtstart = [line for line in rrule_lines if line.startswith("DTSTART")][0]
75+
rrule_dtstart = rrule_dtstart + "Z"
76+
rrule_rrule = [line for line in rrule_lines if line.startswith("RRULE")][0]
77+
event.extra.append(
78+
ics.ContentLine(
79+
name=rrule_rrule.split(":", 1)[0],
80+
value=rrule_rrule.split(":", 1)[1],
81+
)
82+
)
7683

7784
event.dtstamp = datetime.utcnow().replace(tzinfo=dateutil.tz.UTC)
7885
if tz and event.floating and not event.all_day:
@@ -86,34 +93,34 @@ def events_to_calendar(events: list) -> str:
8693
cal.events.append(event)
8794
return cal
8895

96+
8997
def files_to_calendar(files: list) -> ics.Calendar:
9098
"""'main' function: list of files to our result"""
91-
all_events = [ ]
92-
name = None
99+
all_events = []
93100
for f in files:
94-
if hasattr(f, 'read'):
101+
if hasattr(f, "read"):
95102
calendar_yaml = yaml.load(f.read(), Loader=yaml.FullLoader)
96103
else:
97-
calendar_yaml = yaml.load(open(f, 'r'), Loader=yaml.FullLoader)
104+
calendar_yaml = yaml.load(open(f, "r"), Loader=yaml.FullLoader)
98105
tz = None
99-
if 'meta' in calendar_yaml:
100-
if 'tz' in calendar_yaml['meta']:
101-
tz = gettz(calendar_yaml['meta']['tz'])
102-
for event in calendar_yaml['events']:
106+
if "meta" in calendar_yaml:
107+
if "tz" in calendar_yaml["meta"]:
108+
tz = gettz(calendar_yaml["meta"]["tz"])
109+
for event in calendar_yaml["events"]:
103110
all_events.append(event_from_yaml(event, tz=tz))
104111
calendar = events_to_calendar(all_events)
105112
return calendar
106113

107114

108-
if __name__ == '__main__':
115+
if __name__ == "__main__":
109116
if len(sys.argv) < 2:
110-
print('Usage: yaml2ics.py FILE1.yaml FILE2.yaml ...')
117+
print("Usage: yaml2ics.py FILE1.yaml FILE2.yaml ...")
111118
sys.exit(-1)
112119

113120
files = sys.argv[1:]
114121
for f in files:
115122
if not os.path.isfile(f):
116-
print(f'Error: {f} is not a file', file=sys.stderr)
123+
print(f"Error: {f} is not a file", file=sys.stderr)
117124
sys.exit(-1)
118125

119126
calendar = files_to_calendar(files)

0 commit comments

Comments
 (0)