diff options
| author | vin <git@vineetk.net> | 2025-12-08 16:51:59 -0500 |
|---|---|---|
| committer | vin <git@vineetk.net> | 2025-12-08 16:55:05 -0500 |
| commit | af9627b43eaf4e40fadc9be82ccc2f10f33746a3 (patch) | |
| tree | d66c4aed05c37f159718e4a8af6b8b80134f4116 /elfeed-custom-feeds-github.el | |
| parent | 2113d0279b035f183c0c05627bbd2b0779e98f35 (diff) | |
attempt to make the plugin more async-y
Diffstat (limited to 'elfeed-custom-feeds-github.el')
| -rw-r--r-- | elfeed-custom-feeds-github.el | 76 |
1 files changed, 54 insertions, 22 deletions
diff --git a/elfeed-custom-feeds-github.el b/elfeed-custom-feeds-github.el index 660350d..a857963 100644 --- a/elfeed-custom-feeds-github.el +++ b/elfeed-custom-feeds-github.el | |||
| @@ -57,15 +57,15 @@ | |||
| 57 | (funcall cb r dn items)))) | 57 | (funcall cb r dn items)))) |
| 58 | nil t))))) | 58 | nil t))))) |
| 59 | 59 | ||
| 60 | (defun elfeed-custom-feeds-github--prs-to-elfeed (repo display-name prs) | 60 | (defun elfeed-custom-feeds-github--prs-to-elfeed (repo display-name prs completion-callback) |
| 61 | "Convert GitHub PRS to elfeed entries for REPO with DISPLAY-NAME." | 61 | "Convert GitHub PRS to elfeed entries for REPO with DISPLAY-NAME. |
| 62 | Call COMPLETION-CALLBACK with (repo display-name new-entries) when done." | ||
| 62 | (let ((feed-url (format "https://github.com/%s/pulls" repo)) | 63 | (let ((feed-url (format "https://github.com/%s/pulls" repo)) |
| 63 | (new-count 0) | ||
| 64 | (new-entries ())) | 64 | (new-entries ())) |
| 65 | (let ((feed (elfeed-db-get-feed feed-url))) | 65 | (let ((feed (elfeed-db-get-feed feed-url))) |
| 66 | (setf (elfeed-feed-url feed) feed-url | 66 | (setf (elfeed-feed-url feed) feed-url |
| 67 | (elfeed-feed-title feed) (format "GitHub: %s [%s]" repo display-name))) | 67 | (elfeed-feed-title feed) (format "GitHub: %s [%s]" repo display-name))) |
| 68 | 68 | ||
| 69 | (dolist (pr prs) | 69 | (dolist (pr prs) |
| 70 | (let* ((number (alist-get 'number pr)) | 70 | (let* ((number (alist-get 'number pr)) |
| 71 | (title-text (alist-get 'title pr)) | 71 | (title-text (alist-get 'title pr)) |
| @@ -86,7 +86,7 @@ | |||
| 86 | (format "<p><strong>Labels:</strong> %s</p>" | 86 | (format "<p><strong>Labels:</strong> %s</p>" |
| 87 | (mapconcat 'identity labels ", ")) | 87 | (mapconcat 'identity labels ", ")) |
| 88 | "") | 88 | "") |
| 89 | (replace-regexp-in-string "<" "<" | 89 | (replace-regexp-in-string "<" "<" |
| 90 | (replace-regexp-in-string ">" ">" body))))) | 90 | (replace-regexp-in-string ">" ">" body))))) |
| 91 | (unless (elfeed-db-get-entry entry-id) | 91 | (unless (elfeed-db-get-entry entry-id) |
| 92 | (let ((entry (elfeed-entry--create | 92 | (let ((entry (elfeed-entry--create |
| @@ -98,27 +98,59 @@ | |||
| 98 | :content-type 'html | 98 | :content-type 'html |
| 99 | :feed-id feed-url | 99 | :feed-id feed-url |
| 100 | :tags '(unread github)))) | 100 | :tags '(unread github)))) |
| 101 | (push entry new-entries) | 101 | (push entry new-entries))))) |
| 102 | (setq new-count (1+ new-count)))))) | 102 | |
| 103 | 103 | ;; Call completion callback with results | |
| 104 | (when new-entries | 104 | (funcall completion-callback repo display-name (nreverse new-entries)))) |
| 105 | (elfeed-db-add (nreverse new-entries))) | ||
| 106 | |||
| 107 | (message "GitHub feed %s [%s]: %d new entries" repo display-name new-count) | ||
| 108 | (when (get-buffer "*elfeed-search*") | ||
| 109 | (with-current-buffer "*elfeed-search*" | ||
| 110 | (elfeed-search-update--force))))) | ||
| 111 | 105 | ||
| 112 | ;;;###autoload | 106 | ;;;###autoload |
| 113 | (defun elfeed-custom-feeds-github-update () | 107 | (defun elfeed-custom-feeds-github-update () |
| 114 | "Update all GitHub PR feeds." | 108 | "Update all GitHub PR feeds asynchronously. |
| 109 | Batches all entries and updates UI once at the end to avoid blocking." | ||
| 115 | (interactive) | 110 | (interactive) |
| 116 | (cl-loop for (repo query display-name) in elfeed-custom-github-pr-queries | 111 | (let* ((total (length elfeed-custom-github-pr-queries)) |
| 117 | for i from 0 | 112 | (processed 0) |
| 118 | for delay = (* i elfeed-custom-github-request-delay) | 113 | (all-new-entries '()) |
| 119 | do (elfeed-custom-feeds-github--fetch-prs repo query display-name | 114 | (results '())) |
| 120 | #'elfeed-custom-feeds-github--prs-to-elfeed | 115 | |
| 121 | delay))) | 116 | (when (zerop total) |
| 117 | (message "No GitHub PR queries configured") | ||
| 118 | (cl-return-from elfeed-custom-feeds-github-update nil)) | ||
| 119 | |||
| 120 | ;; Completion callback that batches everything | ||
| 121 | (let ((completion-callback | ||
| 122 | (lambda (repo display-name new-entries) | ||
| 123 | (setq processed (1+ processed)) | ||
| 124 | (when new-entries | ||
| 125 | (setq all-new-entries (append all-new-entries new-entries))) | ||
| 126 | (push (list repo display-name (length new-entries)) results) | ||
| 127 | |||
| 128 | ;; When all queries are done, batch add to DB and update UI once | ||
| 129 | (when (= processed total) | ||
| 130 | (let ((total-count (length all-new-entries))) | ||
| 131 | (when (> total-count 0) | ||
| 132 | (elfeed-db-add all-new-entries)) | ||
| 133 | ;; Report results for each feed | ||
| 134 | (dolist (result (nreverse results)) | ||
| 135 | (message "GitHub feed %s [%s]: %d new entries" | ||
| 136 | (nth 0 result) (nth 1 result) (nth 2 result))) | ||
| 137 | ;; Defer UI update to avoid blocking | ||
| 138 | (run-with-idle-timer 0.1 nil | ||
| 139 | (lambda () | ||
| 140 | (when (get-buffer "*elfeed-search*") | ||
| 141 | (with-current-buffer "*elfeed-search*" | ||
| 142 | (elfeed-search-update--force)))))))))) | ||
| 143 | |||
| 144 | ;; Start all async fetches | ||
| 145 | (cl-loop for (repo query display-name) in elfeed-custom-github-pr-queries | ||
| 146 | for i from 0 | ||
| 147 | for delay = (* i elfeed-custom-github-request-delay) | ||
| 148 | do (elfeed-custom-feeds-github--fetch-prs | ||
| 149 | repo query display-name | ||
| 150 | (lambda (r dn items) | ||
| 151 | (elfeed-custom-feeds-github--prs-to-elfeed r dn items completion-callback)) | ||
| 152 | delay))) | ||
| 153 | nil)) | ||
| 122 | 154 | ||
| 123 | (provide 'elfeed-custom-feeds-github) | 155 | (provide 'elfeed-custom-feeds-github) |
| 124 | 156 | ||
