mirror of
https://github.com/mitb-archive/filebot
synced 2024-08-13 17:03:45 -04:00
120 lines
3.4 KiB
Java
120 lines
3.4 KiB
Java
package net.filebot.archive;
|
|
|
|
import static java.nio.charset.StandardCharsets.*;
|
|
import static java.util.Arrays.*;
|
|
import static net.filebot.Logging.*;
|
|
import static net.filebot.util.RegularExpressions.*;
|
|
|
|
import java.io.File;
|
|
import java.io.FileFilter;
|
|
import java.io.FileNotFoundException;
|
|
import java.io.IOException;
|
|
import java.lang.ProcessBuilder.Redirect;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.stream.Stream;
|
|
|
|
import net.filebot.util.ByteBufferOutputStream;
|
|
import net.filebot.vfs.FileInfo;
|
|
import net.filebot.vfs.SimpleFileInfo;
|
|
|
|
public class SevenZipExecutable implements ArchiveExtractor {
|
|
|
|
private File archive;
|
|
|
|
public SevenZipExecutable(File file) throws Exception {
|
|
if (!file.exists()) {
|
|
throw new FileNotFoundException(file.getAbsolutePath());
|
|
}
|
|
|
|
this.archive = file.getCanonicalFile();
|
|
}
|
|
|
|
protected String get7zCommand() {
|
|
// use 7z executable path as specified by the cmdline or default to "7z" and let the shell figure it out
|
|
return System.getProperty("net.filebot.Archive.7z", "7z");
|
|
}
|
|
|
|
protected CharSequence execute(String... command) throws IOException {
|
|
Process process = new ProcessBuilder(command).redirectError(Redirect.INHERIT).start();
|
|
|
|
try (ByteBufferOutputStream bb = new ByteBufferOutputStream(8 * 1024)) {
|
|
bb.transferFully(process.getInputStream());
|
|
|
|
int returnCode = process.waitFor();
|
|
String output = UTF_8.decode(bb.getByteBuffer()).toString();
|
|
|
|
// DEBUG
|
|
debug.fine(format("Execute: %s", asList(command)));
|
|
debug.finest(output);
|
|
|
|
if (returnCode == 0) {
|
|
return output;
|
|
} else {
|
|
throw new IOException(String.format("%s failed with exit code %d: %s", get7zCommand(), returnCode, SPACE.matcher(output).replaceAll(" ").trim()));
|
|
}
|
|
} catch (InterruptedException e) {
|
|
throw new IOException(String.format("%s timed out", get7zCommand()), e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public List<FileInfo> listFiles() throws IOException {
|
|
// e.g. 7z l -y archive.7z
|
|
CharSequence output = execute(get7zCommand(), "l", "-slt", "-y", archive.getPath());
|
|
|
|
List<FileInfo> paths = new ArrayList<FileInfo>();
|
|
|
|
String path = null;
|
|
long size = -1;
|
|
|
|
for (String line : NEWLINE.split(output)) {
|
|
int split = line.indexOf(" = ");
|
|
|
|
// ignore empty lines
|
|
if (split < 0) {
|
|
continue;
|
|
}
|
|
|
|
String key = line.substring(0, split);
|
|
String value = line.substring(split + 3, line.length());
|
|
|
|
// ignore empty lines
|
|
if (key.isEmpty() || value.isEmpty()) {
|
|
continue;
|
|
}
|
|
|
|
if ("Path".equals(key)) {
|
|
path = value;
|
|
} else if ("Size".equals(key)) {
|
|
size = Long.parseLong(value);
|
|
}
|
|
|
|
if (path != null && size >= 0) {
|
|
paths.add(new SimpleFileInfo(path, size));
|
|
|
|
path = null;
|
|
size = -1;
|
|
}
|
|
}
|
|
|
|
return paths;
|
|
}
|
|
|
|
@Override
|
|
public void extract(File outputDir) throws IOException {
|
|
// e.g. 7z x -y -aos archive.7z
|
|
execute(get7zCommand(), "x", "-y", "-aos", archive.getPath(), "-o" + outputDir.getCanonicalPath());
|
|
}
|
|
|
|
@Override
|
|
public void extract(File outputDir, FileFilter filter) throws IOException {
|
|
// e.g. 7z x -y -aos archive.7z file.txt image.png info.nfo
|
|
Stream<String> command = Stream.of(get7zCommand(), "x", "-y", "-aos", archive.getPath(), "-o" + outputDir.getCanonicalPath());
|
|
Stream<String> selection = listFiles().stream().filter(f -> filter.accept(f.toFile())).map(f -> f.getPath());
|
|
|
|
execute(Stream.concat(command, selection).toArray(String[]::new));
|
|
}
|
|
|
|
}
|