calnow/main.go
2024-11-23 13:06:38 -07:00

194 lines
3.8 KiB
Go

package main
import (
"context"
"flag"
"log"
"net/http"
"os"
"slices"
"time"
"github.com/emersion/go-webdav"
"github.com/emersion/go-webdav/caldav"
"github.com/sosodev/duration"
)
const (
fullTimeFmt = "20060102T150405"
fullFimeTmt = "20060102T150405"
)
var (
debug = false
)
func msg(fmt string, args ...any) {
if debug {
log.Printf(fmt, args...)
}
}
func between(now, begin, end time.Time) bool {
return now.After(begin) && now.Before(end)
}
func fixDate(a, b time.Time) time.Time {
return time.Date(
a.Year(),
a.Month(),
a.Day(),
a.Hour(),
a.Minute(),
a.Second(),
a.Nanosecond(),
b.Location(),
)
}
func main() {
flag.BoolVar(&debug, "debug", false, "print debug messages")
flag.Parse()
username := os.Getenv("CALNOW_USER")
serverURL := os.Getenv("CALNOW_URL")
password := os.Getenv("CALNOW_PASS")
if username == "" || password == "" {
log.Fatal("Please set CALNOW_USER and CALNOW_PASS environment variables")
}
client, err := caldav.NewClient(webdav.HTTPClientWithBasicAuth(
&http.Client{},
username,
password,
), serverURL)
if err != nil {
log.Fatal("Failed to create client:", err)
}
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
princ, err := client.FindCurrentUserPrincipal(ctx)
homeSets, err := client.FindCalendarHomeSet(ctx, princ)
if err != nil {
log.Fatal("Failed to find home set:", err)
}
calendars, err := client.FindCalendars(ctx, homeSets)
if err != nil {
log.Printf("Failed to find calendars for home set %s: %v", homeSets, err)
}
now := time.Now()
start := time.Date(
now.Year(),
now.Month(),
now.Day(),
0, 0, 1, 0,
now.Location(),
)
end := time.Date(
now.Year(),
now.Month(),
now.Day(),
23, 59, 59, 999999999,
now.Location(),
)
for _, cal := range calendars {
if !slices.Contains(cal.SupportedComponentSet, "VEVENT") {
continue
}
path := cal.Path
query := &caldav.CalendarQuery{
CompRequest: caldav.CalendarCompRequest{
Name: "VCALENDAR",
Comps: []caldav.CalendarCompRequest{{
Name: "VEVENT",
Props: []string{
"SUMMARY",
"UID",
"DTSTART",
"DTEND",
"DURATION",
},
}},
},
CompFilter: caldav.CompFilter{
Name: "VCALENDAR",
Comps: []caldav.CompFilter{{
Name: "VEVENT",
Start: start,
End: end,
}},
},
}
events, err := client.QueryCalendar(ctx, path, query)
if err != nil {
continue
}
for _, e := range events {
for i := range e.Data.Children {
sum := e.Data.Children[i].Props.Get("SUMMARY")
end := e.Data.Children[i].Props.Get("DTEND")
dur := e.Data.Children[i].Props.Get("DURATION")
begin := e.Data.Children[i].Props.Get("DTSTART")
if sum != nil {
msg("%s:%s", cal.Name, sum.Value)
}
if begin == nil && dur == nil {
continue
}
if end != nil {
endTime, err := time.Parse(fullTimeFmt, end.Value)
if err != nil {
continue
}
beginTime, err := time.Parse(fullTimeFmt, begin.Value)
if err != nil {
continue
}
endTime = fixDate(endTime, now)
beginTime = fixDate(beginTime, now)
msg("%s <%s> %s, between: %t", beginTime, now, endTime, between(now, beginTime, endTime))
if between(now, beginTime, endTime) {
os.Exit(0)
}
}
if dur != nil && begin != nil {
beginTime, err := time.Parse(fullTimeFmt, begin.Value)
if err != nil {
continue
}
eDur, err := duration.Parse(dur.Value)
if err != nil {
continue
}
endTime := beginTime.Add(eDur.ToTimeDuration())
endTime = fixDate(endTime, now)
beginTime = fixDate(beginTime, now)
msg("%s <%s> %s, between: %t", beginTime, now, endTime, between(now, beginTime, endTime))
if between(now, beginTime, endTime) {
os.Exit(0)
}
}
}
}
}
os.Exit(1)
}