NEXT What is TT-RSS?
TT-RSS on The Wobserver
with some extra plugins ...
The tt-rss plugin sources are pulled in as flake inputs pinned by flake.lock:
ttrss_wallabag = {
url = "github:joshp23/ttrss-to-wallabag-v2";
flake = false;
};large_apod = {
url = "github:joshp23/TTRSS-APOD-Fix";
flake = false;
};ttrss_readability = {
url = "git+https://gitlab.tt-rss.org/tt-rss/plugins/ttrss-af-readability";
flake = false;
};elfeed-sync = {
url = "github:SqrtMinusOne/elfeed-sync";
flake = false;
};ttrss_adaptive_score = {
url = "git+https://code.rix.si/rrix/ttrss_adaptive_score";
flake = false;
};{ inputs, pkgs, ... }:
let
wallabag = pkgs.stdenv.mkDerivation rec {
pname = "tt-rss-plugin-wallabag";
version = "2.0.0";
src = inputs.ttrss_wallabag;
installPhase = ''
mkdir -p $out/wallabag_v2
cp -r wallabag_v2/* $out/wallabag_v2/
'';
};
large_apod = pkgs.stdenv.mkDerivation rec {
pname = "tt-rss-plugin-large-apod";
version = "0.0.1";
src = inputs.large_apod;
installPhase = ''
mkdir -p $out/large_apod
cp -r large_apod/* $out/large_apod
'';
};
readability = pkgs.stdenv.mkDerivation rec {
pname = "tt-rss-plugin-af_readability";
version = "0.0.1";
src = inputs.ttrss_readability;
installPhase = ''
mkdir -p $out/af_readability
cp -r ./* $out/af_readability
'';
};
elfeed_sync = pkgs.stdenv.mkDerivation rec {
pname = "tt-rss-plugin-elfeed_sync";
version = "0.1.1";
src = inputs.elfeed-sync;
installPhase = ''
mkdir -p $out/elfeed_sync
cp -r ./* $out/elfeed_sync
'';
};
adaptive_score = pkgs.stdenv.mkDerivation rec {
pname = "tt-rss-plugin-adaptive_score";
version = "1.0.0";
src = inputs.ttrss_adaptive_score;
installPhase = ''
mkdir -p $out/adaptive_score
cp -r ./* $out/adaptive_score
'';
};
in {
services.nginx.virtualHosts."feeds.whatthefuck.computer" = {
extraConfig = ''
client_max_body_size 10M;
fastcgi_read_timeout 600;
'';
addSSL = true;
useACMEHost = "fontkeming.fail";
};
services.tt-rss = {
enable = true;
database = {
type = "pgsql";
};
logDestination = "syslog";
root = "/srv/tt-rss";
selfUrlPath = "https://feeds.whatthefuck.computer";
virtualHost = "feeds.whatthefuck.computer";
pluginPackages = [
wallabag
large_apod
readability
elfeed_sync
adaptive_score
];
plugins = [
"auth_internal"
"note"
"wallabag_v2"
"large_apod"
"af_readability"
"elfeed_sync"
"adaptive_score"
];
};
}Syncing tt-rss in Emacs with Elfeed
Linked from
Base elfeed configuration
(use-package elfeed
:config
;; add feeds' embedded categories as elfeed tags like tt-rss does
(defun cce/elfeed-category-tags (entry)
(let* ((m (elfeed-entry-meta entry))
(cats (plist-get m :categories))
(sym-cats (-map (lambda (cat) (make-symbol cat)) cats)))
(when cats
(apply (apply-partially #'elfeed-tag entry)
sym-cats))))
(add-to-list 'elfeed-new-entry-hook #'cce/elfeed-category-tags))Elfeed Summary and Evil Mode bindings for it
(use-package elfeed-summary
:config
(add-to-list 'display-buffer-alist '("\\`\\*elfeed-summary" (display-buffer-full-frame)))
(evil-collection-set-readonly-bindings 'elfeed-search-mode-map)
(evil-set-initial-state 'elfeed-search-mode 'normal)
(evil-collection-define-key 'normal 'elfeed-summary-mode-map
(kbd "<tab>") #'magit-section-toggle
(kbd "RET") #'elfeed-summary--action
(kbd "M-RET") #'elfeed-summary--action-show-read
"R" #'elfeed-summary-update
"U" #'elfeed-summary--action-mark-read
"h" #'magit-section-up
"j" #'evil-next-line
"J" #'magit-section-forward
"k" #'evil-previous-line
"K" #'magit-section-backward
"p" #'elfeed-summary-update-at-point
"r" #'elfeed-summary--refresh
"u" #'elfeed-summary-toggle-only-unread
;; quit
"q" 'elfeed-summary-quit-window
"ZQ" 'elfeed-summary-quit-window
"ZZ" 'elfeed-summary-quit-window)
(evil-collection-define-key 'normal 'elfeed-show-mode
"n" #'elfeed-show-next
"p" #'elfeed-show-prev))Summary groups:
(setq elfeed-summary-settings
'((search (:filter . "@1-day-ago +unread") (:title . "Fresh"))
(search (:filter . "@1970-01-01--@4-day-ago +unread") (:title . "Stale"))
(search (:filter . "+Tech") (:title . "Tech"))
(search (:filter . "+Tea") (:title . "Tea"))
(search (:filter . "+Art") (:title . "Art"))
(search (:filter . "+Motorsports") (:title . "Motorsports"))
(search (:filter . "+Regional") (:title . "Regional"))
(search (:filter . "+NatWorld") (:title . "Nation and World"))
(search (:filter . "+Blog") (:title . "Blogs"))
(search (:filter . "+Media") (:title . "Media"))
(search (:filter . "+Brain") (:title . "Brain"))
(search (:filter . "+Videos") (:title . "Videos"))
(auto-tags (:original-order t :hide t))
(group (:title . "Miscellaneous")
(:elements
(group
(:title . "Searches")
(:elements
(search (:filter . "@6-months-ago rrix") (:title . "About me"))
(search (:filter . "+later") (:title . "Check later"))))))))My Feeds and the blogroll
elfeed-sync "only" goes one way but elfeed-org will import the OPML that tt-rss spits out to set up the org doc for the first time. It took some small effort to get the elfeed-sync-feeds function to run but once it is all lined up things are nice. To subscribe to something the RSS can go in either My RSS Feeds or My Blog Roll.
(use-package elfeed-org
:config
(elfeed-org)
(setq rmh-elfeed-org-files
'("~/org/elfeed_feeds.org"
"~/org/my_blogroll.org")))Server Sync Setup
(use-package elfeed-sync
:after elfeed
:config
(elfeed-sync-mode))Then set up the following variables:
elfeed-sync-tt-rss-instance - point that to your tt-rss instance, e.g. (No trailing slash)
elfeed-sync-tt-rss-login
elfeed-sync-tt-rss-password
elfeed-sync-unread-tag - elfeed tag to map to read status in tt-rss. unread by default.
elfeed-sync-marked-tag - elfeed tag to map to marked status in tt-rss. later by default.
This isn't in melpa, and I'll end up doing some more work on it to add some functionality but for now it pulls its the package from GitHub via a flake input pinned by flake.lock:
elfeed-sync = epkgs.melpaBuild {
pname = "elfeed-sync";
version = "20231226.1546";
commit = "unknown";
src = inputs.elfeed-sync;
recipe = pkgs.writeText "recipe" ''
(elfeed-sync
:repo "SqrtMinusOne/elfeed-sync"
:fetcher github)
'';
packageRequires = [ epkgs.elfeed epkgs.request ];
meta = {
homepage = "https://github.com/SqrtMinusOne/elfeed-sync/";
license = lib.licenses.gpl3Plus;
};
};NEXT add score filter fetching from the API
(use-package elfeed-score)