forked from aksdb/CalAnonSync
Added wholeDay updating
This commit is contained in:
parent
3c400b3664
commit
580dafe123
|
@ -52,7 +52,7 @@ func main() {
|
||||||
!ewsItem.End.Equal(calDavItem.End()) {
|
!ewsItem.End.Equal(calDavItem.End()) {
|
||||||
|
|
||||||
// So times have changed. Update.
|
// So times have changed. Update.
|
||||||
calDavItem.Update(ewsItem.Start, ewsItem.End)
|
calDavItem.Update(ewsItem.Start, ewsItem.End, ewsItem.IsAllDayEvent)
|
||||||
|
|
||||||
err := c.UploadItem(calDavItem)
|
err := c.UploadItem(calDavItem)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
|
@ -78,7 +78,39 @@ var fieldMatch = regexp.MustCompile(`^(\w+)[;:]`)
|
||||||
|
|
||||||
// Update the ical structure with a new start/end time (and the
|
// Update the ical structure with a new start/end time (and the
|
||||||
// timestamp of the last modification).
|
// timestamp of the last modification).
|
||||||
func (ical *ICal) Update(newStart, newEnd time.Time) {
|
// If wholeDay is requested, the start and end times are tried
|
||||||
|
// first. If they are precisely 0:00 to 0:00, fine. Otherwise
|
||||||
|
// they are converted to local timezone and tried again. If that
|
||||||
|
// also fails the event is NOT considered whole day!
|
||||||
|
func (ical *ICal) Update(newStart, newEnd time.Time, wholeDay bool) {
|
||||||
|
if wholeDay && (newStart.Hour() != 0 || newStart.Minute() != 0 ||
|
||||||
|
newEnd.Hour() != 0 || newEnd.Hour() != 0) {
|
||||||
|
|
||||||
|
newStart = newStart.In(time.Local)
|
||||||
|
newEnd = newEnd.In(time.Local)
|
||||||
|
|
||||||
|
if newStart.Hour() != 0 || newStart.Minute() != 0 ||
|
||||||
|
newEnd.Hour() != 0 || newEnd.Hour() != 0 {
|
||||||
|
|
||||||
|
log.Printf("Cannot update event %s as whole day.\n", ical.UID())
|
||||||
|
wholeDay = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if wholeDay {
|
||||||
|
// For wholeDay events, the endDate is the beginning of the next day. For
|
||||||
|
// the formatting to work, we need to move that back into the previous day.
|
||||||
|
newEnd = newEnd.Add(-1 * time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
|
formatTime := func(t time.Time) string {
|
||||||
|
if wholeDay {
|
||||||
|
return ";VALUE=DATE:" + t.Format(ICAL_DATE)
|
||||||
|
} else {
|
||||||
|
return ":" + t.UTC().Format(ICAL_TIME) + "Z"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for i, line := range ical.eventData {
|
for i, line := range ical.eventData {
|
||||||
match := fieldMatch.FindStringSubmatch(line)
|
match := fieldMatch.FindStringSubmatch(line)
|
||||||
if match == nil {
|
if match == nil {
|
||||||
|
@ -90,9 +122,9 @@ func (ical *ICal) Update(newStart, newEnd time.Time) {
|
||||||
|
|
||||||
switch match[1] {
|
switch match[1] {
|
||||||
case "DTSTART":
|
case "DTSTART":
|
||||||
ical.eventData[i] = "DTSTART:" + newStart.UTC().Format(ICAL_TIME) + "Z"
|
ical.eventData[i] = match[1] + formatTime(newStart)
|
||||||
case "DTEND":
|
case "DTEND":
|
||||||
ical.eventData[i] = "DTEND:" + newEnd.UTC().Format(ICAL_TIME) + "Z"
|
ical.eventData[i] = match[1] + formatTime(newEnd)
|
||||||
case "DTSTAMP", "LAST-MODIFIED":
|
case "DTSTAMP", "LAST-MODIFIED":
|
||||||
ical.eventData[i] = match[1] + ":" + now.Format(ICAL_TIME) + "Z"
|
ical.eventData[i] = match[1] + ":" + now.Format(ICAL_TIME) + "Z"
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,7 @@ func TestICal_Update(t *testing.T) {
|
||||||
|
|
||||||
t.Run("Values updated", func(t *testing.T) {
|
t.Run("Values updated", func(t *testing.T) {
|
||||||
ical, _ := ParseICal(strings.NewReader(icsSimple))
|
ical, _ := ParseICal(strings.NewReader(icsSimple))
|
||||||
ical.Update(newStart, newEnd)
|
ical.Update(newStart, newEnd, false)
|
||||||
|
|
||||||
if ical.Start() != newStart {
|
if ical.Start() != newStart {
|
||||||
t.Error("Start not updated correctly")
|
t.Error("Start not updated correctly")
|
||||||
|
@ -92,6 +92,7 @@ func TestICal_Update(t *testing.T) {
|
||||||
t.Error("Timestamp doesn't seem to be updated")
|
t.Error("Timestamp doesn't seem to be updated")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Other values untouched", func(t *testing.T) {
|
t.Run("Other values untouched", func(t *testing.T) {
|
||||||
// Use a ICal structure with dummy/unknown fields but also without
|
// Use a ICal structure with dummy/unknown fields but also without
|
||||||
// DTSTAMP or LAST-MODIFIED, so we can do a string comparison against
|
// DTSTAMP or LAST-MODIFIED, so we can do a string comparison against
|
||||||
|
@ -112,7 +113,7 @@ END:VEVENT
|
||||||
EVEN;MORE:STUFF
|
EVEN;MORE:STUFF
|
||||||
END:VCALENDAR`))
|
END:VCALENDAR`))
|
||||||
|
|
||||||
ical.Update(newStart, newEnd)
|
ical.Update(newStart, newEnd, false)
|
||||||
|
|
||||||
if ical.String() != `BEGIN:VCALENDAR
|
if ical.String() != `BEGIN:VCALENDAR
|
||||||
PRODID:-//some//thing//EN
|
PRODID:-//some//thing//EN
|
||||||
|
@ -133,6 +134,25 @@ END:VCALENDAR` {
|
||||||
t.Error("The resulting ICS seems wrong.")
|
t.Error("The resulting ICS seems wrong.")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("Values wholeDay", func(t *testing.T) {
|
||||||
|
newStart := time.Date(2019, 1, 2, 0, 0, 0, 0, time.Local)
|
||||||
|
newEnd := time.Date(2019, 1, 3, 0, 0, 0, 0, time.Local)
|
||||||
|
|
||||||
|
ical, _ := ParseICal(strings.NewReader(icsSimple))
|
||||||
|
ical.Update(newStart, newEnd, true)
|
||||||
|
|
||||||
|
if ical.Start() != newStart {
|
||||||
|
t.Error("Start not updated correctly")
|
||||||
|
}
|
||||||
|
if ical.End() != newEnd {
|
||||||
|
t.Error("End not updated correctly")
|
||||||
|
}
|
||||||
|
|
||||||
|
if ical.getTimeField("DTSTAMP").Sub(time.Now()) > 5*time.Second {
|
||||||
|
t.Error("Timestamp doesn't seem to be updated")
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const icsWithTZ = `BEGIN:VCALENDAR
|
const icsWithTZ = `BEGIN:VCALENDAR
|
||||||
|
|
Loading…
Reference in New Issue