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

Fix regression issues caused by selectSearchResult now taking into account alias titles (which is not desirable when query was entered manually)

This commit is contained in:
Reinhard Pointner 2016-02-08 22:29:50 +00:00
parent 037c3d9e68
commit 1ebece8d19
3 changed files with 27 additions and 31 deletions

View File

@ -285,7 +285,7 @@ public class CmdlineOperations implements CmdlineInterface {
// select search result // select search result
if (results.size() > 0) { if (results.size() > 0) {
List<SearchResult> selectedSearchResults = selectSearchResult(query, results, strict); List<SearchResult> selectedSearchResults = selectSearchResult(query, results, true, strict);
if (selectedSearchResults != null) { if (selectedSearchResults != null) {
for (SearchResult it : selectedSearchResults) { for (SearchResult it : selectedSearchResults) {
@ -404,7 +404,7 @@ public class CmdlineOperations implements CmdlineInterface {
} }
// force all mappings // force all mappings
Movie result = (Movie) selectSearchResult(query, validResults, strict).get(0); Movie result = (Movie) selectSearchResult(query, validResults, false, strict).get(0);
for (File file : files) { for (File file : files) {
movieByFile.put(file, result); movieByFile.put(file, result);
} }
@ -447,7 +447,7 @@ public class CmdlineOperations implements CmdlineInterface {
// select first element if matches are reliable // select first element if matches are reliable
if (options.size() > 0) { if (options.size() > 0) {
// make sure to get the language-specific movie object for the selected option // make sure to get the language-specific movie object for the selected option
movie = service.getMovieDescriptor((Movie) selectSearchResult(null, options, strict).get(0), locale); movie = service.getMovieDescriptor((Movie) selectSearchResult(null, options, false, strict).get(0), locale);
} }
} catch (Exception e) { } catch (Exception e) {
CLILogger.log(Level.WARNING, String.format("%s: [%s/%s] %s", e.getClass().getSimpleName(), guessMovieFolder(file) != null ? guessMovieFolder(file).getName() : null, file.getName(), e.getMessage())); CLILogger.log(Level.WARNING, String.format("%s: [%s/%s] %s", e.getClass().getSimpleName(), guessMovieFolder(file) != null ? guessMovieFolder(file).getName() : null, file.getName(), e.getMessage()));
@ -910,23 +910,22 @@ public class CmdlineOperations implements CmdlineInterface {
return output; return output;
} }
@SuppressWarnings("unchecked") private List<SearchResult> selectSearchResult(String query, Collection<? extends SearchResult> options, boolean alias, boolean strict) throws Exception {
public List<SearchResult> selectSearchResult(String query, Collection<? extends SearchResult> searchResults, boolean strict) throws Exception { List<SearchResult> probableMatches = getProbableMatches(query, options, alias, strict);
List<SearchResult> probableMatches = getProbableMatches(query, searchResults, strict);
if (probableMatches.isEmpty() || (strict && probableMatches.size() != 1)) { if (probableMatches.isEmpty() || (strict && probableMatches.size() != 1)) {
// allow single search results to just pass through in non-strict mode even if match confidence is low // allow single search results to just pass through in non-strict mode even if match confidence is low
if (searchResults.size() == 1 && !strict) { if (options.size() == 1 && !strict) {
return new ArrayList<SearchResult>(searchResults); return new ArrayList<SearchResult>(options);
} }
if (strict) { if (strict) {
throw new CmdlineException("Multiple options: Force auto-select requires non-strict matching: " + searchResults); throw new CmdlineException("Multiple options: Force auto-select requires non-strict matching: " + options);
} }
// just pick the best 5 matches // just pick the best 5 matches
if (query != null) { if (query != null) {
probableMatches = (List<SearchResult>) sortBySimilarity(searchResults, singleton(query), getSeriesMatchMetric()); probableMatches = new ArrayList<SearchResult>(sortBySimilarity(options, singleton(query), getSeriesMatchMetric()));
} }
} }
@ -1081,7 +1080,7 @@ public class CmdlineOperations implements CmdlineInterface {
Locale locale = getLanguage(languageName).getLocale(); Locale locale = getLanguage(languageName).getLocale();
// fetch episode data // fetch episode data
SearchResult hit = selectSearchResult(query, service.search(query, locale), false).get(0); SearchResult hit = selectSearchResult(query, service.search(query, locale), false, false).get(0);
List<Episode> episodes = service.getEpisodeList(hit, sortOrder, locale); List<Episode> episodes = service.getEpisodeList(hit, sortOrder, locale);
// apply filter // apply filter

View File

@ -36,6 +36,7 @@ import java.util.Set;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.function.Function;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@ -706,19 +707,12 @@ public class MediaDetection {
} }
public static <T extends SearchResult> List<T> sortBySimilarity(Collection<T> options, Collection<String> terms, SimilarityMetric metric) { public static <T extends SearchResult> List<T> sortBySimilarity(Collection<T> options, Collection<String> terms, SimilarityMetric metric) {
// similarity comparator with multi-value support return sortBySimilarity(options, terms, metric, SearchResult::getEffectiveNames);
SimilarityComparator comparator = new SimilarityComparator(metric, terms.toArray()) { }
@Override public static <T extends SearchResult> List<T> sortBySimilarity(Collection<T> options, Collection<String> terms, SimilarityMetric metric, Function<SearchResult, Collection<String>> mapper) {
public float getMaxSimilarity(Object obj) { // similarity comparator with multi-value support
Collection<?> names = obj instanceof SearchResult ? ((SearchResult) obj).getEffectiveNames() : singleton(obj); SimilarityComparator<SearchResult, String> comparator = new SimilarityComparator<SearchResult, String>(metric, terms, mapper);
float f = 0;
for (Object it : names) {
f = Math.max(f, super.getMaxSimilarity(it));
}
return f;
}
};
// DEBUG // DEBUG
// System.out.format("sortBySimilarity %s => %s%n", terms, options.stream().sorted(comparator).distinct().collect(Collectors.toList())); // System.out.format("sortBySimilarity %s => %s%n", terms, options.stream().sorted(comparator).distinct().collect(Collectors.toList()));
@ -732,7 +726,7 @@ public class MediaDetection {
paragon.addAll(stripReleaseInfo(terms, true)); paragon.addAll(stripReleaseInfo(terms, true));
paragon.addAll(stripReleaseInfo(terms, false)); paragon.addAll(stripReleaseInfo(terms, false));
return sortBySimilarity(options, paragon, getMovieMatchMetric()); return sortBySimilarity(options, paragon, getMovieMatchMetric(), SearchResult::getEffectiveNames);
} }
public static boolean isEpisodeNumberMatch(File f, Episode e) { public static boolean isEpisodeNumberMatch(File f, Episode e) {
@ -1258,11 +1252,14 @@ public class MediaDetection {
return WebServices.TheTVDB.getSeriesInfo(thetvdbid, locale); return WebServices.TheTVDB.getSeriesInfo(thetvdbid, locale);
} }
public static List<SearchResult> getProbableMatches(String query, Collection<? extends SearchResult> options, boolean strict) { public static List<SearchResult> getProbableMatches(String query, Collection<? extends SearchResult> options, boolean alias, boolean strict) {
if (query == null) { if (query == null) {
return new ArrayList<SearchResult>(options); return new ArrayList<SearchResult>(options);
} }
// check all alias names, or just the primary name
Function<SearchResult, Collection<String>> names = alias ? SearchResult::getEffectiveNames : (it) -> singleton(it.getName());
// auto-select most probable search result // auto-select most probable search result
List<SearchResult> probableMatches = new ArrayList<SearchResult>(); List<SearchResult> probableMatches = new ArrayList<SearchResult>();
@ -1272,17 +1269,17 @@ public class MediaDetection {
float sanity = strict && options.size() > 1 ? 0.5f : 0.2f; float sanity = strict && options.size() > 1 ? 0.5f : 0.2f;
// remove trailing braces, e.g. Doctor Who (2005) -> doctor who // remove trailing braces, e.g. Doctor Who (2005) -> doctor who
query = removeTrailingBrackets(query).toLowerCase(); String q = removeTrailingBrackets(query).toLowerCase();
// find probable matches using name similarity > 0.8 (or > 0.6 in non-strict mode) // find probable matches using name similarity > 0.8 (or > 0.6 in non-strict mode)
for (SearchResult option : options) { for (SearchResult option : options) {
float f = 0; float f = 0;
for (String n : option.getEffectiveNames()) { for (String n : names.apply(option)) {
n = removeTrailingBrackets(n).toLowerCase(); n = removeTrailingBrackets(n).toLowerCase();
f = Math.max(f, metric.getSimilarity(query, n)); f = Math.max(f, metric.getSimilarity(q, n));
// boost matching beginnings // boost matching beginnings
if (f >= sanity && n.startsWith(query)) { if (f >= sanity && n.startsWith(q)) {
f = 1; f = 1;
break; break;
} }
@ -1293,7 +1290,7 @@ public class MediaDetection {
} }
} }
return sortBySimilarity(probableMatches, singleton(query), new NameSimilarityMetric()); return sortBySimilarity(probableMatches, singleton(query), new NameSimilarityMetric(), names);
} }
public static class IndexEntry<T> implements Serializable { public static class IndexEntry<T> implements Serializable {

View File

@ -70,7 +70,7 @@ class EpisodeListMatcher implements AutoCompleteMatcher {
} }
// auto-select most probable search result // auto-select most probable search result
List<SearchResult> probableMatches = getProbableMatches(query, searchResults, true); List<SearchResult> probableMatches = getProbableMatches(query, searchResults, true, true);
// auto-select first and only probable search result // auto-select first and only probable search result
if (probableMatches.size() == 1) { if (probableMatches.size() == 1) {