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.PostProcessor;
|
||||||
import ctbrec.recorder.postprocessing.Remux;
|
import ctbrec.recorder.postprocessing.Remux;
|
||||||
import ctbrec.recorder.postprocessing.Rename;
|
import ctbrec.recorder.postprocessing.Rename;
|
||||||
|
import ctbrec.recorder.postprocessing.Script;
|
||||||
import ctbrec.ui.controls.Dialogs;
|
import ctbrec.ui.controls.Dialogs;
|
||||||
import ctbrec.ui.settings.api.Preferences;
|
import ctbrec.ui.settings.api.Preferences;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
|
@ -22,6 +23,7 @@ public class PostProcessingDialogFactory {
|
||||||
static Map<Class<?>, Class<?>> ppToDialogMap = new HashMap<>();
|
static Map<Class<?>, Class<?>> ppToDialogMap = new HashMap<>();
|
||||||
static {
|
static {
|
||||||
ppToDialogMap.put(Remux.class, RemuxerPaneFactory.class);
|
ppToDialogMap.put(Remux.class, RemuxerPaneFactory.class);
|
||||||
|
ppToDialogMap.put(Script.class, ScriptPaneFactory.class);
|
||||||
ppToDialogMap.put(Rename.class, RenamerPaneFactory.class);
|
ppToDialogMap.put(Rename.class, RenamerPaneFactory.class);
|
||||||
ppToDialogMap.put(Move.class, MoverPaneFactory.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.RemoveKeepFile;
|
||||||
import ctbrec.recorder.postprocessing.Remux;
|
import ctbrec.recorder.postprocessing.Remux;
|
||||||
import ctbrec.recorder.postprocessing.Rename;
|
import ctbrec.recorder.postprocessing.Rename;
|
||||||
|
import ctbrec.recorder.postprocessing.Script;
|
||||||
import ctbrec.ui.controls.Dialogs;
|
import ctbrec.ui.controls.Dialogs;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ListChangeListener;
|
import javafx.collections.ListChangeListener;
|
||||||
|
@ -34,9 +35,10 @@ public class PostProcessingStepPanel extends GridPane {
|
||||||
|
|
||||||
private static final Class<?>[] POST_PROCESSOR_CLASSES = new Class<?>[] { // @formatter: off
|
private static final Class<?>[] POST_PROCESSOR_CLASSES = new Class<?>[] { // @formatter: off
|
||||||
Copy.class,
|
Copy.class,
|
||||||
Remux.class,
|
|
||||||
Rename.class,
|
Rename.class,
|
||||||
Move.class,
|
Move.class,
|
||||||
|
Remux.class,
|
||||||
|
Script.class,
|
||||||
DeleteOriginal.class,
|
DeleteOriginal.class,
|
||||||
RemoveKeepFile.class
|
RemoveKeepFile.class
|
||||||
}; // @formatter: on
|
}; // @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}",
|
"${epochSecond}",
|
||||||
"${fileSuffix}",
|
"${fileSuffix}",
|
||||||
"${modelNotes}",
|
"${modelNotes}",
|
||||||
"${recordingsDir}"
|
"${recordingsDir}",
|
||||||
|
"${absolutePath}",
|
||||||
|
"${absoluteParentPath}"
|
||||||
};
|
};
|
||||||
|
|
||||||
public String fillInPlaceHolders(String input, Recording rec, Config config) {
|
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("${epochSecond}", Long.toString(rec.getStartDate().getEpochSecond()))
|
||||||
.replace("${modelNotes}", config.getModelNotes(rec.getModel()))
|
.replace("${modelNotes}", config.getModelNotes(rec.getModel()))
|
||||||
.replace("${recordingsDir}", config.getSettings().recordingsDir)
|
.replace("${recordingsDir}", config.getSettings().recordingsDir)
|
||||||
|
.replace("${absolutePath}", rec.getPostProcessedFile().getAbsolutePath())
|
||||||
|
.replace("${absoluteParentPath}", rec.getPostProcessedFile().getParentFile().getAbsolutePath())
|
||||||
;
|
;
|
||||||
|
|
||||||
output = replaceUtcDateTime(rec, output);
|
output = replaceUtcDateTime(rec, output);
|
||||||
|
|
|
@ -1,14 +1,26 @@
|
||||||
package ctbrec.recorder.postprocessing;
|
package ctbrec.recorder.postprocessing;
|
||||||
|
|
||||||
import java.io.IOException;
|
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.Config;
|
||||||
import ctbrec.NotImplementedExcetion;
|
import ctbrec.OS;
|
||||||
import ctbrec.Recording;
|
import ctbrec.Recording;
|
||||||
|
import ctbrec.io.StreamRedirectThread;
|
||||||
import ctbrec.recorder.RecordingManager;
|
import ctbrec.recorder.RecordingManager;
|
||||||
|
import ctbrec.recorder.download.ProcessExitedUncleanException;
|
||||||
|
|
||||||
public class Script extends AbstractPlaceholderAwarePostProcessor {
|
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
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "execute script";
|
return "execute script";
|
||||||
|
@ -16,7 +28,46 @@ public class Script extends AbstractPlaceholderAwarePostProcessor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void postprocess(Recording rec, RecordingManager recordingManager, Config config) throws IOException, InterruptedException {
|
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
|
List<String> cmdline = buildCommandLine(rec, config);
|
||||||
throw new NotImplementedExcetion();
|
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