Browse Source

fix(fs): asset url handling

Andelf 2 years ago
parent
commit
ad564a4d72

+ 2 - 1
deps/graph-parser/src/logseq/graph_parser/extract.cljc

@@ -41,7 +41,8 @@
   (let [ast  (map first ast)
   (let [ast  (map first ast)
         file (if uri-encoded? (js/decodeURI file-path) file-path)]
         file (if uri-encoded? (js/decodeURI file-path) file-path)]
     ;; check backward compatibility?
     ;; check backward compatibility?
-    (if (string/includes? file "pages/contents.")
+    ;; FIXME: use pre-config dir
+    (if (string/starts-with? file "pages/contents.")
       "Contents"
       "Contents"
       (let [first-block (last (first (filter gp-block/heading-block? ast)))
       (let [first-block (last (first (filter gp-block/heading-block? ast)))
             property-name (when (contains? #{"Properties" "Property_Drawer"} (ffirst ast))
             property-name (when (contains? #{"Properties" "Property_Drawer"} (ffirst ast))

+ 1 - 0
src/main/frontend/components/block.cljs

@@ -201,6 +201,7 @@
                             asset-path (gp-config/remove-asset-protocol src)]
                             asset-path (gp-config/remove-asset-protocol src)]
                         (if (string/blank? asset-path)
                         (if (string/blank? asset-path)
                           (reset! *exist? false)
                           (reset! *exist? false)
+                          ;; FIXME(andelf): possible bug here
                           (p/let [exist? (fs/file-or-href-exists? "" asset-path)]
                           (p/let [exist? (fs/file-or-href-exists? "" asset-path)]
                             (reset! *exist? (boolean exist?))))
                             (reset! *exist? (boolean exist?))))
                         (assoc state ::asset-path asset-path ::asset-file? true))
                         (assoc state ::asset-path asset-path ::asset-file? true))

+ 0 - 1
src/main/frontend/fs/node.cljs

@@ -47,7 +47,6 @@
 (defn- write-file-impl!
 (defn- write-file-impl!
   [this repo dir rpath content {:keys [ok-handler error-handler old-content skip-compare?]} stat]
   [this repo dir rpath content {:keys [ok-handler error-handler old-content skip-compare?]} stat]
   (prn ::write-file-impl repo dir rpath)
   (prn ::write-file-impl repo dir rpath)
-  (js/console.trace)
   (let [file-path (fs2-path/path-join dir rpath)]
   (let [file-path (fs2-path/path-join dir rpath)]
     (if skip-compare?
     (if skip-compare?
       (p/catch
       (p/catch

+ 8 - 10
src/main/frontend/fs2/path.cljs

@@ -15,8 +15,9 @@
 
 
 
 
 
 
-(defn file-name
-  "File name of a path or URL"
+(defn filename
+  "File name of a path or URL.
+   Returns nil when it's a path."
   [path]
   [path]
   (let [fname (if (string/ends-with? path "/")
   (let [fname (if (string/ends-with? path "/")
                 nil
                 nil
@@ -29,11 +30,11 @@
 (defn split-ext
 (defn split-ext
   "Split file name into stem and extension, for both path and URL"
   "Split file name into stem and extension, for both path and URL"
   [path]
   [path]
-  (let [fname (file-name path)
+  (let [fname (filename path)
         pos (string/last-index-of fname ".")]
         pos (string/last-index-of fname ".")]
     (if-not (or (nil? pos) (zero? pos))
     (if-not (or (nil? pos) (zero? pos))
       [(subs fname 0 pos)
       [(subs fname 0 pos)
-       (subs fname (+ pos 1))]
+       (string/lower-case (subs fname (+ pos 1)))]
       [fname ""])))
       [fname ""])))
 
 
 (defn file-stem
 (defn file-stem
@@ -42,12 +43,12 @@
   (first (split-ext path)))
   (first (split-ext path)))
 
 
 (defn file-ext
 (defn file-ext
-  "File extension"
+  "File extension, lowercased"
   [path]
   [path]
   (second (split-ext path)))
   (second (split-ext path)))
 
 
-(defn safe-file-name?
-  "Safe path on all platforms"
+(defn safe-filename?
+  "Safe filename on all platforms"
   [fname]
   [fname]
   (and (not (string/blank? fname))
   (and (not (string/blank? fname))
        (< (count fname) 255)
        (< (count fname) 255)
@@ -57,9 +58,6 @@
                 (re-find #"(?i)^(COM[0-9]|CON|LPT[0-9]|NUL|PRN|AUX|com[0-9]|con|lpt[0-9]|nul|prn|aux)\..+" fname)
                 (re-find #"(?i)^(COM[0-9]|CON|LPT[0-9]|NUL|PRN|AUX|com[0-9]|con|lpt[0-9]|nul|prn|aux)\..+" fname)
                 (re-find #"[\u0000-\u001f\u0080-\u009f]" fname)))))
                 (re-find #"[\u0000-\u001f\u0080-\u009f]" fname)))))
 
 
-(comment defn inspect [x]
-         (prn ::inspect x)
-         x)
 
 
 (defn path-join
 (defn path-join
   "Joins the given path segments into a single path, handling relative paths,
   "Joins the given path segments into a single path, handling relative paths,

+ 40 - 27
src/main/frontend/handler/editor.cljs

@@ -54,7 +54,8 @@
             [logseq.graph-parser.util.block-ref :as block-ref]
             [logseq.graph-parser.util.block-ref :as block-ref]
             [logseq.graph-parser.util.page-ref :as page-ref]
             [logseq.graph-parser.util.page-ref :as page-ref]
             [promesa.core :as p]
             [promesa.core :as p]
-            [rum.core :as rum]))
+            [rum.core :as rum]
+            [frontend.fs2.path :as fs2-path]))
 
 
 ;; FIXME: should support multiple images concurrently uploading
 ;; FIXME: should support multiple images concurrently uploading
 
 
@@ -1386,21 +1387,25 @@
   (p/let [repo-dir (config/get-repo-dir repo)
   (p/let [repo-dir (config/get-repo-dir repo)
           assets-dir "assets"
           assets-dir "assets"
           _ (fs/mkdir-if-not-exists (str repo-dir "/" assets-dir))]
           _ (fs/mkdir-if-not-exists (str repo-dir "/" assets-dir))]
+    (prn ::ensure-assets-dir repo-dir  assets-dir)
     [repo-dir assets-dir]))
     [repo-dir assets-dir]))
 
 
 (defn get-asset-path
 (defn get-asset-path
   "Get asset path from filename, ensure assets dir exists"
   "Get asset path from filename, ensure assets dir exists"
   [filename]
   [filename]
   (p/let [[repo-dir assets-dir] (ensure-assets-dir! (state/get-current-repo))]
   (p/let [[repo-dir assets-dir] (ensure-assets-dir! (state/get-current-repo))]
-    (util/safe-path-join repo-dir assets-dir filename)))
+    (fs2-path/path-join repo-dir assets-dir filename)))
 
 
 (defn save-assets!
 (defn save-assets!
+  "Save incoming(pasted) assets to assets directory.
+
+   Returns: [filename file-obj file-fpath matched-alias]"
   ([_ repo files]
   ([_ repo files]
    (p/let [[repo-dir assets-dir] (ensure-assets-dir! repo)]
    (p/let [[repo-dir assets-dir] (ensure-assets-dir! repo)]
      (save-assets! repo repo-dir assets-dir files
      (save-assets! repo repo-dir assets-dir files
-                   (fn [index file-base]
+                   (fn [index file-stem]
                      ;; TODO: maybe there're other chars we need to handle?
                      ;; TODO: maybe there're other chars we need to handle?
-                     (let [file-base (-> file-base
+                     (let [file-base (-> file-stem
                                          (string/replace " " "_")
                                          (string/replace " " "_")
                                          (string/replace "%" "_")
                                          (string/replace "%" "_")
                                          (string/replace "/" "_"))
                                          (string/replace "/" "_"))
@@ -1411,24 +1416,23 @@
     (for [[index ^js file] (map-indexed vector files)]
     (for [[index ^js file] (map-indexed vector files)]
       ;; WARN file name maybe fully qualified path when paste file
       ;; WARN file name maybe fully qualified path when paste file
       (let [file-name (util/node-path.basename (.-name file))
       (let [file-name (util/node-path.basename (.-name file))
-            [file-base ext-full ext-base] (if file-name
-                              (let [ext-base (util/node-path.extname file-name)
-                                    ext-full (if-not (config/extname-of-supported? ext-base)
-                                               (util/full-path-extname file-name) ext-base)]
-                                [(subs file-name 0 (- (count file-name)
-                                                      (count ext-full))) ext-full ext-base])
-                              ["" "" ""])
-            filename  (str (gen-filename index file-base) ext-full)
+            [file-stem ext-full ext-base] (if file-name
+                                            (let [ext-base (util/node-path.extname file-name)
+                                                  ext-full (if-not (config/extname-of-supported? ext-base)
+                                                             (util/full-path-extname file-name) ext-base)]
+                                              [(subs file-name 0 (- (count file-name)
+                                                                    (count ext-full))) ext-full ext-base])
+                                            ["" "" ""])
+            filename  (str (gen-filename index file-stem) ext-full)
             filename  (str path "/" filename)
             filename  (str path "/" filename)
             matched-alias (assets-handler/get-matched-alias-by-ext ext-base)
             matched-alias (assets-handler/get-matched-alias-by-ext ext-base)
-              filename (cond-> filename
-                         (not (nil? matched-alias))
-                         (string/replace #"^[.\/\\]*assets[\/\\]+" ""))
-              dir (or (:dir matched-alias) dir)]
+            filename (cond-> filename
+                       (not (nil? matched-alias))
+                       (string/replace #"^[.\/\\]*assets[\/\\]+" ""))
+            dir (or (:dir matched-alias) dir)]
 
 
         (if (util/electron?)
         (if (util/electron?)
-          (let [from (.-path file)
-                from (if (string/blank? from) nil from)]
+          (let [from (not-empty (.-path file))]
 
 
             (js/console.debug "Debug: Copy Asset #" dir filename from)
             (js/console.debug "Debug: Copy Asset #" dir filename from)
 
 
@@ -1447,6 +1451,7 @@
 (defonce *assets-url-cache (atom {}))
 (defonce *assets-url-cache (atom {}))
 
 
 (defn make-asset-url
 (defn make-asset-url
+  "Make asset URL for UI element, to fill img.src"
   [path] ;; path start with "/assets" or compatible for "../assets"
   [path] ;; path start with "/assets" or compatible for "../assets"
   (if config/publishing? path
   (if config/publishing? path
     (let [repo      (state/get-current-repo)
     (let [repo      (state/get-current-repo)
@@ -1454,6 +1459,7 @@
           path      (string/replace path "../" "/")
           path      (string/replace path "../" "/")
           full-path (util/node-path.join repo-dir path)
           full-path (util/node-path.join repo-dir path)
           data-url? (string/starts-with? path "data:")]
           data-url? (string/starts-with? path "data:")]
+      (prn ::make-asset-url full-path)
       (cond
       (cond
         data-url?
         data-url?
         path ;; just return the original
         path ;; just return the original
@@ -1499,25 +1505,32 @@
 
 
 ;; assets/journals_2021_02_03_1612350230540_0.png
 ;; assets/journals_2021_02_03_1612350230540_0.png
 (defn resolve-relative-path
 (defn resolve-relative-path
+  "Relative path to current file path.
+   
+   Requires editing state"
   [file-path]
   [file-path]
-  (if-let [current-file (or (db-model/get-block-file-path (state/get-edit-block))
+  (if-let [current-file-rpath (or (db-model/get-block-file-path (state/get-edit-block))
                             ;; fix dummy file path of page
                             ;; fix dummy file path of page
-                            (and (util/electron?)
-                                 (util/node-path.join
-                                  (config/get-repo-dir (state/get-current-repo))
-                                  (config/get-pages-directory) "_.md")))]
-    (util/get-relative-path current-file file-path)
+                               (and (util/electron?)
+                                    (util/node-path.join
+                                     (config/get-repo-dir (state/get-current-repo))
+                                     (config/get-pages-directory) "_.md")))]
+    (let [repo-dir (config/get-repo-dir (state/get-current-repo))
+            current-file-fpath (fs2-path/path-join repo-dir current-file-rpath)]
+        (util/get-relative-path current-file-fpath file-path))
     file-path))
     file-path))
 
 
 (defn upload-asset
 (defn upload-asset
+  "Paste asset and insert link to current editing block"
   [id ^js files format uploading? drop-or-paste?]
   [id ^js files format uploading? drop-or-paste?]
   (let [repo (state/get-current-repo)
   (let [repo (state/get-current-repo)
         block (state/get-edit-block)]
         block (state/get-edit-block)]
     (when (config/local-db? repo)
     (when (config/local-db? repo)
       (-> (save-assets! block repo (js->clj files))
       (-> (save-assets! block repo (js->clj files))
+          ;; FIXME: only the first asset is handled
           (p/then
           (p/then
            (fn [res]
            (fn [res]
-             (when-let [[asset-file-name file full-file-path matched-alias] (and (seq res) (first res))]
+             (when-let [[asset-file-name file-obj asset-file-fpath matched-alias] (and (seq res) (first res))]
                (let [image? (config/ext-of-image? asset-file-name)]
                (let [image? (config/ext-of-image? asset-file-name)]
                  (insert-command!
                  (insert-command!
                   id
                   id
@@ -1526,8 +1539,8 @@
                                          (str
                                          (str
                                           (if image? "../assets/" "")
                                           (if image? "../assets/" "")
                                           "@" (:name matched-alias) "/" asset-file-name)
                                           "@" (:name matched-alias) "/" asset-file-name)
-                                         (resolve-relative-path (or full-file-path asset-file-name)))
-                                       (if file (.-name file) (if image? "image" "asset"))
+                                         (resolve-relative-path (or asset-file-fpath asset-file-name)))
+                                       (if file-obj (.-name file-obj) (if image? "image" "asset"))
                                        image?)
                                        image?)
                   format
                   format
                   {:last-pattern (if drop-or-paste? "" (state/get-editor-command-trigger))
                   {:last-pattern (if drop-or-paste? "" (state/get-editor-command-trigger))