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:
parent
037c3d9e68
commit
1ebece8d19
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user