mirror of
https://gitlab.com/eql/EQL5.git
synced 2025-12-15 23:00:50 -08:00
69 lines
2.7 KiB
Common Lisp
69 lines
2.7 KiB
Common Lisp
;;; this is just a snippet to show how to use Qt for POST requests to
|
|
;;; a cgi script (using e.g. python for cgi)
|
|
;;;
|
|
;;; this is here to have an alternative to Lisp solutions, which don't
|
|
;;; work well in ECL on some platforms (namely Windows)
|
|
;;;
|
|
;;; example usage:
|
|
;;;
|
|
;;; (server-request "booking.py"
|
|
;;; (list (cons "from" "2020-08-01")
|
|
;;; (cons "to" "2020-08-08")))
|
|
;;;
|
|
;;; please note the use of QLET to have all locally created Qt objects deleted
|
|
;;; when leaving the function body;
|
|
;;;
|
|
;;; note also how this is done with function HTTP-PART, where we can't use QLET
|
|
;;; inside the function for 'QHttpPart', because we need to return the newly
|
|
;;; created Qt object; in this case, QLET is placed in the caller, see:
|
|
;;;
|
|
;;; (dolist...
|
|
;;; (qlet ((part (http-part param)))
|
|
;;; (|append|...
|
|
;;;
|
|
;;; ...and since we are at it, just a reminder:
|
|
;;;
|
|
;;; as you already should know, QLET is crucial for all only locally used Qt
|
|
;;; objects, because it guarantees two things:
|
|
;;; - the C++ destructors being called when leaving the QLET body
|
|
;;; - not leaving around some garbage (GC through finalizing is only implemen-
|
|
;;; ted for return values from Qt function calls)
|
|
|
|
(qrequire :network)
|
|
|
|
;; for testing, using e.g. python3 -m http.server 8080 --cgi
|
|
(defparameter *server* "http://localhost:8080/cgi-bin/")
|
|
|
|
(defun http-part (parameter)
|
|
(let ((part (qnew "QHttpPart")))
|
|
(qlet ((name "QVariant(QString)"
|
|
(format nil "form-data; name=~S" (car parameter))))
|
|
(|setHeader| part |QNetworkRequest.ContentDispositionHeader| name)
|
|
(|setBody| part (x:string-to-bytes (cdr parameter))))
|
|
part))
|
|
|
|
(defun server-request (script &optional parameters)
|
|
"Make a http POST request to a cgi script, forcing synchronous behaviour,
|
|
which simplifies things and is preferable in many cases."
|
|
(start-busy-animation) ; pseudo code
|
|
(let (response)
|
|
(qlet ((ev-loop "QEventLoop")
|
|
(manager "QNetworkAccessManager"))
|
|
(qconnect manager "finished(QNetworkReply*)"
|
|
(lambda (reply)
|
|
(|deleteLater| reply)
|
|
(let ((err (|error| reply)))
|
|
(when (= |QNetworkReply.NoError| err)
|
|
(setf response (qfrom-utf8 (|readAll| reply)))))
|
|
(|exit| ev-loop)))
|
|
(qlet ((multi "QHttpMultiPart")
|
|
(qurl "QUrl(QString)" (x:cc *server* script))
|
|
(request "QNetworkRequest(QUrl)" qurl))
|
|
(dolist (param parameters)
|
|
(qlet ((part (http-part param)))
|
|
(|append| multi part)))
|
|
(|post| manager request multi)
|
|
(|exec| ev-loop |QEventLoop.ExcludeUserInputEvents|)
|
|
(stop-busy-animation) ; pseudo code
|
|
response))))
|
|
|