view calsync/gcalclient/gcalclient.go @ 73:50ddf6a48816

gcalclient should return errors, not exit
author drewp@bigasterisk.com
date Fri, 06 Sep 2024 17:33:08 -0700
parents 0f09464d4974
children 30ad34850ef1
line wrap: on
line source

package gcalclient

/*
Note: this module keeps gcal *paging* private (we fetch all the pages), but
*sync* is public. At least, callers may receive a syncToken and have to pass it
back in.
*/
import (
	"context"
	"crypto/md5"
	"fmt"
	"net/url"
	"time"

	"bigasterisk.com/go/gcalendarwatch/mongoclienttypes"
	"google.golang.org/api/calendar/v3"
)

const urlBase = "http://bigasterisk.com/calendar/"

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 urlBase + url.QueryEscape(calId)
}

func MakeEventUrl(calUrl string, evId string) string {
	return calUrl + "/" + url.QueryEscape(evId)
}

func New(ctx context.Context) (*GCalClient, error) {
	srv, err := newService(ctx)
	if err != nil {
		return nil, err
	}
	return &GCalClient{ctx, srv}, nil
}

func (gc *GCalClient) Close() {
	// todo: disconnect watches if possible
}

func (gc *GCalClient) AllCalendars() ([]*calendar.CalendarListEntry, error) {
	// todo: pagination
	list, err := gc.srv.CalendarList.List().MaxResults( /*maxResults*/ 100).Do()
	if err != nil {
		return nil, err
	}
	return list.Items, nil
}

func shortDebugHash(pageToken string) string {
	if pageToken == "" {
		return "(empty)"
	}
	return fmt.Sprintf("%x", md5.Sum([]byte(pageToken)))
}

func (gc *GCalClient) WatchEvents(cal *mongoclienttypes.MongoCal, watchId string, expire time.Duration) error {
	_, err := watchEventsCall(gc.srv, cal.GoogleId, expire, watchId).Do()
	return err
}