Skip to content

Instantly share code, notes, and snippets.

@rlb3
Created August 6, 2011 16:46
Show Gist options
  • Save rlb3/1129505 to your computer and use it in GitHub Desktop.
Save rlb3/1129505 to your computer and use it in GitHub Desktop.
Common Lisp Fogbugz Library
(asdf:oos 'asdf:load-op :drakma)
(asdf:oos 'asdf:load-op :cl-libxml2)
(asdf:oos 'asdf:load-op :iterate)
(defpackage :fogbugz(:use :cl :iter :drakma :xtree :xpath))
(in-package :fogbugz)
(use-package :iterate)
(defclass Context ()
((user :initarg :user
:accessor user)
(password :initarg :password
:accessor password)
(token :initarg :token
:accessor token)))
(defclass Fogbugz ()
((url :initarg :url
:accessor url)
(context :initarg :context
:accessor context)))
(defun connect (&key user pass url)
(let* ((c (make-instance 'Context :user user :password pass))
(fb (make-instance 'Fogbugz :url url :context c)))
(progn (login fb)
fb)))
(defmethod login ((f Fogbugz))
(let ((params `(("cmd" . "logon")
("email" . ,(user (context f)))
("password" . ,(password (context f))))))
(multiple-value-bind (xml status headers) (http-request (url f) :parameters params)
(setf (token (context f)) (car (xtree:with-parse-document (doc xml)
(iter (for node in-xpath-result "/response/token" on doc)
(iter:collect (xtree:text-content node)))))))))
(defmethod login-p ((f Fogbugz))
(or (token (context f)) nil))
(defmethod logout ((f Fogbugz))
(let ((params `(("cmd" . "logoff")
("token" . ,(token (context f))))))
(http-request (url f) :parameters params)
(setf (token (context f)) nil)))
(defmethod set-filter ((f Fogbugz) filter)
(let ((params `(("cmd" . "setCurrentFilter")
("sFilter" . ,(format nil "~d" filter))
("token" . ,(token (context f))))))
(multiple-value-bind (xml status headers) (http-request (url f) :parameters params)
(when (= status 200) t))))
(defmethod list-filters ((f Fogbugz))
(let ((params `(("cmd" . "listFilters")
("token" . ,(token (context f)))))
(xpath-string (format nil "~{~a~^ | ~}" '("/response/filters/filter/@sFilter"
"/response/filters/filter/node()"))))
(multiple-value-bind (xml status headers) (http-request (url f) :parameters params)
(let ((plist (xtree:with-parse-document (doc xml)
(iter (for node in-xpath-result xpath-string on doc)
(collect (xtree:text-content node))))))
(labels ((to-alist (a lst)
(let ((key (first lst))
(val (second lst)))
(if (null lst)
a
(to-alist (acons key val a) (cddr lst))))))
(to-alist '() plist))))))
(defmethod list-cases ((f Fogbugz))
(let ((params `(("cmd" . "search")
("cols" . "ixBug,fOpen,sTitle,sLatestTextSummary,sPersonAssignedTo,sStatus,ixPriority")
("token" . ,(token (context f)))))
(xpath-string (format nil "~{~a~^ | ~}" '("/response/cases/case/ixBug"
"/response/cases/case/fOpen"
"/response/cases/case/sTitle"
"/response/cases/case/sLatestTextSummary"
"/response/cases/case/sPersonAssignedTo"
"/response/cases/case/sStatus"
"/response/cases/case/ixPriority"))))
(multiple-value-bind (xml status headers) (http-request (url f) :parameters params)
(let ((lst (xtree:with-parse-document (doc xml)
(iter (for node in-xpath-result xpath-string on doc)
(collect (xtree:text-content node))))))
(labels ((build-tree (a lst)
(let ((case (nth 0 lst))
(open (nth 1 lst))
(title (nth 2 lst))
(summary (nth 3 lst))
(name (nth 4 lst))
(status (nth 5 lst))
(priority (nth 6 lst)))
(if (null lst)
a
(build-tree
(concatenate 'list a (list (list (cons :CASE case)
(cons :OPEN open)
(cons :TITLE title)
(cons :SUMMARY summary)
(cons :ASSIGNED name)
(cons :STATUS status)
(cons :PRIORITY priority))))
(cdddr (cddddr lst)))))))
(build-tree '() lst))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment