mirror of
https://github.com/xavo95/repak.git
synced 2025-01-18 19:04:07 +00:00
Allow unpack
to accept multiple paks; resolves #10
This commit is contained in:
parent
720222ba39
commit
9c9be74946
1 changed files with 66 additions and 54 deletions
|
@ -43,10 +43,10 @@ struct ActionHashList {
|
||||||
struct ActionUnpack {
|
struct ActionUnpack {
|
||||||
/// Input .pak path
|
/// Input .pak path
|
||||||
#[arg(index = 1)]
|
#[arg(index = 1)]
|
||||||
input: String,
|
input: Vec<String>,
|
||||||
|
|
||||||
/// Output directory. Defaults to next to input pak
|
/// Output directory. Defaults to next to input pak
|
||||||
#[arg(index = 2)]
|
#[arg(short, long)]
|
||||||
output: Option<String>,
|
output: Option<String>,
|
||||||
|
|
||||||
/// Prefix to strip from entry path
|
/// Prefix to strip from entry path
|
||||||
|
@ -279,41 +279,47 @@ fn hash_list(aes_key: Option<aes::Aes256>, action: ActionHashList) -> Result<(),
|
||||||
const STYLE: &str = "[{elapsed_precise}] [{wide_bar}] {pos}/{len} ({eta})";
|
const STYLE: &str = "[{elapsed_precise}] [{wide_bar}] {pos}/{len} ({eta})";
|
||||||
|
|
||||||
fn unpack(aes_key: Option<aes::Aes256>, action: ActionUnpack) -> Result<(), repak::Error> {
|
fn unpack(aes_key: Option<aes::Aes256>, action: ActionUnpack) -> Result<(), repak::Error> {
|
||||||
let pak = repak::PakReader::new_any_with_optional_key(
|
for input in &action.input {
|
||||||
&mut BufReader::new(File::open(&action.input)?),
|
let pak = repak::PakReader::new_any_with_optional_key(
|
||||||
aes_key,
|
&mut BufReader::new(File::open(input)?),
|
||||||
)?;
|
aes_key.clone(),
|
||||||
let output = action
|
)?;
|
||||||
.output
|
let output = action
|
||||||
.map(PathBuf::from)
|
.output
|
||||||
.unwrap_or_else(|| Path::new(&action.input).with_extension(""));
|
.as_ref()
|
||||||
match fs::create_dir(&output) {
|
.map(PathBuf::from)
|
||||||
Ok(_) => Ok(()),
|
.unwrap_or_else(|| Path::new(input).with_extension(""));
|
||||||
Err(ref e) if e.kind() == std::io::ErrorKind::AlreadyExists => Ok(()),
|
match fs::create_dir(&output) {
|
||||||
Err(e) => Err(e),
|
Ok(_) => Ok(()),
|
||||||
}?;
|
Err(ref e)
|
||||||
if !action.force && output.read_dir()?.next().is_some() {
|
if action.output.is_some() && e.kind() == std::io::ErrorKind::AlreadyExists =>
|
||||||
return Err(repak::Error::OutputNotEmpty(
|
{
|
||||||
output.to_string_lossy().to_string(),
|
Ok(())
|
||||||
));
|
}
|
||||||
}
|
Err(e) => Err(e),
|
||||||
let mount_point = PathBuf::from(pak.mount_point());
|
}?;
|
||||||
let prefix = Path::new(&action.strip_prefix);
|
if action.output.is_none() && !action.force && output.read_dir()?.next().is_some() {
|
||||||
|
return Err(repak::Error::OutputNotEmpty(
|
||||||
|
output.to_string_lossy().to_string(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
let mount_point = PathBuf::from(pak.mount_point());
|
||||||
|
let prefix = Path::new(&action.strip_prefix);
|
||||||
|
|
||||||
let includes = action
|
let includes = action
|
||||||
.include
|
.include
|
||||||
.iter()
|
.iter()
|
||||||
.map(|i| prefix.join(Path::new(i)))
|
.map(|i| prefix.join(Path::new(i)))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
struct UnpackEntry {
|
struct UnpackEntry {
|
||||||
entry_path: String,
|
entry_path: String,
|
||||||
out_path: PathBuf,
|
out_path: PathBuf,
|
||||||
out_dir: PathBuf,
|
out_dir: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
let entries =
|
let entries = pak
|
||||||
pak.files()
|
.files()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|entry_path| {
|
.map(|entry_path| {
|
||||||
let full_path = mount_point.join(&entry_path);
|
let full_path = mount_point.join(&entry_path);
|
||||||
|
@ -346,27 +352,33 @@ fn unpack(aes_key: Option<aes::Aes256>, action: ActionUnpack) -> Result<(), repa
|
||||||
.filter_map(|e| e.transpose())
|
.filter_map(|e| e.transpose())
|
||||||
.collect::<Result<Vec<_>, repak::Error>>()?;
|
.collect::<Result<Vec<_>, repak::Error>>()?;
|
||||||
|
|
||||||
let progress = indicatif::ProgressBar::new(entries.len() as u64)
|
let progress = indicatif::ProgressBar::new(entries.len() as u64)
|
||||||
.with_style(indicatif::ProgressStyle::with_template(STYLE).unwrap());
|
.with_style(indicatif::ProgressStyle::with_template(STYLE).unwrap());
|
||||||
entries.par_iter().try_for_each_init(
|
entries.par_iter().try_for_each_init(
|
||||||
|| (progress.clone(), File::open(&action.input)),
|
|| (progress.clone(), File::open(input)),
|
||||||
|(progress, file), entry| -> Result<(), repak::Error> {
|
|(progress, file), entry| -> Result<(), repak::Error> {
|
||||||
if action.verbose {
|
if action.verbose {
|
||||||
progress.println(format!("unpacking {}", entry.entry_path));
|
progress.println(format!("unpacking {}", entry.entry_path));
|
||||||
}
|
}
|
||||||
fs::create_dir_all(&entry.out_dir)?;
|
fs::create_dir_all(&entry.out_dir)?;
|
||||||
pak.read_file(
|
pak.read_file(
|
||||||
&entry.entry_path,
|
&entry.entry_path,
|
||||||
&mut BufReader::new(file.as_ref().unwrap()), // TODO: avoid this unwrap
|
&mut BufReader::new(file.as_ref().unwrap()), // TODO: avoid this unwrap
|
||||||
&mut fs::File::create(&entry.out_path)?,
|
&mut fs::File::create(&entry.out_path)?,
|
||||||
)?;
|
)?;
|
||||||
progress.inc(1);
|
progress.inc(1);
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
progress.finish();
|
progress.finish();
|
||||||
|
|
||||||
println!("Unpacked {} files to {}", entries.len(), output.display());
|
println!(
|
||||||
|
"Unpacked {} files to {} from {}",
|
||||||
|
entries.len(),
|
||||||
|
output.display(),
|
||||||
|
input
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue