upend/src/dataops.rs

112 lines
2.8 KiB
Rust

use crate::models::NewFile;
use anyhow::Result;
use filebuffer::FileBuffer;
use log::info;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};
use tiny_keccak::{Hasher, KangarooTwelve};
use walkdir::WalkDir;
use actix::prelude::*;
// use rayon::prelude::*;
// pub struct VaultUpdater(
// pub Addr<crate::database::DbExecutor>,
// pub Addr<HasherWorker>,
// );
// impl Actor for VaultUpdater {
// type Context = Context<Self>;
// }
// struct UpdateDirectory<'a> {
// path: &'a Path,
// }
// impl Message for UpdateDirectory<'_> {
// type Result = Result<(), Box<dyn error::Error>>;
// }
// impl Handler<UpdateDirectory<'_>> for VaultUpdater {
// type Result = Result<(), Box<dyn error::Error>>;
// fn handle(&mut self, msg: UpdateDirectory, _: &mut Self::Context) -> Self::Result {
// update_directory(msg.path, &self.0, &self.1).await
// }
// }
pub async fn update_directory<T: AsRef<Path>>(
directory: T,
db_executor: &Addr<crate::database::DbExecutor>,
hasher_worker: &Addr<HasherWorker>,
) -> Result<()> {
for entry in WalkDir::new(&directory)
.into_iter()
.filter_map(|e| e.ok())
.filter(|e| e.path().is_file())
{
info!("Processing: {}", entry.path().display());
let metadata = fs::metadata(entry.path())?;
let size = metadata.len() as i64;
if size < 0 {
panic!("File {} too large?!", entry.path().display());
}
let msg = ComputeHash {
path: entry.path().to_path_buf(),
};
let digest = hasher_worker.send(msg).await;
let new_file = NewFile {
path: entry
.path()
.to_str()
.expect("path not valid unicode?!")
.to_string(),
hash: digest.unwrap().unwrap(),
size: size,
};
let _insert_result = db_executor
.send(crate::database::InsertFile { file: new_file })
.await?;
}
info!("Finished updating {}.", directory.as_ref().display());
Ok(())
}
pub struct HasherWorker;
impl Actor for HasherWorker {
type Context = SyncContext<Self>;
}
#[derive(Message)]
#[rtype(result = "Result<String, io::Error>")]
struct ComputeHash {
path: PathBuf,
}
impl Handler<ComputeHash> for HasherWorker {
type Result = Result<String, io::Error>;
fn handle(&mut self, msg: ComputeHash, _: &mut Self::Context) -> Self::Result {
compute_digest(msg.path)
}
}
pub fn compute_digest<P: AsRef<Path>>(filepath: P) -> Result<String, io::Error> {
let fbuffer = FileBuffer::open(&filepath)?;
let mut k12 = KangarooTwelve::new(b"");
k12.update(&fbuffer);
let mut result = [0u8; 256 / 8];
k12.finalize(&mut result);
Ok(bs58::encode(&result).into_string())
}