Reputation: 426
I'm attempting to quickly find free/busy time by fetching the calendar events for an iCloud calendar via CalDAV. I'm able to get the available calendars, and according to documentation here or using the DAViCal client library fetching the calendar information for a given date range should be as simple as sending this REPORT xml request to a calendar URL (ie. https://caldav.icloud.com/..userid../calendars/work/):
<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
<d:prop>
<d:getetag />
<c:calendar-data />
</d:prop>
<c:filter>
<c:comp-filter name="VCALENDAR">
<C:comp-filter name="VEVENT">
<C:time-range start="20131115T000000Z" end="20131201T000000Z"/>
</C:comp-filter>
</c:comp-filter>
</c:filter>
</c:calendar-query>
which is essentially what the GetEvents()
function does in the DAViCal library. However I'm just getting the URL for each calendar entry in the reply, rather than the calendar data itself:
<?xml version='1.0' encoding='UTF-8'?><multistatus xmlns='DAV:'>
<response>
<href>/..userid../calendars/work/8D2D90EB-BD23-4137-AD22-70D971C587F2.ics</href>
<propstat>
<prop>
<getetag>"C=7734@U=b09ce345-d654-491e-bb4a-55358e7019d9"</getetag>
<getcontenttype>text/calendar</getcontenttype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/..userid../calendars/work/AA2385AB-EA58-4625-AF87-6D4FB9405686.ics</href>
<propstat>
<prop>
<getetag>"C=7733@U=b09ce345-d654-491e-bb4a-55358e7019d9"</getetag>
<getcontenttype>text/calendar</getcontenttype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
...
</multistatus>
I can of course do a GET request for each individual calendar item, but obviously this is quite slow. Is there a trick to getting the calendar data downloaded in one request?
Upvotes: 4
Views: 11139
Reputation: 460
Now, apple calendar server supports both tags.
Iam using calendar server 9.0.
<?xml version="1.0" encoding="utf-8" ?>
<C:calendar-query
xmlns:D="DAV:"
xmlns:C="urn:ietf:params:xml:ns:caldav">
<D:prop>
<D:getetag />
<C:calendar-data>
<C:comp name="VCALENDAR">
<C:prop name="VERSION"/>
<C:comp name="VEVENT"></C:comp>
</C:comp>
<C:expand start="20170101T060000Z" end="20170630T060000Z"/>
</C:calendar-data>
</D:prop>
<C:filter>
<C:comp-filter name="VCALENDAR">
<C:comp-filter name="VEVENT">
<C:time-range end="20170630T060000Z" start="20170101T060000Z"/>
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>
Response -
<?xml version='1.0' encoding='UTF-8'?>
<multistatus xmlns='DAV:'>
<response>
<href>/calendars/users/test/calendar/43fdddd1-ad3a-4c00-ac63-a76d89e074da.ics</href>
<propstat>
<prop>
<getetag>"14db35d8d385ee62ced664efd56d3ac4"</getetag>
<calendar-data xmlns='urn:ietf:params:xml:ns:caldav'><![CDATA[BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:43fdddd1-ad3a-4c00-ac63-a76d89e074da
DTSTART;VALUE=DATE:20170110
DTEND;VALUE=DATE:20170111
CATEGORIES:Birthday
CREATED:20170130T070433Z
DESCRIPTION:Birthday from thunderbird
DTSTAMP:20170130T070515Z
LAST-MODIFIED:20170130T070515Z
SUMMARY:Test Event 123
TRANSP:TRANSPARENT
END:VEVENT
END:VCALENDAR
]]></calendar-data>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/calendars/users/test/calendar/53f7e764-9e46-4f7d-a851-714f9ea03ad1.ics</href>
<propstat>
<prop>
<getetag>"e08f17f5f7483d31017c5391a7618d9b"</getetag>
<calendar-data xmlns='urn:ietf:params:xml:ns:caldav'><![CDATA[BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:53f7e764-9e46-4f7d-a851-714f9ea03ad1
DTSTART:20170112T093000Z
DTEND:20170112T103000Z
CREATED:20170130T092637Z
DESCRIPTION:Time based Event
DTSTAMP:20170130T092651Z
LAST-MODIFIED:20170130T092651Z
SUMMARY:Time based Event
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR
]]></calendar-data>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/calendars/users/test/calendar/73a21941-ac24-492a-b00e-48d38feb7d01.ics</href>
<propstat>
<prop>
<getetag>"8bceb0306b81b67a8dfb2f5d95d76dd1"</getetag>
<calendar-data xmlns='urn:ietf:params:xml:ns:caldav'><![CDATA[BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:73a21941-ac24-492a-b00e-48d38feb7d01
DTSTART;VALUE=DATE:20170111
DTEND;VALUE=DATE:20170112
CATEGORIES:Favorites
CREATED:20170130T073845Z
DESCRIPTION:Duration Event Desc
DTSTAMP:20170130T092634Z
LAST-MODIFIED:20170130T092634Z
SEQUENCE:1
SUMMARY:Duration Event
TRANSP:TRANSPARENT
X-MOZ-GENERATION:1
END:VEVENT
END:VCALENDAR
]]></calendar-data>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
</multistatus>
Upvotes: 0
Reputation: 364
It works if you just include
<c:calendar-data />
and NOT
<d:getetag />
in the request, like this:
<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
<d:prop>
<c:calendar-data />
</d:prop>
<c:filter>
<c:comp-filter name="VCALENDAR">
<C:comp-filter name="VEVENT">
<C:time-range start="20131115T000000Z" end="20131201T000000Z"/>
</C:comp-filter>
</c:comp-filter>
</c:filter>
</c:calendar-query>
:-)
Upvotes: 4