* improved fault-tolerance for fetch banner script

* santize Groovy stack trace
This commit is contained in:
Reinhard Pointner 2011-12-30 10:35:26 +00:00
parent 4390757fc3
commit a097daf079
5 changed files with 89 additions and 44 deletions

View File

@ -10,6 +10,7 @@ import java.io.File;
import java.security.AccessController;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.logging.Level;
import javax.script.Bindings;
import javax.script.SimpleBindings;
@ -93,8 +94,8 @@ public class ArgumentProcessor {
CLILogger.finest("Done ヾ(@⌒ー⌒@)");
return 0;
} catch (Exception e) {
CLILogger.severe(String.format("%s: %s", getRootCause(e).getClass().getSimpleName(), getRootCauseMessage(e)));
} catch (Throwable e) {
CLILogger.log(Level.SEVERE, String.format("%s: %s", getRootCause(e).getClass().getSimpleName(), getRootCauseMessage(e)), getRootCause(e));
CLILogger.finest("Failure (°_°)");
return -1;
}

View File

@ -4,6 +4,7 @@ package net.sourceforge.filebot.cli;
import static java.lang.System.*;
import java.io.PrintStream;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
@ -14,7 +15,7 @@ class CLILogging extends Handler {
public static final Logger CLILogger = createCommandlineLogger("net.sourceforge.filebot.cli");
private static Logger createCommandlineLogger(String name) {
Logger log = Logger.getLogger(name);
log.setLevel(Level.ALL);
@ -28,13 +29,16 @@ class CLILogging extends Handler {
return log;
}
@Override
public void publish(LogRecord record) {
if (record.getLevel().intValue() <= getLevel().intValue())
return;
// print messages to stdout
// use either System.out or System.err depending on the severity of the error
PrintStream out = record.getLevel().intValue() < Level.WARNING.intValue() ? System.out : System.err;
// print messages
out.println(record.getMessage());
if (record.getThrown() != null) {
record.getThrown().printStackTrace(out);
@ -44,13 +48,13 @@ class CLILogging extends Handler {
out.flush();
}
@Override
public void close() throws SecurityException {
}
@Override
public void flush() {
out.flush();

View File

@ -29,6 +29,7 @@ import javax.script.SimpleBindings;
import javax.script.SimpleScriptContext;
import org.codehaus.groovy.jsr223.GroovyScriptEngineFactory;
import org.codehaus.groovy.runtime.StackTraceUtils;
import net.sourceforge.filebot.MediaTypes;
import net.sourceforge.filebot.WebServices;
@ -92,7 +93,7 @@ class ScriptShell {
}
public Object run(URL scriptLocation, Bindings bindings) throws Exception {
public Object run(URL scriptLocation, Bindings bindings) throws Throwable {
if (scriptLocation.getProtocol().equals("file")) {
return run(new File(scriptLocation.toURI()), bindings);
}
@ -109,27 +110,31 @@ class ScriptShell {
}
public Object run(File scriptFile, Bindings bindings) throws Exception {
public Object run(File scriptFile, Bindings bindings) throws Throwable {
String script = readAll(new InputStreamReader(new FileInputStream(scriptFile), "UTF-8"));
return evaluate(script, bindings);
}
public Object evaluate(final String script, final Bindings bindings) throws Exception {
if (trustScript) {
return engine.eval(script, bindings);
}
public Object evaluate(final String script, final Bindings bindings) throws Throwable {
try {
return AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws ScriptException {
return engine.eval(script, bindings);
}
}, getSandboxAccessControlContext());
} catch (PrivilegedActionException e) {
throw e.getException();
if (trustScript) {
return engine.eval(script, bindings);
}
try {
return AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws ScriptException {
return engine.eval(script, bindings);
}
}, getSandboxAccessControlContext());
} catch (PrivilegedActionException e) {
throw e.getException();
}
} catch (Throwable e) {
throw StackTraceUtils.deepSanitize(e); // make Groovy stack human-readable
}
}

View File

@ -19,6 +19,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -638,15 +639,18 @@ public class TheTVDBClient extends AbstractEpisodeListProvider {
*
* @see http://thetvdb.com/wiki/index.php/API:banners.xml
*/
public BannerDescriptor getBanner(TheTVDBSearchResult series, String bannerType, String bannerType2, Integer season, Locale locale, int index) throws Exception {
public BannerDescriptor getBanner(TheTVDBSearchResult series, Map<?, ?> filterDescriptor) throws Exception {
EnumMap<BannerProperty, String> filter = new EnumMap<BannerProperty, String>(BannerProperty.class);
for (Entry<?, ?> it : filterDescriptor.entrySet()) {
if (it.getValue() != null) {
filter.put(BannerProperty.valueOf(it.getKey().toString()), it.getValue().toString());
}
}
// search for a banner matching the selector
int n = 0;
for (BannerDescriptor it : getBannerList(series)) {
if ((bannerType == null || it.getBannerType().equalsIgnoreCase(bannerType)) && (bannerType2 == null || it.getBannerType2().equalsIgnoreCase(bannerType2)) && (season == null || it.getSeason().equals(season))
&& ((locale == null && it.getLocale().getLanguage().equals("en")) || it.getLocale().getLanguage().equals(locale.getLanguage()))) {
if (index == n++) {
return it;
}
if (it.fields.entrySet().containsAll(filter.entrySet())) {
return it;
}
}
@ -736,12 +740,20 @@ public class TheTVDBClient extends AbstractEpisodeListProvider {
public URL getBannerMirrorUrl() throws MalformedURLException {
return new URL(get(BannerProperty.BannerMirror));
try {
return new URL(get(BannerProperty.BannerMirror));
} catch (Exception e) {
return null;
}
}
public URL getUrl() throws MalformedURLException {
return new URL(getBannerMirrorUrl(), get(BannerProperty.BannerPath));
try {
return new URL(getBannerMirrorUrl(), get(BannerProperty.BannerPath));
} catch (Exception e) {
return null;
}
}
@ -750,8 +762,12 @@ public class TheTVDBClient extends AbstractEpisodeListProvider {
}
public int getId() {
return Integer.parseInt(get(BannerProperty.id));
public Integer getId() {
try {
return new Integer(get(BannerProperty.id));
} catch (Exception e) {
return null;
}
}
@ -780,17 +796,29 @@ public class TheTVDBClient extends AbstractEpisodeListProvider {
public Locale getLocale() {
return new Locale(get(BannerProperty.Language));
try {
return new Locale(get(BannerProperty.Language));
} catch (Exception e) {
return null;
}
}
public double getRating() {
return Double.parseDouble(get(BannerProperty.Rating));
public Double getRating() {
try {
return new Double(get(BannerProperty.Rating));
} catch (Exception e) {
return null;
}
}
public int getRatingCount() {
return Integer.parseInt(get(BannerProperty.RatingCount));
public Integer getRatingCount() {
try {
return new Integer(get(BannerProperty.RatingCount));
} catch (Exception e) {
return null;
}
}
@ -800,12 +828,20 @@ public class TheTVDBClient extends AbstractEpisodeListProvider {
public URL getThumbnailUrl() throws MalformedURLException {
return new URL(getBannerMirrorUrl(), get(BannerProperty.ThumbnailPath));
try {
return new URL(getBannerMirrorUrl(), get(BannerProperty.ThumbnailPath));
} catch (Exception e) {
return null;
}
}
public URL getVignetteUrl() throws MalformedURLException {
return new URL(getBannerMirrorUrl(), get(BannerProperty.VignettePath));
try {
return new URL(getBannerMirrorUrl(), get(BannerProperty.VignettePath));
} catch (Exception e) {
return null;
}
}

View File

@ -1,8 +1,7 @@
// filebot -script "http://filebot.sf.net/scripts/artwork.tvdb.groovy" -trust-script /path/to/media/
// EXPERIMENTAL // HERE THERE BE DRAGONS
if (net.sourceforge.filebot.Settings.applicationRevisionNumber < 812) throw new Exception("Application revision too old")
if (net.sourceforge.filebot.Settings.applicationRevisionNumber < 815) throw new Exception("Application revision too old")
/*
* Fetch series and season banners for all tv shows. Series name is auto-detected if possible or the folder name is used.
@ -10,7 +9,7 @@ if (net.sourceforge.filebot.Settings.applicationRevisionNumber < 812) throw new
def fetchBanner(outputFile, series, bannerType, bannerType2 = null, season = null) {
// select and fetch banner
def banner = TheTVDB.getBanner(series, bannerType, bannerType2, season, Locale.ENGLISH, 0)
def banner = ['en', null].findResult { TheTVDB.getBanner(series, [BannerType:bannerType, BannerType2:bannerType2, Season:season, Language:it]) }
if (banner == null) {
println "Banner not found: $outputFile / $bannerType:$bannerType2"
return null