aboutsummaryrefslogtreecommitdiff
path: root/sx-request.el
diff options
context:
space:
mode:
authorSean Allred <code@seanallred.com>2014-11-18 23:49:07 -0500
committerSean Allred <code@seanallred.com>2014-11-19 00:00:42 -0500
commit0dd95e3a3d4ee52f52a585388c3ba65e045c305b (patch)
treef8c4497519cf6f741ea7ec379c537f4b71a4de88 /sx-request.el
parent20dd7254da8e95bd01ce57f806733dee20005039 (diff)
parent681319aeb250a83d982d1e3e02264a7af0ae4120 (diff)
Merge branch 'master' into documentation
Conflicts: sx-method.el sx-question-list.el sx-question-mode.el sx-question.el sx-request.el sx.el
Diffstat (limited to 'sx-request.el')
-rw-r--r--sx-request.el87
1 files changed, 57 insertions, 30 deletions
diff --git a/sx-request.el b/sx-request.el
index b3668fe..89c9a59 100644
--- a/sx-request.el
+++ b/sx-request.el
@@ -96,12 +96,15 @@ number of requests left every time it finishes a call.")
;;; Making Requests
(defun sx-request-make
- (method &optional args)
+ (method &optional args need-auth use-post)
"Make a request to the API, executing METHOD with ARGS.
You should almost certainly be using `sx-method-call' instead of
this function.
+Returns cleaned response content.
+See (`sx-encoding-clean-content-deep').
+
The full call is built with `sx-request-build', prepending
`sx-request-api-key' to receive a higher quota. This call is
then resolved with `url-retrieve-synchronously' to a temporary
@@ -111,16 +114,19 @@ is then tested with `sx-encoding-gzipped-buffer-p' for
compression. If it is compressed, `sx-request-unzip-program' is
called to uncompress the response. The uncompressed respons is
then read with `json-read-from-string'.
+
`sx-request-remaining-api-requests' is updated appropriately and
the main content of the response is returned."
(let ((url-automatic-caching sx-request-cache-p)
(url-inhibit-uncompression t)
- (call (sx-request-build
- method
- (cons (cons 'key sx-request-api-key)
- args))))
- (sx-message "Request: %S" call)
- (let ((response-buffer (url-retrieve-synchronously call)))
+ (request-method (if use-post "POST" "GET"))
+ (request-args
+ (sx-request--build-keyword-arguments args nil need-auth))
+ (request-url (concat sx-request-api-root method)))
+ (sx-message "Request: %S" request-url)
+ (let ((response-buffer (sx-request--request request-url
+ request-args
+ request-method)))
(if (not response-buffer)
(error "Something went wrong in `url-retrieve-synchronously'")
(with-current-buffer response-buffer
@@ -158,37 +164,58 @@ the main content of the response is returned."
;;; Support Functions
-(defun sx-request-build (method keyword-arguments &optional kv-value-sep root)
- "Construct METHOD to use KEYWORD-ARGUMENTS.
+(defun sx-request--request (url args method)
+ "Return the response buffer for URL with ARGS using METHOD."
+ (let ((url-request-method method)
+ (url-request-extra-headers
+ '(("Content-Type" . "application/x-www-form-urlencoded")))
+ (url-request-data args))
+ (url-retrieve-synchronously url)))
-The KEYWORD-ARGUMENTS are joined with KV-VALUE-SEP when it
-contains a 'vector'. See `sx-request--build-keyword-arguments'."
- (let ((base (concat (or root sx-request-api-root) method))
- (args (sx-request--build-keyword-arguments
- keyword-arguments kv-value-sep)))
- (if (string-equal "" args)
- base
- (concat base "?" args))))
-(defun sx-request--build-keyword-arguments (alist &optional kv-value-sep)
- "Format ALIST as a key-value joined with KV-VALUE-SEP.
+(defun sx-request--build-keyword-arguments (alist &optional
+ kv-sep need-auth)
+ "Format ALIST as a key-value list joined with KV-SEP.
+
+If authentication is needed, include it also or error if it is
+not available.
Build a \"key=value&key=value&...\"-style string with the elements
of ALIST. If any value in the alist is `nil', that pair will not
be included in the return. If you wish to pass a notion of
false, use the symbol `false'. Each element is processed with
`sx--thing-as-string'."
- (mapconcat
- (lambda (pair)
- (concat
- (sx--thing-as-string (car pair))
- "="
- (sx--thing-as-string (cdr pair) kv-value-sep)))
- (delq nil (mapcar
- (lambda (pair)
- (when (cdr pair) pair))
- alist))
- "&"))
+ ;; Add API key to list of arguments, this allows for increased quota
+ ;; automatically.
+ (let* ((warn (equal need-auth 'warn))
+ (api-key (cons "key" sx-request-api-key))
+ (auth
+ (let ((auth (car (sx-cache-get 'auth))))
+ (cond
+ (auth)
+ ;; Pass user error when asking to warn
+ (warn
+ (user-error
+ "This query requires authentication; run `M-x sx-auth-authenticate' and try again"))
+ ((not auth)
+ (lwarn "stack-mode" :debug
+ "This query requires authentication")
+ nil)))))
+ (push api-key alist)
+ (if (and need-auth auth)
+ (push auth alist))
+ (mapconcat
+ (lambda (pair)
+ (concat
+ (sx--thing-as-string (car pair))
+ "="
+ (sx--thing-as-string (cdr pair) kv-sep)))
+ (delq nil (mapcar
+ (lambda (pair)
+ (when (cdr pair) pair))
+ alist))
+ "&")))
+
(provide 'sx-request)
;;; sx-request.el ends here