Added wholeDay updating

This commit is contained in:
Andreas Schneider 2018-04-02 12:56:55 +02:00
parent 3c400b3664
commit 580dafe123
3 changed files with 58 additions and 6 deletions

View File

@ -52,7 +52,7 @@ func main() {
!ewsItem.End.Equal(calDavItem.End()) {
// So times have changed. Update.
calDavItem.Update(ewsItem.Start, ewsItem.End)
calDavItem.Update(ewsItem.Start, ewsItem.End, ewsItem.IsAllDayEvent)
err := c.UploadItem(calDavItem)
if err == nil {

View File

@ -78,7 +78,39 @@ var fieldMatch = regexp.MustCompile(`^(\w+)[;:]`)
// Update the ical structure with a new start/end time (and the
// 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 {
match := fieldMatch.FindStringSubmatch(line)
if match == nil {
@ -90,9 +122,9 @@ func (ical *ICal) Update(newStart, newEnd time.Time) {
switch match[1] {
case "DTSTART":
ical.eventData[i] = "DTSTART:" + newStart.UTC().Format(ICAL_TIME) + "Z"
ical.eventData[i] = match[1] + formatTime(newStart)
case "DTEND":
ical.eventData[i] = "DTEND:" + newEnd.UTC().Format(ICAL_TIME) + "Z"
ical.eventData[i] = match[1] + formatTime(newEnd)
case "DTSTAMP", "LAST-MODIFIED":
ical.eventData[i] = match[1] + ":" + now.Format(ICAL_TIME) + "Z"
}

View File

@ -79,7 +79,7 @@ func TestICal_Update(t *testing.T) {
t.Run("Values updated", func(t *testing.T) {
ical, _ := ParseICal(strings.NewReader(icsSimple))
ical.Update(newStart, newEnd)
ical.Update(newStart, newEnd, false)
if ical.Start() != newStart {
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.Run("Other values untouched", func(t *testing.T) {
// Use a ICal structure with dummy/unknown fields but also without
// DTSTAMP or LAST-MODIFIED, so we can do a string comparison against
@ -112,7 +113,7 @@ END:VEVENT
EVEN;MORE:STUFF
END:VCALENDAR`))
ical.Update(newStart, newEnd)
ical.Update(newStart, newEnd, false)
if ical.String() != `BEGIN:VCALENDAR
PRODID:-//some//thing//EN
@ -133,6 +134,25 @@ END:VCALENDAR` {
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