Refactor ExpressionFormat into generic ExpressionFormat (used by -mediainfo and -list calls) and ExpressionFileFormat (used when generating output paths) that performs all the file path validation logic (strip spaces, don't allow /\ in binding values, etc)
This commit is contained in:
parent
1d91160521
commit
f28e41626f
|
@ -31,6 +31,7 @@ import net.filebot.Language;
|
|||
import net.filebot.StandardRenameAction;
|
||||
import net.filebot.WebServices;
|
||||
import net.filebot.format.ExpressionFileFilter;
|
||||
import net.filebot.format.ExpressionFileFormat;
|
||||
import net.filebot.format.ExpressionFilter;
|
||||
import net.filebot.format.ExpressionFormat;
|
||||
import net.filebot.hash.HashType;
|
||||
|
@ -216,6 +217,10 @@ public class ArgumentBean {
|
|||
return format == null ? null : new ExpressionFormat(format);
|
||||
}
|
||||
|
||||
public ExpressionFileFormat getExpressionFileFormat() throws Exception {
|
||||
return format == null ? null : new ExpressionFileFormat(format);
|
||||
}
|
||||
|
||||
public ExpressionFilter getExpressionFilter() throws Exception {
|
||||
return filter == null ? null : new ExpressionFilter(filter);
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ public class ArgumentProcessor {
|
|||
}
|
||||
|
||||
if (args.rename) {
|
||||
cli.rename(files, args.getRenameAction(), args.getConflictAction(), args.getAbsoluteOutputFolder(), args.getExpressionFormat(), args.getDatasource(), args.getSearchQuery(), args.getSortOrder(), args.getExpressionFilter(), args.getLanguage().getLocale(), args.isStrict());
|
||||
cli.rename(files, args.getRenameAction(), args.getConflictAction(), args.getAbsoluteOutputFolder(), args.getExpressionFileFormat(), args.getDatasource(), args.getSearchQuery(), args.getSortOrder(), args.getExpressionFilter(), args.getLanguage().getLocale(), args.isStrict());
|
||||
}
|
||||
|
||||
if (args.check) {
|
||||
|
|
|
@ -11,6 +11,7 @@ import java.util.stream.Stream;
|
|||
|
||||
import net.filebot.Language;
|
||||
import net.filebot.RenameAction;
|
||||
import net.filebot.format.ExpressionFileFormat;
|
||||
import net.filebot.format.ExpressionFilter;
|
||||
import net.filebot.format.ExpressionFormat;
|
||||
import net.filebot.hash.HashType;
|
||||
|
@ -22,7 +23,7 @@ import net.filebot.web.SortOrder;
|
|||
|
||||
public interface CmdlineInterface {
|
||||
|
||||
List<File> rename(Collection<File> files, RenameAction action, ConflictAction conflict, File output, ExpressionFormat format, Datasource db, String query, SortOrder order, ExpressionFilter filter, Locale locale, boolean strict) throws Exception;
|
||||
List<File> rename(Collection<File> files, RenameAction action, ConflictAction conflict, File output, ExpressionFileFormat format, Datasource db, String query, SortOrder order, ExpressionFilter filter, Locale locale, boolean strict) throws Exception;
|
||||
|
||||
List<File> rename(Map<File, File> rename, RenameAction action, ConflictAction conflict) throws Exception;
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ import net.filebot.RenameAction;
|
|||
import net.filebot.StandardRenameAction;
|
||||
import net.filebot.archive.Archive;
|
||||
import net.filebot.archive.FileMapper;
|
||||
import net.filebot.format.ExpressionFileFormat;
|
||||
import net.filebot.format.ExpressionFilter;
|
||||
import net.filebot.format.ExpressionFormat;
|
||||
import net.filebot.format.MediaBindingBean;
|
||||
|
@ -85,7 +86,7 @@ import net.filebot.web.VideoHashSubtitleService;
|
|||
public class CmdlineOperations implements CmdlineInterface {
|
||||
|
||||
@Override
|
||||
public List<File> rename(Collection<File> files, RenameAction action, ConflictAction conflict, File output, ExpressionFormat format, Datasource db, String query, SortOrder order, ExpressionFilter filter, Locale locale, boolean strict) throws Exception {
|
||||
public List<File> rename(Collection<File> files, RenameAction action, ConflictAction conflict, File output, ExpressionFileFormat format, Datasource db, String query, SortOrder order, ExpressionFilter filter, Locale locale, boolean strict) throws Exception {
|
||||
// movie mode
|
||||
if (db instanceof MovieIdentificationService) {
|
||||
return renameMovie(files, action, conflict, output, format, (MovieIdentificationService) db, query, filter, locale, strict);
|
||||
|
|
|
@ -219,11 +219,8 @@ public abstract class ScriptShellBaseClass extends Script {
|
|||
public String getMediaInfo(File file, String format) throws Exception {
|
||||
ExpressionFormat formatter = new ExpressionFormat(format);
|
||||
|
||||
Object o = xattr.getMetaInfo(file);
|
||||
File f = file.getCanonicalFile();
|
||||
|
||||
try {
|
||||
return formatter.format(new MediaBindingBean(o, f));
|
||||
return formatter.format(new MediaBindingBean(xattr.getMetaInfo(file), file));
|
||||
} catch (SuppressedThrowables e) {
|
||||
debug.finest(format("%s => %s", format, e.getMessage()));
|
||||
}
|
||||
|
@ -342,7 +339,7 @@ public abstract class ScriptShellBaseClass extends Script {
|
|||
|
||||
try {
|
||||
if (files.size() > 0) {
|
||||
return getCLI().rename(files, args.getRenameAction(), args.getConflictAction(), args.getAbsoluteOutputFolder(), args.getExpressionFormat(), args.getDatasource(), args.getSearchQuery(), args.getSortOrder(), args.getExpressionFilter(), args.getLanguage().getLocale(), args.isStrict());
|
||||
return getCLI().rename(files, args.getRenameAction(), args.getConflictAction(), args.getAbsoluteOutputFolder(), args.getExpressionFileFormat(), args.getDatasource(), args.getSearchQuery(), args.getSortOrder(), args.getExpressionFilter(), args.getLanguage().getLocale(), args.isStrict());
|
||||
}
|
||||
|
||||
if (map.size() > 0) {
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
package net.filebot.format;
|
||||
|
||||
import static net.filebot.similarity.Normalization.*;
|
||||
import static net.filebot.util.FileUtilities.*;
|
||||
|
||||
import javax.script.Bindings;
|
||||
import javax.script.ScriptException;
|
||||
|
||||
public class ExpressionFileFormat extends ExpressionFormat {
|
||||
|
||||
public ExpressionFileFormat(String expression) throws ScriptException {
|
||||
super(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bindings getBindings(Object value) {
|
||||
return new ExpressionBindings(value) {
|
||||
|
||||
@Override
|
||||
public Object get(Object key) {
|
||||
return normalizeBindingValue(super.get(key));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected Object normalizeBindingValue(Object value) {
|
||||
// if the binding value is a String, then remove illegal characters (that would insert accidental directory separators)
|
||||
if (value instanceof CharSequence) {
|
||||
return replacePathSeparators(value.toString(), " ");
|
||||
}
|
||||
|
||||
// if the binding value is an Object, just leave it
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String normalizeResult(CharSequence value) {
|
||||
// normalize unicode space characters and remove newline characters
|
||||
return normalizePathSeparators(replaceSpace(value, " ").trim());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,9 +1,6 @@
|
|||
package net.filebot.format;
|
||||
|
||||
import static net.filebot.similarity.Normalization.*;
|
||||
import static net.filebot.util.ExceptionUtilities.*;
|
||||
import static net.filebot.util.FileUtilities.*;
|
||||
import static net.filebot.util.RegularExpressions.*;
|
||||
|
||||
import java.security.AccessController;
|
||||
import java.text.FieldPosition;
|
||||
|
@ -66,7 +63,7 @@ public class ExpressionFormat extends Format {
|
|||
if (c == open) {
|
||||
if (level == 0) {
|
||||
if (token.length() > 0) {
|
||||
compilation.add(NEWLINE.matcher(token).replaceAll(""));
|
||||
compilation.add(token.toString());
|
||||
token.setLength(0);
|
||||
}
|
||||
} else {
|
||||
|
@ -124,13 +121,7 @@ public class ExpressionFormat extends Format {
|
|||
}
|
||||
|
||||
public Bindings getBindings(Object value) {
|
||||
return new ExpressionBindings(value) {
|
||||
|
||||
@Override
|
||||
public Object get(Object key) {
|
||||
return normalizeBindingValue(super.get(key));
|
||||
}
|
||||
};
|
||||
return new ExpressionBindings(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -183,26 +174,15 @@ public class ExpressionFormat extends Format {
|
|||
}
|
||||
|
||||
protected Object normalizeBindingValue(Object value) {
|
||||
// if the binding value is a String, remove illegal characters
|
||||
if (value instanceof CharSequence) {
|
||||
return replacePathSeparators((CharSequence) value, " ").trim();
|
||||
}
|
||||
|
||||
// if the binding value is an Object, just leave it
|
||||
return value;
|
||||
}
|
||||
|
||||
protected CharSequence normalizeExpressionValue(Object value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return normalizePathSeparators(value.toString());
|
||||
return value == null ? null : value.toString();
|
||||
}
|
||||
|
||||
protected String normalizeResult(CharSequence value) {
|
||||
// normalize unicode space characters and remove newline characters
|
||||
return replaceSpace(value, " ").trim();
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
protected Throwable normalizeExpressionException(ScriptException exception) {
|
||||
|
|
|
@ -12,14 +12,14 @@ import java.util.logging.Level;
|
|||
import javax.script.ScriptException;
|
||||
|
||||
import net.filebot.ApplicationFolder;
|
||||
import net.filebot.format.ExpressionFormat;
|
||||
import net.filebot.format.ExpressionFileFormat;
|
||||
import net.filebot.format.MediaBindingBean;
|
||||
import net.filebot.similarity.Match;
|
||||
|
||||
class ExpressionFormatter implements MatchFormatter {
|
||||
|
||||
private final String expression;
|
||||
private ExpressionFormat format;
|
||||
private ExpressionFileFormat format;
|
||||
|
||||
private Format preview;
|
||||
private Class<?> target;
|
||||
|
@ -34,7 +34,7 @@ class ExpressionFormatter implements MatchFormatter {
|
|||
this.target = target;
|
||||
}
|
||||
|
||||
public ExpressionFormatter(ExpressionFormat format, Format preview, Class<?> target) {
|
||||
public ExpressionFormatter(ExpressionFileFormat format, Format preview, Class<?> target) {
|
||||
this(format.getExpression(), preview, target);
|
||||
|
||||
// use compiled format expression right away
|
||||
|
@ -60,7 +60,7 @@ class ExpressionFormatter implements MatchFormatter {
|
|||
public synchronized String format(Match<?, ?> match, boolean extension, Map<?, ?> context) throws ScriptException {
|
||||
// lazy initialize script engine
|
||||
if (format == null) {
|
||||
format = new ExpressionFormat(expression);
|
||||
format = new ExpressionFileFormat(expression);
|
||||
}
|
||||
|
||||
// evaluate the expression using the given bindings
|
||||
|
|
|
@ -61,6 +61,7 @@ import net.filebot.ResourceManager;
|
|||
import net.filebot.Settings;
|
||||
import net.filebot.UserFiles;
|
||||
import net.filebot.format.BindingException;
|
||||
import net.filebot.format.ExpressionFileFormat;
|
||||
import net.filebot.format.ExpressionFormat;
|
||||
import net.filebot.format.MediaBindingBean;
|
||||
import net.filebot.format.SuppressedThrowables;
|
||||
|
@ -87,7 +88,7 @@ import net.miginfocom.swing.MigLayout;
|
|||
public class FormatDialog extends JDialog {
|
||||
|
||||
private boolean submit = false;
|
||||
private ExpressionFormat format;
|
||||
private ExpressionFileFormat format;
|
||||
|
||||
private Mode mode;
|
||||
private boolean locked = false;
|
||||
|
@ -398,7 +399,7 @@ public class FormatDialog extends JDialog {
|
|||
// bind text to preview
|
||||
addPropertyChangeListener("sample", evt -> {
|
||||
newSwingWorker(() -> {
|
||||
return new ExpressionFormat(format).format(sample);
|
||||
return new ExpressionFileFormat(format).format(sample);
|
||||
}, s -> {
|
||||
formatExample.setText(s);
|
||||
}).execute();
|
||||
|
@ -449,7 +450,7 @@ public class FormatDialog extends JDialog {
|
|||
private void checkFormatInBackground() {
|
||||
try {
|
||||
// check syntax in foreground
|
||||
ExpressionFormat format = new ExpressionFormat(editor.getText().trim());
|
||||
ExpressionFileFormat format = new ExpressionFileFormat(editor.getText().trim());
|
||||
|
||||
// activate delayed to avoid flickering when formatting takes only a couple of milliseconds
|
||||
Timer progressIndicatorTimer = invokeLater(400, () -> progressIndicator.setVisible(true));
|
||||
|
@ -666,7 +667,7 @@ public class FormatDialog extends JDialog {
|
|||
protected final Action approveFormatAction = newAction("Use Format", ResourceManager.getIcon("dialog.continue"), evt -> {
|
||||
try {
|
||||
// check syntax
|
||||
format = new ExpressionFormat(editor.getText().trim());
|
||||
format = new ExpressionFileFormat(editor.getText().trim());
|
||||
|
||||
if (format.getExpression().isEmpty()) {
|
||||
throw new ScriptException("Expression is empty");
|
||||
|
|
|
@ -15,6 +15,7 @@ import net.filebot.CachedResource.Transform;
|
|||
import net.filebot.Language;
|
||||
import net.filebot.StandardRenameAction;
|
||||
import net.filebot.format.ExpressionFileFilter;
|
||||
import net.filebot.format.ExpressionFileFormat;
|
||||
import net.filebot.format.ExpressionFilter;
|
||||
import net.filebot.format.ExpressionFormat;
|
||||
import net.filebot.media.XattrMetaInfoProvider;
|
||||
|
@ -60,8 +61,8 @@ public class Preset {
|
|||
return getInputFolder() == null ? null : getValue(includes, expression -> new ExpressionFileFilter(expression));
|
||||
}
|
||||
|
||||
public ExpressionFormat getFormat() {
|
||||
return getValue(format, ExpressionFormat::new);
|
||||
public ExpressionFileFormat getFormat() {
|
||||
return getValue(format, ExpressionFileFormat::new);
|
||||
}
|
||||
|
||||
public String getMatchMode() {
|
||||
|
|
|
@ -37,8 +37,8 @@ import net.filebot.ResourceManager;
|
|||
import net.filebot.StandardRenameAction;
|
||||
import net.filebot.UserFiles;
|
||||
import net.filebot.WebServices;
|
||||
import net.filebot.format.ExpressionFileFormat;
|
||||
import net.filebot.format.ExpressionFilter;
|
||||
import net.filebot.format.ExpressionFormat;
|
||||
import net.filebot.format.MediaBindingBean;
|
||||
import net.filebot.mac.MacAppUtilities;
|
||||
import net.filebot.ui.HeaderPanel;
|
||||
|
@ -181,7 +181,7 @@ public class PresetEditor extends JDialog {
|
|||
String name = presetNameHeader.getTitleLabel().getText();
|
||||
File path = inheritRadio.isSelected() ? null : new File(pathInput.getText());
|
||||
ExpressionFilter includes = inheritRadio.isSelected() ? null : new ExpressionFilter(filterEditor.getText());
|
||||
ExpressionFormat format = formatEditor.getText().trim().isEmpty() ? null : new ExpressionFormat(formatEditor.getText());
|
||||
ExpressionFileFormat format = formatEditor.getText().trim().isEmpty() ? null : new ExpressionFileFormat(formatEditor.getText());
|
||||
Datasource database = ((Datasource) providerCombo.getSelectedItem());
|
||||
SortOrder sortOrder = sortOrderCombo.isEnabled() ? ((SortOrder) sortOrderCombo.getSelectedItem()) : null;
|
||||
String matchMode = matchModeCombo.isEnabled() ? (String) matchModeCombo.getSelectedItem() : null;
|
||||
|
|
|
@ -64,7 +64,7 @@ import net.filebot.Settings;
|
|||
import net.filebot.StandardRenameAction;
|
||||
import net.filebot.UserFiles;
|
||||
import net.filebot.WebServices;
|
||||
import net.filebot.format.ExpressionFormat;
|
||||
import net.filebot.format.ExpressionFileFormat;
|
||||
import net.filebot.format.MediaBindingBean;
|
||||
import net.filebot.mac.MacAppUtilities;
|
||||
import net.filebot.media.MetaAttributes;
|
||||
|
@ -741,7 +741,7 @@ public class RenamePanel extends JComponent {
|
|||
@Override
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
SwingWorker<ExpressionFormatter, Void> worker = newSwingWorker(() -> {
|
||||
ExpressionFormat format = preset.getFormat();
|
||||
ExpressionFileFormat format = preset.getFormat();
|
||||
|
||||
if (format != null && preset.getDatasource() != null) {
|
||||
switch (Mode.getMode(preset.getDatasource())) {
|
||||
|
|
Loading…
Reference in New Issue