Использование метода отчета Sardines для запроса событий с сервера CalDAV

Я пытаюсь получить события с сервера CalDAV, используя Sardineраз в две недели). У меня работает получение всего календаря:

Sardine sardine = SardineFactory.begin();
InputStream is = sardine.get(CALDAV_URL_STRING);
ICalendar iCalendar = Biweekly.parse(is).first();

Теперь я хотел бы получить события для определенного диапазона времени. Основываясь на этой статье "Создание клиента CalDAV", я предполагаю, что вам следует использовать Сардины report способ сделать это, не так ли?

Если да, то как следует использовать этот метод? Это не задокументировано в вики, и Javadoc также не очень ясен.

Должен ли я написать свой собственный SardineReport? Похоже, я должен получить что-то вроде:

Sardine sardine = SardineFactory.begin();
SardineReport<List<VEvent>> report = new MyRangeReport(FROM_DATE, END_DATE);
List<VEvent> result = sardine.report(CALDAV_URL_STRING, 1, report);

Я на правильном пути? Кто-нибудь знает, как написать свой собственный отчет о Сардине?


person Jasper de Vries    schedule 27.06.2016    source источник


Ответы (2)


Вы правы, чтобы выполнить запрос диапазона времени, вам нужно выполнить HTTP-запрос REPORT, содержащий calendar-query. Пример можно найти в RFC 4719, раздел 7.8.1. Я не знаю Сардину, но да, report звучит правильно ;-)

Упрощено еще больше:

 REPORT /bernard/work/ HTTP/1.1
 Host: cal.example.com
 Depth: 1
 Content-Type: application/xml; charset="utf-8"
 Content-Length: xxxx

 <?xml version="1.0" encoding="utf-8" ?>
 <calendar-query xmlns:D="DAV:" xmlns="urn:ietf:params:xml:ns:caldav">
   <D:prop>
     <D:getetag/>
     <calendar-data />
   </D:prop>
   <filter>
     <comp-filter name="VCALENDAR">
       <comp-filter name="VEVENT">
         <time-range start="20060104T000000Z" end="20060105T000000Z"/>
       </comp-filter>
     </comp-filter>
  </filter>
</calendar-query>

Должен ли я написать свой собственный SardineReport?

Похоже, что сканирование GitHub Sardine не включает запросы CalDAV. Вероятно, вы можете основываться на их SyncCollectionReport.java.

Обратите внимание, что ответ на calendar-query REPORT — это обычный ответ WebDAV 207 multi-status. Ничего дополнительно не требуется. (объект Result будет таким же, как в их SyncCollectionReport, но без дополнительного syncToken).

person hnh    schedule 28.06.2016
comment
Спасибо! Я уже написал свой собственный класс отчета, который возвращает результаты. Я начинаю задаваться вопросом, поддерживает ли Radicale (сервер, который мы используем) фильтр time-range. - person Jasper de Vries; 28.06.2016
comment
Я не знаю, но этот ответ предполагает, что это не так. Проверьте комментарий: Проблема заключается в Radicale. Перешел на SabreDAV, теперь работает - person hnh; 28.06.2016
comment
Спасибо. Я думаю, нам нужно проверить sabre/dav. Для документации я добавил свой класс отчета. - person Jasper de Vries; 28.06.2016

Я реализовал класс отчета, который работает, однако результат, возвращаемый Radicale, кажется неверным. Похоже, Radicale не поддерживает фильтр time-range.

Для чего это стоит, вот соответствующие фрагменты отчета:

public class VEventsTimeRangeSardineReport extends SardineReport<List<VEvent>>
{

    ...

    @Override
    public String toXml() throws IOException
    {
        // Hardcode for now
        String xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" +
                     "<c:calendar-query xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n" +
                     "  <d:prop>\n" +
                     "    <c:calendar-data/>\n" +
                     "    <d:getetag/>\n" +
                     "  </d:prop>\n" +
                     "  <c:filter>\n" +
                     "    <c:comp-filter name=\"VCALENDAR\">\n" +
                     "      <c:comp-filter name=\"VEVENT\">\n" +
                     "        <c:time-range start=\"%s\" end=\"%s\"/>\n" +
                     "      </c:comp-filter>\n" +
                     "    </c:comp-filter>\n" +
                     "  </c:filter>\n" +
                     "</c:calendar-query>";
        return String.format(xml, SDF.format(fromDate), SDF.format(toDate));
    }


    @Override
    public List<VEvent> fromMultistatus(Multistatus multistatus)
    {
        List<VEvent> events = new ArrayList<>(multistatus.getResponse().size());
        for (Response response : multistatus.getResponse()) {
            // Here response.getPropstat().get(0).getProp().getAny().get(0).getFirstChild().getTextContent() is parsed
            events.addAll(ICalendarSardineReport.getICalendar(response).getEvents());
        }
        return events;
    }


    @Override
    public Object toJaxb()
    {
        return null;
    }

}
person Jasper de Vries    schedule 28.06.2016