mirror of
https://github.com/mitb-archive/filebot
synced 2025-03-09 05:51:31 -04:00
Refactor system exec
This commit is contained in:
parent
45528ef212
commit
3fa0530da9
85
source/net/filebot/Execute.java
Normal file
85
source/net/filebot/Execute.java
Normal file
@ -0,0 +1,85 @@
|
||||
package net.filebot;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.*;
|
||||
import static java.util.Arrays.*;
|
||||
import static java.util.stream.Collectors.*;
|
||||
import static net.filebot.Logging.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.ProcessBuilder.Redirect;
|
||||
import java.util.List;
|
||||
|
||||
import net.filebot.util.ByteBufferOutputStream;
|
||||
|
||||
public class Execute {
|
||||
|
||||
private static final int BUFFER_SIZE = 8 * 1024;
|
||||
|
||||
public static CharSequence execute(String... command) throws IOException {
|
||||
return execute(asList(command), null);
|
||||
}
|
||||
|
||||
public static CharSequence execute(String[] command, File directory) throws IOException {
|
||||
return execute(asList(command), directory);
|
||||
}
|
||||
|
||||
public static CharSequence execute(String[]... command) throws IOException {
|
||||
return execute(stream(command).flatMap(a -> stream(a)).collect(toList()), null);
|
||||
}
|
||||
|
||||
public static CharSequence execute(List<String> command, File directory) throws IOException {
|
||||
ProcessBuilder processBuilder = new ProcessBuilder(command);
|
||||
processBuilder.redirectError(Redirect.INHERIT);
|
||||
|
||||
if (directory != null) {
|
||||
processBuilder.directory(directory);
|
||||
}
|
||||
|
||||
Process process = processBuilder.start();
|
||||
|
||||
try (ByteBufferOutputStream bb = new ByteBufferOutputStream(BUFFER_SIZE)) {
|
||||
bb.transferFully(process.getInputStream());
|
||||
|
||||
int exitCode = process.waitFor();
|
||||
CharSequence output = UTF_8.decode(bb.getByteBuffer());
|
||||
|
||||
// DEBUG
|
||||
debug.finest(format("Execute %s%n%s", command, output));
|
||||
|
||||
if (exitCode != 0) {
|
||||
throw new ExecuteException(command, exitCode);
|
||||
}
|
||||
|
||||
return output;
|
||||
} catch (InterruptedException e) {
|
||||
throw new IOException(String.format("%s timed out", command), e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void system(String[] command, File directory) throws IOException {
|
||||
system(asList(command), directory);
|
||||
}
|
||||
|
||||
public static void system(List<String> command, File directory) throws IOException {
|
||||
ProcessBuilder processBuilder = new ProcessBuilder(command);
|
||||
processBuilder.inheritIO();
|
||||
|
||||
if (directory != null) {
|
||||
processBuilder.directory(directory);
|
||||
}
|
||||
|
||||
// DEBUG
|
||||
debug.finest(format("Execute %s", command));
|
||||
|
||||
try {
|
||||
int exitCode = processBuilder.start().waitFor();
|
||||
if (exitCode != 0) {
|
||||
throw new ExecuteException(command, exitCode);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
throw new IOException(String.format("%s timed out", command), e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
23
source/net/filebot/ExecuteException.java
Normal file
23
source/net/filebot/ExecuteException.java
Normal file
@ -0,0 +1,23 @@
|
||||
package net.filebot;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public class ExecuteException extends IOException {
|
||||
|
||||
private int exitCode;
|
||||
|
||||
public ExecuteException(String message, int exitCode) {
|
||||
super(message);
|
||||
this.exitCode = exitCode;
|
||||
}
|
||||
|
||||
public ExecuteException(List<String> command, int exitCode) {
|
||||
this(String.format("%s failed with exit code %d", command, exitCode), exitCode);
|
||||
}
|
||||
|
||||
public int getExitCode() {
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
}
|
@ -1,20 +1,16 @@
|
||||
package net.filebot.archive;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.*;
|
||||
import static java.util.Arrays.*;
|
||||
import static java.util.stream.Collectors.*;
|
||||
import static net.filebot.Logging.*;
|
||||
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.lang.ProcessBuilder.Redirect;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import net.filebot.util.ByteBufferOutputStream;
|
||||
import net.filebot.util.FileUtilities.ExtensionFileFilter;
|
||||
import net.filebot.vfs.FileInfo;
|
||||
import net.filebot.vfs.SimpleFileInfo;
|
||||
@ -48,37 +44,10 @@ public class ShellExecutables implements ArchiveExtractor {
|
||||
command.extract(archive, outputFolder.getCanonicalFile(), filter);
|
||||
}
|
||||
|
||||
protected static Command getCommand(File archive) {
|
||||
protected Command getCommand(File archive) {
|
||||
return RAR_FILES.accept(archive) ? Command.unrar : Command.p7zip;
|
||||
}
|
||||
|
||||
protected static CharSequence execute(String[]... command) throws IOException {
|
||||
return execute(stream(command).flatMap(a -> stream(a)).toArray(String[]::new));
|
||||
}
|
||||
|
||||
protected static 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", asList(command), returnCode, output.trim()));
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
throw new IOException(String.format("%s timed out", asList(command)), e);
|
||||
}
|
||||
}
|
||||
|
||||
public enum Command {
|
||||
|
||||
p7zip {
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.filebot.cli;
|
||||
|
||||
import static java.util.stream.Collectors.*;
|
||||
import static net.filebot.Execute.*;
|
||||
import static net.filebot.Logging.*;
|
||||
|
||||
import java.io.File;
|
||||
@ -28,7 +29,7 @@ public class ExecCommand {
|
||||
this.directory = directory;
|
||||
}
|
||||
|
||||
public void execute(MediaBindingBean... group) throws IOException, InterruptedException {
|
||||
public void execute(MediaBindingBean... group) throws IOException {
|
||||
if (parallel) {
|
||||
executeParallel(group);
|
||||
} else {
|
||||
@ -36,7 +37,7 @@ public class ExecCommand {
|
||||
}
|
||||
}
|
||||
|
||||
private void executeSequence(MediaBindingBean... group) throws IOException, InterruptedException {
|
||||
private void executeSequence(MediaBindingBean... group) throws IOException {
|
||||
// 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());
|
||||
@ -44,18 +45,18 @@ public class ExecCommand {
|
||||
|
||||
// execute unique commands
|
||||
for (List<String> command : commands) {
|
||||
execute(command);
|
||||
system(command, directory);
|
||||
}
|
||||
}
|
||||
|
||||
private void executeParallel(MediaBindingBean... group) throws IOException, InterruptedException {
|
||||
private void executeParallel(MediaBindingBean... group) throws IOException {
|
||||
// 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);
|
||||
system(command, directory);
|
||||
}
|
||||
|
||||
private String getArgumentValue(ExpressionFormat template, MediaBindingBean variables) {
|
||||
@ -67,19 +68,6 @@ public class ExecCommand {
|
||||
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;
|
||||
|
@ -1,7 +1,8 @@
|
||||
package net.filebot.cli;
|
||||
|
||||
import static net.filebot.Execute.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import net.filebot.RenameAction;
|
||||
|
||||
@ -17,14 +18,9 @@ public class ExecutableRenameAction implements RenameAction {
|
||||
|
||||
@Override
|
||||
public File rename(File from, File to) throws Exception {
|
||||
ProcessBuilder process = new ProcessBuilder(executable, from.getCanonicalPath(), getRelativePath(directory, to));
|
||||
process.directory(directory);
|
||||
process.inheritIO();
|
||||
String[] command = { executable, from.getCanonicalPath(), getRelativePath(directory, to) };
|
||||
|
||||
int exitCode = process.start().waitFor();
|
||||
if (exitCode != 0) {
|
||||
throw new IOException(String.format("%s failed with exit code %d", process.command(), exitCode));
|
||||
}
|
||||
system(command, directory);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
@ -3,10 +3,10 @@ package net.filebot.media;
|
||||
import static java.util.Arrays.*;
|
||||
import static java.util.Collections.*;
|
||||
import static java.util.stream.Collectors.*;
|
||||
import static net.filebot.Execute.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.ProcessBuilder.Redirect;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
@ -25,23 +25,12 @@ public class FFProbe implements MediaCharacteristics {
|
||||
}
|
||||
|
||||
protected Map<String, Object> parse(File file) throws IOException, InterruptedException {
|
||||
ProcessBuilder processBuilder = new ProcessBuilder(getFFProbeCommand(), "-show_streams", "-show_format", "-print_format", "json", "-v", "error", file.getCanonicalPath());
|
||||
String[] command = { getFFProbeCommand(), "-show_streams", "-show_format", "-print_format", "json", "-v", "error", file.getCanonicalPath() };
|
||||
|
||||
processBuilder.directory(file.getParentFile());
|
||||
processBuilder.redirectError(Redirect.INHERIT);
|
||||
|
||||
Process process = processBuilder.start();
|
||||
CharSequence output = execute(command, file.getParentFile());
|
||||
|
||||
// parse process standard output
|
||||
Map<String, Object> json = (Map) JsonReader.jsonToJava(process.getInputStream(), singletonMap(JsonReader.USE_MAPS, true));
|
||||
|
||||
int exitCode = process.waitFor();
|
||||
if (exitCode != 0) {
|
||||
throw new IOException(String.format("%s failed with exit code %d", processBuilder.command(), exitCode));
|
||||
}
|
||||
|
||||
// group video / audio / subtitle streams together
|
||||
return json;
|
||||
return (Map) JsonReader.jsonToJava(output.toString(), singletonMap(JsonReader.USE_MAPS, true));
|
||||
}
|
||||
|
||||
private Map<String, Object> json;
|
||||
|
Loading…
x
Reference in New Issue
Block a user