Просмотр исходного кода

bin/darkwikid: add support for deleting files

ghassmo 4 лет назад
Родитель
Сommit
91f6ce0f8f
1 измененных файлов с 68 добавлено и 11 удалено
  1. 68 11
      bin/darkwikid/src/main.rs

+ 68 - 11
bin/darkwikid/src/main.rs

@@ -1,6 +1,6 @@
 use async_std::sync::{Arc, Mutex};
 use std::{
-    fs::{create_dir_all, read_dir},
+    fs::{create_dir_all, read_dir, remove_file},
     path::{Path, PathBuf},
 };
 
@@ -138,6 +138,20 @@ fn get_docs_paths(files: &mut Vec<PathBuf>, path: &Path, parent: Option<&Path>)
     Ok(())
 }
 
+fn is_delete_patch(patch: &Patch) -> bool {
+    if patch.ops().0.len() != 1 {
+        return false
+    }
+
+    if let OpMethod::Delete(d) = patch.ops().0[0] {
+        if patch.base.len() as u64 == d {
+            return true
+        }
+    }
+
+    return false
+}
+
 struct Darkwiki {
     settings: DarkWikiSettings,
     rpc: (
@@ -246,7 +260,6 @@ impl Darkwiki {
         let local_files = read_dir(&local_path)?;
         for file in local_files {
             let file_id = file?.file_name();
-            let file_id = file_id.to_str().unwrap();
             let file_path = local_path.join(&file_id);
             let local_patch: Patch = load_json_file(&file_path)?;
 
@@ -330,15 +343,20 @@ impl Darkwiki {
 
                 // check if the same doc has received patch from the network
                 if let Ok(sync_patch) = load_json_file::<Patch>(&sync_path.join(&doc_id)) {
-                    if sync_patch.timestamp != local_patch.timestamp {
-                        sync_patches.push(sync_patch.clone());
-
-                        let sync_patch_t = new_patch.transform(&sync_patch);
-                        new_patch = new_patch.merge(&sync_patch_t);
-                        if !dry {
-                            self.save_doc(doc_path, &new_patch.to_string())?;
+                    if !is_delete_patch(&sync_patch) {
+                        if sync_patch.timestamp != local_patch.timestamp {
+                            sync_patches.push(sync_patch.clone());
+
+                            let sync_patch_t = new_patch.transform(&sync_patch);
+                            new_patch = new_patch.merge(&sync_patch_t);
+                            if !dry {
+                                self.save_doc(doc_path, &new_patch.to_string())?;
+                            }
+                            merge_patches.push(new_patch.clone());
                         }
-                        merge_patches.push(new_patch.clone());
+                    } else {
+                        merge_patches.push(sync_patch);
+                        patches = vec![];
                     }
                 }
             } else {
@@ -358,10 +376,23 @@ impl Darkwiki {
         let sync_files = read_dir(&sync_path)?;
         for file in sync_files {
             let file_id = file?.file_name();
-            let file_id = file_id.to_str().unwrap();
             let file_path = sync_path.join(&file_id);
             let sync_patch: Patch = load_json_file(&file_path)?;
 
+            if is_delete_patch(&sync_patch) {
+                if local_path.join(&sync_patch.id).exists() {
+                    sync_patches.push(sync_patch.clone());
+                }
+
+                if !dry {
+                    remove_file(docs_path.join(&sync_patch.path)).unwrap_or(());
+                    remove_file(local_path.join(&sync_patch.id)).unwrap_or(());
+                    remove_file(file_path).unwrap_or(());
+                }
+
+                continue
+            }
+
             if let Ok(local_patch) = load_json_file::<Patch>(&local_path.join(&file_id)) {
                 if local_patch.timestamp == sync_patch.timestamp {
                     continue
@@ -382,6 +413,32 @@ impl Darkwiki {
             }
         }
 
+        // check if any doc remove from ~/darkwiki
+        let local_files = read_dir(&local_path)?;
+        for file in local_files {
+            let file_id = file?.file_name();
+            let file_path = local_path.join(&file_id);
+            let local_patch: Patch = load_json_file(&file_path)?;
+
+            if !files_name.is_empty() && !files_name.contains(&local_patch.path.to_string()) {
+                continue
+            }
+
+            if !docs_path.join(&local_patch.path).exists() {
+                let mut new_patch =
+                    Patch::new(&local_patch.path, &local_patch.id, &self.settings.author);
+                new_patch.add_op(&OpMethod::Delete(local_patch.to_string().len() as u64));
+                patches.push(new_patch.clone());
+
+                new_patch.base = local_patch.base;
+                local_patches.push(new_patch);
+
+                if !dry {
+                    remove_file(file_path).unwrap_or(());
+                }
+            }
+        }
+
         Ok((patches, local_patches, sync_patches, merge_patches))
     }