fix(caldav): make sure colors are correctly saved and returned
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Resolves https://community.vikunja.io/t/caldav-sync-tasks-org-strips-colour-and-end-date-values/2753/2
This commit is contained in:
parent
5aa0b6a0cf
commit
ffcc48ec87
@ -92,7 +92,8 @@ func getCaldavColor(color string) (caldavcolor string) {
|
||||
return `
|
||||
X-APPLE-CALENDAR-COLOR:` + color + `
|
||||
X-OUTLOOK-COLOR:` + color + `
|
||||
X-FUNAMBOL-COLOR:` + color
|
||||
X-FUNAMBOL-COLOR:` + color + `
|
||||
COLOR:` + color
|
||||
}
|
||||
|
||||
func formatDuration(duration time.Duration) string {
|
||||
|
@ -64,6 +64,7 @@ PRODID:-//RandomProdID which is not random//EN
|
||||
X-APPLE-CALENDAR-COLOR:#ffffffFF
|
||||
X-OUTLOOK-COLOR:#ffffffFF
|
||||
X-FUNAMBOL-COLOR:#ffffffFF
|
||||
COLOR:#ffffffFF
|
||||
BEGIN:VTODO
|
||||
UID:randommduid
|
||||
DTSTAMP:20181201T011204Z
|
||||
@ -71,6 +72,7 @@ SUMMARY:Todo #1
|
||||
X-APPLE-CALENDAR-COLOR:#affffeFF
|
||||
X-OUTLOOK-COLOR:#affffeFF
|
||||
X-FUNAMBOL-COLOR:#affffeFF
|
||||
COLOR:#affffeFF
|
||||
DESCRIPTION:Lorem Ipsum\nDolor sit amet
|
||||
LAST-MODIFIED:00010101T000000Z
|
||||
END:VTODO
|
||||
@ -241,6 +243,7 @@ PRODID:-//RandomProdID which is not random//EN
|
||||
X-APPLE-CALENDAR-COLOR:#ffffffFF
|
||||
X-OUTLOOK-COLOR:#ffffffFF
|
||||
X-FUNAMBOL-COLOR:#ffffffFF
|
||||
COLOR:#ffffffFF
|
||||
BEGIN:VTODO
|
||||
UID:randommduid
|
||||
DTSTAMP:20181201T011204Z
|
||||
@ -248,6 +251,7 @@ SUMMARY:Todo #1
|
||||
X-APPLE-CALENDAR-COLOR:#affffeFF
|
||||
X-OUTLOOK-COLOR:#affffeFF
|
||||
X-FUNAMBOL-COLOR:#affffeFF
|
||||
COLOR:#affffeFF
|
||||
CATEGORIES:label1,label2
|
||||
LAST-MODIFIED:00010101T000000Z
|
||||
END:VTODO
|
||||
|
@ -30,6 +30,160 @@ import (
|
||||
ics "github.com/arran4/golang-ical"
|
||||
)
|
||||
|
||||
var cssColorsToHex map[string]string
|
||||
|
||||
func init() {
|
||||
cssColorsToHex = map[string]string{
|
||||
"aliceblue": "f0f8ff",
|
||||
"antiquewhite": "faebd7",
|
||||
"aqua": "00ffff",
|
||||
"aquamarine": "7fffd4",
|
||||
"azure": "f0ffff",
|
||||
"beige": "f5f5dc",
|
||||
"bisque": "ffe4c4",
|
||||
"black": "000000",
|
||||
"blanchedalmond": "ffebcd",
|
||||
"blue": "0000ff",
|
||||
"blueviolet": "8a2be2",
|
||||
"brown": "a52a2a",
|
||||
"burlywood": "deb887",
|
||||
"cadetblue": "5f9ea0",
|
||||
"chartreuse": "7fff00",
|
||||
"chocolate": "d2691e",
|
||||
"coral": "ff7f50",
|
||||
"cornflowerblue": "6495ed",
|
||||
"cornsilk": "fff8dc",
|
||||
"crimson": "dc143c",
|
||||
"cyan": "00ffff",
|
||||
"darkblue": "00008b",
|
||||
"darkcyan": "008b8b",
|
||||
"darkgoldenrod": "b8860b",
|
||||
"darkgray": "a9a9a9",
|
||||
"darkgreen": "006400",
|
||||
"darkgrey": "a9a9a9",
|
||||
"darkkhaki": "bdb76b",
|
||||
"darkmagenta": "8b008b",
|
||||
"darkolivegreen": "556b2f",
|
||||
"darkorange": "ff8c00",
|
||||
"darkorchid": "9932cc",
|
||||
"darkred": "8b0000",
|
||||
"darksalmon": "e9967a",
|
||||
"darkseagreen": "8fbc8f",
|
||||
"darkslateblue": "483d8b",
|
||||
"darkslategray": "2f4f4f",
|
||||
"darkslategrey": "2f4f4f",
|
||||
"darkturquoise": "00ced1",
|
||||
"darkviolet": "9400d3",
|
||||
"deeppink": "ff1493",
|
||||
"deepskyblue": "00bfff",
|
||||
"dimgray": "696969",
|
||||
"dimgrey": "696969",
|
||||
"dodgerblue": "1e90ff",
|
||||
"firebrick": "b22222",
|
||||
"floralwhite": "fffaf0",
|
||||
"forestgreen": "228b22",
|
||||
"fuchsia": "ff00ff",
|
||||
"gainsboro": "dcdcdc",
|
||||
"ghostwhite": "f8f8ff",
|
||||
"gold": "ffd700",
|
||||
"goldenrod": "daa520",
|
||||
"gray": "808080",
|
||||
"green": "008000",
|
||||
"greenyellow": "adff2f",
|
||||
"grey": "808080",
|
||||
"honeydew": "f0fff0",
|
||||
"hotpink": "ff69b4",
|
||||
"indianred": "cd5c5c",
|
||||
"indigo": "4b0082",
|
||||
"ivory": "fffff0",
|
||||
"khaki": "f0e68c",
|
||||
"lavender": "e6e6fa",
|
||||
"lavenderblush": "fff0f5",
|
||||
"lawngreen": "7cfc00",
|
||||
"lemonchiffon": "fffacd",
|
||||
"lightblue": "add8e6",
|
||||
"lightcoral": "f08080",
|
||||
"lightcyan": "e0ffff",
|
||||
"lightgoldenrodyellow": "fafad2",
|
||||
"lightgray": "d3d3d3",
|
||||
"lightgreen": "90ee90",
|
||||
"lightgrey": "d3d3d3",
|
||||
"lightpink": "ffb6c1",
|
||||
"lightsalmon": "ffa07a",
|
||||
"lightseagreen": "20b2aa",
|
||||
"lightskyblue": "87cefa",
|
||||
"lightslategray": "778899",
|
||||
"lightslategrey": "778899",
|
||||
"lightsteelblue": "b0c4de",
|
||||
"lightyellow": "ffffe0",
|
||||
"lime": "00ff00",
|
||||
"limegreen": "32cd32",
|
||||
"linen": "faf0e6",
|
||||
"magenta": "ff00ff",
|
||||
"maroon": "800000",
|
||||
"mediumaquamarine": "66cdaa",
|
||||
"mediumblue": "0000cd",
|
||||
"mediumorchid": "ba55d3",
|
||||
"mediumpurple": "9370db",
|
||||
"mediumseagreen": "3cb371",
|
||||
"mediumslateblue": "7b68ee",
|
||||
"mediumspringgreen": "00fa9a",
|
||||
"mediumturquoise": "48d1cc",
|
||||
"mediumvioletred": "c71585",
|
||||
"midnightblue": "191970",
|
||||
"mintcream": "f5fffa",
|
||||
"mistyrose": "ffe4e1",
|
||||
"moccasin": "ffe4b5",
|
||||
"navajowhite": "ffdead",
|
||||
"navy": "000080",
|
||||
"oldlace": "fdf5e6",
|
||||
"olive": "808000",
|
||||
"olivedrab": "6b8e23",
|
||||
"orange": "ffa500",
|
||||
"orangered": "ff4500",
|
||||
"orchid": "da70d6",
|
||||
"palegoldenrod": "eee8aa",
|
||||
"palegreen": "98fb98",
|
||||
"paleturquoise": "afeeee",
|
||||
"palevioletred": "db7093",
|
||||
"papayawhip": "ffefd5",
|
||||
"peachpuff": "ffdab9",
|
||||
"peru": "cd853f",
|
||||
"pink": "ffc0cb",
|
||||
"plum": "dda0dd",
|
||||
"powderblue": "b0e0e6",
|
||||
"purple": "800080",
|
||||
"red": "ff0000",
|
||||
"rosybrown": "bc8f8f",
|
||||
"royalblue": "4169e1",
|
||||
"saddlebrown": "8b4513",
|
||||
"salmon": "fa8072",
|
||||
"sandybrown": "f4a460",
|
||||
"seagreen": "2e8b57",
|
||||
"seashell": "fff5ee",
|
||||
"sienna": "a0522d",
|
||||
"silver": "c0c0c0",
|
||||
"skyblue": "87ceeb",
|
||||
"slateblue": "6a5acd",
|
||||
"slategray": "708090",
|
||||
"slategrey": "708090",
|
||||
"snow": "fffafa",
|
||||
"springgreen": "00ff7f",
|
||||
"steelblue": "4682b4",
|
||||
"tan": "d2b48c",
|
||||
"teal": "008080",
|
||||
"thistle": "d8bfd8",
|
||||
"tomato": "ff6347",
|
||||
"turquoise": "40e0d0",
|
||||
"violet": "ee82ee",
|
||||
"wheat": "f5deb3",
|
||||
"white": "ffffff",
|
||||
"whitesmoke": "f5f5f5",
|
||||
"yellow": "ffff00",
|
||||
"yellowgreen": "9acd32",
|
||||
}
|
||||
}
|
||||
|
||||
func GetCaldavTodosForTasks(project *models.ProjectWithTasksAndBuckets, projectTasks []*models.TaskWithComments) string {
|
||||
|
||||
// Make caldav todos from Vikunja todos
|
||||
@ -90,6 +244,27 @@ func GetCaldavTodosForTasks(project *models.ProjectWithTasksAndBuckets, projectT
|
||||
return ParseTodos(caldavConfig, caldavtodos)
|
||||
}
|
||||
|
||||
func getHexColorFromCaldavColor(caldavColor string) string {
|
||||
if caldavColor == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
if caldavColor[:1] == "#" {
|
||||
caldavColor = strings.TrimPrefix(caldavColor, "#")
|
||||
if len(caldavColor) > 6 {
|
||||
caldavColor = caldavColor[:6]
|
||||
}
|
||||
return caldavColor
|
||||
}
|
||||
|
||||
hexColor, has := cssColorsToHex[caldavColor]
|
||||
if !has {
|
||||
return ""
|
||||
}
|
||||
|
||||
return hexColor
|
||||
}
|
||||
|
||||
func ParseTaskFromVTODO(content string) (vTask *models.Task, err error) {
|
||||
parsed, err := ics.ParseCalendar(strings.NewReader(content))
|
||||
if err != nil {
|
||||
@ -104,12 +279,26 @@ func ParseTaskFromVTODO(content string) (vTask *models.Task, err error) {
|
||||
}
|
||||
// We put the vTodo details in a map to be able to handle them more easily
|
||||
task := make(map[string]ics.IANAProperty)
|
||||
|
||||
var relations []ics.IANAProperty
|
||||
var color string
|
||||
for _, c := range vTodo.UnknownPropertiesIANAProperties() {
|
||||
task[c.IANAToken] = c
|
||||
if strings.HasPrefix(c.IANAToken, "RELATED-TO") {
|
||||
relations = append(relations, c)
|
||||
}
|
||||
if c.IANAToken == "X-APPLE-CALENDAR-COLOR" {
|
||||
color = c.Value
|
||||
}
|
||||
if c.IANAToken == "X-OUTLOOK-COLOR" {
|
||||
color = c.Value
|
||||
}
|
||||
if c.IANAToken == "X-FUNAMBOL-COLOR" {
|
||||
color = c.Value
|
||||
}
|
||||
if c.IANAToken == "COLOR" {
|
||||
color = c.Value
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the priority
|
||||
@ -150,6 +339,7 @@ func ParseTaskFromVTODO(content string) (vTask *models.Task, err error) {
|
||||
Updated: caldavTimeToTimestamp(task["DTSTAMP"]),
|
||||
StartDate: caldavTimeToTimestamp(task["DTSTART"]),
|
||||
DoneAt: caldavTimeToTimestamp(task["COMPLETED"]),
|
||||
HexColor: getHexColorFromCaldavColor(color),
|
||||
}
|
||||
|
||||
for _, c := range relations {
|
||||
|
@ -353,6 +353,142 @@ END:VCALENDAR`,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with apple hex color",
|
||||
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
|
||||
X-APPLE-CALENDAR-COLOR:#affffeFF
|
||||
END:VTODO
|
||||
END:VCALENDAR`,
|
||||
},
|
||||
wantVTask: &models.Task{
|
||||
HexColor: "affffe",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with apple css color",
|
||||
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
|
||||
X-APPLE-CALENDAR-COLOR:mediumslateblue
|
||||
END:VTODO
|
||||
END:VCALENDAR`,
|
||||
},
|
||||
wantVTask: &models.Task{
|
||||
HexColor: "7b68ee",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with outlook hex color",
|
||||
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
|
||||
X-OUTLOOK-COLOR:#affffeFF
|
||||
END:VTODO
|
||||
END:VCALENDAR`,
|
||||
},
|
||||
wantVTask: &models.Task{
|
||||
HexColor: "affffe",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with outlook css color",
|
||||
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
|
||||
X-OUTLOOK-COLOR:mediumslateblue
|
||||
END:VTODO
|
||||
END:VCALENDAR`,
|
||||
},
|
||||
wantVTask: &models.Task{
|
||||
HexColor: "7b68ee",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with funambol hex color",
|
||||
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
|
||||
X-FUNAMBOL-COLOR:#affffeFF
|
||||
END:VTODO
|
||||
END:VCALENDAR`,
|
||||
},
|
||||
wantVTask: &models.Task{
|
||||
HexColor: "affffe",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with funambol css color",
|
||||
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
|
||||
X-FUNAMBOL-COLOR:mediumslateblue
|
||||
END:VTODO
|
||||
END:VCALENDAR`,
|
||||
},
|
||||
wantVTask: &models.Task{
|
||||
HexColor: "7b68ee",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with hex color",
|
||||
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
|
||||
COLOR:#affffeFF
|
||||
END:VTODO
|
||||
END:VCALENDAR`,
|
||||
},
|
||||
wantVTask: &models.Task{
|
||||
HexColor: "affffe",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with css color",
|
||||
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
|
||||
COLOR:mediumslateblue
|
||||
END:VTODO
|
||||
END:VCALENDAR`,
|
||||
},
|
||||
wantVTask: &models.Task{
|
||||
HexColor: "7b68ee",
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user