From d7f9faf602a5cae66acb9a39114a55199532c15d Mon Sep 17 00:00:00 2001 From: DecDuck Date: Thu, 18 Dec 2025 17:36:47 +1100 Subject: [PATCH] feat: new 7z output parser --- libraries/droplet/Cargo.lock | 2 +- libraries/droplet/Cargo.toml | 4 +- libraries/droplet/src/lib.rs | 5 +- libraries/droplet/src/manifest.rs | 2 + libraries/droplet/src/tests.rs | 11 ++++ libraries/droplet/src/versions/backends.rs | 62 ++++++++++++---------- libraries/droplet/test.txt | 1 + 7 files changed, 54 insertions(+), 33 deletions(-) create mode 100644 libraries/droplet/src/tests.rs create mode 100644 libraries/droplet/test.txt diff --git a/libraries/droplet/Cargo.lock b/libraries/droplet/Cargo.lock index 99753d69..a5da8f87 100644 --- a/libraries/droplet/Cargo.lock +++ b/libraries/droplet/Cargo.lock @@ -219,7 +219,7 @@ dependencies = [ [[package]] name = "droplet-rs" -version = "0.11.1" +version = "0.11.2" dependencies = [ "anyhow", "async-trait", diff --git a/libraries/droplet/Cargo.toml b/libraries/droplet/Cargo.toml index f2141354..76f06cc4 100644 --- a/libraries/droplet/Cargo.toml +++ b/libraries/droplet/Cargo.toml @@ -2,7 +2,7 @@ edition = "2021" authors = ["Drop-OSS"] name = "droplet-rs" -version = "0.11.1" +version = "0.11.2" license = "AGPL-3.0-only" description = "Droplet is a `napi.rs` Rust/Node.js package full of high-performance and low-level utils for Drop" @@ -11,7 +11,7 @@ hex = "0.4.3" time = "0.3.41" ring = "0.17.14" dyn-clone = "1.0.20" -tokio = { version = "^1.48.0", features = ["process", "fs", "io-util", "sync", "macros", "rt-multi-thread"] } +tokio = { version = "^1.48.0", features = ["process", "fs", "io-util", "rt", "rt-multi-thread", "macros", "sync"] } anyhow = "1.0.100" async-trait = "0.1.89" serde = { version = "1.0.228", features = ["derive"] } diff --git a/libraries/droplet/src/lib.rs b/libraries/droplet/src/lib.rs index 4a873503..6781cc7a 100644 --- a/libraries/droplet/src/lib.rs +++ b/libraries/droplet/src/lib.rs @@ -4,4 +4,7 @@ pub mod file_utils; pub mod ssl; pub mod versions; -pub mod manifest; \ No newline at end of file +pub mod manifest; + +#[cfg(test)] +pub mod tests; diff --git a/libraries/droplet/src/manifest.rs b/libraries/droplet/src/manifest.rs index 47e515c4..7b0b015a 100644 --- a/libraries/droplet/src/manifest.rs +++ b/libraries/droplet/src/manifest.rs @@ -29,6 +29,7 @@ pub struct FileEntry { pub struct ChunkData { files: Vec, checksum: String, + //iv: [u8; 16] } #[derive(Serialize)] @@ -155,6 +156,7 @@ pub async fn generate_manifest_rusty( let mut chunk_data = ChunkData { files: Vec::new(), checksum: String::new(), + //iv: }; let mut chunk_length = 0; diff --git a/libraries/droplet/src/tests.rs b/libraries/droplet/src/tests.rs new file mode 100644 index 00000000..99edf35b --- /dev/null +++ b/libraries/droplet/src/tests.rs @@ -0,0 +1,11 @@ +use std::path::PathBuf; + +use crate::versions::create_backend_constructor; + +#[tokio::test] +pub async fn test_7z_list() { + let zip_path = "/home/decduck/Dev/droplet/assets/TheGame.zip"; + let mut backend = create_backend_constructor(&PathBuf::from(zip_path)).unwrap()().unwrap(); + let files = backend.list_files().await.unwrap(); + tokio::fs::write("./test.txt", format!("{:?}", files)).await.unwrap(); +} diff --git a/libraries/droplet/src/versions/backends.rs b/libraries/droplet/src/versions/backends.rs index 1eb1b825..6ca9c23c 100644 --- a/libraries/droplet/src/versions/backends.rs +++ b/libraries/droplet/src/versions/backends.rs @@ -15,6 +15,7 @@ use tokio::{ io::{AsyncReadExt as _, AsyncSeekExt as _, BufReader}, process::Command, }; +use x509_parser::nom::InputIter; use crate::versions::types::{MinimumFileObject, VersionBackend, VersionFile}; @@ -148,7 +149,7 @@ impl ZipVersionBackend { impl VersionBackend for ZipVersionBackend { async fn list_files(&mut self) -> anyhow::Result> { let mut list_command = Command::new("7z"); - list_command.args(vec!["l", "-ba", &self.path]); + list_command.args(vec!["l", &self.path]); let result = list_command.output().await?; if !result.status.success() { return Err(anyhow!( @@ -157,35 +158,38 @@ impl VersionBackend for ZipVersionBackend { )); } let raw_result = String::from_utf8(result.stdout)?; - let files = raw_result - .split("\n") - .filter(|v| !v.is_empty()) - .map(|v| v.split(" ").filter(|v| !v.is_empty())); - let mut results = Vec::new(); + let mut lines = raw_result.split("\n").skip(11); - for file in files { - let values = file.collect::>(); - let mut iter = values.iter(); - let (date, time, attrs, size, compress, name) = ( - iter.next().expect("failed to read date"), - iter.next().expect("failed to read time"), - iter.next().expect("failed to read attrs"), - iter.next().expect("failed to read size"), - iter.next().expect("failed to read compress"), - iter.collect::>(), - ); - if attrs.starts_with("D") { - continue; - } - results.push(VersionFile { - relative_filename: name - .into_iter().copied() - .fold(String::new(), |a, b| a + b + " ") - .trim_end() - .to_owned(), - permission: 0o744, // owner r/w/x, everyone else, read - size: size.parse().unwrap(), - }); + let mut column_lines = lines + .find(|v| v.starts_with('-')) + .ok_or(anyhow!("invalid 7z output"))? + .chars(); + let file_lines = lines.take_while(|v| !v.starts_with("-")); + + /* + Date Time Attr Size Compressed Name + ------------------- ----- ------------ ------------ ------------------------ + */ + let datetime_pos = 0usize; + let attrs_pos = datetime_pos + column_lines.position(|v| v == ' ').unwrap() + 1; + let size_pos = attrs_pos + column_lines.position(|v| v == ' ').unwrap() + 1; + let compressed_size_pos = size_pos + column_lines.position(|v| v == ' ').unwrap() + 1; + let name_pos = compressed_size_pos + column_lines.position(|v| v == ' ').unwrap() + 1; + + let mut results = Vec::new(); + for file in file_lines { + let name = file[name_pos..].trim(); + let size = file[size_pos..compressed_size_pos].trim(); + + let size = str::parse::(size)?; + + let version_file = VersionFile { + relative_filename: name.to_string(), + permission: 0o744, + size: size, + }; + + results.push(version_file); } Ok(results) diff --git a/libraries/droplet/test.txt b/libraries/droplet/test.txt new file mode 100644 index 00000000..f250dadf --- /dev/null +++ b/libraries/droplet/test.txt @@ -0,0 +1 @@ +[VersionFile { relative_filename: "setup.exe", permission: 484, size: 1024000000 }, VersionFile { relative_filename: "test file.txt", permission: 484, size: 12 }] \ No newline at end of file