node.cljs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. (ns frontend.fs.node
  2. (:require [clojure.string :as string]
  3. [electron.ipc :as ipc]
  4. [frontend.config :as config]
  5. [frontend.db :as db]
  6. [frontend.fs.protocol :as protocol]
  7. [frontend.state :as state]
  8. [frontend.util :as util]
  9. [goog.object :as gobj]
  10. [lambdaisland.glogi :as log]
  11. [promesa.core :as p]
  12. [frontend.encrypt :as encrypt]))
  13. (defn concat-path
  14. [dir path]
  15. (cond
  16. (nil? path)
  17. dir
  18. (string/starts-with? path dir)
  19. path
  20. :else
  21. (str (string/replace dir #"/$" "")
  22. (when path
  23. (str "/" (string/replace path #"^/" ""))))))
  24. (defn- contents-matched?
  25. [disk-content db-content]
  26. (when (and (string? disk-content) (string? db-content))
  27. (if (encrypt/encrypted-db? (state/get-current-repo))
  28. (p/let [decrypted-content (encrypt/decrypt disk-content)]
  29. (= (string/trim decrypted-content) (string/trim db-content)))
  30. (p/resolved (= (string/trim disk-content) (string/trim db-content))))))
  31. (defn- write-file-impl!
  32. [this repo dir path content {:keys [ok-handler error-handler old-content skip-compare?]} stat]
  33. (if skip-compare?
  34. (p/catch
  35. (p/let [result (ipc/ipc "writeFile" repo path content)]
  36. (when ok-handler
  37. (ok-handler repo path result)))
  38. (fn [error]
  39. (if error-handler
  40. (error-handler error)
  41. (log/error :write-file-failed error))))
  42. (p/let [disk-content (when (not= stat :not-found)
  43. (-> (protocol/read-file this dir path nil)
  44. (p/catch (fn [error]
  45. (js/console.error error)
  46. nil))))
  47. disk-content (or disk-content "")
  48. ext (string/lower-case (util/get-file-ext path))
  49. db-content (or old-content (db/get-file repo path) "")
  50. contents-matched? (contents-matched? disk-content db-content)]
  51. (cond
  52. (and
  53. (not= stat :not-found) ; file on the disk was deleted
  54. (not contents-matched?)
  55. (not (contains? #{"excalidraw" "edn" "css"} ext))
  56. (not (string/includes? path "/.recycle/")))
  57. (p/let [disk-content (encrypt/decrypt disk-content)]
  58. (state/pub-event! [:file/not-matched-from-disk path disk-content content]))
  59. :else
  60. (->
  61. (p/let [result (ipc/ipc "writeFile" repo path content)
  62. mtime (gobj/get result "mtime")]
  63. (when-not contents-matched?
  64. (ipc/ipc "backupDbFile" (config/get-local-dir repo) path disk-content content))
  65. (db/set-file-last-modified-at! repo path mtime)
  66. (p/let [content (if (encrypt/encrypted-db? (state/get-current-repo))
  67. (encrypt/decrypt content)
  68. content)]
  69. (db/set-file-content! repo path content))
  70. (when ok-handler
  71. (ok-handler repo path result))
  72. result)
  73. (p/catch (fn [error]
  74. (if error-handler
  75. (error-handler error)
  76. (log/error :write-file-failed error)))))))))
  77. (defn- open-dir []
  78. (p/let [dir-path (util/mocked-open-dir-path)
  79. result (if dir-path
  80. (ipc/ipc "getFiles" dir-path)
  81. (ipc/ipc "openDir" {}))]
  82. result))
  83. (defrecord Node []
  84. protocol/Fs
  85. (mkdir! [_this dir]
  86. (ipc/ipc "mkdir" dir))
  87. (mkdir-recur! [_this dir]
  88. (ipc/ipc "mkdir-recur" dir))
  89. (readdir [_this dir] ; recursive
  90. (ipc/ipc "readdir" dir))
  91. (unlink! [_this repo path _opts]
  92. (ipc/ipc "unlink"
  93. (config/get-repo-dir repo)
  94. path))
  95. (rmdir! [_this _dir]
  96. ;; Too dangerious!!! We'll never implement this.
  97. nil)
  98. (read-file [_this dir path _options]
  99. (let [path (concat-path dir path)]
  100. (ipc/ipc "readFile" path)))
  101. (write-file! [this repo dir path content opts]
  102. (let [path (concat-path dir path)]
  103. (p/let [stat (p/catch
  104. (protocol/stat this dir path)
  105. (fn [_e] :not-found))
  106. sub-dir (first (util/get-dir-and-basename path))
  107. _ (protocol/mkdir-recur! this sub-dir)]
  108. (write-file-impl! this repo dir path content opts stat))))
  109. (rename! [_this _repo old-path new-path]
  110. (ipc/ipc "rename" old-path new-path))
  111. (stat [_this dir path]
  112. (let [path (concat-path dir path)]
  113. (ipc/ipc "stat" path)))
  114. (open-dir [_this _ok-handler]
  115. (open-dir))
  116. (get-files [_this path-or-handle _ok-handler]
  117. (ipc/ipc "getFiles" path-or-handle))
  118. (watch-dir! [_this dir options]
  119. (ipc/ipc "addDirWatcher" dir options))
  120. (unwatch-dir! [_this dir]
  121. (ipc/ipc "unwatchDir" dir)))