aboutsummaryrefslogtreecommitdiff
path: root/sx-request.el
diff options
context:
space:
mode:
Diffstat (limited to 'sx-request.el')
-rw-r--r--sx-request.el57
1 files changed, 39 insertions, 18 deletions
diff --git a/sx-request.el b/sx-request.el
index d7fd058..1eabc41 100644
--- a/sx-request.el
+++ b/sx-request.el
@@ -190,7 +190,9 @@ the main content of the response is returned."
;; @TODO should use `condition-case' here -- set
;; RESPONSE to 'corrupt or something
(response (with-demoted-errors "`json' error: %S"
- (json-read-from-string data))))
+ (let ((json-false nil)
+ (json-null :null))
+ (json-read-from-string data)))))
(kill-buffer response-buffer)
(when (and (not response) (string-equal data "{}"))
(sx-message "Unable to parse response: %S" response)
@@ -199,13 +201,13 @@ the main content of the response is returned."
(sx-assoc-let response
(when .error_id
(error "Request failed: (%s) [%i %s] %S"
- .method .error_id .error_name .error_message))
+ .method .error_id .error_name .error_message))
(when (< (setq sx-request-remaining-api-requests .quota_remaining)
sx-request-remaining-api-requests-message-threshold)
(sx-message "%d API requests remaining"
sx-request-remaining-api-requests))
(funcall (or process-function #'sx-request-response-get-items)
- response)))))))
+ response)))))))
(defun sx-request-fallback (_method &optional _args _request-method _process-function)
"Fallback method when authentication is not available.
@@ -221,25 +223,44 @@ Currently returns nil."
"https://raw.githubusercontent.com/vermiculus/sx.el/data/data/%s.el"
"Url of the \"data\" directory inside the SX `data' branch.")
-(defun sx-request-get-url (url)
- "Fetch and return data stored online at URL."
+(defun sx-request--read-buffer-data ()
+ "Return the buffer contents after any url headers.
+Error if url headers are absent or if they indicate something
+went wrong."
+ (goto-char (point-min))
+ (unless (string-match "200" (thing-at-point 'line))
+ (error "Page not found."))
+ (if (not (search-forward "\n\n" nil t))
+ (error "Headers missing; response corrupt")
+ (prog1 (buffer-substring (point) (point-max))
+ (kill-buffer (current-buffer)))))
+
+(defun sx-request-get-url (url &optional callback)
+ "Fetch and return data stored online at URL.
+If CALLBACK is nil, fetching is done synchronously and the
+data (buffer contents sans headers) is returned as a string.
+
+Otherwise CALLBACK must be a function of a single argument. Then
+`url-retrieve' is called asynchronously and CALLBACK is passed
+the retrieved data."
(let* ((url-automatic-caching t)
(url-inhibit-uncompression t)
(url-request-method "GET")
(url-request-extra-headers
'(("Content-Type" . "application/x-www-form-urlencoded")))
- (response-buffer (url-retrieve-synchronously url)))
- (if (not response-buffer)
- (error "Something went wrong in `url-retrieve-synchronously'")
- (with-current-buffer response-buffer
- (progn
- (goto-char (point-min))
- (unless (string-match "200" (thing-at-point 'line))
- (error "Page not found."))
- (if (not (search-forward "\n\n" nil t))
- (error "Headers missing; response corrupt")
- (prog1 (buffer-substring (point) (point-max))
- (kill-buffer (current-buffer)))))))))
+ (callback-internal
+ (when callback
+ ;; @TODO: Error check in STATUS.
+ (lambda (_status)
+ (funcall callback (sx-request--read-buffer-data)))))
+ (response-buffer
+ (if callback (url-retrieve url callback-internal nil 'silent)
+ (url-retrieve-synchronously url))))
+ (unless callback
+ (if (not response-buffer)
+ (error "Something went wrong in `url-retrieve-synchronously'")
+ (with-current-buffer response-buffer
+ (sx-request--read-buffer-data))))))
(defun sx-request-get-data (file)
"Fetch and return data stored online by SX.
@@ -289,7 +310,7 @@ false, use the symbol `false'. Each element is processed with
(defun sx-request-all-stop-when-no-more (response)
(or (not response)
- (equal :json-false (cdr (assoc 'has_more response)))))
+ (not (cdr (assoc 'has_more response)))))
(provide 'sx-request)
;;; sx-request.el ends here