目录

Emacs Elfeed 跨设备同步

GENERATED BY AI..

1 问题

Elfeed 数据库无法跨设备同步,导致阅读进度不一致。

2 解决方案

使用 rclone + 坚果云 WebDAV 实现双向同步。

3 文件

rclone 配置 (~/.dot-files/utils/.config/rclone/rclone.conf)

1
2
3
4
5
6
[jianguoyun]
type = webdav
url = https://dav.jianguoyun.com/dav
vendor = jianguoyun
user = [YOUR_EMAIL]
pass = [YOUR_PASSWORD]

坚果云支持 WebDAV,通过 rclone 挂载后即可像操作本地文件一样同步。

同步脚本 (~/.dot-files/emacs/.emacs.d/tools/elfeed-sync.sh)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/usr/bin/env bash
###
### sync elfeed database
###
### Usage:
###  elfeed-sync.sh [OPTIONS] <upload|download>
###
### Options:
###   -h, --help    Show this message.
###   -D, --debug   Debug mode, output debug logs.

source ~/.local/share/shell/yc-common.sh
abort-if-no-network

[[ $# -eq 0 ]] && die "Usage: elfeed-sync.sh download/upload"

LOCAL="${HOME}"/.cache/rclone/
REMOTE="jianguoyun:elfeed"

(
    if ! [[ -d "${LOCAL}"/elfeed ]]; then
        mkdir -p "${LOCAL}"
        cd "${LOCAL}"
        rclone copy ${REMOTE} elfeed
    fi

    cd "${LOCAL}"
    pinfo "    elfeed-sync: $1"
    case "$1" in
        d | download) rclone sync "${REMOTE}" elfeed ;;
        u | upload) rclone sync elfeed "${REMOTE}" ;;
        *) die "Operation not support: $1" ;;
    esac
)

脚本支持 downloadupload 两个操作: 首次运行时, 若本地目录不存在, 先用 rclone copy 从云端完整复制; 后续则用 rclone sync 增量同步。=abort-if-no-network= 确保无网络时不会执行。

4 同步时机

  • /异步同步/:=elfeed-db-save= 后自动触发 upload,不阻塞 Emacs。
  • /等待同步/:启动 Emacs 前手动 download,或在 Emacs 关闭时等待 upload 完成。
  • /最佳实践/:启动前 download,退出前 upload,避免用其他设备前先 download。

5 Emacs 集成

数据库路径

1
(elfeed-db-directory (f-expand "~/.cache/rclone/elfeed"))

与同步脚本的本地路径 ~/.cache/rclone/elfeed 一致,确保 Emacs 读写与 rclone 同步操作的是同一份数据。

自动同步

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
(defadvice! :after 'elfeed-db-save yc/after-elfeed-db-save-a (&rest _)
  "Synchronize database for elfeed."
  (let ((proc (start-process "elfeed-sync" nil
                             (f-expand "~/.emacs.d/tools/elfeed-sync.sh") "upload")))
    (set-process-filter proc (lambda (_ msg) (message "%s" msg)))
    (set-process-sentinel
     proc (lambda (_ event)
            (message "Elfeed sync %s" event)
            (unless (zerop (process-exit-status proc))
              (if yc/emacs-shutting-down
                  (message "WARNING: Elfeed sync failed with code %d" (process-exit-status proc))
                (display-warning 'elfeed (format "Elfeed sync failed with code %d"
                                           (process-exit-status proc))
                                 :error)))))
    (when (bound-and-true-p yc/emacs-shutting-down)
      (let ((tmo 30))
        (while (and (process-live-p proc) (> tmo 0))
          (sit-for 0.5)
          (cl-decf tmo))
        (when (process-live-p proc)
          (message "Elfeed sync still running, detaching."))))))

利用 defadvice!elfeed-db-save 后异步启动 elfeed-sync.sh upload=,不阻塞 Emacs 正常操作。若 Emacs 正在关闭 (=yc/emacs-shutting-down),则等待最多 30 秒确保同步完成后再退出。

网络配置

1
2
(elfeed-use-curl t)
(elfeed-curl-extra-arguments (yc/get-curl-proxy))

使用 curl 获取 RSS 内容,并通过代理访问。

6 总结

  • 数据库放在 =~/.cache/rclone/elfeed=,由 rclone 与坚果云双向同步。
  • elfeed-db-save 时自动上传;启动前手动下载。
  • 借助坚果云 WebDAV 实现跨设备数据一致,无需额外服务器。