0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-13 10:38:13 -05:00

Make the exportation streaming directly to response

This commit is contained in:
Andrey Antukh 2022-09-29 14:28:45 +02:00
parent 4378d71b70
commit 8c39c3af9f
2 changed files with 39 additions and 22 deletions

View file

@ -280,7 +280,7 @@
(assoc ::binf/file-ids file-ids) (assoc ::binf/file-ids file-ids)
(assoc ::binf/embed-assets? embed?) (assoc ::binf/embed-assets? embed?)
(assoc ::binf/include-libraries? libs?) (assoc ::binf/include-libraries? libs?)
(binf/export!))] (binf/export-to-tmpfile!))]
(if clone? (if clone?
(let [project-id (some-> (profile/retrieve-additional-data pool profile-id) :default-project-id)] (let [project-id (some-> (profile/retrieve-additional-data pool profile-id) :default-project-id)]
(binf/import! (binf/import!

View file

@ -30,7 +30,8 @@
[clojure.walk :as walk] [clojure.walk :as walk]
[cuerdas.core :as str] [cuerdas.core :as str]
[datoteka.io :as io] [datoteka.io :as io]
[yetti.adapter :as yt]) [yetti.adapter :as yt]
[yetti.response :as yrs])
(:import (:import
com.github.luben.zstd.ZstdInputStream com.github.luben.zstd.ZstdInputStream
com.github.luben.zstd.ZstdOutputStream com.github.luben.zstd.ZstdOutputStream
@ -799,27 +800,40 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn export! (defn export!
[cfg] [cfg output]
(let [path (tmp/tempfile :prefix "penpot.export.") (let [id (uuid/next)
id (uuid/next) tp (dt/tpoint)
ts (dt/now) ab (volatile! false)
cs (volatile! nil)] cs (volatile! nil)]
(try (try
(l/info :hint "start exportation" :export-id id) (l/info :hint "start exportation" :export-id id)
(with-open [output (io/output-stream path)] (with-open [output (io/output-stream output)]
(binding [*position* (atom 0)] (binding [*position* (atom 0)]
(write-export! (assoc cfg ::output output)) (write-export! (assoc cfg ::output output))))
path))
(catch java.io.IOException _cause
;; Do nothing, EOF means client closes connection abruptly
(vreset! ab true)
nil)
(catch Throwable cause (catch Throwable cause
(vreset! cs cause) (vreset! cs cause)
(vreset! ab true)
(throw cause)) (throw cause))
(finally (finally
(l/info :hint "exportation finished" :export-id id (l/info :hint "exportation finished" :export-id id
:elapsed (str (inst-ms (dt/diff ts (dt/now))) "ms") :elapsed (str (inst-ms (tp)) "ms")
:aborted @ab
:cause @cs))))) :cause @cs)))))
(defn export-to-tmpfile!
[cfg]
(let [path (tmp/tempfile :prefix "penpot.export.")]
(with-open [output (io/output-stream path)]
(export! cfg output)
path)))
(defn import! (defn import!
[{:keys [::input] :as cfg}] [{:keys [::input] :as cfg}]
(let [id (uuid/next) (let [id (uuid/next)
@ -855,17 +869,20 @@
"Export a penpot file in a binary format." "Export a penpot file in a binary format."
{::doc/added "1.15"} {::doc/added "1.15"}
[{:keys [pool] :as cfg} {:keys [profile-id file-id include-libraries? embed-assets?] :as params}] [{:keys [pool] :as cfg} {:keys [profile-id file-id include-libraries? embed-assets?] :as params}]
(db/with-atomic [conn pool] (files/check-read-permissions! pool profile-id file-id)
(files/check-read-permissions! conn profile-id file-id) (let [resp (reify yrs/StreamableResponseBody
(let [path (export! (assoc cfg (-write-body-to-stream [_ _ output-stream]
::file-ids [file-id] (-> cfg
::embed-assets? embed-assets? (assoc ::file-ids [file-id])
::include-libraries? include-libraries?))] (assoc ::embed-assets? embed-assets?)
(with-meta {} (assoc ::include-libraries? include-libraries?)
(export! output-stream))))]
(with-meta (sv/wrap nil)
{:transform-response (fn [_ response] {:transform-response (fn [_ response]
(assoc response (-> response
:body (io/input-stream path) (assoc :body resp)
:headers {"content-type" "application/octet-stream"}))})))) (assoc :headers {"content-type" "application/octet-stream"})))})))
(s/def ::file ::media/upload) (s/def ::file ::media/upload)
(s/def ::import-binfile (s/def ::import-binfile