mirror of
https://github.com/Drop-OSS/droplet.git
synced 2025-11-17 02:01:19 +10:00
new manifest generation with checksums for Drop
This commit is contained in:
@ -1,25 +1,83 @@
|
||||
use std::{collections::HashMap, fs::File, path::Path};
|
||||
use std::{
|
||||
fs::File,
|
||||
io::{BufRead, BufReader},
|
||||
path::Path,
|
||||
};
|
||||
|
||||
use ciborium::into_writer;
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
pub struct ManifestChunk {
|
||||
pub uuid: String,
|
||||
pub index: i64,
|
||||
use gxhash::gxhash128;
|
||||
use napi::Error;
|
||||
use serde::Serialize;
|
||||
use serde_json::json;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::file_utils::list_files;
|
||||
|
||||
const CHUNK_SIZE: usize = 1024 * 1024 * 16;
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct Chunk {
|
||||
id: String,
|
||||
permissions: u32,
|
||||
file_name: String,
|
||||
chunk_index: u32,
|
||||
checksum: String,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
pub struct ManifestRecord {
|
||||
pub chunks: Vec<ManifestChunk>,
|
||||
pub permissions: u32,
|
||||
}
|
||||
#[napi]
|
||||
pub fn generate_manifest(dir: String) -> Result<String, Error> {
|
||||
let base_dir = Path::new(&dir);
|
||||
let files = list_files(base_dir);
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
pub struct Manifest {
|
||||
pub record: HashMap<String, ManifestRecord>,
|
||||
}
|
||||
let mut chunks: Vec<Chunk> = Vec::new();
|
||||
|
||||
pub fn generate_manifest(manifest: Manifest, path: &Path) {
|
||||
let file = File::create(path).unwrap();
|
||||
into_writer(&manifest, file).unwrap();
|
||||
for file_path in files {
|
||||
let file = File::open(file_path.clone()).unwrap();
|
||||
let relative = file_path.strip_prefix(base_dir).unwrap();
|
||||
let permission_object = file.try_clone().unwrap().metadata().unwrap().permissions();
|
||||
let permissions = {
|
||||
let mut perm = 0;
|
||||
#[cfg(unix)]
|
||||
{
|
||||
perm = permission_object.mode();
|
||||
}
|
||||
perm
|
||||
};
|
||||
|
||||
let mut reader = BufReader::with_capacity(CHUNK_SIZE, file);
|
||||
|
||||
let mut chunk_index = 0;
|
||||
loop {
|
||||
let mut buffer: Vec<u8> = Vec::new();
|
||||
reader.fill_buf().unwrap().clone_into(&mut buffer);
|
||||
let length = buffer.len();
|
||||
|
||||
if length == 0 {
|
||||
break;
|
||||
}
|
||||
|
||||
let chunk_id = Uuid::new_v4();
|
||||
let checksum = gxhash128(&buffer, 0);
|
||||
let checksum_string = hex::encode(checksum.to_le_bytes());
|
||||
|
||||
let chunk = Chunk {
|
||||
id: chunk_id.to_string(),
|
||||
chunk_index: chunk_index,
|
||||
permissions: permissions,
|
||||
file_name: relative.to_str().unwrap().to_string(),
|
||||
checksum: checksum_string,
|
||||
};
|
||||
|
||||
chunks.push(chunk);
|
||||
|
||||
println!("Processed chunk {} for {}", chunk_index, relative.to_str().unwrap());
|
||||
reader.consume(length);
|
||||
chunk_index += 1;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Ok(json!(chunks).to_string())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user