Files
helioscal/main.go

161 lines
3.1 KiB
Go
Raw Normal View History

2020-09-09 03:26:23 +00:00
package main
import (
"flag"
"io/ioutil"
"log"
"time"
"golang.org/x/oauth2/google"
"google.golang.org/api/calendar/v3"
)
var calName = flag.String("calendar", "", "name of calendar")
2020-09-09 03:53:12 +00:00
var days = flag.Int("days", 0, "number of days in the future")
2020-09-09 03:26:23 +00:00
func main() {
flag.Parse()
b, err := ioutil.ReadFile("credentials.json")
if err != nil {
log.Fatal(err)
}
// If modifying these scopes, delete your previously saved token.json.
config, err := google.ConfigFromJSON(b, calendar.CalendarScope)
if err != nil {
log.Fatal(err)
}
client, err := getClient(config)
if err != nil {
log.Fatal(err)
}
srv, err := calendar.New(client)
if err != nil {
log.Fatal(err)
}
calendars, err := srv.CalendarList.List().Do()
if err != nil {
log.Fatal(err)
}
var myCal *calendar.CalendarListEntry
for _, item := range calendars.Items {
if item.Summary == *calName {
myCal = item
break
}
}
if myCal == nil {
log.Fatalf("calendar '%s' not found", *calName)
}
loc, err := time.LoadLocation("US/Pacific")
if err != nil {
log.Fatal(err)
}
now := time.Now().In(loc)
2020-09-09 03:53:12 +00:00
for i := 0; i < *days; i++ {
date := now.Add(time.Duration(i * 24) * time.Hour)
2020-09-09 03:26:23 +00:00
2020-09-09 04:57:57 +00:00
eventMap, err := getDayEvents(srv, myCal.Id, date)
if err != nil {
log.Fatal(err)
}
2020-09-09 03:53:12 +00:00
for _, class := range classes {
2020-09-09 04:03:49 +00:00
if !class.happensOnDay(date) {
2020-09-09 03:53:12 +00:00
continue
2020-09-09 03:26:23 +00:00
}
2020-09-09 04:03:49 +00:00
ev := class.buildEvent(date)
2020-09-09 03:26:23 +00:00
2020-09-09 04:57:57 +00:00
old := eventMap[ev.Summary]
if old == nil {
log.Printf("add: [%s] %s", ev.Start.DateTime, ev.Summary)
_, err := srv.Events.Insert(myCal.Id, ev).Do()
if err != nil {
log.Fatal(err)
}
} else {
if !eventsEqual(old, ev) {
log.Printf("upd: [%s] %s", ev.Start.DateTime, ev.Summary)
_, err := srv.Events.Update(myCal.Id, old.Id, ev).Do()
if err != nil {
log.Fatal(err)
}
}
2020-09-09 03:53:12 +00:00
}
2020-09-09 03:26:23 +00:00
}
}
2020-09-09 04:57:57 +00:00
}
func getDayEvents(srv *calendar.Service, calendarId string, t time.Time) (map[string]*calendar.Event, error) {
start := time.Date(
t.Year(),
t.Month(),
t.Day(),
0, 0, 0, 0,
t.Location())
// This may be wrong for DST changes, but it's the middle of the night and probably doesn't matter
end := start.Add(24 * time.Hour)
events, err := srv.Events.List(calendarId).
ShowDeleted(false).
SingleEvents(true).
TimeMin(start.Format(time.RFC3339)).
TimeMax(end.Format(time.RFC3339)).
MaxResults(250).
Do()
if err != nil {
return nil, err
}
2020-09-09 03:26:23 +00:00
2020-09-09 04:57:57 +00:00
eventMap := map[string]*calendar.Event{}
2020-09-09 03:26:23 +00:00
2020-09-09 04:57:57 +00:00
for _, item := range events.Items {
eventMap[item.Summary] = item
2020-09-09 03:26:23 +00:00
}
2020-09-09 04:57:57 +00:00
return eventMap, nil
}
func eventsEqual(a *calendar.Event, b *calendar.Event) bool {
if a.Summary != b.Summary {
return false
2020-09-09 03:26:23 +00:00
}
2020-09-09 04:57:57 +00:00
if a.Description != b.Description {
return false
}
2020-09-09 03:26:23 +00:00
2020-09-09 04:57:57 +00:00
if a.Start.DateTime[:19] != b.Start.DateTime[:19] {
return false
2020-09-09 03:26:23 +00:00
}
2020-09-09 04:57:57 +00:00
if a.End.DateTime[:19] != b.End.DateTime[:19] {
return false
}
if len(a.Attendees) != len(b.Attendees) {
return false
}
emails := map[string]bool{}
for _, attendee := range a.Attendees {
emails[attendee.Email] = true
}
for _, attendee := range b.Attendees {
if !emails[attendee.Email] {
return false
2020-09-09 03:26:23 +00:00
}
}
2020-09-09 04:57:57 +00:00
return true
2020-09-09 03:26:23 +00:00
}