feat(caldav): Export Labels to Caldav (#1409)
Partially resolves https://kolaente.dev/vikunja/api/issues/1274 Co-authored-by: ce72 <christoph.ernst72@googlemail.com> Reviewed-on: https://kolaente.dev/vikunja/api/pulls/1409 Reviewed-by: konrad <k@knt.li> Co-authored-by: cernst <ce72@noreply.kolaente.de> Co-committed-by: cernst <ce72@noreply.kolaente.de>
This commit is contained in:
parent
d47535b831
commit
53197b85e3
@ -58,13 +58,13 @@ type Todo struct {
|
|||||||
Priority int64 // 0-9, 1 is highest
|
Priority int64 // 0-9, 1 is highest
|
||||||
RelatedToUID string
|
RelatedToUID string
|
||||||
Color string
|
Color string
|
||||||
|
Categories []string
|
||||||
Start time.Time
|
Start time.Time
|
||||||
End time.Time
|
End time.Time
|
||||||
DueDate time.Time
|
DueDate time.Time
|
||||||
Duration time.Duration
|
Duration time.Duration
|
||||||
RepeatAfter int64
|
RepeatAfter int64
|
||||||
RepeatMode models.TaskRepeatMode
|
RepeatMode models.TaskRepeatMode
|
||||||
|
|
||||||
Created time.Time
|
Created time.Time
|
||||||
Updated time.Time // last-mod
|
Updated time.Time // last-mod
|
||||||
@ -239,6 +239,11 @@ RRULE:FREQ=SECONDLY;INTERVAL=` + strconv.FormatInt(t.RepeatAfter, 10)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(t.Categories) > 0 {
|
||||||
|
caldavtodos += `
|
||||||
|
CATEGORIES:` + strings.Join(t.Categories, ",")
|
||||||
|
}
|
||||||
|
|
||||||
caldavtodos += `
|
caldavtodos += `
|
||||||
LAST-MODIFIED:` + makeCalDavTimeFromTimeStamp(t.Updated)
|
LAST-MODIFIED:` + makeCalDavTimeFromTimeStamp(t.Updated)
|
||||||
|
|
||||||
|
@ -481,6 +481,45 @@ DUE:20181201T011204Z
|
|||||||
RRULE:FREQ=SECONDLY;INTERVAL=435
|
RRULE:FREQ=SECONDLY;INTERVAL=435
|
||||||
LAST-MODIFIED:00010101T000000Z
|
LAST-MODIFIED:00010101T000000Z
|
||||||
END:VTODO
|
END:VTODO
|
||||||
|
END:VCALENDAR`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "with categories",
|
||||||
|
args: args{
|
||||||
|
config: &Config{
|
||||||
|
Name: "test",
|
||||||
|
ProdID: "RandomProdID which is not random",
|
||||||
|
Color: "ffffff",
|
||||||
|
},
|
||||||
|
todos: []*Todo{
|
||||||
|
{
|
||||||
|
Summary: "Todo #1",
|
||||||
|
UID: "randommduid",
|
||||||
|
Timestamp: time.Unix(1543626724, 0).In(config.GetTimeZone()),
|
||||||
|
Color: "affffe",
|
||||||
|
Categories: []string{"label1", "label2"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantCaldavtasks: `BEGIN:VCALENDAR
|
||||||
|
VERSION:2.0
|
||||||
|
METHOD:PUBLISH
|
||||||
|
X-PUBLISHED-TTL:PT4H
|
||||||
|
X-WR-CALNAME:test
|
||||||
|
PRODID:-//RandomProdID which is not random//EN
|
||||||
|
X-APPLE-CALENDAR-COLOR:#ffffffFF
|
||||||
|
X-OUTLOOK-COLOR:#ffffffFF
|
||||||
|
X-FUNAMBOL-COLOR:#ffffffFF
|
||||||
|
BEGIN:VTODO
|
||||||
|
UID:randommduid
|
||||||
|
DTSTAMP:20181201T011204Z
|
||||||
|
SUMMARY:Todo #1
|
||||||
|
X-APPLE-CALENDAR-COLOR:#affffeFF
|
||||||
|
X-OUTLOOK-COLOR:#affffeFF
|
||||||
|
X-FUNAMBOL-COLOR:#affffeFF
|
||||||
|
CATEGORIES:label1,label2
|
||||||
|
LAST-MODIFIED:00010101T000000Z
|
||||||
|
END:VTODO
|
||||||
END:VCALENDAR`,
|
END:VCALENDAR`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,10 @@ func GetCaldavTodosForTasks(list *models.ListWithTasksAndBuckets, listTasks []*m
|
|||||||
for _, t := range listTasks {
|
for _, t := range listTasks {
|
||||||
|
|
||||||
duration := t.EndDate.Sub(t.StartDate)
|
duration := t.EndDate.Sub(t.StartDate)
|
||||||
|
var categories []string
|
||||||
|
for _, label := range t.Labels {
|
||||||
|
categories = append(categories, label.Title)
|
||||||
|
}
|
||||||
|
|
||||||
caldavtodos = append(caldavtodos, &Todo{
|
caldavtodos = append(caldavtodos, &Todo{
|
||||||
Timestamp: t.Updated,
|
Timestamp: t.Updated,
|
||||||
@ -42,6 +46,7 @@ func GetCaldavTodosForTasks(list *models.ListWithTasksAndBuckets, listTasks []*m
|
|||||||
Description: t.Description,
|
Description: t.Description,
|
||||||
Completed: t.DoneAt,
|
Completed: t.DoneAt,
|
||||||
// Organizer: &t.CreatedBy, // Disabled until we figure out how this works
|
// Organizer: &t.CreatedBy, // Disabled until we figure out how this works
|
||||||
|
Categories: categories,
|
||||||
Priority: t.Priority,
|
Priority: t.Priority,
|
||||||
Start: t.StartDate,
|
Start: t.StartDate,
|
||||||
End: t.EndDate,
|
End: t.EndDate,
|
||||||
|
@ -99,3 +99,84 @@ END:VCALENDAR`,
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetCaldavTodosForTasks(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
list *models.ListWithTasksAndBuckets
|
||||||
|
tasks []*models.TaskWithComments
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
wantCaldav string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Format single Task as Caldav",
|
||||||
|
args: args{
|
||||||
|
list: &models.ListWithTasksAndBuckets{
|
||||||
|
List: models.List{
|
||||||
|
Title: "List title",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
tasks: []*models.TaskWithComments{
|
||||||
|
{
|
||||||
|
Task: models.Task{
|
||||||
|
Title: "Task 1",
|
||||||
|
UID: "randomuid",
|
||||||
|
Description: "Description",
|
||||||
|
Priority: 3,
|
||||||
|
Created: time.Unix(1543626721, 0).In(config.GetTimeZone()),
|
||||||
|
DueDate: time.Unix(1543626722, 0).In(config.GetTimeZone()),
|
||||||
|
StartDate: time.Unix(1543626723, 0).In(config.GetTimeZone()),
|
||||||
|
EndDate: time.Unix(1543626724, 0).In(config.GetTimeZone()),
|
||||||
|
Updated: time.Unix(1543626725, 0).In(config.GetTimeZone()),
|
||||||
|
DoneAt: time.Unix(1543626726, 0).In(config.GetTimeZone()),
|
||||||
|
RepeatAfter: 86400,
|
||||||
|
Labels: []*models.Label{
|
||||||
|
{
|
||||||
|
ID: 1,
|
||||||
|
Title: "label1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: 2,
|
||||||
|
Title: "label2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantCaldav: `BEGIN:VCALENDAR
|
||||||
|
VERSION:2.0
|
||||||
|
METHOD:PUBLISH
|
||||||
|
X-PUBLISHED-TTL:PT4H
|
||||||
|
X-WR-CALNAME:List title
|
||||||
|
PRODID:-//Vikunja Todo App//EN
|
||||||
|
BEGIN:VTODO
|
||||||
|
UID:randomuid
|
||||||
|
DTSTAMP:20181201T011205Z
|
||||||
|
SUMMARY:Task 1
|
||||||
|
DTSTART:20181201T011203Z
|
||||||
|
DTEND:20181201T011204Z
|
||||||
|
DESCRIPTION:Description
|
||||||
|
COMPLETED:20181201T011206Z
|
||||||
|
STATUS:COMPLETED
|
||||||
|
DUE:20181201T011202Z
|
||||||
|
CREATED:20181201T011201Z
|
||||||
|
PRIORITY:3
|
||||||
|
RRULE:FREQ=SECONDLY;INTERVAL=86400
|
||||||
|
CATEGORIES:label1,label2
|
||||||
|
LAST-MODIFIED:20181201T011205Z
|
||||||
|
END:VTODO
|
||||||
|
END:VCALENDAR`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := GetCaldavTodosForTasks(tt.args.list, tt.args.tasks)
|
||||||
|
if diff, equal := messagediff.PrettyDiff(got, tt.wantCaldav); !equal {
|
||||||
|
t.Errorf("GetCaldavTodosForTasks() gotVTask = %v, want %v, diff = %s", got, tt.wantCaldav, diff)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user