Browse Source

enhance: assets can be imported on CLI

Also add individual asset error handling, like is done for doc files
Gabriel Horner 1 year ago
parent
commit
09816b6427

+ 11 - 2
deps/graph-parser/script/db_import.cljs

@@ -45,7 +45,13 @@
        {:notify-user prn :macros (:macros config)})
       (assoc-in [:extract-options :verbose] (:verbose options))))
 
-(defn- import-file-graph-to-db [file-graph-dir conn options]
+(defn- <copy-asset-file [file db-graph-dir file-graph-dir]
+  (p/let [parent-dir (node-path/dirname
+                      (node-path/join db-graph-dir (node-path/relative file-graph-dir (:rpath file))))
+          _ (fsp/mkdir parent-dir #js {:recursive true})]
+    (fsp/copyFile (:rpath file) (node-path/join parent-dir (node-path/basename (:rpath file))))))
+
+(defn- import-file-graph-to-db [file-graph-dir db-graph-dir conn options]
   (p/let [*files (build-graph-files file-graph-dir)
           config-file (first (filter #(string/ends-with? (:rpath %) "logseq/config.edn") *files))
           _ (assert config-file "No 'logseq/config.edn' found for file graph dir")
@@ -54,11 +60,14 @@
           files (remove-hidden-files file-graph-dir config *files)
           import-options (build-import-options conn config options)
           logseq-file? #(string/includes? (:rpath %) "logseq/")
+          asset-files (when (fs/existsSync (node-path/join file-graph-dir "assets"))
+                        (map #(hash-map :rpath %) (common-graph/readdir (node-path/join file-graph-dir "assets"))))
           doc-files (remove logseq-file? files)
           logseq-files (filter logseq-file? files)]
     (println "Importing" (count files) "files ...")
     (p/do!
      (gp-exporter/import-logseq-files conn logseq-files <read-file {:notify-user prn})
+     (gp-exporter/import-from-asset-files! asset-files #(<copy-asset-file % db-graph-dir file-graph-dir) {:notify-user prn})
      (gp-exporter/import-from-doc-files! conn doc-files <read-file import-options)
      (gp-exporter/import-class-properties conn conn))))
 
@@ -107,7 +116,7 @@
         directory? (.isDirectory (fs/statSync file-graph'))]
     (p/do!
      (if directory?
-       (import-file-graph-to-db file-graph' conn (merge options {:graph-name db-name}))
+       (import-file-graph-to-db file-graph' (node-path/join dir db-name) conn (merge options {:graph-name db-name}))
        (import-files-to-db file-graph' conn (merge options {:graph-name db-name})))
      (when (:verbose options) (println "Transacted" (count (d/datoms @conn :eavt)) "datoms"))
      (println "Created graph" (str db-name "!")))))

+ 23 - 0
deps/graph-parser/src/logseq/graph_parser/exporter.cljs

@@ -753,3 +753,26 @@
                     :block/schema {:properties (vec prop-ids)}})
                  class-to-prop-uuids)]
     (ldb/transact! repo-or-conn tx)))
+
+(defn import-from-asset-files!
+  [*asset-files <copy-asset-file {:keys [notify-user]}]
+  (let [asset-files (mapv #(assoc %1 :idx %2)
+                          ;; Sort files to ensure reproducible import behavior
+                          (sort-by :rpath *asset-files)
+                          (range 0 (count *asset-files)))
+        copy-asset (fn copy-asset [{:keys [rpath] :as file}]
+                     (p/catch
+                      (<copy-asset-file file)
+                      (fn [error]
+                        (notify-user {:msg (str "Import failed on " (pr-str rpath) " with error:\n" error)
+                                      :level :error
+                                      :ex-data {:path rpath :error error}}))))]
+    (when (seq asset-files)
+      (-> (p/loop [_ (copy-asset (get asset-files 0))
+                   i 0]
+            (when-not (>= i (dec (count asset-files)))
+              (p/recur (copy-asset (get asset-files (inc i)))
+                       (inc i))))
+          (p/catch (fn [e]
+                     (notify-user {:msg (str "Import has an unexpected error:\n" e)
+                                   :level :error})))))))

+ 11 - 21
src/main/frontend/components/imports.cljs

@@ -168,25 +168,6 @@
       (ui/button "Submit"
                  {:on-click on-submit})]]))
 
-(defn- import-from-asset-files!
-  [asset-files]
-  (let [ch (async/to-chan! asset-files)
-        repo (state/get-current-repo)
-        repo-dir (config/get-repo-dir repo)]
-    (prn :in-files asset-files)
-    (async/go-loop []
-      (if-let [file (async/<! ch)]
-        (do
-          (async/<! (p->c (-> (.arrayBuffer (:file-object file))
-                              (p/then (fn [buffer]
-                                        (let [content (js/Uint8Array. buffer)
-                                              parent-dir (path/path-join repo-dir (path/dirname (:rpath file)))]
-                                          (p/do!
-                                           (fs/mkdir-if-not-exists parent-dir)
-                                           (fs/write-file! repo repo-dir (:rpath file) content {:skip-transact? true}))))))))
-          (recur))
-        true))))
-
 (defn- build-hidden-favorites-page-blocks
   [page-block-uuid-coll]
   (map
@@ -376,7 +357,16 @@
                            :import-file (fn import-file [conn m opts]
                                           (let [tx-report
                                                 (gp-exporter/add-file-to-db-graph conn (:file/path m) (:file/content m) opts)]
-                                            (db-browser/transact! @db-browser/*worker repo (:tx-data tx-report) (:tx-meta tx-report))))})]
+                                            (db-browser/transact! @db-browser/*worker repo (:tx-data tx-report) (:tx-meta tx-report))))})
+          repo-dir (config/get-repo-dir repo)
+          <copy-asset (fn copy-asset [file]
+                        (-> (.arrayBuffer (:file-object file))
+                            (p/then (fn [buffer]
+                                      (let [content (js/Uint8Array. buffer)
+                                            parent-dir (path/path-join repo-dir (path/dirname (:rpath file)))]
+                                        (p/do!
+                                         (fs/mkdir-if-not-exists parent-dir)
+                                         (fs/write-file! repo repo-dir (:rpath file) content {:skip-transact? true})))))))]
       (async/<! (p->c (gp-exporter/import-logseq-files (state/get-current-repo)
                                                        (filter logseq-file? files)
                                                        <read-file
@@ -384,7 +374,7 @@
                                                                       (db-editor-handler/save-file! path content))
                                                         :notify-user show-notification})))
       (state/set-state! [:graph/importing-state :current-page] "Asset files")
-      (async/<! (import-from-asset-files! asset-files))
+      (async/<! (p->c (gp-exporter/import-from-asset-files! asset-files <copy-asset {:notify-user show-notification})))
       (async/<! (p->c (gp-exporter/import-from-doc-files! db-conn doc-files <read-file import-options)))
       (async/<! (p->c (import-favorites-from-config-edn! db-conn repo config-file)))
       (async/<! (p->c (gp-exporter/import-class-properties db-conn repo)))