+ added initial support for episode formatting language preferences

(preferred language will be ignored if data-source doesn't support multiple languages)
This commit is contained in:
Reinhard Pointner 2011-08-08 17:37:45 +00:00
parent 38bbaaf5d8
commit 949b1ce864
23 changed files with 215 additions and 148 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 947 B

View File

@ -1,5 +1,5 @@
package net.sourceforge.filebot.ui.panel.subtitle;
package net.sourceforge.filebot.ui;
import java.util.Comparator;

View File

@ -4,11 +4,12 @@ package net.sourceforge.filebot.ui.panel.rename;
import java.io.File;
import java.util.List;
import java.util.Locale;
import net.sourceforge.filebot.similarity.Match;
interface AutoCompleteMatcher {
List<Match<File, ?>> match(List<File> files) throws Exception;
List<Match<File, ?>> match(List<File> files, Locale locale) throws Exception;
}

View File

@ -14,6 +14,7 @@ import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
@ -91,6 +92,7 @@ class EpisodeListMatcher implements AutoCompleteMatcher {
selectDialog.getHeaderLabel().setText(String.format("Shows matching '%s':", query));
selectDialog.getCancelAction().putValue(Action.NAME, "Ignore");
selectDialog.pack();
// show dialog
selectDialog.setLocation(getOffsetLocation(selectDialog.getOwner()));
@ -111,7 +113,7 @@ class EpisodeListMatcher implements AutoCompleteMatcher {
}
protected Set<Episode> fetchEpisodeSet(Collection<String> seriesNames) throws Exception {
protected Set<Episode> fetchEpisodeSet(Collection<String> seriesNames, final Locale locale) throws Exception {
List<Callable<List<Episode>>> tasks = new ArrayList<Callable<List<Episode>>>();
// detect series names and create episode list fetch tasks
@ -120,14 +122,14 @@ class EpisodeListMatcher implements AutoCompleteMatcher {
@Override
public List<Episode> call() throws Exception {
List<SearchResult> results = provider.search(query);
List<SearchResult> results = provider.search(query, locale);
// select search result
if (results.size() > 0) {
SearchResult selectedSearchResult = selectSearchResult(query, results);
if (selectedSearchResult != null) {
return provider.getEpisodeList(selectedSearchResult);
return provider.getEpisodeList(selectedSearchResult, locale);
}
}
@ -157,12 +159,12 @@ class EpisodeListMatcher implements AutoCompleteMatcher {
@Override
public List<Match<File, ?>> match(final List<File> files) throws Exception {
public List<Match<File, ?>> match(final List<File> files, Locale locale) throws Exception {
// focus on movie and subtitle files
List<File> mediaFiles = FileUtilities.filter(files, VIDEO_FILES, SUBTITLE_FILES);
// detect series name and fetch episode list
Set<Episode> episodes = fetchEpisodeSet(detectSeriesNames(mediaFiles));
Set<Episode> episodes = fetchEpisodeSet(detectSeriesNames(mediaFiles), locale);
List<Match<File, ?>> matches = new ArrayList<Match<File, ?>>();

View File

@ -14,6 +14,7 @@ import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
@ -44,7 +45,7 @@ class MovieHashMatcher implements AutoCompleteMatcher {
@Override
public List<Match<File, ?>> match(final List<File> files) throws Exception {
public List<Match<File, ?>> match(final List<File> files, Locale locale) throws Exception {
// handle movie files
File[] movieFiles = filter(files, VIDEO_FILES).toArray(new File[0]);
MovieDescriptor[] movieDescriptors = service.getMovieDescriptors(movieFiles);

View File

@ -2,29 +2,38 @@
package net.sourceforge.filebot.ui.panel.rename;
import static javax.swing.JOptionPane.*;
import static javax.swing.SwingUtilities.*;
import static net.sourceforge.filebot.Settings.*;
import static net.sourceforge.tuned.ui.LoadingOverlayPane.*;
import static net.sourceforge.tuned.ui.TunedUtilities.*;
import java.awt.Component;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.DefaultListCellRenderer;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import ca.odell.glazedlists.ListSelection;
@ -35,6 +44,7 @@ import net.sourceforge.filebot.ResourceManager;
import net.sourceforge.filebot.Settings;
import net.sourceforge.filebot.WebServices;
import net.sourceforge.filebot.similarity.Match;
import net.sourceforge.filebot.ui.Language;
import net.sourceforge.filebot.ui.panel.rename.RenameModel.FormattedFuture;
import net.sourceforge.filebot.web.Episode;
import net.sourceforge.filebot.web.EpisodeListProvider;
@ -61,6 +71,7 @@ public class RenamePanel extends JComponent {
private static final PreferencesEntry<String> persistentPreserveExtension = Settings.forPackage(RenamePanel.class).entry("rename.extension.preserve").defaultValue("true");
private static final PreferencesEntry<String> persistentFormatExpression = Settings.forPackage(RenamePanel.class).entry("rename.format");
private static final PreferencesEntry<String> persistentPreferredLanguage = Settings.forPackage(RenamePanel.class).entry("rename.language").defaultValue("en");
public RenamePanel() {
@ -161,7 +172,7 @@ public class RenamePanel extends JComponent {
@Override
public void actionPerformed(ActionEvent evt) {
EpisodeFormatDialog dialog = new EpisodeFormatDialog(SwingUtilities.getWindowAncestor(RenamePanel.this));
EpisodeFormatDialog dialog = new EpisodeFormatDialog(getWindowAncestor(RenamePanel.this));
dialog.setLocation(getOffsetLocation(dialog.getOwner()));
dialog.setVisible(true);
@ -178,6 +189,51 @@ public class RenamePanel extends JComponent {
}
});
actionPopup.add(new AbstractAction("Preferences", ResourceManager.getIcon("action.preferences")) {
@Override
public void actionPerformed(ActionEvent evt) {
List<Language> languages = new LinkedList<Language>();
// all languages
Language[] availableLanguages = Language.availableLanguages();
Arrays.sort(availableLanguages, Language.ALPHABETIC_ORDER);
Collections.addAll(languages, availableLanguages);
// guess preferred language
if (!Locale.getDefault().equals(Locale.ENGLISH)) {
languages.add(0, Language.getLanguage(Locale.getDefault().getLanguage()));
}
languages.add(0, Language.getLanguage("en"));
JList message = new JList(languages.toArray());
message.setCellRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
setIcon(ResourceManager.getFlagIcon(((Language) value).getCode()));
return this;
}
});
// pre-select current language preferences
for (Language language : languages) {
if (language.getCode().equals(persistentPreferredLanguage.getValue())) {
message.setSelectedValue(language, true);
break;
}
}
JOptionPane pane = new JOptionPane(new JScrollPane(message), PLAIN_MESSAGE, OK_CANCEL_OPTION);
pane.createDialog(getWindowAncestor(RenamePanel.this), "Language Preference").setVisible(true);
if (pane.getValue() != null && pane.getValue().equals(OK_OPTION)) {
persistentPreferredLanguage.setValue(((Language) message.getSelectedValue()).getCode());
}
}
});
return actionPopup;
}
@ -292,11 +348,12 @@ public class RenamePanel extends JComponent {
SwingWorker<List<Match<File, ?>>, Void> worker = new SwingWorker<List<Match<File, ?>>, Void>() {
private final List<File> remainingFiles = new LinkedList<File>(renameModel.files());
private final Locale locale = new Locale(persistentPreferredLanguage.getValue());
@Override
protected List<Match<File, ?>> doInBackground() throws Exception {
List<Match<File, ?>> matches = matcher.match(remainingFiles);
List<Match<File, ?>> matches = matcher.match(remainingFiles, locale);
// remove matched files
for (Match<File, ?> match : matches) {

View File

@ -13,6 +13,7 @@ import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import net.sourceforge.filebot.ResourceManager;
import net.sourceforge.filebot.ui.Language;
class LanguageComboBoxCellRenderer implements ListCellRenderer {

View File

@ -2,7 +2,7 @@
package net.sourceforge.filebot.ui.panel.subtitle;
import static net.sourceforge.filebot.ui.panel.subtitle.Language.*;
import static net.sourceforge.filebot.ui.Language.*;
import java.util.AbstractList;
import java.util.ArrayList;
@ -14,6 +14,8 @@ import java.util.Set;
import javax.swing.AbstractListModel;
import javax.swing.ComboBoxModel;
import net.sourceforge.filebot.ui.Language;
class LanguageComboBoxModel extends AbstractListModel implements ComboBoxModel {

View File

@ -20,6 +20,7 @@ import java.util.ResourceBundle;
import javax.swing.SwingWorker;
import javax.swing.event.SwingPropertyChangeSupport;
import net.sourceforge.filebot.ui.Language;
import net.sourceforge.filebot.web.SubtitleDescriptor;
import net.sourceforge.tuned.FileUtilities;

View File

@ -23,6 +23,7 @@ import javax.swing.JComboBox;
import net.sourceforge.filebot.Settings;
import net.sourceforge.filebot.WebServices;
import net.sourceforge.filebot.ui.AbstractSearchPanel;
import net.sourceforge.filebot.ui.Language;
import net.sourceforge.filebot.ui.SelectDialog;
import net.sourceforge.filebot.web.SearchResult;
import net.sourceforge.filebot.web.SubtitleDescriptor;

View File

@ -0,0 +1,55 @@
package net.sourceforge.filebot.web;
import static net.sourceforge.filebot.web.EpisodeListUtilities.*;
import java.util.List;
import java.util.Locale;
public abstract class AbstractEpisodeListProvider implements EpisodeListProvider {
@Override
public boolean hasSingleSeasonSupport() {
return true;
}
@Override
public boolean hasLocaleSupport() {
return false;
}
@Override
public List<SearchResult> search(String query) throws Exception {
return search(query, Locale.ENGLISH);
}
@Override
public List<Episode> getEpisodeList(SearchResult searchResult) throws Exception {
return getEpisodeList(searchResult, Locale.ENGLISH);
}
@Override
public List<Episode> getEpisodeList(SearchResult searchResult, int season) throws Exception {
return getEpisodeList(searchResult, season, Locale.ENGLISH);
}
@Override
public List<Episode> getEpisodeList(SearchResult searchResult, int season, Locale locale) throws Exception {
List<Episode> all = getEpisodeList(searchResult, locale);
List<Episode> eps = filterBySeason(all, season);
if (eps.isEmpty()) {
throw new SeasonOutOfBoundsException(searchResult.getName(), season, getLastSeason(all));
}
return eps;
}
}

View File

@ -42,7 +42,7 @@ import net.sf.ehcache.Element;
import net.sourceforge.filebot.ResourceManager;
public class AnidbClient implements EpisodeListProvider {
public class AnidbClient extends AbstractEpisodeListProvider {
private static final String host = "anidb.net";
private static final AnidbCache cache = new AnidbCache(CacheManager.getInstance().getCache("web-persistent-datasource"));
@ -70,7 +70,19 @@ public class AnidbClient implements EpisodeListProvider {
@Override
public List<SearchResult> search(String query) throws Exception {
public boolean hasSingleSeasonSupport() {
return false;
}
@Override
public boolean hasLocaleSupport() {
return true;
}
@Override
public List<SearchResult> search(String query, Locale locale) throws Exception {
// normalize
query = query.toLowerCase();
@ -123,12 +135,9 @@ public class AnidbClient implements EpisodeListProvider {
@Override
public List<Episode> getEpisodeList(SearchResult searchResult) throws Exception {
return getEpisodeList((AnidbSearchResult) searchResult, Locale.ENGLISH);
}
public List<Episode> getEpisodeList(AnidbSearchResult anime, Locale language) throws Exception {
public List<Episode> getEpisodeList(SearchResult searchResult, Locale language) throws Exception {
AnidbSearchResult anime = (AnidbSearchResult) searchResult;
// e.g. http://api.anidb.net:9001/httpapi?request=anime&client=filebot&clientver=1&protover=1&aid=4521
URL url = new URL("http", "api." + host, 9001, "/httpapi?request=anime&client=" + client + "&clientver=" + clientver + "&protover=1&aid=" + anime.getAnimeId());
@ -141,7 +150,10 @@ public class AnidbClient implements EpisodeListProvider {
Document dom = getDocument(url);
// select main title
String animeTitle = selectString("//titles/title[@type='main']", dom);
String animeTitle = selectString("//titles/title[@type='official' and @lang='" + language.getLanguage() + "']", dom);
if (animeTitle.isEmpty()) {
animeTitle = selectString("//titles/title[@type='main']", dom);
}
episodes = new ArrayList<Episode>(25);
@ -151,6 +163,10 @@ public class AnidbClient implements EpisodeListProvider {
// ignore special episodes
if (number != null) {
String title = selectString(".//title[@lang='" + language.getLanguage() + "']", node);
if (title.isEmpty()) { // English language fall-back
title = selectString(".//title[@lang='en']", node);
}
String airdate = getTextContent("airdate", node);
// no seasons for anime
@ -187,13 +203,7 @@ public class AnidbClient implements EpisodeListProvider {
@Override
public boolean hasSingleSeasonSupport() {
return false;
}
@Override
public List<Episode> getEpisodeList(SearchResult searchResult, int season) throws Exception {
public List<Episode> getEpisodeList(SearchResult searchResult, int season, Locale locale) throws Exception {
throw new UnsupportedOperationException();
}

View File

@ -78,6 +78,9 @@ public class Date implements Serializable {
public static Date parse(String string, String pattern) {
if (string == null || string.isEmpty())
return null;
SimpleDateFormat formatter = new SimpleDateFormat(pattern, Locale.ROOT);
formatter.setLenient(false); // enable strict mode (e.g. fail on invalid dates like 0000-00-00)

View File

@ -4,33 +4,46 @@ package net.sourceforge.filebot.web;
import java.net.URI;
import java.util.List;
import java.util.Locale;
import javax.swing.Icon;
public interface EpisodeListProvider {
public List<SearchResult> search(String query) throws Exception;
public String getName();
public Icon getIcon();
public boolean hasSingleSeasonSupport();
public boolean hasLocaleSupport();
public List<SearchResult> search(String query) throws Exception;
public List<SearchResult> search(String query, Locale locale) throws Exception;
public List<Episode> getEpisodeList(SearchResult searchResult) throws Exception;
public List<Episode> getEpisodeList(SearchResult searchResult, int season) throws Exception;
public List<Episode> getEpisodeList(SearchResult searchResult, Locale locale) throws Exception;
public List<Episode> getEpisodeList(SearchResult searchResult, int season, Locale locale) throws Exception;
public URI getEpisodeListLink(SearchResult searchResult);
public URI getEpisodeListLink(SearchResult searchResult, int season);
public String getName();
public Icon getIcon();
}

View File

@ -2,7 +2,6 @@
package net.sourceforge.filebot.web;
import static net.sourceforge.filebot.web.EpisodeListUtilities.*;
import static net.sourceforge.filebot.web.WebRequest.*;
import static net.sourceforge.tuned.XPathUtilities.*;
@ -14,6 +13,7 @@ import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -27,7 +27,7 @@ import org.xml.sax.SAXException;
import net.sourceforge.filebot.ResourceManager;
public class IMDbClient implements EpisodeListProvider {
public class IMDbClient extends AbstractEpisodeListProvider {
private static final String host = "www.imdb.com";
@ -45,13 +45,7 @@ public class IMDbClient implements EpisodeListProvider {
@Override
public boolean hasSingleSeasonSupport() {
return true;
}
@Override
public List<SearchResult> search(String query) throws IOException, SAXException {
public List<SearchResult> search(String query, Locale locale) throws IOException, SAXException {
URL searchUrl = new URL("http", host, "/find?s=tt&q=" + URLEncoder.encode(query, "UTF-8"));
@ -87,7 +81,7 @@ public class IMDbClient implements EpisodeListProvider {
@Override
public List<Episode> getEpisodeList(SearchResult searchResult) throws IOException, SAXException {
public List<Episode> getEpisodeList(SearchResult searchResult, Locale locale) throws IOException, SAXException {
Document dom = getHtmlDocument(openConnection(getEpisodeListLink(searchResult).toURL()));
String seriesName = normalizeName(selectString("//H1/A", dom));
@ -113,19 +107,6 @@ public class IMDbClient implements EpisodeListProvider {
}
@Override
public List<Episode> getEpisodeList(SearchResult searchResult, int season) throws Exception {
List<Episode> all = getEpisodeList(searchResult);
List<Episode> eps = filterBySeason(all, season);
if (eps.isEmpty()) {
throw new SeasonOutOfBoundsException(searchResult.getName(), season, getLastSeason(all));
}
return eps;
}
protected URLConnection openConnection(URL url) throws IOException {
URLConnection connection = url.openConnection();

View File

@ -17,6 +17,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.AbstractMap.SimpleEntry;
import java.util.Map.Entry;
@ -36,7 +37,7 @@ import net.sf.ehcache.Element;
import net.sourceforge.filebot.ResourceManager;
public class SerienjunkiesClient implements EpisodeListProvider {
public class SerienjunkiesClient extends AbstractEpisodeListProvider {
private static final String host = "api.serienjunkies.de";
private static final SerienjunkiesCache cache = new SerienjunkiesCache(CacheManager.getInstance().getCache("web-persistent-datasource"));
@ -62,13 +63,7 @@ public class SerienjunkiesClient implements EpisodeListProvider {
@Override
public boolean hasSingleSeasonSupport() {
return true;
}
@Override
public List<SearchResult> search(String query) throws IOException {
public List<SearchResult> search(String query, Locale locale) throws IOException {
// normalize
query = query.toLowerCase();
@ -151,7 +146,7 @@ public class SerienjunkiesClient implements EpisodeListProvider {
@Override
public List<Episode> getEpisodeList(SearchResult searchResult) throws IOException {
public List<Episode> getEpisodeList(SearchResult searchResult, Locale locale) throws IOException {
SerienjunkiesSearchResult series = (SerienjunkiesSearchResult) searchResult;
// try cache first
@ -186,19 +181,6 @@ public class SerienjunkiesClient implements EpisodeListProvider {
}
@Override
public List<Episode> getEpisodeList(SearchResult searchResult, int season) throws IOException {
List<Episode> all = getEpisodeList(searchResult);
List<Episode> eps = filterBySeason(all, season);
if (eps.isEmpty()) {
throw new SeasonOutOfBoundsException(searchResult.getName(), season, getLastSeason(all));
}
return eps;
}
protected Object request(String resource) throws IOException {
URL url = new URL("https", host, resource);
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();

View File

@ -13,6 +13,7 @@ import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@ -31,7 +32,7 @@ import org.xml.sax.SAXException;
import net.sourceforge.filebot.ResourceManager;
public class TVDotComClient implements EpisodeListProvider {
public class TVDotComClient extends AbstractEpisodeListProvider {
private static final String host = "www.tv.com";
@ -49,14 +50,7 @@ public class TVDotComClient implements EpisodeListProvider {
@Override
public boolean hasSingleSeasonSupport() {
return true;
}
@Override
public List<SearchResult> search(String query) throws IOException, SAXException {
public List<SearchResult> search(String query, Locale locale) throws IOException, SAXException {
// use ajax search request, because we don't need the whole search result page
URL searchUrl = new URL("http", host, "/search.php?type=Search&stype=ajax_search&search_type=program&qs=" + URLEncoder.encode(query, "UTF-8"));
@ -81,8 +75,7 @@ public class TVDotComClient implements EpisodeListProvider {
@Override
public List<Episode> getEpisodeList(final SearchResult searchResult) throws Exception {
public List<Episode> getEpisodeList(final SearchResult searchResult, final Locale locale) throws Exception {
// get document for season 1
Document dom = getHtmlDocument(getEpisodeListLink(searchResult, 1).toURL());
@ -113,7 +106,7 @@ public class TVDotComClient implements EpisodeListProvider {
@Override
public List<Episode> call() throws Exception {
return getEpisodeList(searchResult, season);
return getEpisodeList(searchResult, season, locale);
}
}));
}
@ -137,9 +130,8 @@ public class TVDotComClient implements EpisodeListProvider {
@Override
public List<Episode> getEpisodeList(SearchResult searchResult, int season) throws IOException, SAXException {
public List<Episode> getEpisodeList(SearchResult searchResult, int season, Locale locale) throws IOException, SAXException {
Document dom = getHtmlDocument(getEpisodeListLink(searchResult, season).toURL());
return getEpisodeList(searchResult, dom);
}

View File

@ -12,9 +12,9 @@ import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import javax.swing.Icon;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
@ -23,7 +23,7 @@ import org.xml.sax.SAXException;
import net.sourceforge.filebot.ResourceManager;
public class TVRageClient implements EpisodeListProvider {
public class TVRageClient extends AbstractEpisodeListProvider {
private static final String host = "services.tvrage.com";
@ -41,13 +41,7 @@ public class TVRageClient implements EpisodeListProvider {
@Override
public boolean hasSingleSeasonSupport() {
return true;
}
@Override
public List<SearchResult> search(String query) throws SAXException, IOException, ParserConfigurationException {
public List<SearchResult> search(String query, Locale locale) throws IOException, SAXException {
URL searchUrl = new URL("http", host, "/feeds/full_search.php?show=" + URLEncoder.encode(query, "UTF-8"));
@ -70,7 +64,7 @@ public class TVRageClient implements EpisodeListProvider {
@Override
public List<Episode> getEpisodeList(SearchResult searchResult) throws IOException, SAXException, ParserConfigurationException {
public List<Episode> getEpisodeList(SearchResult searchResult, Locale locale) throws IOException, SAXException {
int showId = ((TVRageSearchResult) searchResult).getShowId();
URL episodeListUrl = new URL("http", host, "/feeds/episode_list.php?sid=" + showId);
@ -110,19 +104,6 @@ public class TVRageClient implements EpisodeListProvider {
}
@Override
public List<Episode> getEpisodeList(SearchResult searchResult, int season) throws IOException, SAXException, ParserConfigurationException {
List<Episode> all = getEpisodeList(searchResult);
List<Episode> eps = filterBySeason(all, season);
if (eps.isEmpty()) {
throw new SeasonOutOfBoundsException(searchResult.getName(), season, getLastSeason(all));
}
return eps;
}
@Override
public URI getEpisodeListLink(SearchResult searchResult) {
return getEpisodeListLink(searchResult, "all");

View File

@ -35,7 +35,7 @@ import net.sf.ehcache.Element;
import net.sourceforge.filebot.ResourceManager;
public class TheTVDBClient implements EpisodeListProvider {
public class TheTVDBClient extends AbstractEpisodeListProvider {
private static final String host = "www.thetvdb.com";
@ -73,11 +73,12 @@ public class TheTVDBClient implements EpisodeListProvider {
@Override
public List<SearchResult> search(String query) throws Exception {
return search(query, Locale.ENGLISH);
public boolean hasLocaleSupport() {
return true;
}
@Override
public List<SearchResult> search(String query, Locale language) throws Exception {
// check if the exact series name is already cached
Integer cachedResult = cache.getSeriesId(query, language);
@ -105,31 +106,14 @@ public class TheTVDBClient implements EpisodeListProvider {
@Override
public List<Episode> getEpisodeList(SearchResult searchResult) throws Exception {
return getEpisodeList((TheTVDBSearchResult) searchResult, Locale.ENGLISH);
}
@Override
public List<Episode> getEpisodeList(SearchResult searchResult, int season) throws Exception {
List<Episode> all = getEpisodeList(searchResult);
List<Episode> eps = filterBySeason(all, season);
if (eps.isEmpty()) {
throw new SeasonOutOfBoundsException(searchResult.getName(), season, getLastSeason(all));
}
return eps;
}
public List<Episode> getEpisodeList(TheTVDBSearchResult searchResult, Locale language) throws Exception {
List<Episode> episodes = cache.getEpisodeList(searchResult.getSeriesId(), language);
public List<Episode> getEpisodeList(SearchResult searchResult, Locale language) throws Exception {
TheTVDBSearchResult series = (TheTVDBSearchResult) searchResult;
List<Episode> episodes = cache.getEpisodeList(series.getSeriesId(), language);
if (episodes != null)
return episodes;
Document seriesRecord = getSeriesRecord(searchResult, language);
Document seriesRecord = getSeriesRecord(series, language);
// we could get the series name from the search result, but the language may not match the given parameter
String seriesName = selectString("Data/Series/SeriesName", seriesRecord);
@ -176,7 +160,7 @@ public class TheTVDBClient implements EpisodeListProvider {
try {
// cache seasonId for each season (always when we are at the first episode)
// because it might be required by getEpisodeListLink
cache.putSeasonId(searchResult.getSeriesId(), seasonNumber, getIntegerContent("seasonid", node));
cache.putSeasonId(series.getSeriesId(), seasonNumber, getIntegerContent("seasonid", node));
} catch (NumberFormatException e) {
// season/episode is not a number, just ignore
}
@ -189,7 +173,7 @@ public class TheTVDBClient implements EpisodeListProvider {
// add specials at the end
episodes.addAll(specials);
cache.putEpisodeList(searchResult.getSeriesId(), language, episodes);
cache.putEpisodeList(series.getSeriesId(), language, episodes);
return episodes;
}

View File

@ -99,7 +99,7 @@ public class AnidbClientTest {
Episode first = list.get(0);
assertEquals("Juuni Kokki", first.getSeriesName());
assertEquals("The Twelve Kingdoms", first.getSeriesName());
assertEquals("Shadow of the Moon, The Sea of Shadow - Chapter 1", first.getTitle());
assertEquals("1", first.getEpisode().toString());
assertEquals("1", first.getAbsolute().toString());
@ -119,7 +119,7 @@ public class AnidbClientTest {
List<Episode> list = anidb.getEpisodeList(monsterSearchResult, Locale.JAPANESE);
Episode last = list.get(73);
assertEquals("Monster", last.getSeriesName());
assertEquals("モンスター", last.getSeriesName());
assertEquals("本当の怪物", last.getTitle());
assertEquals("74", last.getEpisode().toString());
assertEquals("74", last.getAbsolute().toString());

View File

@ -64,7 +64,7 @@ public class OpenSubtitlesXmlRpcTest {
OpenSubtitlesSubtitleDescriptor sample = list.get(75);
assertEquals("\"Wonderfalls\"", sample.getProperty(Property.MovieName));
assertEquals("Wonderfalls", sample.getProperty(Property.MovieName));
assertEquals("Hungarian", sample.getProperty(Property.LanguageName));
assertEquals("imdbid", sample.getProperty(Property.MatchedBy));

View File

@ -75,7 +75,7 @@ public class TheTVDBClientTest {
assertEquals("Unaired Pilot", last.getTitle());
assertEquals("1", last.getSeason().toString());
assertEquals(null, last.getEpisode());
assertEquals("1", last.getAbsolute().toString());
assertEquals(null, last.getAbsolute());
assertEquals("1", last.getSpecial().toString());
assertEquals(null, last.airdate());
}
@ -85,7 +85,7 @@ public class TheTVDBClientTest {
public void getEpisodeListSingleSeason() throws Exception {
List<Episode> list = thetvdb.getEpisodeList(new TheTVDBSearchResult("Wonderfalls", 78845), 1);
assertEquals(13, list.size());
assertEquals(14, list.size());
Episode first = list.get(0);