1
0
Fork 0

- [gemini] added "no wait" directive when downloading non gemini text format from gemini

allow opening file before it is downloaded completely.
This commit is contained in:
cage 2021-07-25 18:36:06 +02:00
parent dc8df6c91f
commit 8209d5739c
3 changed files with 81 additions and 29 deletions

View File

@ -169,9 +169,17 @@ color-regexp = ":rendering" cyan
# open png files with gimp but cache them before
# ▼▼▼▼▼▼▼▼▼
# open "https?://png$" with "gimp" use cache
# if you want to open some kind of file with tinmop try the following
# valid values are "tinmop" "me" "internal"
# using "no wait" allow for content to be opened before download is
# completed; note that not all file types can be opened before the
# whole file is available to the opening program
# ▼▼▼▼▼▼▼
# open "mp3$" with "xterm -e mpv" no wait
#
# finally if you want to open some kind of file with tinmop try the
# following: valid values are "tinmop" "me" "internal"
# ▼▼▼▼▼▼▼▼
open "^((gemini://)|(\\.)|(/)).+gmi$" with "tinmop"
open "^((gemini://)|(\\.)|(/)).+txt$" with "tinmop"
open "^((gemini://)|(\\.)|(/)).+sh$" with "tinmop"
open "^((gemini://)|(\\.)|(/)).+sh$" with "tinmop"

View File

@ -19,9 +19,12 @@
(defparameter *gemini-db-streams-lock* (bt:make-recursive-lock))
(define-constant +read-buffer-size+ 1024
(define-constant +read-buffer-size+ 2048
:documentation "Chunk's size of the buffer when reading non gemini contents from stream")
(define-constant +buffer-minimum-size-to-open+ 4096
:documentation "Minimum size of the saved contents (non gemini text) before attempt to opening with an user defined program: see configuration directive 'use program foo *no wait*'")
(defparameter *gemini-streams-db* ())
(defun push-db-stream (stream-object)
@ -462,25 +465,42 @@
(when-let ((extension (fs:get-extension path)))
(setf support-file (fs:temporary-file :extension extension)))
(with-open-support-file (file-stream support-file)
(labels ((%fill-buffer ()
(let ((partial-content-not-opened t))
(labels ((download-completed-p (buffer read-so-far)
(< read-so-far (length buffer)))
(opening-partial-contents-p (read-so-far)
(> read-so-far +buffer-minimum-size-to-open+))
(%fill-buffer ()
(declare (optimize (debug 0) (speed 3)))
(when (downloading-allowed-p wrapper-object)
(multiple-value-bind (buffer read-so-far)
(read-array download-stream +read-buffer-size+)
(declare ((vector (unsigned-byte 8)) buffer))
(declare (fixnum read-so-far))
(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)
(setf (stream-status wrapper-object) :completed)
(gemini-client:close-ssl-socket socket)
(os-utils:open-resource-with-external-program support-file nil))
(progn
(write-sequence buffer file-stream)
(%fill-buffer)))))))
(%fill-buffer))))))
(multiple-value-bind (program-exists y wait-for-download)
(swconf:link-regex->program-to-use support-file)
(declare (ignore y))
(multiple-value-bind (buffer read-so-far)
(read-array download-stream +read-buffer-size+)
(declare ((vector (unsigned-byte 8)) buffer))
(declare (fixnum read-so-far))
(increment-bytes-count wrapper-object read-so-far)
(if (download-completed-p buffer read-so-far)
(progn
(write-sequence buffer file-stream :start 0 :end read-so-far)
(force-output file-stream)
(setf (stream-status wrapper-object) :completed)
(gemini-client:close-ssl-socket socket)
(when wait-for-download
(os-utils:open-resource-with-external-program support-file
nil)))
(progn
(write-sequence buffer file-stream)
(when (and partial-content-not-opened
program-exists
(not wait-for-download)
(opening-partial-contents-p (octect-count wrapper-object)))
(setf partial-content-not-opened nil)
(os-utils:open-resource-with-external-program support-file
nil))
(%fill-buffer))))))))
(%fill-buffer)))))))
(defun request-success-dispatched-clrs (enqueue)
(lambda (status code-description meta response socket iri parsed-iri)

View File

@ -29,7 +29,7 @@
;; COMMENT*
;; SERVER-ASSIGN := SERVER-KEY BLANKS ASSIGN BLANKS GENERIC-VALUE BLANKS
;; USERNAME-ASSIGN := USERNAME-KEY BLANKS WITH BLANKS GENERIC-VALUE BLANKS
;; OPEN-LINK-HELPER := OPEN-LINK-HELPER-KEY BLANKS ASSIGN BLANKS REGEXP PROGRAM-NAME BLANKS USE-CACHE
;; OPEN-LINK-HELPER := OPEN-LINK-HELPER-KEY BLANKS ASSIGN BLANKS REGEXP PROGRAM-NAME BLANKS USE-CACHE? NOWAIT?
;; GENERIC-ASSIGN := (and key blanks assign blanks
;; (or quoted-string
;; hexcolor
@ -44,6 +44,9 @@
;; FILEPATH := QUOTED-STRING
;; PROGRAM-NAME := QUOTED-STRING
;; USE-CACHE := USE BLANKS CACHE
;; NOWAIT := NO BLANKS WAIT
;; NO := "no"
;; WAIT := "wait"
;; CACHE := "cache"
;; USE := "use"
;; SERVER-KEY := "server"
@ -294,7 +297,12 @@
:initform t
:initarg :use-cache
:reader use-cache-p
:writer (setf use-cache)))
:writer (setf use-cache))
(wait
:initform t
:initarg :wait
:reader waitp
:writer (setf wait)))
(:documentation "When a gemini link matches `re' try to open it with 'program-name'"))
(defmethod print-object ((object open-link-helper) stream)
@ -304,13 +312,14 @@
(use-cache-p use-cache-p)) object
(format stream "re: ~s program: ~s use cache? ~a" re program-name use-cache-p))))
(defun make-open-link-helper (re program-name use-cache)
(defun make-open-link-helper (re program-name use-cache &key (wait t))
(assert (stringp program-name))
(assert (stringp re))
(make-instance 'open-link-helper
:re re
:program-name program-name
:use-cache use-cache))
:use-cache use-cache
:wait wait))
(defrule use "use"
(:text t))
@ -318,7 +327,17 @@
(defrule cache "cache"
(:text t))
(defrule use-cache (and use blanks cache))
(defrule no "no"
(:text t))
(defrule wait "wait"
(:text t))
(defrule use-cache (and use blanks cache)
(:constant t))
(defrule no-wait (and no blanks wait)
(:constant t))
(defrule open-link-helper
(and open-link-helper-key
@ -330,11 +349,15 @@
regexp ; 6 program to use
blanks
(? (and use-cache ; 8 use cache?
blanks))
(? (and no-wait ; 9 wait download?
blanks)))
(:function (lambda (args)
(list :open-link-helper
(make-open-link-helper (elt args 2) (elt args 6) (elt args 8))))))
(make-open-link-helper (elt args 2)
(elt args 6)
(elt args 8)
:wait (not (elt args 9)))))))
(defrule filepath quoted-string)
(defparameter *already-included-files* ())
@ -883,7 +906,8 @@
(cl-ppcre:scan (re a) link))
(config-all-link-open-program))))
(values (program-name found)
(use-cache-p found))))
(use-cache-p found)
(waitp found))))
(defun use-tinmop-as-external-program-p (program)
(cl-ppcre:scan "(^me$)|(^internal$)|(tinmop)" program))