1 ;;; org-jira-sdk.el -- SDK Layer for entities
3 ;; Copyright (C) 2018 Matthew Carter <m@ahungry.com>
6 ;; Matthew Carter <m@ahungry.com>
8 ;; Maintainer: Matthew Carter <m@ahungry.com>
9 ;; URL: https://github.com/ahungry/org-jira
11 ;; Keywords: ahungry jira org bug tracker
12 ;; Package-Requires: ((emacs "24.5") (cl-lib "0.5") (request "0.2.0") (s "0.0.0"))
14 ;; This file is not part of GNU Emacs.
16 ;; This program is free software: you can redistribute it and/or modify
17 ;; it under the terms of the GNU General Public License as published by
18 ;; the Free Software Foundation, either version 3 of the License, or
19 ;; (at your option) any later version.
21 ;; This program is distributed in the hope that it will be useful,
22 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
23 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 ;; GNU General Public License for more details.
26 ;; You should have received a copy of the GNU General Public License
27 ;; along with this program. If not, see
28 ;; <http://www.gnu.org/licenses/> or write to the Free Software
29 ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
34 ;; This provides an SDK wrapper for more strictly defining the entities we interact with.
45 (defclass org-jira-sdk-record
()
46 ((id :initarg
:id
:type string
:required t
)
47 (data :initarg
:data
:documentation
"The area to hold a big alist of data.")
48 (hydrate-fn :initform
(lambda (id) (message "Not implemented."))))
49 "The ID of the record.")
51 (defun org-jira-sdk-string-but-first (s) (cl-subseq s
1))
53 (defun org-jira-sdk-to-string (s) (format "%s" s
))
55 (defun org-jira-sdk-to-prefixed-string (s) (format "org-jira-sdk-%s" s
))
57 (defun org-jira-sdk-record-type-to-symbol (record-type)
58 (-> record-type symbol-name org-jira-sdk-string-but-first org-jira-sdk-to-prefixed-string intern
))
60 (defun org-jira-sdk-create-from-id (record-type id
&optional parent-id callback
)
61 (let ((rec (funcall (org-jira-sdk-record-type-to-symbol record-type
)
63 :parent-id parent-id
)))
64 (with-slots (data) rec
65 (setf data
(org-jira-sdk-hydrate rec callback
))
66 (org-jira-sdk-from-data rec
))))
68 (defun org-jira-sdk-create-from-data (record-type data
)
69 (let ((rec (funcall (org-jira-sdk-record-type-to-symbol record-type
) :data data
)))
70 (org-jira-sdk-from-data rec
)))
72 (cl-defmethod org-jira-sdk-hydrate ((rec org-jira-sdk-record
) &optional callback
)
73 "Populate the record with data from the remote endpoint."
74 (with-slots (id hydrate-fn
) rec
75 (funcall hydrate-fn id callback
)))
77 (cl-defgeneric org-jira-sdk-from-data
((rec org-jira-sdk-record
)))
79 (cl-defmethod org-jira-sdk-dump ((rec org-jira-sdk-record
))
80 "A decent pretty print/object dump for working with the class items."
81 (let ((slots (mapcar (lambda (slot) (aref slot
1)) (eieio-class-slots (eieio-object-class rec
)))))
82 (setq slots
(cl-remove-if (lambda (s) (not (slot-boundp rec s
))) slots
))
84 (mapcar (lambda (slot)
85 (let ((slot (intern (org-jira-sdk-to-string slot
))))
86 (format "\n%+16s: %s" slot
(slot-value rec
(intern (org-jira-sdk-to-string slot
)))))
90 (defun org-jira-sdk-path (alist key-chain
)
91 "Query a nested path in some type of ALIST by traversing down the keys of KEY-CHAIN."
92 (cl-reduce (lambda (a k
) (alist-get k a
)) key-chain
:initial-value alist
))
94 (defclass org-jira-sdk-issue
(org-jira-sdk-record)
95 ((assignee :type
(or null string
) :initarg
:assignee
)
96 (components :type string
:initarg
:components
)
97 (created :type string
:initarg
:created
)
98 (description :type
(or null string
) :initarg
:description
)
99 (duedate :type
(or null string
) :initarg
:duedate
)
100 (headline :type string
:initarg
:headline
)
101 (id :type string
:initarg
:id
) ; TODO: Probably remove me
102 (issue-id :type string
:initarg
:issue-id
:documentation
"The common ID/key, such as EX-1.")
103 (issue-id-int :type string
:initarg
:issue-id-int
:documentation
"The internal Jira ID, such as 12345.")
104 (priority :type string
:initarg
:priority
)
105 (proj-key :type string
:initarg
:proj-key
)
106 (reporter :type
(or null string
) :initarg
:reporter
)
107 (resolution :type
(or null string
) :initarg
:resolution
)
108 (start-date :type
(or null string
) :initarg
:start-date
)
109 (status :type string
:initarg
:status
)
110 (summary :type string
:initarg
:summary
)
111 (type :type string
:initarg
:type
)
112 (updated :type string
:initarg
:updated
)
113 (data :initarg
:data
:documentation
"The remote Jira data object (alist).")
114 (hydrate-fn :initform
#'jiralib-get-issue
:initarg
:hydrate-fn
))
115 "An issue on the end. ID of the form EX-1, or a numeric such as 10000.")
117 (defclass org-jira-sdk-comment
(org-jira-sdk-record)
118 ((author :type string
:initarg
:author
)
119 (body :type string
:initarg
:body
)
120 (comment-id :type string
:initarg
:comment-id
:documentation
"The comment ID, such as 12345.")
121 (created :type string
:initarg
:created
)
122 (headline :type string
:initarg
:headline
)
123 (parent-id :type string
:initarg
:parent-id
:documentation
"The parent issue-id such as EX-1.")
124 (updated :type string
:initarg
:updated
)
125 (data :initarg
:data
:documentation
"The reomte Jira data object (alist).")
126 (hydrate-fn :initform
#'jiralib-get-comment
:initarg
:hydrate-fn
)))
128 (defclass org-jira-sdk-board
(org-jira-sdk-record)
129 ((name :type string
:initarg
:name
:required t
)
130 (url :type string
:initarg
:url
:required t
)
131 (board-type :type string
:initarg
:board-type
)
132 (jql :type string
:initarg
:jql
)
133 (limit :type integer
:initarg
:limit
)
135 (parent-id :type string
:initarg
:parent-id
)
136 (hydrate-fn :initform
#'jiralib-get-board
:initarg
:hydrate-fn
)))
138 (cl-defmethod org-jira-sdk-hydrate ((rec org-jira-sdk-comment
) &optional callback
)
139 "Populate the record with data from the remote endpoint."
140 (with-slots (id proj-key hydrate-fn
) rec
141 (funcall hydrate-fn proj-key id callback
)))
143 (cl-defmethod org-jira-sdk-from-data ((rec org-jira-sdk-issue
))
144 (cl-flet ((path (keys) (org-jira-sdk-path (oref rec data
) keys
)))
146 :assignee
(path '(fields assignee name
))
147 :components
(mapconcat (lambda (c) (org-jira-sdk-path c
'(name))) (path '(fields components
)) ", ")
148 :created
(path '(fields created
)) ; confirm
149 :description
(or (path '(fields description
)) "")
150 :duedate
(path '(fields duedate
)) ; confirm
151 :headline
(path '(fields summary
)) ; Duplicate of summary, maybe different.
153 :issue-id
(path '(key))
154 :issue-id-int
(path '(id))
155 :priority
(path '(fields priority name
))
156 :proj-key
(path '(fields project key
))
157 :reporter
(path '(fields reporter name
)) ; reporter could be an object of its own slot values
158 :resolution
(path '(fields resolution name
)) ; confirm
159 :start-date
(path '(fields start-date
)) ; confirm
160 :status
(org-jira-decode (path '(fields status name
)))
161 :summary
(path '(fields summary
))
162 :type
(path '(fields issuetype name
))
163 :updated
(path '(fields updated
)) ; confirm
165 ;; :data (oref rec data)
168 (cl-defmethod org-jira-sdk-from-data ((rec org-jira-sdk-comment
))
169 (cl-flet ((path (keys) (org-jira-sdk-path (oref rec data
) keys
)))
170 (org-jira-sdk-comment
171 :author
(path '(author displayName
))
173 :comment-id
(path '(id))
174 :created
(path '(created))
175 :headline
(format "Comment: %s" (path '(author displayName
)))
176 :parent-id
(if (slot-boundp rec
'parent-id
) (oref rec parent-id
) "")
177 :updated
(path '(updated))
179 ;; :data (oref rec data)
182 (cl-defmethod org-jira-sdk-from-data ((rec org-jira-sdk-board
))
183 (with-slots (data) rec
185 :id
(int-to-string (alist-get 'id data
))
186 :name
(alist-get 'name data
)
187 :url
(alist-get 'self data
)
188 ;; TODO: remove it? used by org-jira-sdk-create-from-id
190 :board-type
(alist-get 'type data
))))
193 (defun org-jira-sdk-create-issue-from-data (d) (org-jira-sdk-create-from-data :issue d
))
194 (defun org-jira-sdk-create-issues-from-data-list (ds) (mapcar #'org-jira-sdk-create-issue-from-data ds
))
197 (defun org-jira-sdk-create-comment-from-data (d) (org-jira-sdk-create-from-data :comment d
))
198 (defun org-jira-sdk-create-comments-from-data-list (ds) (mapcar #'org-jira-sdk-create-comment-from-data ds
))
200 (defun org-jira-sdk-isa-record?
(i) (typep i
'org-jira-sdk-record
))
201 (defun org-jira-sdk-isa-issue?
(i) (typep i
'org-jira-sdk-issue
))
202 (defun org-jira-sdk-isa-comment?
(i) (typep i
'org-jira-sdk-comment
))
205 (defun org-jira-sdk-create-board-from-data (d) (org-jira-sdk-create-from-data :board d
))
206 (defun org-jira-sdk-create-boards-from-data-list (ds) (mapcar #'org-jira-sdk-create-board-from-data ds
))
208 (provide 'org-jira-sdk
)
210 ;;; org-jira-sdk.el ends here