aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/ical/service.go
diff options
context:
space:
mode:
authorLeonardo Bishop <me@leonardobishop.com>2025-01-20 02:56:25 +0000
committerLeonardo Bishop <me@leonardobishop.com>2025-01-20 02:56:25 +0000
commitdc55f9c0097e1c36b85d7666071b840b902920e9 (patch)
treec8c8ae10a9e134810b3361aabc8a9d426d813808 /pkg/ical/service.go
parent5e7ce6cbae81a1b6e46fe6738dc10039a06bec95 (diff)
Add calendar support
Diffstat (limited to 'pkg/ical/service.go')
-rw-r--r--pkg/ical/service.go78
1 files changed, 78 insertions, 0 deletions
diff --git a/pkg/ical/service.go b/pkg/ical/service.go
new file mode 100644
index 0000000..2b89fe7
--- /dev/null
+++ b/pkg/ical/service.go
@@ -0,0 +1,78 @@
+package ical
+
+import (
+ "errors"
+ "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
+ }
+
+ sched, _, err := s.scheduleService.GetSchedule()
+ 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()
+
+ // https://www.rfc-editor.org/rfc/rfc5545.html
+
+ ret := "BEGIN:VCALENDAR\n"
+ ret += "VERSION:2.0\n"
+ ret += "METHOD:PUBLISH\n"
+ ret += "X-WR-CALNAME:confplanner calendar\n"
+ for _, event := range events {
+ utcStart := event.Start.UTC()
+ utcEnd := event.End.UTC()
+
+ ret += "BEGIN:VEVENT\n"
+ ret += "SUMMARY:" + event.Title + "\n"
+ ret += "DTSTART;TZID=" + sched.Conference.TimeZoneName + ":" + utcStart.Format("20060102T150405Z") + "\n"
+ ret += "DTEND;TZID=" + sched.Conference.TimeZoneName + ":" + utcEnd.Format("20060102T150405Z") + "\n"
+ ret += "LOCATION:" + event.Room + "\n"
+ ret += "DESCRIPTION;ENCODING=QUOTED-PRINTABLE:" + bluemonday.StrictPolicy().Sanitize(strings.Replace(event.Abstract, "\n", "\\n", -1)) + "\\nLast Synchronised: " + now.Format(time.DateTime) + "\n"
+ ret += "END:VEVENT\n"
+ }
+ ret += "END:VCALENDAR\n"
+
+ return ret, nil
+}