Unify CLI/GUI lookupSubtitleByHash

This commit is contained in:
Reinhard Pointner 2016-02-27 05:22:46 +00:00
parent 66fa39af25
commit 87238fe330
5 changed files with 54 additions and 45 deletions

View File

@ -718,8 +718,8 @@ public class CmdlineOperations implements CmdlineInterface {
try {
CLILogger.fine("Looking up subtitles by hash via " + service.getName());
Map<File, SubtitleDescriptor> subtitles = lookupSubtitleByHash(service, language, remainingVideos, strict);
Map<File, File> downloads = downloadSubtitleBatch(service.getName(), subtitles, outputFormat, outputEncoding, naming);
Map<File, List<SubtitleDescriptor>> options = lookupSubtitleByHash(service, language.getName(), remainingVideos, false, strict);
Map<File, File> downloads = downloadSubtitleBatch(service.getName(), options, outputFormat, outputEncoding, naming);
remainingVideos.removeAll(downloads.keySet());
subtitleFiles.addAll(downloads.values());
} catch (Exception e) {
@ -734,13 +734,8 @@ public class CmdlineOperations implements CmdlineInterface {
try {
CLILogger.fine(format("Looking up subtitles by name via %s", service.getName()));
Map<File, SubtitleDescriptor> subtitles = new TreeMap<File, SubtitleDescriptor>();
for (Entry<File, List<SubtitleDescriptor>> it : findSubtitleMatches(service, remainingVideos, language.getName(), query, false, strict).entrySet()) {
if (it.getValue().size() > 0) {
subtitles.put(it.getKey(), it.getValue().get(0));
}
}
Map<File, File> downloads = downloadSubtitleBatch(service.getName(), subtitles, outputFormat, outputEncoding, naming);
Map<File, List<SubtitleDescriptor>> options = findSubtitleByName(service, remainingVideos, language.getName(), query, false, strict);
Map<File, File> downloads = downloadSubtitleBatch(service.getName(), options, outputFormat, outputEncoding, naming);
remainingVideos.removeAll(downloads.keySet());
subtitleFiles.addAll(downloads.values());
} catch (Exception e) {
@ -752,6 +747,7 @@ public class CmdlineOperations implements CmdlineInterface {
for (File it : remainingVideos) {
CLILogger.warning("No matching subtitles found: " + it);
}
return subtitleFiles;
}
@ -828,17 +824,20 @@ public class CmdlineOperations implements CmdlineInterface {
}
}
private Map<File, File> downloadSubtitleBatch(String service, Map<File, SubtitleDescriptor> subtitles, SubtitleFormat outputFormat, Charset outputEncoding, SubtitleNaming naming) {
Map<File, File> downloads = new HashMap<File, File>();
private Map<File, File> downloadSubtitleBatch(String service, Map<File, List<SubtitleDescriptor>> subtitles, SubtitleFormat outputFormat, Charset outputEncoding, SubtitleNaming naming) {
Map<File, File> downloads = new LinkedHashMap<File, File>();
// fetch subtitle
for (Entry<File, SubtitleDescriptor> it : subtitles.entrySet()) {
try {
downloads.put(it.getKey(), downloadSubtitle(it.getValue(), it.getKey(), outputFormat, outputEncoding, naming));
} catch (Exception e) {
CLILogger.warning(format("Failed to download %s: %s", it.getValue().getPath(), e.getMessage()));
subtitles.forEach((movie, options) -> {
if (options.size() > 0) {
SubtitleDescriptor subtitle = options.get(0);
try {
downloads.put(movie, downloadSubtitle(subtitle, movie, outputFormat, outputEncoding, naming));
} catch (Exception e) {
CLILogger.warning(format("Failed to download %s: %s", subtitle.getPath(), e.getMessage()));
}
}
}
});
return downloads;
}
@ -868,22 +867,6 @@ public class CmdlineOperations implements CmdlineInterface {
return destination;
}
private Map<File, SubtitleDescriptor> lookupSubtitleByHash(VideoHashSubtitleService service, Language language, Collection<File> videoFiles, boolean strict) throws Exception {
Map<File, SubtitleDescriptor> subtitleByVideo = new TreeMap<File, SubtitleDescriptor>();
for (Entry<File, List<SubtitleDescriptor>> it : service.getSubtitleList(videoFiles.toArray(new File[0]), language.getName()).entrySet()) {
// guess best hash match (default order is open bad due to invalid hash links)
SubtitleDescriptor bestMatch = getBestMatch(it.getKey(), it.getValue(), strict);
if (bestMatch != null) {
CLILogger.finest(format("Matched [%s] to [%s] via hash", it.getKey().getName(), bestMatch.getName()));
subtitleByVideo.put(it.getKey(), bestMatch);
}
}
return subtitleByVideo;
}
private <T> List<T> applyExpressionFilter(Collection<T> input, ExpressionFilter filter) throws Exception {
if (filter == null) {
return new ArrayList<T>(input);

View File

@ -940,7 +940,7 @@ public class MediaBindingBean {
// still no good match found -> just take the most probable video from the same folder
if (videos.size() > 0) {
sort(videos, SimilarityComparator.compareTo(getMediaFile(), FileUtilities::getName));
sort(videos, SimilarityComparator.compareTo(FileUtilities.getName(getMediaFile()), FileUtilities::getName));
return videos.get(0);
}
}

View File

@ -9,8 +9,8 @@ import java.util.function.Function;
public class SimilarityComparator<T, P> implements Comparator<T> {
public static <T, S extends CharSequence> SimilarityComparator<T, S> compareTo(T value, Function<T, S> mapper) {
return new SimilarityComparator<T, S>(new NameSimilarityMetric(), singleton(mapper.apply(value)), mapper.andThen(Collections::singleton));
public static <T, S extends CharSequence> SimilarityComparator<T, S> compareTo(S value, Function<T, S> mapper) {
return new SimilarityComparator<T, S>(new NameSimilarityMetric(), singleton(value), mapper.andThen(Collections::singleton));
}
protected SimilarityMetric metric;

View File

@ -28,6 +28,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeSet;
import java.util.function.Predicate;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
@ -41,6 +42,7 @@ import net.filebot.similarity.MetricAvg;
import net.filebot.similarity.NameSimilarityMetric;
import net.filebot.similarity.SeasonEpisodeMatcher.SxE;
import net.filebot.similarity.SequenceMatchSimilarity;
import net.filebot.similarity.SimilarityComparator;
import net.filebot.similarity.SimilarityMetric;
import net.filebot.util.ByteBufferInputStream;
import net.filebot.util.UnicodeReader;
@ -50,6 +52,7 @@ import net.filebot.web.Movie;
import net.filebot.web.SubtitleDescriptor;
import net.filebot.web.SubtitleProvider;
import net.filebot.web.SubtitleSearchResult;
import net.filebot.web.VideoHashSubtitleService;
import com.optimaize.langdetect.DetectedLanguage;
import com.optimaize.langdetect.LanguageDetector;
@ -62,7 +65,30 @@ import com.optimaize.langdetect.profiles.LanguageProfileReader;
public final class SubtitleUtilities {
public static Map<File, List<SubtitleDescriptor>> findSubtitleMatches(SubtitleProvider service, Collection<File> fileSet, String languageName, String forceQuery, boolean addOptions, boolean strict) throws Exception {
public static Map<File, List<SubtitleDescriptor>> lookupSubtitleByHash(VideoHashSubtitleService service, String languageName, Collection<File> files, boolean addOptions, boolean strict) throws Exception {
Map<File, List<SubtitleDescriptor>> options = service.getSubtitleList(files.toArray(new File[files.size()]), languageName);
Map<File, List<SubtitleDescriptor>> results = new LinkedHashMap<File, List<SubtitleDescriptor>>(options.size());
options.forEach((k, v) -> {
// guess best hash match (default order is open bad due to invalid hash links)
SubtitleDescriptor bestMatch = getBestMatch(k, v, strict);
// ignore results if there is no best match
if (bestMatch != null) {
if (addOptions) {
Stream<SubtitleDescriptor> top1 = Stream.of(bestMatch);
Stream<SubtitleDescriptor> topN = v.stream().filter(Predicate.isEqual(bestMatch).negate()).sorted(SimilarityComparator.compareTo(getName(k), SubtitleDescriptor::getName));
results.put(k, Stream.concat(top1, topN).collect(toList()));
} else {
results.put(k, singletonList(bestMatch));
}
}
});
return results;
}
public static Map<File, List<SubtitleDescriptor>> findSubtitleByName(SubtitleProvider service, Collection<File> fileSet, String languageName, String forceQuery, boolean addOptions, boolean strict) throws Exception {
// ignore anything that is not a video
fileSet = filter(fileSet, VIDEO_FILES);
@ -331,13 +357,13 @@ public final class SubtitleUtilities {
if (outputFormat == SubtitleFormat.SubRip) {
// output buffer
StringBuilder buffer = new StringBuilder(4 * 1024);
SubRipWriter out = new SubRipWriter(buffer);
for (SubtitleElement it : decodeSubtitles(data)) {
if (outputTimingOffset != 0) {
it = new SubtitleElement(max(0, it.getStart() + outputTimingOffset), max(0, it.getEnd() + outputTimingOffset), it.getText());
try (SubRipWriter out = new SubRipWriter(buffer)) {
for (SubtitleElement it : decodeSubtitles(data)) {
if (outputTimingOffset != 0) {
it = new SubtitleElement(max(0, it.getStart() + outputTimingOffset), max(0, it.getEnd() + outputTimingOffset), it.getText());
}
out.write(it);
}
out.write(it);
}
return outputEncoding.encode(CharBuffer.wrap(buffer));

View File

@ -915,7 +915,7 @@ class SubtitleAutoMatchDialog extends JDialog {
@Override
protected Map<File, List<SubtitleDescriptor>> getSubtitleList(Collection<File> files, String languageName, Component parent) throws Exception {
return service.getSubtitleList(files.toArray(new File[0]), languageName);
return lookupSubtitleByHash(service, languageName, files, true, false);
}
@Override
@ -940,7 +940,7 @@ class SubtitleAutoMatchDialog extends JDialog {
@Override
protected Map<File, List<SubtitleDescriptor>> getSubtitleList(Collection<File> fileSet, String languageName, Component parent) throws Exception {
return findSubtitleMatches(service, fileSet, languageName, null, true, false);
return findSubtitleByName(service, fileSet, languageName, null, true, false);
}
@Override