summaryrefslogtreecommitdiff
path: root/rem2ics
blob: 895277155437a835acb70b44b78dbc4d834bb5a1 (plain) (blame)
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()