filebot/source/net/filebot/cli/ExecCommand.java

100 lines
2.8 KiB
Java

package net.filebot.cli;
import static java.util.stream.Collectors.*;
import static net.filebot.Logging.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;
import javax.script.ScriptException;
import net.filebot.format.ExpressionFormat;
import net.filebot.format.MediaBindingBean;
public class ExecCommand {
private List<ExpressionFormat> template;
private boolean parallel;
private File directory;
public ExecCommand(List<ExpressionFormat> template, boolean parallel, File directory) {
this.template = template;
this.parallel = parallel;
this.directory = directory;
}
public void execute(MediaBindingBean... group) throws IOException, InterruptedException {
if (parallel) {
executeParallel(group);
} else {
executeSequence(group);
}
}
private void executeSequence(MediaBindingBean... group) throws IOException, InterruptedException {
// collect unique commands
List<List<String>> commands = Stream.of(group).map(v -> {
return template.stream().map(t -> getArgumentValue(t, v)).filter(Objects::nonNull).collect(toList());
}).distinct().collect(toList());
// execute unique commands
for (List<String> command : commands) {
execute(command);
}
}
private void executeParallel(MediaBindingBean... group) throws IOException, InterruptedException {
// collect single command
List<String> command = template.stream().flatMap(t -> {
return Stream.of(group).map(v -> getArgumentValue(t, v)).filter(Objects::nonNull).distinct();
}).collect(toList());
// execute single command
execute(command);
}
private String getArgumentValue(ExpressionFormat template, MediaBindingBean variables) {
try {
return template.format(variables);
} catch (Exception e) {
debug.warning(cause(template.getExpression(), e));
}
return null;
}
private void execute(List<String> command) throws IOException, InterruptedException {
ProcessBuilder process = new ProcessBuilder(command);
process.directory(directory);
process.inheritIO();
debug.finest(format("Execute %s", command));
int exitCode = process.start().waitFor();
if (exitCode != 0) {
throw new IOException(String.format("%s failed with exit code %d", command, exitCode));
}
}
public static ExecCommand parse(List<String> args, File directory) throws ScriptException {
// execute one command per file or one command with many file arguments
boolean parallel = args.lastIndexOf("+") == args.size() - 1;
if (parallel) {
args = args.subList(0, args.size() - 1);
}
List<ExpressionFormat> template = new ArrayList<ExpressionFormat>();
for (String argument : args) {
template.add(new ExpressionFormat(argument));
}
return new ExecCommand(template, parallel, directory);
}
}