diff options
authorLukas Fleischer <>2018-05-25 16:25:09 +0200
committerLukas Fleischer <>2018-05-25 16:25:45 +0200
commit9e8ceefb48b78306344528a8e203abd9d8912980 (patch)
parent14fed9433b6bc981f7114a1a99d90672dda95942 (diff)
Add an HTML version of the calcurse-caldav README
Signed-off-by: Lukas Fleischer <>
2 files changed, 170 insertions, 2 deletions
diff --git a/files/calcurse-caldav.html b/files/calcurse-caldav.html
new file mode 100644
index 0000000..c67933b
--- /dev/null
+++ b/files/calcurse-caldav.html
@@ -0,0 +1,168 @@
+<!DOCTYPE html>
+<html lang="en">
+<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
+<title>calcurse-caldav README</title>
+<style type="text/css">
+body { font-family: Georgia,serif; }
+h1, h2, h3, h4, h5, h6 { font-family: Arial,Helvetica,sans-serif; color: #527bbd; margin-top: 1.2em; margin-bottom: 0.5em; line-height: 1.3; }
+body { margin: 1em 5% 1em 5%; }
+a { color: blue; text-decoration: underline; }
+a:visited { color: fuchsia; }
+em { font-style: italic; color: navy; }
+strong { font-weight: bold; color: #083194; }
+h1, h2, h3 { border-bottom: 2px solid silver; }
+h2 { padding-top: 0.5em; } h3 { float: left; }
+h3 + * { clear: left; }
+h5 { font-size: 1.0em; }
+hr { border: 1px solid silver; }
+p { margin-top: 0.5em; margin-bottom: 0.5em; }
+code, pre { font-family: "Courier New", Courier, monospace; font-size: inherit; color: navy; padding: 0; margin: 0; }
+pre { border: 1px solid #dddddd; border-left: 5px solid #f0f0f0; background: #f8f8f8; padding: 0.5em; white-space: pre-wrap; }
+<p>calcurse-caldav is a simple Python script that can be used to synchronize
+calcurse with a CalDAV server. Please note that the script is alpha software!
+This means that:</p>
+<p>We are eagerly looking for testers to run the script and give feedback! If
+ you find any bugs, please report them to the calcurse mailing lists or to the
+ GitHub bug tracker. If the script works fine for you, please report back as
+ well!</p>
+<p>The script might still have bugs. MAKE BACKUPS, especially before running
+ calcurse-caldav for the first time!</p>
+<p>calcurse-caldav requires an up-to-date version of calcurse and a configuration
+file located at ~/.calcurse/caldav/config. An example configuration file can be
+found under contrib/caldav/config.sample in the calcurse source tree. You will
+also need to install <em>httplib2</em> for Python 3 using <em>pip</em> (e.g. <code>pip3 install
+--user httplib2</code>) or your distribution's package manager.</p>
+<p>If you run calcurse-caldav for the first time, you need to provide the <code>--init</code>
+argument. You can choose between the following initialization modes:</p>
+<pre><code>--init=keep-remote Remove all local calcurse items and import remote objects
+--init=keep-local Remove all remote objects and push local calcurse items
+--init=two-way Copy local objects to the CalDAV server and vice versa
+<p>For subsequent calcurse-caldav invocations, you don't need to specify any
+additional parameters.</p>
+<p>You can specify a username and password for basic authentication in the
+config file. Alternatively, the password can be passed securely from another
+program (such as <em>pass</em>) via the <code>CALCURSE_CALDAV_PASSWORD</code> environment variable like
+<pre><code>CALCURSE_CALDAV_PASSWORD=$(pass show calcurse) calcurse-caldav
+<p>You can place scripts in <code>$HOME/.calcurse/caldav/hooks/</code> to trigger actions at
+certain events. To enable a hook, add a script with one of the following names
+to this directory. Also make sure the scripts are executable.</p>
+ Executed before the data files are synchronized.
+ Executed after the data files are synchronized.</p>
+<p>Some examples can be found in the <code>contrib/caldav/hooks/</code> directory of the
+calcurse source tree.</p>
+<h2>How It Works</h2>
+<p>calcurse-caldav creates a so-called synchronization database at
+<code>~/.calcurse/caldav/sync.db</code> that always keeps a snapshot of the last time the
+script was executed. When running the script, it compares the objects on the
+server and the local objects with that snapshot to identify items that were
+added or deleted. It then</p>
+<li>downloads new objects from the server and imports them into calcurse,</li>
+<li>deletes local objects that no longer exist on the server,</li>
+<li>uploads objects to the server that were added locally,</li>
+<li>deleted objects from the server that were deleted locally,</li>
+<li>updates the synchronization database with a new snapshot.</li>
+<p>Note: Since calcurse does not use unique identifiers for items, it cannot keep
+track of moved/edited items. Thus, modifying an item is equivalent to deleting
+the old item and creating a new one.</p>
+<h2>OAuth2 Authentication</h2>
+<p>calcurse-caldav also has support for services requiring OAuth2 authentication
+such as Google Calendar. Note that you can only have a single calendar synced
+at any given time, regardless of authentication method. To enable OAuth2 you
+will need to:</p>
+<li>Change <em>AuthMethod</em> from "<em>basic</em>" to "<em>oauth2</em>" in your config file</li>
+<li>Fill in the appropriate settings in your config file: "<em>ClientID</em>",
+ "<em>ClientSecret</em>", "<em>Scope</em>", and "<em>RedirectURI</em>". These can be obtained from
+ the API provider. (See below for Google Calendar)</li>
+<li>Install <em>oauth2client</em> for Python 3 using <em>pip</em> (e.g. <code>pip3 install --user
+oauth2client</code>) or your distribution's package manager</li>
+<h2>Synchronization With Google Calendar</h2>
+<p>You will need to use your Google account to create a Google API project and
+enable both the CalDAV API and the Google Calendar API. We will be doing this to
+receive a Client ID and Client Secret. The hostname, path, scope and redirect
+URI are listed below.</p>
+<p>First, you will need to go to the <a href="">Google Developers Console</a> and click <em>Create
+Project</em>. After doing that, you can go to the <a href="">API Library</a> and
+search for the CalDAV API and enable it for your project. You will then need to
+do the same for the Google Calendar API.</p>
+<p>Next, go to the <a href="">Credentials page</a>
+, click on <em>Create credentials</em>, and choose <em>OAuth client ID</em>. If it asks you
+to "set a product name on the consent screen", click on <em>Configure consent
+screen</em> to do so. Any product name will do. Upon saving and returning to the
+"Create client ID" screen, choose <em>Other</em> as the Application type and click
+<em>Create</em>. You now have your Client ID and Client Secret to put into your
+calcurse-caldav config file!</p>
+<p>The following options should also be changed in your config file:</p>
+<pre><code>Hostname =
+Path = /caldav/v2/*your_calendar_id_here*/events/
+Scope =
+SyncFilter = cal
+<p>Your Calendar ID for "<em>Path</em>" should be your email for the default calendar.
+If you have multiple calendars, you can get the Calendar ID by going under
+Calendar Details at <a href=""></a>.
+The default Redirect URI in the config file is; this should
+work fine, but can be changed to http://localhost, a local web server, or
+another device if you encounter errors related to it.</p>
+<p>A complete config file for would have the following options:</p>
+Hostname =
+Path = /caldav/v2/
+AuthMethod = oauth2
+SyncFilter = cal
+ClientID =
+ClientSecret = XPYGqHFsfF343GwJeOGiUi
+Scope =
+RedirectURI =
+<p><a href="">The full guide from Google can be found here.</a></p>
+<p>Upon your first run with the <code>--init</code> flag, you will be asked to go to a URL to
+log in and authorize synchronization with your Google account. You can access
+this URL on any other device if you cannot open a browser locally (e.g., on
+a headless server). Once you authorize synchronization, you will be redirected
+to your Redirect URI with a code attached to the end, e.g.,
+<code></code>. You will need
+to copy the code after <code></code>. In this case, it would be
+<p>Finally pass this authorization code to calcurse-caldav with the <code>--authcode</code>
+flag and initialize the synchronization database like so (note that the quotes
+around the authorization code might be necessary or not, depending on your shell):</p>
+<pre><code>calcurse-caldav --init keep-remote --authcode '4/Ok6mBNW2nppfIwyL-Q1ZPVkEk3zZdZN3mHcY#'
diff --git a/support/index.html b/support/index.html
index 910f57a..be1d3b7 100644
--- a/support/index.html
+++ b/support/index.html
@@ -40,7 +40,7 @@
<dt>How do I setup CalDAV synchronization?</dt>
Check the
- <a href=""><tt>calcurse-caldav</tt> <tt>README</tt> file</a>.
+ <a href="/files/calcurse-caldav.html">calcurse-caldav documentation</a>.
<dt>Is it possible to get rid of the messages confirming loaded/saved data?</dt>
@@ -64,7 +64,7 @@
<li><a href="/files/manual.pdf">PDF</a> (171kB)</li>
<li><a href="/files/calcurse.1.html">calcurse(1) Manual Page</a> (28kB)</li>
- <li><a href=""><tt>calcurse-caldav</tt> <tt>README</tt></a></li>
+ <li><a href="/files/calcurse-caldav.html">calcurse-caldav documentation</a> (9kB)</li>