aboutsummaryrefslogtreecommitdiffstats
path: root/bin
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-09-18 09:26:32 +0200
committerDanilo M. <danix@danix.xyz>2026-09-18 09:26:32 +0200
commitc64bf67e15b075182deb4eebead8315c9081ac46 (patch)
treefaa8bbce23d9f2358b606727f5c36707e2ac2acb /bin
parent6aee635dd0cc5bab4fe3a989e41cea7faa75a9e1 (diff)
downloadconky-theme-udt-c64bf67e15b075182deb4eebead8315c9081ac46.tar.gz
conky-theme-udt-c64bf67e15b075182deb4eebead8315c9081ac46.zip
feat: add a calendar card reading khal
The month grid with the week's appointments below it, colour-coded by calendar. Events come from a cache file rather than a live call: khal costs about 200ms of Python startup, which is two orders of magnitude over the 2-second draw budget, so bin/calendar-sample.sh writes the cache on a 5-minute execi and the widget only parses. Calendar colours are read out of khal's own config by the sampler and mapped onto the board's palette roles, so the card follows a scheme change instead of pinning three literal hues. khal will not emit an ISO date: {start-date} uses the user's dateformat, which carries no year here, and a strftime spec inside the field raises. The sampler asks for {start-date-long} and data.calendar_date recovers the numbers by position, resolving day/month by magnitude and reading a genuinely ambiguous pair day-first. A 2-digit year is refused rather than guessed at. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'bin')
-rwxr-xr-xbin/calendar-sample.sh76
1 files changed, 76 insertions, 0 deletions
diff --git a/bin/calendar-sample.sh b/bin/calendar-sample.sh
new file mode 100755
index 0000000..1937cf6
--- /dev/null
+++ b/bin/calendar-sample.sh
@@ -0,0 +1,76 @@
+#!/bin/bash
+# Sample khal's upcoming events into a cache file, for widgets/calendar.lua.
+#
+# Conky's Lua has no way to run a process, and shelling out to khal every two
+# seconds would fork a Python interpreter per draw. khal takes ~200ms to start,
+# which is two orders of magnitude more than the whole frame budget.
+
+set -u
+
+CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/udt"
+CACHE="$CACHE_DIR/calendar.txt"
+
+umask 077
+mkdir -p "$CACHE_DIR"
+
+TMP="$CACHE.tmp.$$"
+trap 'rm -f "$TMP"' EXIT
+
+# {start-date-long}, not {start-date}: the latter renders with khal's
+# `dateformat`, which here is '%d.%m.' with no year at all, so an event in
+# January sorts before one in December of the year before and the widget cannot
+# tell which is which. The long form uses `longdateformat` and carries the
+# year. Both are the user's own format strings and khal offers no ISO override
+# (a strftime spec inside the field, '{start-date:%Y-%m-%d}', raises), so the
+# widget parses the three numbers out by position rather than assuming an
+# order.
+#
+# --day-format '' suppresses the 'Today, 18.09.2026' header lines khal
+# interleaves between days; without it every group of events is preceded by a
+# line that does not parse as a record.
+#
+# Fields are pipe-separated: a title may contain anything except a newline, so
+# the separator has to be a character no date, time or calendar name uses, and
+# the parser splits on the first four only, leaving the title intact even if it
+# contains a pipe itself.
+#
+# 8d, not 7d: khal's range is exclusive of the final day in practice for
+# all-day events, and one extra day costs nothing but avoids a birthday
+# vanishing from the card on the morning it matters.
+EVENTS=$(khal list --day-format '' \
+ --format '{start-date-long}|{start-time}|{end-time}|{calendar}|{title}' \
+ --notstarted today 8d 2>/dev/null)
+
+# khal's exit status is 0 even with no calendars configured, so emptiness is
+# not distinguishable from failure by status alone. The widget treats a missing
+# 'generated' key as "the sampler never ran" and an empty event list as "no
+# events", which are genuinely different states and read differently on the
+# card.
+{
+ echo "generated $(date +%s)"
+ date +'today %Y-%m-%d'
+ # Calendar colours, as khal itself declares them. Parsed from khal's config
+ # rather than hardcoded, so adding a calendar does not mean editing Lua.
+ # Only the [[name]] / color = value pairs inside [calendars]; the section
+ # test stops at the next top-level [section] so a 'color' key elsewhere in
+ # the config cannot be misread as a calendar's.
+ awk '
+ /^\[calendars\]/ { in_cal = 1; next }
+ /^\[[^[]/ { in_cal = 0 }
+ in_cal && /^\[\[/ {
+ name = $0
+ gsub(/^\[\[|\]\]$/, "", name)
+ next
+ }
+ in_cal && /^[ \t]*color[ \t]*=/ {
+ sub(/^[^=]*=[ \t]*/, "")
+ if (name != "") print "color " name " " $0
+ }
+ ' "${XDG_CONFIG_HOME:-$HOME/.config}/khal/config" 2>/dev/null
+
+ if [ -n "$EVENTS" ]; then
+ printf '%s\n' "$EVENTS" | sed 's/^/event /'
+ fi
+} > "$TMP"
+
+mv -f "$TMP" "$CACHE"