1
0
mirror of https://github.com/mitb-archive/filebot synced 2024-08-13 17:03:45 -04:00

* support referencing match model from naming scheme

This commit is contained in:
Reinhard Pointner 2013-01-27 08:17:12 +00:00
parent 1280031dd2
commit 2e68365b6e
9 changed files with 115 additions and 40 deletions

View File

@ -19,6 +19,7 @@ import java.io.FileFilter;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.AbstractMap;
import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.ArrayList;
import java.util.Collection;
@ -153,7 +154,7 @@ public class CmdlineOperations implements CmdlineInterface {
}
// similarity metrics for matching
List<Match<File, Object>> matches = new ArrayList<Match<File, Object>>();
List<Match<File, ?>> matches = new ArrayList<Match<File, ?>>();
// auto-determine optimal batch sets
for (Entry<Set<File>, Set<String>> sameSeriesGroup : mapSeriesNamesByFiles(mediaFiles, locale).entrySet()) {
@ -188,7 +189,7 @@ public class CmdlineOperations implements CmdlineInterface {
CLILogger.fine(String.format("Apply Filter: {%s}", filter.getExpression()));
for (Iterator<Episode> itr = episodes.iterator(); itr.hasNext();) {
Episode episode = itr.next();
if (filter.matches(new MediaBindingBean(episode, null))) {
if (filter.matches(new MediaBindingBean(episode, null, null))) {
CLILogger.finest(String.format("Include [%s]", episode));
} else {
itr.remove();
@ -221,10 +222,10 @@ public class CmdlineOperations implements CmdlineInterface {
// map old files to new paths by applying formatting and validating filenames
Map<File, File> renameMap = new LinkedHashMap<File, File>();
for (Match<File, Object> match : matches) {
for (Match<File, ?> match : matches) {
File file = match.getValue();
Object episode = match.getCandidate();
String newName = (format != null) ? format.format(new MediaBindingBean(episode, file)) : validateFileName(EpisodeFormat.SeasonEpisode.format(episode));
String newName = (format != null) ? format.format(new MediaBindingBean(episode, file, getContext(matches))) : validateFileName(EpisodeFormat.SeasonEpisode.format(episode));
renameMap.put(file, getDestinationFile(file, newName, outputDir));
}
@ -494,7 +495,7 @@ public class CmdlineOperations implements CmdlineInterface {
for (Match<File, ?> match : matches) {
File file = match.getValue();
Object movie = match.getCandidate();
String newName = (format != null) ? format.format(new MediaBindingBean(movie, file)) : validateFileName(MovieFormat.NameYear.format(movie));
String newName = (format != null) ? format.format(new MediaBindingBean(movie, file, getContext(matches))) : validateFileName(MovieFormat.NameYear.format(movie));
renameMap.put(file, getDestinationFile(file, newName, outputDir));
}
@ -509,17 +510,21 @@ public class CmdlineOperations implements CmdlineInterface {
CLILogger.config(format("Rename music using [%s]", service.getName()));
List<File> audioFiles = filter(files, AUDIO_FILES);
// check audio files against acoustid
List<Match<File, ?>> matches = new ArrayList<Match<File, ?>>();
for (Entry<File, AudioTrack> it : service.lookup(audioFiles).entrySet()) {
if (it.getKey() != null && it.getValue() != null) {
matches.add(new Match<File, AudioTrack>(it.getKey(), it.getValue()));
}
}
// map old files to new paths by applying formatting and validating filenames
Map<File, File> renameMap = new LinkedHashMap<File, File>();
// check audio files against acoustid
for (Entry<File, AudioTrack> match : service.lookup(audioFiles).entrySet()) {
File file = match.getKey();
AudioTrack music = match.getValue();
if (music == null)
continue;
String newName = (format != null) ? format.format(new MediaBindingBean(music, file)) : validateFileName(music.toString());
for (Match<File, ?> it : matches) {
File file = it.getValue();
AudioTrack music = (AudioTrack) it.getCandidate();
String newName = (format != null) ? format.format(new MediaBindingBean(music, file, getContext(matches))) : validateFileName(music.toString());
renameMap.put(file, getDestinationFile(file, newName, outputDir));
}
@ -539,6 +544,23 @@ public class CmdlineOperations implements CmdlineInterface {
}
private Map<File, Object> getContext(final Collection<Match<File, ?>> matches) {
return new AbstractMap<File, Object>() {
@Override
public Set<Entry<File, Object>> entrySet() {
Set<Entry<File, Object>> context = new LinkedHashSet<Entry<File, Object>>();
for (Match<File, ?> it : matches) {
if (it.getValue() != null && it.getCandidate() != null) {
context.add(new SimpleImmutableEntry<File, Object>(it.getValue(), it.getCandidate()));
}
}
return context;
}
};
}
private File getDestinationFile(File original, String newName, File outputDir) {
String extension = getExtension(original);
File newFile = new File(extension != null ? newName + '.' + extension : newName);
@ -1028,7 +1050,7 @@ public class CmdlineOperations implements CmdlineInterface {
List<String> episodes = new ArrayList<String>();
for (Episode it : service.getEpisodeList(hit, sortOrder, locale)) {
String name = (format != null) ? format.format(new MediaBindingBean(it, null)) : EpisodeFormat.SeasonEpisode.format(it);
String name = (format != null) ? format.format(new MediaBindingBean(it, null, null)) : EpisodeFormat.SeasonEpisode.format(it);
episodes.add(name);
}
@ -1039,7 +1061,7 @@ public class CmdlineOperations implements CmdlineInterface {
@Override
public String getMediaInfo(File file, String expression) throws Exception {
ExpressionFormat format = new ExpressionFormat(expression != null ? expression : "{fn} [{resolution} {af} {vc} {ac}]");
return format.format(new MediaBindingBean(file, file));
return format.format(new MediaBindingBean(file, file, null));
}

View File

@ -21,6 +21,7 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import java.util.Set;
import java.util.SortedSet;
@ -46,13 +47,16 @@ public class MediaBindingBean {
private final Object infoObject;
private final File mediaFile;
private final Map<File, Object> context;
private MediaInfo mediaInfo;
private Object metaInfo;
public MediaBindingBean(Object infoObject, File mediaFile) {
public MediaBindingBean(Object infoObject, File mediaFile, Map<File, Object> context) {
this.infoObject = infoObject;
this.mediaFile = mediaFile;
this.context = context;
}
@ -597,7 +601,7 @@ public class MediaBindingBean {
@Define("folder")
public File getMediaParentFolder() {
return mediaFile.getParentFile();
return getMediaFile().getParentFile();
}
@ -607,11 +611,24 @@ public class MediaBindingBean {
}
@Define("object")
public Object getInfoObject() {
return infoObject;
}
@Define("index")
public Integer getIndex() {
return new ArrayList<File>(getContext().keySet()).indexOf(getMediaFile()) + 1;
}
@Define("model")
public Map<File, Object> getContext() {
return context;
}
private File getInferredMediaFile() {
// make sure media file is defined
checkMediaFile();
@ -622,7 +639,16 @@ public class MediaBindingBean {
if (videos.size() > 0) {
return videos.iterator().next();
}
} else if (!VIDEO_FILES.accept(mediaFile)) {
} else if ((infoObject instanceof Episode || infoObject instanceof Movie) && !VIDEO_FILES.accept(mediaFile)) {
// prefer equal match from current context if possible
if (getContext() != null) {
for (Entry<File, Object> it : getContext().entrySet()) {
if (infoObject.equals(it.getValue()) && VIDEO_FILES.accept(it.getKey())) {
return it.getKey();
}
}
}
// file is a subtitle, or nfo, etc
String baseName = stripReleaseInfo(FileUtilities.getName(mediaFile)).toLowerCase();
File[] videos = mediaFile.getParentFile().listFiles(VIDEO_FILES);

View File

@ -119,7 +119,7 @@ class BindingDialog extends JDialog {
if (bindingModel.executor.isShutdown())
return;
bindingModel.setModel(getSampleExpressions(), new MediaBindingBean(getInfoObject(), getMediaFile()));
bindingModel.setModel(getSampleExpressions(), new MediaBindingBean(getInfoObject(), getMediaFile(), null));
}
};

View File

@ -4,6 +4,7 @@ package net.sourceforge.filebot.ui.rename;
import java.io.File;
import java.text.Format;
import java.util.Map;
import javax.script.ScriptException;
@ -46,14 +47,14 @@ class ExpressionFormatter implements MatchFormatter {
@Override
public synchronized String format(Match<?, ?> match) throws ScriptException {
public synchronized String format(Match<?, ?> match, Map<?, ?> context) throws ScriptException {
// lazy initialize script engine
if (format == null) {
format = new ExpressionFormat(expression);
}
// evaluate the expression using the given bindings
Object bindingBean = new MediaBindingBean(match.getValue(), (File) match.getCandidate());
Object bindingBean = new MediaBindingBean(match.getValue(), (File) match.getCandidate(), (Map<File, Object>) context);
String result = format.format(bindingBean).trim();
// if result is empty, check for script exceptions

View File

@ -3,6 +3,7 @@ package net.sourceforge.filebot.ui.rename;
import java.io.File;
import java.util.Map;
import net.sourceforge.filebot.similarity.Match;
import net.sourceforge.filebot.vfs.FileInfo;
@ -27,12 +28,12 @@ class FileNameFormatter implements MatchFormatter {
@Override
public String preview(Match<?, ?> match) {
return format(match);
return format(match, null);
}
@Override
public String format(Match<?, ?> match) {
public String format(Match<?, ?> match, Map<?, ?> context) {
Object value = match.getValue();
if (value instanceof File) {

View File

@ -405,7 +405,7 @@ class FormatDialog extends JDialog {
media = new File(path);
}
return new MediaBindingBean(info, media);
return new MediaBindingBean(info, media, null);
}
@ -610,7 +610,7 @@ class FormatDialog extends JDialog {
File file = dialog.getMediaFile();
// change sample
sample = new MediaBindingBean(info, file);
sample = new MediaBindingBean(info, file, null);
// remember
mode.persistentSample().setValue(info == null ? "" : mode.getFormat().format(info));

View File

@ -2,6 +2,8 @@
package net.sourceforge.filebot.ui.rename;
import java.util.Map;
import net.sourceforge.filebot.similarity.Match;
@ -13,6 +15,6 @@ public interface MatchFormatter {
public String preview(Match<?, ?> match);
public String format(Match<?, ?> match) throws Exception;
public String format(Match<?, ?> match, Map<?, ?> context) throws Exception;
}

View File

@ -5,6 +5,7 @@ package net.sourceforge.filebot.ui.rename;
import static net.sourceforge.tuned.FileUtilities.*;
import java.util.Formatter;
import java.util.Map;
import net.sourceforge.filebot.similarity.Match;
import net.sourceforge.filebot.web.MoviePart;
@ -20,12 +21,12 @@ class MovieFormatter implements MatchFormatter {
@Override
public String preview(Match<?, ?> match) {
return format(match);
return format(match, null);
}
@Override
public String format(Match<?, ?> match) {
public String format(Match<?, ?> match, Map<?, ?> context) {
MoviePart video = (MoviePart) match.getValue();
Formatter name = new Formatter(new StringBuilder());

View File

@ -7,10 +7,13 @@ import static net.sourceforge.tuned.FileUtilities.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
@ -45,12 +48,12 @@ public class RenameModel extends MatchModel<Object, File> {
@Override
public String preview(Match<?, ?> match) {
return format(match);
return format(match, null);
}
@Override
public String format(Match<?, ?> match) {
public String format(Match<?, ?> match, Map<?, ?> context) {
// clean up path separators like / or \
return replacePathSeparators(String.valueOf(match.getValue())).trim();
}
@ -207,7 +210,7 @@ public class RenameModel extends MatchModel<Object, File> {
Match<Object, File> match = getMatch(index);
// create new future
final FormattedFuture future = new FormattedFuture(match, getFormatter(match));
final FormattedFuture future = new FormattedFuture(match, getFormatter(match), getContext());
// update data
if (type == ListEvent.INSERT) {
@ -255,7 +258,7 @@ public class RenameModel extends MatchModel<Object, File> {
for (int i = 0; i < size(); i++) {
FormattedFuture obsolete = futures.get(i);
FormattedFuture future = new FormattedFuture(obsolete.getMatch(), getFormatter(obsolete.getMatch()));
FormattedFuture future = new FormattedFuture(obsolete.getMatch(), getFormatter(obsolete.getMatch()), getContext());
// replace and cancel old future
cancel(futures.set(i, future));
@ -270,6 +273,23 @@ public class RenameModel extends MatchModel<Object, File> {
}
private Map<File, Object> getContext() {
return new AbstractMap<File, Object>() {
@Override
public Set<Entry<File, Object>> entrySet() {
Set<Entry<File, Object>> context = new LinkedHashSet<Entry<File, Object>>();
for (Match<Object, File> it : matches()) {
if (it.getValue() != null && it.getCandidate() != null) {
context.add(new SimpleImmutableEntry<File, Object>(it.getCandidate(), it.getValue()));
}
}
return context;
}
};
}
private void submit(FormattedFuture future) {
// observe and enqueue worker task
future.addPropertyChangeListener(futureListener);
@ -305,13 +325,15 @@ public class RenameModel extends MatchModel<Object, File> {
public static class FormattedFuture extends SwingWorker<String, Void> {
private final Match<Object, File> match;
private final Map<File, Object> context;
private final MatchFormatter formatter;
private FormattedFuture(Match<Object, File> match, MatchFormatter formatter) {
private FormattedFuture(Match<Object, File> match, MatchFormatter formatter, Map<File, Object> context) {
this.match = match;
this.formatter = formatter;
this.context = context;
}
@ -332,7 +354,7 @@ public class RenameModel extends MatchModel<Object, File> {
@Override
protected String doInBackground() throws Exception {
return formatter.format(match).trim();
return formatter.format(match, context).trim();
}