Browse Source

feat: export public assets

Junyu Zhan 4 years ago
parent
commit
49ddce0729

+ 8 - 2
resources/js/preload.js

@@ -67,8 +67,14 @@ contextBridge.exposeInMainWorld('apis', {
    *
    * @param {string} html html file with embedded state
    */
-  exportPublishAssets(html, customCSSPath) {
-    ipcRenderer.invoke('export-publish-assets', html, customCSSPath)
+  exportPublishAssets(html, customCSSPath, repoPath, assetFilenames) {
+    ipcRenderer.invoke(
+      'export-publish-assets',
+      html,
+      customCSSPath,
+      repoPath,
+      assetFilenames
+    )
   },
 
   /**

+ 24 - 14
src/electron/electron/core.cljs

@@ -26,18 +26,18 @@
   []
   (let [win-state (windowStateKeeper (clj->js {:defaultWidth 980 :defaultHeight 700}))
         win-opts (cond->
-                   {:width         (.-width win-state)
-                    :height        (.-height win-state)
-                    :frame         (not mac?)
-                    :autoHideMenuBar (not mac?)
-                    :titleBarStyle (if mac? "hidden" nil)
-                    :webPreferences
-                    {:plugins                 true ; pdf
-                     :nodeIntegration         false
-                     :nodeIntegrationInWorker false
-                     :contextIsolation        true
-                     :spellcheck              true
-                     :preload                 (path/join js/__dirname "js/preload.js")}}
+                  {:width         (.-width win-state)
+                   :height        (.-height win-state)
+                   :frame         (not mac?)
+                   :autoHideMenuBar (not mac?)
+                   :titleBarStyle (if mac? "hidden" nil)
+                   :webPreferences
+                   {:plugins                 true ; pdf
+                    :nodeIntegration         false
+                    :nodeIntegrationInWorker false
+                    :contextIsolation        true
+                    :spellcheck              true
+                    :preload                 (path/join js/__dirname "js/preload.js")}}
                    linux?
                    (assoc :icon (path/join js/__dirname "icons/logseq.png")))
         url MAIN_WINDOW_ENTRY
@@ -53,7 +53,7 @@
   ;;  (init-updater {:repo   "logseq/logseq"
   ;;                 :logger logger
   ;;                 :win    win}))
-)
+  )
 
 (defn setup-interceptor! []
   (.registerFileProtocol
@@ -65,19 +65,29 @@
        (callback #js {:path path}))))
   #(.unregisterProtocol protocol "assets"))
 
-(defn- handle-export-publish-assets [_event html custom-css-path]
+(defn- handle-export-publish-assets [_event html custom-css-path repo-path asset-filenames]
   (let [app-path (. app getAppPath)
+        asset-filenames (js->clj asset-filenames)
         paths (js->clj (. dialog showOpenDialogSync (clj->js {:properties ["openDirectory" "createDirectory" "promptToCreate", "multiSelections"]})))]
     (when (seq paths)
       (let [root-dir (first paths)
             static-dir (path/join root-dir "static")
+            assets-from-dir (path/join repo-path "assets")
+            assets-to-dir (path/join root-dir "assets")
             index-html-path (path/join root-dir "index.html")]
         (p/let [_ (. fs ensureDir static-dir)
+                _ (. fs ensureDir assets-to-dir)
                 _ (p/all  (concat
                            [(. fs writeFile index-html-path html)
 
+
                             (. fs copy (path/join app-path "404.html") (path/join root-dir "404.html"))]
 
+                           (map
+                            (fn [filename] (. fs copy (path/join assets-from-dir filename) (path/join assets-to-dir filename)))
+
+                            asset-filenames)
+
                            (map
                             (fn [part]
                               (. fs copy (path/join app-path part) (path/join static-dir part)))

+ 44 - 42
src/main/frontend/components/block.cljs

@@ -248,9 +248,11 @@
     (if (and (config/local-asset? href)
              (config/local-db? (state/get-current-repo)))
       (asset-link config title href label metadata full_text)
-      (let [href (if (util/starts-with? href "http")
-                   href
-                   (get-file-absolute-path config href))]
+      (let [href (if config/publishing?
+                   (subs href 1)
+                   (if (util/starts-with? href "http")
+                     href
+                     (get-file-absolute-path config href)))]
         (resizable-image config title href metadata full_text false)))))
 
 (defn repetition-to-string
@@ -428,8 +430,8 @@
          [:span.text-gray-500.bracket "[["])
        (let [s (string/trim s)]
          (page-cp (assoc config
-                        :label (mldoc/plain->text label)
-                        :contents-page? contents-page?) {:block/name s}))
+                         :label (mldoc/plain->text label)
+                         :contents-page? contents-page?) {:block/name s}))
        (when (and (or show-brackets? nested-link?)
                   (not html-export?)
                   (not contents-page?))
@@ -865,22 +867,22 @@
         (when-let [url (first arguments)]
           (let [id-regex #"https?://www\.bilibili\.com/video/([\w\W]+)"]
             (when-let [id (cond
-                           (<= (count url) 15) url
-                           :else
-                           (last (re-find id-regex url)))]
-             (when-not (string/blank? id)
-               (let [width (min (- (util/get-width) 96)
-                                560)
-                     height (int (* width (/ 315 560)))]
-                 [:iframe
-                  {:allowfullscreen true
-                   :framespacing "0"
-                   :frameborder "no"
-                   :border "0"
-                   :scrolling "no"
-                   :src (str "https://player.bilibili.com/player.html?bvid=" id "&high_quality=1")
-                   :width width
-                   :height (max 500 height)}])))))
+                            (<= (count url) 15) url
+                            :else
+                            (last (re-find id-regex url)))]
+              (when-not (string/blank? id)
+                (let [width (min (- (util/get-width) 96)
+                                 560)
+                      height (int (* width (/ 315 560)))]
+                  [:iframe
+                   {:allowfullscreen true
+                    :framespacing "0"
+                    :frameborder "no"
+                    :border "0"
+                    :scrolling "no"
+                    :src (str "https://player.bilibili.com/player.html?bvid=" id "&high_quality=1")
+                    :width width
+                    :height (max 500 height)}])))))
 
         (= name "embed")
         (let [a (first arguments)]
@@ -1039,7 +1041,7 @@
        :on-click (fn [e]
                    (util/stop e)
                    (when-not (and (not collapsed?) (not has-child?))
-                       (editor-handler/set-block-property! uuid :collapsed (not collapsed?))))}
+                     (editor-handler/set-block-property! uuid :collapsed (not collapsed?))))}
       (cond
         (and control-show? collapsed?)
         (svg/caret-right)
@@ -1350,22 +1352,22 @@
                  (and (util/sup? target)
                       (d/has-class? target "fn"))
                  (d/has-class? target "image-resize"))
-       (editor-handler/clear-selection! nil)
-       (editor-handler/unhighlight-blocks!)
-       (let [block (or (db/pull [:block/uuid (:block/uuid block)]) block)
-             f #(let [cursor-range (util/caret-range (gdom/getElement block-id))]
-                  (state/set-editing!
-                   edit-input-id
-                   content
-                   block
-                   cursor-range
-                   false))]
+        (editor-handler/clear-selection! nil)
+        (editor-handler/unhighlight-blocks!)
+        (let [block (or (db/pull [:block/uuid (:block/uuid block)]) block)
+              f #(let [cursor-range (util/caret-range (gdom/getElement block-id))]
+                   (state/set-editing!
+                    edit-input-id
+                    content
+                    block
+                    cursor-range
+                    false))]
          ;; wait a while for the value of the caret range
-         (if (util/ios?)
-           (f)
-           (js/setTimeout f 5)))
+          (if (util/ios?)
+            (f)
+            (js/setTimeout f 5)))
 
-       (when block-id (state/set-selection-start-block! block-id))))))
+        (when block-id (state/set-selection-start-block! block-id))))))
 
 (defn- block-content-on-drag-over
   [event uuid]
@@ -1444,11 +1446,11 @@
         (do
           [:div.block-body {:style {:display (if (and collapsed? (seq title)) "none" "")}}
           ;; TODO: consistent id instead of the idx (since it could be changed later)
-          (let [body (block/trim-break-lines! (:block/body block))]
-            (for [[idx child] (medley/indexed body)]
-              (when-let [block (markup-element-cp config child)]
-                (rum/with-key (block-child block)
-                  (str uuid "-" idx)))))]))]
+           (let [body (block/trim-break-lines! (:block/body block))]
+             (for [[idx child] (medley/indexed body)]
+               (when-let [block (markup-element-cp config child)]
+                 (rum/with-key (block-child block)
+                   (str uuid "-" idx)))))]))]
      (when (and block-refs-count (> block-refs-count 0))
        [:div
         [:a.open-block-ref-link.bg-base-2
@@ -1539,7 +1541,7 @@
                                          (for [{:block/keys [uuid title name]} parents]
                                            (when-not name ; not page
                                              [:a {:href (rfe/href :page {:name uuid})}
-                                             (map-inline config title)])))
+                                              (map-inline config title)])))
                                 parents (remove nil? parents)]
                             (reset! parents-atom parents)
                             (when (seq parents)

+ 105 - 92
src/main/frontend/db/model.cljs

@@ -44,7 +44,7 @@
     ;;            [(identity ?vs) [?v ...]]
     ;;            (not-join [?e ?v]
     ;;                      [?e ?a ?v]))]
-])
+    ])
 
 (defn transact-files-db!
   ([tx-data]
@@ -156,7 +156,7 @@
             :where
             [?file :file/path ?path]
             ;; [?file :file/last-modified-at ?modified-at]
-]
+            ]
           conn)
          (seq)
          ;; (sort-by last)
@@ -224,7 +224,7 @@
    (when (and repo path)
      (->
       (react/q repo [:file/content path]
-        {:use-cache? true}
+               {:use-cache? true}
                '[:find ?content
                  :in $ ?path
                  :where
@@ -243,7 +243,7 @@
         :where
         [?file :file/path ?path]
         [?file :file/content ?content]]
-       conn)
+      conn)
      (into {}))))
 
 
@@ -562,18 +562,18 @@
   [blocks parent]
   (let [blocks (keep-only-one-file blocks parent)]
     (when (not= (count blocks) (count (set (map :block/left blocks))))
-     (let [duplicates (->> (map (comp :db/id :block/left) blocks)
-                           frequencies
-                           (filter (fn [[_k v]] (> v 1)))
-                           (map (fn [[k _v]]
-                                  (let [left (db-utils/pull k)]
-                                    {:left left
-                                     :duplicates (->>
-                                                  (filter (fn [block]
-                                                            (= k (:db/id (:block/left block))))
-                                                          blocks)
-                                                  (map #(select-keys % [:db/id :block/level :block/content :block/file])))}))))]
-       (util/pprint duplicates)))
+      (let [duplicates (->> (map (comp :db/id :block/left) blocks)
+                            frequencies
+                            (filter (fn [[_k v]] (> v 1)))
+                            (map (fn [[k _v]]
+                                   (let [left (db-utils/pull k)]
+                                     {:left left
+                                      :duplicates (->>
+                                                   (filter (fn [block]
+                                                             (= k (:db/id (:block/left block))))
+                                                           blocks)
+                                                   (map #(select-keys % [:db/id :block/level :block/content :block/file])))}))))]
+        (util/pprint duplicates)))
     (assert (= (count blocks) (count (set (map :block/left blocks)))) "Each block should have a different left node")
     (let [left->blocks (reduce (fn [acc b] (assoc acc (:db/id (:block/left b)) b)) {} blocks)]
       (loop [block parent
@@ -587,26 +587,26 @@
   [repo block-uuid]
   (when-let [conn (conn/get-conn repo)]
     (-> (d/q
-          '[:find [(pull ?b [*]) ...]
-            :in $ ?parent-id
-            :where
-            [?b :block/parent ?parent]
-            [?parent :block/uuid ?parent-id]]
-          conn
-          block-uuid)
+         '[:find [(pull ?b [*]) ...]
+           :in $ ?parent-id
+           :where
+           [?b :block/parent ?parent]
+           [?parent :block/uuid ?parent-id]]
+         conn
+         block-uuid)
         (sort-by-left (db-utils/entity [:block/uuid block-uuid])))))
 
 (defn get-blocks-by-page
   [id-or-lookup-ref]
   (when-let [conn (conn/get-conn)]
     (->
-      (d/q
-       '[:find (pull ?block [*])
-         :in $ ?page
-         :where
-         [?block :block/page ?page]]
-       conn id-or-lookup-ref)
-      flatten)))
+     (d/q
+      '[:find (pull ?block [*])
+        :in $ ?page
+        :where
+        [?block :block/page ?page]]
+      conn id-or-lookup-ref)
+     flatten)))
 
 (defn get-block-children
   "Including nested children."
@@ -622,18 +622,18 @@
    (get-block-and-children repo block-uuid true))
   ([repo block-uuid use-cache?]
    (some-> (react/q repo [:block/block block-uuid]
-             {:use-cache? use-cache?
-              :transform-fn #(block-and-children-transform % repo block-uuid)}
-             '[:find (pull ?c [*])
-               :in $ ?id %
-               :where
-               [?b :block/uuid ?id]
-               (or-join [?b ?c ?id]
+                    {:use-cache? use-cache?
+                     :transform-fn #(block-and-children-transform % repo block-uuid)}
+                    '[:find (pull ?c [*])
+                      :in $ ?id %
+                      :where
+                      [?b :block/uuid ?id]
+                      (or-join [?b ?c ?id]
                         ;; including the parent
-                        [?c :block/uuid ?id]
-                        (parent ?b ?c))]
-             block-uuid
-             rules)
+                               [?c :block/uuid ?id]
+                               (parent ?b ?c))]
+                    block-uuid
+                    rules)
            react)))
 
 (defn get-file-page
@@ -794,17 +794,17 @@
   (when-let [conn (conn/get-conn repo)]
     (->
      (d/q
-       '[:find [?ref-page ...]
-         :in $ % ?page
-         :where
-         [?p :block/name ?page]
-         [?b :block/path-refs ?p]
-         [?b :block/refs ?other-p]
-         [(not= ?p ?other-p)]
-         [?other-p :block/name ?ref-page]]
-       conn
-       rules
-       page)
+      '[:find [?ref-page ...]
+        :in $ % ?page
+        :where
+        [?p :block/name ?page]
+        [?b :block/path-refs ?p]
+        [?b :block/refs ?other-p]
+        [(not= ?p ?other-p)]
+        [?other-p :block/name ?ref-page]]
+      conn
+      rules
+      page)
      (distinct))))
 
 ;; Ignore files with empty blocks for now
@@ -891,15 +891,15 @@
     (when (seq blocks)
       (let [block-ids (set (map :db/id blocks))
             refs (d/q
-                   '[:find ?p ?ref
-                     :in $ % ?block-ids
-                     :where
-                     (parent ?p ?b)
-                     [(contains? ?block-ids ?p)]
-                     [?b :block/refs ?ref]]
-                   conn
-                   rules
-                   block-ids)
+                  '[:find ?p ?ref
+                    :in $ % ?block-ids
+                    :where
+                    (parent ?p ?b)
+                    [(contains? ?block-ids ?p)]
+                    [?b :block/refs ?ref]]
+                  conn
+                  rules
+                  block-ids)
             refs (->> (group-by first refs)
                       (medley/map-vals #(set (map (fn [[_ id]] {:db/id id}) %))))]
         (map (fn [block] (assoc block :block/children-refs
@@ -914,7 +914,7 @@
             :where
             [?b :block/refs ?page-id]]
           (conn/get-conn repo)
-       page-id)
+          page-id)
      (flatten))))
 
 (defn get-page-referenced-blocks
@@ -969,29 +969,29 @@
   (when-let [date (date/journal-title->int journal-title)]
     (let [future-days (state/get-scheduled-future-days)]
       (when-let [repo (state/get-current-repo)]
-       (when-let [conn (conn/get-conn repo)]
-         (->> (react/q repo [:custom :scheduled-deadline journal-title] {}
-                '[:find (pull ?block [*])
-                  :in $ ?day ?future
-                  :where
-                  (or
-                   [?block :block/scheduled ?d]
-                   [?block :block/deadline ?d])
-                  [(get-else $ ?block :block/repeated? false) ?repeated]
-                  [(get-else $ ?block :block/marker "NIL") ?marker]
-                  [(not= ?marker "DONE")]
-                  [(not= ?marker "CANCELED")]
-                  [(not= ?marker "CANCELLED")]
-                  [(<= ?d ?future)]
-                  (or-join [?repeated ?d ?day]
-                           [(true? ?repeated)]
-                           [(>= ?d ?day)])]
-                date
-                (+ date future-days))
-              react
-              db-utils/seq-flatten
-              sort-blocks
-              db-utils/group-by-page))))))
+        (when-let [conn (conn/get-conn repo)]
+          (->> (react/q repo [:custom :scheduled-deadline journal-title] {}
+                        '[:find (pull ?block [*])
+                          :in $ ?day ?future
+                          :where
+                          (or
+                           [?block :block/scheduled ?d]
+                           [?block :block/deadline ?d])
+                          [(get-else $ ?block :block/repeated? false) ?repeated]
+                          [(get-else $ ?block :block/marker "NIL") ?marker]
+                          [(not= ?marker "DONE")]
+                          [(not= ?marker "CANCELED")]
+                          [(not= ?marker "CANCELLED")]
+                          [(<= ?d ?future)]
+                          (or-join [?repeated ?d ?day]
+                                   [(true? ?repeated)]
+                                   [(>= ?d ?day)])]
+                        date
+                        (+ date future-days))
+               react
+               db-utils/seq-flatten
+               sort-blocks
+               db-utils/group-by-page))))))
 
 (defn get-files-that-referenced-page
   [page-id]
@@ -1151,8 +1151,8 @@
      @blocks-count-cache
      (when-let [conn (conn/get-conn)]
        (let [n (count (d/datoms conn :avet :block/uuid))]
-        (reset! blocks-count-cache n)
-        n)))))
+         (reset! blocks-count-cache n)
+         n)))))
 
 ;; block/uuid and block/content
 (defn get-all-block-contents
@@ -1192,8 +1192,21 @@
                                             (contains? public-pages (:e datom)))
                                        (and (= ns "block")
                                             (contains? public-pages (:db/id (:block/page (d/entity db (:e datom))))))))))
-            datoms (d/datoms filtered-db :eavt)]
-        @(d/conn-from-datoms datoms db-schema/schema)))))
+            datoms (d/datoms filtered-db :eavt)
+            public-assets-filesnames
+
+            (keep
+             (fn [datom]
+
+               (if (= :block/content (:a datom))
+                 (let [matched (re-seq #"\([./]*/assets/([^)]+)\)" (:v datom))
+
+                       path (get (get (into [] matched) 0) 1)]
+                   path)))
+             datoms)]
+
+
+        [@(d/conn-from-datoms datoms db-schema/schema) (into [] public-assets-filesnames)]))))
 
 (defn delete-blocks
   [repo-url files]
@@ -1265,8 +1278,8 @@
              :where
              [?b :block/page ?page]
              [?b :block/pre-block? true]]
