mirror of
https://codeberg.org/cage/tinmop/
synced 2025-02-18 08:20:35 +01:00
- [gemini] wrapped non gemini files download's thread.
Also added a few of useful slotslike temporary file path and number of bytes downloaded so far.
This commit is contained in:
parent
8ae83a2323
commit
0bb4406be7
@ -81,6 +81,14 @@
|
||||
:initform nil
|
||||
:initarg :download-socket
|
||||
:accessor download-socket)
|
||||
(support-file
|
||||
:initform (fs:temporary-file)
|
||||
:initarg :support-file
|
||||
:accessor support-file)
|
||||
(octect-count
|
||||
:initform 0
|
||||
:initarg :octect-count
|
||||
:accessor octect-count)
|
||||
(thread
|
||||
:initform nil
|
||||
:initarg :thread
|
||||
@ -123,12 +131,42 @@
|
||||
|
||||
(defclass gemini-file-stream (gemini-stream) ())
|
||||
|
||||
(defclass gemini-others-data-stream (gemini-stream) ())
|
||||
|
||||
(defmacro with-open-support-file ((stream file &optional (element-type '(unsigned-byte 8)))
|
||||
&body body)
|
||||
`(with-open-file (,stream ,file
|
||||
:element-type ',element-type
|
||||
:direction :output
|
||||
:element-type 'character
|
||||
:if-exists :supersede
|
||||
:if-does-not-exist :create)
|
||||
,@body))
|
||||
|
||||
(defgeneric increment-bytes-count (object data &key &allow-other-keys))
|
||||
|
||||
(defmethod increment-bytes-count ((object gemini-stream) data
|
||||
&key (convert-to-octects nil))
|
||||
(with-accessors ((octect-count octect-count)) object
|
||||
(if convert-to-octects
|
||||
(incf octect-count (babel:string-size-in-octets data
|
||||
:errorp nil))
|
||||
(incf octect-count (length data)))))
|
||||
|
||||
(defmethod increment-bytes-count ((object gemini-stream) (data number)
|
||||
&key &allow-other-keys)
|
||||
(with-accessors ((octect-count octect-count)) object
|
||||
(incf octect-count data)))
|
||||
|
||||
(defun request-stream-gemini-document-thread (wrapper-object host
|
||||
port path query
|
||||
status-code status-code-description meta)
|
||||
(with-accessors ((download-socket download-socket)
|
||||
(download-stream download-stream)) wrapper-object
|
||||
(download-stream download-stream)
|
||||
(octect-count octect-count)
|
||||
(support-file support-file)) wrapper-object
|
||||
(lambda ()
|
||||
(with-open-support-file (file-stream support-file character)
|
||||
(let* ((url (gemini-parser:make-gemini-uri host path query port))
|
||||
(parsed-url (gemini-parser:parse-gemini-file (format nil "-> ~a~%" url)))
|
||||
(url-response (gemini-client:make-gemini-file-response nil
|
||||
@ -161,6 +199,8 @@
|
||||
(event (make-instance 'program-events:gemini-got-line-event
|
||||
:wrapper-object wrapper-object
|
||||
:payload response)))
|
||||
(write-sequence line file-stream)
|
||||
(increment-bytes-count wrapper-object line :convert-to-octects t)
|
||||
(program-events:push-event event))
|
||||
(progn
|
||||
(return-from download-loop nil))))
|
||||
@ -168,21 +208,40 @@
|
||||
(ui:notify (_ "Gemini document downloading aborted"))
|
||||
(ui:notify (_ "Gemini document downloading completed")))
|
||||
(allow-downloading wrapper-object)
|
||||
(gemini-client:close-ssl-socket download-socket)))))
|
||||
(gemini-client:close-ssl-socket download-socket)))
|
||||
(fs:delete-file-if-exists support-file))))
|
||||
|
||||
(defun request-stream-other-document-thread (socket stream host
|
||||
port path query
|
||||
(defun request-stream-other-document-thread (wrapper-object
|
||||
socket
|
||||
host
|
||||
port
|
||||
path
|
||||
query
|
||||
status-code status-code-description meta)
|
||||
(declare (ignorable host
|
||||
port path query
|
||||
status-code status-code-description meta))
|
||||
(with-accessors ((download-socket download-socket)
|
||||
(download-stream download-stream)
|
||||
(octect-count octect-count)
|
||||
(support-file support-file)) wrapper-object
|
||||
|
||||
(lambda ()
|
||||
(fs:with-anaphoric-temp-file (out-stream)
|
||||
(let* ((buffer (misc:read-all stream)))
|
||||
(with-open-support-file (file-stream support-file)
|
||||
(labels ((%fill-buffer ()
|
||||
(multiple-value-bind (buffer read-so-far)
|
||||
(read-array download-stream 1024)
|
||||
(increment-bytes-count wrapper-object read-so-far)
|
||||
(if (< read-so-far (length buffer))
|
||||
(progn
|
||||
(write-sequence buffer file-stream :start 0 :end read-so-far)
|
||||
(force-output file-stream)
|
||||
(gemini-client:close-ssl-socket socket)
|
||||
(write-sequence buffer out-stream)
|
||||
(force-output out-stream)
|
||||
(os-utils:xdg-open fs:temp-file)))))
|
||||
(os-utils:xdg-open support-file))
|
||||
(progn
|
||||
(write-sequence buffer file-stream)
|
||||
(%fill-buffer))))))
|
||||
(%fill-buffer))))))
|
||||
|
||||
(defun request (url)
|
||||
(let ((parsed-uri (quri:uri url)))
|
||||
@ -238,7 +297,6 @@
|
||||
((gemini-client:response-sensitive-input-p status)
|
||||
(get-user-input t host meta))
|
||||
((streamp response)
|
||||
(let ((stream response))
|
||||
(if (gemini-client:mime-gemini-p meta)
|
||||
(let* ((gemini-stream (make-instance 'gemini-file-stream
|
||||
:download-stream response
|
||||
@ -258,15 +316,25 @@
|
||||
port
|
||||
path
|
||||
query))
|
||||
(bt:make-thread (request-stream-other-document-thread socket
|
||||
stream
|
||||
(let* ((gemini-stream (make-instance 'gemini-others-data-stream
|
||||
:download-stream response
|
||||
:download-socket socket))
|
||||
(thread-fn
|
||||
(request-stream-other-document-thread gemini-stream
|
||||
socket
|
||||
host
|
||||
port
|
||||
path
|
||||
query
|
||||
status
|
||||
code-description
|
||||
meta))))))))
|
||||
meta)))
|
||||
(downloading-start-thread gemini-stream
|
||||
thread-fn
|
||||
host
|
||||
port
|
||||
path
|
||||
query)))))))
|
||||
(gemini-client:gemini-tofu-error (e)
|
||||
(let ((host (gemini-client:host e)))
|
||||
(flet ((on-input-complete (maybe-accepted)
|
||||
|
@ -453,9 +453,9 @@ Name from Emacs Lisp."
|
||||
(defun read-array (stream size &key (offset nil))
|
||||
(when offset
|
||||
(file-position stream offset))
|
||||
(let* ((bytes (misc-utils:make-array-frame size 0 '(unsigned-byte 8) t)))
|
||||
(read-sequence bytes stream)
|
||||
bytes))
|
||||
(let* ((bytes (misc-utils:make-array-frame size 0 '(unsigned-byte 8) t))
|
||||
(read-so-far (read-sequence bytes stream)))
|
||||
(values bytes read-so-far)))
|
||||
|
||||
(defun read-all (stream)
|
||||
"Read all the octent from stream ad returns them as array"
|
||||
|
Loading…
x
Reference in New Issue
Block a user