|
@@ -634,7 +634,7 @@
|
|
|
(defprotocol IRSAPI
|
|
|
(rsapi-ready? [this graph-uuid] "return true when rsapi ready")
|
|
|
(<key-gen [this] "generate public+private keys")
|
|
|
- (<set-env [this prod? private-key public-key graph-uuid] "set environment")
|
|
|
+ (<set-env [this graph-uuid prod? private-key public-key] "set environment")
|
|
|
(<get-local-files-meta [this graph-uuid base-path filepaths] "get local files' metadata")
|
|
|
(<get-local-all-files-meta [this graph-uuid base-path] "get all local files' metadata")
|
|
|
(<rename-local-file [this graph-uuid base-path from to])
|
|
@@ -643,8 +643,8 @@
|
|
|
(<delete-local-files [this graph-uuid base-path filepaths])
|
|
|
(<update-remote-files [this graph-uuid base-path filepaths local-txid] "local -> remote, return err or txid")
|
|
|
(<delete-remote-files [this graph-uuid base-path filepaths local-txid] "return err or txid")
|
|
|
- (<encrypt-fnames [this fnames])
|
|
|
- (<decrypt-fnames [this fnames]))
|
|
|
+ (<encrypt-fnames [this graph-uuid fnames])
|
|
|
+ (<decrypt-fnames [this graph-uuid fnames]))
|
|
|
|
|
|
(defprotocol IRemoteAPI
|
|
|
(<user-info [this] "user info")
|
|
@@ -673,17 +673,17 @@
|
|
|
it happens on macos (case-insensitive fs)
|
|
|
|
|
|
return canonicalized filepath if exists"
|
|
|
- [irsapi base-path filepath]
|
|
|
+ [graph-uuid irsapi base-path filepath]
|
|
|
(go
|
|
|
- (let [r (<! (<get-local-files-meta irsapi "" base-path [filepath]))]
|
|
|
+ (let [r (<! (<get-local-files-meta irsapi graph-uuid base-path [filepath]))]
|
|
|
(when (some-> r first :path (not= filepath))
|
|
|
(-> r first :path)))))
|
|
|
|
|
|
|
|
|
(defn <local-file-not-exist?
|
|
|
- [irsapi base-path filepath]
|
|
|
+ [graph-uuid irsapi base-path filepath]
|
|
|
(go
|
|
|
- (let [r (<! (<get-local-files-meta irsapi "" base-path [filepath]))]
|
|
|
+ (let [r (<! (<get-local-files-meta irsapi graph-uuid base-path [filepath]))]
|
|
|
|
|
|
(or
|
|
|
;; not found at all
|
|
@@ -720,13 +720,13 @@
|
|
|
(rsapi-ready? [_ graph-uuid] (and (= graph-uuid graph-uuid') private-key' public-key'))
|
|
|
(<key-gen [_] (go (js->clj (<! (p->c (ipc/ipc "key-gen")))
|
|
|
:keywordize-keys true)))
|
|
|
- (<set-env [_ prod? private-key public-key graph-uuid]
|
|
|
+ (<set-env [_ graph-uuid prod? private-key public-key]
|
|
|
(when (not-empty private-key)
|
|
|
(print (util/format "[%s] setting sync age-encryption passphrase..." graph-uuid)))
|
|
|
(set! graph-uuid' graph-uuid)
|
|
|
(set! private-key' private-key)
|
|
|
(set! public-key' public-key)
|
|
|
- (p->c (ipc/ipc "set-env" (if prod? "prod" "dev") private-key public-key)))
|
|
|
+ (p->c (ipc/ipc "set-env" graph-uuid (if prod? "prod" "dev") private-key public-key)))
|
|
|
(<get-local-all-files-meta [_ graph-uuid base-path]
|
|
|
(go
|
|
|
(let [r (<! (<retry-rsapi #(p->c (ipc/ipc "get-local-all-files-meta" graph-uuid base-path))))]
|
|
@@ -781,9 +781,9 @@
|
|
|
(<!
|
|
|
(<retry-rsapi
|
|
|
#(p->c (ipc/ipc "delete-remote-files" graph-uuid base-path filepaths local-txid token)))))))
|
|
|
- (<encrypt-fnames [_ fnames] (go (js->clj (<! (p->c (ipc/ipc "encrypt-fnames" fnames))))))
|
|
|
- (<decrypt-fnames [_ fnames] (go
|
|
|
- (let [r (<! (p->c (ipc/ipc "decrypt-fnames" fnames)))]
|
|
|
+ (<encrypt-fnames [_ graph-uuid fnames] (go (js->clj (<! (p->c (ipc/ipc "encrypt-fnames" graph-uuid fnames))))))
|
|
|
+ (<decrypt-fnames [_ graph-uuid fnames] (go
|
|
|
+ (let [r (<! (p->c (ipc/ipc "decrypt-fnames" graph-uuid fnames)))]
|
|
|
(if (instance? ExceptionInfo r)
|
|
|
(ex-info "decrypt-failed" {:fnames fnames} (ex-cause r))
|
|
|
(js->clj r))))))
|
|
@@ -806,7 +806,7 @@
|
|
|
(go (let [r (<! (p->c (.keygen mobile-util/file-sync #js {})))]
|
|
|
(-> r
|
|
|
(js->clj :keywordize-keys true)))))
|
|
|
- (<set-env [_ prod? secret-key public-key graph-uuid]
|
|
|
+ (<set-env [_ graph-uuid prod? secret-key public-key]
|
|
|
(set! graph-uuid' graph-uuid)
|
|
|
(set! private-key secret-key)
|
|
|
(set! public-key' public-key)
|
|
@@ -899,14 +899,14 @@
|
|
|
r
|
|
|
(get (js->clj r) "txid")))))
|
|
|
|
|
|
- (<encrypt-fnames [_ fnames]
|
|
|
+ (<encrypt-fnames [_ _graph-uuid fnames]
|
|
|
(go
|
|
|
(let [r (<! (p->c (.encryptFnames mobile-util/file-sync
|
|
|
(clj->js {:filePaths fnames}))))]
|
|
|
(if (instance? ExceptionInfo r)
|
|
|
(.-cause r)
|
|
|
(get (js->clj r) "value")))))
|
|
|
- (<decrypt-fnames [_ fnames]
|
|
|
+ (<decrypt-fnames [_ _graph-uuid fnames]
|
|
|
(go (let [r (<! (p->c (.decryptFnames mobile-util/file-sync
|
|
|
(clj->js {:filePaths fnames}))))]
|
|
|
(if (instance? ExceptionInfo r)
|
|
@@ -1107,7 +1107,7 @@
|
|
|
exp-r
|
|
|
(let [file-meta-list* (persistent! file-meta-list)
|
|
|
encrypted-path-list* (persistent! encrypted-path-list)
|
|
|
- path-list-or-exp (<! (<decrypt-fnames rsapi encrypted-path-list*))]
|
|
|
+ path-list-or-exp (<! (<decrypt-fnames rsapi graph-uuid encrypted-path-list*))]
|
|
|
(if (instance? ExceptionInfo path-list-or-exp)
|
|
|
path-list-or-exp
|
|
|
(let [encrypted-path->path-map (zipmap encrypted-path-list* path-list-or-exp)]
|
|
@@ -1124,12 +1124,12 @@
|
|
|
(<get-remote-files-meta [this graph-uuid filepaths]
|
|
|
{:pre [(coll? filepaths)]}
|
|
|
(go
|
|
|
- (let [encrypted-paths* (<! (<encrypt-fnames rsapi filepaths))
|
|
|
+ (let [encrypted-paths* (<! (<encrypt-fnames rsapi graph-uuid filepaths))
|
|
|
r (<! (.<request this "get_files_meta" {:GraphUUID graph-uuid :Files encrypted-paths*}))]
|
|
|
(if (instance? ExceptionInfo r)
|
|
|
r
|
|
|
(let [encrypted-paths (mapv :FilePath r)
|
|
|
- paths-or-exp (<! (<decrypt-fnames rsapi encrypted-paths))]
|
|
|
+ paths-or-exp (<! (<decrypt-fnames rsapi graph-uuid encrypted-paths))]
|
|
|
(if (instance? ExceptionInfo paths-or-exp)
|
|
|
paths-or-exp
|
|
|
(let [encrypted-path->path-map (zipmap encrypted-paths paths-or-exp)]
|
|
@@ -1152,7 +1152,7 @@
|
|
|
|
|
|
(<get-remote-file-versions [this graph-uuid filepath]
|
|
|
(go
|
|
|
- (let [encrypted-path (first (<! (<encrypt-fnames rsapi [filepath])))]
|
|
|
+ (let [encrypted-path (first (<! (<encrypt-fnames rsapi graph-uuid [filepath])))]
|
|
|
(<! (.<request this "get_file_version_list" {:GraphUUID graph-uuid :File encrypted-path})))))
|
|
|
|
|
|
(<list-remote-graphs [this]
|
|
@@ -1168,7 +1168,7 @@
|
|
|
encrypted-path->path-map
|
|
|
(zipmap
|
|
|
encrypted-paths
|
|
|
- (<! (<decrypt-fnames rsapi encrypted-paths)))
|
|
|
+ (<! (<decrypt-fnames rsapi graph-uuid encrypted-paths)))
|
|
|
txns
|
|
|
(mapv
|
|
|
(fn [txn] (update txn :path #(get encrypted-path->path-map %)))
|
|
@@ -1205,7 +1205,7 @@
|
|
|
encrypted-path->path-map
|
|
|
(zipmap
|
|
|
encrypted-paths
|
|
|
- (<! (<decrypt-fnames rsapi encrypted-paths)))
|
|
|
+ (<! (<decrypt-fnames rsapi graph-uuid encrypted-paths)))
|
|
|
txns
|
|
|
(mapv
|
|
|
(fn [txn]
|
|
@@ -1334,11 +1334,11 @@
|
|
|
[@graphs-txid local-txid remote-txid])))))
|
|
|
|
|
|
(defn- get-local-files-checksum
|
|
|
- [base-path relative-paths]
|
|
|
+ [graph-uuid base-path relative-paths]
|
|
|
(go
|
|
|
(into {}
|
|
|
(map (juxt #(.-path ^FileMetadata %) #(.-etag ^FileMetadata %)))
|
|
|
- (<! (<get-local-files-meta rsapi "" base-path relative-paths)))))
|
|
|
+ (<! (<get-local-files-meta rsapi graph-uuid base-path relative-paths)))))
|
|
|
|
|
|
(declare sync-state--add-current-local->remote-files
|
|
|
sync-state--add-current-remote->local-files
|
|
@@ -1406,7 +1406,8 @@
|
|
|
(remove nil?))]
|
|
|
|
|
|
(doseq [relative-p (map relative-path filetxns)]
|
|
|
- (when-some [relative-p* (<! (<case-different-local-file-exist? rsapi base-path relative-p))]
|
|
|
+ (when-some [relative-p*
|
|
|
+ (<! (<case-different-local-file-exist? graph-uuid rsapi base-path relative-p))]
|
|
|
(let [recent-remote->local-file-item {:remote->local-type :delete
|
|
|
:checksum nil
|
|
|
:path relative-p*}]
|
|
@@ -1433,7 +1434,7 @@
|
|
|
(.-deleted? (first filetxns))
|
|
|
(let [filetxn (first filetxns)]
|
|
|
(assert (= 1 (count filetxns)))
|
|
|
- (if (<! (<local-file-not-exist? rsapi base-path (relative-path filetxn)))
|
|
|
+ (if (<! (<local-file-not-exist? graph-uuid rsapi base-path (relative-path filetxn)))
|
|
|
;; not exist, ignore
|
|
|
true
|
|
|
(let [r (<! (<delete-local-files rsapi graph-uuid base-path [(relative-path filetxn)]))]
|
|
@@ -1547,7 +1548,7 @@
|
|
|
|
|
|
|
|
|
(defn- <file-change-event=>recent-remote->local-file-item
|
|
|
- [^FileChangeEvent e]
|
|
|
+ [graph-uuid ^FileChangeEvent e]
|
|
|
(go
|
|
|
(let [tp (case (.-type e)
|
|
|
("add" "change") :update
|
|
@@ -1555,7 +1556,7 @@
|
|
|
path (relative-path e)]
|
|
|
{:remote->local-type tp
|
|
|
:checksum (if (= tp :delete) nil
|
|
|
- (val (first (<! (get-local-files-checksum (.-dir e) [path])))))
|
|
|
+ (val (first (<! (get-local-files-checksum graph-uuid (.-dir e) [path])))))
|
|
|
:path path})))
|
|
|
|
|
|
(defn- distinct-file-change-events-xf
|
|
@@ -1590,6 +1591,7 @@
|
|
|
(map #(partition-all n %))
|
|
|
cat))
|
|
|
|
|
|
+(declare sync-state--valid-to-accept-filewatcher-event?)
|
|
|
(defonce local-changes-chan (chan (async/dropping-buffer 1000)))
|
|
|
(defn file-watch-handler
|
|
|
"file-watcher callback"
|
|
@@ -1597,12 +1599,13 @@
|
|
|
(when-let [current-graph (state/get-current-repo)]
|
|
|
(when (string/ends-with? current-graph dir)
|
|
|
(let [sync-state (state/get-file-sync-state current-graph)]
|
|
|
- (when (and sync-state (not (sync-state--stopped? sync-state)))
|
|
|
+ (when (and sync-state (sync-state--valid-to-accept-filewatcher-event? sync-state))
|
|
|
(when (or (:mtime stat) (= type "unlink"))
|
|
|
(go
|
|
|
(let [path (remove-dir-prefix dir path)
|
|
|
files-meta (and (not= "unlink" type)
|
|
|
- (<! (<get-local-files-meta rsapi "" dir [path])))
|
|
|
+ (<! (<get-local-files-meta
|
|
|
+ rsapi (:current-syncing-graph-uuid sync-state) dir [path])))
|
|
|
checksum (and (coll? files-meta) (some-> files-meta first :etag))]
|
|
|
(>! local-changes-chan (->FileChangeEvent type dir path stat checksum))))))))))
|
|
|
|
|
@@ -1853,7 +1856,7 @@
|
|
|
(let [{:keys [private-key public-key]} (get @pwd-map graph-uuid)]
|
|
|
(assert (and private-key public-key) (pr-str :private-key private-key :public-key public-key
|
|
|
:pwd-map @pwd-map))
|
|
|
- (<set-env rsapi prod? private-key public-key graph-uuid)))
|
|
|
+ (<set-env rsapi graph-uuid prod? private-key public-key)))
|
|
|
|
|
|
(defn- <ensure-set-env&keys
|
|
|
[graph-uuid *stopped?]
|
|
@@ -2037,6 +2040,13 @@
|
|
|
{:pre [(s/valid? ::sync-state sync-state)]}
|
|
|
(= ::stop (:state sync-state)))
|
|
|
|
|
|
+(defn sync-state--valid-to-accept-filewatcher-event?
|
|
|
+ [sync-state]
|
|
|
+ {:pre [(s/valid? ::sync-state sync-state)]}
|
|
|
+ (contains? #{::idle ::local->remote ::remote->local ::local->remote-full-sync ::remote->local-full-sync}
|
|
|
+ (:state sync-state)))
|
|
|
+
|
|
|
+
|
|
|
;;; ### remote->local syncer & local->remote syncer
|
|
|
|
|
|
(defprotocol IRemote->LocalSync
|
|
@@ -2159,18 +2169,18 @@
|
|
|
(case (.-type e)
|
|
|
"unlink"
|
|
|
;; keep this e when it's not found
|
|
|
- (<! (<local-file-not-exist? rsapi basepath r-path))
|
|
|
+ (<! (<local-file-not-exist? graph-uuid rsapi basepath r-path))
|
|
|
|
|
|
("add" "change")
|
|
|
;; 1. local file exists
|
|
|
;; 2. compare with remote file, and changed
|
|
|
- (and (not (<! (<local-file-not-exist? rsapi basepath r-path)))
|
|
|
+ (and (not (<! (<local-file-not-exist? graph-uuid rsapi basepath r-path)))
|
|
|
(<! (<file-changed? graph-uuid r-path basepath)))))))
|
|
|
|
|
|
(defn- <filter-checksum-not-consistent
|
|
|
"filter out FileChangeEvents checksum changed,
|
|
|
compare checksum in FileChangeEvent and checksum calculated now"
|
|
|
- [es]
|
|
|
+ [graph-uuid es]
|
|
|
{:pre [(or (nil? es) (coll? es))
|
|
|
(every? #(instance? FileChangeEvent %) es)]}
|
|
|
(go
|
|
@@ -2178,7 +2188,8 @@
|
|
|
(if (= "unlink" (.-type ^FileChangeEvent (first es)))
|
|
|
es
|
|
|
(let [base-path (.-dir (first es))
|
|
|
- files-meta (<! (<get-local-files-meta rsapi "" base-path (mapv relative-path es)))
|
|
|
+ files-meta (<! (<get-local-files-meta
|
|
|
+ rsapi graph-uuid base-path (mapv relative-path es)))
|
|
|
current-checksum-map (when (coll? files-meta) (into {} (mapv (juxt :path :etag) files-meta)))
|
|
|
origin-checksum-map (into {} (mapv (juxt relative-path #(.-checksum ^FileChangeEvent %)) es))
|
|
|
origin-map (into {} (mapv (juxt relative-path identity) es))]
|
|
@@ -2243,7 +2254,8 @@
|
|
|
(not (ignored? e)) ;not ignored
|
|
|
;; download files will also trigger file-change-events, ignore them
|
|
|
(let [r (not (contains? (:recent-remote->local-files @*sync-state)
|
|
|
- (<! (<file-change-event=>recent-remote->local-file-item e))))]
|
|
|
+ (<! (<file-change-event=>recent-remote->local-file-item
|
|
|
+ graph-uuid e))))]
|
|
|
(when (and (true? r)
|
|
|
(seq (:recent-remote->local-files @*sync-state)))
|
|
|
(println :debug (:recent-remote->local-files @*sync-state) e))
|
|
@@ -2291,7 +2303,7 @@
|
|
|
(map #(relative-path %))
|
|
|
(remove ignored?))]
|
|
|
(go
|
|
|
- (let [es* (<! (<filter-checksum-not-consistent es))
|
|
|
+ (let [es* (<! (<filter-checksum-not-consistent graph-uuid es))
|
|
|
_ (when (not= (count es*) (count es))
|
|
|
(println :debug :filter-checksum-changed
|
|
|
(mapv relative-path (set/difference (set es) (set es*)))))
|
|
@@ -2385,7 +2397,7 @@
|
|
|
(loop [[f & fs] delete-local-files]
|
|
|
(when f
|
|
|
(let [relative-p (relative-path f)]
|
|
|
- (when-not (<! (<local-file-not-exist? rsapi base-path relative-p))
|
|
|
+ (when-not (<! (<local-file-not-exist? graph-uuid rsapi base-path relative-p))
|
|
|
(let [fake-recent-remote->local-file-item {:remote->local-type :delete
|
|
|
:checksum nil
|
|
|
:path relative-p}]
|