* define --filter as include filter rather than exclude filter

This commit is contained in:
Reinhard Pointner 2012-03-26 01:18:27 +00:00
parent 0d1264febf
commit 2b5de3cf81
3 changed files with 41 additions and 13 deletions

View File

@ -170,24 +170,26 @@ public class CmdlineOperations implements CmdlineInterface {
// fetch episode data // fetch episode data
Set<Episode> episodes = fetchEpisodeSet(db, seriesNames, sortOrder, locale, strict); Set<Episode> episodes = fetchEpisodeSet(db, seriesNames, sortOrder, locale, strict);
if (episodes.size() == 0) {
CLILogger.warning("Failed to fetch episode data: " + seriesNames);
continue;
}
// filter episodes // filter episodes
if (filter != null) { if (filter != null) {
CLILogger.fine(String.format("Apply Filter: {%s}", filter.getExpression())); CLILogger.fine(String.format("Apply Filter: {%s}", filter.getExpression()));
for (Iterator<Episode> itr = episodes.iterator(); itr.hasNext();) { for (Iterator<Episode> itr = episodes.iterator(); itr.hasNext();) {
Episode episode = itr.next(); Episode episode = itr.next();
if (filter.matches(new MediaBindingBean(episode, null))) { if (filter.matches(new MediaBindingBean(episode, null))) {
CLILogger.finest(String.format("Exclude [%s]", episode)); CLILogger.finest(String.format("Include [%s]", episode));
} else {
itr.remove(); itr.remove();
} }
} }
} }
if (episodes.size() > 0) {
matches.addAll(matchEpisodes(filter(batch, VIDEO_FILES), episodes, strict)); matches.addAll(matchEpisodes(filter(batch, VIDEO_FILES), episodes, strict));
matches.addAll(matchEpisodes(filter(batch, SUBTITLE_FILES), episodes, strict)); matches.addAll(matchEpisodes(filter(batch, SUBTITLE_FILES), episodes, strict));
} else {
CLILogger.warning("Failed to fetch episode data: " + seriesNames);
}
} }
} }

View File

@ -11,6 +11,7 @@ import javax.script.CompiledScript;
import javax.script.ScriptContext; import javax.script.ScriptContext;
import javax.script.ScriptEngine; import javax.script.ScriptEngine;
import javax.script.ScriptException; import javax.script.ScriptException;
import javax.script.SimpleBindings;
import javax.script.SimpleScriptContext; import javax.script.SimpleScriptContext;
import org.codehaus.groovy.jsr223.GroovyScriptEngineFactory; import org.codehaus.groovy.jsr223.GroovyScriptEngineFactory;
@ -20,12 +21,18 @@ public class ExpressionFilter {
private final String expression; private final String expression;
private final CompiledScript script; private final CompiledScript userScript;
private final CompiledScript asBooleanScript;
private Throwable lastException;
public ExpressionFilter(String expression) throws ScriptException { public ExpressionFilter(String expression) throws ScriptException {
this.expression = expression; this.expression = expression;
this.script = new SecureCompiledScript(((Compilable) initScriptEngine()).compile(expression)); // sandboxed script
Compilable engine = (Compilable) initScriptEngine();
this.userScript = new SecureCompiledScript(engine.compile(expression)); // sandboxed script
this.asBooleanScript = engine.compile("value as Boolean");
} }
@ -34,6 +41,11 @@ public class ExpressionFilter {
} }
public Throwable getLastException() {
return lastException;
}
protected ScriptEngine initScriptEngine() throws ScriptException { protected ScriptEngine initScriptEngine() throws ScriptException {
// use Groovy script engine // use Groovy script engine
ScriptEngine engine = new GroovyScriptEngineFactory().getScriptEngine(); ScriptEngine engine = new GroovyScriptEngineFactory().getScriptEngine();
@ -48,6 +60,8 @@ public class ExpressionFilter {
public boolean matches(Bindings bindings) throws ScriptException { public boolean matches(Bindings bindings) throws ScriptException {
this.lastException = null;
// use privileged bindings so we are not restricted by the script sandbox // use privileged bindings so we are not restricted by the script sandbox
Bindings priviledgedBindings = PrivilegedInvocation.newProxy(Bindings.class, bindings, AccessController.getContext()); Bindings priviledgedBindings = PrivilegedInvocation.newProxy(Bindings.class, bindings, AccessController.getContext());
@ -56,12 +70,19 @@ public class ExpressionFilter {
context.setBindings(priviledgedBindings, ScriptContext.GLOBAL_SCOPE); context.setBindings(priviledgedBindings, ScriptContext.GLOBAL_SCOPE);
try { try {
Object value = script.eval(context); // evaluate user script
if (value instanceof Boolean) { Object value = userScript.eval(context);
return (Boolean) value;
// convert value to boolean
Bindings valueBinding = new SimpleBindings();
valueBinding.put("value", value);
Object result = asBooleanScript.eval(valueBinding);
if (result instanceof Boolean) {
return (Boolean) result;
} }
} catch (Throwable e) { } catch (Throwable e) {
// ignore any and all scripting exceptions // ignore any and all scripting exceptions
this.lastException = e;
} }
return false; return false;

View File

@ -198,6 +198,11 @@
<td>conflict resolution</td> <td>conflict resolution</td>
<td>override | skip | fail</td> <td>override | skip | fail</td>
</tr> </tr>
<tr>
<td>--filter</td>
<td>episode include rules</td>
<td>filter expression (e.g. &quot;y > 2000&quot;)</td>
</tr>
<tr> <tr>
<td>-get-subtitles</td> <td>-get-subtitles</td>
<td>fetch subtitles</td> <td>fetch subtitles</td>
@ -234,7 +239,7 @@
</tr> </tr>
<tr> <tr>
<td>-check</td> <td>-check</td>
<td>create/check verification file</td> <td>create/check sfv file</td>
<td>folder or sfv file</td> <td>folder or sfv file</td>
</tr> </tr>
<tr> <tr>