emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] scratch/api.el be74f6a 4/4: * lisp/emacs-lisp/rest.el: Fin


From: Artur Malabarba
Subject: [Emacs-diffs] scratch/api.el be74f6a 4/4: * lisp/emacs-lisp/rest.el: Finish renaming
Date: Fri, 13 Nov 2015 15:08:41 +0000

branch: scratch/api.el
commit be74f6a7cffe3fc80604549da5d024652f63fd26
Author: Artur Malabarba <address@hidden>
Commit: Artur Malabarba <address@hidden>

    * lisp/emacs-lisp/rest.el: Finish renaming
---
 lisp/emacs-lisp/rest.el |  246 ++++++++++++++++++++++-------------------------
 1 files changed, 116 insertions(+), 130 deletions(-)

diff --git a/lisp/emacs-lisp/rest.el b/lisp/emacs-lisp/rest.el
index 592836d..08408c6 100644
--- a/lisp/emacs-lisp/rest.el
+++ b/lisp/emacs-lisp/rest.el
@@ -1,6 +1,6 @@
-;;; api.el --- library for interacting with restful web APIs  -*- 
lexical-binding: t; -*-
+;;; rest.el --- library for interacting with restful web APIs  -*- 
lexical-binding: t; -*-
 
-;; Copyright (C) 2015  Artur Malabarba
+;; Copyright (C) 2015  Free Software Foundation, Inc.
 
 ;; Author: Artur Malabarba <address@hidden>
 ;; Keywords: comm
@@ -28,7 +28,7 @@
 
 
 ;;; Error reporting
-(defun api-report-buffer ()
+(defun rest-report-buffer ()
   "Write TEXT to the *Api Server* buffer."
   (let ((text (buffer-string)))
     (with-current-buffer (get-buffer-create "*Api Report*")
@@ -37,42 +37,42 @@
         (insert text))
       (goto-char (point-min)))))
 
