1
0
mirror of https://github.com/mitb-archive/filebot synced 2024-11-04 16:35:08 -05:00

* added extra hints for when user input is required for movie/series identification

This commit is contained in:
Reinhard Pointner 2014-07-19 07:45:14 +00:00
parent 2cdd0ddc17
commit 02f789e1bf
5 changed files with 112 additions and 35 deletions

View File

@ -278,16 +278,16 @@ class EpisodeListMatcher implements AutoCompleteMatcher {
String parentPathHint = normalizePathSeparators(getRelativePathTail(files.get(0).getParentFile(), 2).getPath()); String parentPathHint = normalizePathSeparators(getRelativePathTail(files.get(0).getParentFile(), 2).getPath());
String suggestion = detectedSeriesNames.size() > 0 ? join(detectedSeriesNames, ", ") : parentPathHint; String suggestion = detectedSeriesNames.size() > 0 ? join(detectedSeriesNames, ", ") : parentPathHint;
List<String> input = emptyList(); List<String> input;
synchronized (inputMemory) { synchronized (inputMemory) {
input = inputMemory.get(suggestion); input = inputMemory.get(suggestion);
if (input == null || suggestion == null || suggestion.isEmpty()) { if (input == null || suggestion == null || suggestion.isEmpty()) {
input = showMultiValueInputDialog("Enter series name:", suggestion, parentPathHint, parent); input = showMultiValueInputDialog(getQueryInputMessage(files), suggestion, parentPathHint, parent);
inputMemory.put(suggestion, input); inputMemory.put(suggestion, input);
} }
} }
if (input.size() > 0) { if (input != null && input.size() > 0) {
// only allow one fetch session at a time so later requests can make use of cached results // only allow one fetch session at a time so later requests can make use of cached results
synchronized (providerLock) { synchronized (providerLock) {
episodes = fetchEpisodeSet(input, sortOrder, locale, new HashMap<String, SearchResult>(), parent); episodes = fetchEpisodeSet(input, sortOrder, locale, new HashMap<String, SearchResult>(), parent);
@ -309,14 +309,39 @@ class EpisodeListMatcher implements AutoCompleteMatcher {
return matches; return matches;
} }
protected String getQueryInputMessage(List<File> files) throws Exception {
StringBuilder html = new StringBuilder(512);
html.append("<html>");
html.append("Unable to identify the following files:").append("<br>");
for (File file : sortByUniquePath(files)) {
html.append("<nobr>");
html.append("");
File path = getStructurePathTail(file);
if (path == null) {
path = getRelativePathTail(file, 3);
}
new TextColorizer().colorizePath(html, path, true);
html.append("</nobr>");
html.append("<br>");
}
html.append("<br>");
html.append("Please enter series name:");
html.append("</html>");
return html.toString();
}
public List<Match<File, ?>> justFetchEpisodeList(final SortOrder sortOrder, final Locale locale, final Component parent) throws Exception { public List<Match<File, ?>> justFetchEpisodeList(final SortOrder sortOrder, final Locale locale, final Component parent) throws Exception {
// require user input // require user input
String input = showInputDialog("Enter series name:", "", "Fetch Episode List", parent); List<String> input = showMultiValueInputDialog("Enter series name:", "", "Fetch Episode List", parent);
List<Match<File, ?>> matches = new ArrayList<Match<File, ?>>(); List<Match<File, ?>> matches = new ArrayList<Match<File, ?>>();
if (input != null && input.length() > 0) { if (input.size() > 0) {
synchronized (providerLock) { synchronized (providerLock) {
Set<Episode> episodes = fetchEpisodeSet(singleton(input), sortOrder, locale, new HashMap<String, SearchResult>(), parent); Set<Episode> episodes = fetchEpisodeSet(input, sortOrder, locale, new HashMap<String, SearchResult>(), parent);
for (Episode it : episodes) { for (Episode it : episodes) {
matches.add(new Match<File, Episode>(null, it)); matches.add(new Match<File, Episode>(null, it));
} }

View File

@ -277,7 +277,7 @@ class MovieHashMatcher implements AutoCompleteMatcher {
String input = inputMemory.get(suggestion); String input = inputMemory.get(suggestion);
if (input == null || suggestion == null || suggestion.isEmpty()) { if (input == null || suggestion == null || suggestion.isEmpty()) {
File movieFolder = guessMovieFolder(movieFile); File movieFolder = guessMovieFolder(movieFile);
input = showInputDialog("Enter movie name:", suggestion != null && suggestion.length() > 0 ? suggestion : getName(movieFile), movieFolder == null ? movieFile.getName() : String.format("%s/%s", movieFolder.getName(), movieFile.getName()), parent); input = showInputDialog(getQueryInputMessage(movieFile), suggestion != null && suggestion.length() > 0 ? suggestion : getName(movieFile), movieFolder == null ? movieFile.getName() : String.format("%s/%s", movieFolder.getName(), movieFile.getName()), parent);
inputMemory.put(suggestion, input); inputMemory.put(suggestion, input);
} }
@ -292,6 +292,28 @@ class MovieHashMatcher implements AutoCompleteMatcher {
return options.isEmpty() ? null : selectMovie(movieFile, null, options, memory, parent); return options.isEmpty() ? null : selectMovie(movieFile, null, options, memory, parent);
} }
protected String getQueryInputMessage(File file) throws Exception {
File path = getStructurePathTail(file);
if (path == null) {
path = getRelativePathTail(file, 3);
}
StringBuilder html = new StringBuilder(512);
html.append("<html>");
html.append("Unable to identify the following files:").append("<br>");
html.append("<nobr>");
html.append("");
new TextColorizer().colorizePath(html, path, file.isFile());
html.append("</nobr>");
html.append("<br>");
html.append("<br>");
html.append("Please enter movie name:");
html.append("</html>");
return html.toString();
}
protected String checkedStripReleaseInfo(File file) throws Exception { protected String checkedStripReleaseInfo(File file) throws Exception {
String name = stripReleaseInfo(getName(file)); String name = stripReleaseInfo(getName(file));

View File

@ -13,7 +13,6 @@ import java.awt.RenderingHints;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D; import java.awt.geom.RoundRectangle2D;
import java.io.File; import java.io.File;
import java.util.List;
import javax.swing.DefaultListCellRenderer; import javax.swing.DefaultListCellRenderer;
import javax.swing.JList; import javax.swing.JList;
@ -44,8 +43,7 @@ class RenameListCellRenderer extends DefaultFancyListCellRenderer {
private Color warningGradientBeginColor = Color.RED; private Color warningGradientBeginColor = Color.RED;
private Color warningGradientEndColor = new Color(0xDC143C); private Color warningGradientEndColor = new Color(0xDC143C);
private Color pathRainbowBeginColor = new Color(0xCC3300); private TextColorizer textColorizer = new TextColorizer();
private Color pathRainbowEndColor = new Color(0x008080);
public RenameListCellRenderer(RenameModel renameModel) { public RenameListCellRenderer(RenameModel renameModel) {
super(new Insets(4, 7, 4, 7)); super(new Insets(4, 7, 4, 7));
@ -164,29 +162,11 @@ class RenameListCellRenderer extends DefaultFancyListCellRenderer {
} }
protected String colorizePath(File file, boolean hasExtension) { protected String colorizePath(File file, boolean hasExtension) {
List<File> path = listPath(file);
StringBuilder html = new StringBuilder(512); StringBuilder html = new StringBuilder(512);
html.append("<html><nobr>"); html.append("<html><nobr>");
textColorizer.colorizePath(html, file, hasExtension);
// colorize parent path html.append("</nobr></html>");
for (int i = 0; i < path.size() - 1; i++) { return html.toString();
float f = (path.size() <= 2) ? 1 : (float) i / (path.size() - 2);
Color c = interpolateHSB(pathRainbowBeginColor, pathRainbowEndColor, f);
html.append(String.format("<span style='color:rgb(%1$d, %2$d, %3$d)'>%4$s</span><span style='color:rgb(%1$d, %2$d, %3$d)'>/</span>", c.getRed(), c.getGreen(), c.getBlue(), escapeHTML(FileUtilities.getFolderName(path.get(i)))));
}
// only colorize extension
if (hasExtension) {
html.append(escapeHTML(FileUtilities.getName(file)));
String extension = FileUtilities.getExtension(file);
if (extension != null) {
html.append(String.format("<span style='color:#607080'>.%s</span>", escapeHTML(extension))); // highlight extension
}
} else {
html.append(file.getName());
}
return html.append("</nobr></html>").toString();
} }
protected File resolveAbsolutePath(File targetDir, String path, String extension) { protected File resolveAbsolutePath(File targetDir, String path, String extension) {

View File

@ -0,0 +1,50 @@
package net.filebot.ui.rename;
import static net.filebot.util.FileUtilities.*;
import static net.filebot.util.ui.TunedUtilities.*;
import java.awt.Color;
import java.io.File;
import java.util.List;
import net.filebot.util.FileUtilities;
public class TextColorizer {
private Color pathRainbowBeginColor;
private Color pathRainbowEndColor;
public TextColorizer() {
this(new Color(0xCC3300), new Color(0x008080));
}
public TextColorizer(Color pathRainbowBeginColor, Color pathRainbowEndColor) {
this.pathRainbowBeginColor = pathRainbowBeginColor;
this.pathRainbowEndColor = pathRainbowEndColor;
}
public StringBuilder colorizePath(StringBuilder html, File file, boolean hasExtension) {
List<File> path = listPath(file);
// colorize parent path
for (int i = 0; i < path.size() - 1; i++) {
float f = (path.size() <= 2) ? 1 : (float) i / (path.size() - 2);
Color c = interpolateHSB(pathRainbowBeginColor, pathRainbowEndColor, f);
html.append(String.format("<span style='color:rgb(%1$d, %2$d, %3$d)'>%4$s</span><span style='color:rgb(%1$d, %2$d, %3$d)'>/</span>", c.getRed(), c.getGreen(), c.getBlue(), escapeHTML(FileUtilities.getFolderName(path.get(i)))));
}
// only colorize extension
if (hasExtension) {
html.append(escapeHTML(FileUtilities.getName(file)));
String extension = FileUtilities.getExtension(file);
if (extension != null) {
html.append(String.format("<span style='color:#607080'>.%s</span>", escapeHTML(extension))); // highlight extension
}
} else {
html.append(file.getName());
}
return html;
}
}

View File

@ -135,8 +135,8 @@ public final class TunedUtilities {
return (frame.getExtendedState() & Frame.MAXIMIZED_BOTH) != 0; return (frame.getExtendedState() & Frame.MAXIMIZED_BOTH) != 0;
} }
public static List<String> showMultiValueInputDialog(final String text, final String initialValue, final String title, final Component parent) throws InvocationTargetException, InterruptedException { public static List<String> showMultiValueInputDialog(final Object message, final String initialValue, final String title, final Component parent) throws InvocationTargetException, InterruptedException {
String input = showInputDialog(text, initialValue, title, parent); String input = showInputDialog(message, initialValue, title, parent);
if (input == null || input.isEmpty()) { if (input == null || input.isEmpty()) {
return emptyList(); return emptyList();
} }
@ -161,14 +161,14 @@ public final class TunedUtilities {
return singletonList(input); return singletonList(input);
} }
public static String showInputDialog(final String text, final String initialValue, final String title, final Component parent) throws InvocationTargetException, InterruptedException { public static String showInputDialog(final Object message, final String initialValue, final String title, final Component parent) throws InvocationTargetException, InterruptedException {
final StringBuilder buffer = new StringBuilder(); final StringBuilder buffer = new StringBuilder();
Runnable runnable = new Runnable() { Runnable runnable = new Runnable() {
@Override @Override
public void run() { public void run() {
Object value = JOptionPane.showInputDialog(parent, text, title, PLAIN_MESSAGE, null, null, initialValue); Object value = JOptionPane.showInputDialog(parent, message, title, PLAIN_MESSAGE, null, null, initialValue);
if (value != null) { if (value != null) {
buffer.append(value.toString().trim()); buffer.append(value.toString().trim());
} }