emacs-ipython-notebook/lisp/ein-query.el

137 lines
4.7 KiB
EmacsLisp
Raw Normal View History

2012-05-25 20:57:48 +02:00
;;; ein-query.el --- jQuery like interface on to of url-retrieve
;; Copyright (C) 2012- Takafumi Arakaki
2012-07-01 20:18:05 +02:00
;; Author: Takafumi Arakaki <aka.tkf at gmail.com>
2012-05-25 20:57:48 +02:00
;; This file is NOT part of GNU Emacs.
;; ein-query.el is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; ein-query.el is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with ein-query.el. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;
;;; Code:
(eval-when-compile (require 'cl))
(require 'request)
(require 'request-deferred)
(require 'url)
2012-05-25 20:57:48 +02:00
(require 'ein-core)
2012-05-25 20:57:48 +02:00
(require 'ein-log)
2012-06-08 13:54:39 +02:00
;;; Utils
2012-05-25 20:57:48 +02:00
(defun ein:safe-funcall-packed (packed &rest args)
(when packed
(ein:log-ignore-errors (apply #'ein:funcall-packed packed args))))
2012-06-08 13:54:39 +02:00
;;; Variables
2012-05-27 01:58:39 +02:00
(defcustom ein:query-timeout
(if (eq request-backend 'url-retrieve) 1000 nil)
2012-06-21 00:38:15 +02:00
"Default query timeout for HTTP access in millisecond.
Setting this to `nil' means no timeout.
If you have ``curl`` command line program, it is automatically set to
`nil' as ``curl`` is reliable than `url-retrieve' therefore no need for
a workaround (see below).
2012-06-21 00:38:15 +02:00
If you do the same operation before the timeout, old operation
will be canceled \(see also `ein:query-singleton-ajax').
.. note:: This value exists because it looks like `url-retrieve'
2012-06-21 15:03:41 +02:00
occasionally fails to finish \(start?) querying. Timeout is
used to let user notice that their operation is not finished.
It also prevent opening a lot of useless process buffers.
You will see them when closing Emacs if there is no timeout.
2012-06-21 00:38:15 +02:00
2012-06-21 15:03:41 +02:00
If you know how to fix the problem with `url-retrieve', please
let me know or send pull request at github!
2012-06-21 00:38:15 +02:00
\(Related bug report in Emacs bug tracker:
http://debbugs.gnu.org/cgi/bugreport.cgi?bug=11469)"
2012-05-27 01:58:39 +02:00
:type '(choice (integer :tag "Timeout [ms]" 5000)
(const :tag "No timeout" nil))
:group 'ein)
2012-06-08 13:54:39 +02:00
;;; Functions
2012-06-20 20:56:04 +02:00
(defvar ein:query-running-process-table (make-hash-table :test 'equal))
(defun ein:query-prepare-header (url settings &optional securep)
"Ensure that REST calls to the jupyter server have the correct
_xsrf argument."
(let ((cookies (request-cookie-alist (url-host (url-generic-parse-url url))
"/" securep)))
(ein:aif (assoc-string "_xsrf" cookies)
(plist-put settings :headers (list (cons "X-XSRFTOKEN" (cdr it))))
settings)))
(defun* ein:query-singleton-ajax (key url &rest settings
&key
(timeout ein:query-timeout)
&allow-other-keys)
2012-06-20 20:56:04 +02:00
"Cancel the old process if there is a process associated with
KEY, then call `request' with URL and SETTINGS. KEY is compared by
2012-06-20 20:56:04 +02:00
`equal'."
(with-local-quit
(ein:query-gc-running-process-table)
(when timeout
(setq settings (plist-put settings :timeout (/ timeout 1000.0))))
(ein:aif (gethash key ein:query-running-process-table)
(unless (request-response-done-p it)
(request-abort it))) ; This will run callbacks
(let ((response (apply #'request (url-encode-url url)
(ein:query-prepare-header url settings))))
(puthash key response ein:query-running-process-table)
response)))
2012-06-20 20:56:04 +02:00
(defun* ein:query-deferred (url &rest settings
&key
(timeout ein:query-timeout)
&allow-other-keys)
""
(apply #'request-deferred (url-encode-url url)
(ein:query-prepare-header url settings)))
2012-06-20 20:56:04 +02:00
(defun ein:query-gc-running-process-table ()
"Garbage collect dead processes in `ein:query-running-process-table'."
(maphash
(lambda (key buffer)
(when (request-response-done-p buffer)
2012-06-20 20:56:04 +02:00
(remhash key ein:query-running-process-table)))
ein:query-running-process-table))
(defun ein:get-response-redirect (response)
"Determine if the query has been redirected, and if so return then URL the request was redirected to."
(if (length (request-response-history response))
(let ((url (url-generic-parse-url (format "%s" (request-response-url response)))))
(format "%s://%s:%s"
(url-type url)
(url-host url)
(url-port url)))))
2012-12-17 16:48:18 +01:00
;;; Cookie
2012-12-29 19:30:00 +01:00
(defalias 'ein:query-get-cookie 'request-cookie-string)
2012-12-17 16:48:18 +01:00
2012-05-25 20:57:48 +02:00
(provide 'ein-query)
;;; ein-query.el ends here