Skip to content

Commit 7e69cbc

Browse files
committed
REDCap: Added redcap-export-report
New function to export a data report from REDCap. Also handles the optional argument for tables, if using JSON tables
1 parent 8e3bc3f commit 7e69cbc

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

modules/africastalking/africastalking.scm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9494
;; For creating POST request to Africa's Talking
9595
(define (atalk:make-request-str host url username apikey number message)
9696
(let ((request (string-append "username=" username "&to=" (atalk:percent-encode number) "&message=" (atalk:percent-encode message))))
97-
(string-append "POST " url " HTTP/1.0" "\r\n"
97+
(string-append "POST " url " HTTP/1.1" "\r\n"
9898
"Host: " host "\r\n"
9999
"Content-Length: " (number->string (string-length request)) "\r\n"
100100
"Content-Type: application/x-www-form-urlencoded" "\r\n"

modules/redcap/redcap.scm

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,68 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
274274
)
275275
)
276276

277+
(define (redcap-export-report host token report . xargs)
278+
;; See if format was specified in xargs, use json by default
279+
(let* ((format (redcap:arg 'format xargs "json"))
280+
;; Similarly, use lists (not tables) by default
281+
(use-tables? (redcap:arg 'tables xargs #f))
282+
(request (string-append
283+
"format=" format
284+
"&content=report&token=" token
285+
"&report_id=" report
286+
"&csvDelimiter="
287+
"&rawOrLabel=raw"
288+
"&rawOrLabelHeaders=raw"
289+
"&exportCheckboxLabel=false"
290+
"&returnFormat=json"))
291+
(request-str (redcap:make-request-str host request)))
292+
;; Check if we have a valid connection before proceeding
293+
(if (fx= (httpsclient-open host redcap:port) 1)
294+
(begin
295+
(httpsclient-send (string->u8vector request-str))
296+
(redcap:data-clear!)
297+
(let loop ((n #f))
298+
(if (and n (fx<= n 0))
299+
(begin
300+
(httpsclient-close)
301+
(let ((output (cadr (redcap:split-headerbody (redcap:data->string)))))
302+
(if (string=? format "json")
303+
;; If format is json, turn into a list, otherwise just return output
304+
(let ((datalist (redcap:jsonstr->list output)))
305+
(cond
306+
((not (list? datalist))
307+
;; If no list returned, json not properly formatted
308+
(log-error "REDCap error: Incomplete json " output)
309+
#f)
310+
((and (not use-tables?)
311+
(fx> (length datalist) 0)
312+
(string=? (caaar datalist) "error"))
313+
;; If the first entry is an error, then log it and return false
314+
(log-error "REDCap error: " (cdaar datalist))
315+
#f)
316+
((and use-tables?
317+
(fx> (length datalist) 0)
318+
(table-ref (car datalist) "error" #f))
319+
(log-error "REDCap error: " (table-ref (car datalist) "error" ""))
320+
#f)
321+
(else datalist)))
322+
output))
323+
) (begin
324+
(if (and n (> n 0))
325+
(redcap:data-append! (subu8vector redcap:buf 0 n)))
326+
(loop (httpsclient-recv redcap:buf))
327+
))
328+
)
329+
)
330+
(begin
331+
(log-warning "Cannot export from REDCap, no valid connection")
332+
(httpsclient-close)
333+
#f ;; Denote difference between no data and no connection
334+
)
335+
)
336+
)
337+
)
338+
277339
(define (redcap-import-record host token record data . xargs)
278340
(let* ((event (redcap:arg 'event xargs ""))
279341
(instance (redcap:arg 'instance xargs #f))

0 commit comments

Comments
 (0)