about summary refs log blame commit diff
path: root/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-request.el
blob: 43c97face3c174a067cea1e74093362976bbd7aa (plain) (tree)

































































































































































                                                                                                                              
;;; slack-request.el ---slack request function       -*- lexical-binding: t; -*-

;; Copyright (C) 2015  南優也

;; Author: 南優也 <yuyaminami@minamiyuunari-no-MacBook-Pro.local>
;; Keywords:

;; This program 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.

;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:

;;

;;; Code:

(require 'eieio)
(require 'json)
(require 'request)
(require 'slack-util)

(defcustom slack-request-timeout 10
  "Request Timeout in seconds."
  :group 'slack)

(defun slack-parse ()
  (let ((json-object-type 'plist)
        (json-array-type 'list))
    (json-read)))

(defun slack-request-parse-payload (payload)
  (let ((json-object-type 'plist)
        (json-array-type 'list))
    (condition-case err-var
        (json-read-from-string payload)
      (json-end-of-file nil))))

(defclass slack-request-request ()
  ((response :initform nil)
   (url :initarg :url)
   (team :initarg :team)
   (type :initarg :type :initform "GET")
   (success :initarg :success)
   (error :initarg :error :initform nil)
   (params :initarg :params :initform nil)
   (data :initarg :data :initform nil)
   (parser :initarg :parser :initform #'slack-parse)
   (sync :initarg :sync :initform nil)
   (files :initarg :files :initform nil)
   (headers :initarg :headers :initform nil)
   (timeout :initarg :timeout :initform `,slack-request-timeout)
   (execute-at :initform 0.0 :type float)))

(cl-defun slack-request-create
    (url team &key type success error params data parser sync files headers timeout)
  (let ((args (list
               :url url :team team :type type
               :success success :error error
               :params params :data data :parser parser
               :sync sync :files files :headers headers
               :timeout timeout))
        (ret nil))
    (mapc #'(lambda (maybe-key)
              (let ((value (plist-get args maybe-key)))
                (when value
                  (setq ret (plist-put ret maybe-key value)))))
          args)
    (apply #'make-instance 'slack-request-request ret)))

(defmethod slack-equalp ((this slack-request-request) other)
  (and (string= (oref (oref this team) id)
                (oref (oref other team) id))
       (string= "GET" (oref this type))
       (string= "GET" (oref other type))
       (string= (oref this url)
                (oref other url))
       (equalp (oref this params)
               (oref other params))))

(defmethod slack-request-retry-request ((req slack-request-request) retry-after team)
  (oset req execute-at (+ retry-after (time-to-seconds)))
  (slack-request-worker-push req))

(cl-defmethod slack-request ((req slack-request-request)
                             &key (on-success nil) (on-error nil))
  (let ((team (oref req team)))
    (with-slots (url type success error params data parser sync files headers timeout) req
      (cl-labels
          ((on-success (&key data &allow-other-keys)
                       (funcall success :data data)
                       (slack-log
                        (format "Request Finished. URL: %s, PARAMS: %s"
                                url
                                params)
                        team :level 'trace)
                       (when (functionp on-success)
                         (funcall on-success)))
           (on-error (&key error-thrown symbol-status response data)
                     (slack-if-let* ((retry-after (request-response-header response "retry-after"))
                                     (retry-after-sec (string-to-number retry-after)))
                         (progn
                           (slack-request-retry-request req retry-after-sec team)
                           (slack-log (format "Retrying Request After: %s second, URL: %s, PARAMS: %s"
                                              retry-after-sec
                                              url
                                              params)
                                      team))
                       (slack-log (format "Request Failed. URL: %s, PARAMS: %s, ERROR-THROWN: %s, SYMBOL-STATUS: %s, DATA: %s"
                                          url
                                          params
                                          error-thrown
                                          symbol-status
                                          data)
                                  team
                                  :level 'error)
                       (when (functionp error)
                         (funcall error
                                  :error-thrown error-thrown
                                  :symbol-status symbol-status
                                  :response response
                                  :data data))
                       (when (functionp on-error)
                         (funcall on-error)))))
        (oset req response
              (request
               url
               :type type
               :sync sync
               :params (cons (cons "token" (oref team token))
                             params)
               :data data
               :files files
               :headers headers
               :parser parser
               :success #'on-success
               :error #'on-error
               :timeout timeout))))))


(cl-defmacro slack-request-handle-error ((data req-name &optional handler) &body body)
  "Bind error to e if present in DATA."
  `(if (eq (plist-get ,data :ok) :json-false)
       (if ,handler
           (funcall ,handler (plist-get ,data :error))
         (message "Failed to request %s: %s"
                  ,req-name
                  (plist-get ,data :error)))
     (progn
       ,@body)))

(provide 'slack-request)
;;; slack-request.el ends here