mirror of
https://github.com/logseq/logseq.git
synced 2026-06-02 19:31:24 +00:00
refactor(fs): handle global file write
This commit is contained in:
@@ -129,6 +129,7 @@
|
||||
(cond
|
||||
;; image type
|
||||
(and format (contains? (gp-config/img-formats) format))
|
||||
;; FIXME(andelf): bad path op
|
||||
[:img {:src (util/node-path.join "file://" path)}]
|
||||
|
||||
(and format
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
[frontend.util :as util]
|
||||
[logseq.graph-parser.config :as gp-config]
|
||||
[logseq.graph-parser.util :as gp-util]
|
||||
[shadow.resource :as rc]
|
||||
[frontend.fs2.path :as path]))
|
||||
[shadow.resource :as rc]))
|
||||
|
||||
(goog-define DEV-RELEASE false)
|
||||
(defonce dev-release? DEV-RELEASE)
|
||||
@@ -493,14 +492,21 @@
|
||||
(fs2-path/path-join repo-dir app-name export-css-file))))
|
||||
|
||||
(defn expand-relative-assets-path
|
||||
;; resolve all relative links in custom.css to assets:// URL
|
||||
;; ../assets/xxx -> {assets|file}://{current-graph-root-path}/xxx
|
||||
[source]
|
||||
(when-let [protocol (and (string? source)
|
||||
(not (string/blank? source))
|
||||
(if (util/electron?) "assets" "file"))]
|
||||
(js/console.error "BUG: assets:// url handling")
|
||||
(string/replace
|
||||
source "../assets" (util/format "%s://%s/assets" protocol (get-repo-dir (state/get-current-repo))))))
|
||||
(prn ::expand-relative-assets-path source)
|
||||
(let [protocol (and (string? source)
|
||||
(not (string/blank? source))
|
||||
(if (util/electron?) "assets://" "file://"))
|
||||
;; BUG: use "assets" as fake current directory
|
||||
assets-link-fn (fn [_]
|
||||
(str (fs2-path/path-join protocol
|
||||
(get-repo-dir (state/get-current-repo)) "assets"))
|
||||
"/")]
|
||||
(when (not-empty source)
|
||||
(string/replace source #"\\.\\./assets/"
|
||||
assets-link-fn))))
|
||||
|
||||
(defn get-current-repo-assets-root
|
||||
[]
|
||||
|
||||
@@ -23,12 +23,28 @@
|
||||
(defonce node-backend (node/->Node))
|
||||
(defonce mobile-backend (capacitor-fs/->Capacitorfs))
|
||||
|
||||
(defn- get-native-backend
|
||||
"Native FS backend of current platform"
|
||||
[]
|
||||
(cond
|
||||
(util/electron?)
|
||||
node-backend
|
||||
|
||||
(mobile-util/native-platform?)
|
||||
mobile-backend
|
||||
|
||||
:else
|
||||
nfs-backend))
|
||||
|
||||
(defn get-fs
|
||||
[dir]
|
||||
(let [bfs-local? (or (string/starts-with? dir "/local")
|
||||
(string/starts-with? dir "local"))]
|
||||
(let [bfs-local? (and dir
|
||||
(or (string/starts-with? dir "/local")
|
||||
(string/starts-with? dir "local")))]
|
||||
(cond
|
||||
(nil? dir) ;; global file op, use native backend
|
||||
(get-native-backend)
|
||||
|
||||
(string/starts-with? dir "memory://")
|
||||
memory-backend
|
||||
|
||||
@@ -144,19 +160,6 @@
|
||||
(let [fpath (fs2-path/path-join dir path)]
|
||||
(protocol/stat (get-fs dir) fpath))))
|
||||
|
||||
(defn- get-native-backend
|
||||
"Native FS backend of current platform"
|
||||
[]
|
||||
(cond
|
||||
(util/electron?)
|
||||
node-backend
|
||||
|
||||
(mobile-util/native-platform?)
|
||||
mobile-backend
|
||||
|
||||
:else
|
||||
nfs-backend))
|
||||
|
||||
(defn open-dir
|
||||
[dir]
|
||||
(let [record (get-native-backend)]
|
||||
|
||||
@@ -106,7 +106,9 @@
|
||||
;; Too dangerious!!! We'll never implement this.
|
||||
nil)
|
||||
(read-file [_this dir path _options]
|
||||
(let [path (fs2-path/path-join dir path)]
|
||||
(let [path (if (nil? dir)
|
||||
path
|
||||
(fs2-path/path-join dir path))]
|
||||
(ipc/ipc "readFile" path)))
|
||||
(write-file! [this repo dir path content opts]
|
||||
(p/let [fpath (fs2-path/path-join dir path)
|
||||
|
||||
@@ -153,9 +153,14 @@
|
||||
(defn path-join
|
||||
"Join path segments, or URL base and path segments"
|
||||
[base & segments]
|
||||
(when (string/blank? base)
|
||||
(js/console.error "BUG: SHOULD-NOT-JOIN-EMPTY")
|
||||
(js/console.trace))
|
||||
|
||||
(cond
|
||||
(nil? base)
|
||||
(println "path join global directory" segments)
|
||||
(= base "")
|
||||
(js/console.error "BUG: should not join with empty dir" segments)
|
||||
:else
|
||||
nil)
|
||||
|
||||
(if (is-file-url base)
|
||||
(apply url-join base segments)
|
||||
@@ -184,20 +189,6 @@
|
||||
(url-normalize path)
|
||||
(path-normalize-internal path)))
|
||||
|
||||
(defn trim-dir-prefix
|
||||
"Trim dir prefix from path"
|
||||
[base-path sub-path]
|
||||
(let [base-path (path-normalize base-path)
|
||||
sub-path (path-normalize sub-path)
|
||||
is-url? (is-file-url base-path)]
|
||||
(if (string/starts-with? sub-path base-path)
|
||||
(if is-url?
|
||||
(gp-util/safe-decode-uri-component (string/replace (subs sub-path (count base-path)) #"^/+", ""))
|
||||
(string/replace (subs sub-path (count base-path)) #"^/+", ""))
|
||||
(do
|
||||
(js/console.error "unhandled trim-base" base-path sub-path)
|
||||
sub-path))))
|
||||
|
||||
(defn url-to-path
|
||||
"Extract path part of a URL, decoded.
|
||||
|
||||
@@ -214,6 +205,19 @@
|
||||
path)
|
||||
original-url))
|
||||
|
||||
(defn trim-dir-prefix
|
||||
"Trim dir prefix from path"
|
||||
[base-path sub-path]
|
||||
(let [base-path (path-normalize base-path)
|
||||
sub-path (path-normalize sub-path)
|
||||
is-url? (is-file-url base-path)]
|
||||
(if (string/starts-with? sub-path base-path)
|
||||
(if is-url?
|
||||
(gp-util/safe-decode-uri-component (string/replace (subs sub-path (count base-path)) #"^/+", ""))
|
||||
(string/replace (subs sub-path (count base-path)) #"^/+", ""))
|
||||
(do
|
||||
(js/console.error "unhandled trim-base" base-path sub-path)
|
||||
nil))))
|
||||
|
||||
(defn relative-path
|
||||
"Get relative path from base path.
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
(ns frontend.handler.code
|
||||
"Codemirror editor related."
|
||||
(:require [frontend.state :as state]
|
||||
[goog.object :as gobj]
|
||||
(:require [clojure.string :as string]
|
||||
[frontend.config :as config]
|
||||
[frontend.db :as db]
|
||||
[frontend.handler.editor :as editor-handler]
|
||||
[frontend.handler.file :as file-handler]
|
||||
[frontend.state :as state]
|
||||
[goog.object :as gobj]
|
||||
[logseq.graph-parser.utf8 :as utf8]
|
||||
[clojure.string :as string]))
|
||||
[frontend.fs2.path :as fs2-path]
|
||||
[frontend.components.content :as content]))
|
||||
|
||||
(defn save-code-editor!
|
||||
[]
|
||||
@@ -20,6 +23,7 @@
|
||||
default-value (gobj/get textarea "defaultValue")]
|
||||
(when (not= value default-value)
|
||||
(cond
|
||||
;; save block content
|
||||
(:block/uuid config)
|
||||
(let [block (db/pull [:block/uuid (:block/uuid config)])
|
||||
content (:block/content block)
|
||||
@@ -34,16 +38,25 @@
|
||||
(state/set-edit-content! (state/get-edit-input-id) new-content)
|
||||
(editor-handler/save-block-if-changed! block new-content))
|
||||
|
||||
(:file-path config)
|
||||
(not-empty (:file-path config))
|
||||
(let [path (:file-path config)
|
||||
content (or (db/get-file path) "")]
|
||||
(when (and
|
||||
(not (string/blank? value))
|
||||
(not= (string/trim value) (string/trim content)))
|
||||
(file-handler/alter-file (state/get-current-repo)
|
||||
path
|
||||
(str (string/trim value) "\n")
|
||||
{:re-render-root? true})))
|
||||
repo (state/get-current-repo)
|
||||
repo-dir (config/get-repo-dir repo)
|
||||
rpath (fs2-path/trim-dir-prefix repo-dir path)
|
||||
;; old-content (db/get-file rpath)
|
||||
_ (prn ::calc rpath)]
|
||||
(if rpath
|
||||
;; in-db file
|
||||
(let [old-content (db/get-file rpath)]
|
||||
(when (and
|
||||
(not (string/blank? value))
|
||||
(not= (string/trim value) (string/trim old-content)))
|
||||
(file-handler/alter-file (state/get-current-repo)
|
||||
rpath
|
||||
(str (string/trim value) "\n")
|
||||
{:re-render-root? true})))
|
||||
;; global file
|
||||
(file-handler/alter-global-file path (str (string/trim value) "\n"))))
|
||||
|
||||
:else
|
||||
nil))))))
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
(defn set-config!
|
||||
([k v]
|
||||
(set-config! (state/get-current-repo) k v))
|
||||
([repo k v]
|
||||
(let [path (config/get-repo-config-path repo)]
|
||||
([_repo k v]
|
||||
(let [path "logseq/config.edn"]
|
||||
(repo-config-set-key-value path k v))))
|
||||
|
||||
(defn toggle-ui-show-brackets! []
|
||||
|
||||
@@ -115,17 +115,28 @@
|
||||
(defn- write-file-aux!
|
||||
[repo path content write-file-options]
|
||||
(let [original-content (db/get-file repo path)
|
||||
path-dir (if (and
|
||||
(config/global-config-enabled?)
|
||||
;; Hack until we better understand failure in error handler
|
||||
(global-config-handler/global-config-dir-exists?)
|
||||
(= (path/dirname path) (global-config-handler/global-config-dir)))
|
||||
(global-config-handler/global-config-dir)
|
||||
(config/get-repo-dir repo))
|
||||
path-dir (config/get-repo-dir repo)
|
||||
;;path-dir (if (and
|
||||
;; (config/global-config-enabled?)
|
||||
;; ;; Hack until we better understand failure in error handler
|
||||
;; (global-config-handler/global-config-dir-exists?)
|
||||
;; (= (path/dirname path) (global-config-handler/global-config-dir)))
|
||||
;; (global-config-handler/global-config-dir)
|
||||
;; (config/get-repo-dir repo))
|
||||
write-file-options' (merge write-file-options
|
||||
(when original-content {:old-content original-content}))]
|
||||
(fs/write-file! repo path-dir path content write-file-options')))
|
||||
|
||||
(defn alter-global-file
|
||||
"Write global file, e.g. global config"
|
||||
[path content]
|
||||
(p/let [_ (fs/write-file! "" nil path content {:skip-compare? true})]
|
||||
(cond
|
||||
(and (config/global-config-enabled?)
|
||||
(= path (global-config-handler/global-config-path)))
|
||||
(p/let [_ (global-config-handler/restore-global-config!)]
|
||||
(state/pub-event! [:shortcut/refresh])))))
|
||||
|
||||
(defn alter-file
|
||||
[repo path content {:keys [reset? re-render-root? from-disk? skip-compare? new-graph? verbose
|
||||
skip-db-transact? extracted-block-ids]
|
||||
|
||||
@@ -529,8 +529,8 @@
|
||||
exist? (fs/file-exists? path dirname)
|
||||
_ (when-not exist? (fs/mkdir! (util/node-path.join path dirname)))
|
||||
path (util/node-path.join path dirname (str key ".json"))
|
||||
_ (fs/create-if-not-exists repo "" path (or default "{}"))
|
||||
json (fs/read-file "" path)]
|
||||
_ (fs/create-if-not-exists repo nil path (or default "{}"))
|
||||
json (fs/read-file nil path)]
|
||||
[path (js/JSON.parse json)]))))
|
||||
|
||||
(defn make-fn-to-save-dotdir-json
|
||||
@@ -540,7 +540,7 @@
|
||||
(p/let [repo ""
|
||||
path (get-ls-dotdir-root)
|
||||
path (util/node-path.join path dirname (str key ".json"))]
|
||||
(fs/write-file! repo "" path content {:skip-compare? true})))))
|
||||
(fs/write-file! repo nil path content {:skip-compare? true})))))
|
||||
|
||||
(defn make-fn-to-unlink-dotdir-json
|
||||
[dirname]
|
||||
|
||||
@@ -37,16 +37,14 @@ when a plugin is installed, updated or removed"
|
||||
rewrite/parse-string
|
||||
(rewrite/assoc (keyword id) (select-keys plugin common-plugin-keys))
|
||||
str)]
|
||||
;; fs protocols require repo and dir when they aren't necessary. For this component,
|
||||
;; neither is needed so these are nil and blank respectively
|
||||
(fs/write-file! nil "" (plugin-config-path) updated-content {:skip-compare? true})))
|
||||
(fs/write-file! "" nil (plugin-config-path) updated-content {:skip-compare? true})))
|
||||
|
||||
(defn remove-plugin
|
||||
"Removes a plugin from plugin.edn"
|
||||
[plugin-id]
|
||||
(p/let [content (fs/read-file "" (plugin-config-path))
|
||||
updated-content (-> content rewrite/parse-string (rewrite/dissoc (keyword plugin-id)) str)]
|
||||
(fs/write-file! nil "" (plugin-config-path) updated-content {:skip-compare? true})))
|
||||
(fs/write-file! "" nil (plugin-config-path) updated-content {:skip-compare? true})))
|
||||
|
||||
(defn- create-plugin-config-file-if-not-exists
|
||||
[]
|
||||
@@ -54,6 +52,7 @@ when a plugin is installed, updated or removed"
|
||||
(update-vals #(select-keys % common-plugin-keys))
|
||||
pprint/pprint
|
||||
with-out-str)]
|
||||
(prn ::plugin-dir @global-config-handler/root-dir (plugin-config-path))
|
||||
(fs/create-if-not-exists nil @global-config-handler/root-dir (plugin-config-path) content)))
|
||||
|
||||
(defn- determine-plugins-to-change
|
||||
|
||||
@@ -175,17 +175,18 @@
|
||||
|
||||
(def ^:export load_plugin_config
|
||||
(fn [path]
|
||||
(fs/read-file "" (util/node-path.join path "package.json"))))
|
||||
(fs/read-file nil (util/node-path.join path "package.json"))))
|
||||
|
||||
(def ^:export load_plugin_readme
|
||||
(fn [path]
|
||||
(fs/read-file "" (util/node-path.join path "readme.md"))))
|
||||
(fs/read-file nil (util/node-path.join path "readme.md"))))
|
||||
|
||||
(def ^:export save_plugin_config
|
||||
(fn [path ^js data]
|
||||
(let [repo ""
|
||||
|
||||
path (util/node-path.join path "package.json")]
|
||||
(fs/write-file! repo "" path (js/JSON.stringify data nil 2) {:skip-compare? true}))))
|
||||
(fs/write-file! repo nil path (js/JSON.stringify data nil 2) {:skip-compare? true}))))
|
||||
|
||||
(def ^:export save_focused_code_editor_content
|
||||
(fn []
|
||||
@@ -205,7 +206,7 @@
|
||||
user-path-root (util/node-path.dirname user-path)
|
||||
exist? (fs/file-exists? user-path-root "")
|
||||
_ (when-not exist? (fs/mkdir-recur! user-path-root))
|
||||
_ (fs/write-file! repo "" user-path content {:skip-compare? true})]
|
||||
_ (fs/write-file! repo nil user-path content {:skip-compare? true})]
|
||||
user-path))
|
||||
|
||||
(defn ^:private write_dotdir_file
|
||||
@@ -325,9 +326,10 @@
|
||||
(fn []
|
||||
(p/let [repo ""
|
||||
path (plugin-handler/get-ls-dotdir-root)
|
||||
_ (prn ::dotdir path)
|
||||
path (util/node-path.join path "preferences.json")
|
||||
_ (fs/create-if-not-exists repo "" path)
|
||||
json (fs/read-file "" path)
|
||||
_ (fs/create-if-not-exists repo nil path)
|
||||
json (fs/read-file nil path)
|
||||
json (if (string/blank? json) "{}" json)]
|
||||
(js/JSON.parse json))))
|
||||
|
||||
@@ -337,7 +339,7 @@
|
||||
(p/let [repo ""
|
||||
path (plugin-handler/get-ls-dotdir-root)
|
||||
path (util/node-path.join path "preferences.json")]
|
||||
(fs/write-file! repo "" path (js/JSON.stringify data nil 2) {:skip-compare? true})))))
|
||||
(fs/write-file! repo nil path (js/JSON.stringify data nil 2) {:skip-compare? true})))))
|
||||
|
||||
(def ^:export load_plugin_user_settings
|
||||
;; results [path data]
|
||||
|
||||
Reference in New Issue
Block a user