CalAnonSync/src/calanonsync/calanonsync.go

111 lines
2.8 KiB
Go

package main
import (
"fmt"
"github.com/spf13/cobra"
"log"
"os"
"time"
)
func main() {
rootCmd := &cobra.Command{
Use: "calanonsync",
Short: "Synchronize a calendar from EWS to CalDAV by event time and an anonymized title only.",
Run: runSynchronization,
}
rootCmd.AddCommand(InitSettingsCmd())
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
func runSynchronization(cmd *cobra.Command, args []string) {
s := LoadSettings()
e := NewEWSCalendar(s.EWS.URL, s.EWS.Username, s.EWS.Password)
id, err := e.getCalendarFolderID()
if err != nil {
log.Fatalln(err)
}
items, err := e.getCalendarItems(id,
time.Now().AddDate(0, -1, 0), // One month past
time.Now().AddDate(0, 2, 0)) // Two months ahead
if err != nil {
log.Fatalf("Could not get EWS items: %s\n", err)
}
relevantEWSItems := make(map[string]CalendarItem)
for _, item := range items {
// Ignore private items.
if item.Sensitivity != "Private" && !item.IsCancelled() {
// None-private items though ... remember them by hash.
// The hash will equal the CalDAV UID (and its filename).
relevantEWSItems[item.Hash()] = item
}
}
c := NewCalDAV(s.CalDAV)
calDavItems, err := c.GetEvents()
if err != nil {
log.Fatalf("Could not get CalDAV items: %s\n", err)
}
// Build a map for easier lookup by UID
calDavItemMap := make(map[string]CalDAVItem)
for _, item := range calDavItems {
calDavItemMap[item.UID()] = item
}
// First step: find items that were changed or that were removed
// and update the CalDAV side accordingly.
for uid, calDavItem := range calDavItemMap {
if ewsItem, ok := relevantEWSItems[uid]; ok {
// Good, so we still know the item at least.
if !ewsItem.Start.Equal(calDavItem.Start()) ||
!ewsItem.End.Equal(calDavItem.End()) {
// So times have changed. Update.
calDavItem.Update(ewsItem.Start, ewsItem.End, ewsItem.IsAllDayEvent)
err := c.UploadItem(calDavItem)
if err == nil {
log.Printf("Updated item %s (%s)\n", uid, ewsItem.Subject)
} else {
// Not fatal, but worth a note.
log.Println(err)
}
}
} else {
// Oops, seems the item vanished.
err := c.DeleteItem(calDavItem)
if err == nil {
log.Printf("Deleted item %s (%s)\n", calDavItem.UID(), calDavItem.Summary())
} else {
// Not fatal, but worth a note.
log.Println(err)
}
}
}
// Find items we don't know so far and create them.
for uid, ewsItem := range relevantEWSItems {
if _, ok := calDavItemMap[uid]; !ok {
title := s.Anonymize.Title.Apply(ewsItem.Subject)
ical := CreateICal(ewsItem.Hash(), title, ewsItem.Start, ewsItem.End, ewsItem.IsAllDayEvent)
calDavItem := CalDAVItem{HRef: uid + ".ics", ICal: ical}
err := c.UploadItem(calDavItem)
if err == nil {
log.Printf("Created item %s (%s)\n", uid, ewsItem.Subject)
} else {
log.Println(err)
}
}
}
}