From c4e395ccaaac33b1898d447b09377b8e3fd9cfa3 Mon Sep 17 00:00:00 2001 From: Akshay Nair Date: Tue, 10 Sep 2024 17:59:56 +0530 Subject: Refactor newsboat config to nix --- modules/newsboat.home/.gitignore | 1 + modules/newsboat.home/config.nix | 49 +++++++++++++++++++++++++++++ modules/newsboat.home/default.nix | 59 +++++++++++++++++++++++++++++++++++ modules/newsboat.home/opener.sh | 26 +++++++++++++++ modules/newsboat.home/public-feed.nix | 59 +++++++++++++++++++++++++++++++++++ 5 files changed, 194 insertions(+) create mode 100644 modules/newsboat.home/.gitignore create mode 100644 modules/newsboat.home/config.nix create mode 100644 modules/newsboat.home/default.nix create mode 100755 modules/newsboat.home/opener.sh create mode 100644 modules/newsboat.home/public-feed.nix (limited to 'modules/newsboat.home') diff --git a/modules/newsboat.home/.gitignore b/modules/newsboat.home/.gitignore new file mode 100644 index 0000000..16189dc --- /dev/null +++ b/modules/newsboat.home/.gitignore @@ -0,0 +1 @@ +./private-feed.nix diff --git a/modules/newsboat.home/config.nix b/modules/newsboat.home/config.nix new file mode 100644 index 0000000..2669482 --- /dev/null +++ b/modules/newsboat.home/config.nix @@ -0,0 +1,49 @@ +rec { + config = { + reload-threads = 6; + max-items = 20; + browser = "~/.config/newsboat/opener.sh '%t' %u"; + show-keymap-hint = false; + refresh-on-startup = true; + save-path = "~/Downloads/articles"; + articlelist-format = "%?T?| %-26T | %5i: ?%t"; + prepopulate-query-feeds = true; + }; + + keys = { + j = "down"; + k = "up"; + l = "open"; + h = "quit"; + g = "home"; + G = "end"; + q = "hard-quit"; + n = "next"; + p = "prev"; + }; + + macros = let + copyCmd = "~/.config/newsboat/opener.sh copy %u"; + in { + y = ''set browser "${copyCmd}"; open-in-browser; set browser "${config.browser}"''; + }; + + extraConfig = '' +color background color223 default +color listnormal color246 default +color listnormal_unread color62 default bold +color listfocus white magenta +color listfocus_unread white magenta bold underline +color info color8 default +color article white default + +highlight article "^(Feed|Link|Title|Date|Author):.*$" color223 default bold +highlight article "\\[[0-9]+\\]" color62 default bold +highlight article "https?://[^ ]+" color117 default underline +highlight article "\\[image\\ [0-9]+\\]" color117 default bold +highlight articlelist "\\|[^|]*\\|" color253 default bold +highlight articlelist "\\| \\[yt\\][^|]*\\|" color1 default bold +highlight articlelist "\\| r/[^|]*\\|" color253 default +highlight articlelist "\\| VimTricks[^|]*\\|" color27 default + ''; +} diff --git a/modules/newsboat.home/default.nix b/modules/newsboat.home/default.nix new file mode 100644 index 0000000..aedf7db --- /dev/null +++ b/modules/newsboat.home/default.nix @@ -0,0 +1,59 @@ +{ lib, pkgs, ... }: +let + cfg = import ./config.nix; + urls = mergeFeeds [ (import ./public-feed.nix) privateFeed ]; + privateFeed = let feedpath = ./private-feed.nix; + in if builtins.pathExists feedpath then import feedpath else {}; + + mergeFeeds = feeds: lib.attrsets.foldAttrs (value: acc: + if lib.isList value + then value ++ (if acc != null then acc else []) + else value // (if acc != null then acc else {}) + ) null ([{ queries = {}; visible = []; hidden = []; }] ++ feeds); + + joinLines = lib.concatStringsSep "\n"; + joinWords = lib.concatStringsSep " "; + + toUrl = url: joinWords (lib.map toString [ + url.url + (lib.optional (url ? "hidden" && url.hidden) "!") + (lib.optional (url ? "tags") (joinWords url.tags)) + (lib.optional (url ? "title") ''"~${url.title}"'') + ]); + + toUrls = urls: joinLines (lib.map toUrl urls); + + toQueries = queries: joinLines + (lib.mapAttrsToList (key: val: "\"query:${key}:${val}\"") queries); + + # { raw = a; } -> a | bool -> yesno | string -> "string" | number + toConfigValue = val: + if val ? "raw" then toString val.raw + else if lib.isBool val then lib.hm.booleans.yesNo val + else if lib.isString val then ''"${val}"'' + else toString val; + + cfgFileContent = joinLines [ + (joinLines + (lib.mapAttrsToList (key: val: "${key} ${toConfigValue val}") cfg.config)) + (joinLines + (lib.mapAttrsToList (key: val: "bind-key ${key} ${val}") cfg.keys)) + (joinLines + (lib.mapAttrsToList (key: val: "macro ${key} ${val}") cfg.macros)) + cfg.extraConfig + ]; + + urlsFileContent = joinLines [ + (toQueries urls.queries) + (toUrls urls.visible) + (toUrls (lib.map (x: x // { hidden = true; }) urls.hidden)) + ]; +in { + home.packages = [ pkgs.newsboat ]; + + xdg.configFile = { + "newsboat/urls".text = urlsFileContent; + "newsboat/config".text = cfgFileContent; + "newsboat/opener.sh".source = ./opener.sh; + }; +} diff --git a/modules/newsboat.home/opener.sh b/modules/newsboat.home/opener.sh new file mode 100755 index 0000000..7a5da4e --- /dev/null +++ b/modules/newsboat.home/opener.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +type="$1"; shift; + +video() { + mpv \ + --player-operation-mode=pseudo-gui \ + --force-window=immediate \ + "$@" >/dev/null 2>&1 & disown; +} +image() { feh -x -F --image-bg "#0f0c19" "$@" >/dev/null 2>&1 & disown; } + +browser() { sensible-browser "$@" >/dev/null 2>&1 & disown; } + +case "$type" in + copy) echo "$@" | xclip -selection clipboard ;; + image) image "$@" ;; + video|audio) video "$@" ;; + *) + case "$1" in + https://*youtu.be/*|https://*youtube.com/v/*) video "$@" ;; + https://*youtube.com/watch*) video "$@" ;; + *) browser ;; + esac + ;; +esac; diff --git a/modules/newsboat.home/public-feed.nix b/modules/newsboat.home/public-feed.nix new file mode 100644 index 0000000..09ea6a7 --- /dev/null +++ b/modules/newsboat.home/public-feed.nix @@ -0,0 +1,59 @@ +let + tag = t: ''tags # \"${toString t}\"''; + youtube = title: id: tags: + { title = "[yt] ${title} youtube"; url = "https://www.youtube.com/feeds/videos.xml?channel_id=${id}"; tags = ["youtube"] ++ tags; }; +in { + queries = { + "dev tag" = tag "dev"; + "news tag" = tag "news"; + "opensource tag" = tag "opensource"; + "youtube tag" = tag "youtube"; + "funny tag" = tag "funny"; + "science tag" = tag "sci"; + }; + + visible = [ + { url = "https://mshibanami.github.io/GitHubTrendingRSS/weekly/all.xml"; tags = ["latest"]; } + { url = "https://dotfyle.com/this-week-in-neovim/rss.xml"; tags = ["opensource" "latest"]; } + { url = "https://www.reddit.com/r/neovim.rss"; tags = ["reddit"]; title = "r/neovim"; } + ]; + + hidden = [ + { url = "https://www.nasa.gov/feeds/iotd-feed"; tags = ["sci"]; } + { url = "https://www.nasa.gov/news-release/feed/"; tags = ["sci"]; } + { url = "https://www.nature.com/nature.rss"; tags = ["sci"]; } + { url = "https://what-if.xkcd.com/feed.atom"; tags = ["sci"]; } + { url = "https://overreacted.io/rss.xml"; tags = ["dev"]; } + + { url = "https://overreacted.io/rss.xml"; tags = ["dev"]; } + { url = "https://kentcdodds.com/blog/rss.xml"; tags = ["dev"]; } + { url = "https://developer.chrome.com/blog/feed.xml"; tags = ["dev"]; } + { url = "https://programmingisterrible.com/rss"; tags = ["dev"]; } + { url = "https://cprss.s3.amazonaws.com/javascriptweekly.com.xml"; tags = ["dev"]; } + { url = "https://cprss.s3.amazonaws.com/react.statuscode.com.xml"; tags = ["dev"]; } + { url = "https://dev.to/feed/tag/typescript"; tags = ["dev"]; title = "TS - dev.to"; } + { url = "https://dev.to/feed/tag/haskell"; tags = ["dev"]; title = "Haskell - dev.to"; } + { url = "https://nitter.privacydev.net/vim_tricks/rss"; tags = ["twitter" "dev" "opensource"]; } + + { url = "https://hnrss.org/frontpage"; tags = ["news"]; } + { url = "https://hackernoon.com/feed"; tags = ["news"]; } + { url = "https://nixos.org/blog/announcements-rss.xml"; tags = ["opensource" "news"]; } + { url = "https://www.reddit.com/r/opensource.rss"; tags = ["reddit" "opensource"]; title = "r/opensource"; } + { url = "https://www.cyberciti.com/feed/"; tags = ["opensource" "news"]; } + { url = "https://itsfoss.com/rss/"; tags = ["opensource" "news"]; } + + { url = "https://xkcd.com/rss.xml"; tags = ["funny"]; } + { url = "http://phdcomics.com/gradfeed.php"; tags = ["funny"]; } + { url = "https://www.reddit.com/r/ProgrammerHumor.rss"; tags = ["funny" "reddit"]; title = "r/ProgrammerHumor"; } + { url = "https://feeds.feedburner.com/TheDailyWtf"; tags = ["funny"]; } + + # Youtube channels + (youtube "IamMoBo" "UCJswRv22oiUgmT1FuFeUekw" ["funny"]) + (youtube "NaturalHabitatShorts" "UCSb_Sui6FBxVS4_ROsrU_Iw" ["funny"]) + (youtube "InternetHistorian" "UCR1D15p_vdP3HkrH8wgjQRw" ["funny"]) + (youtube "Incognito Mode" "UC8Q7XEy86Q7T-3kNpNjYgwA" ["funny"]) + (youtube "Fireship" "UCsBjURrPoezykLs9EqgamOA" ["dev"]) + (youtube "No boilerplate" "UCUMwY9iS8oMyWDYIe6_RmoA" ["dev"]) + (youtube "TypeCraft" "UCo71RUe6DX4w-Vd47rFLXPg" ["dev"]) + ]; +} -- cgit v1.3.1