forked from j62/ctbrec
Add script post-processor
This commit is contained in:
parent
67ff48e2dc
commit
f6afed3717
|
@ -11,6 +11,7 @@ import ctbrec.recorder.postprocessing.Move;
|
|||
import ctbrec.recorder.postprocessing.PostProcessor;
|
||||
import ctbrec.recorder.postprocessing.Remux;
|
||||
import ctbrec.recorder.postprocessing.Rename;
|
||||
import ctbrec.recorder.postprocessing.Script;
|
||||
import ctbrec.ui.controls.Dialogs;
|
||||
import ctbrec.ui.settings.api.Preferences;
|
||||
import javafx.collections.ObservableList;
|
||||
|
@ -22,6 +23,7 @@ public class PostProcessingDialogFactory {
|
|||
static Map<Class<?>, Class<?>> ppToDialogMap = new HashMap<>();
|
||||
static {
|
||||
ppToDialogMap.put(Remux.class, RemuxerPaneFactory.class);
|
||||
ppToDialogMap.put(Script.class, ScriptPaneFactory.class);
|
||||
ppToDialogMap.put(Rename.class, RenamerPaneFactory.class);
|
||||
ppToDialogMap.put(Move.class, MoverPaneFactory.class);
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import ctbrec.recorder.postprocessing.PostProcessor;
|
|||
import ctbrec.recorder.postprocessing.RemoveKeepFile;
|
||||
import ctbrec.recorder.postprocessing.Remux;
|
||||
import ctbrec.recorder.postprocessing.Rename;
|
||||
import ctbrec.recorder.postprocessing.Script;
|
||||
import ctbrec.ui.controls.Dialogs;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ListChangeListener;
|
||||
|
@ -34,9 +35,10 @@ public class PostProcessingStepPanel extends GridPane {
|
|||
|
||||
private static final Class<?>[] POST_PROCESSOR_CLASSES = new Class<?>[] { // @formatter: off
|
||||
Copy.class,
|
||||
Remux.class,
|
||||
Rename.class,
|
||||
Move.class,
|
||||
Remux.class,
|
||||
Script.class,
|
||||
DeleteOriginal.class,
|
||||
RemoveKeepFile.class
|
||||
}; // @formatter: on
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package ctbrec.ui.settings;
|
||||
|
||||
import ctbrec.recorder.postprocessing.PostProcessor;
|
||||
import ctbrec.recorder.postprocessing.Script;
|
||||
import ctbrec.ui.settings.api.Category;
|
||||
import ctbrec.ui.settings.api.Preferences;
|
||||
import ctbrec.ui.settings.api.Setting;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
|
||||
public class ScriptPaneFactory extends AbstractPostProcessingPaneFactory {
|
||||
|
||||
@Override
|
||||
public Preferences doCreatePostProcessorPane(PostProcessor pp) {
|
||||
SimpleStringProperty script = new SimpleStringProperty(null, Script.SCRIPT_EXECUTABLE, pp.getConfig().getOrDefault(Script.SCRIPT_EXECUTABLE, "c:\\users\\johndoe\\somescript"));
|
||||
SimpleStringProperty params = new SimpleStringProperty(null, Script.SCRIPT_PARAMS, pp.getConfig().getOrDefault(Script.SCRIPT_PARAMS, "${absolutePath}"));
|
||||
properties.add(script);
|
||||
properties.add(params);
|
||||
|
||||
return Preferences.of(new MapPreferencesStorage(),
|
||||
Category.of(pp.getName(),
|
||||
Setting.of("Script", script),
|
||||
Setting.of("Parameters", params)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -25,7 +25,9 @@ public abstract class AbstractPlaceholderAwarePostProcessor extends AbstractPost
|
|||
"${epochSecond}",
|
||||
"${fileSuffix}",
|
||||
"${modelNotes}",
|
||||
"${recordingsDir}"
|
||||
"${recordingsDir}",
|
||||
"${absolutePath}",
|
||||
"${absoluteParentPath}"
|
||||
};
|
||||
|
||||
public String fillInPlaceHolders(String input, Recording rec, Config config) {
|
||||
|
@ -40,6 +42,8 @@ public abstract class AbstractPlaceholderAwarePostProcessor extends AbstractPost
|
|||
.replace("${epochSecond}", Long.toString(rec.getStartDate().getEpochSecond()))
|
||||
.replace("${modelNotes}", config.getModelNotes(rec.getModel()))
|
||||
.replace("${recordingsDir}", config.getSettings().recordingsDir)
|
||||
.replace("${absolutePath}", rec.getPostProcessedFile().getAbsolutePath())
|
||||
.replace("${absoluteParentPath}", rec.getPostProcessedFile().getParentFile().getAbsolutePath())
|
||||
;
|
||||
|
||||
output = replaceUtcDateTime(rec, output);
|
||||
|
|
|
@ -1,14 +1,26 @@
|
|||
package ctbrec.recorder.postprocessing;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ctbrec.Config;
|
||||
import ctbrec.NotImplementedExcetion;
|
||||
import ctbrec.OS;
|
||||
import ctbrec.Recording;
|
||||
import ctbrec.io.StreamRedirectThread;
|
||||
import ctbrec.recorder.RecordingManager;
|
||||
import ctbrec.recorder.download.ProcessExitedUncleanException;
|
||||
|
||||
public class Script extends AbstractPlaceholderAwarePostProcessor {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Script.class);
|
||||
public static final String SCRIPT_EXECUTABLE = "script.executable";
|
||||
public static final String SCRIPT_PARAMS = "script.params";
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "execute script";
|
||||
|
@ -16,7 +28,46 @@ public class Script extends AbstractPlaceholderAwarePostProcessor {
|
|||
|
||||
@Override
|
||||
public void postprocess(Recording rec, RecordingManager recordingManager, Config config) throws IOException, InterruptedException {
|
||||
// TODO make it possible to choose, which placeholders to pass to the script
|
||||
throw new NotImplementedExcetion();
|
||||
List<String> cmdline = buildCommandLine(rec, config);
|
||||
Runtime rt = Runtime.getRuntime();
|
||||
String[] args = cmdline.toArray(new String[0]);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Running {}", Arrays.toString(args));
|
||||
}
|
||||
Process process = rt.exec(args, OS.getEnvironment());
|
||||
startLogging(process);
|
||||
int exitCode = process.waitFor();
|
||||
LOG.debug("Process finished with exit code {}", exitCode);
|
||||
if (exitCode != 0) {
|
||||
throw new ProcessExitedUncleanException("Script finished with exit code " + exitCode);
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> buildCommandLine(Recording rec, Config config) throws IOException {
|
||||
String script = getConfig().getOrDefault(SCRIPT_EXECUTABLE, "somescript");
|
||||
String params = getConfig().getOrDefault(SCRIPT_PARAMS, "${absolutePath}");
|
||||
List<String> cmdline = new ArrayList<>();
|
||||
cmdline.add(script);
|
||||
String replacedParams = fillInPlaceHolders(params, rec, config);
|
||||
Arrays.stream(replacedParams.split(" ")).forEach(cmdline::add);
|
||||
return cmdline;
|
||||
}
|
||||
|
||||
private void startLogging(Process process) {
|
||||
// TODO maybe write these to a separate log file, e.g. recname.ts.script.log
|
||||
Thread std = new Thread(new StreamRedirectThread(process.getInputStream(), System.out));
|
||||
std.setName("Process stdout pipe");
|
||||
std.setDaemon(true);
|
||||
std.start();
|
||||
Thread err = new Thread(new StreamRedirectThread(process.getErrorStream(), System.err));
|
||||
err.setName("Process stderr pipe");
|
||||
err.setDaemon(true);
|
||||
err.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return (getName() + " " + getConfig().getOrDefault(Script.SCRIPT_EXECUTABLE, "")).trim();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue