diff --git a/backend/service/ical/icalFileGeneration.go b/backend/service/ical/icalFileGeneration.go index 47f41d9..833b44d 100644 --- a/backend/service/ical/icalFileGeneration.go +++ b/backend/service/ical/icalFileGeneration.go @@ -4,6 +4,7 @@ import ( "htwkalender/model" "htwkalender/service/functions" "htwkalender/service/names" + "strconv" "time" "github.com/jordic/goics" @@ -20,21 +21,30 @@ func (icalModel IcalModel) EmitICal() goics.Componenter { europeTime, _ := time.LoadLocation("Europe/Berlin") c := goics.NewComponent() c.SetType("VCALENDAR") + // PRODID is required by the standard + c.AddProperty("PRODID", "-//HTWK Kalender//htwkalender.de//DE") + c.AddProperty("VERSION", "2.0") - c.AddProperty("CALSCAL", "GREGORIAN") - c.AddProperty("TZID", "Europe/Berlin") + c.AddProperty("CALSCALE", "GREGORIAN") + c.AddProperty("TZID", "EUROPE/BERLIN") c.AddProperty("X-WR-CALNAME", "HTWK Kalender") - c.AddProperty("X-WR-TIMEZONE", "Europe/Berlin") - c.AddProperty("X-LIC-LOCATION", "Europe/Berlin") - for _, event := range icalModel.Events { + c.AddProperty("X-WR-TIMEZONE", "EUROPE/BERLIN") + c.AddProperty("X-LIC-LOCATION", "EUROPE/BERLIN") + //add v time zone + icalModel.vtimezone(c) + + var timeStamp = time.Now().Local().In(europeTime).Format("20060102T150405") + + for i, event := range icalModel.Events { mapEntry, mappingFound := icalModel.Mapping[event.UUID] s := goics.NewComponent() s.SetType("VEVENT") - k, v := goics.FormatDateTime("DTEND;TZID=Europe/Berlin", event.End.Time().Local().In(europeTime)) - s.AddProperty(k, v) - k, v = goics.FormatDateTime("DTSTART;TZID=Europe/Berlin", event.Start.Time().Local().In(europeTime)) - s.AddProperty(k, v) + + s.AddProperty(goics.FormatDateTime("DTSTAMP", time.Now().Local().In(europeTime))) + s.AddProperty("UID", strconv.FormatInt(int64(i), 16)+"-"+timeStamp+"@htwkalender.de") + s.AddProperty(goics.FormatDateTime("DTEND", event.End.Time().Local().In(europeTime))) + s.AddProperty(goics.FormatDateTime("DTSTART", event.Start.Time().Local().In(europeTime))) if mappingFound { addPropertyIfNotEmpty(s, "SUMMARY", replaceNameIfUserDefined(&event, mapEntry)) @@ -50,6 +60,45 @@ func (icalModel IcalModel) EmitICal() goics.Componenter { return c } +func (icalModel IcalModel) vtimezone(c *goics.Component) { + tz := goics.NewComponent() + tz.SetType("VTIMEZONE") + tz.AddProperty("TZID", "EUROPE/BERLIN") + tz.AddProperty("X-LIC-LOCATION", "EUROPE/BERLIN") + //add standard time + icalModel.standard(tz) + //add daylight time + icalModel.daylight(tz) + + c.AddComponent(tz) +} + +func (icalModel IcalModel) standard(tz *goics.Component) { + st := NewHtwkalenderComponent() + st.SetType("STANDARD") + st.AddProperty("DTSTART", "19701025T030000") + st.AddProperty("RRULE", "FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU") + + st.AddProperty("TZOFFSETFROM", "+0200") + st.AddProperty("TZOFFSETTO", "+0100") + st.AddProperty("TZNAME", "CET") + tz.AddComponent(st) +} + +// create an override for goics component function Write +// to add the RRULE property + +func (icalModel IcalModel) daylight(tz *goics.Component) { + dt := NewHtwkalenderComponent() + dt.SetType("DAYLIGHT") + dt.AddProperty("DTSTART", "19700329T020000") + dt.AddProperty("TZOFFSETFROM", "+0100") + dt.AddProperty("TZOFFSETTO", "+0200") + dt.AddProperty("TZNAME", "CEST") + dt.AddProperty("RRULE", "FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU") + tz.AddComponent(dt) +} + // if reminder is specified in the configuration for this event, an alarm will be added to the event func addAlarmIfSpecified(s *goics.Component, event model.Event, mapping model.FeedCollection) { if mapping.Reminder { diff --git a/backend/service/ical/icsComponenter.go b/backend/service/ical/icsComponenter.go new file mode 100644 index 0000000..b44c74a --- /dev/null +++ b/backend/service/ical/icsComponenter.go @@ -0,0 +1,46 @@ +package ical + +import ( + "github.com/jordic/goics" + "sort" + "strings" +) + +type HtwkalenderComponent struct { + *goics.Component +} + +func NewHtwkalenderComponent() *HtwkalenderComponent { + return &HtwkalenderComponent{ + Component: goics.NewComponent(), + } +} + +// Writes the component to the Writer +func (c *HtwkalenderComponent) Write(w *goics.ICalEncode) { + w.WriteLine("BEGIN:" + c.Tipo + goics.CRLF) + + // Iterate over component properties + var keys []string + for k := range c.Properties { + keys = append(keys, k) + } + sort.Strings(keys) + for _, key := range keys { + vals := c.Properties[key] + for _, val := range vals { + w.WriteLine(WriteStringField(key, val)) + } + } + + for _, xc := range c.Elements { + xc.Write(w) + } + + w.WriteLine("END:" + c.Tipo + goics.CRLF) +} + +// WriteStringField UID:asdfasdfаs@dfasdf.com +func WriteStringField(key string, val string) string { + return strings.ToUpper(key) + ":" + (val) + goics.CRLF +}