From 8cccc2cd64105062ae4558090f11cc5b11e968a4 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Sat, 20 Jun 2026 12:57:40 -0400 Subject: refactor(elfeed): extract HTML-entity decoder, drop leftover DEBUG logging cj/youtube-to-elfeed-feed-format hand-decoded an og:title with six sequential replace-regexp-in-string calls; extract cj/--decode-html-entities (alist-driven, & first) and call it. Also remove the leftover DEBUG cj/log-silently instrumentation from cj/extract-stream-url. Behavior unchanged; adds coverage of the decoder. --- modules/elfeed-config.el | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) (limited to 'modules') diff --git a/modules/elfeed-config.el b/modules/elfeed-config.el index ad7bda83a..7712f48db 100644 --- a/modules/elfeed-config.el +++ b/modules/elfeed-config.el @@ -126,23 +126,13 @@ Returns the stream URL or nil on failure." (cmd-args (append '("yt-dlp" "-q" "-g") format-args (list url))) - ;; DEBUG: Log the command - (_ (cj/log-silently "DEBUG: Extracting with command: %s" - (mapconcat #'shell-quote-argument cmd-args " "))) (output (with-temp-buffer (let ((exit-code (apply #'call-process (car cmd-args) nil t nil (cdr cmd-args)))) (if (zerop exit-code) (string-trim (buffer-string)) - (progn - ;; DEBUG: Log failure - (cj/log-silently "DEBUG: yt-dlp failed with exit code %d" exit-code) - (cj/log-silently "DEBUG: Error output: %s" (buffer-string)) - nil)))))) - ;; DEBUG: Log the result - (cj/log-silently "DEBUG: Extracted URL: %s" - (if output (truncate-string-to-width output 100) "nil")) + nil))))) (when (and output (string-match-p "^https?://" output)) output))) @@ -223,6 +213,15 @@ Note: Function name kept for backwards compatibility." "Seconds to wait for a synchronous YouTube page fetch before giving up. Without a timeout a hung request would block Emacs indefinitely.") +(defun cj/--decode-html-entities (text) + "Decode the common HTML entities in TEXT. +Handles & < > " ' and ' -- the entities YouTube's +og:title meta tag emits. Decoded left-to-right, & first." + (let ((entities '(("&" . "&") ("<" . "<") (">" . ">") + (""" . "\"") ("'" . "'") ("'" . "'")))) + (dolist (pair entities text) + (setq text (replace-regexp-in-string (car pair) (cdr pair) text))))) + (defun cj/youtube-to-elfeed-feed-format (url type) "Convert YouTube URL to elfeed-feeds format. @@ -274,13 +273,8 @@ TYPE should be either \='channel or \='playlist." (goto-char (point-min)) (when (re-search-forward "" title)) - (setq title (replace-regexp-in-string """ "\"" title)) - (setq title (replace-regexp-in-string "'" "'" title)) - (setq title (replace-regexp-in-string "'" "'" title)))))) + ;; Decode HTML entities in the extracted title + (setq title (cj/--decode-html-entities title)))))) ;; Always kill the temporary URL buffer, even when extraction failed -- ;; the old code only killed it when an ID was found, leaking it otherwise. (when (buffer-live-p buffer) -- cgit v1.2.3