watcher_handler.cljs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. (ns frontend.fs.watcher-handler
  2. (:require [clojure.string :as string]
  3. [frontend.config :as config]
  4. [frontend.db :as db]
  5. [frontend.db.model :as model]
  6. [frontend.handler.editor :as editor]
  7. [logseq.graph-parser.extract :as extract]
  8. [frontend.handler.file :as file-handler]
  9. [frontend.handler.page :as page-handler]
  10. [frontend.handler.repo :as repo-handler]
  11. [frontend.handler.ui :as ui-handler]
  12. [logseq.graph-parser.util :as gp-util]
  13. [lambdaisland.glogi :as log]
  14. [electron.ipc :as ipc]
  15. [promesa.core :as p]
  16. [frontend.state :as state]
  17. [frontend.encrypt :as encrypt]))
  18. ;; all IPC paths must be normalized! (via gp-util/path-normalize)
  19. (defn- set-missing-block-ids!
  20. [content]
  21. (when (string? content)
  22. (doseq [block-id (extract/extract-all-block-refs content)]
  23. (when-let [block (try
  24. (model/get-block-by-uuid block-id)
  25. (catch js/Error _e
  26. nil))]
  27. (let [id-property (:id (:block/properties block))]
  28. (when-not (= (str id-property) (str block-id))
  29. (editor/set-block-property! block-id "id" block-id)))))))
  30. (defn- handle-add-and-change!
  31. [repo path content db-content mtime backup?]
  32. (p/let [
  33. ;; save the previous content in a versioned bak file to avoid data overwritten.
  34. _ (when backup? (ipc/ipc "backupDbFile" (config/get-local-dir repo) path db-content content))
  35. _ (file-handler/alter-file repo path content {:re-render-root? true
  36. :from-disk? true})]
  37. (set-missing-block-ids! content)
  38. (db/set-file-last-modified-at! repo path mtime)))
  39. (defn handle-changed!
  40. [type {:keys [dir path content stat] :as payload}]
  41. (when dir
  42. (let [path (gp-util/path-normalize path)
  43. repo (config/get-local-repo dir)
  44. pages-metadata-path (config/get-pages-metadata-path)
  45. {:keys [mtime]} stat
  46. db-content (or (db/get-file repo path) "")]
  47. (when (and (or content (= type "unlink"))
  48. (not (encrypt/content-encrypted? content))
  49. (not (:encryption/graph-parsing? @state/state)))
  50. (cond
  51. (and (= "add" type)
  52. (not= (string/trim content) (string/trim db-content))
  53. (not= path pages-metadata-path))
  54. (let [backup? (not (string/blank? db-content))]
  55. (handle-add-and-change! repo path content db-content mtime backup?))
  56. (and (= "change" type)
  57. (not (db/file-exists? repo path)))
  58. (js/console.error "Can't get file in the db: " path)
  59. (and (= "change" type)
  60. (not= (string/trim content) (string/trim db-content))
  61. (not= path pages-metadata-path))
  62. (when-not (and
  63. (string/includes? path (str "/" (config/get-journals-directory) "/"))
  64. (or
  65. (= (string/trim content)
  66. (string/trim (or (state/get-default-journal-template) "")))
  67. (= (string/trim content) "-")
  68. (= (string/trim content) "*")))
  69. (handle-add-and-change! repo path content db-content mtime true))
  70. (and (= "unlink" type)
  71. (db/file-exists? repo path))
  72. (when-let [page-name (db/get-file-page path)]
  73. (println "Delete page: " page-name ", file path: " path ".")
  74. (page-handler/delete! page-name #() :delete-file? false))
  75. (and (contains? #{"add" "change" "unlink"} type)
  76. (string/ends-with? path "logseq/custom.css"))
  77. (do
  78. (println "reloading custom.css")
  79. (ui-handler/add-style-if-exists!))
  80. ;; When metadata is added to watcher, update timestamps in db accordingly
  81. ;; This event is not triggered on re-index
  82. ;; Persistent metadata is gold standard when db is offline, so it's forced
  83. (and (contains? #{"add"} type)
  84. (= path pages-metadata-path))
  85. (p/do! (repo-handler/update-pages-metadata! repo content true))
  86. ;; Change is triggered by external changes, so update to the db
  87. ;; Don't forced update when db is online, but resolving conflicts
  88. (and (contains? #{"change"} type)
  89. (= path pages-metadata-path))
  90. (p/do! (repo-handler/update-pages-metadata! repo content false))
  91. (contains? #{"add" "change" "unlink"} type)
  92. nil
  93. :else
  94. (log/error :fs/watcher-no-handler {:type type
  95. :payload payload})))
  96. ;; return nil, otherwise the entire db will be transfered by ipc
  97. nil)))