summaryrefslogtreecommitdiff
path: root/rt-liberation-rest.el
diff options
context:
space:
mode:
Diffstat (limited to 'rt-liberation-rest.el')
-rw-r--r--rt-liberation-rest.el152
1 files changed, 152 insertions, 0 deletions
diff --git a/rt-liberation-rest.el b/rt-liberation-rest.el
new file mode 100644
index 0000000..2fbe8a6
--- /dev/null
+++ b/rt-liberation-rest.el
@@ -0,0 +1,152 @@
+;;; rt-liberation-rest.el --- Interface to the RT REST API
+
+;; Copyright (C) 2014 Yoni Rabkin
+;;
+;; Authors: Yoni Rabkin <yrk@gnu.org>
+;;
+;; 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 2 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, write to the Free
+;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
+;;
+;; Note: Licensed under GPLv2+ and not GPLv3+ in order to be
+;; compatible with the license of RT.
+
+;;; History:
+;;
+;; Started in May of 2014 in order to remove rt-liberation's
+;; dependency on a local copy of the RT CLI.
+
+;;; Code:
+
+(require 'url)
+(require 'url-util)
+
+
+(defvar rt-liber-rest-debug ""
+ "Debug capture of last HTTP call.")
+
+(defvar rt-liber-rest-scheme "https"
+ "Scheme used for transport. Is one of http or https.")
+
+(defvar rt-liber-rest-url ""
+ "URL of RT installation.")
+
+(defvar rt-liber-rest-username ""
+ "Username of RT account.")
+
+(defvar rt-liber-rest-password ""
+ "Password of RT account.")
+
+
+(defun rt-liber-rest-search-string (scheme url username password query)
+ ""
+ (let ((user (url-encode-url username))
+ (pass (url-encode-url password)))
+ (concat scheme
+ "://"
+ url
+ "/REST/1.0/search/ticket" "?"
+ "user=" user "&"
+ "pass=" pass "&"
+ "query=" (url-encode-url query) "&"
+ "format=i" "&"
+ "orderby=+Created")))
+
+(defun rt-liber-rest-show-string (scheme url ticket-id-list username password query)
+ ""
+ (let ((user (url-encode-url username))
+ (pass (url-encode-url password)))
+ (concat scheme
+ "://"
+ url
+ "/REST/1.0/ticket/" ticket-id-list
+ "/show" "?"
+ "user=" user "&"
+ "pass=" pass "&")))
+
+(defun rt-liber-rest-call (url)
+ ""
+ (let ((url-request-method "POST"))
+ (let ((response
+ (url-retrieve-synchronously url))
+ str)
+ (setq str
+ (with-current-buffer response
+ (buffer-substring-no-properties (point-min)
+ (point-max))))
+ (setq rt-liber-rest-debug str)
+ str)))
+
+(defun rt-liber-rest-query-runner (op query-string)
+ (message "starting REST '%s' query at %s..." op (current-time-string))
+ (when (or (not (stringp op))
+ (not (stringp query-string)))
+ (error "bad arguments"))
+ (cond ((string= op "ls")
+ (rt-liber-rest-call
+ (rt-liber-rest-search-string rt-liber-rest-scheme
+ rt-liber-rest-url
+ rt-liber-rest-username
+ rt-liber-rest-password
+ query-string)))
+ ;; The "show" API call doesn't support getting multiple
+ ;; tickets at once. This is a problem. I've emailed the
+ ;; rt-users mailing list asking how to to this.
+ ;;
+ ;; A much more insidious method to figure this out is to
+ ;; wireshark the CLI connection as it asks for multiple
+ ;; tickets and see if we can capture the query the CLI
+ ;; uses. This would necessitate a non-HTTPS connection, such
+ ;; that the one to the demo servers.
+ ((string= op "show")
+ (rt-liber-rest-show-string rt-liber-rest-scheme
+ rt-liber-rest-url
+ query-string
+ rt-liber-rest-username
+ rt-liber-rest-password
+ query-string))
+ (t (error "unknown op [%s]" op))))
+
+(defun rt-liber-rest-parse-http-header ()
+ "Parse the HTTP header from the server."
+ (let ((http-ok-regexp "^HTTP.*200 OK$")
+ (rt-ok-regexp "^rt/.*200 ok$"))
+ (condition-case excep
+ (progn
+ (re-search-forward http-ok-regexp (point-max))
+ (re-search-forward rt-ok-regexp (point-max)))
+ (error "bad HTTP response from server"))))
+
+(defun rt-liber-rest-ticketsql-runner-parser-f ()
+ "Parser function for a textual list of tickets."
+ (let (idsub-list)
+ (rt-liber-rest-parse-http-header)
+ (while (re-search-forward "ticket/\\([0-9].+\\)" (point-max) t)
+ ;; the output should be compatible with the input to
+ ;; `rt-liber-create-tickets-string'
+ (push (list (match-string-no-properties 1)
+ ".")
+ idsub-list))
+ idsub-list))
+
+(defun rt-liber-rest-run-ls-query (query)
+ "Run an \"ls\" type query against the server with QUERY."
+ (rt-liber-parse-answer
+ (rt-liber-rest-query-runner "ls" query)
+ 'rt-liber-rest-ticketsql-runner-parser-f))
+
+
+(provide 'rt-liber-rest)
+
+;;; rt-liberation-rest.el ends here.