~willvaughn/.emacs.d

d7222f8cfaa0c4638d80ed47854ecaedaf005036 — William Vaughn 6 months ago cc6517f
add wv-rss, elfeed and youtube-dl
4 files changed, 106 insertions(+), 1 deletions(-)

M .gitignore
M init.el
M lisp/wv-packages.el
A lisp/wv-rss.el
M .gitignore => .gitignore +1 -0
@@ 61,6 61,7 @@ flycheck_*.el
/transient/
/.org-generic-id-locations
/org-gcal/
/elfeed/
/persist/
/request/
/emojis/

M init.el => init.el +1 -1
@@ 15,7 15,7 @@
(require 'wv-org)
(require 'wv-email)
(require 'wv-irc)
;; (require 'wv-rss)
(require 'wv-rss)

;; Without this I was getting nagged for every load of an org file
(advice-add 'risky-local-variable-p :override #'ignore)

M lisp/wv-packages.el => lisp/wv-packages.el +2 -0
@@ 33,6 33,8 @@
(straight-use-package 'circe)
(straight-use-package 'emojify)
(straight-use-package '0x0)
(straight-use-package 'elfeed)
(straight-use-package 'youtube-dl)
(straight-use-package 'editorconfig)
(straight-use-package 'parinfer-rust-mode)
(straight-use-package 'rainbow-delimiters)

A lisp/wv-rss.el => lisp/wv-rss.el +102 -0
@@ 0,0 1,102 @@
;;; lisp/wv-rss.el -*- lexical-binding: t; -*-

(defvar wv-rss/rss-youtube-feed-format
  '(("^UC" . "https://www.youtube.com/feeds/videos.xml?channel_id=%s")
    ("^PL" . "https://www.youtube.com/feeds/videos.xml?playlist_id=%s")
    (""    . "https://www.youtube.com/feeds/videos.xml?user=%s")))

(defun wv-rss/rss-show-youtube-dl ()
  "Download the current entry with youtube-dl."
  (interactive)
  (if (youtube-dl (elfeed-entry-link elfeed-show-entry))
      (message "Downloading %s" (elfeed-entry-title elfeed-show-entry))
    (message "Entry is not a YouTube link!"))
  (funcall elfeed-show-entry-delete)
  (youtube-dl-list))

(defun wv-rss/rss-search-youtube-dl ()
  "Download the current entry with youtube-dl."
  (interactive)
  (let ((entries (elfeed-search-selected)))
    (dolist (entry entries)
      (if (null (youtube-dl (elfeed-entry-link entry)
                            :title (elfeed-entry-title entry)))
          (message "Entry is not a YouTube link!")
        (message "Downloading %s" (elfeed-entry-title entry)))
      (elfeed-untag entry 'unread)
      (elfeed-search-update-entry entry)
      (unless (use-region-p) (forward-line)))))

(defun wv-rss/rss-podcast-tagger (entry)
  (when (elfeed-entry-enclosures entry)
    (elfeed-tag entry 'podcast)))

(defun wv-rss/rss-elfeed-expand (listing)
  "Expand feed LISTING urls depending on their tags."
  (cl-destructuring-bind (url . tags) listing
    (cond
     ((member 'youtube tags)
      (let* ((case-fold-search nil)
             (test (lambda (s r) (string-match-p r s)))
             (format (cl-assoc url wv-rss/rss-youtube-feed-format :test test)))
        (cons (format (cdr format) url) tags)))
     (listing))))

(defun wv-rss/rss-set-elfeed! (&rest feeds)
  "Helper for setting multiple elfeed FEEDS."
  (setq elfeed-feeds (mapcar #'wv-rss/rss-elfeed-expand feeds)))

(use-package elfeed
  :init
  (setq elfeed-db-directory (concat user-emacs-directory "elfeed/db/")
        elfeed-enclosure-default-dir (concat user-emacs-directory "elfeed/enclosures/"))
  :config
  (setq elfeed-search-filter "@2-days-ago +unread -nyt -twoplustwo"
        elfeed-show-entry-switch #'pop-to-buffer
        elfeed-show-entry-delete #'kill-buffer-and-window)

  (make-directory elfeed-db-directory t)
  (wv-rss/rss-set-elfeed!
   '("https://news.ycombinator.com/rss" tech hackernews)
   '("https://clojure.org/feed.xml" tech clojure)
   ;; '("https://reddit.com/r/Clojure/hot/.rss" reddit tech clojure)
   ;; '("https://reddit.com/r/emacs/hot/.rss" reddit tech emacs)
   ;; '("https://reddit.com/r/formula1/hot/.rss" reddit f1)
   '("https://sachachua.com/blog/category/emacs/feed/" blog emacs)
   '("https://archlinux.org/feeds/news/" tech archlinux-news)
   ;; '("https://files.manager-tools.com/files/public/feeds/manager-tools-podcasts.xml" manager-tools)
   '("https://feeds.megaphone.fm/boxofneutrals" f1 mcginley)
   '("https://podcasts.files.bbci.co.uk/p02nrsjn.rss" f1 5live)
   '("https://rss.nytimes.com/services/xml/rss/nyt/World.xml" news nyt)
   ;; '("https://rss.nytimes.com/services/xml/rss/nyt/Business.xml" news nyt)
   ;; '("https://rss.nytimes.com/services/xml/rss/nyt/EnergyEnvironment.xml" news nyt)
   ;; '("https://rss.nytimes.com/services/xml/rss/nyt/Technology.xml" news tech nyt)
   '("https://danielmiessler.com/feed" blog tech miessler)
   '("https://willvaughn.org/index.xml" blog tech willvaughn)
   '("https://blog.benoitj.ca/posts/index.xml" blog tech benoitj)
   '("https://irreal.org/blog/?feed=rss2" blog tech irreal)
   '("https://lethain.com/feeds.xml" blog mgmt lethain)
   '("https://drewdevault.com/blog/index.xml" blog tech sircmpwn)
   '("https://metaredux.com/feed.xml" blog tech bbatsov)
   '("https://corfield.org/atom.xml" blog tech corfield)
   '("https://itrevolution.com/feed/" blog tech genekim)
   '("https://karthinks.com/index.xml" blog tech karthik)
   '("https://shom.dev/index.xml" blog tech shom)
   ;; '("https://xkcd.com/rss.xml" comic xkcd tech)
   '("https://itsfoss.com/feed/" foss tech linux)
   ;; '("http://www.twoplustwo.com/two-plus-two-magazine-rss.xml" poker twoplustwo)
   '("UCfz8x0lVzJpb_dgWm9kPVrw" tech devopstoolkit youtube) ; DevOps Toolkit by Viktor Farcic
   ;; '("PLEoMzSkcN8oPQtn7FQEF3D7sroZbXuPZ7" tech systemcrafters youtube) ; SystemCrafters Learning Elisp Series
   ;; '("UCVls1GmFKf6WlTraIb_IaJg" tech distrotube youtube) ; DistroTube
   '("UCAiiOTio8Yu69c3XnR7nQBQ" tech systemcrafters youtube)) ; SystemCrafters
  :hook (elfeed-new-entry wv-rss/rss-podcast-tagger))

(use-package youtube-dl
  :after elfeed
  :bind (:map elfeed-show-mode-map
              ("y" . wv-rss/rss-show-youtube-dl)
              :map elfeed-search-mode-map
              ("y" . wv-rss/rss-search-youtube-dl)
              ("L" . youtube-dl-list)))

(provide 'wv-rss)