all lists on lists.proxmox.com
 help / color / mirror / Atom feed
* [pbs-devel] [RFC PATCH proxmox-backup 1/5] api2/admin/datastore: refactor list_dir_content in catalog_reader
@ 2020-12-21 11:25 Dominik Csapak
  2020-12-21 11:25 ` [pbs-devel] [RFC PATCH proxmox-backup 2/5] api2/admin/datastore: accept "/" as path for root Dominik Csapak
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Dominik Csapak @ 2020-12-21 11:25 UTC (permalink / raw)
  To: pbs-devel

we will reuse that later in the client, so we need it somewhere
we can use from there

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 src/api2/admin/datastore.rs | 52 ++++-------------------------
 src/backup/catalog.rs       | 65 +++++++++++++++++++++++++++++++++++++
 2 files changed, 72 insertions(+), 45 deletions(-)

diff --git a/src/api2/admin/datastore.rs b/src/api2/admin/datastore.rs
index 16fee943..5f06a2bf 100644
--- a/src/api2/admin/datastore.rs
+++ b/src/api2/admin/datastore.rs
@@ -1302,7 +1302,7 @@ fn catalog(
     _param: Value,
     _info: &ApiMethod,
     rpcenv: &mut dyn RpcEnvironment,
-) -> Result<Value, Error> {
+) -> Result<Vec<Value>, Error> {
     let datastore = DataStore::lookup_datastore(&store)?;
 
     let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
@@ -1334,52 +1334,14 @@ fn catalog(
     let reader = BufferedDynamicReader::new(index, chunk_reader);
 
     let mut catalog_reader = CatalogReader::new(reader);
-    let mut current = catalog_reader.root()?;
-    let mut components = vec![];
-
 
-    if filepath != "root" {
-        components = base64::decode(filepath)?;
-        if components.len() > 0 && components[0] == '/' as u8 {
-            components.remove(0);
-        }
-        for component in components.split(|c| *c == '/' as u8) {
-            if let Some(entry) = catalog_reader.lookup(&current, component)? {
-                current = entry;
-            } else {
-                bail!("path {:?} not found in catalog", &String::from_utf8_lossy(&components));
-            }
-        }
-    }
-
-    let mut res = Vec::new();
-
-    for direntry in catalog_reader.read_dir(&current)? {
-        let mut components = components.clone();
-        components.push('/' as u8);
-        components.extend(&direntry.name);
-        let path = base64::encode(components);
-        let text = String::from_utf8_lossy(&direntry.name);
-        let mut entry = json!({
-            "filepath": path,
-            "text": text,
-            "type": CatalogEntryType::from(&direntry.attr).to_string(),
-            "leaf": true,
-        });
-        match direntry.attr {
-            DirEntryAttribute::Directory { start: _ } => {
-                entry["leaf"] = false.into();
-            },
-            DirEntryAttribute::File { size, mtime } => {
-                entry["size"] = size.into();
-                entry["mtime"] = mtime.into();
-            },
-            _ => {},
-        }
-        res.push(entry);
-    }
+    let path = if filepath != "root" {
+        base64::decode(filepath)?
+    } else {
+        vec![b'/']
+    };
 
-    Ok(res.into())
+    catalog_reader.list_dir_content(&path)
 }
 
 fn recurse_files<'a, T, W>(
diff --git a/src/backup/catalog.rs b/src/backup/catalog.rs
index b500fb93..5f8e85a6 100644
--- a/src/backup/catalog.rs
+++ b/src/backup/catalog.rs
@@ -5,6 +5,7 @@ use std::io::{Read, Write, Seek, SeekFrom};
 use std::os::unix::ffi::OsStrExt;
 
 use anyhow::{bail, format_err, Error};
+use serde_json::{json, Value};
 
 use pathpatterns::{MatchList, MatchType};
 use proxmox::tools::io::ReadExt;
@@ -474,6 +475,32 @@ impl <R: Read + Seek> CatalogReader<R> {
         Ok(entry_list)
     }
 
+    /// Lookup a DirEntry from an absolute path
+    pub fn lookup_recursive(
+        &mut self,
+        path: &[u8],
+    ) -> Result<DirEntry, Error> {
+        let mut current = self.root()?;
+        if path == b"/" {
+            return Ok(current);
+        }
+
+        let components = if path.len() > 0 && path[0] == b'/' {
+            &path[1..]
+        } else {
+            path
+        }.split(|c| *c == b'/');
+
+        for comp in components {
+            if let Some(entry) = self.lookup(&current, comp)? {
+                current = entry;
+            } else {
+                bail!("path {:?} not found in catalog", String::from_utf8_lossy(&path));
+            }
+        }
+        Ok(current)
+    }
+
     /// Lockup a DirEntry inside a parent directory
     pub fn lookup(
         &mut self,
@@ -554,6 +581,44 @@ impl <R: Read + Seek> CatalogReader<R> {
         })
     }
 
+    /// Returns the list of content of the given path as json
+    pub fn list_dir_content(&mut self, path: &[u8]) -> Result<Vec<Value>, Error> {
+        let dir = self.lookup_recursive(path)?;
+        let mut res = vec![];
+        let mut path = path.to_vec();
+        if path.len() > 0 && path[0] == b'/' {
+            path.remove(0);
+        }
+
+        for direntry in self.read_dir(&dir)? {
+            let mut components = path.clone();
+            components.push(b'/');
+            components.extend(&direntry.name);
+            let path = base64::encode(&components);
+            let text = String::from_utf8_lossy(&direntry.name);
+            let mut entry = json!({
+                "filepath": path,
+                "text": text,
+                "name": direntry.name.clone(),
+                "type": CatalogEntryType::from(&direntry.attr).to_string(),
+                "leaf": true,
+            });
+            match direntry.attr {
+                DirEntryAttribute::Directory { start: _ } => {
+                    entry["leaf"] = false.into();
+                },
+                DirEntryAttribute::File { size, mtime } => {
+                    entry["size"] = size.into();
+                    entry["mtime"] = mtime.into();
+                },
+                _ => {},
+            }
+            res.push(entry);
+        }
+
+        Ok(res)
+    }
+
     /// Finds all entries matching the given match patterns and calls the
     /// provided callback on them.
     pub fn find(
-- 
2.20.1





^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2020-12-22  7:52 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-21 11:25 [pbs-devel] [RFC PATCH proxmox-backup 1/5] api2/admin/datastore: refactor list_dir_content in catalog_reader Dominik Csapak
2020-12-21 11:25 ` [pbs-devel] [RFC PATCH proxmox-backup 2/5] api2/admin/datastore: accept "/" as path for root Dominik Csapak
2020-12-21 11:25 ` [pbs-devel] [RFC PATCH proxmox-backup 3/5] api2/admin/datastore: refactor create_zip into pxar/extract Dominik Csapak
2020-12-21 11:25 ` [pbs-devel] [RFC PATCH proxmox-backup 4/5] pxar/extract: add extract_sub_dir Dominik Csapak
2020-12-21 11:25 ` [pbs-devel] [RFC PATCH 5/5] proxmox-backup-client: add file-restore commands Dominik Csapak
2020-12-21 11:43   ` Dominik Csapak
2020-12-22  5:49 ` [pbs-devel] [RFC PATCH proxmox-backup 1/5] api2/admin/datastore: refactor list_dir_content in catalog_reader Dietmar Maurer
2020-12-22  7:52   ` Dominik Csapak

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal