filebot/source/net/filebot/archive/ShellExecutables.java

151 lines
4.7 KiB
Java

package net.filebot.archive;
import static java.util.stream.Collectors.*;
import static net.filebot.Execute.*;
import static net.filebot.util.RegularExpressions.*;
import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;
import java.util.regex.Pattern;
import net.filebot.util.FileUtilities.ExtensionFileFilter;
import net.filebot.vfs.FileInfo;
import net.filebot.vfs.SimpleFileInfo;
public class ShellExecutables implements ArchiveExtractor {
private Command command;
private File archive;
public ShellExecutables(File archive) throws Exception {
if (!archive.exists()) {
throw new FileNotFoundException(archive.getPath());
}
this.archive = archive.getCanonicalFile();
this.command = getCommand(this.archive);
}
@Override
public List<FileInfo> listFiles() throws IOException {
return command.listFiles(archive);
}
@Override
public void extract(File outputFolder) throws IOException {
command.extract(archive, outputFolder.getCanonicalFile());
}
@Override
public void extract(File outputFolder, FileFilter filter) throws IOException {
command.extract(archive, outputFolder.getCanonicalFile(), filter);
}
protected Command getCommand(File archive) {
return RAR_FILES.accept(archive) ? Command.unrar : Command.p7zip;
}
public enum Command {
p7zip {
@Override
public String getCommand() {
return System.getProperty("net.filebot.archive.7z", "7z");
}
@Override
public List<FileInfo> listFiles(File archive) throws IOException {
CharSequence output = execute(getCommand(), "l", "-y", archive.getPath());
return NEWLINE.splitAsStream(output).map(String::trim).map(l -> SPACE.split(l, 6)).filter(r -> {
return r.length == 6 && !r[5].isEmpty() && NON_DIGIT.matcher(r[2]).matches() && DIGIT.matcher(r[3]).matches();
}).map(r -> {
return new SimpleFileInfo(r[5], Long.parseLong(r[3]));
}).collect(toList());
}
@Override
public void extract(File archive, File outputFolder) throws IOException {
String[] command = { getCommand(), "x", "-y", "-o" + outputFolder.getPath(), archive.getPath() };
execute(command);
}
@Override
public void extract(File archive, File outputFolder, FileFilter filter) throws IOException {
String[] command = { getCommand(), "x", "-y", "-o" + outputFolder.getPath(), archive.getPath() };
String[] selection = listFiles(archive).stream().filter(f -> filter.accept(f.toFile())).map(FileInfo::getPath).toArray(String[]::new);
execute(command, selection);
}
@Override
public String version() throws IOException {
CharSequence output = execute(getCommand());
return NEWLINE.splitAsStream(output).map(String::trim).filter(s -> s.startsWith("p7zip")).findFirst().orElse(null);
}
},
unrar {
@Override
public String getCommand() {
return System.getProperty("net.filebot.archive.unrar", "unrar");
}
@Override
public List<FileInfo> listFiles(File archive) throws IOException {
CharSequence output = execute(getCommand(), "l", "-y", archive.getPath());
return NEWLINE.splitAsStream(output).map(String::trim).map(l -> SPACE.split(l, 5)).filter(r -> {
return r.length == 5 && r[4].length() > 0 && NON_DIGIT.matcher(r[0]).matches() && DIGIT.matcher(r[1]).matches();
}).map(r -> {
return new SimpleFileInfo(r[4], Long.parseLong(r[1]));
}).collect(toList());
}
@Override
public void extract(File archive, File outputFolder) throws IOException {
String[] command = { getCommand(), "x", "-y", archive.getPath(), outputFolder.getPath() };
execute(command);
}
@Override
public void extract(File archive, File outputFolder, FileFilter filter) throws IOException {
String[] command = { getCommand(), "x", "-y", archive.getPath() };
String[] selection = listFiles(archive).stream().filter(f -> filter.accept(f.toFile())).map(FileInfo::getPath).toArray(String[]::new);
String[] output = { outputFolder.getPath() };
execute(command, selection, output);
}
@Override
public String version() throws IOException {
CharSequence output = execute(getCommand());
return Pattern.compile("\\n+|\\s\\s+").splitAsStream(output).map(String::trim).filter(s -> !s.isEmpty()).findFirst().orElse(null);
}
};
public abstract String getCommand();
public abstract List<FileInfo> listFiles(File archive) throws IOException;
public abstract void extract(File archive, File outputFolder) throws IOException;
public abstract void extract(File archive, File outputFolder, FileFilter filter) throws IOException;
public abstract String version() throws IOException;
}
public static final FileFilter RAR_FILES = new ExtensionFileFilter("rar", "r00");
}