75 lines
1.5 KiB
Go
75 lines
1.5 KiB
Go
|
package calendar
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"fmt"
|
||
|
"text/template"
|
||
|
"time"
|
||
|
|
||
|
"kumoly.io/kumoly/app/store"
|
||
|
)
|
||
|
|
||
|
const ics_base = `BEGIN:VCALENDAR
|
||
|
PRODID:-//Kumoly//Kumoly App v0.0.1//EN
|
||
|
VERSION:2.0
|
||
|
CALSCALE:GREGORIAN
|
||
|
METHOD:PUBLISH
|
||
|
X-WR-CALNAME:{{.Name}}
|
||
|
X-WR-TIMEZONE:Asia/Taipei
|
||
|
X-WR-CALDESC:{{.Name}}
|
||
|
BEGIN:VTIMEZONE
|
||
|
TZID:{{.Timezone}}
|
||
|
X-LIC-LOCATION:{{.Timezone}}
|
||
|
BEGIN:STANDARD
|
||
|
TZOFFSETFROM:+0800
|
||
|
TZOFFSETTO:+0800
|
||
|
TZNAME:CST
|
||
|
DTSTART:19700101T000000
|
||
|
END:STANDARD
|
||
|
END:VTIMEZONE
|
||
|
{{with .Events}}{{ if gt (len .) 0 }}{{ range $event := . }}
|
||
|
BEGIN:VEVENT
|
||
|
DTSTART:{{$event.Start|icstime}}
|
||
|
DTEND:{{$event.End|icstime}}
|
||
|
DTSTAMP:{{now|icstime}}
|
||
|
UID:{{$event.ID}}
|
||
|
CREATED:{{$event.CreatedAt|icstime}}
|
||
|
DESCRIPTION:{{$event.ID}}
|
||
|
LAST-MODIFIED:{{$event.UpdatedAt|icstime}}
|
||
|
LOCATION:{{$event.Location}}
|
||
|
SEQUENCE:0
|
||
|
STATUS:CONFIRMED
|
||
|
SUMMARY:{{$event.Name}}
|
||
|
TRANSP:TRANSPARENT
|
||
|
END:VEVENT
|
||
|
{{end}}{{end}}{{end}}
|
||
|
END:VCALENDAR`
|
||
|
|
||
|
var tmpl *template.Template
|
||
|
|
||
|
func init() {
|
||
|
tmpl = template.Must(template.New("").Funcs(template.FuncMap{
|
||
|
"icstime": icstime,
|
||
|
"now": func() time.Time { return time.Now() },
|
||
|
}).Parse(ics_base))
|
||
|
}
|
||
|
|
||
|
func ICS(cal_id string, from time.Time, to time.Time) (string, error) {
|
||
|
cal := &Calendar{}
|
||
|
store.DB.Preload("Events", "start > ? and end < ?", from, to).
|
||
|
First(cal, "id = ?", cal_id)
|
||
|
buf := &bytes.Buffer{}
|
||
|
if err := tmpl.Execute(buf, cal); err != nil {
|
||
|
return "", err
|
||
|
}
|
||
|
return buf.String(), nil
|
||
|
}
|
||
|
|
||
|
func icstime(t time.Time) string {
|
||
|
return t.UTC().Format("20060102T150405Z")
|
||
|
}
|
||
|
|
||
|
func offsetStr(offset int) string {
|
||
|
return fmt.Sprintf("%+05d", offset/36)
|
||
|
}
|