Calendar JavaScript中CalDAV的增量同步

Calendar JavaScript中CalDAV的增量同步,calendar,synchronization,contacts,caldav,carddav,Calendar,Synchronization,Contacts,Caldav,Carddav,我想从服务器获取CalDAV日历和地址簿,将值本地存储在磁盘上以缓存它们,并保存syncToken。然后,稍后,在某个时间间隔内或最晚在下一次启动应用程序时,再次运行同步。在第二次同步期间,我只想获取那些(确切地说是那些)已更改(包括添加、删除或修改)的日历条目和联系人 我无法从日历和通讯簿同步API的=,找出如何做到这一点。文件中没有描述这一点。有一个syncCalendar()函数,从名称上看,它应该做我需要做的事情,但是没有描述参数和整个过程。代码中有一个syncToken(还有一个cta

我想从服务器获取CalDAV日历和地址簿,将值本地存储在磁盘上以缓存它们,并保存syncToken。然后,稍后,在某个时间间隔内或最晚在下一次启动应用程序时,再次运行同步。在第二次同步期间,我只想获取那些(确切地说是那些)已更改(包括添加、删除或修改)的日历条目和联系人

我无法从日历和通讯簿同步API的=,找出如何做到这一点。文件中没有描述这一点。有一个
syncCalendar()
函数,从名称上看,它应该做我需要做的事情,但是没有描述参数和整个过程。代码中有一个
syncToken
(还有一个
ctag
etag
)。我正在尝试使用syncToken,它应该满足我的需要,但它没有

在同步之后,我获取日历.syncToken并存储它,在下一次同步之前(可能是在重新启动之后),我恢复syncToken。但我每次都能得到完全同步。似乎我使用的API是错误的,但我不知道什么是正确的

专用测试用例:

  • git克隆https://github.com/benbucksch/test-dav-sync/
  • 纱线安装
  • 纱线开始
  • 代码,用于自包含性:

    import dav from 'dav';
    import config from './config.js'; /* Pseudo JSON File with:
    export default
    {
      "serverURL": "https://...hostname.../remote.php/dav",
      "username": "...",
      "password": "..."
    }
    */
    
    var gJSONSavedFile = {}; // would normally be a file or database table
    
    async function start() {
      let syncToken = gJSONSavedFile.syncToken; // get it from file
      console.info("sync token from file", syncToken);
    
      console.time("calendar-connect");
      let xhr = new dav.transport.Basic(
        new dav.Credentials({
          username: config.username,
          password: config.password,
        })
      );
      let account = await dav.createAccount({
        server: config.serverURL,
        //loadCollections: false,
        //loadObjects: false,
        xhr: xhr,
      });
      console.timeEnd("calendar-connect");
      let calendar = account.calendars[0]; // just the first, just for testing
      console.time("calendar sync");
      console.log("sync token after init", calendar.syncToken);
      if (syncToken) {
        console.log("but setting sync token to", syncToken);
        calendar.syncToken = syncToken; // TODO Already set. Doesn't work.
      }
      calendar = await dav.syncCalendar(calendar, {
        syncToken: syncToken, // TODO Doesn't work
        xhr: xhr,
      });
      console.timeEnd("calendar sync");
      gJSONSavedFile.syncToken = calendar.syncToken; // save it
      console.log("sync token after sync", gJSONSavedFile.syncToken);
      console.log("Got", calendar.objects.length, "calendar entries");
    }
    
    
    (async () => {
      try {
        console.log("Test first start");
        await start();
        console.log("\nTest second start");
        await start();
      } catch (ex) {
        console.error(ex);
      }
    })();
    
    针对NextCloud运行时的输出:

    Test first start
    sync token from file undefined
    calendar-connect: 4.765s
    sync token after init http://sabre.io/ns/sync/1157
    calendar sync: 2.562s
    sync token after sync http://sabre.io/ns/sync/1157
    Got 1051 calendar entries
    
    Test second start
    sync token from file http://sabre.io/ns/sync/1157
    calendar-connect: 3.351s
    sync token after init http://sabre.io/ns/sync/1157
    but setting sync token to http://sabre.io/ns/sync/1157
    calendar sync: 2.510s
    sync token after sync http://sabre.io/ns/sync/1157
    Got 1051 calendar entries
    Done in 13.29s.
    
    预期产出将是:

  • 第二次同步返回0个条目
  • calendar.syncToken
    不会在初始化和登录后立即设置

  • syncToken
    已经在init之后设置,这表明我误解了这里的API。

    在深入分析dav库之后,我找到了如何与令牌同步的方法。(实际上请求的
    道具部分花费的时间最多,因为文档很差)

    由于
    syncCollection
    仅代表请求,因此需要手动发送请求,即需要执行以下操作:

  • 创建您的请求:
  • var req=dav.request.syncCollection({
    同步级别:1,
    syncToken:“http://sabre.io/ns/sync/138“,//这里您需要放置您的令牌
    道具:[{
    命名空间:“DAV:”,
    名称:“getetag”
    }],
    });
    
  • 发送请求:
  • var result=wait xhr.send(请求,'https://demo.calendar.com/dav/calendars/user_123/democalendar/')
    
    这将导致以下响应:

    结果{
    响应:
    [
    {
    href:'/dav/calendars/user_123/democalendar/4564659816516.ical',
    道具:[物体]
    }
    ],
    syncToken:'http://sabre.io/ns/sync/139'
    }
    
    经过对dav库的深入分析,我找到了如何与令牌同步的方法。(实际上请求的
    道具部分花费的时间最多,因为文档很差)

    由于
    syncCollection
    仅代表请求,因此需要手动发送请求,即需要执行以下操作:

  • 创建您的请求:
  • var req=dav.request.syncCollection({
    同步级别:1,
    syncToken:“http://sabre.io/ns/sync/138“,//这里您需要放置您的令牌
    道具:[{
    命名空间:“DAV:”,
    名称:“getetag”
    }],
    });
    
  • 发送请求:
  • var result=wait xhr.send(请求,'https://demo.calendar.com/dav/calendars/user_123/democalendar/')
    
    这将导致以下响应:

    结果{
    响应:
    [
    {
    href:'/dav/calendars/user_123/democalendar/4564659816516.ical',
    道具:[物体]
    }
    ],
    syncToken:'http://sabre.io/ns/sync/139'
    }
    
    我在找同样的。。。不幸的是,caldav的文档非常差。我认为
    dav.syncCalendar
    在选项对象中没有任何syncToken属性,至少我在源代码中找不到任何syncToken属性。我正在寻找相同的。。。不幸的是,caldav的文档非常差。我认为
    dav.syncCalendar
    在选项对象中没有任何syncToken属性,至少在源代码中找不到任何。