feat: new 7z output parser
This commit is contained in:
Generated
+1
-1
@@ -219,7 +219,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "droplet-rs"
|
||||
version = "0.11.1"
|
||||
version = "0.11.2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
|
||||
@@ -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"] }
|
||||
|
||||
@@ -4,4 +4,7 @@
|
||||
pub mod file_utils;
|
||||
pub mod ssl;
|
||||
pub mod versions;
|
||||
pub mod manifest;
|
||||
pub mod manifest;
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod tests;
|
||||
|
||||
@@ -29,6 +29,7 @@ pub struct FileEntry {
|
||||
pub struct ChunkData {
|
||||
files: Vec<FileEntry>,
|
||||
checksum: String,
|
||||
//iv: [u8; 16]
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
@@ -155,6 +156,7 @@ pub async fn generate_manifest_rusty<T: Fn(String), V: Fn(f32)>(
|
||||
let mut chunk_data = ChunkData {
|
||||
files: Vec::new(),
|
||||
checksum: String::new(),
|
||||
//iv:
|
||||
};
|
||||
|
||||
let mut chunk_length = 0;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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<Vec<VersionFile>> {
|
||||
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::<Vec<&str>>();
|
||||
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::<Vec<&&str>>(),
|
||||
);
|
||||
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::<u64>(size)?;
|
||||
|
||||
let version_file = VersionFile {
|
||||
relative_filename: name.to_string(),
|
||||
permission: 0o744,
|
||||
size: size,
|
||||
};
|
||||
|
||||
results.push(version_file);
|
||||
}
|
||||
|
||||
Ok(results)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
[VersionFile { relative_filename: "setup.exe", permission: 484, size: 1024000000 }, VersionFile { relative_filename: "test file.txt", permission: 484, size: 12 }]
|
||||
Reference in New Issue
Block a user