1

我正在尝试使用Sardine(和biweekly)从 CalDAV 服务器获取事件。获取整个日历对我有用:

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

现在我想获取特定时间范围的事件。根据这篇“构建 CalDAV 客户端”文章,我假设您应该使用 Sardinesreport方法来执行此操作,对吗?

如果是这样,您应该如何使用该方法?它没有在 wiki 中记录,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);

我在正确的轨道上吗?有人对如何编写自己的沙丁鱼报告有任何指示吗?

4

2 回答 2

1

您是对的,要运行时间范围查询,您需要发出一个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,它似乎不包括 CalDAV 查询。您可能可以基于他们的 SyncCollectionReport.java

请注意,对 的响应calendar-query REPORT只是常规的 WebDAV207 multi-status响应。不需要额外的东西。(Result对象将与它们的对象相同,SyncCollectionReport但没有额外的同步令牌)。

于 2016-06-28T13:29:37.257 回答
0

我已经实现了一个可以工作的报告类,但是,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;
    }

}
于 2016-06-28T13:49:37.680 回答