-        (conn/get-conn repo)
-        page-id)
+           (conn/get-conn repo)
+           page-id)
       ffirst))
 
 (comment
@@ -1293,4 +1306,4 @@
                    [(contains? ?refs ?b-ref)]))]
        (conn/get-conn)
        rules
-    page-ids))
+       page-ids))

+ 12 - 11
src/main/frontend/handler/export.cljs

@@ -105,9 +105,9 @@
 (defn export-repo-as-html!
   [repo]
   (when-let [db (db/get-conn repo)]
-    (let [db           (if (state/all-pages-public?)
-                         (db/clean-export! db)
-                         (db/filter-only-public-pages-and-blocks db))
+    (let [[db asset-filenames]           (if (state/all-pages-public?)
+                                           (db/clean-export! db)
+                                           (db/filter-only-public-pages-and-blocks db))
           db-str       (db/db->string db)
           state        (select-keys @state/state
                                     [:ui/theme :ui/cycle-collapse
@@ -120,7 +120,8 @@
           html-str     (str "data:text/html;charset=UTF-8,"
                             (js/encodeURIComponent raw-html-str))]
       (if (util/electron?)
-        (js/window.apis.exportPublishAssets raw-html-str (config/get-custom-css-path))
+        (js/window.apis.exportPublishAssets raw-html-str (config/get-custom-css-path) (config/get-repo-dir repo) (clj->js asset-filenames))
+
         (when-let [anchor (gdom/getElement "download-as-html")]
           (.setAttribute anchor "href" html-str)
           (.setAttribute anchor "download" "index.html")
@@ -424,13 +425,13 @@
     (->>
      md-files
      (map (fn [[path content]] {:path path :content content
-                               :names (d/q '[:find [?n ?n2]
-                                             :in $ ?p
-                                             :where [?e :file/path ?p]
-                                             [?e2 :block/file ?e]
-                                             [?e2 :block/name ?n]
-                                             [?e2 :block/original-name ?n2]] conn path)
-                               :format (f/get-format path)})))))
+                                :names (d/q '[:find [?n ?n2]
+                                              :in $ ?p
+                                              :where [?e :file/path ?p]
+                                              [?e2 :block/file ?e]
+                                              [?e2 :block/name ?n]
+                                              [?e2 :block/original-name ?n2]] conn path)
+                                :format (f/get-format path)})))))
 
 (defn export-repo-as-markdown!
   [repo]