跨平台日历同步:使用 CalDAV 和 Radicale 打造个人日历云服务

大家好,我是张晋涛。

前段时间,群里有小伙伴提出想听听我在"时间管理"方面的一些经验,可惜一直没能抽出时间来分享。于是乎,我决定干脆写一篇博客来详细介绍一下吧。

chat

在我看来,"时间管理"可以分为两个核心部分,分别是:

  • 日程管理
  • 任务管理

日程管理 主要涉及到那些有计划的事件,例如会议、各类行程、直播、家庭活动等。这类事件通常是提前规划好的,并且有明确的开始和结束时间。虽然偶尔也会遇到一些不确定因素,如改期或者超时等。但在大多数情况下,我们仍然能够清楚地知道在某个时间段需要完成什么任务,而且这些时间节点通常是无法更改的。在后续安排其他事情的时候,需要尽量避开这些时间段,以免冲突。

任务管理 则主要是一系列的待办事项,这些事情有优先级,有目标,有 deadline 等。可能有多个来源,比如工作,社区,一些合作等。但是这些任务的执行并不像固定日程那样,有明确的时间段,可能会根据任务的难度,目标,优先级之类的进行一些调整。如果想要知道自己在哪些任务上的耗时,就搭配个时间追踪工具即可。

我在这篇中会主要介绍我在日程管理上的经验, 至于任务管理,因为它涉及的内容太多,我就之后再写一篇吧。

集中式日程管理

日程通常具备排他性,日程安排时需要尽量避免出现冲突,所以集中式的日程管理是非常有必要的。

我的日程来源有很多种,比如公司在用 Feishu 日历,社区中在用 Google 日历,一些的其他会议活动可能会安排在各类会议软件中, 比如我经常参与线上的直播都在用腾讯会议之类的。还有一些私人邮箱中的活动,以及一些研讨会,或者 Conference 会有自己单独的日历。

另一方面,我希望能及时的收到日程提醒,所以不能完全依赖于电脑,移动设备是刚需。其实我更依赖的是 Apple Watch,因为我手机是常年静音(看不看的到随缘了), 手表上有日程提醒的话,更容易看到。

所以我的集中式日程管理就选择了 用 iOS 的系统日历 了,电脑上的话直接 Thunderbird 做集成。

iOS 的系统日历中想要查看 Feishu 和 Google 日历都还是比较简单的,在 设置 - 账户 中,添加账户或者订阅日历就可以。以下是参考文档:

  • Add Google Calendar events to Apple Calendar - iPhone & iPad - Google Calendar Help
  • 个人用户如何设置本地系统日历到飞书日历的单向同步

但对于我来说,还缺少一些不在这两个系统内的日程,幸好 iOS 的日历支持添加 CalDAV 账户,所以这就是解决问题的关键了。Thunderbird 也同样支持。

选择 CalDAV server

先来聊下 CalDAV 是什么。

CalDAV(Calendar Distributed Authoring and Versioning)是一种基于 WebDAV 协议的网络日历访问协议,允许用户在不同设备和应用程序之间访问、管理和共享日历数据。CalDAV 主要使用 iCalendar(iCal)格式来存储和传输日历信息。

CalDAV的主要作用包括:

  • 跨设备和应用程序同步日历数据:CalDAV 协议使得用户能够在多个设备(如手机、平板和电脑)和不同的日历应用程序之间同步日历数据,从而实现统一的日程管理。
  • 多用户日历共享和协作:CalDAV 支持多用户之间的日历共享,允许多用户查看和编辑彼此的日程安排,便于提升协作效率。
  • 与现有的日历应用程序兼容:许多流行的日历应用程序,如 Google Calendar、Apple Calendar 和 Microsoft Outlook 等,都支持 CalDAV 协议。这意味着用户可以在不更换日历应用程序的情况下使用 CalDAV 功能。
  • 支持离线访问和修改:CalDAV 允许用户在离线状态下访问和修改日历数据,当设备重新连接到互联网时,所有更改将自动同步到服务器和其他设备上。

所以我只要有一个支持 CalDAV 的 server,并在其他的地方将日程写入,就可以直接在手机上查看这些日程了。

关于 CalDAV server 的选择有很多,我随便搜了下 CalDAV | Tasks.org

CalDAV server

对我而言主要考虑如下方面:

  • 需要能满足我的需求,可以用其他支持 CalDAV 的客户端进行订阅;
  • 尽可能轻量,因为我的目标很清晰,对其他功能没依赖;
  • 可以支持认证鉴权,为了让自己更轻松,日历中通常会包含很多关键信息,我不想让信息泄漏;

经过一番对比,我最终选择了 Radicale 作为我的 CalDAV Server 。

Radicale

Radicale 是一个用 Python 开发的 CalDAV 和 CardDAV server,主要有如下功能:

  • 支持通过 CalDAV、CardDAV 和 HTTP 进行分享;
  • 支持认证鉴权;
  • 开箱即用;
  • 可以通过 plugin 进行扩展;
  • 支持绝对多数的 client;
  • 直接通过文件存储,无需额外依赖;
  • GPLv3 授权的开源软件

事实上它的使用很简单,直接执行如下命令就可以启动了。

代码语言:javascript
复制
python3 -m pip install --upgrade radicale
python3 -m radicale --storage-filesystem-folder=~/.var/lib/radicale/collections

但如果想要把服务暴露到公网的时候,建议把认证打开,上面默认的启动方法是不开认证的。

我之前是直接通过把它作为一个 systemd service 运行的,官方文档中也有示例。

代码语言:javascript
复制
[Unit]
Description=A simple CalDAV (calendar) and CardDAV (contact) server
After=network.target
Requires=network.target

[Service]
ExecStart=/usr/bin/env python3 -m radicale
Restart=on-failure
User=radicale

Deny other users access to the calendar data

UMask=0027

Optional security settings

PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
PrivateDevices=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
NoNewPrivileges=true
ReadWritePaths=/var/lib/radicale/collections

[Install]
WantedBy=multi-user.target

不过前段时间迁机房,我顺手把它改容器化的方式部署了。有兴趣的小伙伴可以看下,仓库地址是 https://github.com/tao12345666333/radicale

可以先写一个配置文件 radicale.ini,其中 [auth][rights] 部分是进行认证和鉴权,可以参考文档进行修改 Radicale: Authentication and Rights

代码语言:javascript
复制
[server]
hosts = 0.0.0.0:5232

[auth]
type = htpasswd
htpasswd_filename = /radicale/users
htpasswd_encryption = md5

[rights]
type = from_file
file = /radicale/rights.ini

[storage]
filesystem_folder = /radicale/collections

然后使用如下命令启动即可。

代码语言:javascript
复制
docker run --restart unless-stopped -d -p 127.0.0.1:5232:5232 -v $PWD:/radicale ghcr.io/tao12345666333/radicale:v23.07.16 python3 -m radicale --config=/radicale/radicale.ini

使用 Kubernetes 部署的话也同样,配置文件写入 ConfigMap,注意把数据文件挂载 volume 进行持久化。

最后在 iOS 的设置 - 日历 - 账户 中添加账户即可,电脑上的话,我使用 Thunderbird 直接添加日历即可。

ios CalDAV

总结

日程管理相对来说比较简单,有集中式管理会比较方便,避免安排出现冲突。我的一些活动类日程可能提前一两周甚至一两个月就确定下了,邮件确认后直接添加进日历,全平台进行同步。

当然,Radicale 除了支持日历外,还支持 task 和通过 CalDAV 同步联系人,有需要的小伙伴也可以自行探索下。

TheMoeLove