Mercurial > code > home > repos > gcalendarwatch
view calsync/gcalclient/gcalclient.go @ 53:f248f018a663
refactor; dead code
author | drewp@bigasterisk.com |
---|---|
date | Mon, 19 Aug 2024 19:28:50 -0700 |
parents | 5f7c393577e9 |
children | 3a12a3ac9164 |
line wrap: on
line source
package gcalclient import ( "context" "log" "net/url" "strings" "time" "bigasterisk.com/go/gcalendarwatch/mongoclient" "google.golang.org/api/calendar/v3" ) type GCalClient struct { ctx context.Context srv *calendar.Service } // Same as calendar.Event, but includes our urls type CalendarEvent struct { *calendar.Event CalendarUrl string EventUrl string } func MakeCalUrl(calId string) string { return "http://bigasterisk.com/calendar/" + url.QueryEscape(calId) } func MakeEventUrl(calUrl string, evId string) string { return calUrl + "/" + url.QueryEscape(evId) } func New(ctx context.Context) (*GCalClient, error) { err, srv := newService(ctx) if err != nil { log.Fatalf("Unable to retrieve Calendar client: %v", err) } return &GCalClient{ctx, srv}, nil } func (gc *GCalClient) Close() { // todo: disconnect watches if possible } func (gc *GCalClient) AllCalendars(maxResults int64) ([]*calendar.CalendarListEntry, error) { // todo: pagination list, err := gc.srv.CalendarList.List().MaxResults(maxResults).Do() if err != nil { return nil, err } list.Items = list.Items[:4] return list.Items, nil } type FindEventsMessage struct { // either non-nil this: Event *CalendarEvent // or these: CalId string OlderThanThisIsDeletable time.Time } // FindEvents considers all calendars. It runs forever. func (gc *GCalClient) FindEvents( mc *mongoclient.MongoClient, // For each calendar, after events in this time range have been sent to // `out`, the chan will get the other kind of FindEventsMessage (CalId, // ...). That message signals that the caller may cull old events on the given // calendar. After that point, all events will be updates (including // deletes). initialFillStart, initialFillEnd time.Time, out chan *FindEventsMessage, ) error { cals, err := mc.GetAllCals() if err != nil { return err } log.Println("reading", len(cals), "calendars") for calNum, cal := range cals { t := time.Now() log.Println(" cal", calNum, cal.Url) log.Println(" cal", calNum, "readEventsInRange", "from", initialFillStart, "to", initialFillEnd) syncToken, err := gc.readEventsInRange(&cal, initialFillStart, initialFillEnd, out) if err != nil { return err } out <- &FindEventsMessage{nil, cal.GoogleId, t} ew := gc.NewEventWatch(&cal, t, syncToken, out) for loop := 0; loop < 30; loop++ { log.Println("") log.Println("tail loop", loop, "for", cal.Url) err := ew.GetMoreEvents() if err != nil { return err } time.Sleep(2 * time.Second) } } return nil } // Synchronous. func (gc *GCalClient) readEventsInRange( cal *mongoclient.MongoCal, initialFillStart, initialFillEnd time.Time, out chan *FindEventsMessage, ) (string, error) { log.Println( " get initial events for", cal.Url, "between", initialFillStart, "and", initialFillEnd) pageToken := "" syncToken := "" for { log.Println(" getting another page", pageToken) events, err := rangedEventsCall(gc.srv, cal.GoogleId, initialFillStart, initialFillEnd, pageToken).Do() if err != nil { return "", err } log.Println(" got", len(events.Items), "events, sync=", events.NextSyncToken) if len(events.Items) == 0 { break } sendEvents(events, cal, out) syncToken = events.NextSyncToken if events.NextPageToken == "" { break } pageToken = events.NextPageToken } return syncToken, nil } // Send a page of calendar.Events over a channel, as CalendarEvent structs. func sendEvents(events *calendar.Events, cal *mongoclient.MongoCal, out chan *FindEventsMessage) { for _, event := range events.Items { if event.Status == "cancelled" { log.Fatal("todo") } out <- &FindEventsMessage{ Event: &CalendarEvent{ Event: event, CalendarUrl: cal.Url, EventUrl: MakeEventUrl(cal.Url, event.Id), }} } } type eventWatch struct { gc *GCalClient cal *mongoclient.MongoCal nextSyncToken string nextPageToken string modSince time.Time out chan *FindEventsMessage } func (gc *GCalClient) NewEventWatch( cal *mongoclient.MongoCal, modSince time.Time, syncToken string, out chan *FindEventsMessage, ) *eventWatch { ew := &eventWatch{gc, cal, syncToken, "", modSince, out} return ew } // Call this when there are likely new changes to sync. func (w *eventWatch) GetMoreEvents() error { call := syncEventsCall(w.gc.srv, w.cal.GoogleId) log.Println("listing events on", w.cal.GoogleId, "with") if w.nextPageToken != "" { call = call.PageToken(w.nextPageToken) log.Println(" pageToken", w.nextPageToken) } else if w.nextSyncToken != "" { call = call.SyncToken(w.nextSyncToken) log.Println(" syncToken", w.nextSyncToken) } else { call = call.UpdatedMin((w.modSince.Format(time.RFC3339))) log.Println(" updatedMin", w.modSince.Format(time.RFC3339)) } ret, err := call.Do() if err != nil { return err } w.nextSyncToken = ret.NextSyncToken w.nextPageToken = ret.NextPageToken log.Println(len(ret.Items), "more events received") sendEvents(ret, w.cal, w.out) log.Println("got nextSyncToken=", w.nextSyncToken) log.Println("got nextPageToken=", w.nextPageToken) return err }