Skip to content

Conversation

@DeepDiver1975
Copy link
Contributor

@DeepDiver1975 DeepDiver1975 commented Feb 22, 2024

Todo:

  • add support for these props on PROPFIND
  • build the same for CardDAV MKCOL
@DeepDiver1975
Copy link
Contributor Author

@emersion please review

@DeepDiver1975 DeepDiver1975 force-pushed the feat/create-calendar-props branch from 36d2981 to c2ad716 Compare February 22, 2024 22:03
@DeepDiver1975 DeepDiver1975 changed the title fix: add support for more props on CalDAV MKCOL feat: add support for more props on CalDAV MKCOL and PROPFIND on calendars Feb 22, 2024
@DeepDiver1975
Copy link
Contributor Author

@emersion how can we get this moving? THX

"encoding/xml"
"fmt"
"github.com/emersion/go-webdav/internal"
"github.com/stretchr/testify/assert"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to not add the testify dependency.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Testify allows to write a bit more compact test code.
Which improves readability.

Copy link
Owner

@emersion emersion Mar 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a whole new library to learn. I prefer to write tests like the Go standard library does. Also, compact ≠ readable (quite the contrary in general).

calendarName = xml.Name{namespace, "calendar"}
calendarDataName = xml.Name{namespace, "calendar-data"}
calendarColorName = xml.Name{
Space: "http://apple.com/ns/ical/",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The standard way to set the color of a calendar is: https://datatracker.ietf.org/doc/html/rfc7986#section-5.9

This is a non-standard, Apple-specfic property. I'm not sure I want to support it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I never saw this one in real life. But happy to add this as well.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just adding my 2 cents: I have indeed also observed the proliferation of this pseudo-standard (apple.com/ns/ical) into many open-source clients (e.g. DavX5 sets it on MKCOL). On the other hand, from my experience, after initial calendar creation, this is treated as a pure client-side property by pretty much all clients (i.e. it never gets updated again), so not sure how necessary it really is...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so not sure how necessary it really is...

agreed - this is for sure a pretty low feature.
Never the less if the color is stored server side it will be "synced" once opening the calendar with another client which has some benefits of recognizing calendars.

e.g. on the owncloud 10 codebase (php+sabredav) colors are the same on all clients (owncloud calendar app in web, DAVx and iOS)

Copy link
Owner

@emersion emersion Apr 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, actually it doesn't seem like there is any standard way to fetch a VCALENDAR for the calendar itself in CalDAV. So RFC 7986 is only useful to set the calendar color when exporting a whole calendar as .ics.

Oh well, let's just do like everybody else then…

DisplayName string `xml:"set>prop>displayname"`
Description string `xml:"set>prop>calendar-description"`
CalendarColor string `xml:"set>prop>calendar-color"`
CalemdarTimeZone string `xml:"set>prop>calendar-timezone"`
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: "Calendar"

@emersion
Copy link
Owner

Some more general notes:

  • Please try to keep 1 commit (or 1 pull request) per separate feature
  • We don't use the "feat:" commit prefix, instead we prefix commit messages by the name of the Go package involved.
@DeepDiver1975 DeepDiver1975 force-pushed the feat/create-calendar-props branch from 89545b3 to 46d5e86 Compare April 9, 2024 10:54
@DeepDiver1975 DeepDiver1975 changed the title feat: add support for more props on CalDAV MKCOL and PROPFIND on calendars caldav: add support for more props on MKCOL and PROPFIND Apr 9, 2024
@DeepDiver1975 DeepDiver1975 force-pushed the feat/create-calendar-props branch from 46d5e86 to 96422a0 Compare April 9, 2024 10:57
@DeepDiver1975 DeepDiver1975 force-pushed the feat/create-calendar-props branch from 96422a0 to ab37619 Compare April 9, 2024 11:25
@DeepDiver1975
Copy link
Contributor Author

@emersion @bitfehler please review again - did not yet change the color prop name ... as explained above this is the property I see in real life .... 🤷

ResourceType internal.ResourceType `xml:"set>prop>resourcetype"`
DisplayName string `xml:"set>prop>displayname"`
Description string `xml:"set>prop>calendar-description"`
CalendarColor string `xml:"set>prop>calendar-color"`
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably specify the http://apple.com/ns/ical/ namespace for this prop?

Color string
MaxResourceSize int64
SupportedComponentSet []string
Timezone string
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be a parsed *ical.Calendar?

We should probably check that the parsed value contains exactly one VTIMEZONE component?

@Opisek
Copy link

Opisek commented Dec 27, 2024

I have a huge need for this feature in my project. How could I contribute to continue development of this?

@emersion
Copy link
Owner

Maybe open a new PR? Ideally changes would be logically split to ease review.

@Opisek
Copy link

Opisek commented Dec 28, 2024

Maybe open a new PR? Ideally changes would be logically split to ease review.

Not talking about the git aspect. Just wondering what is still missing or what's blocking this from being merged. Once I know which direction to go in, then I can branch off and create a PR later.

@emersion
Copy link
Owner

There are unresolved comments above.

@barkyq
Copy link

barkyq commented Jan 12, 2025

my 2 cents: one can split into:

  • one PR for the calendar-timezone property (there is unresolved comment concerning the fact that the timezone property should be a parsed icalendar object instead of a string)
  • one PR for the color property.
  • a separate PR to handle to MKCOL stuff; in general there seems to be some thing related to caldav: add MKCALENDAR support #177 because the calendars apps I have seen do not use MKCOL
@barkyq
Copy link

barkyq commented Jan 13, 2025

Here is the output of interaction between iOS calendar app and MWE.

One can see which properties iOS asks for.

2025/01/11 18:27:55 Starting CalDAV server on :8181 >------------- PROPFIND /.well-known/caldav context.Background.WithValue(net/http context value http-server, *http.Server).WithValue(net/http context value local-addr, 127.0.0.1:8181).WithCancel.WithCancel User-Agent: iOS/18.1.1 (22B91) dataaccessd/1.0 Prefer: return=minimal Brief: t Accept: */* Content-Type: text/xml Depth: 0 Accept-Encoding: gzip, deflate, br Accept-Language: fr-FR,fr;q=0.9 Connection: close Content-Length: 181 <------------- >------------- PROPFIND /user/ context.Background.WithValue(net/http context value http-server, *http.Server).WithValue(net/http context value local-addr, 127.0.0.1:8181).WithCancel.WithCancel Accept-Encoding: gzip, deflate, br User-Agent: iOS/18.1.1 (22B91) dataaccessd/1.0 Accept-Language: fr-FR,fr;q=0.9 Connection: close Depth: 0 Brief: t Content-Length: 181 Prefer: return=minimal Content-Type: text/xml Accept: */* <------------- <?xml version="1.0" encoding="UTF-8"?> <A:propfind xmlns:A="DAV:"> <A:prop> <A:current-user-principal/> <A:principal-URL/> <A:resourcetype/> </A:prop> </A:propfind> >------------- OPTIONS /user/ context.Background.WithValue(net/http context value http-server, *http.Server).WithValue(net/http context value local-addr, 127.0.0.1:8181).WithCancel.WithCancel Accept-Encoding: gzip, deflate, br User-Agent: iOS/18.1.1 (22B91) dataaccessd/1.0 Accept-Language: fr-FR,fr;q=0.9 Connection: close Content-Length: 0 Accept: */* <------------- >------------- PROPFIND /user/ context.Background.WithValue(net/http context value http-server, *http.Server).WithValue(net/http context value local-addr, 127.0.0.1:8181).WithCancel.WithCancel Brief: t User-Agent: iOS/18.1.1 (22B91) dataaccessd/1.0 Accept-Language: fr-FR,fr;q=0.9 Connection: close Content-Length: 181 Accept: */* Accept-Encoding: gzip, deflate, br Prefer: return=minimal Content-Type: text/xml Depth: 0 <------------- <?xml version="1.0" encoding="UTF-8"?> <A:propfind xmlns:A="DAV:"> <A:prop> <A:current-user-principal/> <A:principal-URL/> <A:resourcetype/> </A:prop> </A:propfind> >------------- OPTIONS /user/ context.Background.WithValue(net/http context value http-server, *http.Server).WithValue(net/http context value local-addr, 127.0.0.1:8181).WithCancel.WithCancel User-Agent: iOS/18.1.1 (22B91) dataaccessd/1.0 Accept-Language: fr-FR,fr;q=0.9 Connection: close Content-Length: 0 Accept: */* Accept-Encoding: gzip, deflate, br <------------- >------------- PROPFIND /user/ context.Background.WithValue(net/http context value http-server, *http.Server).WithValue(net/http context value local-addr, 127.0.0.1:8181).WithCancel.WithCancel Brief: t Accept: */* User-Agent: iOS/18.1.1 (22B91) dataaccessd/1.0 Accept-Language: fr-FR,fr;q=0.9 Content-Length: 819 Prefer: return=minimal Content-Type: text/xml Accept-Encoding: gzip, deflate, br Connection: close Depth: 0 <------------- <?xml version="1.0" encoding="UTF-8"?> <A:propfind xmlns:A="DAV:"> <A:prop> <B:calendar-home-set xmlns:B="urn:ietf:params:xml:ns:caldav"/> <B:calendar-user-address-set xmlns:B="urn:ietf:params:xml:ns:caldav"/> <A:current-user-principal/> <A:displayname/> <C:dropbox-home-URL xmlns:C="http://calendarserver.org/ns/"/> <C:email-address-set xmlns:C="http://calendarserver.org/ns/"/> <B:max-attendees-per-instance xmlns:B="urn:ietf:params:xml:ns:caldav"/> <C:notification-URL xmlns:C="http://calendarserver.org/ns/"/> <A:principal-collection-set/> <A:principal-URL/> <A:resource-id/> <B:schedule-inbox-URL xmlns:B="urn:ietf:params:xml:ns:caldav"/> <B:schedule-outbox-URL xmlns:B="urn:ietf:params:xml:ns:caldav"/> <A:supported-report-set/> </A:prop> </A:propfind> >------------- OPTIONS /user/ context.Background.WithValue(net/http context value http-server, *http.Server).WithValue(net/http context value local-addr, 127.0.0.1:8181).WithCancel.WithCancel Connection: close Content-Length: 0 Accept: */* Accept-Encoding: gzip, deflate, br User-Agent: iOS/18.1.1 (22B91) dataaccessd/1.0 Accept-Language: fr-FR,fr;q=0.9 <------------- >------------- PROPFIND /user/calendars/ context.Background.WithValue(net/http context value http-server, *http.Server).WithValue(net/http context value local-addr, 127.0.0.1:8181).WithCancel.WithCancel Prefer: return=minimal Depth: 1 Connection: close Content-Length: 2237 Content-Type: text/xml Brief: t Accept: */* Accept-Encoding: gzip, deflate, br User-Agent: iOS/18.1.1 (22B91) dataaccessd/1.0 Accept-Language: fr-FR,fr;q=0.9 <------------- <?xml version="1.0" encoding="UTF-8"?> <A:propfind xmlns:A="DAV:"> <A:prop> <A:add-member/> <C:allowed-sharing-modes xmlns:C="http://calendarserver.org/ns/"/> <D:autoprovisioned xmlns:D="http://apple.com/ns/ical/"/> <E:bulk-requests xmlns:E="http://me.com/_namespace/"/> <B:calendar-alarm xmlns:B="urn:ietf:params:xml:ns:caldav"/> <D:calendar-color xmlns:D="http://apple.com/ns/ical/"/> <B:calendar-description xmlns:B="urn:ietf:params:xml:ns:caldav"/> <B:calendar-free-busy-set xmlns:B="urn:ietf:params:xml:ns:caldav"/> <D:calendar-order xmlns:D="http://apple.com/ns/ical/"/> <B:calendar-timezone xmlns:B="urn:ietf:params:xml:ns:caldav"/> <A:current-user-privilege-set/> <B:default-alarm-vevent-date xmlns:B="urn:ietf:params:xml:ns:caldav"/> <B:default-alarm-vevent-datetime xmlns:B="urn:ietf:params:xml:ns:caldav"/> <A:displayname/> <C:getctag xmlns:C="http://calendarserver.org/ns/"/> <D:language-code xmlns:D="http://apple.com/ns/ical/"/> <D:location-code xmlns:D="http://apple.com/ns/ical/"/> <B:max-attendees-per-instance xmlns:B="urn:ietf:params:xml:ns:caldav"/> <A:owner/> <C:pre-publish-url xmlns:C="http://calendarserver.org/ns/"/> <C:publish-url xmlns:C="http://calendarserver.org/ns/"/> <C:push-transports xmlns:C="http://calendarserver.org/ns/"/> <C:pushkey xmlns:C="http://calendarserver.org/ns/"/> <A:quota-available-bytes/> <A:quota-used-bytes/> <D:refreshrate xmlns:D="http://apple.com/ns/ical/"/> <A:resource-id/> <A:resourcetype/> <B:schedule-calendar-transp xmlns:B="urn:ietf:params:xml:ns:caldav"/> <B:schedule-default-calendar-URL xmlns:B="urn:ietf:params:xml:ns:caldav"/> <C:source xmlns:C="http://calendarserver.org/ns/"/> <C:subscribed-strip-alarms xmlns:C="http://calendarserver.org/ns/"/> <C:subscribed-strip-attachments xmlns:C="http://calendarserver.org/ns/"/> <C:subscribed-strip-todos xmlns:C="http://calendarserver.org/ns/"/> <B:supported-calendar-component-set xmlns:B="urn:ietf:params:xml:ns:caldav"/> <B:supported-calendar-component-sets xmlns:B="urn:ietf:params:xml:ns:caldav"/> <A:supported-report-set/> <A:sync-token/> </A:prop> </A:propfind> >------------- PROPPATCH /user/calendars/default/ context.Background.WithValue(net/http context value http-server, *http.Server).WithValue(net/http context value local-addr, 127.0.0.1:8181).WithCancel.WithCancel User-Agent: iOS/18.1.1 (22B91) dataaccessd/1.0 Accept-Language: fr-FR,fr;q=0.9 Connection: close Content-Length: 163 Accept: */* Content-Type: text/xml Accept-Encoding: gzip, deflate, br <------------- <?xml version="1.0" encoding="UTF-8"?> <A:propertyupdate xmlns:A="DAV:"><A:set><A:prop><A:displayname>default</A:displayname></A:prop></A:set></A:propertyupdate> >------------- PROPPATCH /user/calendars/default/ context.Background.WithValue(net/http context value http-server, *http.Server).WithValue(net/http context value local-addr, 127.0.0.1:8181).WithCancel.WithCancel Accept-Language: fr-FR,fr;q=0.9 Connection: close Content-Length: 228 Accept: */* Content-Type: text/xml Accept-Encoding: gzip, deflate, br User-Agent: iOS/18.1.1 (22B91) dataaccessd/1.0 <------------- <?xml version="1.0" encoding="UTF-8"?> <A:propertyupdate xmlns:A="DAV:"><A:set><A:prop><D:calendar-color xmlns:D="http://apple.com/ns/ical/" symbolic-color="orange">#FF9500</D:calendar-color></A:prop></A:set></A:propertyupdate> >------------- PROPPATCH /user/calendars/default/ context.Background.WithValue(net/http context value http-server, *http.Server).WithValue(net/http context value local-addr, 127.0.0.1:8181).WithCancel.WithCancel Connection: close Content-Length: 198 Accept: */* Content-Type: text/xml Accept-Encoding: gzip, deflate, br User-Agent: iOS/18.1.1 (22B91) dataaccessd/1.0 Accept-Language: fr-FR,fr;q=0.9 <------------- <?xml version="1.0" encoding="UTF-8"?> <A:propertyupdate xmlns:A="DAV:"><A:set><A:prop><D:calendar-order xmlns:D="http://apple.com/ns/ical/">1</D:calendar-order></A:prop></A:set></A:propertyupdate> >------------- PROPFIND /user/calendars/default/ context.Background.WithValue(net/http context value http-server, *http.Server).WithValue(net/http context value local-addr, 127.0.0.1:8181).WithCancel.WithCancel Connection: close Content-Length: 181 Accept: */* Accept-Encoding: gzip, deflate, br Accept-Language: fr-FR,fr;q=0.9 Prefer: return=minimal Content-Type: text/xml Depth: 0 Brief: t User-Agent: iOS/18.1.1 (22B91) dataaccessd/1.0 <------------- <?xml version="1.0" encoding="UTF-8"?> <A:propfind xmlns:A="DAV:"> <A:prop> <C:getctag xmlns:C="http://calendarserver.org/ns/"/> <A:sync-token/> </A:prop> </A:propfind> >------------- PROPFIND /user/calendars/default/ context.Background.WithValue(net/http context value http-server, *http.Server).WithValue(net/http context value local-addr, 127.0.0.1:8181).WithCancel.WithCancel Content-Length: 145 Depth: 1 Accept: */* User-Agent: iOS/18.1.1 (22B91) dataaccessd/1.0 Accept-Language: fr-FR,fr;q=0.9 Connection: close Prefer: return=minimal Content-Type: text/xml Brief: t Accept-Encoding: gzip, deflate, br <------------- <?xml version="1.0" encoding="UTF-8"?> <A:propfind xmlns:A="DAV:"> <A:prop> <A:getcontenttype/> <A:getetag/> </A:prop> </A:propfind> signal: interrupt 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

5 participants