2012-05-25 20:57:48 +02:00
|
|
|
;;; ein-query.el --- jQuery like interface on to of url-retrieve
|
|
|
|
|
|
|
|
;; Copyright (C) 2012- Takafumi Arakaki
|
|
|
|
|
|
|
|
;; Author: Takafumi Arakaki
|
|
|
|
|
|
|
|
;; 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 'url)
|
|
|
|
|
|
|
|
(require 'ein-utils)
|
|
|
|
(require 'ein-log)
|
|
|
|
|
|
|
|
(defun ein:safe-funcall-packed (packed &rest args)
|
|
|
|
(when packed
|
|
|
|
(ein:log-ignore-errors (apply #'ein:funcall-packed packed args))))
|
|
|
|
|
2012-05-26 16:34:04 +02:00
|
|
|
(ein:deflocal ein:query-ajax-timer nil)
|
|
|
|
|
2012-05-25 20:57:48 +02:00
|
|
|
(defun* ein:query-ajax (url &rest settings
|
|
|
|
&key
|
|
|
|
(cache t)
|
|
|
|
(type "GET")
|
|
|
|
(data nil)
|
|
|
|
(headers nil)
|
|
|
|
(success nil)
|
|
|
|
(error nil)
|
|
|
|
(timeout nil)
|
|
|
|
(status-code nil))
|
|
|
|
"Mimic `$.ajax'.
|
|
|
|
|
|
|
|
:CACHE (nil/t) : append time-stamp to URL so the URL is always loaded.
|
|
|
|
:TYPE (string) : sets `url-request-method'
|
|
|
|
:DATA (string) : sets `url-request-data'
|
|
|
|
:HEADERS (alist) : sets `url-request-extra-headers'
|
|
|
|
:SUCCESS (cons) : called on success
|
|
|
|
:ERROR (cons) : called on error
|
|
|
|
:TIMEOUT (number) : timeout in millisecond
|
|
|
|
:STATUS-CODE (alist) : map status code (int) to callback (cons)
|
|
|
|
|
|
|
|
* Callback functions
|
|
|
|
|
|
|
|
All callbacks must be given as `cons' where car is a FUNCTION and
|
|
|
|
cdr is its first ARGUMENT. It is analogous of `$.proxy'. Call
|
|
|
|
signature is like this:
|
|
|
|
\(FUNCTION ARGUMENT [other callback specific arguments])
|
|
|
|
|
|
|
|
The second note is that the callback FUNCTION must be defined
|
|
|
|
using `defun*' with `&key' and `&allow-other-keys' to ignore
|
|
|
|
missing/extra arguments as some callback (namely :ERROR) changes
|
|
|
|
arguments to be passed, depending on situation.
|
|
|
|
|
|
|
|
Finally, note that callback FUNCTION is executed on the process
|
|
|
|
buffer, meaning that response data is on the current buffer when
|
|
|
|
the FUNCTION is called. There is no `:data' argument for
|
|
|
|
FUNCTION so it must be fetched from the buffer.
|
|
|
|
|
|
|
|
* :ERROR callback
|
|
|
|
|
|
|
|
:SYMBOL-STATUS (`error'/`timeout') : analogous of `textStatus'
|
|
|
|
:STATUS (list) : see `url-retrieve'
|
|
|
|
|
|
|
|
The :SUCCESS callback also takes the :STATUS argument.
|
|
|
|
|
|
|
|
* See also: http://api.jquery.com/jQuery.ajax/"
|
2012-05-26 16:34:04 +02:00
|
|
|
(ein:log 'debug "EIN:QUERY-AJAX")
|
2012-05-25 20:57:48 +02:00
|
|
|
(unless cache
|
|
|
|
(setq url (ein:url-no-cache url)))
|
|
|
|
(let* ((url-request-extra-headers headers)
|
|
|
|
(url-request-method type)
|
|
|
|
(url-request-data data)
|
|
|
|
(buffer (url-retrieve url #'ein:query-ajax-callback settings)))
|
|
|
|
(when timeout
|
2012-05-26 16:34:04 +02:00
|
|
|
(ein:log 'debug "Start timer: timeout=%s ms" timeout)
|
|
|
|
(with-current-buffer buffer
|
|
|
|
(setq ein:query-ajax-timer
|
2012-05-26 17:01:23 +02:00
|
|
|
(apply #'run-at-time
|
|
|
|
(/ timeout 1000.0) nil
|
|
|
|
#'ein:query-ajax-timeout-callback
|
|
|
|
(cons buffer settings)))))
|
2012-05-25 20:57:48 +02:00
|
|
|
buffer))
|
|
|
|
|
|
|
|
(defun* ein:query-ajax-callback (status &key
|
|
|
|
(headers nil)
|
|
|
|
(success nil)
|
|
|
|
(error nil)
|
|
|
|
(timeout nil)
|
|
|
|
(status-code nil)
|
|
|
|
&allow-other-keys)
|
2012-05-26 17:18:34 +02:00
|
|
|
(declare (special url-http-response-status
|
|
|
|
url-http-method))
|
2012-05-25 20:57:48 +02:00
|
|
|
(unwind-protect
|
|
|
|
(progn
|
|
|
|
(ein:log 'debug "EIN:QUERY-AJAX-CALLBACK")
|
|
|
|
(ein:log 'debug "status = %S" status)
|
|
|
|
(ein:log 'debug "url-http-response-status = %s"
|
2012-05-26 17:18:34 +02:00
|
|
|
url-http-response-status)
|
2012-05-25 20:57:48 +02:00
|
|
|
(ein:log 'debug "(buffer-string) =\n%s" (buffer-string))
|
|
|
|
|
2012-05-26 17:13:17 +02:00
|
|
|
(save-current-buffer
|
|
|
|
(apply #'ein:safe-funcall-packed
|
|
|
|
(if (plist-get status :error)
|
|
|
|
(list error :symbol-status 'error :status status)
|
2012-05-26 17:20:20 +02:00
|
|
|
(list success :status status))))
|
|
|
|
(save-current-buffer
|
2012-05-26 17:18:34 +02:00
|
|
|
(ein:aif (assq url-http-response-status status-code)
|
2012-05-26 17:13:17 +02:00
|
|
|
(ein:safe-funcall-packed (cdr it)))))
|
2012-05-26 16:34:04 +02:00
|
|
|
(ein:query-ajax-cancel-timer)
|
2012-05-25 20:57:48 +02:00
|
|
|
(kill-buffer)))
|
|
|
|
|
|
|
|
(defun* ein:query-ajax-timeout-callback (buffer &key
|
|
|
|
(error nil)
|
|
|
|
&allow-other-keys)
|
2012-05-26 17:01:23 +02:00
|
|
|
(ein:log 'debug "EIN:QUERY-AJAX-TIMEOUT-CALLBACK buffer = %s" buffer)
|
2012-05-25 20:57:48 +02:00
|
|
|
(with-current-buffer buffer
|
|
|
|
(ein:safe-funcall-packed error :symbol-status 'timeout))
|
|
|
|
(let ((proc (process-buffer buffer)))
|
|
|
|
(kill-process proc)
|
|
|
|
(kill-buffer buffer)))
|
|
|
|
|
2012-05-26 16:34:04 +02:00
|
|
|
(defun ein:query-ajax-cancel-timer ()
|
|
|
|
(ein:log 'debug "EIN:QUERY-AJAX-CANCEL-TIMER")
|
|
|
|
(when ein:query-ajax-timer
|
2012-05-26 17:00:21 +02:00
|
|
|
(cancel-timer ein:query-ajax-timer)
|
|
|
|
(setq ein:query-ajax-timer nil)))
|
2012-05-26 16:34:04 +02:00
|
|
|
|
2012-05-25 20:57:48 +02:00
|
|
|
(provide 'ein-query)
|
|
|
|
|
|
|
|
;;; ein-query.el ends here
|