mirror of
https://github.com/penpot/penpot.git
synced 2025-12-11 22:14:05 +01:00
Mainly removes the custom app.util.time namespace from frontend and backend and normalize all to use the app.common.time namespace
167 lines
5.7 KiB
Clojure
167 lines
5.7 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 INC
|
|
|
|
(ns app.rpc.commands.binfile
|
|
(:refer-clojure :exclude [assert])
|
|
(:require
|
|
[app.binfile.common :as bfc]
|
|
[app.binfile.v1 :as bf.v1]
|
|
[app.binfile.v3 :as bf.v3]
|
|
[app.common.features :as cfeat]
|
|
[app.common.logging :as l]
|
|
[app.common.schema :as sm]
|
|
[app.common.time :as ct]
|
|
[app.config :as cf]
|
|
[app.db :as db]
|
|
[app.http.sse :as sse]
|
|
[app.loggers.audit :as-alias audit]
|
|
[app.loggers.webhooks :as-alias webhooks]
|
|
[app.media :as media]
|
|
[app.rpc :as-alias rpc]
|
|
[app.rpc.commands.files :as files]
|
|
[app.rpc.commands.projects :as projects]
|
|
[app.rpc.commands.teams :as teams]
|
|
[app.rpc.doc :as-alias doc]
|
|
[app.tasks.file-gc]
|
|
[app.util.services :as sv]
|
|
[app.worker :as-alias wrk]
|
|
[promesa.exec :as px]
|
|
[yetti.response :as yres]))
|
|
|
|
(set! *warn-on-reflection* true)
|
|
|
|
;; --- Command: export-binfile
|
|
|
|
(def ^:private
|
|
schema:export-binfile
|
|
[:map {:title "export-binfile"}
|
|
[:file-id ::sm/uuid]
|
|
[:version {:optional true} ::sm/int]
|
|
[:include-libraries ::sm/boolean]
|
|
[:embed-assets ::sm/boolean]])
|
|
|
|
(defn stream-export-v1
|
|
[cfg {:keys [file-id include-libraries embed-assets] :as params}]
|
|
(yres/stream-body
|
|
(fn [_ output-stream]
|
|
(try
|
|
(-> cfg
|
|
(assoc ::bfc/ids #{file-id})
|
|
(assoc ::bfc/embed-assets embed-assets)
|
|
(assoc ::bfc/include-libraries include-libraries)
|
|
(bf.v1/export-files! output-stream))
|
|
(catch Throwable cause
|
|
(l/err :hint "exception on exporting file"
|
|
:file-id (str file-id)
|
|
:cause cause))))))
|
|
|
|
(defn stream-export-v3
|
|
[cfg {:keys [file-id include-libraries embed-assets] :as params}]
|
|
(yres/stream-body
|
|
(fn [_ output-stream]
|
|
(try
|
|
(-> cfg
|
|
(assoc ::bfc/ids #{file-id})
|
|
(assoc ::bfc/embed-assets embed-assets)
|
|
(assoc ::bfc/include-libraries include-libraries)
|
|
(bf.v3/export-files! output-stream))
|
|
(catch Throwable cause
|
|
(l/err :hint "exception on exporting file"
|
|
:file-id (str file-id)
|
|
:cause cause))))))
|
|
|
|
(sv/defmethod ::export-binfile
|
|
"Export a penpot file in a binary format."
|
|
{::doc/added "1.15"
|
|
::webhooks/event? true
|
|
::sm/params schema:export-binfile}
|
|
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id version file-id] :as params}]
|
|
(files/check-read-permissions! pool profile-id file-id)
|
|
(fn [_]
|
|
(let [version (or version 1)
|
|
body (case (int version)
|
|
1 (stream-export-v1 cfg params)
|
|
2 (throw (ex-info "not-implemented" {}))
|
|
3 (stream-export-v3 cfg params))]
|
|
|
|
{::yres/status 200
|
|
::yres/headers {"content-type" "application/octet-stream"}
|
|
::yres/body body})))
|
|
|
|
;; --- Command: import-binfile
|
|
|
|
(defn- import-binfile
|
|
[{:keys [::db/pool ::wrk/executor] :as cfg} {:keys [profile-id project-id version name file]}]
|
|
(let [team (teams/get-team pool
|
|
:profile-id profile-id
|
|
:project-id project-id)
|
|
cfg (-> cfg
|
|
(assoc ::bfc/features (cfeat/get-team-enabled-features cf/flags team))
|
|
(assoc ::bfc/project-id project-id)
|
|
(assoc ::bfc/profile-id profile-id)
|
|
(assoc ::bfc/name name)
|
|
(assoc ::bfc/input (:path file)))
|
|
|
|
;; NOTE: the importation process performs some operations that are
|
|
;; not very friendly with virtual threads, and for avoid
|
|
;; unexpected blocking of other concurrent operations we dispatch
|
|
;; that operation to a dedicated executor.
|
|
result (case (int version)
|
|
1 (px/invoke! executor (partial bf.v1/import-files! cfg))
|
|
3 (px/invoke! executor (partial bf.v3/import-files! cfg)))]
|
|
|
|
(db/update! pool :project
|
|
{:modified-at (ct/now)}
|
|
{:id project-id}
|
|
{::db/return-keys false})
|
|
|
|
result))
|
|
|
|
(def ^:private schema:import-binfile
|
|
[:map {:title "import-binfile"}
|
|
[:name [:or [:string {:max 250}]
|
|
[:map-of ::sm/uuid [:string {:max 250}]]]]
|
|
[:project-id ::sm/uuid]
|
|
[:file-id {:optional true} ::sm/uuid]
|
|
[:version {:optional true} ::sm/int]
|
|
[:file ::media/upload]])
|
|
|
|
(sv/defmethod ::import-binfile
|
|
"Import a penpot file in a binary format. If `file-id` is provided,
|
|
an in-place import will be performed instead of creating a new file.
|
|
|
|
The in-place imports are only supported for binfile-v3 and when a
|
|
.penpot file only contains one penpot file.
|
|
"
|
|
{::doc/added "1.15"
|
|
::doc/changes ["1.20" "Add file-id param for in-place import"
|
|
"1.20" "Set default version to 3"]
|
|
|
|
::webhooks/event? true
|
|
::sse/stream? true
|
|
::sm/params schema:import-binfile}
|
|
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id project-id version file-id file] :as params}]
|
|
(projects/check-edition-permissions! pool profile-id project-id)
|
|
(let [version (or version 3)
|
|
params (-> params
|
|
(assoc :profile-id profile-id)
|
|
(assoc :version version))
|
|
|
|
cfg (cond-> cfg
|
|
(uuid? file-id)
|
|
(assoc ::bfc/file-id file-id))
|
|
|
|
manifest (case (int version)
|
|
1 nil
|
|
3 (bf.v3/get-manifest (:path file)))]
|
|
|
|
(with-meta
|
|
(sse/response (partial import-binfile cfg params))
|
|
{::audit/props {:file nil
|
|
:file-id file-id
|
|
:generated-by (:generated-by manifest)
|
|
:referer (:referer manifest)}})))
|