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
|
package ical
import (
"errors"
"strconv"
"strings"
"time"
"github.com/LMBishop/confplanner/pkg/database/sqlc"
"github.com/LMBishop/confplanner/pkg/favourites"
"github.com/LMBishop/confplanner/pkg/schedule"
"github.com/microcosm-cc/bluemonday"
)
type Service interface {
GenerateIcalForCalendar(calendar sqlc.Calendar) (string, error)
}
var (
ErrImproperType = errors.New("improper type")
ErrNotFound = errors.New("not found")
)
type service struct {
favouritesService favourites.Service
scheduleService schedule.Service
}
func NewService(
favouritesService favourites.Service,
scheduleService schedule.Service,
) Service {
return &service{
favouritesService: favouritesService,
scheduleService: scheduleService,
}
}
func (s *service) GenerateIcalForCalendar(calendar sqlc.Calendar) (string, error) {
favourites, err := s.favouritesService.GetFavouritesForUser(calendar.UserID)
if err != nil {
return "", err
}
events := make([]schedule.Event, 0)
for _, favourite := range *favourites {
event := s.scheduleService.GetEventByID(favourite.EventID.Int32)
events = append(events, *event)
}
now := time.Now()
counter := 0
// https://www.rfc-editor.org/rfc/rfc5545.html
ret := "BEGIN:VCALENDAR\r\n"
ret += "PRODID:-//LMBishop//confplanner//EN\r\n"
ret += "VERSION:2.0\r\n"
ret += "METHOD:PUBLISH\r\n"
ret += "X-WR-CALNAME:confplanner calendar\r\n"
for _, event := range events {
utcStart := event.Start.UTC()
utcEnd := event.End.UTC()
ret += "BEGIN:VEVENT\r\n"
ret += "SUMMARY:" + event.Title + "\r\n"
ret += "UID:" + now.Format("20060102T150405Z") + "-" + strconv.Itoa(counter) + "\r\n"
ret += "DTSTAMP:" + now.Format("20060102T150405Z") + "\r\n"
ret += "DTSTART:" + utcStart.Format("20060102T150405Z") + "\r\n"
ret += "DTEND:" + utcEnd.Format("20060102T150405Z") + "\r\n"
ret += "LOCATION:" + event.Room + "\r\n"
ret += "DESCRIPTION;ENCODING=QUOTED-PRINTABLE:" + bluemonday.StrictPolicy().Sanitize(strings.Replace(event.Abstract, "\n", "\\n\\n", -1)) + "\\n\\nconfplanner: last synchronised: " + now.Format(time.RFC1123) + "\r\n"
ret += "BEGIN:VALARM\r\n"
ret += "TRIGGER:-PT10M\r\n"
ret += "ACTION:AUDIO\r\n"
ret += "END:VALARM\r\n"
ret += "END:VEVENT\r\n"
counter++
}
ret += "END:VCALENDAR\r\n"
return ret, nil
}
|