feat: multi-calendar CalDAV sync + macOS install script
org-caldav: - Sync personal calendar (twoway) + family calendar (fromcal/read-only) - Clean helper fns: my/caldav-get-password, my/caldav-register-digest - authinfo: add 'family' entry for family calendar password - ~/.authinfo: machine cal.apps.sukany.cz login family password PASS macos-install.sh: - Bootstrap script for fresh macOS: brew, Emacs prereqs, search tools - Perl (cpanm + LSP/Tidy/Critic), Python (ruff/pyright), Go (gopls) - Ansible, Terraform, Podman, Kubernetes, email (mu/isync) - Doom Emacs setup guidance
This commit is contained in:
79
config.el
79
config.el
@@ -1744,38 +1744,59 @@ current frame."
|
||||
org-caldav-files '("~/org/personal.org" "~/org/work.org")
|
||||
org-caldav-sync-direction 'twoway)
|
||||
|
||||
;; Baikal uses Digest auth. Pre-register credentials from ~/.authinfo
|
||||
;; so Emacs url package doesn't prompt interactively.
|
||||
(defun my/caldav-setup-digest-auth ()
|
||||
"Pre-register Baikal Digest auth. HA1 = MD5(user:realm:pass) from authinfo.
|
||||
Falls back to hardcoded hash if auth-source lookup fails.
|
||||
url-digest-auth-storage format: ((\"server:port\" (\"realm\" user ha1)) ...)"
|
||||
(require 'url-auth)
|
||||
(let* ((user "martin")
|
||||
(realm "BaikalDAV")
|
||||
(server "cal.apps.sukany.cz:443")
|
||||
(found (car (auth-source-search :host "cal.apps.sukany.cz"
|
||||
:user user :max 1)))
|
||||
(pass (when found
|
||||
(let ((s (plist-get found :secret)))
|
||||
(if (functionp s) (funcall s) s))))
|
||||
;; Compute HA1 from authinfo password, or use pre-computed fallback
|
||||
(ha1 (if pass
|
||||
(md5 (concat user ":" realm ":" pass))
|
||||
;; Fallback: MD5("martin:BaikalDAV:treasure-Hunter")
|
||||
"7cf9c41c78f4986fd65948029bcc4743")))
|
||||
(if (boundp 'url-digest-auth-storage)
|
||||
;; Modern Emacs: inject into url-digest-auth-storage
|
||||
(setq url-digest-auth-storage
|
||||
(list (list server (list realm user ha1))))
|
||||
;; Older Emacs: warn and skip
|
||||
(message "org-caldav: url-digest-auth-storage not available, auth may fail"))))
|
||||
(defun my/caldav-get-password (host user)
|
||||
"Fetch plaintext password from auth-source for HOST and USER."
|
||||
(let* ((found (car (auth-source-search :host host :user user :max 1)))
|
||||
(s (when found (plist-get found :secret))))
|
||||
(when s (if (functionp s) (funcall s) s))))
|
||||
|
||||
(defun my/caldav-register-digest (user realm server plaintext-pass)
|
||||
"Register Digest auth for USER@SERVER with realm REALM.
|
||||
Stores HA1 = MD5(user:realm:pass) in url-digest-auth-storage."
|
||||
(when (and (boundp 'url-digest-auth-storage) plaintext-pass)
|
||||
(let ((ha1 (md5 (concat user ":" realm ":" plaintext-pass))))
|
||||
(setf (alist-get server url-digest-auth-storage nil nil #'equal)
|
||||
(list (list realm user ha1))))))
|
||||
|
||||
(defun my/org-caldav-sync ()
|
||||
"Sync org-caldav after pre-registering Baikal Digest auth."
|
||||
"Sync org-caldav: personal calendar (twoway) + family calendar (read-only)."
|
||||
(interactive)
|
||||
(my/caldav-setup-digest-auth)
|
||||
(org-caldav-sync)))
|
||||
(require 'url-auth)
|
||||
(let* ((host "cal.apps.sukany.cz")
|
||||
(realm "BaikalDAV")
|
||||
(srv "cal.apps.sukany.cz:443")
|
||||
;; Get passwords from ~/.authinfo:
|
||||
;; machine cal.apps.sukany.cz login martin password PASS
|
||||
;; machine cal.apps.sukany.cz login family password PASS
|
||||
(pass-m (my/caldav-get-password host "martin"))
|
||||
(pass-f (my/caldav-get-password host "family")))
|
||||
|
||||
;; Fallback: pre-computed HA1 for martin if authinfo missing
|
||||
(if pass-m
|
||||
(my/caldav-register-digest "martin" realm srv pass-m)
|
||||
(when (boundp 'url-digest-auth-storage)
|
||||
(setf (alist-get srv url-digest-auth-storage nil nil #'equal)
|
||||
(list (list realm "martin" "7cf9c41c78f4986fd65948029bcc4743")))))
|
||||
|
||||
;; Sync personal calendar (twoway — new events go here)
|
||||
(setq org-caldav-url "https://cal.apps.sukany.cz/dav.php/calendars/martin"
|
||||
org-caldav-calendar-id "default"
|
||||
org-caldav-inbox "~/org/caldav-inbox.org"
|
||||
org-caldav-files '("~/org/personal.org" "~/org/work.org")
|
||||
org-caldav-sync-direction 'twoway)
|
||||
(org-caldav-sync)
|
||||
|
||||
;; Sync family calendar (fromcal = read-only, no writes back)
|
||||
(when pass-f
|
||||
(my/caldav-register-digest "family" realm srv pass-f))
|
||||
(setq org-caldav-url "https://cal.apps.sukany.cz/dav.php/calendars/family"
|
||||
org-caldav-calendar-id "default"
|
||||
org-caldav-inbox "~/org/family-calendar.org"
|
||||
org-caldav-files nil
|
||||
org-caldav-sync-direction 'fromcal)
|
||||
(org-caldav-sync)
|
||||
|
||||
(message "CalDAV sync complete: personal (twoway) + family (read-only)"))))
|
||||
|
||||
(map! :leader "o c" #'my/org-caldav-sync)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user