feat: convert VALARMs to Reminders
Some checks failed
continuous-integration/drone/pr Build is failing
Some checks failed
continuous-integration/drone/pr Build is failing
This commit is contained in:
parent
06508f0287
commit
32cb200f87
|
@ -237,16 +237,3 @@ func makeCalDavDuration(duration time.Duration) (caldavtime string) {
|
||||||
caldavtime += "PT" + strings.ToUpper(duration.Truncate(time.Millisecond).String())
|
caldavtime += "PT" + strings.ToUpper(duration.Truncate(time.Millisecond).String())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func calcAlarmDateFromReminder(eventStart, reminder time.Time) (alarmTime string) {
|
|
||||||
diff := reminder.Sub(eventStart)
|
|
||||||
diffStr := strings.ToUpper(diff.String())
|
|
||||||
if diff < 0 {
|
|
||||||
alarmTime += `-`
|
|
||||||
// We append the - at the beginning of the caldav flag, that would get in the way if the minutes
|
|
||||||
// themselves are also containing it
|
|
||||||
diffStr = diffStr[1:]
|
|
||||||
}
|
|
||||||
alarmTime += `PT` + diffStr
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
|
@ -141,52 +141,56 @@ func ParseTaskFromVTODO(content string) (vTask *models.Task, err error) {
|
||||||
vTask.EndDate = vTask.StartDate.Add(duration)
|
vTask.EndDate = vTask.StartDate.Add(duration)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reminders := make([]*models.TaskReminder, 0)
|
||||||
for _, vAlarm := range vTodo.SubComponents() {
|
for _, vAlarm := range vTodo.SubComponents() {
|
||||||
switch vAlarm := vAlarm.(type) {
|
switch vAlarm := vAlarm.(type) {
|
||||||
case *ics.VAlarm:
|
case *ics.VAlarm:
|
||||||
parseVAlarm(vAlarm, vTask)
|
reminders = parseVAlarm(vAlarm, reminders)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if len(reminders) > 0 {
|
||||||
|
vTask.Reminders = reminders
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseVAlarm(vAlarm *ics.VAlarm, vTask *models.Task) {
|
func parseVAlarm(vAlarm *ics.VAlarm, reminders []*models.TaskReminder) []*models.TaskReminder {
|
||||||
for _, property := range vAlarm.UnknownPropertiesIANAProperties() {
|
for _, property := range vAlarm.UnknownPropertiesIANAProperties() {
|
||||||
if property.IANAToken == "TRIGGER" {
|
if property.IANAToken == "TRIGGER" {
|
||||||
if len(property.ICalParameters["VALUE"]) > 0 {
|
if len(property.ICalParameters["VALUE"]) > 0 {
|
||||||
switch property.ICalParameters["VALUE"][0] {
|
switch property.ICalParameters["VALUE"][0] {
|
||||||
case "DATE-TIME":
|
case "DATE-TIME":
|
||||||
// Example: TRIGGER;VALUE=DATE-TIME:20181201T011210Z
|
// Example: TRIGGER;VALUE=DATE-TIME:20181201T011210Z
|
||||||
vTask.ReminderDates = append(vTask.ReminderDates, caldavTimeToTimestamp(property.Value))
|
reminders = append(reminders, &models.TaskReminder{
|
||||||
|
Reminder: caldavTimeToTimestamp(property.Value)})
|
||||||
|
}
|
||||||
|
} else if len(property.ICalParameters["RELATED"]) > 0 {
|
||||||
|
duration := parseDuration(property.Value)
|
||||||
|
switch property.ICalParameters["RELATED"][0] {
|
||||||
|
case "START":
|
||||||
|
// Example: TRIGGER;RELATED=START:-P2D
|
||||||
|
reminders = append(reminders, &models.TaskReminder{
|
||||||
|
RelativePeriod: int64(duration.Seconds()),
|
||||||
|
RelativeTo: models.ReminderRelationStartDate})
|
||||||
|
case "END":
|
||||||
|
// Example: TRIGGER;RELATED=END:-P2D
|
||||||
|
reminders = append(reminders, &models.TaskReminder{
|
||||||
|
RelativePeriod: int64(duration.Seconds()),
|
||||||
|
RelativeTo: models.ReminderRelationEndDate})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
duration := parseDuration(property.Value)
|
||||||
|
if duration != 0 {
|
||||||
|
// Example: TRIGGER:-PT60M
|
||||||
|
reminders = append(reminders, &models.TaskReminder{
|
||||||
|
RelativePeriod: int64(duration.Seconds()),
|
||||||
|
RelativeTo: models.ReminderRelationDueDate})
|
||||||
}
|
}
|
||||||
//} else if len(property.ICalParameters["RELATED"]) > 0 {
|
|
||||||
// duration := parseDuration(property.Value)
|
|
||||||
// switch property.ICalParameters["RELATED"][0] {
|
|
||||||
// case "START":
|
|
||||||
// // Example: TRIGGER;RELATED=START:-P2D
|
|
||||||
// if !vTask.StartDate.IsZero() {
|
|
||||||
// vTask.Reminders = append(vTask.Reminders, vTask.StartDate.Add(duration))
|
|
||||||
// }
|
|
||||||
// case "END":
|
|
||||||
// // Example: TRIGGER;RELATED=END:-P2D
|
|
||||||
// if !vTask.EndDate.IsZero() {
|
|
||||||
// vTask.Reminders = append(vTask.Reminders, vTask.EndDate.Add(duration))
|
|
||||||
// } else if !vTask.DueDate.IsZero() {
|
|
||||||
// vTask.Reminders = append(vTask.Reminders, vTask.DueDate.Add(duration))
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//} else {
|
|
||||||
// duration := parseDuration(property.Value)
|
|
||||||
// if duration != 0 {
|
|
||||||
// // Example: TRIGGER:-PT60M
|
|
||||||
// if !vTask.DueDate.IsZero() {
|
|
||||||
// vTask.Reminders = append(vTask.Reminders, vTask.DueDate.Add(duration))
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return reminders
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://tools.ietf.org/html/rfc5545#section-3.3.5
|
// https://tools.ietf.org/html/rfc5545#section-3.3.5
|
||||||
|
@ -213,7 +217,6 @@ func caldavTimeToTimestamp(tstring string) time.Time {
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: move to utils/time.go and share with ticktick.go
|
|
||||||
var durationRegex = regexp.MustCompile(`([-+])?P([\d\.]+Y)?([\d\.]+M)?([\d\.]+D)?T?([\d\.]+H)?([\d\.]+M)?([\d\.]+?S)?`)
|
var durationRegex = regexp.MustCompile(`([-+])?P([\d\.]+Y)?([\d\.]+M)?([\d\.]+D)?T?([\d\.]+H)?([\d\.]+M)?([\d\.]+?S)?`)
|
||||||
|
|
||||||
// ParseDuration converts a ISO8601 duration into a time.Duration
|
// ParseDuration converts a ISO8601 duration into a time.Duration
|
||||||
|
|
|
@ -142,56 +142,67 @@ END:VCALENDAR`,
|
||||||
Title: "Todo #1",
|
Title: "Todo #1",
|
||||||
UID: "randomuid",
|
UID: "randomuid",
|
||||||
Description: "Lorem Ipsum",
|
Description: "Lorem Ipsum",
|
||||||
ReminderDates: []time.Time{
|
Reminders: []*models.TaskReminder{
|
||||||
time.Date(2018, 12, 1, 1, 12, 10, 0, config.GetTimeZone()),
|
{
|
||||||
|
Reminder: time.Date(2018, 12, 1, 1, 12, 10, 0, config.GetTimeZone()),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Updated: time.Unix(1543626724, 0).In(config.GetTimeZone()),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "With alarm (relative trigger)",
|
||||||
|
args: args{content: `BEGIN:VCALENDAR
|
||||||
|
VERSION:2.0
|
||||||
|
METHOD:PUBLISH
|
||||||
|
X-PUBLISHED-TTL:PT4H
|
||||||
|
X-WR-CALNAME:test
|
||||||
|
PRODID:-//RandomProdID which is not random//EN
|
||||||
|
BEGIN:VTODO
|
||||||
|
UID:randomuid
|
||||||
|
DTSTAMP:20181201T011204
|
||||||
|
SUMMARY:Todo #1
|
||||||
|
DESCRIPTION:Lorem Ipsum
|
||||||
|
DTSTART:20230228T170000Z
|
||||||
|
DUE:20230304T150000Z
|
||||||
|
BEGIN:VALARM
|
||||||
|
TRIGGER:-PT60M
|
||||||
|
ACTION:DISPLAY
|
||||||
|
END:VALARM
|
||||||
|
BEGIN:VALARM
|
||||||
|
TRIGGER;RELATED=START:-P1D
|
||||||
|
ACTION:DISPLAY
|
||||||
|
END:VALARM
|
||||||
|
BEGIN:VALARM
|
||||||
|
TRIGGER;RELATED=END:-PT30M
|
||||||
|
ACTION:DISPLAY
|
||||||
|
END:VALARM
|
||||||
|
END:VTODO
|
||||||
|
END:VCALENDAR`,
|
||||||
|
},
|
||||||
|
wantVTask: &models.Task{
|
||||||
|
Title: "Todo #1",
|
||||||
|
UID: "randomuid",
|
||||||
|
Description: "Lorem Ipsum",
|
||||||
|
StartDate: time.Date(2023, 2, 28, 17, 0, 0, 0, config.GetTimeZone()),
|
||||||
|
DueDate: time.Date(2023, 3, 4, 15, 0, 0, 0, config.GetTimeZone()),
|
||||||
|
Reminders: []*models.TaskReminder{
|
||||||
|
{
|
||||||
|
RelativeTo: models.ReminderRelationDueDate,
|
||||||
|
RelativePeriod: -3600,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
RelativeTo: models.ReminderRelationStartDate,
|
||||||
|
RelativePeriod: -86400,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
RelativeTo: models.ReminderRelationEndDate,
|
||||||
|
RelativePeriod: -1800,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Updated: time.Unix(1543626724, 0).In(config.GetTimeZone()),
|
Updated: time.Unix(1543626724, 0).In(config.GetTimeZone()),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// {
|
|
||||||
// name: "With alarm (relative trigger)",
|
|
||||||
// args: args{content: `BEGIN:VCALENDAR
|
|
||||||
// VERSION:2.0
|
|
||||||
// METHOD:PUBLISH
|
|
||||||
// X-PUBLISHED-TTL:PT4H
|
|
||||||
// X-WR-CALNAME:test
|
|
||||||
// PRODID:-//RandomProdID which is not random//EN
|
|
||||||
// BEGIN:VTODO
|
|
||||||
// UID:randomuid
|
|
||||||
// DTSTAMP:20181201T011204
|
|
||||||
// SUMMARY:Todo #1
|
|
||||||
// DESCRIPTION:Lorem Ipsum
|
|
||||||
// DTSTART:20230228T170000Z
|
|
||||||
// DUE:20230304T150000Z
|
|
||||||
// BEGIN:VALARM
|
|
||||||
// TRIGGER:-PT60M
|
|
||||||
// ACTION:DISPLAY
|
|
||||||
// END:VALARM
|
|
||||||
// BEGIN:VALARM
|
|
||||||
// TRIGGER;RELATED=START:-P1D
|
|
||||||
// ACTION:DISPLAY
|
|
||||||
// END:VALARM
|
|
||||||
// BEGIN:VALARM
|
|
||||||
// TRIGGER;RELATED=END:-PT30M
|
|
||||||
// ACTION:DISPLAY
|
|
||||||
// END:VALARM
|
|
||||||
// END:VTODO
|
|
||||||
// END:VCALENDAR`,
|
|
||||||
// },
|
|
||||||
// wantVTask: &models.Task{
|
|
||||||
// Title: "Todo #1",
|
|
||||||
// UID: "randomuid",
|
|
||||||
// Description: "Lorem Ipsum",
|
|
||||||
// StartDate: time.Date(2023, 2, 28, 17, 0, 0, 0, config.GetTimeZone()),
|
|
||||||
// DueDate: time.Date(2023, 3, 4, 15, 0, 0, 0, config.GetTimeZone()),
|
|
||||||
// Reminders: []time.Time{
|
|
||||||
// time.Date(2023, 3, 4, 14, 0, 0, 0, config.GetTimeZone()),
|
|
||||||
// time.Date(2023, 2, 27, 17, 00, 0, 0, config.GetTimeZone()),
|
|
||||||
// time.Date(2023, 3, 4, 14, 30, 0, 0, config.GetTimeZone()),
|
|
||||||
// },
|
|
||||||
// Updated: time.Unix(1543626724, 0).In(config.GetTimeZone()),
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user