* refactoring of ExpressionFormat and related classes
This commit is contained in:
parent
09a1e0b731
commit
54bf7c2ca3
|
@ -1,41 +0,0 @@
|
||||||
|
|
||||||
package net.sourceforge.filebot.format;
|
|
||||||
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
import javax.script.Bindings;
|
|
||||||
import javax.script.ScriptException;
|
|
||||||
|
|
||||||
import net.sourceforge.filebot.similarity.Match;
|
|
||||||
import net.sourceforge.filebot.web.Episode;
|
|
||||||
|
|
||||||
|
|
||||||
public class EpisodeExpressionFormat extends ExpressionFormat {
|
|
||||||
|
|
||||||
public EpisodeExpressionFormat(String format) throws ScriptException {
|
|
||||||
super(format);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Bindings getBindings(Object value) {
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
Match<Episode, File> match = (Match<Episode, File>) value;
|
|
||||||
|
|
||||||
return new ExpressionBindings(new EpisodeFormatBindingBean(match.getValue(), match.getCandidate()));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void dispose(Bindings bindings) {
|
|
||||||
// dispose binding bean
|
|
||||||
getBindingBean(bindings).dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private EpisodeFormatBindingBean getBindingBean(Bindings bindings) {
|
|
||||||
return (EpisodeFormatBindingBean) ((ExpressionBindings) bindings).getBindingBean();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -8,6 +8,7 @@ import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.util.Scanner;
|
||||||
import java.util.zip.CRC32;
|
import java.util.zip.CRC32;
|
||||||
|
|
||||||
import net.sf.ehcache.Cache;
|
import net.sf.ehcache.Cache;
|
||||||
|
@ -17,7 +18,6 @@ import net.sourceforge.filebot.FileBotUtilities;
|
||||||
import net.sourceforge.filebot.mediainfo.MediaInfo;
|
import net.sourceforge.filebot.mediainfo.MediaInfo;
|
||||||
import net.sourceforge.filebot.mediainfo.MediaInfo.StreamKind;
|
import net.sourceforge.filebot.mediainfo.MediaInfo.StreamKind;
|
||||||
import net.sourceforge.filebot.web.Episode;
|
import net.sourceforge.filebot.web.Episode;
|
||||||
import net.sourceforge.tuned.FileUtilities;
|
|
||||||
|
|
||||||
|
|
||||||
public class EpisodeFormatBindingBean {
|
public class EpisodeFormatBindingBean {
|
||||||
|
@ -91,6 +91,15 @@ public class EpisodeFormatBindingBean {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Define("ext")
|
||||||
|
public String getContainerExtension() {
|
||||||
|
String extensions = getMediaInfo(StreamKind.General, 0, "Codec/Extensions");
|
||||||
|
|
||||||
|
// get first token
|
||||||
|
return new Scanner(extensions).next();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Define("resolution")
|
@Define("resolution")
|
||||||
public String getVideoResolution() {
|
public String getVideoResolution() {
|
||||||
String width = getMediaInfo(StreamKind.Video, 0, "Width");
|
String width = getMediaInfo(StreamKind.Video, 0, "Width");
|
||||||
|
@ -122,16 +131,6 @@ public class EpisodeFormatBindingBean {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Define("ext")
|
|
||||||
public String getExtension() {
|
|
||||||
if (mediaFile != null) {
|
|
||||||
return FileUtilities.getExtension(mediaFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Define("general")
|
@Define("general")
|
||||||
public Object getGeneralMediaInfo() {
|
public Object getGeneralMediaInfo() {
|
||||||
return new AssociativeScriptObject(getMediaInfo().snapshot(StreamKind.General, 0));
|
return new AssociativeScriptObject(getMediaInfo().snapshot(StreamKind.General, 0));
|
||||||
|
@ -162,6 +161,16 @@ public class EpisodeFormatBindingBean {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Episode getEpisode() {
|
||||||
|
return episode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public File getMediaFile() {
|
||||||
|
return mediaFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public synchronized MediaInfo getMediaInfo() {
|
public synchronized MediaInfo getMediaInfo() {
|
||||||
if (mediaFile == null) {
|
if (mediaFile == null) {
|
||||||
throw new NullPointerException("Media file is null");
|
throw new NullPointerException("Media file is null");
|
||||||
|
@ -179,16 +188,6 @@ public class EpisodeFormatBindingBean {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public synchronized void dispose() {
|
|
||||||
if (mediaInfo != null) {
|
|
||||||
mediaInfo.close();
|
|
||||||
mediaInfo.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
mediaInfo = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private String getMediaInfo(StreamKind streamKind, int streamNumber, String... keys) {
|
private String getMediaInfo(StreamKind streamKind, int streamNumber, String... keys) {
|
||||||
for (String key : keys) {
|
for (String key : keys) {
|
||||||
String value = getMediaInfo().get(streamKind, streamNumber, key);
|
String value = getMediaInfo().get(streamKind, streamNumber, key);
|
||||||
|
|
|
@ -84,45 +84,40 @@ public class ExpressionFormat extends Format {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected Bindings getBindings(Object value) {
|
public Bindings getBindings(Object value) {
|
||||||
// no bindings by default
|
return new ExpressionBindings(value);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StringBuffer format(Object object, StringBuffer sb, FieldPosition pos) {
|
public StringBuffer format(Object object, StringBuffer sb, FieldPosition pos) {
|
||||||
Bindings bindings = getBindings(object);
|
return format(getBindings(object), sb);
|
||||||
|
|
||||||
ScriptContext context = new SimpleScriptContext();
|
|
||||||
context.setBindings(bindings, ScriptContext.GLOBAL_SCOPE);
|
|
||||||
|
|
||||||
try {
|
|
||||||
for (Object snipped : expressions) {
|
|
||||||
if (snipped instanceof CompiledScript) {
|
|
||||||
try {
|
|
||||||
Object value = ((CompiledScript) snipped).eval(context);
|
|
||||||
|
|
||||||
if (value != null) {
|
|
||||||
sb.append(value);
|
|
||||||
}
|
|
||||||
} catch (ScriptException e) {
|
|
||||||
lastException = e;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sb.append(snipped);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
dispose(bindings);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sb;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void dispose(Bindings bindings) {
|
public StringBuffer format(Bindings bindings, StringBuffer sb) {
|
||||||
|
ScriptContext context = new SimpleScriptContext();
|
||||||
|
context.setBindings(bindings, ScriptContext.GLOBAL_SCOPE);
|
||||||
|
|
||||||
|
for (Object snipped : expressions) {
|
||||||
|
if (snipped instanceof CompiledScript) {
|
||||||
|
try {
|
||||||
|
Object value = ((CompiledScript) snipped).eval(context);
|
||||||
|
|
||||||
|
if (value != null) {
|
||||||
|
sb.append(value);
|
||||||
|
}
|
||||||
|
} catch (ScriptException e) {
|
||||||
|
lastException = e;
|
||||||
|
} catch (Exception e) {
|
||||||
|
lastException = new ScriptException(e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sb.append(snipped);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.text.Format;
|
import java.text.Format;
|
||||||
|
import java.text.ParseException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
|
@ -50,8 +51,8 @@ import javax.swing.filechooser.FileNameExtensionFilter;
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
import net.sourceforge.filebot.ResourceManager;
|
import net.sourceforge.filebot.ResourceManager;
|
||||||
import net.sourceforge.filebot.Settings;
|
import net.sourceforge.filebot.Settings;
|
||||||
import net.sourceforge.filebot.format.EpisodeExpressionFormat;
|
import net.sourceforge.filebot.format.EpisodeFormatBindingBean;
|
||||||
import net.sourceforge.filebot.similarity.Match;
|
import net.sourceforge.filebot.format.ExpressionFormat;
|
||||||
import net.sourceforge.filebot.web.Episode;
|
import net.sourceforge.filebot.web.Episode;
|
||||||
import net.sourceforge.filebot.web.Episode.EpisodeFormat;
|
import net.sourceforge.filebot.web.Episode.EpisodeFormat;
|
||||||
import net.sourceforge.tuned.ExceptionUtilities;
|
import net.sourceforge.tuned.ExceptionUtilities;
|
||||||
|
@ -72,8 +73,7 @@ public class EpisodeFormatDialog extends JDialog {
|
||||||
private JLabel warningMessage = new JLabel(ResourceManager.getIcon("status.warning"));
|
private JLabel warningMessage = new JLabel(ResourceManager.getIcon("status.warning"));
|
||||||
private JLabel errorMessage = new JLabel(ResourceManager.getIcon("status.error"));
|
private JLabel errorMessage = new JLabel(ResourceManager.getIcon("status.error"));
|
||||||
|
|
||||||
private Episode previewSampleEpisode = getPreviewSampleEpisode();
|
private EpisodeFormatBindingBean previewSample = new EpisodeFormatBindingBean(getPreviewSampleEpisode(), getPreviewSampleMediaFile());
|
||||||
private File previewSampleMediaFile = getPreviewSampleMediaFile();
|
|
||||||
|
|
||||||
private ExecutorService previewExecutor = createPreviewExecutor();
|
private ExecutorService previewExecutor = createPreviewExecutor();
|
||||||
|
|
||||||
|
@ -138,9 +138,6 @@ public class EpisodeFormatDialog extends JDialog {
|
||||||
|
|
||||||
setLocation(TunedUtilities.getPreferredLocation(this));
|
setLocation(TunedUtilities.getPreferredLocation(this));
|
||||||
|
|
||||||
// update preview to current format
|
|
||||||
checkFormatInBackground();
|
|
||||||
|
|
||||||
// update format on change
|
// update format on change
|
||||||
editor.getDocument().addDocumentListener(new LazyDocumentAdapter() {
|
editor.getDocument().addDocumentListener(new LazyDocumentAdapter() {
|
||||||
|
|
||||||
|
@ -166,6 +163,9 @@ public class EpisodeFormatDialog extends JDialog {
|
||||||
editor.requestFocusInWindow();
|
editor.requestFocusInWindow();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// update preview to current format
|
||||||
|
firePreviewSampleChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -176,16 +176,18 @@ public class EpisodeFormatDialog extends JDialog {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent evt) {
|
public void actionPerformed(ActionEvent evt) {
|
||||||
String episode = JOptionPane.showInputDialog(EpisodeFormatDialog.this, null, previewSampleEpisode);
|
String episodeString = JOptionPane.showInputDialog(EpisodeFormatDialog.this, null, EpisodeFormat.getInstance().format(previewSample.getEpisode()));
|
||||||
|
|
||||||
if (episode != null) {
|
if (episodeString != null) {
|
||||||
try {
|
try {
|
||||||
previewSampleEpisode = EpisodeFormat.getInstance().parseObject(episode);
|
Episode episode = EpisodeFormat.getInstance().parseObject(episodeString);
|
||||||
Settings.userRoot().put("dialog.sample.episode", episode);
|
|
||||||
|
|
||||||
EpisodeFormatDialog.this.firePropertyChange("previewSample", null, previewSample());
|
// change episode
|
||||||
} catch (Exception e) {
|
previewSample = new EpisodeFormatBindingBean(episode, previewSample.getMediaFile());
|
||||||
Logger.getLogger("ui").warning(String.format("Cannot parse %s", episode));
|
Settings.userRoot().put("dialog.sample.episode", episodeString);
|
||||||
|
firePreviewSampleChanged();
|
||||||
|
} catch (ParseException e) {
|
||||||
|
Logger.getLogger("ui").warning(String.format("Cannot parse %s", episodeString));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -196,15 +198,14 @@ public class EpisodeFormatDialog extends JDialog {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent evt) {
|
public void actionPerformed(ActionEvent evt) {
|
||||||
JFileChooser fileChooser = new JFileChooser();
|
JFileChooser fileChooser = new JFileChooser();
|
||||||
fileChooser.setSelectedFile(previewSampleMediaFile);
|
fileChooser.setSelectedFile(previewSample.getMediaFile());
|
||||||
fileChooser.setFileFilter(new FileNameExtensionFilter("Media files", "avi", "mkv", "mp4", "ogm"));
|
fileChooser.setFileFilter(new FileNameExtensionFilter("Media files", "avi", "mkv", "mp4", "ogm"));
|
||||||
|
|
||||||
if (fileChooser.showOpenDialog(EpisodeFormatDialog.this) == JFileChooser.APPROVE_OPTION) {
|
if (fileChooser.showOpenDialog(EpisodeFormatDialog.this) == JFileChooser.APPROVE_OPTION) {
|
||||||
previewSampleMediaFile = fileChooser.getSelectedFile();
|
File mediaFile = fileChooser.getSelectedFile();
|
||||||
Settings.userRoot().put("dialog.sample.file", previewSampleMediaFile.getAbsolutePath());
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
MediaInfoComponent.showMessageDialog(EpisodeFormatDialog.this, previewSampleMediaFile);
|
MediaInfoComponent.showMessageDialog(EpisodeFormatDialog.this, mediaFile);
|
||||||
} catch (LinkageError e) {
|
} catch (LinkageError e) {
|
||||||
// MediaInfo native library is missing -> notify user
|
// MediaInfo native library is missing -> notify user
|
||||||
Logger.getLogger("ui").log(Level.SEVERE, e.getMessage(), e);
|
Logger.getLogger("ui").log(Level.SEVERE, e.getMessage(), e);
|
||||||
|
@ -213,7 +214,10 @@ public class EpisodeFormatDialog extends JDialog {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
EpisodeFormatDialog.this.firePropertyChange("previewSample", null, previewSample());
|
// change media file
|
||||||
|
previewSample = new EpisodeFormatBindingBean(previewSample.getEpisode(), mediaFile);
|
||||||
|
Settings.userRoot().put("dialog.sample.file", mediaFile.getAbsolutePath());
|
||||||
|
firePreviewSampleChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -265,11 +269,6 @@ public class EpisodeFormatDialog extends JDialog {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Match<Episode, File> previewSample() {
|
|
||||||
return new Match<Episode, File>(previewSampleEpisode, previewSampleMediaFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private Episode getPreviewSampleEpisode() {
|
private Episode getPreviewSampleEpisode() {
|
||||||
String sample = Settings.userRoot().get("dialog.sample.episode");
|
String sample = Settings.userRoot().get("dialog.sample.episode");
|
||||||
|
|
||||||
|
@ -328,9 +327,9 @@ public class EpisodeFormatDialog extends JDialog {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String doInBackground() throws Exception {
|
protected String doInBackground() throws Exception {
|
||||||
EpisodeExpressionFormat format = new EpisodeExpressionFormat(editor.getText().trim());
|
ExpressionFormat format = new ExpressionFormat(editor.getText().trim());
|
||||||
|
|
||||||
String text = format.format(previewSample());
|
String text = format.format(previewSample);
|
||||||
warning = format.scriptException();
|
warning = format.scriptException();
|
||||||
|
|
||||||
// check if format produces empty strings
|
// check if format produces empty strings
|
||||||
|
@ -344,7 +343,6 @@ public class EpisodeFormatDialog extends JDialog {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void done() {
|
protected void done() {
|
||||||
|
|
||||||
Exception error = null;
|
Exception error = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -405,7 +403,7 @@ public class EpisodeFormatDialog extends JDialog {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent evt) {
|
public void actionPerformed(ActionEvent evt) {
|
||||||
try {
|
try {
|
||||||
finish(new EpisodeExpressionFormat(editor.getText()));
|
finish(new ExpressionFormat(editor.getText()));
|
||||||
Settings.userRoot().put("dialog.format", editor.getText());
|
Settings.userRoot().put("dialog.format", editor.getText());
|
||||||
} catch (ScriptException e) {
|
} catch (ScriptException e) {
|
||||||
Logger.getLogger("ui").log(Level.WARNING, ExceptionUtilities.getRootCauseMessage(e), e);
|
Logger.getLogger("ui").log(Level.WARNING, ExceptionUtilities.getRootCauseMessage(e), e);
|
||||||
|
@ -414,6 +412,11 @@ public class EpisodeFormatDialog extends JDialog {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
protected void firePreviewSampleChanged() {
|
||||||
|
firePropertyChange("previewSample", null, previewSample);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static Format showDialog(Component parent) {
|
public static Format showDialog(Component parent) {
|
||||||
EpisodeFormatDialog dialog = new EpisodeFormatDialog(TunedUtilities.getWindow(parent));
|
EpisodeFormatDialog dialog = new EpisodeFormatDialog(TunedUtilities.getWindow(parent));
|
||||||
|
|
||||||
|
@ -439,35 +442,23 @@ public class EpisodeFormatDialog extends JDialog {
|
||||||
|
|
||||||
protected class ExampleFormatLabel extends JLabel {
|
protected class ExampleFormatLabel extends JLabel {
|
||||||
|
|
||||||
private final String format;
|
public ExampleFormatLabel(final String format) {
|
||||||
|
|
||||||
|
|
||||||
public ExampleFormatLabel(String format) {
|
|
||||||
this.format = format;
|
|
||||||
|
|
||||||
// initialize text
|
|
||||||
updateText(previewSample());
|
|
||||||
|
|
||||||
// bind text to preview
|
// bind text to preview
|
||||||
EpisodeFormatDialog.this.addPropertyChangeListener("previewSample", new PropertyChangeListener() {
|
EpisodeFormatDialog.this.addPropertyChangeListener("previewSample", new PropertyChangeListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void propertyChange(PropertyChangeEvent evt) {
|
public void propertyChange(PropertyChangeEvent evt) {
|
||||||
updateText(evt.getNewValue());
|
try {
|
||||||
|
setText(new ExpressionFormat(format).format(previewSample));
|
||||||
|
setForeground(defaultColor);
|
||||||
|
} catch (Exception e) {
|
||||||
|
setText(ExceptionUtilities.getRootCauseMessage(e));
|
||||||
|
setForeground(errorColor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void updateText(Object episode) {
|
|
||||||
try {
|
|
||||||
setText(new EpisodeExpressionFormat(format).format(episode));
|
|
||||||
setForeground(defaultColor);
|
|
||||||
} catch (Exception e) {
|
|
||||||
setText(ExceptionUtilities.getRootCauseMessage(e));
|
|
||||||
setForeground(errorColor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -57,13 +57,14 @@ public class ExpressionFormatTest {
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Bindings getBindings(Object value) {
|
public Bindings getBindings(Object value) {
|
||||||
Bindings bindings = new SimpleBindings();
|
Bindings bindings = new SimpleBindings();
|
||||||
|
|
||||||
bindings.put("value", value);
|
bindings.put("value", value);
|
||||||
|
|
||||||
return bindings;
|
return bindings;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue