mirror of
https://github.com/penpot/penpot.git
synced 2026-10-04 01:36:15 +00:00
* ✨ Add export job model, store and scheduler to exporter * ✨ Render wasm exports on pooled worker threads * ✨ Add export job REST API to exporter * ✨ Use export job API and allow cancelling wasm exports * 🔧 Show export jobs in the internal debug panel * 🔧 Pass flags and export job settings to the exporter container * 📚 Document the exporter job API and its redis layout
94 lines
3.1 KiB
Clojure
94 lines
3.1 KiB
Clojure
;; This Source Code Form is subject to the terms of the Mozilla Public
|
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
;;
|
|
;; Copyright (c) KALEIDOS SUBSIDIARY SL
|
|
|
|
(ns app.handlers.export-frames
|
|
(:require
|
|
[app.common.spec :as us]
|
|
[app.handlers.export-shapes :refer [count-objects headless-exports? prepare-exports]]
|
|
[app.handlers.resources :as rsc]
|
|
[app.jobs :as jobs]
|
|
[app.jobs.utils :as job.utils]
|
|
[app.renderer :as rd]
|
|
[app.util.shell :as sh]
|
|
[cljs.spec.alpha :as s]
|
|
[cuerdas.core :as str]
|
|
[promesa.core :as p]))
|
|
|
|
(declare ^:private join-pdf)
|
|
(declare ^:private move-file)
|
|
|
|
(s/def ::name ::us/string)
|
|
(s/def ::file-id ::us/uuid)
|
|
(s/def ::page-id ::us/uuid)
|
|
(s/def ::object-id ::us/uuid)
|
|
(s/def ::is-wasm ::us/boolean)
|
|
|
|
(s/def ::export
|
|
(s/keys :req-un [::file-id ::page-id ::object-id ::name]))
|
|
|
|
(s/def ::exports
|
|
(s/every ::export :kind vector? :min-count 1))
|
|
|
|
(s/def ::params
|
|
(s/keys :req-un [::exports]
|
|
:opt-un [::name ::is-wasm]))
|
|
|
|
(defn- run-export
|
|
[job auth-token resource {:keys [exports is-wasm file-id]}]
|
|
(let [rendered (atom [])
|
|
|
|
on-object
|
|
(fn [{:keys [path] :as _object}]
|
|
(job.utils/track! (:id job) path)
|
|
(jobs/progress! job (count (swap! rendered conj path))))
|
|
|
|
exports
|
|
(map #(assoc % :is-wasm is-wasm :job-id (:id job)) exports)]
|
|
|
|
(job.utils/track! (:id job) (:path resource))
|
|
(->> (rd/with-scope exports
|
|
(fn [render]
|
|
(jobs/check-cancelled! job)
|
|
(->> exports
|
|
(map (fn [export] (render export on-object)))
|
|
(p/all))))
|
|
(p/fmap (fn [_] @rendered))
|
|
(p/mcat (partial join-pdf job file-id))
|
|
(p/mcat (partial move-file resource))
|
|
(p/fmap (constantly resource))
|
|
(p/mcat (partial rsc/upload-resource auth-token))
|
|
(p/mcat (fn [resource]
|
|
(->> (sh/stat (:path resource))
|
|
(p/fmap #(merge resource %)))))
|
|
(p/fmap (fn [resource] (dissoc resource :path))))))
|
|
|
|
(defn prepare
|
|
[auth-token {:keys [exports name is-wasm] :as _params}]
|
|
(let [exports (-> (map #(assoc % :type :pdf :scale 1 :suffix "") exports)
|
|
(prepare-exports auth-token is-wasm))
|
|
resource (rsc/create :pdf (or name (-> exports first :name)))
|
|
file-id (-> exports first :file-id)]
|
|
{:resource resource
|
|
:total (count-objects exports)
|
|
:headless (headless-exports? exports is-wasm)
|
|
:run (fn [job] (run-export job auth-token resource
|
|
{:exports exports
|
|
:is-wasm is-wasm
|
|
:file-id file-id}))}))
|
|
|
|
(defn- join-pdf
|
|
[job file-id paths]
|
|
(p/let [prefix (str/concat "penpot.pdfunite." file-id ".")
|
|
path (job.utils/track! (:id job) (sh/tempfile :prefix prefix :suffix ".pdf"))]
|
|
(apply sh/run-cmd! "pdfunite" (conj (vec paths) path))
|
|
path))
|
|
|
|
(defn- move-file
|
|
[{:keys [path] :as resource} output-path]
|
|
(p/do
|
|
(sh/move! output-path path)
|
|
resource))
|