* trim result after formatting in EpisodeExpressionFormatter
* refactoring / cleanup
This commit is contained in:
parent
28990f939d
commit
6593bfdbda
@ -19,7 +19,7 @@ public final class ResourceManager {
|
||||
|
||||
private static final Cache cache = CacheManager.getInstance().getCache("resource");
|
||||
|
||||
|
||||
|
||||
public static Icon getIcon(String name) {
|
||||
return getIcon(name, null);
|
||||
}
|
||||
@ -41,12 +41,7 @@ public final class ResourceManager {
|
||||
|
||||
|
||||
public static Icon getFlagIcon(String languageCode) {
|
||||
return getIcon(String.format("flags/%s", languageCode), "flags/default");
|
||||
}
|
||||
|
||||
|
||||
public static Icon getArchiveIcon(String type) {
|
||||
return getIcon(String.format("archives/%s", type), "archives/default");
|
||||
return getIcon(String.format("flags/%s", languageCode));
|
||||
}
|
||||
|
||||
|
||||
|
@ -7,6 +7,7 @@ import static javax.swing.ScrollPaneConstants.*;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
@ -53,7 +54,7 @@ public abstract class AbstractSearchPanel<S, E> extends JComponent {
|
||||
|
||||
protected final EventList<String> searchHistory = createSearchHistory();
|
||||
|
||||
|
||||
|
||||
public AbstractSearchPanel() {
|
||||
historyPanel.setColumnHeader(2, "Duration");
|
||||
|
||||
@ -73,7 +74,7 @@ public abstract class AbstractSearchPanel<S, E> extends JComponent {
|
||||
|
||||
searchTextField.getEditor().setAction(searchAction);
|
||||
|
||||
searchTextField.getSelectButton().setModel(createSearchEngines());
|
||||
searchTextField.getSelectButton().setModel(Arrays.asList(createSearchEngines()));
|
||||
searchTextField.getSelectButton().setLabelProvider(createSearchEngineLabelProvider());
|
||||
|
||||
try {
|
||||
@ -98,7 +99,7 @@ public abstract class AbstractSearchPanel<S, E> extends JComponent {
|
||||
}
|
||||
|
||||
|
||||
protected abstract List<S> createSearchEngines();
|
||||
protected abstract S[] createSearchEngines();
|
||||
|
||||
|
||||
protected abstract LabelProvider<S> createSearchEngineLabelProvider();
|
||||
@ -143,6 +144,7 @@ public abstract class AbstractSearchPanel<S, E> extends JComponent {
|
||||
return history;
|
||||
}
|
||||
|
||||
|
||||
private final AbstractAction searchAction = new AbstractAction("Find", ResourceManager.getIcon("action.find")) {
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
@ -155,12 +157,12 @@ public abstract class AbstractSearchPanel<S, E> extends JComponent {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
private class SearchTask extends SwingWorker<Collection<? extends SearchResult>, Void> {
|
||||
|
||||
private final RequestProcessor<?, E> requestProcessor;
|
||||
|
||||
|
||||
|
||||
public SearchTask(RequestProcessor<?, E> requestProcessor) {
|
||||
this.requestProcessor = requestProcessor;
|
||||
}
|
||||
@ -235,7 +237,7 @@ public abstract class AbstractSearchPanel<S, E> extends JComponent {
|
||||
|
||||
private final RequestProcessor<?, E> requestProcessor;
|
||||
|
||||
|
||||
|
||||
public FetchTask(RequestProcessor<?, E> requestProcessor) {
|
||||
this.requestProcessor = requestProcessor;
|
||||
}
|
||||
@ -292,7 +294,7 @@ public abstract class AbstractSearchPanel<S, E> extends JComponent {
|
||||
|
||||
private final String searchText;
|
||||
|
||||
|
||||
|
||||
public Request(String searchText) {
|
||||
this.searchText = searchText;
|
||||
}
|
||||
@ -315,7 +317,7 @@ public abstract class AbstractSearchPanel<S, E> extends JComponent {
|
||||
|
||||
private long duration = 0;
|
||||
|
||||
|
||||
|
||||
public RequestProcessor(R request, JComponent component) {
|
||||
this.request = request;
|
||||
this.tab = new FileBotTab<JComponent>(component);
|
||||
|
@ -10,9 +10,7 @@ import java.beans.PropertyChangeListener;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Icon;
|
||||
@ -70,16 +68,14 @@ public class EpisodeListPanel extends AbstractSearchPanel<EpisodeListProvider, E
|
||||
|
||||
|
||||
@Override
|
||||
protected List<EpisodeListProvider> createSearchEngines() {
|
||||
List<EpisodeListProvider> engines = new ArrayList<EpisodeListProvider>(4);
|
||||
|
||||
engines.add(new TVRageClient());
|
||||
engines.add(new AnidbClient());
|
||||
engines.add(new TVDotComClient());
|
||||
engines.add(new IMDbClient());
|
||||
engines.add(new TheTVDBClient(Settings.userRoot().get("thetvdb.apikey")));
|
||||
|
||||
return engines;
|
||||
protected EpisodeListProvider[] createSearchEngines() {
|
||||
return new EpisodeListProvider[] {
|
||||
new TVRageClient(),
|
||||
new AnidbClient(),
|
||||
new TVDotComClient(),
|
||||
new IMDbClient(),
|
||||
new TheTVDBClient(Settings.userRoot().get("thetvdb.apikey"))
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
@ -38,7 +38,7 @@ class EpisodeExpressionFormatter extends ExpressionFormat implements MatchFormat
|
||||
Episode episode = (Episode) match.getValue();
|
||||
File mediaFile = (File) match.getCandidate();
|
||||
|
||||
return format(new EpisodeFormatBindingBean(episode, mediaFile));
|
||||
return format(new EpisodeFormatBindingBean(episode, mediaFile)).trim();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,8 +4,6 @@ package net.sourceforge.filebot.ui.panel.subtitle;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
@ -24,8 +22,6 @@ public class SubtitleListCellRenderer extends AbstractFancyListCellRenderer {
|
||||
|
||||
private final JProgressBar progressBar = new JProgressBar(0, 100);
|
||||
|
||||
private final Map<String, String> languageCodeMap = mapLanguageCodeByName(Language.availableLanguages());
|
||||
|
||||
|
||||
public SubtitleListCellRenderer() {
|
||||
setHighlightingEnabled(false);
|
||||
@ -54,8 +50,8 @@ public class SubtitleListCellRenderer extends AbstractFancyListCellRenderer {
|
||||
titleLabel.setText(subtitle.getName());
|
||||
|
||||
if (languageLabel.isVisible()) {
|
||||
languageLabel.setText(subtitle.getLanguageName());
|
||||
languageLabel.setIcon(ResourceManager.getFlagIcon(languageCodeMap.get(subtitle.getLanguageName())));
|
||||
languageLabel.setText(subtitle.getLanguage().getName());
|
||||
languageLabel.setIcon(ResourceManager.getFlagIcon(subtitle.getLanguage().getCode()));
|
||||
}
|
||||
|
||||
//TODO download + progress
|
||||
@ -70,17 +66,6 @@ public class SubtitleListCellRenderer extends AbstractFancyListCellRenderer {
|
||||
}
|
||||
|
||||
|
||||
private Map<String, String> mapLanguageCodeByName(Language[] languages) {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
|
||||
for (Language language : languages) {
|
||||
map.put(language.getName(), language.getCode());
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
public JLabel getLanguageLabel() {
|
||||
return languageLabel;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package net.sourceforge.filebot.ui.panel.subtitle;
|
||||
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Action;
|
||||
@ -18,7 +19,6 @@ import net.sourceforge.filebot.ResourceManager;
|
||||
import ca.odell.glazedlists.BasicEventList;
|
||||
import ca.odell.glazedlists.EventList;
|
||||
import ca.odell.glazedlists.FilterList;
|
||||
import ca.odell.glazedlists.GlazedLists;
|
||||
import ca.odell.glazedlists.ListSelection;
|
||||
import ca.odell.glazedlists.TextFilterator;
|
||||
import ca.odell.glazedlists.swing.EventListModel;
|
||||
@ -34,10 +34,17 @@ public class SubtitleListComponent extends JComponent {
|
||||
|
||||
private JTextField filterEditor = new JTextField();
|
||||
|
||||
|
||||
|
||||
public SubtitleListComponent() {
|
||||
TextFilterator<SubtitlePackage> filterator = GlazedLists.toStringTextFilterator();
|
||||
TextComponentMatcherEditor<SubtitlePackage> matcherEditor = new TextComponentMatcherEditor<SubtitlePackage>(filterEditor, filterator);
|
||||
// allow filtering by language name and subtitle name
|
||||
TextComponentMatcherEditor<SubtitlePackage> matcherEditor = new TextComponentMatcherEditor<SubtitlePackage>(filterEditor, new TextFilterator<SubtitlePackage>() {
|
||||
|
||||
@Override
|
||||
public void getFilterStrings(List<String> list, SubtitlePackage element) {
|
||||
list.add(element.getLanguage().getName());
|
||||
list.add(element.getName());
|
||||
}
|
||||
});
|
||||
|
||||
JList list = new JList(new EventListModel<SubtitlePackage>(new FilterList<SubtitlePackage>(model, matcherEditor)));
|
||||
list.setCellRenderer(renderer);
|
||||
@ -68,6 +75,7 @@ public class SubtitleListComponent extends JComponent {
|
||||
renderer.getLanguageLabel().setVisible(visible);
|
||||
}
|
||||
|
||||
|
||||
private final Action clearFilterAction = new AbstractAction(null, ResourceManager.getIcon("edit.clear")) {
|
||||
|
||||
@Override
|
||||
|
@ -2,9 +2,11 @@
|
||||
package net.sourceforge.filebot.ui.panel.subtitle;
|
||||
|
||||
|
||||
import javax.swing.Icon;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import net.sourceforge.filebot.ResourceManager;
|
||||
import net.sourceforge.filebot.web.SubtitleDescriptor;
|
||||
import net.sourceforge.tuned.DownloadTask;
|
||||
|
||||
@ -13,25 +15,16 @@ public class SubtitlePackage {
|
||||
|
||||
private final SubtitleDescriptor subtitleDescriptor;
|
||||
|
||||
private final ArchiveType archiveType;
|
||||
|
||||
private final Icon archiveIcon;
|
||||
private final Language language;
|
||||
|
||||
private final DownloadTask downloadTask;
|
||||
|
||||
|
||||
|
||||
public SubtitlePackage(SubtitleDescriptor subtitleDescriptor) {
|
||||
this.subtitleDescriptor = subtitleDescriptor;
|
||||
|
||||
downloadTask = subtitleDescriptor.createDownloadTask();
|
||||
|
||||
archiveType = ArchiveType.forName(subtitleDescriptor.getArchiveType());
|
||||
archiveIcon = ResourceManager.getArchiveIcon(archiveType.getExtension());
|
||||
}
|
||||
|
||||
|
||||
public SubtitleDescriptor getSubtitleDescriptor() {
|
||||
return subtitleDescriptor;
|
||||
this.language = new Language(languageCodeByName.get(subtitleDescriptor.getLanguageName()), subtitleDescriptor.getLanguageName());
|
||||
this.downloadTask = subtitleDescriptor.createDownloadTask();
|
||||
}
|
||||
|
||||
|
||||
@ -40,24 +33,13 @@ public class SubtitlePackage {
|
||||
}
|
||||
|
||||
|
||||
public String getLanguageName() {
|
||||
return subtitleDescriptor.getLanguageName();
|
||||
public Language getLanguage() {
|
||||
return language;
|
||||
}
|
||||
|
||||
|
||||
public ArchiveType getArchiveType() {
|
||||
return archiveType;
|
||||
}
|
||||
|
||||
|
||||
public Icon getArchiveIcon() {
|
||||
return archiveIcon;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getName();
|
||||
return ArchiveType.forName(subtitleDescriptor.getArchiveType());
|
||||
}
|
||||
|
||||
|
||||
@ -65,4 +47,29 @@ public class SubtitlePackage {
|
||||
return downloadTask;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return subtitleDescriptor.getName();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Map english language name to language code.
|
||||
*/
|
||||
private static final Map<String, String> languageCodeByName = mapLanguageCodeByName();
|
||||
|
||||
|
||||
private static Map<String, String> mapLanguageCodeByName() {
|
||||
ResourceBundle bundle = ResourceBundle.getBundle(Language.class.getName(), Locale.ENGLISH);
|
||||
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
|
||||
for (String code : bundle.keySet()) {
|
||||
map.put(bundle.getString(code), code);
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import net.sourceforge.filebot.ui.AbstractSearchPanel;
|
||||
import net.sourceforge.filebot.ui.SelectDialog;
|
||||
import net.sourceforge.filebot.web.OpenSubtitlesSubtitleClient;
|
||||
import net.sourceforge.filebot.web.SearchResult;
|
||||
import net.sourceforge.filebot.web.SublightSubtitleClient;
|
||||
import net.sourceforge.filebot.web.SubsceneSubtitleClient;
|
||||
import net.sourceforge.filebot.web.SubtitleDescriptor;
|
||||
import net.sourceforge.filebot.web.SubtitleProvider;
|
||||
@ -35,7 +36,7 @@ public class SubtitlePanel extends AbstractSearchPanel<SubtitleProvider, Subtitl
|
||||
|
||||
private final LanguageComboBoxModel languageModel = new LanguageComboBoxModel();
|
||||
|
||||
|
||||
|
||||
public SubtitlePanel() {
|
||||
historyPanel.setColumnHeader(0, "Show / Movie");
|
||||
historyPanel.setColumnHeader(1, "Number of Subtitles");
|
||||
@ -76,14 +77,15 @@ public class SubtitlePanel extends AbstractSearchPanel<SubtitleProvider, Subtitl
|
||||
|
||||
|
||||
@Override
|
||||
protected List<SubtitleProvider> createSearchEngines() {
|
||||
List<SubtitleProvider> engines = new ArrayList<SubtitleProvider>(2);
|
||||
protected SubtitleProvider[] createSearchEngines() {
|
||||
String clientInfo = String.format("%s v%s", getApplicationName(), getApplicationVersion());
|
||||
|
||||
engines.add(new OpenSubtitlesSubtitleClient(String.format("%s v%s", getApplicationName(), getApplicationVersion())));
|
||||
engines.add(new SubsceneSubtitleClient());
|
||||
engines.add(new SubtitleSourceClient());
|
||||
|
||||
return engines;
|
||||
return new SubtitleProvider[] {
|
||||
new OpenSubtitlesSubtitleClient(clientInfo),
|
||||
new SubsceneSubtitleClient(),
|
||||
new SublightSubtitleClient(clientInfo),
|
||||
new SubtitleSourceClient()
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -111,13 +113,13 @@ public class SubtitlePanel extends AbstractSearchPanel<SubtitleProvider, Subtitl
|
||||
return new SubtitleRequestProcessor(new SubtitleRequest(provider, text, languageName));
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected static class SubtitleRequest extends Request {
|
||||
|
||||
private final SubtitleProvider provider;
|
||||
private final String languageName;
|
||||
|
||||
|
||||
|
||||
public SubtitleRequest(SubtitleProvider provider, String searchText, String languageName) {
|
||||
super(searchText);
|
||||
|
||||
@ -202,6 +204,7 @@ public class SubtitlePanel extends AbstractSearchPanel<SubtitleProvider, Subtitl
|
||||
|
||||
}
|
||||
|
||||
|
||||
private final PreferencesEntry<Language> persistentSelectedLanguage = getSettings().entry("language.selected", new AbstractAdapter<Language>() {
|
||||
|
||||
@Override
|
||||
|
@ -12,9 +12,9 @@ public class Episode implements Serializable {
|
||||
private final String episode;
|
||||
private final String title;
|
||||
|
||||
|
||||
public Episode(String seriesName, Integer season, Integer episode, String title) {
|
||||
this(seriesName, season.toString(), episode.toString(), title);
|
||||
|
||||
public Episode(String seriesName, int season, int episode, String title) {
|
||||
this(seriesName, String.valueOf(season), String.valueOf(episode), title);
|
||||
}
|
||||
|
||||
|
||||
|
@ -14,7 +14,7 @@ public class EpisodeFormat extends Format {
|
||||
|
||||
private static final EpisodeFormat instance = new EpisodeFormat();
|
||||
|
||||
|
||||
|
||||
public static EpisodeFormat getInstance() {
|
||||
return instance;
|
||||
}
|
||||
@ -24,18 +24,25 @@ public class EpisodeFormat extends Format {
|
||||
public StringBuffer format(Object obj, StringBuffer sb, FieldPosition pos) {
|
||||
Episode episode = (Episode) obj;
|
||||
|
||||
sb.append(episode.getSeriesName()).append(" - ");
|
||||
// try to format episode number, or use episode "number" string as is
|
||||
String episodeNumber = (episode.getEpisodeNumber() != null ? String.format("%02d", episode.getEpisodeNumber()) : episode.getEpisode());
|
||||
|
||||
// series name should not be empty or null
|
||||
sb.append(episode.getSeriesName());
|
||||
|
||||
if (episode.getSeason() != null) {
|
||||
sb.append(episode.getSeason()).append('x');
|
||||
// season and episode
|
||||
sb.append(" - ").append(episode.getSeason()).append('x').append(episodeNumber);
|
||||
} else if (episodeNumber != null) {
|
||||
// episode, but no season
|
||||
sb.append(" - ").append(episodeNumber);
|
||||
}
|
||||
|
||||
Integer episodeNumber = episode.getEpisodeNumber();
|
||||
if (episode.getTitle() != null) {
|
||||
sb.append(" - ").append(episode.getTitle());
|
||||
}
|
||||
|
||||
// try to format episode number, or use episode "number" string as is
|
||||
sb.append(episodeNumber != null ? String.format("%02d", episodeNumber) : episode.getEpisode());
|
||||
|
||||
return sb.append(" - ").append(episode.getTitle());
|
||||
return sb;
|
||||
}
|
||||
|
||||
|
||||
|
@ -31,7 +31,7 @@ public class IMDbClient implements EpisodeListProvider {
|
||||
|
||||
private static final String host = "www.imdb.com";
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "IMDb";
|
||||
@ -66,17 +66,16 @@ public class IMDbClient implements EpisodeListProvider {
|
||||
String year = node.getNextSibling().getTextContent().trim();
|
||||
String href = getAttribute("href", node);
|
||||
|
||||
String nameAndYear = String.format("%s %s", name, year).trim();
|
||||
|
||||
results.add(new MovieDescriptor(nameAndYear, getImdbId(href)));
|
||||
results.add(new MovieDescriptor(name, Integer.parseInt(year), getImdbId(href)));
|
||||
}
|
||||
|
||||
// we might have been redirected to the movie page
|
||||
if (results.isEmpty()) {
|
||||
String name = removeQuotationMarks(selectString("//H1/text()", dom));
|
||||
String year = selectString("//H1//A", dom);
|
||||
String url = selectString("//LINK[@rel='canonical']/@href", dom);
|
||||
|
||||
results.add(new MovieDescriptor(name, getImdbId(url)));
|
||||
results.add(new MovieDescriptor(name, Integer.parseInt(year), getImdbId(url)));
|
||||
}
|
||||
|
||||
return results;
|
||||
|
@ -4,15 +4,23 @@ package net.sourceforge.filebot.web;
|
||||
|
||||
public class MovieDescriptor extends SearchResult {
|
||||
|
||||
private final int year;
|
||||
private final int imdbId;
|
||||
|
||||
|
||||
public MovieDescriptor(String name, int imdbId) {
|
||||
|
||||
public MovieDescriptor(String name, int year, int imdbId) {
|
||||
super(name);
|
||||
|
||||
this.year = year;
|
||||
this.imdbId = imdbId;
|
||||
}
|
||||
|
||||
|
||||
public int getYear() {
|
||||
return year;
|
||||
}
|
||||
|
||||
|
||||
public int getImdbId() {
|
||||
return imdbId;
|
||||
}
|
||||
@ -22,10 +30,16 @@ public class MovieDescriptor extends SearchResult {
|
||||
public boolean equals(Object object) {
|
||||
if (object instanceof MovieDescriptor) {
|
||||
MovieDescriptor other = (MovieDescriptor) object;
|
||||
return this.getImdbId() == other.getImdbId() && this.getName() == other.getName();
|
||||
return getImdbId() == other.getImdbId() && getName().equals(other.getName()) && getYear() == other.getYear();
|
||||
}
|
||||
|
||||
return super.equals(object);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s (%d)", getName(), getYear());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -24,13 +24,13 @@ public class OpenSubtitlesClient {
|
||||
|
||||
private static final String url = "http://www.opensubtitles.org/xml-rpc";
|
||||
|
||||
private final String useragent;
|
||||
private final String clientInfo;
|
||||
|
||||
private String token = null;
|
||||
|
||||
|
||||
public OpenSubtitlesClient(String useragent) {
|
||||
this.useragent = useragent;
|
||||
|
||||
public OpenSubtitlesClient(String clientInfo) {
|
||||
this.clientInfo = clientInfo;
|
||||
}
|
||||
|
||||
|
||||
@ -70,7 +70,7 @@ public class OpenSubtitlesClient {
|
||||
@SuppressWarnings("unchecked")
|
||||
public synchronized void login(String username, String password, String language) throws XmlRpcFault {
|
||||
|
||||
Map<String, String> response = (Map<String, String>) invoke("LogIn", username, password, language, useragent);
|
||||
Map<String, String> response = (Map<String, String>) invoke("LogIn", username, password, language, clientInfo);
|
||||
checkStatus(response.get("status"));
|
||||
|
||||
token = response.get("token");
|
||||
@ -191,7 +191,7 @@ public class OpenSubtitlesClient {
|
||||
title = title.substring(0, endIndex);
|
||||
}
|
||||
|
||||
movies.add(new MovieDescriptor(title, new Integer(movie.get("id"))));
|
||||
movies.add(new MovieDescriptor(title, Integer.parseInt(movie.get("year")), Integer.parseInt(movie.get("id"))));
|
||||
}
|
||||
|
||||
return movies;
|
||||
|
@ -19,14 +19,14 @@ import java.nio.channels.FileChannel.MapMode;
|
||||
* checksum of the first and last 64k (even if they overlap because the file is smaller than
|
||||
* 128k).
|
||||
*/
|
||||
public class OpenSubtitlesHasher {
|
||||
public final class OpenSubtitlesHasher {
|
||||
|
||||
/**
|
||||
* Size of the chunks that will be hashed in bytes (64 KB)
|
||||
*/
|
||||
private static final int HASH_CHUNK_SIZE = 64 * 1024;
|
||||
|
||||
|
||||
|
||||
public static String computeHash(File file) throws IOException {
|
||||
long size = file.length();
|
||||
long chunkSizeForFile = Math.min(HASH_CHUNK_SIZE, size);
|
||||
|
@ -21,7 +21,7 @@ public class OpenSubtitlesSubtitleClient implements SubtitleProvider {
|
||||
|
||||
private final OpenSubtitlesClient client;
|
||||
|
||||
|
||||
|
||||
public OpenSubtitlesSubtitleClient(String useragent) {
|
||||
this.client = new OpenSubtitlesClient(useragent);
|
||||
}
|
||||
@ -39,21 +39,27 @@ public class OpenSubtitlesSubtitleClient implements SubtitleProvider {
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public List<SearchResult> search(String query) throws Exception {
|
||||
// require login
|
||||
login();
|
||||
|
||||
return (List) client.searchMoviesOnIMDB(query);
|
||||
@SuppressWarnings("unchecked")
|
||||
List<SearchResult> results = (List) client.searchMoviesOnIMDB(query);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public List<SubtitleDescriptor> getSubtitleList(SearchResult searchResult, String languageName) throws Exception {
|
||||
// require login
|
||||
login();
|
||||
|
||||
return (List) client.searchSubtitles(((MovieDescriptor) searchResult).getImdbId(), languageName);
|
||||
@SuppressWarnings("unchecked")
|
||||
List<SubtitleDescriptor> subtitles = (List) client.searchSubtitles(((MovieDescriptor) searchResult).getImdbId(), languageName);
|
||||
|
||||
return subtitles;
|
||||
}
|
||||
|
||||
|
||||
@ -64,33 +70,33 @@ public class OpenSubtitlesSubtitleClient implements SubtitleProvider {
|
||||
}
|
||||
|
||||
|
||||
private synchronized void login() throws Exception {
|
||||
protected synchronized void login() throws Exception {
|
||||
if (!client.isLoggedOn()) {
|
||||
client.loginAnonymous();
|
||||
}
|
||||
|
||||
logoutTimer.set(12, TimeUnit.MINUTES, true);
|
||||
logoutTimer.set(10, TimeUnit.MINUTES, true);
|
||||
}
|
||||
|
||||
|
||||
private synchronized void logout() {
|
||||
logoutTimer.cancel();
|
||||
|
||||
protected synchronized void logout() {
|
||||
if (client.isLoggedOn()) {
|
||||
try {
|
||||
client.logout();
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger(getClass().getName()).log(Level.SEVERE, "Exception while deactivating session", e);
|
||||
Logger.getLogger(getClass().getName()).log(Level.SEVERE, "Logout failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
logoutTimer.cancel();
|
||||
}
|
||||
|
||||
private final Timer logoutTimer = new Timer() {
|
||||
|
||||
protected final Timer logoutTimer = new Timer() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
logout();
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ public abstract class SearchResult implements Serializable {
|
||||
|
||||
private final String name;
|
||||
|
||||
|
||||
|
||||
public SearchResult(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ public class SubtitleSourceClient implements SubtitleProvider {
|
||||
|
||||
private static final int pageSize = 20;
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "SubtitleSource";
|
||||
@ -59,8 +59,9 @@ public class SubtitleSourceClient implements SubtitleProvider {
|
||||
|
||||
if (!movieMap.containsKey(imdb)) {
|
||||
String title = getTextContent("title", node);
|
||||
String year = getTextContent("year", node);
|
||||
|
||||
movieMap.put(imdb, new MovieDescriptor(title, imdb));
|
||||
movieMap.put(imdb, new MovieDescriptor(title, Integer.parseInt(year), imdb));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ public abstract class Timer implements Runnable {
|
||||
private ScheduledFuture<?> scheduledFuture;
|
||||
private Thread shutdownHook;
|
||||
|
||||
|
||||
|
||||
public Timer() {
|
||||
executor = new ScheduledThreadPoolExecutor(1);
|
||||
executor.setKeepAliveTime(200, TimeUnit.MILLISECONDS);
|
||||
|
@ -15,6 +15,8 @@ import java.awt.event.MouseEvent;
|
||||
import java.awt.geom.GeneralPath;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
@ -39,14 +41,14 @@ public class SelectButton<T> extends JButton {
|
||||
|
||||
private final SelectIcon selectIcon = new SelectIcon();
|
||||
|
||||
private List<T> model = new ArrayList<T>(0);
|
||||
private List<T> model = Collections.emptyList();
|
||||
private SingleSelectionModel selectionModel = new DefaultSingleSelectionModel();
|
||||
|
||||
private LabelProvider<T> labelProvider = new NullLabelProvider<T>();
|
||||
|
||||
private boolean hover = false;
|
||||
|
||||
|
||||
|
||||
public SelectButton() {
|
||||
setContentAreaFilled(false);
|
||||
setFocusable(false);
|
||||
@ -63,9 +65,8 @@ public class SelectButton<T> extends JButton {
|
||||
}
|
||||
|
||||
|
||||
public void setModel(List<T> model) {
|
||||
this.model.clear();
|
||||
this.model.addAll(model);
|
||||
public void setModel(Collection<T> model) {
|
||||
this.model = new ArrayList<T>(model);
|
||||
|
||||
setSelectedIndex(0);
|
||||
}
|
||||
@ -180,7 +181,7 @@ public class SelectButton<T> extends JButton {
|
||||
super.processMouseEvent(e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private class OpenPopupOnClick implements ActionListener {
|
||||
|
||||
@Override
|
||||
@ -205,7 +206,7 @@ public class SelectButton<T> extends JButton {
|
||||
|
||||
private final T value;
|
||||
|
||||
|
||||
|
||||
public SelectPopupMenuItem(String text, Icon icon, T value) {
|
||||
super(text, icon);
|
||||
|
||||
@ -236,7 +237,7 @@ public class SelectButton<T> extends JButton {
|
||||
|
||||
private Icon icon;
|
||||
|
||||
|
||||
|
||||
public SelectIcon() {
|
||||
arrow = new GeneralPath(Path2D.WIND_EVEN_ODD, 3);
|
||||
int x = 25;
|
||||
|
@ -13,14 +13,15 @@ public class IMDbClientTest {
|
||||
|
||||
private final IMDbClient imdb = new IMDbClient();
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void search() throws Exception {
|
||||
List<SearchResult> results = imdb.search("battlestar");
|
||||
|
||||
MovieDescriptor movie = (MovieDescriptor) results.get(0);
|
||||
|
||||
assertEquals("Battlestar Galactica (2004)", movie.getName());
|
||||
assertEquals("Battlestar Galactica", movie.getName());
|
||||
assertEquals(2004, movie.getYear());
|
||||
assertEquals(407362, movie.getImdbId(), 0);
|
||||
|
||||
assertEquals(6, results.size(), 0);
|
||||
@ -43,7 +44,7 @@ public class IMDbClientTest {
|
||||
|
||||
@Test
|
||||
public void getEpisodeList() throws Exception {
|
||||
List<Episode> list = imdb.getEpisodeList(new MovieDescriptor("Buffy", 118276));
|
||||
List<Episode> list = imdb.getEpisodeList(new MovieDescriptor("Buffy", 1997, 118276));
|
||||
|
||||
assertEquals(145, list.size());
|
||||
|
||||
@ -65,7 +66,7 @@ public class IMDbClientTest {
|
||||
|
||||
@Test
|
||||
public void getEpisodeListWithUnknownSeason() throws Exception {
|
||||
List<Episode> list = imdb.getEpisodeList(new MovieDescriptor("Mushishi", 807832));
|
||||
List<Episode> list = imdb.getEpisodeList(new MovieDescriptor("Mushishi", 2005, 807832));
|
||||
|
||||
assertEquals(26, list.size());
|
||||
|
||||
@ -80,7 +81,7 @@ public class IMDbClientTest {
|
||||
|
||||
@Test
|
||||
public void getEpisodeListLink() throws Exception {
|
||||
assertEquals("http://www.imdb.com/title/tt0407362/episodes", imdb.getEpisodeListLink(new MovieDescriptor("Battlestar Galactica", 407362)).toString());
|
||||
assertEquals("http://www.imdb.com/title/tt0407362/episodes", imdb.getEpisodeListLink(new MovieDescriptor("Battlestar Galactica", 2004, 407362)).toString());
|
||||
}
|
||||
|
||||
|
||||
|
@ -13,7 +13,7 @@ public class SubtitleSourceClientTest {
|
||||
|
||||
private static final SubtitleSourceClient client = new SubtitleSourceClient();
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void search() throws Exception {
|
||||
List<SearchResult> list = client.search("babylon 5");
|
||||
@ -31,7 +31,7 @@ public class SubtitleSourceClientTest {
|
||||
|
||||
@Test
|
||||
public void getSubtitleListAll() throws Exception {
|
||||
List<SubtitleDescriptor> list = client.getSubtitleList(new MovieDescriptor("Buffy", 118276), "English");
|
||||
List<SubtitleDescriptor> list = client.getSubtitleList(new MovieDescriptor("Buffy", 1997, 118276), "English");
|
||||
|
||||
SubtitleDescriptor sample = list.get(0);
|
||||
|
||||
@ -46,7 +46,7 @@ public class SubtitleSourceClientTest {
|
||||
|
||||
@Test
|
||||
public void getSubtitleListSinglePage() throws Exception {
|
||||
List<SubtitleDescriptor> list = client.getSubtitleList(new MovieDescriptor("Firefly", 303461), 0);
|
||||
List<SubtitleDescriptor> list = client.getSubtitleList(new MovieDescriptor("Firefly", 2002, 303461), 0);
|
||||
|
||||
SubtitleDescriptor sample = list.get(0);
|
||||
|
||||
@ -60,6 +60,6 @@ public class SubtitleSourceClientTest {
|
||||
|
||||
@Test
|
||||
public void getSubtitleListLink() {
|
||||
assertEquals("http://www.subtitlesource.org/title/tt0303461", client.getSubtitleListLink(new MovieDescriptor("Firefly", 303461), null).toString());
|
||||
assertEquals("http://www.subtitlesource.org/title/tt0303461", client.getSubtitleListLink(new MovieDescriptor("Firefly", 2002, 303461), null).toString());
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ public class PreferencesMapTest {
|
||||
private static Preferences temp;
|
||||
private static Preferences sequence;
|
||||
|
||||
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpBeforeClass() throws Exception {
|
||||
root = Preferences.userRoot().node("junit-test");
|
||||
@ -168,7 +168,7 @@ public class PreferencesMapTest {
|
||||
public void serializableAdapter() {
|
||||
Map<String, MovieDescriptor> map = PreferencesMap.map(temp, new SerializableAdapter<MovieDescriptor>());
|
||||
|
||||
MovieDescriptor movie = new MovieDescriptor("The Hitchhiker's Guide to the Galaxy", 42);
|
||||
MovieDescriptor movie = new MovieDescriptor("The Hitchhiker's Guide to the Galaxy", 1981, 42);
|
||||
|
||||
map.put("movie", movie);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user