* optimize subtitle lookup

This commit is contained in:
Reinhard Pointner 2014-11-11 04:55:22 +00:00
parent a8b28ac8cd
commit 0ebf4b0a45
6 changed files with 50 additions and 39 deletions

View File

@ -7,6 +7,7 @@ import static net.filebot.media.MediaDetection.*;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
@ -211,12 +212,17 @@ public final class WebServices {
}
@Override
public synchronized List<SearchResult> search(final String query) throws Exception {
Callable<List<? extends SearchResult>> seriesSearch = () -> seriesIndex.search(query, Locale.ENGLISH);
Callable<List<? extends SearchResult>> movieSearch = () -> movieIndex.searchMovie(query, Locale.ENGLISH);
public synchronized List<SearchResult> search(final String query, final boolean byMovie, final boolean bySeries) throws Exception {
List<Callable<List<? extends SearchResult>>> queries = new ArrayList<>(2);
if (byMovie) {
queries.add(() -> movieIndex.searchMovie(query, Locale.ENGLISH));
}
if (bySeries) {
queries.add(() -> seriesIndex.search(query, Locale.ENGLISH));
}
Set<SearchResult> results = new LinkedHashSet<SearchResult>();
for (Future<List<? extends SearchResult>> resultSet : requestThreadPool.invokeAll(asList(seriesSearch, movieSearch))) {
for (Future<List<? extends SearchResult>> resultSet : requestThreadPool.invokeAll(queries)) {
try {
results.addAll(resultSet.get());
} catch (ExecutionException e) {

View File

@ -65,14 +65,18 @@ public final class SubtitleUtilities {
throw new InterruptedException();
// auto-detect query and search for subtitles
boolean searchByMovie = false, searchBySeries = false;
Collection<String> querySet = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
List<File> files = bySeries.getValue();
if (forceQuery != null && forceQuery.length() > 0) {
querySet.add(forceQuery);
searchByMovie = true;
searchBySeries = true;
} else if (bySeries.getKey().length() > 0) {
// use auto-detected series name as query
querySet.add(bySeries.getKey());
searchBySeries = true;
} else {
for (File f : files) {
List<String> queries = new ArrayList<String>();
@ -88,11 +92,18 @@ public final class SubtitleUtilities {
queries.add(stripReleaseInfo(getName(f)));
}
if (queries.size() > 0) {
querySet.addAll(queries);
searchByMovie = true;
}
}
}
Set<SubtitleDescriptor> subtitles = findSubtitles(service, querySet, languageName);
if (!searchByMovie && !searchBySeries)
continue;
// search for subtitles online using the auto-detected or forced query information
Set<SubtitleDescriptor> subtitles = findSubtitles(service, querySet, searchByMovie, searchBySeries, languageName);
// allow early abort
if (Thread.interrupted())
@ -175,13 +186,13 @@ public final class SubtitleUtilities {
return subtitleByVideo;
}
public static Set<SubtitleDescriptor> findSubtitles(SubtitleProvider service, Collection<String> querySet, String languageName) throws Exception {
public static Set<SubtitleDescriptor> findSubtitles(SubtitleProvider service, Collection<String> querySet, boolean searchByMovie, boolean searchBySeries, String languageName) throws Exception {
Set<SubtitleDescriptor> subtitles = new LinkedHashSet<SubtitleDescriptor>();
// search for and automatically select movie / show entry
Set<SearchResult> resultSet = new HashSet<SearchResult>();
for (String query : querySet) {
resultSet.addAll(findProbableSearchResults(query, service.search(query), querySet.size() == 1 ? 4 : 2));
resultSet.addAll(findProbableSearchResults(query, service.search(query, searchByMovie, searchBySeries), querySet.size() == 1 ? 4 : 2));
}
// fetch subtitles for all search results

View File

@ -51,6 +51,7 @@ import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.SwingWorker.StateValue;
import javax.swing.border.Border;
@ -169,7 +170,7 @@ class SubtitleAutoMatchDialog extends JDialog {
}
protected void addSubtitleService(final SubtitleServiceBean service, final JPanel servicePanel) {
final LinkButton component = new LinkButton(service.getName(), null, ResourceManager.getIcon("database"), service.getLink());
final LinkButton component = new LinkButton(service.getDescription(), null, ResourceManager.getIcon("database"), service.getLink());
component.setBorder(BorderFactory.createEmptyBorder());
component.setVisible(false);
@ -184,7 +185,7 @@ class SubtitleAutoMatchDialog extends JDialog {
}
component.setVisible(true);
component.setToolTipText(service.getError() == null ? null : service.getError().getMessage());
component.setToolTipText(String.format("%s: %s", service.getName(), service.getError() == null ? service.getState().toString().toLowerCase() : service.getError().getMessage()));
servicePanel.setVisible(true);
servicePanel.getParent().revalidate();
}
@ -216,6 +217,11 @@ class SubtitleAutoMatchDialog extends JDialog {
}
}
}
@Override
protected void done() {
SwingUtilities.invokeLater(() -> mappingModel.fireTableStructureChanged()); // make sure UI is refershed after completion
}
};
queryService = Executors.newFixedThreadPool(1);
@ -842,7 +848,7 @@ class SubtitleAutoMatchDialog extends JDialog {
private final URI link;
private StateValue state = StateValue.PENDING;
private Throwable error = null;
private Exception error = null;
public SubtitleServiceBean(String name, Icon icon, URI link) {
this.name = name;
@ -862,6 +868,8 @@ class SubtitleAutoMatchDialog extends JDialog {
return link;
}
public abstract String getDescription();
public abstract float getMatchProbabilty(File videoFile, SubtitleDescriptor descriptor);
protected abstract Map<File, List<SubtitleDescriptor>> getSubtitleList(Collection<File> files, String languageName, Component parent) throws Exception;
@ -872,11 +880,7 @@ class SubtitleAutoMatchDialog extends JDialog {
try {
return getSubtitleList(files, languageName, parent);
} catch (Exception e) {
// remember error
error = e;
// rethrow error
throw e;
throw (error = e);
} finally {
setState(StateValue.DONE);
}
@ -906,8 +910,8 @@ class SubtitleAutoMatchDialog extends JDialog {
}
@Override
public String getName() {
return String.format("%s [via hash]", service.getName());
public String getDescription() {
return "Exact Search";
}
@Override
@ -923,18 +927,16 @@ class SubtitleAutoMatchDialog extends JDialog {
protected static class SubtitleProviderBean extends SubtitleServiceBean {
private SubtitleAutoMatchDialog inputProvider;
private SubtitleProvider service;
public SubtitleProviderBean(SubtitleProvider service, SubtitleAutoMatchDialog inputProvider) {
super(service.getName(), service.getIcon(), service.getLink());
this.service = service;
this.inputProvider = inputProvider;
}
@Override
public String getName() {
return String.format("%s [via name]", service.getName());
public String getDescription() {
return "Fuzzy Search";
}
@Override

View File

@ -214,7 +214,7 @@ public class SubtitlePanel extends AbstractSearchPanel<SubtitleProvider, Subtitl
@Override
public Collection<SearchResult> search() throws Exception {
return request.getProvider().search(request.getSearchText());
return request.getProvider().search(request.getSearchText(), true, true);
}
@Override

View File

@ -90,8 +90,8 @@ public class OpenSubtitlesClient implements SubtitleProvider, VideoHashSubtitleS
}
@Override
public synchronized List<SearchResult> search(String query) throws Exception {
throw new UnsupportedOperationException("SearchMoviesOnIMDB is not allowed due to abuse");
public synchronized List<SearchResult> search(String query, boolean byMovie, boolean bySeries) throws Exception {
throw new UnsupportedOperationException(); // XMLRPC::SearchMoviesOnIMDB is not allowed due to abuse
}
@Override

View File

@ -1,30 +1,22 @@
package net.filebot.web;
import java.net.URI;
import java.util.List;
import javax.swing.Icon;
public interface SubtitleProvider {
public List<SearchResult> search(String query) throws Exception;
public List<SearchResult> search(String query, boolean byMovie, boolean bySeries) throws Exception;
public List<SubtitleDescriptor> getSubtitleList(SearchResult searchResult, String languageName) throws Exception;
public URI getSubtitleListLink(SearchResult searchResult, String languageName);
public String getName();
public URI getLink();
public Icon getIcon();
}