1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
#!/usr/bin/env python3
#
# Converts output of remind to ICS format:
#
# Usage example: rem -ppp12 | rem2ics
#
# https://tools.ietf.org/html/rfc5545
import datetime
import json
import sys
from datetime import datetime, timedelta, timezone
from os.path import basename, splitext
class Event:
def __init__(self, uid, event_json):
self.event_json = event_json
self.uid = uid
def summary(self):
e = self.event_json
summary = e.get('body', '').replace(r'%"', '')
if 'time' in e:
summary = summary.split(' ', 1)[1]
if 'passthru' in e and 'COLOR' in e['passthru']:
summary = ' '.join(summary.split(' ')[3:])
return summary
def categories(self):
filename = basename(self.event_json['filename'].upper())
return splitext(filename)[0]
def dtstart(self):
e = self.event_json
if 'eventstart' in e:
dt = datetime.strptime(e['eventstart'], '%Y-%m-%dT%H:%M')
return self.__datetime_format(dt)
return e['date'].replace('-', '')
def dtend(self):
e = self.event_json
if 'rep' in e and 'until' in e:
dt = datetime.strptime(e['until'], '%Y-%m-%d')
return (dt + timedelta(days=1)).strftime('%Y%m%d')
elif 'eventduration' in e and 'eventstart' in e:
dt = datetime.strptime(e['eventstart'], '%Y-%m-%dT%H:%M')
return self.__datetime_format(dt + timedelta(minutes=int(e['eventduration'])))
return self.dtstart()
@staticmethod
def __datetime_format(dt):
return dt.astimezone(timezone.utc).strftime('%Y%m%dT%H%M%SZ')
def create_uid(event):
if 'rep' in event and 'until' in event:
date = event['until']
else:
date = event['date']
return "%s:%s:%s" % (basename(event['filename']), event['lineno'], date)
def print_ics(events):
print('BEGIN:VCALENDAR')
print('VERSION:2.0')
for event in events:
print('BEGIN:VEVENT')
print('UID:%s' % event.uid)
print('DTSTART:%s' % event.dtstart())
print('DTEND:%s' % event.dtend())
print('SUMMARY:%s' % event.summary())
print('CATEGORIES:%s' % event.categories())
print('END:VEVENT')
print('END:VCALENDAR')
def rem2ics():
added = set()
events = []
data = json.load(sys.stdin)
for month in data:
for event_json in month['entries']:
uid = create_uid(event_json)
if uid in added:
continue
added.add(uid)
events.append(Event(uid, event_json))
print_ics(events)
if __name__ == '__main__':
rem2ics()
|