fs.cljs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. (ns frontend.fs
  2. (:require [cljs-bean.core :as bean]
  3. [frontend.config :as config]
  4. [frontend.fs.nfs :as nfs]
  5. [frontend.fs.node :as node]
  6. [frontend.fs.capacitor-fs :as mobile]
  7. [frontend.fs.bfs :as bfs]
  8. [frontend.mobile.util :as mobile-util]
  9. [frontend.fs.protocol :as protocol]
  10. [frontend.util :as util]
  11. [lambdaisland.glogi :as log]
  12. [promesa.core :as p]
  13. [frontend.db :as db]
  14. [clojure.string :as string]
  15. [frontend.encrypt :as encrypt]
  16. [frontend.state :as state]))
  17. (defonce nfs-record (nfs/->Nfs))
  18. (defonce bfs-record (bfs/->Bfs))
  19. (defonce node-record (node/->Node))
  20. (defonce mobile-record (mobile/->Capacitorfs))
  21. (defn local-db?
  22. [dir]
  23. (and (string? dir)
  24. (config/local-db? (subs dir 1))))
  25. (defn get-fs
  26. [dir]
  27. (let [bfs-local? (or (string/starts-with? dir "/local")
  28. (string/starts-with? dir "local"))]
  29. (cond
  30. (and (util/electron?) (not bfs-local?))
  31. node-record
  32. (mobile-util/native-platform?)
  33. mobile-record
  34. (local-db? dir)
  35. nfs-record
  36. :else
  37. bfs-record)))
  38. (defn mkdir!
  39. [dir]
  40. (protocol/mkdir! (get-fs dir) dir))
  41. (defn mkdir-recur!
  42. [dir]
  43. (protocol/mkdir-recur! (get-fs dir) dir))
  44. (defn readdir
  45. [dir]
  46. (protocol/readdir (get-fs dir) dir))
  47. (defn unlink!
  48. "Should move the path to logseq/recycle instead of deleting it."
  49. [repo path opts]
  50. (protocol/unlink! (get-fs path) repo path opts))
  51. (defn rmdir!
  52. "Remove the directory recursively.
  53. Warning: only run it for browser cache."
  54. [dir]
  55. (when-let [fs (get-fs dir)]
  56. (when (= fs bfs-record)
  57. (protocol/rmdir! fs dir))))
  58. (defn write-file!
  59. [repo dir path content opts]
  60. (when content
  61. (let [fs-record (get-fs dir)]
  62. (p/let [md-or-org? (contains? #{"md" "markdown" "org"} (util/get-file-ext path))
  63. content (if-not md-or-org? content (encrypt/encrypt content))]
  64. (->
  65. (p/let [opts (assoc opts
  66. :error-handler
  67. (fn [error]
  68. (state/pub-event! [:instrument {:type :write-file/failed
  69. :payload {:fs (type fs-record)
  70. :user-agent (when js/navigator js/navigator.userAgent)
  71. :path path
  72. :content-length (count content)
  73. :error-str (str error)
  74. :error error}}])))
  75. _ (protocol/write-file! (get-fs dir) repo dir path content opts)]
  76. (when (= bfs-record fs-record)
  77. (db/set-file-last-modified-at! repo (config/get-file-path repo path) (js/Date.))))
  78. (p/catch (fn [error]
  79. (log/error :file/write-failed {:dir dir
  80. :path path
  81. :error error})
  82. ;; Disable this temporarily
  83. ;; (js/alert "Current file can't be saved! Please copy its content to your local file system and click the refresh button.")
  84. )))))))
  85. (defn read-file
  86. ([dir path]
  87. (let [fs (get-fs dir)
  88. options (if (= fs bfs-record)
  89. {:encoding "utf8"}
  90. {})]
  91. (read-file dir path options)))
  92. ([dir path options]
  93. (protocol/read-file (get-fs dir) dir path options)))
  94. (defn rename!
  95. [repo old-path new-path]
  96. (cond
  97. ; See https://github.com/isomorphic-git/lightning-fs/issues/41
  98. (= old-path new-path)
  99. (p/resolved nil)
  100. :else
  101. (let [[old-path new-path]
  102. (map #(if (or (util/electron?) (mobile-util/native-platform?))
  103. %
  104. (str (config/get-repo-dir repo) "/" %))
  105. [old-path new-path])]
  106. (protocol/rename! (get-fs old-path) repo old-path new-path))))
  107. (defn copy!
  108. [repo old-path new-path]
  109. (cond
  110. (= old-path new-path)
  111. (p/resolved nil)
  112. :else
  113. (let [[old-path new-path]
  114. (map #(if (or (util/electron?) (mobile-util/native-platform?))
  115. %
  116. (str (config/get-repo-dir repo) "/" %))
  117. [old-path new-path])]
  118. (protocol/copy! (get-fs old-path) repo old-path new-path))))
  119. (defn stat
  120. [dir path]
  121. (protocol/stat (get-fs dir) dir path))
  122. (defn- get-record
  123. []
  124. (cond
  125. (util/electron?)
  126. node-record
  127. (mobile-util/native-platform?)
  128. mobile-record
  129. :else
  130. nfs-record))
  131. (defn open-dir
  132. [ok-handler]
  133. (let [record (get-record)]
  134. (p/let [result (protocol/open-dir record ok-handler)]
  135. (if (or (util/electron?)
  136. (mobile-util/native-platform?))
  137. (let [[dir & paths] (bean/->clj result)]
  138. [(:path dir) paths])
  139. result))))
  140. (defn get-files
  141. [path-or-handle ok-handler]
  142. (let [record (get-record)
  143. electron? (util/electron?)
  144. mobile? (mobile-util/native-platform?)]
  145. (p/let [result (protocol/get-files record path-or-handle ok-handler)]
  146. (if (or electron? mobile?)
  147. (let [result (bean/->clj result)]
  148. (if electron? (rest result) result))
  149. result))))
  150. (defn watch-dir!
  151. [dir]
  152. (protocol/watch-dir! (get-record) dir))
  153. (defn unwatch-dir!
  154. [dir]
  155. (protocol/unwatch-dir! (get-record) dir))
  156. (defn mkdir-if-not-exists
  157. [dir]
  158. (->
  159. (when dir
  160. (util/p-handle
  161. (stat dir nil)
  162. (fn [_stat])
  163. (fn [_error]
  164. (mkdir! dir))))
  165. (p/catch (fn [error] (js/console.error error)))))
  166. (defn create-if-not-exists
  167. ([repo dir path]
  168. (create-if-not-exists repo dir path ""))
  169. ([repo dir path initial-content]
  170. (let [path (if (util/absolute-path? path) path
  171. (if (util/starts-with? path "/")
  172. path
  173. (str "/" path)))]
  174. (->
  175. (p/let [_stat (stat dir path)]
  176. true)
  177. (p/catch
  178. (fn [_error]
  179. (p/let [_ (write-file! repo dir path initial-content nil)]
  180. false)))))))
  181. (defn file-exists?
  182. [dir path]
  183. (util/p-handle
  184. (stat dir path)
  185. (fn [_stat] true)
  186. (fn [_e] false)))
  187. (defn dir-exists?
  188. [dir]
  189. (file-exists? dir ""))