-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathfinito-request.el
332 lines (280 loc) Β· 14.4 KB
/
finito-request.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
;;; finito-request.el --- HTTP utilities for finito -*- lexical-binding: t -*-
;; Copyright (C) 2021 Laurence Warne
;; Author: Laurence Warne
;; Local variables:
;; package-lint-main-file: "finito.el"
;; end:
;; 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:
;; This file contains http utilities for finito.
;;; Code:
(require 'dash)
(require 's)
(require 'finito-core)
(require 'finito-graphql)
(defconst finito--headers
'(("Content-Type" . "application/json")
("Accept" . "application/json")))
(defconst finito--bad-sort-ascending-arg-msg
"sort-ascending must be on of 'true or 'false")
;;; Misc functions
(defun finito--search-request-plist
(title-keywords author-keywords &optional max-results)
"Return a plist with headers and body suitable for a search query.
The body will be deduced from TITLE-KEYWORDS, AUTHOR-KEYWORDS and MAX-RESULTS."
(let* ((query-variable-str
(format finito--search-query-variables
(if (> (length title-keywords) 0)
(finito--quotify title-keywords) "null")
(if (> (length author-keywords) 0)
(finito--quotify author-keywords) "null")
(or max-results "null")
finito-language)))
`(:headers ,finito--headers
:data
,(format "{\"query\":\"%s\", \"variables\": %s}"
finito--search-query
query-variable-str))))
(defun finito--isbn-request-plist (isbn)
"Return a plist with headers and body suitable for an isbn request.
ISBN should be isbn of the book to query for."
`(:headers ,finito--headers
:data
,(format "{\"query\":\"%s\", \"variables\": %s}"
finito--isbn-query
(format finito--isbn-query-variables isbn))))
(defun finito--collection-request-plist (name &optional limit offset)
"Return a plist with headers and body suitable for a collection request.
NAME should be the name of the collection to query for.
LIMIT and OFFSET correspond the limit and offset of the collections's books.
If either is nil, all books in the collection are returned."
`(:headers ,finito--headers
:data
,(format "{\"query\":\"%s\", \"variables\": %s}"
finito--collection-query
(format finito--collection-query-variables
name
(finito--books-pagination-input limit offset)))))
(defun finito--collections-request-plist ()
"Return a plist with headers and body suitable for a collections query."
`(:headers ,finito--headers
:data
,(format "{\"query\":\"%s\"}" finito--collections-query)))
(defun finito--create-collection-request-plist (name)
"Return a plist with headers and body suitable for a collection request.
NAME should be the name of the collection to create."
`(:headers ,finito--headers
:data
,(format
"{\"query\":\"%s\", \"variables\": %s}"
finito--create-collection-mutation
(format finito--create-collection-mutation-variables name))))
(defun finito--delete-collection-request-plist (name)
"Return a plist with headers and body suitable for a delete request.
NAME should be the name of the collection to delete."
`(:headers ,finito--headers
:data
,(format
"{\"query\":\"%s\", \"variables\": %s}"
finito--delete-collection-mutation
(format finito--delete-collection-mutation-variables name))))
(defun finito--update-collection-request-plist
(current-name &optional new-name preferred-sort sort-ascending)
"Return a plist with headers and body suitable for an update request.
CURRENT-NAME should be the name of the collection to update, NEW-NAME
should be the new name, PREFERRED-SORT the preferred sorting method, and
SORT-ASCENDING indicates whether the sorting method should be ascending or
descending. All arguments should be strings, except for SORT-ASCENDING
which should be one of the symbols `true' or `false' (if nil is passed
then the property will not be changed)."
`(:headers ,finito--headers
:data
,(format "{\"query\":\"%s\", \"variables\": %s}"
finito--update-collection-mutation
(format
finito--update-collection-mutation-variables
current-name
(if new-name (finito--quotify new-name) "null")
(or preferred-sort "null")
(cond ((eq sort-ascending 'true) "true")
((eq sort-ascending 'false) "false")
((not sort-ascending) "null")
(t (error finito--bad-sort-ascending-arg-msg)))))))
(defun finito--add-book-request-plist (book &optional collection)
"Return a plist with headers and body for an add book request.
COLLECTION should be the name of the collection, and BOOK should be an alist
of the form returned by `finito--create-book-alist' to add to it."
`(:headers ,finito--headers
:data ,(format
"{\"query\":\"%s\", \"variables\": %s}"
finito--add-book-mutation
(let-alist book
(format
finito--add-book-mutation-variables
(if collection (finito--quotify collection) "null")
(s-replace "\"" "'" .title)
(finito--seq-to-json-list .authors)
(s-replace "\"" "'" .description)
(s-replace "\"" "'" .isbn)
(s-replace "\"" "'" .img-uri))))))
(defun finito--remove-book-request-plist (collection isbn)
"Return a plist with headers and body for a remove book request.
COLLECTION should be the name of the collection, and ISBN should be the isbn
of the book to remove."
`(:headers ,finito--headers
:data ,(format "{\"query\":\"%s\", \"variables\": %s}"
finito--remove-book-mutation
(format finito--remove-book-mutation-variables
collection
isbn))))
(defun finito--rate-book-request-plist (book rating)
"Return a plist with headers and body for a rating request.
BOOK should be the book (as an alist) to rate and RATING the rating."
`(:headers ,finito--headers
:data ,(format "{\"query\":\"%s\", \"variables\": %s}"
finito--rate-book-mutation
(let-alist book
(format
finito--rate-book-mutation-variables
rating
(s-replace "\"" "'" .title)
(finito--seq-to-json-list .authors)
(s-replace "\"" "'" .description)
(s-replace "\"" "'" .isbn)
(s-replace "\"" "'" .img-uri))))))
(defun finito--review-book-request-plist (book review)
"Return a plist with headers and body for an add review request.
BOOK should be the book (as an alist) to review and REVIEW the rating strin."
`(:headers ,finito--headers
:data ,(format "{\"query\":\"%s\", \"variables\": %s}"
finito--review-book-mutation
(let-alist book
(format
finito--review-book-mutation-variables
review
(s-replace "\"" "'" .title)
(finito--seq-to-json-list .authors)
(s-replace "\"" "'" .description)
(s-replace "\"" "'" .isbn)
(s-replace "\"" "'" .img-uri))))))
(defun finito--start-reading-request-plist (book &optional start-date)
"Return a plist with headers and body for a start reading request.
BOOK should be the book (as an alist) to start reading and START-DATE is an
optional start date which should be used if this book was started in the past."
`(:headers ,finito--headers
:data ,(format
"{\"query\":\"%s\", \"variables\": %s}"
finito--start-reading-mutation
(let-alist book
(format
finito--start-reading-mutation-variables
(if start-date (finito--quotify start-date) "null")
(s-replace "\"" "'" .title)
(finito--seq-to-json-list .authors)
(s-replace "\"" "'" .description)
(s-replace "\"" "'" .isbn)
(s-replace "\"" "'" .img-uri))))))
(defun finito--finish-reading-request-plist (book &optional date)
"Return a plist with headers and body for a finish reading request.
BOOK should be the book (as an alist) to finish reading and DATE is an
optional date which should be used if this book was finished in the past."
`(:headers ,finito--headers
:data ,(format "{\"query\":\"%s\", \"variables\": %s}"
finito--finish-reading-mutation
(let-alist book
(format
finito--finish-reading-mutation-variables
(if date (finito--quotify date) "null")
(s-replace "\"" "'" .title)
(finito--seq-to-json-list .authors)
(s-replace "\"" "'" .description)
(s-replace "\"" "'" .isbn)
(s-replace "\"" "'" .img-uri))))))
(defun finito--delete-book-data-request-plist (isbn)
"Return a plist with headers and body for a delete book data request.
ISBN should be the isbn of the book to remove data for."
`(:headers ,finito--headers
:data ,(format "{\"query\":\"%s\", \"variables\": %s}"
finito--delete-book-data-mutation
(format finito--delete-book-data-mutation-variables
isbn))))
(defun finito--create-book-request-plist (book)
"Return a plist with headers and body for an create book request.
BOOK should be an alist with keys title, authors, description, isbn and
img-uri."
`(:headers ,finito--headers
:data ,(format "{\"query\":\"%s\", \"variables\": %s}"
finito--create-book-mutation
(let-alist book
(format
finito--create-book-mutation-variables
(s-replace "\"" "'" .title)
(finito--seq-to-json-list .authors)
(s-replace "\"" "'" .description)
(s-replace "\"" "'" .isbn)
(s-replace "\"" "'" .img-uri))))))
(defun finito--series-request-plist (book)
"Return a plist with headers and body for a series request.
BOOK should be an alist with keys title, authors, description, isbn and
img-uri."
`(:headers ,finito--headers
:data ,(format "{\"query\":\"%s\", \"variables\": %s}"
finito--series-query
(let-alist book
(format
finito--series-query-variables
(s-replace "\"" "'" .title)
(finito--seq-to-json-list .authors)
(s-replace "\"" "'" .description)
(s-replace "\"" "'" .isbn)
(s-replace "\"" "'" .img-uri))))))
(defun finito--summary-request-plist
(from to montage-image-columns montage-large-image-width montage-large-image-height montage-large-image-scale-factor montage-large-image-rating-threshold include-added)
"Return a plist with headers and body for a summary request.
FROM and TO should be dates corresponding to the start and end of the summary
period"
`(:headers ,finito--headers
:data ,(format "{\"query\":\"%s\", \"variables\": %s}"
finito--summary-query
(format
finito--summary-query-variables
(finito--quotify from)
(finito--quotify to)
montage-image-columns
montage-large-image-width
montage-large-image-height
montage-large-image-scale-factor
montage-large-image-rating-threshold
(if include-added "true" "false")))))
(defun finito--goodreads-import-request-plist (content)
"Return a plist with headers and body for a Goodreads import request.
CONTENT should be a CSV string corresponding to a goodreads export"
`(:headers ,finito--headers
:data ,(format "{\"query\":\"%s\", \"variables\": %s}"
finito--import-query
(format
finito--import-query-variables
(json-encode "Goodreads")
(json-encode content)
(json-encode finito-language)))))
(defun finito--seq-to-json-list (seq)
"Return SEQ as an escaped json list."
(--> (append seq nil)
(-map #'finito--quotify it)
(s-join ", " it)
(s-prepend "[" it)
(s-append "]" it)))
(defun finito--quotify (s)
"Wrap S in double quotes."
(s-wrap s "\""))
(provide 'finito-request)
;;; finito-request.el ends here