<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>CaldavonDocs</title><link>https://hiraethecho.github.io/docs/tags/caldav/</link><description>Recent contentinCaldavonDocs</description><generator>Hugo --0.152.2</generator><language>en</language><managingEditor>wyz2016zxc@outlook.com(Hiraeth)</managingEditor><webMaster>wyz2016zxc@outlook.com(Hiraeth)</webMaster><lastBuildDate>Mon, 16 Mar 2026 15:39:39 +0800</lastBuildDate><atom:link href="https://hiraethecho.github.io/docs/tags/caldav/index.xml" rel="self" type="application/rss+xml"/><item><title>caldav协议</title><link>https://hiraethecho.github.io/docs/dev/caldav/</link><pubDate>Mon, 30 Jun 2025 00:00:00 +0000</pubDate><author>wyz2016zxc@outlook.com(Hiraeth)</author><guid>https://hiraethecho.github.io/docs/dev/caldav/</guid><description>caldav是一个基于webdav的日历协议，可以用来同步日历数据。它是一个开放的标准，允许不同的日历应用程序和服务之间进行互操作。</description><content:encoded><![CDATA[<h1 id="caldav">
  <a class="anchor inpage" href="#caldav">#</a>Caldav</h1>
<h2 id="caldav-1">
  <a class="anchor inpage" href="#caldav-1">##</a>caldav</h2>
<p>caldav是一个基于webdav的日历协议，可以用来同步日历数据。它是一个开放的标准，允许不同的日历应用程序和服务之间进行互操作。</p>
<p>包括calendar、todo、event等。</p>
<h2 id="manage">
  <a class="anchor inpage" href="#manage">##</a>manage</h2>
<h3 id="todoman">
  <a class="anchor inpage" href="#todoman">###</a>todoman</h3>
<h3 id="khal">
  <a class="anchor inpage" href="#khal">###</a>khal</h3>
<h3 id="apple">
  <a class="anchor inpage" href="#apple">###</a>apple</h3>
<p>原生日历和提醒事项应用程序可以通过CalDAV协议与服务器进行同步。</p>
<h2 id="host-a-caldav">
  <a class="anchor inpage" href="#host-a-caldav">##</a>host a caldav</h2>
<h3 id="radicale">
  <a class="anchor inpage" href="#radicale">###</a>radicale</h3>
<h4 id="install-and-configurations">
  <a class="anchor inpage" href="#install-and-configurations">####</a>Install and configurations</h4>
<p>ref: 
:</p>
<p>Install radicale: 建议用包管理器安装，可以帮助解决依赖，以及创建<code>radicale</code>用户、创建文件夹之类的杂事。比如</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>sudo dnf install radicale</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>configurations:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang=""># /etc/radicale/config

[server]
hosts = [::]:5242, 0.0.0.0:5242 # ipv6, ipv4的host，从任何ip地址都可以访问
# hosts = localhost:5242 # 只允许本地地址访问
[auth]
type = htpasswd
htpasswd_encryption = autodetect
htpasswd_filename = /etc/radicale/users
[storage]
filesystem_folder = /var/lib/radicale/collections</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>set a user and passwd:</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>htpasswd -5 -c /path/to/users user1</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Start as a systemd service:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang=""># /etc/systemd/system/radicale.service
[Unit]
Description=A simple CalDAV (calendar) and CardDAV (contact) server
After=network.target
Requires=network.target

[Service]
ExecStart=/usr/bin/radicale --config /etc/radicale/confif
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/ /var/cache/radicale/

[Install]
WantedBy=multi-user.target</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>这样在<code>http://localhost:5242/</code>就可以访问web页面，可以创建collection等。</p>
<h4 id="host">
  <a class="anchor inpage" href="#host">####</a>host</h4>
<p>用<code>cloudflare</code>的zero trust - network - tunnel来将radicale服务暴露到公网。记得选https。</p>
<h3 id="baikal">
  <a class="anchor inpage" href="#baikal">###</a>baikal</h3>
<h2 id="connect-a-caldav">
  <a class="anchor inpage" href="#connect-a-caldav">##</a>connect a caldav</h2>
<h3 id="from-linux">
  <a class="anchor inpage" href="#from-linux">###</a>from linux</h3>
<p>vdirsync</p>
<h3 id="from-apple-to-caldav-server">
  <a class="anchor inpage" href="#from-apple-to-caldav-server">###</a>from apple to caldav server</h3>
<h3 id="to-apple-caldav">
  <a class="anchor inpage" href="#to-apple-caldav">###</a>To apple caldav</h3>
<p>ref:</p>
<ul>
<li>
</li>
<li>
</li>
</ul>
<p>云上贵州服务器</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">https://&lt;server-id&gt;-caldav.icloud.com.cn/&lt;user-id&gt;/calendars/&lt;calendar-id&gt;/</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>在网页版icloud的日历界面打开开发者工具，然后找<code>Network</code>里的<code>Get</code>请求，过滤<code>XHR</code>，然后找类似 <code>https://&lt;server-id&gt;-calendarws.icloud.com.cn/ca/eventdetail/&lt;calendar-id&gt;/&lt;event-id&gt;?clientBuildNumber=&lt;some-random-text&gt;&amp;clientId=&lt;some-random-text&gt;&amp;clientMasteringNumber=&lt;some-random-text&gt;&amp;clientVersion=&lt;some-random-text&gt;&amp;dsid=&lt;user-id&gt;&amp;lang=&lt;some-random-text&gt;&amp;requestID=&lt;some-random-text&gt;&amp;usertz=&lt;some-random-text&gt;</code>的内容。</p>
<p>用 
 将<code>icloud</code>的日历同步到本地，以<code>.ics</code>格式存储。</p>
<details open>
    <summary>conf</summary><pre
        class="codeblock"
      ><code class="language-conf" data-lang="conf">[storage cal]
type = &#34;caldav&#34;
url = &#34;https://caldav.icloud.com/&#34;
username = &#34;...&#34;
password = &#34;...&#34;

[storage card]
type = &#34;carddav&#34;
url = &#34;https://contacts.icloud.com/&#34;
username = &#34;...&#34;
password = &#34;...&#34;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>这里<code>username</code>就是用户名，而<code>password</code>是双重认证后再生成的app密码。服务器的话中国应该要<code>url = &quot;https://caldav.icloud.com.cn/&quot;</code></p>
<p>但是有两个问题：</p>
<ul>
<li>不支持<code>VTODO</code>格式，apple的提醒事项似乎不是这个协议。</li>
<li><code>icloud</code>如果有多个日历的话，标识id很长，难以记忆或使用，例如<code>87BBBA05-934B-4D5A-BB27-771A9CD413A2</code>。或者其中一个会被记为<code>home</code>，但是不知道什么规则。例如同步到<code>.local/share/calendars</code>后
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">~/.local/share/calendars
├── 87BBBA05-934B-4D5A-BB27-771A9CD413A2
└── home</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
</ul>
]]></content:encoded></item></channel></rss>