view calsync/mongoclient/mongoclient.go @ 49:2991c1166852

start calsync in go. Calendar list seems to sync
author drewp@bigasterisk.com
date Mon, 19 Aug 2024 13:25:03 -0700
parents
children dade5bbd02e3
line wrap: on
line source

package mongoclient

import (
	"context"
	"log"
	"time"

	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

type MongoClient struct {
	ctx              context.Context
	client           *mongo.Client
	db               *mongo.Database
	calsCollection   *mongo.Collection
	eventsCollection *mongo.Collection
}

// docs in calsCollection
type MongoCal struct {
	Url         string `bson:"_id"` // bigasterisk.com/...
	GoogleId    string `bson:"googleId"`
	Summary     string `bson:"summary"`
	Description string `bson:"description"`
}

// docs in eventsCollection
type MongoEvent struct {
	// e.g.
	// {
	// 	"_id" : "http://bigasterisk.com/calendar/08s5m1_20140929T030000Z",
	// 	"htmlLink" : "https://www.google.com/calendar/event?eid=MDhz",
	// 	"title" : "meeting",
	// 	"feedId" : "drewpca@gmail.com",
	// 	"feedTitle" : "drewpca@gmail.com",
	// 	"endTimeUnspecified" : false,
	// 	"start" : "2014-09-28T20:00:00-07:00",
	// 	"startDate" : "2014-09-28",
	// 	"startTime" : ISODate("2014-09-29T03:00:00Z"),
	// 	"end" : "2014-09-28T21:00:00-07:00",
	// 	"endDate" : "2014-09-28",
	// 	"endTime" : ISODate("2014-09-29T04:00:00Z")
	// }

	Url                string    `bson:"_id"`
	GoogleId           string    `bson:"googleId"`
	HtmlLink           string    `bson:"htmlLink"`
	Title              string    `bson:"title"`
	FeedId             string    `bson:"feedId"`
	FeedTitle          string    `bson:"feedTitle"`
	EndTimeUnspecified bool      `bson:"endTimeUnspecified"`
	Start              string    `bson:"start"`
	StartDate          string    `bson:"startDate"`
	StartTime          time.Time `bson:"startTime"`
	End                string    `bson:"end"`
	EndDate            string    `bson:"endDate"`
	EndTime            time.Time `bson:"endTime"`
	LastUpdated        time.Time `bson:"lastUpdated"`
}

func New(ctx context.Context) (*MongoClient, error) {
	log.Println("todo: using fixed ip")
	mclient, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://10.43.98.221:27017"))
	if err != nil {
		return nil, err
	}
	db := mclient.Database("pim")
	return &MongoClient{
			ctx,
			mclient,
			db,
			db.Collection("test_gcalendar_cals"),
			db.Collection("test_gcalendar")},
		nil
}

func (c *MongoClient) Close() {
	c.client.Disconnect(c.ctx)
}

func (c *MongoClient) GetAllCals() ([]MongoCal, error) {
	cur, err := c.calsCollection.Find(c.ctx, bson.D{})
	if err != nil {
		return nil, err
	}
	defer cur.Close(c.ctx)

	var cals []MongoCal
	for cur.Next(c.ctx) {
		var cal MongoCal
		if err := cur.Decode(&cal); err != nil {
			return nil, err
		}
		cals = append(cals, cal)
	}
	return cals, nil
}

func (c *MongoClient) GetOneCal(calId string) (MongoCal, error) {
	res := c.calsCollection.FindOne(c.ctx, bson.M{"_id": calId})
	var cal MongoCal
	err := res.Decode(&cal)
	return cal, err
}

func (c *MongoClient) UpsertOneCal(cal MongoCal) error {
	filter := bson.M{"_id": cal.Url}
	update := bson.M{
		"$set": cal,
		// bson.M{
		// 	"googleId":    cal.GoogleId,
		// 	"summary":     cal.Summary,
		// 	"description": cal.Description,
		// },
	}
	_, err := c.calsCollection.UpdateOne(c.ctx, filter, update, options.Update().SetUpsert(true))
	if err != nil {
		return err
	}
	return nil
}

func (c *MongoClient) DeleteCalsNotInSet(urlsToKeep map[string]bool) error {
	curs, err := c.calsCollection.Find(c.ctx, bson.M{})
	if err != nil {
		return err
	}
	defer curs.Close(c.ctx)

	for curs.Next(c.ctx) {
		var doc bson.M
		err = curs.Decode(&doc)
		if err != nil {
			return err
		}
		calUrl, ok := doc["_id"].(string)
		if !ok {
			continue
		}
		if !urlsToKeep[calUrl] {
			log.Println("  cleaning up", calUrl)
			_, err = c.calsCollection.DeleteOne(c.ctx, bson.M{"_id": doc["_id"]})
			if err != nil {
				return err
			}
		}
	}
	return curs.Err()
}

func (c *MongoClient) UpsertOneEvent(ev MongoEvent) error {
	filter := bson.M{"_id": ev.Url}
	setFields := bson.M{
		"googleId":    ev.GoogleId,
		"lastUpdated": ev.LastUpdated,
		"htmlLink":    ev.HtmlLink,
		"title":       ev.Title,
	}
	update := bson.M{"$set": setFields}
	_, err := c.eventsCollection.UpdateOne(c.ctx, filter, update, options.Update().SetUpsert(true))
	if err != nil {
		return err
	}
	log.Println("  mongo upserted", ev.Url)
	return nil
}

// func (c *MongoClient) FindEventsIntersecting(t1, t2 time.Time) ([]MongoEvent, error) {
// 	cur, err := c.eventsCollection.Find(c.ctx, bson.M{
// 		"end":   bson.M{"$gte": t1},
// 		"start": bson.M{"$lte": t2},
// 	}) // todo: allday evs
// 	if err != nil {
// 		return nil, err
// 	}
// 	defer cur.Close(c.ctx)

// 	var events []MongoEvent
// 	for cur.Next(c.ctx) {
// 		var ev MongoEvent
// 		if err := cur.Decode(&ev); err != nil {
// 			return nil, err
// 		}
// 		events = append(events, ev)
// 	}
// 	return events, nil
// }

// func (c *MongoClient) CurrentEvents(now time.Time) ([]MongoEvent, error) {
// 	return c.FindEventsIntersecting(now, now)
// }
// func (c *MongoClient) UpdateOrInsertEvent(ev MongoEvent) error {
// 	return errors.New("todo")
// }

// func (c *MongoClient) DeleteEvent(ev MongoEvent) error {
// 	return errors.New("todo")
// }