;; 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 INC (ns app.handlers.resources "Temporal resources management." (:require ["archiver" :as arc] ["fs" :as fs] ["path" :as path] [app.common.exceptions :as ex] [app.common.uuid :as uuid] [app.util.mime :as mime] [app.util.shell :as sh] [cljs.core :as c] [cuerdas.core :as str] [promesa.core :as p])) (defn- get-path [type id] (path/join sh/tmpdir (str/concat "penpot.resource." (c/name type) "." id))) (defn create "Generates ephimeral resource object." [type name] (let [task-id (uuid/next)] {:path (get-path type task-id) :mtype (mime/get type) :name name :filename (str/concat name (mime/get-extension type)) :id (str/concat (c/name type) "." task-id)})) (defn- lookup [id] (p/let [[type task-id] (str/split id "." 2) path (get-path type task-id) mtype (mime/get (keyword type)) stat (sh/stat path)] (when-not stat (ex/raise :type :not-found)) {:stream (fs/createReadStream path) :headers {"content-type" mtype "content-length" (:size stat)}})) (defn handler [{:keys [:request/params] :as exchange}] (when-not (contains? params :id) (ex/raise :type :validation :code :missing-id)) (-> (lookup (get params :id)) (p/then (fn [{:keys [stream headers] :as resource}] (-> exchange (assoc :response/status 200) (assoc :response/body stream) (assoc :response/headers headers)))))) (defn create-zip [& {:keys [resource on-complete on-progress on-error]}] (let [^js zip (arc/create "zip") ^js out (fs/createWriteStream (:path resource)) progress (atom 0)] (.on zip "error" on-error) (.on zip "end" on-complete) (.on zip "entry" (fn [data] (let [name (unchecked-get data "name") num (swap! progress inc)] (on-progress {:done num :filename name})))) (.pipe zip out) zip)) (defn add-to-zip! [zip path name] (.file ^js zip path #js {:name name})) (defn close-zip! [zip] (.finalize ^js zip))