unnest archives with only one dir in it
This commit is contained in:
@@ -1,6 +1,9 @@
|
|||||||
use std::{fs, path::Path};
|
use std::{
|
||||||
|
fs,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
|
|
||||||
use anyhow::anyhow;
|
use anyhow::{Ok, anyhow};
|
||||||
use log::error;
|
use log::error;
|
||||||
use zip::ZipArchive;
|
use zip::ZipArchive;
|
||||||
|
|
||||||
@@ -29,6 +32,8 @@ pub fn unpack(archive_path: impl AsRef<Path>, extract_to: impl AsRef<Path>) -> a
|
|||||||
}
|
}
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
|
unnest_dir(extract_to)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,3 +58,47 @@ fn unpack_rar(path: impl AsRef<Path>, to: impl AsRef<Path>) -> anyhow::Result<()
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Moves a directorys content into the parent if it is the only dir
|
||||||
|
fn unnest_dir(path: impl AsRef<Path>) -> anyhow::Result<()> {
|
||||||
|
let path = path.as_ref();
|
||||||
|
|
||||||
|
let Some(nested_dir) = check_nested_dir(path) else {
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
|
||||||
|
for entry in fs::read_dir(&nested_dir)? {
|
||||||
|
let entry = entry?;
|
||||||
|
let src = entry.path();
|
||||||
|
let dest = path.join(entry.file_name());
|
||||||
|
fs::rename(&src, &dest)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs::remove_dir(&nested_dir)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check if the extracted archive has a single directory in it which contains the mod files
|
||||||
|
fn check_nested_dir(path: impl AsRef<Path>) -> Option<PathBuf> {
|
||||||
|
let path = path.as_ref();
|
||||||
|
|
||||||
|
let entries: Vec<_> = fs::read_dir(path).ok()?.filter_map(|e| e.ok()).collect();
|
||||||
|
|
||||||
|
if entries.len() == 1 {
|
||||||
|
let entry = &entries[0];
|
||||||
|
let entry_path = entry.path();
|
||||||
|
|
||||||
|
if entry_path
|
||||||
|
.file_name()
|
||||||
|
.is_some_and(|e| e == "Data" || e == "data")
|
||||||
|
{
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
if entry_path.is_dir() {
|
||||||
|
return Some(entry_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user