summaryrefslogtreecommitdiff
path: root/elfeed-custom-feeds-github.el
diff options
context:
space:
mode:
Diffstat (limited to 'elfeed-custom-feeds-github.el')
-rw-r--r--elfeed-custom-feeds-github.el124
1 files changed, 58 insertions, 66 deletions
diff --git a/elfeed-custom-feeds-github.el b/elfeed-custom-feeds-github.el
index 97a2f60..49e0d6b 100644
--- a/elfeed-custom-feeds-github.el
+++ b/elfeed-custom-feeds-github.el
@@ -11,7 +11,7 @@
11;;; Code: 11;;; Code:
12 12
13(require 'elfeed) 13(require 'elfeed)
14(require 'url) 14(require 'elfeed-curl)
15(require 'json) 15(require 'json)
16(require 'cl-lib) 16(require 'cl-lib)
17 17
@@ -44,29 +44,27 @@
44 (dn display-name)) 44 (dn display-name))
45 (run-at-time delay nil 45 (run-at-time delay nil
46 (lambda () 46 (lambda ()
47 (url-retrieve url 47 (elfeed-curl-enqueue url
48 (lambda (status) 48 (lambda (status)
49 (if (plist-get status :error) 49 (if (not status)
50 (message "Error fetching GitHub PRs %s [%s]: %s" r dn (plist-get status :error)) 50 (message "Error fetching GitHub PRs %s [%s]: %s" r dn elfeed-curl-error-message)
51 (goto-char (point-min)) 51 ;; Capture JSON text for async parsing
52 (re-search-forward "\n\n") 52 (let ((json-text (buffer-substring-no-properties (point-min) (point-max))))
53 ;; Capture JSON text for async parsing 53 ;; Parse JSON in idle timer to avoid blocking
54 (let ((json-text (buffer-substring-no-properties (point) (point-max)))) 54 (run-with-idle-timer 0 nil
55 ;; Parse JSON in idle timer to avoid blocking 55 (lambda ()
56 (run-with-idle-timer 0 nil 56 (condition-case err
57 (lambda () 57 (with-temp-buffer
58 (condition-case err 58 (insert json-text)
59 (with-temp-buffer 59 (goto-char (point-min))
60 (insert json-text) 60 (let* ((json-object-type 'alist)
61 (goto-char (point-min)) 61 (json-array-type 'list)
62 (let* ((json-object-type 'alist) 62 (response (json-read))
63 (json-array-type 'list) 63 (items (alist-get 'items response)))
64 (response (json-read)) 64 (funcall cb r dn items)))
65 (items (alist-get 'items response))) 65 (error
66 (funcall cb r dn items))) 66 (message "Error parsing JSON for GitHub %s [%s]: %s" r dn err))))))))
67 (error 67 :headers '(("Accept" . "application/vnd.github+json")))))))
68 (message "Error parsing JSON for GitHub %s [%s]: %s" r dn err)))))))
69 nil t)))))
70 68
71(defun elfeed-custom-feeds-github--prs-to-elfeed (repo display-name prs completion-callback) 69(defun elfeed-custom-feeds-github--prs-to-elfeed (repo display-name prs completion-callback)
72 "Convert GitHub PRS to elfeed entries for REPO with DISPLAY-NAME. 70 "Convert GitHub PRS to elfeed entries for REPO with DISPLAY-NAME.
@@ -126,7 +124,7 @@ Call COMPLETION-CALLBACK with (repo display-name new-entries) when done."
126 (run-with-idle-timer 0 nil #'process-next-chunk) 124 (run-with-idle-timer 0 nil #'process-next-chunk)
127 ;; All done - call completion callback 125 ;; All done - call completion callback
128 (funcall completion-callback repo display-name (nreverse new-entries))))))) 126 (funcall completion-callback repo display-name (nreverse new-entries)))))))
129 (process-next-chunk))))) 127 (process-next-chunk))))
130 128
131;;;###autoload 129;;;###autoload
132(defun elfeed-custom-feeds-github-update () 130(defun elfeed-custom-feeds-github-update ()
@@ -138,48 +136,42 @@ Batches all entries and updates UI once at the end to avoid blocking."
138 (all-new-entries '()) 136 (all-new-entries '())
139 (results '())) 137 (results '()))
140 138
141 (when (zerop total) 139 (if (zerop total)
142 (message "No GitHub PR queries configured") 140 (message "No GitHub PR queries configured")
143 (cl-return-from elfeed-custom-feeds-github-update nil)) 141 (let ((completion-callback
144 142 (lambda (repo display-name new-entries)
145 ;; Completion callback that batches everything 143 (run-with-idle-timer 0 nil
146 (let ((completion-callback 144 (lambda ()
147 (lambda (repo display-name new-entries) 145 (setq processed (1+ processed))
148 (run-with-idle-timer 0 nil 146 (when new-entries
149 (lambda () 147 (setq all-new-entries (append all-new-entries new-entries)))
150 (setq processed (1+ processed)) 148 (push (list repo display-name (length new-entries)) results)
151 (when new-entries 149 ;; When all queries are done, batch add to DB and update UI once
152 (setq all-new-entries (append all-new-entries new-entries))) 150 (when (= processed total)
153 (push (list repo display-name (length new-entries)) results) 151 (let ((total-count (length all-new-entries)))
154 152 (when (> total-count 0)
155 ;; When all queries are done, batch add to DB and update UI once 153 (run-with-idle-timer 0 nil
156 (when (= processed total) 154 (lambda ()
157 (let ((total-count (length all-new-entries))) 155 (elfeed-db-add all-new-entries))))
158 (when (> total-count 0) 156 ;; Report results for each feed
159 (run-with-idle-timer 0 nil 157 (dolist (result (nreverse results))
158 (message "GitHub feed %s [%s]: %d new entries"
159 (nth 0 result) (nth 1 result) (nth 2 result)))
160 ;; Defer UI update to avoid blocking
161 (run-with-idle-timer 0.2 nil
160 (lambda () 162 (lambda ()
161 (elfeed-db-add all-new-entries)))) 163 (when (get-buffer "*elfeed-search*")
162 ;; Report results for each feed 164 (with-current-buffer "*elfeed-search*"
163 (dolist (result (nreverse results)) 165 (elfeed-search-update--force))))))))))))
164 (message "GitHub feed %s [%s]: %d new entries" 166 ;; Start all async fetches
165 (nth 0 result) (nth 1 result) (nth 2 result))) 167 (cl-loop for (repo query display-name) in elfeed-custom-github-pr-queries
166 ;; Defer UI update to avoid blocking 168 for i from 0
167 (run-with-idle-timer 0.2 nil 169 for delay = (* i elfeed-custom-github-request-delay)
168 (lambda () 170 do (elfeed-custom-feeds-github--fetch-prs
169 (when (get-buffer "*elfeed-search*") 171 repo query display-name
170 (with-current-buffer "*elfeed-search*" 172 (lambda (r dn items)
171 (elfeed-search-update--force))))))))))))) 173 (elfeed-custom-feeds-github--prs-to-elfeed r dn items completion-callback))
172 174 delay))))))
173 ;; Start all async fetches
174 (cl-loop for (repo query display-name) in elfeed-custom-github-pr-queries
175 for i from 0
176 for delay = (* i elfeed-custom-github-request-delay)
177 do (elfeed-custom-feeds-github--fetch-prs
178 repo query display-name
179 (lambda (r dn items)
180 (elfeed-custom-feeds-github--prs-to-elfeed r dn items completion-callback))
181 delay)))
182 nil)
183 175
184(provide 'elfeed-custom-feeds-github) 176(provide 'elfeed-custom-feeds-github)
185 177