feat(caldav): Export Labels to Caldav (#1409)
continuous-integration/drone/push Build is passing Details

Partially resolves vikunja/api#1274

Co-authored-by: ce72 <christoph.ernst72@googlemail.com>
Reviewed-on: vikunja/api#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:
cernst 2023-02-27 11:22:42 +00:00 committed by konrad
parent d47535b831
commit 53197b85e3
4 changed files with 137 additions and 7 deletions

View File

@ -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)

View File

@ -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`,
}, },
} }

View File

@ -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,

View File

@ -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)
}
})
}
}