Agendafs: A filesystem for syncing notes to your calendar

3 months ago 2

#agendafs

Todo | Mailing List + Patches

Screenshot

Agendafs is a FUSE-based filesystem for writing notes. It creates a shim over vdir storages, allowing you to write notes as regular files and synchronize them back to a caldav server. It supports directories, categories, arbitrary metadata and access rights.

#Status

Agendafs is still in early development and is alpha-level software. It probably leaks memory, destroys files and might summon demons. However, I use it daily for my note-taking mostly without issues. If you try it out, I recommend creating a new calendar specifically for agendafs and also regularly backing up your notes elsewhere.

#Installation

Prerequisites: scdoc (man pages), C compiler (currently only tested with gcc), libfuse, libuuid, libical and pkg-config. Optionally a shell.nix exists which sets up all dependencies for you.

Some fields, such as categories, are accessed via xattributes (xattr(7)), for that you will need to have the xattribute utilities installed.

You also need to setup a tool that syncs vdir storages to a caldav server, like vdirsyncer or pimsync.

To build:

git clone https://sr.ht/~marcc/agendafs/ cd agendafs make make install

#Basic principles

Agendafs uses a vdir storage as a backend to allow users to sync VJOURNAL entries to a remote caldav server.

Each vdir entry is represented as a file or directory in Agendafs. Edit these files like you would on a regular filesystem. VJOURNAL entries that have a parent relationships are represented as directories. Some VJOURNAL attributes can also be accessed via xattr(7). Currently supported attributes are:

  • user.categories - comma separated list of categories
  • user.class - Can be either private, public, confidential.

You can also store arbitrary metadata under other user attributes.

Agendafs pairs well with file explorers like ranger, lf or nnn.

#Usage

To mount a vdir storage with Agendafs:

mount.agendafs -o vdir=<vdir directory> <mountpoint>

See agendafs(8) for full list of options and examples.

#Limitations

Some major features are missing before a beta release:

Depending on the caldav server, there might be limitations as to how big a file can be. Usually the limit of one entry is ~5MB, but agendafs does currently not enforce any file size limit.

#Motivation

Note-taking tools like Obsidian and Logseq have great syncing capabilities, but they restrict you to only those editors. I wanted a solution that is more Unixy, allowing me to combine tools and build automation on top. However, when I stored my notes in plain-text, I struggled to find a good solution for syncing and editing notes on other devices. Since I had signed up to an email provider, and thus had a caldav server for my calendar, I thought it'd be a great place to store my notes. Storing notes in ical-format means that I can also take advantage of mobile apps for editing my notes, such as jtx Board on Android.

Agendafs also takes advantage of Xattributes to store categories (aka tags), classification (public vs private) and allows you to store arbitrary metadata to the file. This means that it frees you from just using one file-format while still giving you capabilities to link notes, either via directories or via categories (sibling linking exists in the ical spec, but this is not supported yet). This means Agendafs pairs well with CLI tools, file explorers like nnn, lf, ranger and also editors like Kakoune and Neovim.

Of course, you can also ignore all of that and just use Agendafs as a way to just backup your todotxt or jrnl.

#Appendix

#VJOURNAL support in Nextcloud calendar

To have vjournal support on Nextcloud, I needed to create the calendar manually. This is probably also required in Fastmail.

curl -X MKCALENDAR \ -u me:me \ -H 'Content-Type: application/xml; charset=utf-8' \ -d "<?xml version='1.0' encoding='UTF-8'?> <mkcalendar xmlns='urn:ietf:params:xml:ns:caldav'> <set> <prop> <displayname xmlns='DAV:'>Journal</displayname> <calendar-description xmlns='urn:ietf:params:xml:ns:caldav'>Calendar with VJOURNAL support</calendar-description> <supported-calendar-component-set xmlns='urn:ietf:params:xml:ns:caldav'> <comp name='VEVENT'/> <comp name='VTODO'/> <comp name='VJOURNAL'/> </supported-calendar-component-set> </prop> </set> </mkcalendar>" \ 'https://my-nextcloud-server/remote.php/dav/calendars/me/journal'

#Categories

Categories require xattributes to be installed. See the man pages of xattr(7), setfattr(1), getfattr(1) for basic usage.

#Find all files with categories, and their categories
$ find . -type f -exec getfattr -n user.categories {} + 2>/dev/null
#Find files by category
$ find . -type f -exec getfattr -n user.categories {} + 2>/dev/null | grep -B1 "MY_CATEGORY" | grep '^# file' | awk '{ print substr($0, 9) }'

#Find files by category with nnn

Add the following function to your profile to search for files matching a category.

find_by_category() { category=$1 if [ -z "$category" ]; then echo "Usage: find_by_category <category>" >&2 return 1 fi find . -type f | while read -r file; do fullpath=$(realpath "$file") value=$(getfattr --only-values -n user.categories -- "$file" 2>/dev/null) case $value in *"$category"*) printf '%s\0' "$fullpath" ;; esac done }

Usage: find_by_category MY_CATEGORY | nnn

#Why C?

I started this project to improve my C skills.

Read Entire Article