gcal refreshes next event list every 13m
parent
ca20b2a052
commit
f1846ed93c
1
gcal.go
1
gcal.go
|
|
@ -36,6 +36,7 @@ func (gcal *GCal) EventsToday(ctx context.Context) ([]Event, error) {
|
||||||
|
|
||||||
today := time.Now().Add(-1 * time.Hour * time.Duration(time.Now().Hour()))
|
today := time.Now().Add(-1 * time.Hour * time.Duration(time.Now().Hour()))
|
||||||
tomorrow := today.Add(24 * time.Hour)
|
tomorrow := today.Add(24 * time.Hour)
|
||||||
|
|
||||||
events, err := srv.Events.
|
events, err := srv.Events.
|
||||||
List("primary").
|
List("primary").
|
||||||
ShowDeleted(false).
|
ShowDeleted(false).
|
||||||
|
|
|
||||||
105
main.go
105
main.go
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -27,53 +28,93 @@ func main() {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if *gcal {
|
alerts, err := alerts(ctx, *gcal, fs.Args())
|
||||||
if err := alertGCal(ctx, *ntfy); err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if err := alertAfter(ctx, *ntfy, fs.Args()[0]); err != nil {
|
for alert := range alerts {
|
||||||
|
if err := alertAt(ctx, *ntfy, time.Now(), alert, time.Now().Format("15:04")); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func alertGCal(ctx context.Context, ntfy string) error {
|
func alerts(ctx context.Context, gcal bool, args []string) (chan string, error) {
|
||||||
|
if gcal {
|
||||||
|
return alertsGCal(ctx)
|
||||||
|
}
|
||||||
|
duration, err := time.ParseDuration(args[0])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return alertsAfter(ctx, duration)
|
||||||
|
}
|
||||||
|
|
||||||
|
func alertsAfter(ctx context.Context, dur time.Duration) (chan string, error) {
|
||||||
|
ch := make(chan string)
|
||||||
|
go func() {
|
||||||
|
defer close(ch)
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
case <-time.After(dur):
|
||||||
|
}
|
||||||
|
ch <- "alerting after " + dur.String()
|
||||||
|
}()
|
||||||
|
return ch, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func alertsGCal(ctx context.Context) (chan string, error) {
|
||||||
gcal := NewGCal()
|
gcal := NewGCal()
|
||||||
if err := gcal.Login(ctx); err != nil {
|
if err := gcal.Login(ctx); err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
events, err := gcal.EventsToday(ctx)
|
var events []Event
|
||||||
if err != nil {
|
refresh := func() error {
|
||||||
return err
|
es, err := gcal.EventsToday(ctx)
|
||||||
}
|
es = slices.DeleteFunc(es, func(s Event) bool {
|
||||||
|
return time.Now().After(s.Time)
|
||||||
for _, event := range events {
|
})
|
||||||
until := event.Time.Add(-1 * time.Minute)
|
if !slices.Equal(es, events) {
|
||||||
if until.Sub(time.Now()) < 1 {
|
events = es
|
||||||
continue
|
if len(events) > 0 {
|
||||||
|
log.Println("alerting about", events[0].Name, "at", events[0].Time.Format("15:04"), "(", time.Until(events[0].Time), ")")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("alerting about", event.Name, "at", until.Format("15:04"), "(", time.Until(until), ")")
|
|
||||||
if err := alertAt(ctx, ntfy, until, event.Name, until.Format("15:04")); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func alertAfter(ctx context.Context, ntfy string, duration string) error {
|
|
||||||
d, err := time.ParseDuration(duration)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return alertAt(ctx, ntfy, time.Now().Add(d), os.Args[0], "alerting after "+d.String())
|
if err := refresh(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ch := make(chan string)
|
||||||
|
go func() {
|
||||||
|
defer close(ch)
|
||||||
|
|
||||||
|
c := time.NewTicker(time.Minute * 13)
|
||||||
|
defer c.Stop()
|
||||||
|
for ctx.Err() == nil && len(events) > 0 {
|
||||||
|
select {
|
||||||
|
case <-c.C:
|
||||||
|
if err := refresh(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
case <-time.After(time.Until(events[0].Time.Add(-2 * time.Minute))):
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
case ch <- events[0].Name:
|
||||||
|
}
|
||||||
|
events = events[1:]
|
||||||
|
case <-ctx.Done():
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return ch, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func alertAt(ctx context.Context, ntfy string, deadline time.Time, title, msg string) error {
|
func alertAt(ctx context.Context, ntfy string, deadline time.Time, title, msg string) error {
|
||||||
// n := int64(time.Until(deadline) / time.Second)
|
|
||||||
c := time.NewTicker(time.Second)
|
c := time.NewTicker(time.Second)
|
||||||
defer c.Stop()
|
defer c.Stop()
|
||||||
func() {
|
func() {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue