diff --git a/source/net/sourceforge/filebot/cli/ArgumentProcessor.java b/source/net/sourceforge/filebot/cli/ArgumentProcessor.java index 66ab1485..d1359477 100644 --- a/source/net/sourceforge/filebot/cli/ArgumentProcessor.java +++ b/source/net/sourceforge/filebot/cli/ArgumentProcessor.java @@ -84,7 +84,7 @@ public class ArgumentProcessor { } else { // execute user script Bindings bindings = new SimpleBindings(); - bindings.put("args", args.getFiles(false)); + bindings.put(ScriptShell.ARGV_BINDING_NAME, args.getFiles(false)); DefaultScriptProvider scriptProvider = new DefaultScriptProvider(); URI script = scriptProvider.getScriptLocation(args.script); diff --git a/source/net/sourceforge/filebot/cli/ScriptShell.java b/source/net/sourceforge/filebot/cli/ScriptShell.java index c53406a9..5178d9ae 100644 --- a/source/net/sourceforge/filebot/cli/ScriptShell.java +++ b/source/net/sourceforge/filebot/cli/ScriptShell.java @@ -2,7 +2,6 @@ package net.sourceforge.filebot.cli; import groovy.lang.GroovyClassLoader; -import java.io.InputStreamReader; import java.net.URI; import java.util.Map; import java.util.ResourceBundle; @@ -11,9 +10,6 @@ import javax.script.Bindings; import javax.script.ScriptContext; import javax.script.ScriptEngine; import javax.script.ScriptException; -import javax.script.SimpleScriptContext; - -import net.sourceforge.filebot.format.ExpressionFormat; import org.codehaus.groovy.control.CompilerConfiguration; import org.codehaus.groovy.control.customizers.ImportCustomizer; @@ -22,6 +18,9 @@ import org.codehaus.groovy.runtime.StackTraceUtils; public class ScriptShell { + public static final String ARGV_BINDING_NAME = "args"; + public static final String SHELL_BINDING_NAME = "__shell"; + private final ScriptEngine engine; private final ScriptProvider scriptProvider; @@ -34,19 +33,10 @@ public class ScriptShell { bindings.putAll(globals); // bind API objects - // TODO remove - bindings.put("_cli", new CmdlineOperations()); - bindings.put("_shell", this); + bindings.put(SHELL_BINDING_NAME, this); // setup script context - ScriptContext context = new SimpleScriptContext(); - context.setBindings(bindings, ScriptContext.GLOBAL_SCOPE); - engine.setContext(context); - - // import additional functions into the shell environment - // TODO remove - engine.eval(new InputStreamReader(ExpressionFormat.class.getResourceAsStream("ExpressionFormat.lib.groovy"))); - engine.eval(new InputStreamReader(ScriptShell.class.getResourceAsStream("ScriptShell.lib.groovy"))); + engine.getContext().setBindings(bindings, ScriptContext.GLOBAL_SCOPE); } public ScriptEngine createScriptEngine() { diff --git a/source/net/sourceforge/filebot/cli/ScriptShell.properties b/source/net/sourceforge/filebot/cli/ScriptShell.properties index 7c3487e6..fb340425 100644 --- a/source/net/sourceforge/filebot/cli/ScriptShell.properties +++ b/source/net/sourceforge/filebot/cli/ScriptShell.properties @@ -1,3 +1,3 @@ scriptBaseClass: net.sourceforge.filebot.cli.ScriptShellBaseClass starImport: net.sourceforge.filebot, net.sourceforge.filebot.hash, net.sourceforge.filebot.media, net.sourceforge.filebot.mediainfo, net.sourceforge.filebot.similarity, net.sourceforge.filebot.subtitle, net.sourceforge.filebot.torrent, net.sourceforge.filebot.web, net.sourceforge.filebot.util, groovy.io, groovy.xml, groovy.json, org.jsoup, java.nio.file, java.nio.file.attribute, java.util.regex -starStaticImport: net.sourceforge.filebot.WebServices, java.nio.file.Files \ No newline at end of file +starStaticImport: net.sourceforge.filebot.format.ExpressionFormatFunctions, net.sourceforge.filebot.WebServices, java.nio.file.Files diff --git a/source/net/sourceforge/filebot/cli/ScriptShellBaseClass.java b/source/net/sourceforge/filebot/cli/ScriptShellBaseClass.java index ea5d949b..8f5064d3 100644 --- a/source/net/sourceforge/filebot/cli/ScriptShellBaseClass.java +++ b/source/net/sourceforge/filebot/cli/ScriptShellBaseClass.java @@ -1,14 +1,23 @@ package net.sourceforge.filebot.cli; +import static java.util.Collections.*; import static net.sourceforge.filebot.Settings.*; import static net.sourceforge.filebot.cli.CLILogging.*; import groovy.lang.Closure; +import groovy.lang.MissingPropertyException; import groovy.lang.Script; import java.io.Console; +import java.io.File; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.logging.Logger; +import javax.script.Bindings; +import javax.script.SimpleBindings; + import net.sourceforge.filebot.MediaTypes; import net.sourceforge.filebot.format.AssociativeScriptObject; @@ -18,10 +27,56 @@ public abstract class ScriptShellBaseClass extends Script { System.out.println(this); } - public Object _guarded(Closure c) { + public Object executeScript(String input, Map bindings, Object... args) throws Throwable { + // apply parent script defines + Bindings parameters = new SimpleBindings(); + + // initialize default parameter + parameters.putAll(bindings); + parameters.put(ScriptShell.ARGV_BINDING_NAME, asFileList(args)); + + // run given script + ScriptShell shell = (ScriptShell) getBinding().getVariable(ScriptShell.SHELL_BINDING_NAME); + return shell.runScript(input, parameters); + } + + private Map defaultValues; + + public void setDefaultValues(Map values) { + this.defaultValues = values; + } + + public Map getDefaultValues() { + return defaultValues == null ? null : unmodifiableMap(defaultValues); + } + + @Override + public Object getProperty(String property) { + try { + return super.getProperty(property); + } catch (MissingPropertyException e) { + // try user-defined default values + if (defaultValues != null && defaultValues.containsKey(property)) { + return defaultValues.get(property); + } + + // can't use default value, rethrow exception + throw e; + } + } + + public Object tryQuietly(Closure c) { try { return c.call(); - } catch (Throwable e) { + } catch (Exception e) { + return null; + } + } + + public Object tryLoudly(Closure c) { + try { + return c.call(); + } catch (Exception e) { CLILogger.severe(String.format("%s: %s", e.getClass().getSimpleName(), e.getMessage())); return null; } @@ -67,4 +122,18 @@ public abstract class ScriptShellBaseClass extends Script { return System.console(); } + public static List asFileList(Object... paths) { + List files = new ArrayList(); + for (Object it : paths) { + if (it instanceof CharSequence) { + files.add(new File(it.toString())); + } else if (it instanceof File) { + files.add((File) it); + } else if (it instanceof Path) { + files.add(((Path) it).toFile()); + } + } + return files; + } + }