mirror of
https://github.com/penpot/penpot.git
synced 2025-03-25 06:01:46 -05:00
✨ Adds system to load initial project data
This commit is contained in:
parent
dfc6ebfeb0
commit
66fe0048a5
5 changed files with 174 additions and 11 deletions
|
@ -66,7 +66,11 @@
|
|||
:ldap-auth-username-attribute "uid"
|
||||
:ldap-auth-email-attribute "mail"
|
||||
:ldap-auth-fullname-attribute "displayName"
|
||||
:ldap-auth-avatar-attribute "jpegPhoto"})
|
||||
:ldap-auth-avatar-attribute "jpegPhoto"
|
||||
|
||||
;;:initial-data-project-id "5761a890-3b81-11eb-9e7d-556a2f641513"
|
||||
;;:initial-data-project-name "Penpot Onboarding"
|
||||
})
|
||||
|
||||
(s/def ::http-server-port ::us/integer)
|
||||
(s/def ::http-server-debug ::us/boolean)
|
||||
|
@ -135,6 +139,8 @@
|
|||
(s/def ::telemetry-server-enabled ::us/boolean)
|
||||
(s/def ::telemetry-server-port ::us/integer)
|
||||
|
||||
(s/def ::initial-data-project-id ::us/uuid)
|
||||
(s/def ::initial-data-project-name ::us/string)
|
||||
|
||||
(s/def ::config
|
||||
(s/keys :opt-un [::allow-demo-users
|
||||
|
@ -190,7 +196,9 @@
|
|||
::telemetry-enabled
|
||||
::telemetry-server-enabled
|
||||
::telemetry-server-port
|
||||
::telemetry-uri]))
|
||||
::telemetry-uri
|
||||
::initial-data-project-id
|
||||
::initial-data-project-name]))
|
||||
|
||||
(defn- env->config
|
||||
[env]
|
||||
|
|
|
@ -186,6 +186,18 @@
|
|||
(sql/insert table params opts)
|
||||
(assoc opts :return-keys true))))
|
||||
|
||||
(defn- select-values [map ks]
|
||||
(reduce #(conj %1 (map %2)) [] ks))
|
||||
|
||||
(defn insert-multi!
|
||||
[ds table param-list]
|
||||
(doseq [params param-list]
|
||||
(insert! ds table params))
|
||||
;; FIXME: Won't work
|
||||
#_(let [keys (->> param-list first keys (into []))
|
||||
params (->> param-list (mapv #(->> keys (select-values %) (into []))) )]
|
||||
(jdbc-sql/insert-multi! ds table keys params default-options)))
|
||||
|
||||
(defn update!
|
||||
([ds table params where] (update! ds table params where nil))
|
||||
([ds table params where opts]
|
||||
|
|
138
backend/src/app/db/profile_initial_data.clj
Normal file
138
backend/src/app/db/profile_initial_data.clj
Normal file
|
@ -0,0 +1,138 @@
|
|||
;; 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/.
|
||||
;;
|
||||
;; This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
;; defined by the Mozilla Public License, v. 2.0.
|
||||
;;
|
||||
;; Copyright (c) 2020-2021 UXBOX Labs SL
|
||||
|
||||
(ns app.db.profile-initial-data
|
||||
(:require
|
||||
[app.common.uuid :as uuid]
|
||||
[app.config :as cfg]
|
||||
[app.db :as db]
|
||||
[app.rpc.mutations.projects :as projects]
|
||||
[app.storage :as storage]
|
||||
[clojure.tools.logging :as log]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
(def sql:file
|
||||
"select * from file where project_id = ?")
|
||||
|
||||
(def sql:file-library-rel
|
||||
"with file_ids as (select id from file where project_id = ?)
|
||||
select *
|
||||
from file_library_rel
|
||||
where file_id in (select id from file_ids)")
|
||||
|
||||
(def sql:file-media-object
|
||||
"with file_ids as (select id from file where project_id = ?)
|
||||
select *
|
||||
from file_media_object
|
||||
where file_id in (select id from file_ids)")
|
||||
|
||||
(def sql:file-media-thumbnail
|
||||
"with file_ids as (select id from file where project_id = ?),
|
||||
media_ids as (select id from file_media_object where file_id in (select id from file_ids))
|
||||
select *
|
||||
from file_media_thumbnail
|
||||
where media_object_id in (select id from media_ids)")
|
||||
|
||||
(def sql:storage-object
|
||||
"with file_ids as (select id from file where project_id = ?),
|
||||
media_ids as (select media_id as id from file_media_object where file_id in (select id from file_ids)),
|
||||
thumbs_ids as (select thumbnail_id as id from file_media_object where file_id in (select id from file_ids)),
|
||||
storage_ids as (select id from media_ids union select id from thumbs_ids)
|
||||
select *
|
||||
from storage_object
|
||||
where id in (select id from storage_ids)")
|
||||
|
||||
(defn change-ids
|
||||
"Given a collection and a map from ID to ID. Changes all the `keys` properties
|
||||
so they point to the new ID existing in `map-ids`"
|
||||
[map-ids coll keys]
|
||||
|
||||
(let [generate-id
|
||||
(fn [map-ids {:keys [id]}]
|
||||
(assoc map-ids id (uuid/next)))
|
||||
|
||||
remap-key
|
||||
(fn [obj map-ids key]
|
||||
(cond-> obj
|
||||
(contains? obj key)
|
||||
(assoc key (get map-ids (get obj key) (get obj key)))))
|
||||
|
||||
change-id
|
||||
(fn [map-ids obj]
|
||||
(reduce #(remap-key %1 map-ids %2) obj keys))
|
||||
|
||||
new-map-ids (reduce generate-id map-ids coll)]
|
||||
|
||||
[new-map-ids (map (partial change-id new-map-ids) coll)]))
|
||||
|
||||
(defn allocate-storage-objects
|
||||
"Copies the storage data to a new object and stores the new id into `map-ids`"
|
||||
[storage map-ids objects]
|
||||
(let [clone-object
|
||||
(fn [map-ids object]
|
||||
(try
|
||||
(let [object (storage/row->storage-object object)
|
||||
new-obj (storage/clone-object storage object)]
|
||||
(assoc map-ids (:id object) (:id new-obj)))
|
||||
(catch Exception err
|
||||
(log/errorf "Error cloning store object %s" (:id object))
|
||||
map-ids)))]
|
||||
(->> objects
|
||||
(reduce clone-object map-ids))))
|
||||
|
||||
(defn create-profile-initial-data
|
||||
[conn storage profile]
|
||||
|
||||
(when-let [sample-project-id (get cfg/config :initial-data-project-id)]
|
||||
(let [sample-project-name (get cfg/config :initial-data-project-name "Penpot Onboarding")
|
||||
|
||||
proj (projects/create-project conn {:profile-id (:id profile)
|
||||
:team-id (:default-team-id profile)
|
||||
:name sample-project-name})
|
||||
|
||||
_ (projects/create-project-profile conn {:project-id (:id proj)
|
||||
:profile-id (:id profile)})
|
||||
|
||||
_ (projects/create-team-project-profile conn {:team-id (:default-team-id profile)
|
||||
:project-id (:id proj)
|
||||
:profile-id (:id profile)})
|
||||
|
||||
;; Retrieve data from templates
|
||||
file (db/exec! conn [sql:file, sample-project-id])
|
||||
file-library-rel (db/exec! conn [sql:file-library-rel, sample-project-id])
|
||||
file-media-object (db/exec! conn [sql:file-media-object, sample-project-id])
|
||||
file-media-thumbnail (db/exec! conn [sql:file-media-thumbnail, sample-project-id])
|
||||
storage-object (db/exec! conn [sql:storage-object, sample-project-id])
|
||||
|
||||
map-ids {}
|
||||
|
||||
;; Create new ID's and change the references
|
||||
[map-ids file] (change-ids map-ids file #{:id})
|
||||
|
||||
map-ids (allocate-storage-objects storage map-ids storage-object)
|
||||
|
||||
[map-ids file-library-rel] (change-ids map-ids file-library-rel #{:file-id :library-file-id})
|
||||
[map-ids file-media-object] (change-ids map-ids file-media-object #{:id :file-id :media-id :thumbnail-id})
|
||||
[map-ids file-media-thumbnail] (change-ids map-ids file-media-thumbnail #{:id :media-object-id})
|
||||
|
||||
file (->> file (map (fn [data] (assoc data :project-id (:id proj)))))
|
||||
file-profile-rel (->> file (map (fn [data]
|
||||
(hash-map :file-id (:id data)
|
||||
:profile-id (:id profile)
|
||||
:is-owner true
|
||||
:is-admin true
|
||||
:can-edit true))))]
|
||||
|
||||
;; Re-insert into the database
|
||||
(db/insert-multi! conn :file file)
|
||||
(db/insert-multi! conn :file-profile-rel file-profile-rel)
|
||||
(db/insert-multi! conn :file-library-rel file-library-rel)
|
||||
(db/insert-multi! conn :file-media-object file-media-object)
|
||||
(db/insert-multi! conn :file-media-thumbnail file-media-thumbnail))
|
||||
{:result "OK"}))
|
|
@ -5,7 +5,7 @@
|
|||
;; This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
;; defined by the Mozilla Public License, v. 2.0.
|
||||
;;
|
||||
;; Copyright (c) 2020 UXBOX Labs SL
|
||||
;; Copyright (c) 2020-2021 UXBOX Labs SL
|
||||
|
||||
(ns app.rpc.mutations.profile
|
||||
(:require
|
||||
|
@ -14,6 +14,7 @@
|
|||
[app.common.uuid :as uuid]
|
||||
[app.config :as cfg]
|
||||
[app.db :as db]
|
||||
[app.db.profile-initial-data :refer [create-profile-initial-data]]
|
||||
[app.emails :as emails]
|
||||
[app.http.session :as session]
|
||||
[app.media :as media]
|
||||
|
@ -54,7 +55,7 @@
|
|||
:opt-un [::token]))
|
||||
|
||||
(sv/defmethod ::register-profile {:auth false}
|
||||
[{:keys [pool tokens session] :as cfg} {:keys [token] :as params}]
|
||||
[{:keys [pool tokens session storage] :as cfg} {:keys [token] :as params}]
|
||||
(when-not (:registration-enabled cfg/config)
|
||||
(ex/raise :type :restriction
|
||||
:code :registration-disabled))
|
||||
|
@ -68,6 +69,7 @@
|
|||
(check-profile-existence! conn params)
|
||||
(let [profile (->> (create-profile conn params)
|
||||
(create-profile-relations conn))]
|
||||
(create-profile-initial-data conn storage profile)
|
||||
|
||||
(if token
|
||||
;; If token comes in params, this is because the user comes
|
||||
|
|
|
@ -94,16 +94,19 @@
|
|||
(def ^:private sql:retrieve-storage-object
|
||||
"select * from storage_object where id = ? and deleted_at is null")
|
||||
|
||||
(defn row->storage-object [res]
|
||||
(let [mdata (some-> (:metadata res) (db/decode-transit-pgobject))]
|
||||
(StorageObject. (:id res)
|
||||
(:size res)
|
||||
(:created-at res)
|
||||
(keyword (:backend res))
|
||||
mdata
|
||||
nil)))
|
||||
|
||||
(defn- retrieve-database-object
|
||||
[{:keys [conn] :as storage} id]
|
||||
(when-let [res (db/exec-one! conn [sql:retrieve-storage-object id])]
|
||||
(let [mdata (some-> (:metadata res) (db/decode-transit-pgobject))]
|
||||
(StorageObject. (:id res)
|
||||
(:size res)
|
||||
(:created-at res)
|
||||
(keyword (:backend res))
|
||||
mdata
|
||||
nil))))
|
||||
(row->storage-object res)))
|
||||
|
||||
(def sql:delete-storage-object
|
||||
"update storage_object set deleted_at=now() where id=? and deleted_at is null")
|
||||
|
|
Loading…
Add table
Reference in a new issue