feat: can upload archives

Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
2024-02-18 01:29:46 +01:00
parent c54bbaf017
commit c3739c1bc1
16 changed files with 472 additions and 23 deletions

View File

@@ -0,0 +1,117 @@
#[derive(Clone)]
pub struct FileReader {}
use std::{collections::BTreeMap, path::PathBuf};
pub mod extensions;
use anyhow::anyhow;
#[cfg(test)]
use mockall::{automock, mock, predicate::*};
#[cfg_attr(test, automock)]
impl FileReader {
pub fn new() -> Self {
Self {}
}
pub async fn read_files(&self, location: PathBuf) -> anyhow::Result<Files> {
tracing::trace!("reading files: {}", location.display());
let mut clusters: BTreeMap<String, Vec<File>> = BTreeMap::new();
let mut dir = tokio::fs::read_dir(&location).await?;
while let Some(dir_entry) = dir.next_entry().await? {
if dir_entry.metadata().await?.is_dir() {
tracing::trace!("found cluster in: {}", dir_entry.path().display());
clusters.insert(
dir_entry
.file_name()
.into_string()
.map_err(|_| anyhow!("failed to convert file name to string"))?,
Vec::new(),
);
}
}
for (cluster_name, files) in clusters.iter_mut() {
for file in walkdir::WalkDir::new(location.join(cluster_name))
.into_iter()
.flatten()
{
if !file.file_type().is_file() {
continue;
}
tracing::trace!(
"adding file: {} to cluster: {}",
file.path().display(),
cluster_name
);
files.push(file.into_path().into())
}
}
Ok(clusters.into())
}
}
#[derive(Debug, Clone)]
pub struct File {
pub path: PathBuf,
}
impl From<PathBuf> for File {
fn from(value: PathBuf) -> Self {
Self { path: value }
}
}
#[derive(Default, Clone, Debug)]
pub struct Files {
inner: BTreeMap<String, Vec<File>>,
}
impl From<BTreeMap<String, Vec<File>>> for Files {
fn from(value: BTreeMap<String, Vec<File>>) -> Self {
Self { inner: value }
}
}
impl std::ops::Deref for Files {
type Target = BTreeMap<String, Vec<File>>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl From<Files> for Vec<File> {
fn from(value: Files) -> Self {
value
.iter()
.map(|(cluster_name, files)| (PathBuf::from(cluster_name), files))
.flat_map(|(cluster_name, files)| {
files
.iter()
//.map(|file_path| cluster_name.join(&file_path.path))
.map(|file_path| file_path.path.clone())
.collect::<Vec<_>>()
})
.map(|f| f.into())
.collect::<Vec<_>>()
}
}
impl IntoIterator for Files {
type Item = File;
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
let files: Vec<File> = self.into();
files.into_iter()
}
}