Refactor calendar code
This commit is contained in:
185
calendar.go
Normal file
185
calendar.go
Normal file
@@ -0,0 +1,185 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"golang.org/x/oauth2/google"
|
||||
"google.golang.org/api/calendar/v3"
|
||||
)
|
||||
|
||||
var _globalCalService *calendar.Service
|
||||
|
||||
func getCalService() *calendar.Service {
|
||||
if _globalCalService != nil {
|
||||
return _globalCalService
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
_globalCalService, err := calendar.New(client)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
return _globalCalService
|
||||
}
|
||||
|
||||
func getCalendarId(calName string) (string, error) {
|
||||
client := getCalService()
|
||||
|
||||
calendars, err := client.CalendarList.List().Do()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for _, item := range calendars.Items {
|
||||
if item.Summary == calName {
|
||||
return item.Id, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("calendar '%s' not found", calName)
|
||||
}
|
||||
|
||||
func updateCalendar(calName string, classes []Class, days int) error {
|
||||
loc, err := time.LoadLocation("US/Pacific")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
now := time.Now().In(loc)
|
||||
|
||||
calId, err := getCalendarId(calName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := 0; i < days; i++ {
|
||||
date := now.Add(time.Duration(i * 24) * time.Hour)
|
||||
err = updateDay(calId, date, classes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func updateDay(calId string, date time.Time, classes []Class) error {
|
||||
eventMap, err := getDayEvents(calId, date)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, class := range classes {
|
||||
if !class.happensOnDay(date) {
|
||||
continue
|
||||
}
|
||||
|
||||
if !class.tagsMatch(date) {
|
||||
continue
|
||||
}
|
||||
|
||||
ev := class.buildEvent(date)
|
||||
|
||||
old := eventMap[ev.Summary]
|
||||
|
||||
if old == nil {
|
||||
log.Printf("add: [%s] %s", ev.Start.DateTime, ev.Summary)
|
||||
_, err := getCalService().Events.Insert(calId, ev).Do()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if !eventsEqual(old, ev) {
|
||||
log.Printf("upd: [%s] %s", ev.Start.DateTime, ev.Summary)
|
||||
_, err := getCalService().Events.Update(calId, old.Id, ev).Do()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getDayEvents(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 := getCalService().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
|
||||
}
|
||||
|
||||
eventMap := map[string]*calendar.Event{}
|
||||
|
||||
for _, item := range events.Items {
|
||||
eventMap[item.Summary] = item
|
||||
}
|
||||
|
||||
return eventMap, nil
|
||||
}
|
||||
|
||||
func eventsEqual(a *calendar.Event, b *calendar.Event) bool {
|
||||
if a.Summary != b.Summary {
|
||||
return false
|
||||
}
|
||||
|
||||
if a.Description != b.Description {
|
||||
return false
|
||||
}
|
||||
|
||||
if a.Start.DateTime[:19] != b.Start.DateTime[:19] {
|
||||
return false
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
322
classes.go
322
classes.go
@@ -30,176 +30,178 @@ var tags = TagMap{
|
||||
},
|
||||
}
|
||||
|
||||
var classes = []Class {
|
||||
Class{
|
||||
Summary: "👋 Morning Circle",
|
||||
Start: "08:30",
|
||||
End: "09:00",
|
||||
Days: weekDaysButFriday,
|
||||
Zoom: "https://us02web.zoom.us/j/2274643506?pwd=Nm5NUXMwOVJKbEUzNE5VSkZCQzJ2UT09",
|
||||
},
|
||||
Class{
|
||||
Summary: "🏫 Community Meeting",
|
||||
Start: "08:30",
|
||||
End: "09:00",
|
||||
Days: []time.Weekday{time.Friday},
|
||||
Zoom: "https://zoom.us/j/96371462107",
|
||||
},
|
||||
Class{
|
||||
Summary: "🔢 Math (Claudia & Rachel)",
|
||||
Start: "09:00",
|
||||
End: "09:40",
|
||||
Days: weekDays,
|
||||
Zoom: "https://us02web.zoom.us/j/2274643506?pwd=Nm5NUXMwOVJKbEUzNE5VSkZCQzJ2UT09",
|
||||
Students: []string{
|
||||
"adabelle.pratt@heliosns.org",
|
||||
"oliver.park@heliosns.org",
|
||||
var classes = map[string][]Class {
|
||||
"Hummingbirds Classes": []Class {
|
||||
Class{
|
||||
Summary: "👋 Morning Circle",
|
||||
Start: "08:30",
|
||||
End: "09:00",
|
||||
Days: weekDaysButFriday,
|
||||
Zoom: "https://us02web.zoom.us/j/2274643506?pwd=Nm5NUXMwOVJKbEUzNE5VSkZCQzJ2UT09",
|
||||
},
|
||||
},
|
||||
Class{
|
||||
Summary: "💭 Dreambox",
|
||||
Start: "09:40",
|
||||
End: "10:00",
|
||||
Days: weekDays,
|
||||
},
|
||||
Class{
|
||||
Summary: "🐛 Theme",
|
||||
Start: "10:30",
|
||||
End: "11:30",
|
||||
Days: weekDaysButFriday,
|
||||
Zoom: "https://us02web.zoom.us/j/2274643506?pwd=Nm5NUXMwOVJKbEUzNE5VSkZCQzJ2UT09",
|
||||
},
|
||||
Class{
|
||||
Summary: "❤️ SEL",
|
||||
Start: "10:30",
|
||||
End: "11:15",
|
||||
Days: []time.Weekday{time.Friday},
|
||||
Zoom: "https://us02web.zoom.us/j/2274643506?pwd=Nm5NUXMwOVJKbEUzNE5VSkZCQzJ2UT09",
|
||||
},
|
||||
Class{
|
||||
Summary: "📖 Literacy (Green)",
|
||||
Start: "11:30",
|
||||
End: "12:00",
|
||||
Days: []time.Weekday{time.Monday, time.Wednesday},
|
||||
Zoom: "https://us02web.zoom.us/j/2274643506?pwd=Nm5NUXMwOVJKbEUzNE5VSkZCQzJ2UT09",
|
||||
Students: greenStudents,
|
||||
},
|
||||
Class{
|
||||
Summary: "🤸 PE (Yellow/Green)",
|
||||
Start: "11:30",
|
||||
End: "12:00",
|
||||
Days: []time.Weekday{time.Tuesday},
|
||||
Zoom: "https://zoom.us/j/97472507748?pwd=cW5vUFhyUjNTS2toWlZGN254U1ZqZz09",
|
||||
Students: greenStudents,
|
||||
},
|
||||
Class{
|
||||
Summary: "💡 iLab (Yellow/Green)",
|
||||
Start: "11:30",
|
||||
End: "12:00",
|
||||
Days: []time.Weekday{time.Thursday},
|
||||
Zoom: "https://us02web.zoom.us/j/86403635026?pwd=S2t1WkN2dnNJZlFkejdEbjRsUmNNUT09",
|
||||
Students: greenStudents,
|
||||
},
|
||||
Class{
|
||||
Summary: "📚 Library",
|
||||
Start: "11:30",
|
||||
End: "12:00",
|
||||
Days: []time.Weekday{time.Friday},
|
||||
Zoom: "https://us02web.zoom.us/my/helioslibrary?pwd=cWd4RjNqNXZXNjRjM2dYQVhYeS9Xdz09",
|
||||
},
|
||||
Class{
|
||||
Summary: "🇲🇽 Spanish",
|
||||
Start: "12:45",
|
||||
End: "13:30",
|
||||
Days: []time.Weekday{time.Monday, time.Tuesday, time.Wednesday},
|
||||
Zoom: "https://zoom.us/j/95144364579?pwd=cGdwNTZIOE42Y0syeVcwVEFhZ1JxZz09",
|
||||
Students: []string{
|
||||
"oliver.park@heliosns.org",
|
||||
Class{
|
||||
Summary: "🏫 Community Meeting",
|
||||
Start: "08:30",
|
||||
End: "09:00",
|
||||
Days: []time.Weekday{time.Friday},
|
||||
Zoom: "https://zoom.us/j/96371462107",
|
||||
},
|
||||
},
|
||||
Class{
|
||||
Summary: "🎨 Art",
|
||||
Start: "12:45",
|
||||
End: "13:30",
|
||||
Days: []time.Weekday{time.Monday, time.Tuesday, time.Wednesday},
|
||||
Zoom: "https://us02web.zoom.us/j/86969790982?pwd=TEMraThVbHhMUlBHUjFZYXZVRnpFQT09",
|
||||
Students: []string{
|
||||
"adabelle.pratt@heliosns.org",
|
||||
Class{
|
||||
Summary: "🔢 Math (Claudia & Rachel)",
|
||||
Start: "09:00",
|
||||
End: "09:40",
|
||||
Days: weekDays,
|
||||
Zoom: "https://us02web.zoom.us/j/2274643506?pwd=Nm5NUXMwOVJKbEUzNE5VSkZCQzJ2UT09",
|
||||
Students: []string{
|
||||
"adabelle.pratt@heliosns.org",
|
||||
"oliver.park@heliosns.org",
|
||||
},
|
||||
},
|
||||
},
|
||||
Class{
|
||||
Summary: "🎶 Music & Movement (Blue/Green)",
|
||||
Start: "12:45",
|
||||
End: "13:30",
|
||||
Days: []time.Weekday{time.Friday},
|
||||
Zoom: "https://zoom.us/j/96449009866?pwd=dlBHYUwxaDRReFhjVmRKZ0Vhdjdkdz09",
|
||||
Students: greenStudents,
|
||||
},
|
||||
Class{
|
||||
Summary: "🎨 Art (Blue/Green)",
|
||||
Start: "14:00",
|
||||
End: "14:45",
|
||||
Days: []time.Weekday{time.Friday},
|
||||
Zoom: "https://us02web.zoom.us/j/85434303018?pwd=c3EzQVNCMmk0L0o4bVF4QW85RTZHZz09",
|
||||
Students: greenStudents,
|
||||
},
|
||||
Class{
|
||||
Summary: "👋 Closing Circle",
|
||||
Start: "15:00",
|
||||
End: "15:15",
|
||||
Days: []time.Weekday{time.Friday},
|
||||
Zoom: "https://us02web.zoom.us/j/2274643506?pwd=Nm5NUXMwOVJKbEUzNE5VSkZCQzJ2UT09",
|
||||
},
|
||||
Class{
|
||||
Summary: "🍎 Rachel & Oliver",
|
||||
Start: "13:45",
|
||||
End: "14:00",
|
||||
Days: []time.Weekday{time.Monday},
|
||||
Tags: map[string]string{
|
||||
"week": "A",
|
||||
Class{
|
||||
Summary: "💭 Dreambox",
|
||||
Start: "09:40",
|
||||
End: "10:00",
|
||||
Days: weekDays,
|
||||
},
|
||||
Zoom: "https://us02web.zoom.us/j/3839164321?pwd=aDNUdzN3bjlZbG93NlNqd09hU2xmUT09",
|
||||
Students: []string{
|
||||
"oliver.park@heliosns.org",
|
||||
Class{
|
||||
Summary: "🐛 Theme",
|
||||
Start: "10:30",
|
||||
End: "11:30",
|
||||
Days: weekDaysButFriday,
|
||||
Zoom: "https://us02web.zoom.us/j/2274643506?pwd=Nm5NUXMwOVJKbEUzNE5VSkZCQzJ2UT09",
|
||||
},
|
||||
},
|
||||
Class{
|
||||
Summary: "🍎 Claudia & Oliver",
|
||||
Start: "13:45",
|
||||
End: "14:00",
|
||||
Days: []time.Weekday{time.Monday},
|
||||
Tags: map[string]string{
|
||||
"week": "B",
|
||||
Class{
|
||||
Summary: "❤️ SEL",
|
||||
Start: "10:30",
|
||||
End: "11:15",
|
||||
Days: []time.Weekday{time.Friday},
|
||||
Zoom: "https://us02web.zoom.us/j/2274643506?pwd=Nm5NUXMwOVJKbEUzNE5VSkZCQzJ2UT09",
|
||||
},
|
||||
Zoom: "https://us02web.zoom.us/j/2274643506?pwd=Nm5NUXMwOVJKbEUzNE5VSkZCQzJ2UT09",
|
||||
Students: []string{
|
||||
"oliver.park@heliosns.org",
|
||||
Class{
|
||||
Summary: "📖 Literacy (Green)",
|
||||
Start: "11:30",
|
||||
End: "12:00",
|
||||
Days: []time.Weekday{time.Monday, time.Wednesday},
|
||||
Zoom: "https://us02web.zoom.us/j/2274643506?pwd=Nm5NUXMwOVJKbEUzNE5VSkZCQzJ2UT09",
|
||||
Students: greenStudents,
|
||||
},
|
||||
},
|
||||
Class{
|
||||
Summary: "🍎 Claudia & Adabelle",
|
||||
Start: "13:45",
|
||||
End: "14:00",
|
||||
Days: []time.Weekday{time.Wednesday},
|
||||
Tags: map[string]string{
|
||||
"week": "A",
|
||||
Class{
|
||||
Summary: "🤸 PE (Yellow/Green)",
|
||||
Start: "11:30",
|
||||
End: "12:00",
|
||||
Days: []time.Weekday{time.Tuesday},
|
||||
Zoom: "https://zoom.us/j/97472507748?pwd=cW5vUFhyUjNTS2toWlZGN254U1ZqZz09",
|
||||
Students: greenStudents,
|
||||
},
|
||||
Zoom: "https://us02web.zoom.us/j/2274643506?pwd=Nm5NUXMwOVJKbEUzNE5VSkZCQzJ2UT09",
|
||||
Students: []string{
|
||||
"adabelle.pratt@heliosns.org",
|
||||
Class{
|
||||
Summary: "💡 iLab (Yellow/Green)",
|
||||
Start: "11:30",
|
||||
End: "12:00",
|
||||
Days: []time.Weekday{time.Thursday},
|
||||
Zoom: "https://us02web.zoom.us/j/86403635026?pwd=S2t1WkN2dnNJZlFkejdEbjRsUmNNUT09",
|
||||
Students: greenStudents,
|
||||
},
|
||||
},
|
||||
Class{
|
||||
Summary: "🍎 Rachel & Adabelle",
|
||||
Start: "13:45",
|
||||
End: "14:00",
|
||||
Days: []time.Weekday{time.Wednesday},
|
||||
Tags: map[string]string{
|
||||
"week": "B",
|
||||
Class{
|
||||
Summary: "📚 Library",
|
||||
Start: "11:30",
|
||||
End: "12:00",
|
||||
Days: []time.Weekday{time.Friday},
|
||||
Zoom: "https://us02web.zoom.us/my/helioslibrary?pwd=cWd4RjNqNXZXNjRjM2dYQVhYeS9Xdz09",
|
||||
},
|
||||
Zoom: "https://us02web.zoom.us/j/3839164321?pwd=aDNUdzN3bjlZbG93NlNqd09hU2xmUT09",
|
||||
Students: []string{
|
||||
"adabelle.pratt@heliosns.org",
|
||||
Class{
|
||||
Summary: "🇲🇽 Spanish",
|
||||
Start: "12:45",
|
||||
End: "13:30",
|
||||
Days: []time.Weekday{time.Monday, time.Tuesday, time.Wednesday},
|
||||
Zoom: "https://zoom.us/j/95144364579?pwd=cGdwNTZIOE42Y0syeVcwVEFhZ1JxZz09",
|
||||
Students: []string{
|
||||
"oliver.park@heliosns.org",
|
||||
},
|
||||
},
|
||||
Class{
|
||||
Summary: "🎨 Art",
|
||||
Start: "12:45",
|
||||
End: "13:30",
|
||||
Days: []time.Weekday{time.Monday, time.Tuesday, time.Wednesday},
|
||||
Zoom: "https://us02web.zoom.us/j/86969790982?pwd=TEMraThVbHhMUlBHUjFZYXZVRnpFQT09",
|
||||
Students: []string{
|
||||
"adabelle.pratt@heliosns.org",
|
||||
},
|
||||
},
|
||||
Class{
|
||||
Summary: "🎶 Music & Movement (Blue/Green)",
|
||||
Start: "12:45",
|
||||
End: "13:30",
|
||||
Days: []time.Weekday{time.Friday},
|
||||
Zoom: "https://zoom.us/j/96449009866?pwd=dlBHYUwxaDRReFhjVmRKZ0Vhdjdkdz09",
|
||||
Students: greenStudents,
|
||||
},
|
||||
Class{
|
||||
Summary: "🎨 Art (Blue/Green)",
|
||||
Start: "14:00",
|
||||
End: "14:45",
|
||||
Days: []time.Weekday{time.Friday},
|
||||
Zoom: "https://us02web.zoom.us/j/85434303018?pwd=c3EzQVNCMmk0L0o4bVF4QW85RTZHZz09",
|
||||
Students: greenStudents,
|
||||
},
|
||||
Class{
|
||||
Summary: "👋 Closing Circle",
|
||||
Start: "15:00",
|
||||
End: "15:15",
|
||||
Days: []time.Weekday{time.Friday},
|
||||
Zoom: "https://us02web.zoom.us/j/2274643506?pwd=Nm5NUXMwOVJKbEUzNE5VSkZCQzJ2UT09",
|
||||
},
|
||||
Class{
|
||||
Summary: "🍎 Rachel & Oliver",
|
||||
Start: "13:45",
|
||||
End: "14:00",
|
||||
Days: []time.Weekday{time.Monday},
|
||||
Tags: map[string]string{
|
||||
"week": "A",
|
||||
},
|
||||
Zoom: "https://us02web.zoom.us/j/3839164321?pwd=aDNUdzN3bjlZbG93NlNqd09hU2xmUT09",
|
||||
Students: []string{
|
||||
"oliver.park@heliosns.org",
|
||||
},
|
||||
},
|
||||
Class{
|
||||
Summary: "🍎 Claudia & Oliver",
|
||||
Start: "13:45",
|
||||
End: "14:00",
|
||||
Days: []time.Weekday{time.Monday},
|
||||
Tags: map[string]string{
|
||||
"week": "B",
|
||||
},
|
||||
Zoom: "https://us02web.zoom.us/j/2274643506?pwd=Nm5NUXMwOVJKbEUzNE5VSkZCQzJ2UT09",
|
||||
Students: []string{
|
||||
"oliver.park@heliosns.org",
|
||||
},
|
||||
},
|
||||
Class{
|
||||
Summary: "🍎 Claudia & Adabelle",
|
||||
Start: "13:45",
|
||||
End: "14:00",
|
||||
Days: []time.Weekday{time.Wednesday},
|
||||
Tags: map[string]string{
|
||||
"week": "A",
|
||||
},
|
||||
Zoom: "https://us02web.zoom.us/j/2274643506?pwd=Nm5NUXMwOVJKbEUzNE5VSkZCQzJ2UT09",
|
||||
Students: []string{
|
||||
"adabelle.pratt@heliosns.org",
|
||||
},
|
||||
},
|
||||
Class{
|
||||
Summary: "🍎 Rachel & Adabelle",
|
||||
Start: "13:45",
|
||||
End: "14:00",
|
||||
Days: []time.Weekday{time.Wednesday},
|
||||
Tags: map[string]string{
|
||||
"week": "B",
|
||||
},
|
||||
Zoom: "https://us02web.zoom.us/j/3839164321?pwd=aDNUdzN3bjlZbG93NlNqd09hU2xmUT09",
|
||||
Students: []string{
|
||||
"adabelle.pratt@heliosns.org",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
151
main.go
151
main.go
@@ -2,163 +2,18 @@ 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")
|
||||
var days = flag.Int("days", 0, "number of days in the future")
|
||||
var _days = flag.Int("days", 0, "number of days in the future")
|
||||
|
||||
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)
|
||||
|
||||
for i := 0; i < *days; i++ {
|
||||
date := now.Add(time.Duration(i * 24) * time.Hour)
|
||||
|
||||
eventMap, err := getDayEvents(srv, myCal.Id, date)
|
||||
for calName, classList := range classes {
|
||||
err := updateCalendar(calName, classList, *_days)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for _, class := range classes {
|
||||
if !class.happensOnDay(date) {
|
||||
continue
|
||||
}
|
||||
|
||||
if !class.tagsMatch(date) {
|
||||
continue
|
||||
}
|
||||
|
||||
ev := class.buildEvent(date)
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
eventMap := map[string]*calendar.Event{}
|
||||
|
||||
for _, item := range events.Items {
|
||||
eventMap[item.Summary] = item
|
||||
}
|
||||
|
||||
return eventMap, nil
|
||||
}
|
||||
|
||||
func eventsEqual(a *calendar.Event, b *calendar.Event) bool {
|
||||
if a.Summary != b.Summary {
|
||||
return false
|
||||
}
|
||||
|
||||
if a.Description != b.Description {
|
||||
return false
|
||||
}
|
||||
|
||||
if a.Start.DateTime[:19] != b.Start.DateTime[:19] {
|
||||
return false
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user