-
Notifications
You must be signed in to change notification settings - Fork 1
/
ical.go
117 lines (99 loc) · 2.79 KB
/
ical.go
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package server
import (
"sort"
"time"
ics "github.com/arran4/golang-ical"
)
func getDownstreamCalendar(upstream *ics.Calendar, opts calenderOptions) *ics.Calendar {
downstream := ics.NewCalendar()
for _, component := range upstream.Components {
if _, ok := component.(*ics.VEvent); ok {
continue
}
downstream.Components = append(downstream.Components, component)
}
downstream.CalendarProperties = upstream.CalendarProperties
includes := opts.includes
if len(opts.includes) == 0 {
includes = defaultMatches
}
var events []*ics.VEvent
for _, event := range upstream.Events() {
if includes.matches(event) && !opts.excludes.matches(event) {
events = append(events, event)
}
}
sort.SliceStable(events, func(i, j int) bool {
startI, _ := events[i].GetStartAt()
startJ, _ := events[j].GetStartAt()
return startI.Before(startJ)
})
if opts.merge {
events = mergeEvents(events)
}
for _, event := range events {
downstream.AddVEvent(event)
}
return downstream
}
// mergeEvents will perform the merge algorithm on a slice of events sorted by
// start time.
func mergeEvents(events []*ics.VEvent) []*ics.VEvent {
var (
newEvents []*ics.VEvent
lastEndTime time.Time
)
for _, event := range events {
startTime, _ := event.GetStartAt()
endTime, _ := event.GetEndAt()
if endTime.Before(startTime) {
endTime = startTime
}
if len(newEvents) == 0 || !startTime.Before(lastEndTime) {
lastEndTime = endTime
newEvents = append(newEvents, event)
continue
}
lastEvent := newEvents[len(newEvents)-1]
lastSummary := lastEvent.GetProperty(ics.ComponentPropertySummary)
newSummary := ""
if lastSummary != nil {
newSummary = lastSummary.Value
}
summary := event.GetProperty(ics.ComponentPropertySummary)
if summary != nil {
newSummary += " + "
newSummary += summary.Value
}
lastEvent.SetSummary(newSummary)
lastDescription := lastEvent.GetProperty(ics.ComponentPropertyDescription)
newDescription := ""
if lastDescription != nil {
newDescription = lastDescription.Value
}
description := event.GetProperty(ics.ComponentPropertyDescription)
if description != nil {
newDescription += "\n\n---\n"
if summary != nil {
newDescription += summary.Value + "\n"
}
newDescription += "\n"
newDescription += description.Value
}
if newDescription != "" {
lastEvent.SetProperty(ics.ComponentPropertyDescription, newDescription)
}
if endTime.After(lastEndTime) {
var props []ics.PropertyParameter
for k, v := range event.GetProperty(ics.ComponentPropertyDtEnd).ICalParameters {
props = append(props, &ics.KeyValues{
Key: k,
Value: v,
})
}
lastEvent.SetProperty(ics.ComponentPropertyDtEnd, event.GetProperty(ics.ComponentPropertyDtEnd).Value, props...)
lastEndTime = endTime
}
}
return newEvents
}