diff options
| -rw-r--r-- | rt-liberation-rest.el | 152 | 
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. | 