-(define-error 'api-error "Unkown api error, see \"*Api Report*\" buffer")
-(define-error 'api-page-does-not-exist
+(define-error 'rest-error "Unkown REST error, see \"*Api Report*\" buffer")
+(define-error 'rest-page-does-not-exist
   "This page doesn't seem to exist (see \"*Api Report*\" buffer), replied said"
-  'api-error)
-(define-error 'api-empty-redirect
+  'rest-error)
+(define-error 'rest-empty-redirect
   "Redirect received, but Location header not found! (see \"*Api Report*\" 
buffer)"
-  'api-error)
-(define-error 'api-unintelligible-result
+  'rest-error)
+(define-error 'rest-unintelligible-result
   "Tried contacting server, but I can't understand the reply.  See \"*Api 
Report*\" buffer"
-  'api-error)
-(define-error 'api-bad-request
+  'rest-error)
+(define-error 'rest-bad-request
   "Server didn't understand my request, please you should probably file a bug 
report"
-  'api-error)
-(define-error 'api-unauthorized
+  'rest-error)
+(define-error 'rest-unauthorized
   "Server says you're not authenticated"
-  'api-error)
-(define-error 'api-infinite-redirection-loop
+  'rest-error)
+(define-error 'rest-infinite-redirection-loop
   "Server is sending us in a redirection loop"
-  'api-error)
-(define-error 'api-server-error
+  'rest-error)
+(define-error 'rest-server-error
   "Something bad happened on the server side, see \"*Api Report*\" buffer"
-  'api-error)
+  'rest-error)
 
-(defun api-error (signal &rest args)
+(defun rest-error (signal &rest args)
   "Throw an error SIGNAL with ARGS.
 Also print contents of current buffer to *Api Report*."
   (declare (indent 1))
-  (api-report-buffer)
+  (rest-report-buffer)
   (signal signal args))
 
-(defun api-parse-response-code (&optional is-auth)
+(defun rest-parse-response-code (&optional is-auth)
   "Non-nil if this reponse buffer looks ok.
 Leave point at the return code on the first line."
   (goto-char (point-min))
   (unless (search-forward-regexp "^HTTP/[.0-9]+ +" nil t)
-    (api-error 'api-unintelligible-result))
+    (rest-error 'rest-unintelligible-result))
   (pcase (thing-at-point 'number)
     ((or 100 204) nil)       ;; OK, but no content.
     ((or 200 202 201 203) t) ;; OK, with content.
@@ -80,40 +80,31 @@ Leave point at the return code on the first line."
     ((or 301 302 303 304 305 307)
      (if (search-forward-regexp "^Location: *\\([^\s\n\r\t]+\\)" nil 'noerror)
          (match-string 1)
-       (api-error 'api-empty-redirect)))
+       (rest-error 'rest-empty-redirect)))
     ;; Client errors
-    ((or 403 404 405 410) (api-error 'api-page-does-not-exist
-                            (substring-no-properties (thing-at-point 'line) 0 
-1)))
-    ((or 400 422 408 409 411 412 413 414 415 416 417) (api-error 
'api-bad-request))
-    ((or 401 407) (api-error 'api-unauthorized
-                    (if is-auth "try creating a new token"
-                      "you probably need to configure a token")))
-    ((pred (<= 500)) (api-error 'api-server-error))
-    (_ (api-error 'api-error
-         (substring (thing-at-point 'line) 0 -1)))))
+    ((or 403 404 405 410) (rest-error 'rest-page-does-not-exist
+                                      (substring-no-properties (thing-at-point 
'line) 0 -1)))
+    ((or 400 422 408 409 411 412 413 414 415 416 417) (rest-error 
'rest-bad-request))
+    ((or 401 407) (rest-error 'rest-unauthorized
+                              (if is-auth "try creating a new token"
+                                "you probably need to configure a token")))
+    ((pred (<= 500)) (rest-error 'rest-server-error))
+    (_ (rest-error 'rest-error
+                   (substring (thing-at-point 'line) 0 -1)))))
 
 
 ;;; Requests
-(autoload 'auth-source-search "auth-source")
-(cl-defmacro api--with-server-buffer (method url &rest body &key async 
unwind-form
-                                             extra-headers &allow-other-keys)
+(cl-defmacro rest--with-response-buffer (method url &rest body &key async 
unwind-form
+                                                extra-headers 
&allow-other-keys)
   "Run BODY in a Server request buffer.
 UNWIND-FORM is run no matter what, and doesn't affect the return
 value."
   (declare (indent 2)
            (debug t))
-  (let ((call-name (make-symbol "callback"))
-        (secret (make-symbol "secret")))
+  (let ((call-name (make-symbol "callback")))
     (while (keywordp (car body))
       (setq body (cdr (cdr body))))
-    `(let ((,secret (when ,auth
-                      (if (listp ,auth)
-                          (or (car-safe (apply #'auth-source-search
-                                               :require '(:secret) :max 1
-                                               ,auth))
-                              (user-error "This request requires 
authentication"))
-                        (lambda () ,auth))))
-           (,call-name (lambda (status)
+    `(let ((,call-name (lambda (status)
                          (unwind-protect
                              (progn (when-let ((er (plist-get status :error)))
                                       (error "Error retrieving: %s %S" ,url 
er))
@@ -138,10 +129,10 @@ value."
              (with-current-buffer buffer
                (funcall ,call-name nil))))))))
 
-(defvar-local api-root nil
-  "Prepended to api method when a full url is not given.")
+(defvar-local rest-url-root nil
+  "Prepended to REST url when a full url is not given.")
 
-(defun api--headers-alist ()
+(defun rest--headers-alist ()
   "Return an alist of all headers above point."
   (let ((ac))
     (while (search-backward-regexp "^\\(X-[^ ]+\\): *\\(.*?\\)\r?$" nil 
'noerror)
@@ -149,64 +140,59 @@ value."
             ac))
     ac))
 
-(autoload 'json-read "json")
-
-(defvar api--url-depth nil
-  "Used to detect infinite redirection loops.")
-
 
 ;;; Authentication
-(defun api--auth-source-search (url-obj)
+(autoload 'auth-source-search "auth-source")
+(defun rest--auth-source-search (url-obj)
   "Return authentication information for URL-OBJ.
 URL-OBJ is a value returned by `url-generic-parse-url'.
 Information is found by running `auth-source-search' with the
 properties of URL-OBJ."
-  (let ((type (url-type url-obj))
-        (port (url-port url-obj))
+  (let ((port (url-port url-obj))
         (args (list :require '(:secret) :host (url-host url-obj)
                     :max 1 :user (url-user url-obj))))
-    (car (or (apply #'auth-source-search :port port :type type args)
-             (apply #'auth-source-search :port port args)
+    (car (or (apply #'auth-source-search :port port args)
              ;; If URL does not specify a port, try again without the default.
              (unless (url-portspec url-obj)
-               (or (apply #'auth-source-search :type type args)
-                   (apply #'auth-source-search args)))))))
+               (or (apply #'auth-source-search args)))))))
 
-(defun api--get-auth-info (info)
+(defun rest--get-auth-info (info)
   "Return a function that returns (USER . PASSWORD).
 INFO is a plist returned by `auth-source-search'."
   (let ((user (plist-get info :user))
         (pass (plist-get info :secret)))
     (lambda () (cons user (funcall pass)))))
 
-(defun api--make-authorization-header (_plist user password)
+(defun rest--make-authorization-header (_plist user password)
   "Return an alist containing an \"Authorization\" header.
 The car of the list is nil, so this function can be used as the
-AUTH-METHOD in `api-action'."
+AUTH-METHOD in `rest-action'."
   `(nil . (("Authorization" . ,(concat "Basic "
                                        (base64-encode-string
                                         (concat user ":" password)))))))
 
 
 ;;; The function
+(autoload 'json-read "json")
+
 ;;;###autoload
-(cl-defun api-action (url &rest all-options
-                          &key auth
-                          (method :get)
-                          (reader #'json-read)
-                          (callback #'identity)
-                          async
-                          (max-pages 1)
-                          (next-page-rule '(header "Link"))
-                          extra-headers
-                          (auth-method (if auth 
#'api--make-authorization-header))
-                          (return :simple)
-                          -url-history)
+(cl-defun rest-action (url &rest all-options
+                           &key auth
+                           (method :get)
+                           (reader #'json-read)
+                           (callback #'identity)
+                           async
+                           (max-pages 1)
+                           (next-page-rule '(header "Link"))
+                           extra-headers
+                           (auth-method (if auth 
#'rest--make-authorization-header))
+                           (return :simple)
+                           -url-history)
   "Contact URL with METHOD.
 METHOD is a keyword of an http method, defaulting to :get.
 
 URL can be a string such as \"user/starred?per_page=100\" to
-be appended at the end of `api-root'.  It can also be a full url
+be appended at the end of `rest-url-root'.  It can also be a full url
 string, in which case it is used verbatim.
 
 READER is called as a function with no arguments, with point
@@ -245,7 +231,7 @@ replaces URL and the cdr is appended to EXTRA-HEADERS.  It 
is
 called with a plist, the user string and the password string.
 The plist contais at least :url, :method, and :extra-headers.
 
-`api-action' can also handle the pagination used in server
+`rest-action' can also handle the pagination used in server
 results by appending together the contents of each page.  Use
 MAX-PAGES to increase the number of pages that are
 fetched (default 1).
@@ -263,25 +249,25 @@ values (string), as per `url-request-extra-headers'.
 
 If the http request is unsuccessful, an error is signaled
 according to the reply.  The possible errors are:
-`api-bad-request', `api-server-error', `api-unauthorized',
-`api-unintelligible-result', `api-empty-redirect',
-`api-page-does-not-exist', and `api-infinite-redirection-loop',
-all of which inherit from `api-error'.
+`rest-bad-request', `rest-server-error', `rest-unauthorized',
+`rest-unintelligible-result', `rest-empty-redirect',
+`rest-page-does-not-exist', and `rest-infinite-redirection-loop',
+all of which inherit from `rest-error'.
 
 \(fn URL &key AUTH (METHOD :get) (READER #'json-read) CALLBACK ASYNC 
AUTH-METHOD (MAX-PAGES 1) NEXT-PAGE-RULE EXTRA-HEADERS RETURN)"
   (declare (indent 1))
   (unless (string-match "\\`https?://" url)
-    (setq url (concat api-root url)))
+    (setq url (concat rest-url-root url)))
   (when (member url -url-history)
-    (signal 'api-infinite-redirection-loop (cons url api--url-depth)))
+    (signal 'rest-infinite-redirection-loop (cons url -url-history)))
   (when auth
     (let ((href (url-generic-parse-url url)))
       (when (url-password href)
         (error "AUTH requested, but URL already contains a password"))
       (unless (functionp auth)
-        (setq auth (api--get-auth-info (if (listp auth)
-                                           (apply #'auth-source-search auth)
-                                         (api--auth-source-search href)))))
+        (setq auth (rest--get-auth-info (if (listp auth)
+                                            (apply #'auth-source-search auth)
+                                          (rest--auth-source-search href)))))
       (pcase-let* ((`(,user . ,pass) (funcall auth))
                    (`(,new-url . ,headers)
                     (funcall auth-method (list :url url :method method
@@ -289,47 +275,47 @@ all of which inherit from `api-error'.
                              user pass)))
         (when new-url (setq url new-url))
         (setq extra-headers (append headers extra-headers)))))
-  (api--with-server-buffer method url
-    :extra-headers extra-headers
-    :-url-depth (cons url -url-history)
-    :async async
-    (pcase (api-parse-response-code auth)
-      (`nil nil)
-      ((and (pred stringp) link)
-       (message "Redirected to %s" link)
-       (apply #'api-action all-options))
-      (`t
-       (let ((next-page
-              (when (pcase next-page-rule
-                      (`(header ,name) (search-forward-regexp
-                                        (format "^%s: .*<\\([^>]+\\)>;" 
(regexp-quote name))
-                                        nil t))
-                      (`(regexp ,rx) (search-forward-regexp rx nil t))
-                      (_ nil))
-                (match-string-no-properties 1))))
-         (goto-char (point-min))
-         (search-forward-regexp "^\r?$")
-         (let* ((data (unless (eobp) (funcall reader))))
-           (if (or (not next-page)
-                   (< max-pages 2))
-               (pcase return
-                 (:simple (funcall callback data))
-                 (:rich `(,(funcall callback data)
-                          (next-page . ,next-page)
-                          ,@(api--headers-alist))))
-             (api-action next-page
-               :auth auth
-               :method method
-               :reader reader
-               :next-page-rule next-page-rule
-               :return return
-               :async  async
-               :max-pages (1- max-pages)
-               :callback (lambda (res)
-                           (funcall callback
-                                    (if (listp res)
-                                        (append data res)
-                                      (vconcat data res))))))))))))
-
-(provide 'api)
-;;; api.el ends here
+  (rest--with-response-buffer method url
+                              :extra-headers extra-headers
+                              :-url-depth (cons url -url-history)
+                              :async async
+                              (pcase (rest-parse-response-code auth)
+                                (`nil nil)
+                                ((and (pred stringp) link)
+                                 (message "Redirected to %s" link)
+                                 (apply #'rest-action all-options))
+                                (`t
+                                 (let ((next-page
+                                        (when (pcase next-page-rule
+                                                (`(header ,name) 
(search-forward-regexp
+                                                                  (format 
"^%s: .*<\\([^>]+\\)>;" (regexp-quote name))
+                                                                  nil t))
+                                                (`(regexp ,rx) 
(search-forward-regexp rx nil t))
+                                                (_ nil))
+                                          (match-string-no-properties 1))))
+                                   (goto-char (point-min))
+                                   (search-forward-regexp "^\r?$")
+                                   (let* ((data (unless (eobp) (funcall 
reader))))
+                                     (if (or (not next-page)
+                                             (< max-pages 2))
+                                         (pcase return
+                                           (:simple (funcall callback data))
+                                           (:rich `(,(funcall callback data)
+                                                    (next-page . ,next-page)
+                                                    ,@(rest--headers-alist))))
+                                       (rest-action next-page
+                                                    :auth auth
+                                                    :method method
+                                                    :reader reader
+                                                    :next-page-rule 
next-page-rule
+                                                    :return return
+                                                    :async  async
+                                                    :max-pages (1- max-pages)
+                                                    :callback (lambda (res)
+                                                                (funcall 
callback
+                                                                         (if 
(listp res)
+                                                                             
(append data res)
+                                                                           
(vconcat data res))))))))))))
+
+(provide 'rest)
+;;; rest.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]