+ major rewrite of episode metadata / SeriesInfo
This commit is contained in:
parent
b912baccac
commit
4022251746
|
@ -25,7 +25,6 @@ import net.filebot.similarity.MetricAvg;
|
|||
import net.filebot.web.AcoustIDClient;
|
||||
import net.filebot.web.AnidbClient;
|
||||
import net.filebot.web.AnidbSearchResult;
|
||||
import net.filebot.web.AudioTrack;
|
||||
import net.filebot.web.EpisodeListProvider;
|
||||
import net.filebot.web.FanartTVClient;
|
||||
import net.filebot.web.ID3Lookup;
|
||||
|
@ -40,10 +39,9 @@ import net.filebot.web.SubtitleDescriptor;
|
|||
import net.filebot.web.SubtitleProvider;
|
||||
import net.filebot.web.TMDbClient;
|
||||
import net.filebot.web.TVRageClient;
|
||||
import net.filebot.web.TVRageSearchResult;
|
||||
import net.filebot.web.TheTVDBClient;
|
||||
import net.filebot.web.TheTVDBClient.SeriesInfo;
|
||||
import net.filebot.web.TheTVDBSearchResult;
|
||||
import net.filebot.web.TheTVDBSeriesInfo;
|
||||
import net.filebot.web.VideoHashSubtitleService;
|
||||
|
||||
/**
|
||||
|
@ -114,21 +112,6 @@ public final class WebServices {
|
|||
return null; // default
|
||||
}
|
||||
|
||||
public static Object getServiceBySearchResult(Object r) {
|
||||
if (r instanceof TheTVDBSearchResult)
|
||||
return WebServices.TheTVDB;
|
||||
if (r instanceof AnidbSearchResult)
|
||||
return WebServices.AniDB;
|
||||
if (r instanceof TVRageSearchResult)
|
||||
return WebServices.TVRage;
|
||||
if (r instanceof Movie)
|
||||
return WebServices.TheMovieDB;
|
||||
if (r instanceof AudioTrack)
|
||||
return WebServices.AcoustID;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static final ExecutorService requestThreadPool = Executors.newCachedThreadPool();
|
||||
|
||||
public static class TheTVDBClientWithLocalSearch extends TheTVDBClient {
|
||||
|
@ -161,14 +144,6 @@ public final class WebServices {
|
|||
return localIndex;
|
||||
}
|
||||
|
||||
public SeriesInfo getSeriesInfoByLocalIndex(String name, Locale locale) throws Exception {
|
||||
List<SearchResult> results = getLocalIndex().search(name);
|
||||
if (results.size() > 0) {
|
||||
return getSeriesInfo((TheTVDBSearchResult) results.get(0), locale);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SearchResult> fetchSearchResult(final String query, final Locale locale) throws Exception {
|
||||
Callable<List<SearchResult>> apiSearch = () -> TheTVDBClientWithLocalSearch.super.fetchSearchResult(query, locale);
|
||||
|
@ -258,10 +233,11 @@ public final class WebServices {
|
|||
|
||||
public Movie getIMDbID(SearchResult result) throws Exception {
|
||||
if (result instanceof TheTVDBSearchResult) {
|
||||
TheTVDBSearchResult s = (TheTVDBSearchResult) result;
|
||||
SeriesInfo seriesInfo = ((TheTVDBClient) seriesIndex).getSeriesInfo(s, Locale.ENGLISH);
|
||||
TheTVDBSearchResult searchResult = (TheTVDBSearchResult) result;
|
||||
TheTVDBSeriesInfo seriesInfo = (TheTVDBSeriesInfo) ((TheTVDBClient) seriesIndex).getSeriesInfo(searchResult, Locale.ENGLISH);
|
||||
if (seriesInfo.getImdbId() != null) {
|
||||
return new Movie(seriesInfo.getName(), seriesInfo.getFirstAired().getYear(), seriesInfo.getImdbId(), -1);
|
||||
int imdbId = grepImdbId(seriesInfo.getImdbId()).iterator().next();
|
||||
return new Movie(seriesInfo.getName(), seriesInfo.getStartDate().getYear(), imdbId, -1);
|
||||
}
|
||||
}
|
||||
if (result instanceof Movie) {
|
||||
|
|
|
@ -44,16 +44,15 @@ import net.filebot.mediainfo.MediaInfo.StreamKind;
|
|||
import net.filebot.similarity.SimilarityComparator;
|
||||
import net.filebot.util.FileUtilities;
|
||||
import net.filebot.util.FileUtilities.ExtensionFileFilter;
|
||||
import net.filebot.web.AnidbSearchResult;
|
||||
import net.filebot.web.AudioTrack;
|
||||
import net.filebot.web.Episode;
|
||||
import net.filebot.web.EpisodeListProvider;
|
||||
import net.filebot.web.Movie;
|
||||
import net.filebot.web.MoviePart;
|
||||
import net.filebot.web.MultiEpisode;
|
||||
import net.filebot.web.SearchResult;
|
||||
import net.filebot.web.SeriesInfo;
|
||||
import net.filebot.web.SimpleDate;
|
||||
import net.filebot.web.TheTVDBSearchResult;
|
||||
import net.filebot.web.SortOrder;
|
||||
|
||||
import com.cedarsoftware.util.io.JsonWriter;
|
||||
|
||||
|
@ -99,7 +98,7 @@ public class MediaBindingBean {
|
|||
@Define("y")
|
||||
public Integer getYear() {
|
||||
if (infoObject instanceof Episode)
|
||||
return getEpisode().getSeriesStartDate().getYear();
|
||||
return getEpisode().getSeriesInfo().getStartDate().getYear();
|
||||
if (infoObject instanceof Movie)
|
||||
return getMovie().getYear();
|
||||
if (infoObject instanceof AudioTrack)
|
||||
|
@ -191,7 +190,7 @@ public class MediaBindingBean {
|
|||
|
||||
@Define("startdate")
|
||||
public SimpleDate startdate() {
|
||||
return getEpisode().getSeriesStartDate();
|
||||
return getEpisode().getSeriesInfo().getStartDate();
|
||||
}
|
||||
|
||||
@Define("absolute")
|
||||
|
@ -205,8 +204,8 @@ public class MediaBindingBean {
|
|||
}
|
||||
|
||||
@Define("series")
|
||||
public SearchResult getSeriesObject() {
|
||||
return getEpisode().getSeries();
|
||||
public SeriesInfo getSeriesInfo() {
|
||||
return getEpisode().getSeriesInfo();
|
||||
}
|
||||
|
||||
@Define("alias")
|
||||
|
@ -214,11 +213,9 @@ public class MediaBindingBean {
|
|||
if (infoObject instanceof Movie) {
|
||||
return asList(getMovie().getAliasNames());
|
||||
}
|
||||
|
||||
if (infoObject instanceof Episode) {
|
||||
return asList(getSeriesObject().getAliasNames());
|
||||
return getSeriesInfo().getAliasNames();
|
||||
}
|
||||
|
||||
return emptyList();
|
||||
}
|
||||
|
||||
|
@ -229,13 +226,13 @@ public class MediaBindingBean {
|
|||
}
|
||||
|
||||
if (infoObject instanceof Episode) {
|
||||
if (getSeriesObject() instanceof TheTVDBSearchResult) {
|
||||
return WebServices.TheTVDB.getSeriesInfo((TheTVDBSearchResult) getSeriesObject(), Locale.ENGLISH).getName();
|
||||
// force English series name for TheTVDB data
|
||||
if (WebServices.TheTVDB.getName().equals(getSeriesInfo().getDatabase())) {
|
||||
return WebServices.TheTVDB.getSeriesInfo(getSeriesInfo().getId(), Locale.ENGLISH).getName();
|
||||
}
|
||||
if (getSeriesObject() instanceof AnidbSearchResult) {
|
||||
return ((AnidbSearchResult) getSeriesObject()).getPrimaryTitle();
|
||||
}
|
||||
return getSeriesObject().getName(); // default to original search result
|
||||
|
||||
// default to series info name (for anime this would be the primary title)
|
||||
return getSeriesInfo().getName();
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -558,10 +555,7 @@ public class MediaBindingBean {
|
|||
if (metaInfo == null) {
|
||||
try {
|
||||
if (infoObject instanceof Episode) {
|
||||
Episode episode = (Episode) infoObject;
|
||||
if (episode.getSeries() instanceof TheTVDBSearchResult) {
|
||||
metaInfo = WebServices.TheTVDB.getSeriesInfo((TheTVDBSearchResult) episode.getSeries(), episode.getLanguage() == null ? Locale.ENGLISH : episode.getLanguage());
|
||||
}
|
||||
metaInfo = getSeriesInfo();
|
||||
} else if (infoObject instanceof Movie) {
|
||||
if (getMovie().getTmdbId() > 0) {
|
||||
metaInfo = WebServices.TheMovieDB.getMovieInfo(getMovie(), getMovie().getLanguage() == null ? Locale.ENGLISH : getMovie().getLanguage(), true);
|
||||
|
@ -574,20 +568,20 @@ public class MediaBindingBean {
|
|||
}
|
||||
}
|
||||
|
||||
if (mediaInfo == null) {
|
||||
if (metaInfo == null) {
|
||||
throw new UnsupportedOperationException("Extended metadata not available");
|
||||
}
|
||||
|
||||
return createMapBindings(new PropertyBindings(metaInfo, null));
|
||||
}
|
||||
|
||||
@Define("imdb")
|
||||
public synchronized AssociativeScriptObject getImdbApiInfo() {
|
||||
@Define("omdb")
|
||||
public synchronized AssociativeScriptObject getOmdbApiInfo() {
|
||||
Object metaInfo = null;
|
||||
|
||||
try {
|
||||
if (infoObject instanceof Episode) {
|
||||
metaInfo = WebServices.OMDb.getMovieInfo(new Movie(getEpisode().getSeriesName(), getEpisode().getSeriesStartDate().getYear(), -1, -1));
|
||||
metaInfo = WebServices.OMDb.getMovieInfo(new Movie(getEpisode().getSeriesName(), getEpisode().getSeriesInfo().getStartDate().getYear(), -1, -1));
|
||||
}
|
||||
if (infoObject instanceof Movie) {
|
||||
metaInfo = WebServices.OMDb.getMovieInfo(getMovie());
|
||||
|
@ -605,19 +599,10 @@ public class MediaBindingBean {
|
|||
|
||||
@Define("episodelist")
|
||||
public Object getEpisodeList() throws Exception {
|
||||
return ((EpisodeListProvider) getDatabase()).getEpisodeList(getSeriesObject(), getEpisode().getOrder(), getEpisode().getLanguage());
|
||||
}
|
||||
|
||||
@Define("database")
|
||||
public Object getDatabase() {
|
||||
if (infoObject instanceof Episode) {
|
||||
return WebServices.getServiceBySearchResult(getSeriesObject());
|
||||
}
|
||||
if (infoObject instanceof Movie) {
|
||||
return WebServices.getServiceBySearchResult(getMovie());
|
||||
}
|
||||
if (infoObject instanceof AudioTrack) {
|
||||
return WebServices.getServiceBySearchResult(getMusic());
|
||||
for (EpisodeListProvider service : WebServices.getEpisodeListProviders()) {
|
||||
if (getSeriesInfo().getDatabase().equals(service.getName())) {
|
||||
return service.getEpisodeList(getSeriesInfo().getId(), SortOrder.forName(getSeriesInfo().getOrder()), new Locale(getSeriesInfo().getLanguage()));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -65,8 +65,8 @@ import net.filebot.web.Episode;
|
|||
import net.filebot.web.Movie;
|
||||
import net.filebot.web.MovieIdentificationService;
|
||||
import net.filebot.web.SearchResult;
|
||||
import net.filebot.web.SeriesInfo;
|
||||
import net.filebot.web.SimpleDate;
|
||||
import net.filebot.web.TheTVDBClient.SeriesInfo;
|
||||
import net.filebot.web.TheTVDBSearchResult;
|
||||
|
||||
public class MediaDetection {
|
||||
|
@ -1259,7 +1259,9 @@ public class MediaDetection {
|
|||
}
|
||||
|
||||
public static SeriesInfo grepSeries(File nfo, Locale locale) throws Exception {
|
||||
return WebServices.TheTVDB.getSeriesInfoByID(grepTheTvdbId(new String(readFile(nfo), "UTF-8")).iterator().next(), locale);
|
||||
String contents = new String(readFile(nfo), "UTF-8");
|
||||
int thetvdbid = grepTheTvdbId(contents).iterator().next();
|
||||
return WebServices.TheTVDB.getSeriesInfo(thetvdbid, locale);
|
||||
}
|
||||
|
||||
public static List<SearchResult> getProbableMatches(String query, Collection<SearchResult> options) {
|
||||
|
|
|
@ -26,7 +26,6 @@ import java.util.logging.Logger;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import net.filebot.WebServices;
|
||||
import net.filebot.media.MediaDetection;
|
||||
import net.filebot.media.SmartSeasonEpisodeMatcher;
|
||||
import net.filebot.similarity.SeasonEpisodeMatcher.SxE;
|
||||
|
@ -34,9 +33,8 @@ import net.filebot.vfs.FileInfo;
|
|||
import net.filebot.web.Episode;
|
||||
import net.filebot.web.EpisodeFormat;
|
||||
import net.filebot.web.Movie;
|
||||
import net.filebot.web.SeriesInfo;
|
||||
import net.filebot.web.SimpleDate;
|
||||
import net.filebot.web.TheTVDBClient.SeriesInfo;
|
||||
import net.filebot.web.TheTVDBSearchResult;
|
||||
|
||||
import com.ibm.icu.text.Transliterator;
|
||||
|
||||
|
@ -212,7 +210,7 @@ public enum EpisodeMetrics implements SimilarityMetric {
|
|||
LinkedHashSet<String> keywords = new LinkedHashSet<String>(4);
|
||||
keywords.add(removeTrailingBrackets(episode.getSeriesName()));
|
||||
keywords.add(removeTrailingBrackets(episode.getTitle()));
|
||||
for (String it : episode.getSeries().getEffectiveNames()) {
|
||||
for (String it : episode.getSeriesInfo().getAliasNames()) {
|
||||
keywords.add(removeTrailingBrackets(it));
|
||||
}
|
||||
|
||||
|
@ -277,7 +275,7 @@ public enum EpisodeMetrics implements SimilarityMetric {
|
|||
|
||||
protected List<?> getEffectiveIdentifiers(Object object) {
|
||||
if (object instanceof Episode) {
|
||||
return ((Episode) object).getSeries().getEffectiveNames();
|
||||
return ((Episode) object).getSeriesInfo().getAliasNames();
|
||||
} else if (object instanceof Movie) {
|
||||
return ((Movie) object).getEffectiveNames();
|
||||
} else if (object instanceof File) {
|
||||
|
@ -346,7 +344,7 @@ public enum EpisodeMetrics implements SimilarityMetric {
|
|||
List<String> names = null;
|
||||
|
||||
if (object instanceof Episode) {
|
||||
names = ((Episode) object).getSeries().getEffectiveNames();
|
||||
names = ((Episode) object).getSeriesInfo().getAliasNames();
|
||||
} else if (object instanceof File) {
|
||||
File file = (File) object;
|
||||
|
||||
|
@ -558,39 +556,20 @@ public enum EpisodeMetrics implements SimilarityMetric {
|
|||
return max(r1, r2);
|
||||
}
|
||||
|
||||
private final Map<String, SeriesInfo> seriesInfoCache = new HashMap<String, SeriesInfo>();
|
||||
|
||||
public float getRating(Object o) {
|
||||
if (o instanceof Episode) {
|
||||
try {
|
||||
synchronized (seriesInfoCache) {
|
||||
String n = ((Episode) o).getSeriesName();
|
||||
|
||||
SeriesInfo seriesInfo = seriesInfoCache.get(n);
|
||||
if (seriesInfo == null && !seriesInfoCache.containsKey(n)) {
|
||||
try {
|
||||
seriesInfo = WebServices.TheTVDB.getSeriesInfo((TheTVDBSearchResult) ((Episode) o).getSeries(), Locale.ENGLISH);
|
||||
} catch (Exception e) {
|
||||
seriesInfo = WebServices.TheTVDB.getSeriesInfoByLocalIndex(((Episode) o).getSeriesName(), Locale.ENGLISH);
|
||||
}
|
||||
seriesInfoCache.put(n, seriesInfo);
|
||||
}
|
||||
|
||||
if (seriesInfo != null) {
|
||||
if (seriesInfo.getRatingCount() >= 100) {
|
||||
return (float) floor(seriesInfo.getRating() / 3) + 1; // BOOST POPULAR SHOWS
|
||||
}
|
||||
if (seriesInfo.getRatingCount() >= 10) {
|
||||
return (float) floor(seriesInfo.getRating() / 3); // PUT INTO 3 GROUPS
|
||||
}
|
||||
if (seriesInfo.getRatingCount() >= 1) {
|
||||
return 0; // PENALIZE SHOWS WITH FEW RATINGS
|
||||
}
|
||||
return -1; // BIG PENALTY FOR SHOWS WITH 0 RATINGS
|
||||
}
|
||||
public float getRating(Object object) {
|
||||
if (object instanceof Episode) {
|
||||
SeriesInfo seriesInfo = ((Episode) object).getSeriesInfo();
|
||||
if (seriesInfo != null && seriesInfo.getRating() != null && seriesInfo.getRatingCount() != null) {
|
||||
if (seriesInfo.getRatingCount() >= 100) {
|
||||
return (float) floor(seriesInfo.getRating() / 3) + 1; // BOOST POPULAR SHOWS
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger(EpisodeMetrics.class.getName()).log(Level.WARNING, e.getMessage());
|
||||
if (seriesInfo.getRatingCount() >= 10) {
|
||||
return (float) floor(seriesInfo.getRating() / 3); // PUT INTO 3 GROUPS
|
||||
}
|
||||
if (seriesInfo.getRatingCount() >= 1) {
|
||||
return 0; // PENALIZE SHOWS WITH FEW RATINGS
|
||||
}
|
||||
return -1; // BIG PENALTY FOR SHOWS WITH 0 RATINGS
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -20,7 +20,7 @@ import net.filebot.util.FileUtilities;
|
|||
import net.filebot.util.ui.LoadingOverlayPane;
|
||||
import net.filebot.web.Episode;
|
||||
import net.filebot.web.Movie;
|
||||
import net.filebot.web.SearchResult;
|
||||
import net.filebot.web.SeriesInfo;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
class AttributeTool extends Tool<TableModel> {
|
||||
|
@ -59,20 +59,17 @@ class AttributeTool extends Tool<TableModel> {
|
|||
originalName = attributes.getOriginalName();
|
||||
metaObject = attributes.getObject();
|
||||
|
||||
String format = "%s::%d";
|
||||
if (metaObject instanceof Episode) {
|
||||
Object seriesObject = ((Episode) metaObject).getSeries();
|
||||
if (seriesObject != null) {
|
||||
String type = seriesObject.getClass().getSimpleName().replace(SearchResult.class.getSimpleName(), "");
|
||||
Integer code = (Integer) seriesObject.getClass().getMethod("getId").invoke(seriesObject);
|
||||
metaId = String.format(format, type, code);
|
||||
SeriesInfo seriesInfo = ((Episode) metaObject).getSeriesInfo();
|
||||
if (seriesInfo != null) {
|
||||
metaId = String.format("%s::%d", seriesInfo.getDatabase(), seriesInfo.getId());
|
||||
}
|
||||
} else if (metaObject instanceof Movie) {
|
||||
Movie movie = (Movie) metaObject;
|
||||
if (movie.getTmdbId() > 0) {
|
||||
metaId = String.format(format, "TheMovieDB", movie.getTmdbId());
|
||||
metaId = String.format("%s::%d", "TheMovieDB", movie.getTmdbId());
|
||||
} else if (movie.getImdbId() > 0) {
|
||||
metaId = String.format(format, "IMDB", movie.getImdbId());
|
||||
metaId = String.format("%s::%d", "OMDb", movie.getImdbId());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
|
|
@ -124,7 +124,7 @@ public class EpisodeListPanel extends AbstractSearchPanel<EpisodeListProvider, E
|
|||
EpisodeListProvider provider = searchTextField.getSelectButton().getSelectedValue();
|
||||
|
||||
// lock season spinner on "All Seasons" if provider doesn't support fetching of single seasons
|
||||
if (!provider.hasSingleSeasonSupport()) {
|
||||
if (!provider.hasSeasonSupport()) {
|
||||
seasonSpinnerModel.lock(ALL_SEASONS);
|
||||
} else {
|
||||
seasonSpinnerModel.unlock();
|
||||
|
|
|
@ -60,8 +60,8 @@ import net.filebot.util.ui.EmptySelectionModel;
|
|||
import net.filebot.web.Movie;
|
||||
import net.filebot.web.OpenSubtitlesClient;
|
||||
import net.filebot.web.SearchResult;
|
||||
import net.filebot.web.TheTVDBClient.SeriesInfo;
|
||||
import net.filebot.web.TheTVDBSearchResult;
|
||||
import net.filebot.web.TheTVDBSeriesInfo;
|
||||
import net.filebot.web.VideoHashSubtitleService.CheckResult;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
|
@ -689,10 +689,10 @@ public class SubtitleUploadDialog extends JDialog {
|
|||
for (String name : seriesNames) {
|
||||
List<SearchResult> options = WebServices.TheTVDB.search(name, Locale.ENGLISH);
|
||||
for (SearchResult entry : options) {
|
||||
SeriesInfo seriesInfo = WebServices.TheTVDB.getSeriesInfo((TheTVDBSearchResult) entry, Locale.ENGLISH);
|
||||
Integer imdbid = seriesInfo.getImdbId();
|
||||
if (imdbid != null && imdbid > 0) {
|
||||
mapping.setIdentity(WebServices.OpenSubtitles.getMovieDescriptor(new Movie(null, 0, imdbid, -1), Locale.ENGLISH));
|
||||
TheTVDBSeriesInfo seriesInfo = (TheTVDBSeriesInfo) WebServices.TheTVDB.getSeriesInfo((TheTVDBSearchResult) entry, Locale.ENGLISH);
|
||||
if (seriesInfo.getImdbId() != null) {
|
||||
int imdbId = grepImdbId(seriesInfo.getImdbId()).iterator().next();
|
||||
mapping.setIdentity(WebServices.OpenSubtitles.getMovieDescriptor(new Movie(null, 0, imdbId, -1), Locale.ENGLISH));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
|
||||
package net.filebot.util;
|
||||
|
||||
|
||||
import java.util.AbstractList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
import javax.xml.xpath.XPathConstants;
|
||||
import javax.xml.xpath.XPathExpression;
|
||||
|
@ -14,7 +13,6 @@ import javax.xml.xpath.XPathFactory;
|
|||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
|
||||
public final class XPathUtilities {
|
||||
|
||||
public static Node selectNode(String xpath, Object node) {
|
||||
|
@ -25,7 +23,6 @@ public final class XPathUtilities {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public static List<Node> selectNodes(String xpath, Object node) {
|
||||
try {
|
||||
return new NodeListDecorator((NodeList) getXPath(xpath).evaluate(node, XPathConstants.NODESET));
|
||||
|
@ -34,7 +31,6 @@ public final class XPathUtilities {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public static String selectString(String xpath, Object node) {
|
||||
try {
|
||||
return ((String) getXPath(xpath).evaluate(node, XPathConstants.STRING)).trim();
|
||||
|
@ -43,10 +39,26 @@ public final class XPathUtilities {
|
|||
}
|
||||
}
|
||||
|
||||
public static List<String> selectStrings(String xpath, Object node) {
|
||||
List<String> values = new ArrayList<String>();
|
||||
try {
|
||||
for (Node it : selectNodes(xpath, node)) {
|
||||
String textContent = getTextContent(it);
|
||||
if (textContent.length() > 0) {
|
||||
values.add(textContent);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nodeName search for nodes with this name
|
||||
* @param parentNode search in the child nodes of this nodes
|
||||
* @param nodeName
|
||||
* search for nodes with this name
|
||||
* @param parentNode
|
||||
* search in the child nodes of this nodes
|
||||
* @return text content of the child node or null if no child with the given name was found
|
||||
*/
|
||||
public static Node getChild(String nodeName, Node parentNode) {
|
||||
|
@ -58,7 +70,6 @@ public final class XPathUtilities {
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static List<Node> getChildren(String nodeName, Node parentNode) {
|
||||
List<Node> children = new ArrayList<Node>();
|
||||
|
||||
|
@ -70,7 +81,6 @@ public final class XPathUtilities {
|
|||
return children;
|
||||
}
|
||||
|
||||
|
||||
public static String getAttribute(String attribute, Node node) {
|
||||
Node attributeNode = node.getAttributes().getNamedItem(attribute);
|
||||
|
||||
|
@ -80,14 +90,13 @@ public final class XPathUtilities {
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get text content of the first child node matching the given node name. Use this method
|
||||
* instead of {@link #selectString(String, Object)} whenever xpath support is not required,
|
||||
* because it is much faster, especially for large documents.
|
||||
* Get text content of the first child node matching the given node name. Use this method instead of {@link #selectString(String, Object)} whenever xpath support is not required, because it is much faster, especially for large documents.
|
||||
*
|
||||
* @param childName search for nodes with this name
|
||||
* @param parentNode search in the child nodes of this nodes
|
||||
* @param childName
|
||||
* search for nodes with this name
|
||||
* @param parentNode
|
||||
* search in the child nodes of this nodes
|
||||
* @return text content of the child node or null if no child with the given name was found
|
||||
*/
|
||||
public static String getTextContent(String childName, Node parentNode) {
|
||||
|
@ -100,7 +109,6 @@ public final class XPathUtilities {
|
|||
return getTextContent(child);
|
||||
}
|
||||
|
||||
|
||||
public static String getTextContent(Node node) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
|
@ -111,21 +119,46 @@ public final class XPathUtilities {
|
|||
return sb.toString().trim();
|
||||
}
|
||||
|
||||
|
||||
public static Integer getIntegerContent(String childName, Node parentNode) {
|
||||
try {
|
||||
return new Integer(getTextContent(childName, parentNode));
|
||||
} catch (NumberFormatException e) {
|
||||
return new Scanner(getTextContent(childName, parentNode)).useDelimiter("\\D+").nextInt();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Double getDecimalContent(String childName, Node parentNode) {
|
||||
try {
|
||||
return new Double(getTextContent(childName, parentNode));
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> getListContent(String childName, String delimiter, Node parentNode) {
|
||||
List<String> list = new ArrayList<String>();
|
||||
for (Node node : getChildren(childName, parentNode)) {
|
||||
String textContent = getTextContent(node);
|
||||
if (textContent != null && textContent.length() > 0) {
|
||||
if (delimiter == null) {
|
||||
list.add(textContent);
|
||||
} else {
|
||||
for (String it : textContent.split(delimiter)) {
|
||||
it = it.trim();
|
||||
if (it.length() > 0) {
|
||||
list.add(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static XPathExpression getXPath(String xpath) throws XPathExpressionException {
|
||||
return XPathFactory.newInstance().newXPath().compile(xpath);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Dummy constructor to prevent instantiation.
|
||||
*/
|
||||
|
@ -133,23 +166,19 @@ public final class XPathUtilities {
|
|||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
protected static class NodeListDecorator extends AbstractList<Node> {
|
||||
|
||||
private final NodeList nodes;
|
||||
|
||||
|
||||
public NodeListDecorator(NodeList nodes) {
|
||||
this.nodes = nodes;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Node get(int index) {
|
||||
return nodes.item(index);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return nodes.getLength();
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package net.filebot.web;
|
||||
|
||||
import java.util.Arrays;
|
||||
import static java.util.Arrays.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.logging.Level;
|
||||
|
@ -11,69 +13,86 @@ import net.filebot.Cache.Key;
|
|||
|
||||
public abstract class AbstractEpisodeListProvider implements EpisodeListProvider {
|
||||
|
||||
@Override
|
||||
public boolean hasSingleSeasonSupport() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasLocaleSupport() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected abstract List<SearchResult> fetchSearchResult(String query, Locale locale) throws Exception;
|
||||
|
||||
protected abstract List<Episode> fetchEpisodeList(SearchResult searchResult, SortOrder sortOrder, Locale locale) throws Exception;
|
||||
protected abstract SeriesData fetchSeriesData(SearchResult searchResult, SortOrder sortOrder, Locale locale) throws Exception;
|
||||
|
||||
public List<SearchResult> search(String query) throws Exception {
|
||||
return search(query, getDefaultLocale());
|
||||
}
|
||||
protected abstract SearchResult createSearchResult(int id);
|
||||
|
||||
protected abstract ResultCache getCache();
|
||||
|
||||
protected abstract SortOrder vetoRequestParameter(SortOrder order);
|
||||
|
||||
protected abstract Locale vetoRequestParameter(Locale language);
|
||||
|
||||
@Override
|
||||
public List<SearchResult> search(String query, Locale locale) throws Exception {
|
||||
ResultCache cache = getCache();
|
||||
List<SearchResult> results = (cache != null) ? cache.getSearchResult(query, locale) : null;
|
||||
public List<SearchResult> search(String query, Locale language) throws Exception {
|
||||
List<SearchResult> results = getCache().getSearchResult(query, language);
|
||||
if (results != null) {
|
||||
return results;
|
||||
}
|
||||
|
||||
// perform actual search
|
||||
results = fetchSearchResult(query, locale);
|
||||
results = fetchSearchResult(query, language);
|
||||
|
||||
// cache results and return
|
||||
return (cache != null) ? cache.putSearchResult(query, locale, results) : results;
|
||||
}
|
||||
|
||||
// helper for scripting
|
||||
public List<Episode> getEpisodeList(SearchResult searchResult, String sortOrder, String locale) throws Exception {
|
||||
return getEpisodeList(searchResult, sortOrder == null ? SortOrder.Airdate : SortOrder.forName(sortOrder), new Locale(locale));
|
||||
}
|
||||
|
||||
public List<Episode> getEpisodeList(SearchResult searchResult) throws Exception {
|
||||
return getEpisodeList(searchResult, SortOrder.Airdate, getDefaultLocale());
|
||||
return getCache().putSearchResult(query, language, results);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Episode> getEpisodeList(SearchResult searchResult, SortOrder sortOrder, Locale locale) throws Exception {
|
||||
ResultCache cache = getCache();
|
||||
List<Episode> episodes = (cache != null) ? cache.getEpisodeList(searchResult, sortOrder, locale) : null;
|
||||
if (episodes != null) {
|
||||
return episodes;
|
||||
public List<Episode> getEpisodeList(SearchResult searchResult, SortOrder sortOrder, Locale language) throws Exception {
|
||||
return getSeriesData(searchResult, sortOrder, language).getEpisodeList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Episode> getEpisodeList(int id, SortOrder order, Locale language) throws Exception {
|
||||
return getEpisodeList(createSearchResult(id), order, language);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SeriesInfo getSeriesInfo(SearchResult searchResult, Locale language) throws Exception {
|
||||
return getSeriesData(searchResult, null, language).getSeriesInfo();
|
||||
}
|
||||
|
||||
public SeriesInfo getSeriesInfo(int id, Locale language) throws Exception {
|
||||
return getSeriesInfo(createSearchResult(id), language);
|
||||
}
|
||||
|
||||
protected SeriesData getSeriesData(SearchResult searchResult, SortOrder order, Locale language) throws Exception {
|
||||
// override preferences if requested parameters are not supported
|
||||
order = vetoRequestParameter(order);
|
||||
language = vetoRequestParameter(language);
|
||||
|
||||
SeriesData data = getCache().getSeriesData(searchResult, order, language);
|
||||
if (data != null) {
|
||||
return data;
|
||||
}
|
||||
|
||||
// perform actual search
|
||||
episodes = fetchEpisodeList(searchResult, sortOrder, locale);
|
||||
// perform actual lookup
|
||||
data = fetchSeriesData(searchResult, order, language);
|
||||
|
||||
// cache results and return
|
||||
return (cache != null) ? cache.putEpisodeList(searchResult, sortOrder, locale, episodes) : episodes;
|
||||
return getCache().putSeriesData(searchResult, order, language, data);
|
||||
}
|
||||
|
||||
public Locale getDefaultLocale() {
|
||||
return Locale.ENGLISH;
|
||||
}
|
||||
protected static class SeriesData implements Serializable {
|
||||
|
||||
public SeriesInfo seriesInfo;
|
||||
public Episode[] episodeList;
|
||||
|
||||
public SeriesData(SeriesInfo seriesInfo, List<Episode> episodeList) {
|
||||
this.seriesInfo = seriesInfo;
|
||||
this.episodeList = episodeList.toArray(new Episode[episodeList.size()]);
|
||||
}
|
||||
|
||||
public SeriesInfo getSeriesInfo() {
|
||||
return seriesInfo.clone();
|
||||
}
|
||||
|
||||
public List<Episode> getEpisodeList() {
|
||||
return asList(episodeList.clone());
|
||||
}
|
||||
|
||||
public ResultCache getCache() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected static class ResultCache {
|
||||
|
@ -91,69 +110,39 @@ public abstract class AbstractEpisodeListProvider implements EpisodeListProvider
|
|||
}
|
||||
|
||||
public <T extends SearchResult> List<T> putSearchResult(String query, Locale locale, List<T> value) {
|
||||
try {
|
||||
cache.put(new Key(id, normalize(query), locale), value.toArray(new SearchResult[0]));
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger(AbstractEpisodeListProvider.class.getName()).log(Level.WARNING, e.getMessage());
|
||||
}
|
||||
|
||||
putData("SearchResult", normalize(query), locale, value.toArray(new SearchResult[value.size()]));
|
||||
return value;
|
||||
}
|
||||
|
||||
public List<SearchResult> getSearchResult(String query, Locale locale) {
|
||||
try {
|
||||
SearchResult[] results = cache.get(new Key(id, normalize(query), locale), SearchResult[].class);
|
||||
if (results != null) {
|
||||
return Arrays.asList(results);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger(AbstractEpisodeListProvider.class.getName()).log(Level.WARNING, e.getMessage(), e);
|
||||
}
|
||||
|
||||
return null;
|
||||
SearchResult[] data = getData("SearchResult", normalize(query), locale, SearchResult[].class);
|
||||
return data == null ? null : asList(data);
|
||||
}
|
||||
|
||||
public List<Episode> putEpisodeList(SearchResult key, SortOrder sortOrder, Locale locale, List<Episode> episodes) {
|
||||
try {
|
||||
cache.put(new Key(id, key, sortOrder, locale), episodes.toArray(new Episode[0]));
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger(AbstractEpisodeListProvider.class.getName()).log(Level.WARNING, e.getMessage());
|
||||
}
|
||||
|
||||
return episodes;
|
||||
public SeriesData putSeriesData(SearchResult key, SortOrder sortOrder, Locale locale, SeriesData seriesData) {
|
||||
putData("SeriesData." + sortOrder.name(), key, locale, seriesData);
|
||||
return seriesData;
|
||||
}
|
||||
|
||||
public List<Episode> getEpisodeList(SearchResult key, SortOrder sortOrder, Locale locale) {
|
||||
try {
|
||||
Episode[] episodes = cache.get(new Key(id, key, sortOrder, locale), Episode[].class);
|
||||
if (episodes != null) {
|
||||
return Arrays.asList(episodes);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger(AbstractEpisodeListProvider.class.getName()).log(Level.WARNING, e.getMessage(), e);
|
||||
}
|
||||
|
||||
return null;
|
||||
public SeriesData getSeriesData(SearchResult key, SortOrder sortOrder, Locale locale) {
|
||||
return getData("SeriesData." + sortOrder.name(), key, locale, SeriesData.class);
|
||||
}
|
||||
|
||||
public void putData(Object category, Object key, Locale locale, Object object) {
|
||||
public <T> T putData(Object category, Object key, Locale locale, T object) {
|
||||
try {
|
||||
cache.put(new Key(id, category, locale, key), object);
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger(AbstractEpisodeListProvider.class.getName()).log(Level.WARNING, e.getMessage());
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
public <T> T getData(Object category, Object key, Locale locale, Class<T> type) {
|
||||
try {
|
||||
T value = cache.get(new Key(id, category, locale, key), type);
|
||||
if (value != null) {
|
||||
return value;
|
||||
}
|
||||
return cache.get(new Key(id, category, locale, key), type);
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger(AbstractEpisodeListProvider.class.getName()).log(Level.WARNING, e.getMessage(), e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package net.filebot.web;
|
||||
|
||||
import static java.util.Collections.*;
|
||||
import static net.filebot.util.XPathUtilities.*;
|
||||
import static net.filebot.web.EpisodeUtilities.*;
|
||||
import static net.filebot.web.WebRequest.*;
|
||||
|
@ -58,18 +59,23 @@ public class AnidbClient extends AbstractEpisodeListProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSingleSeasonSupport() {
|
||||
public boolean hasSeasonSupport() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasLocaleSupport() {
|
||||
return true;
|
||||
protected SortOrder vetoRequestParameter(SortOrder order) {
|
||||
return SortOrder.Absolute;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Locale vetoRequestParameter(Locale language) {
|
||||
return language != null ? language : Locale.ENGLISH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultCache getCache() {
|
||||
return new ResultCache(host, Cache.getCache("web-datasource-lv2"));
|
||||
return new ResultCache(getName(), Cache.getCache("web-datasource-lv2"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -87,12 +93,11 @@ public class AnidbClient extends AbstractEpisodeListProvider {
|
|||
return set(it.getEffectiveNames());
|
||||
}
|
||||
};
|
||||
|
||||
return new ArrayList<SearchResult>(index.search(query));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Episode> fetchEpisodeList(SearchResult searchResult, SortOrder sortOrder, Locale locale) throws Exception {
|
||||
protected SeriesData fetchSeriesData(SearchResult searchResult, SortOrder sortOrder, Locale locale) throws Exception {
|
||||
AnidbSearchResult anime = (AnidbSearchResult) searchResult;
|
||||
|
||||
// e.g. http://api.anidb.net:9001/httpapi?request=anime&client=filebot&clientver=1&protover=1&aid=4521
|
||||
|
@ -104,22 +109,30 @@ public class AnidbClient extends AbstractEpisodeListProvider {
|
|||
// get anime page as xml
|
||||
Document dom = getDocument(url);
|
||||
|
||||
// parse series info
|
||||
SeriesInfo seriesInfo = new SeriesInfo(getName(), sortOrder, locale, anime.getId());
|
||||
seriesInfo.setAliasNames(searchResult.getEffectiveNames());
|
||||
|
||||
// AniDB types: Movie, Music Video, Other, OVA, TV Series, TV Special, Web, unknown
|
||||
String animeType = selectString("//type", dom);
|
||||
if (animeType != null && animeType.matches("(?i:music.video|unkown|other)")) {
|
||||
return new ArrayList<Episode>();
|
||||
return new SeriesData(seriesInfo, emptyList());
|
||||
}
|
||||
|
||||
// select main title and anime start date
|
||||
SimpleDate seriesStartDate = SimpleDate.parse(selectString("//startdate", dom), "yyyy-MM-dd");
|
||||
String animeTitle = selectString("//titles/title[@type='official' and @lang='" + locale.getLanguage() + "']", dom);
|
||||
if (animeTitle.isEmpty()) {
|
||||
animeTitle = selectString("//titles/title[@type='main']", dom);
|
||||
seriesInfo.setName(selectString("anime/titles/title[@type='main']", dom));
|
||||
seriesInfo.setRating(new Double(selectString("anime/ratings/permanent", dom)));
|
||||
seriesInfo.setRatingCount(new Integer(selectString("anime/ratings/permanent/@count", dom)));
|
||||
seriesInfo.setStartDate(SimpleDate.parse(selectString("anime/startdate", dom), "yyyy-MM-dd"));
|
||||
|
||||
// parse episode data
|
||||
String animeTitle = selectString("anime/titles/title[@type='official' and @lang='" + locale.getLanguage() + "']", dom);
|
||||
if (animeTitle == null || animeTitle.length() == 0) {
|
||||
animeTitle = seriesInfo.getName();
|
||||
}
|
||||
|
||||
List<Episode> episodes = new ArrayList<Episode>(25);
|
||||
|
||||
for (Node node : selectNodes("//episode", dom)) {
|
||||
for (Node node : selectNodes("anime/episodes/episode", dom)) {
|
||||
Node epno = getChild("epno", node);
|
||||
int number = Integer.parseInt(getTextContent(epno).replaceAll("\\D", ""));
|
||||
int type = Integer.parseInt(getAttribute("type", epno));
|
||||
|
@ -132,9 +145,9 @@ public class AnidbClient extends AbstractEpisodeListProvider {
|
|||
}
|
||||
|
||||
if (type == 1) {
|
||||
episodes.add(new Episode(animeTitle, seriesStartDate, null, number, title, number, null, SortOrder.Absolute, locale, airdate, searchResult)); // normal episode, no seasons for anime
|
||||
episodes.add(new Episode(animeTitle, null, number, title, number, null, airdate, new SeriesInfo(seriesInfo))); // normal episode, no seasons for anime
|
||||
} else {
|
||||
episodes.add(new Episode(animeTitle, seriesStartDate, null, null, title, null, number, SortOrder.Absolute, locale, airdate, searchResult)); // special episode
|
||||
episodes.add(new Episode(animeTitle, null, null, title, null, number, airdate, new SeriesInfo(seriesInfo))); // special episode
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -148,7 +161,12 @@ public class AnidbClient extends AbstractEpisodeListProvider {
|
|||
Logger.getLogger(AnidbClient.class.getName()).log(Level.WARNING, String.format("Unable to parse episode data: %s (%d) => %s", anime, anime.getAnimeId(), getXmlString(dom, false)));
|
||||
}
|
||||
|
||||
return episodes;
|
||||
return new SeriesData(seriesInfo, episodes);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SearchResult createSearchResult(int id) {
|
||||
return new AnidbSearchResult(id, null, new String[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -3,13 +3,10 @@ package net.filebot.web;
|
|||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class Episode implements Serializable {
|
||||
|
||||
protected String seriesName;
|
||||
protected SimpleDate seriesStartDate;
|
||||
|
||||
protected Integer season;
|
||||
protected Integer episode;
|
||||
protected String title;
|
||||
|
@ -20,50 +17,39 @@ public class Episode implements Serializable {
|
|||
// special number
|
||||
protected Integer special;
|
||||
|
||||
// optional episode number order hint & episode name / title language hint
|
||||
protected String order;
|
||||
protected String language;
|
||||
|
||||
// episode airdate
|
||||
protected SimpleDate airdate;
|
||||
|
||||
// original series descriptor
|
||||
protected SearchResult series;
|
||||
// extended series metadata
|
||||
protected SeriesInfo seriesInfo;
|
||||
|
||||
protected Episode() {
|
||||
// used by serializer
|
||||
|
||||
}
|
||||
|
||||
public Episode(Episode obj) {
|
||||
this(obj.seriesName, obj.seriesStartDate, obj.season, obj.episode, obj.title, obj.absolute, obj.special, obj.getOrder(), obj.getLanguage(), obj.airdate, obj.series);
|
||||
this(obj.seriesName, obj.season, obj.episode, obj.title, obj.absolute, obj.special, obj.airdate, obj.seriesInfo);
|
||||
}
|
||||
|
||||
public Episode(String seriesName, SimpleDate seriesStartDate, Integer season, Integer episode, String title, SearchResult series) {
|
||||
this(seriesName, seriesStartDate, season, episode, title, null, null, null, null, null, series);
|
||||
public Episode(String seriesName, Integer season, Integer episode, String title) {
|
||||
this(seriesName, season, episode, title, null, null, null, null);
|
||||
}
|
||||
|
||||
public Episode(String seriesName, SimpleDate seriesStartDate, Integer season, Integer episode, String title, Integer absolute, Integer special, SortOrder order, Locale locale, SimpleDate airdate, SearchResult series) {
|
||||
public Episode(String seriesName, Integer season, Integer episode, String title, Integer absolute, Integer special, SimpleDate airdate, SeriesInfo seriesInfo) {
|
||||
this.seriesName = seriesName;
|
||||
this.seriesStartDate = (seriesStartDate == null ? null : seriesStartDate.clone());
|
||||
this.season = season;
|
||||
this.episode = episode;
|
||||
this.title = title;
|
||||
this.absolute = absolute;
|
||||
this.special = special;
|
||||
this.order = (order == null ? null : order.name());
|
||||
this.language = (locale == null ? null : locale.getLanguage());
|
||||
this.airdate = (airdate == null ? null : airdate.clone());
|
||||
this.series = (series == null ? null : series.clone());
|
||||
this.seriesInfo = (seriesInfo == null ? null : seriesInfo.clone());
|
||||
}
|
||||
|
||||
public String getSeriesName() {
|
||||
return seriesName;
|
||||
}
|
||||
|
||||
public SimpleDate getSeriesStartDate() {
|
||||
return seriesStartDate;
|
||||
}
|
||||
|
||||
public Integer getEpisode() {
|
||||
return episode;
|
||||
}
|
||||
|
@ -84,20 +70,12 @@ public class Episode implements Serializable {
|
|||
return special;
|
||||
}
|
||||
|
||||
public SortOrder getOrder() {
|
||||
return order == null ? null : SortOrder.forName(order);
|
||||
}
|
||||
|
||||
public Locale getLanguage() {
|
||||
return language == null ? null : new Locale(language);
|
||||
}
|
||||
|
||||
public SimpleDate getAirdate() {
|
||||
return airdate;
|
||||
}
|
||||
|
||||
public SearchResult getSeries() {
|
||||
return series;
|
||||
public SeriesInfo getSeriesInfo() {
|
||||
return seriesInfo;
|
||||
}
|
||||
|
||||
public List<Integer> getNumbers() {
|
||||
|
|
|
@ -187,7 +187,7 @@ public class EpisodeFormat extends Format {
|
|||
|
||||
// did parse input
|
||||
pos.setIndex(source.length());
|
||||
return new Episode(name, null, season, episode, title, season == null ? episode : null, special, null, null, airdate, null);
|
||||
return new Episode(name, season, episode, title, season == null ? episode : null, special, airdate, null);
|
||||
}
|
||||
|
||||
// failed to parse input
|
||||
|
|
|
@ -1,33 +1,28 @@
|
|||
|
||||
package net.filebot.web;
|
||||
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
|
||||
public interface EpisodeListProvider {
|
||||
|
||||
public String getName();
|
||||
|
||||
|
||||
public Icon getIcon();
|
||||
|
||||
|
||||
public boolean hasSingleSeasonSupport();
|
||||
|
||||
|
||||
public boolean hasLocaleSupport();
|
||||
|
||||
public boolean hasSeasonSupport();
|
||||
|
||||
public List<SearchResult> search(String query, Locale locale) throws Exception;
|
||||
|
||||
|
||||
public List<Episode> getEpisodeList(SearchResult searchResult, SortOrder order, Locale locale) throws Exception;
|
||||
|
||||
public List<Episode> getEpisodeList(int id, SortOrder order, Locale locale) throws Exception;
|
||||
|
||||
public SeriesInfo getSeriesInfo(SearchResult searchResult, Locale locale) throws Exception;
|
||||
|
||||
public SeriesInfo getSeriesInfo(int id, Locale locale) throws Exception;
|
||||
|
||||
public URI getEpisodeListLink(SearchResult searchResult);
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ public class OpenSubtitlesClient implements SubtitleProvider, VideoHashSubtitleS
|
|||
}
|
||||
|
||||
public ResultCache getCache() {
|
||||
return new ResultCache("opensubtitles.org", Cache.getCache("web-datasource"));
|
||||
return new ResultCache(getName(), Cache.getCache("web-datasource"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
package net.filebot.web;
|
||||
|
||||
import static java.util.Collections.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.AbstractList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class SearchResult implements Serializable {
|
||||
|
@ -28,10 +29,12 @@ public abstract class SearchResult implements Serializable {
|
|||
}
|
||||
|
||||
public List<String> getEffectiveNames() {
|
||||
if (aliasNames == null || aliasNames.length == 0) {
|
||||
return Collections.singletonList(name);
|
||||
if (name == null || name.length() == 0) {
|
||||
return emptyList();
|
||||
}
|
||||
if (aliasNames == null || aliasNames.length == 0) {
|
||||
return singletonList(name);
|
||||
}
|
||||
|
||||
return new AbstractList<String>() {
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,203 @@
|
|||
package net.filebot.web;
|
||||
|
||||
import static java.util.Arrays.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class SeriesInfo implements Serializable {
|
||||
|
||||
// request parameters
|
||||
protected String database;
|
||||
protected String order;
|
||||
protected String language;
|
||||
|
||||
// series parameters
|
||||
protected Integer id;
|
||||
protected String name;
|
||||
protected String[] aliasNames;
|
||||
protected String[] actors;
|
||||
protected String certification;
|
||||
protected SimpleDate startDate;
|
||||
protected String[] genres;
|
||||
protected String network;
|
||||
protected Double rating;
|
||||
protected Integer ratingCount;
|
||||
protected Integer runtime;
|
||||
protected String status;
|
||||
|
||||
protected SeriesInfo() {
|
||||
|
||||
}
|
||||
|
||||
public SeriesInfo(SeriesInfo other) {
|
||||
this.database = other.database;
|
||||
this.order = other.order;
|
||||
this.language = other.language;
|
||||
this.id = other.id;
|
||||
this.name = other.name;
|
||||
this.aliasNames = other.aliasNames == null ? null : other.aliasNames.clone();
|
||||
this.actors = other.actors == null ? null : other.actors.clone();
|
||||
this.certification = other.certification;
|
||||
this.startDate = other.startDate == null ? null : other.startDate.clone();
|
||||
this.genres = other.genres == null ? null : other.genres.clone();
|
||||
this.network = other.network;
|
||||
this.rating = other.rating;
|
||||
this.ratingCount = other.ratingCount;
|
||||
this.runtime = other.runtime;
|
||||
this.status = other.status;
|
||||
}
|
||||
|
||||
public SeriesInfo(String database, SortOrder order, Locale language, Integer id) {
|
||||
this.database = database;
|
||||
this.order = order.name();
|
||||
this.language = language.getLanguage();
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setDatabase(String database) {
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
public String getDatabase() {
|
||||
return database;
|
||||
}
|
||||
|
||||
public void setOrder(String order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
public String getOrder() {
|
||||
return order;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getLanguage() {
|
||||
return language;
|
||||
}
|
||||
|
||||
public void setLanguage(String language) {
|
||||
this.language = language;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public List<String> getAliasNames() {
|
||||
return aliasNames == null ? asList() : asList(aliasNames.clone());
|
||||
}
|
||||
|
||||
public void setAliasNames(List<String> aliasNames) {
|
||||
this.aliasNames = aliasNames.toArray(new String[aliasNames.size()]);
|
||||
}
|
||||
|
||||
public List<String> getActors() {
|
||||
return actors == null ? asList() : asList(actors.clone());
|
||||
}
|
||||
|
||||
public void setActors(List<String> actors) {
|
||||
this.actors = actors.toArray(new String[actors.size()]);
|
||||
}
|
||||
|
||||
public String getCertification() {
|
||||
return certification;
|
||||
}
|
||||
|
||||
public void setCertification(String certification) {
|
||||
this.certification = certification;
|
||||
}
|
||||
|
||||
public SimpleDate getStartDate() {
|
||||
return startDate;
|
||||
}
|
||||
|
||||
public void setStartDate(SimpleDate startDate) {
|
||||
this.startDate = startDate;
|
||||
}
|
||||
|
||||
public List<String> getGenres() {
|
||||
return genres == null ? asList() : asList(genres.clone());
|
||||
}
|
||||
|
||||
public void setGenres(List<String> genres) {
|
||||
this.genres = genres.toArray(new String[genres.size()]);
|
||||
}
|
||||
|
||||
public String getNetwork() {
|
||||
return network;
|
||||
}
|
||||
|
||||
public void setNetwork(String network) {
|
||||
this.network = network;
|
||||
}
|
||||
|
||||
public Double getRating() {
|
||||
return rating;
|
||||
}
|
||||
|
||||
public void setRating(Double rating) {
|
||||
this.rating = rating;
|
||||
}
|
||||
|
||||
public Integer getRatingCount() {
|
||||
return ratingCount;
|
||||
}
|
||||
|
||||
public void setRatingCount(Integer ratingCount) {
|
||||
this.ratingCount = ratingCount;
|
||||
}
|
||||
|
||||
public Integer getRuntime() {
|
||||
return runtime;
|
||||
}
|
||||
|
||||
public void setRuntime(Integer runtime) {
|
||||
this.runtime = runtime;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (object instanceof SeriesInfo) {
|
||||
SeriesInfo other = (SeriesInfo) object;
|
||||
return id.equals(other.id) && database.equals(other.database);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SeriesInfo clone() {
|
||||
return new SeriesInfo(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return database + "::" + id;
|
||||
}
|
||||
|
||||
}
|
|
@ -43,9 +43,24 @@ public class TVRageClient extends AbstractEpisodeListProvider {
|
|||
return ResourceManager.getIcon("search.tvrage");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSeasonSupport() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SortOrder vetoRequestParameter(SortOrder order) {
|
||||
return SortOrder.Airdate;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Locale vetoRequestParameter(Locale language) {
|
||||
return Locale.ENGLISH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultCache getCache() {
|
||||
return new ResultCache(host, Cache.getCache("web-datasource"));
|
||||
return new ResultCache(getName(), Cache.getCache("web-datasource"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -67,14 +82,24 @@ public class TVRageClient extends AbstractEpisodeListProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<Episode> fetchEpisodeList(SearchResult searchResult, SortOrder sortOrder, Locale locale) throws IOException, SAXException {
|
||||
protected SeriesData fetchSeriesData(SearchResult searchResult, SortOrder sortOrder, Locale locale) throws Exception {
|
||||
TVRageSearchResult series = (TVRageSearchResult) searchResult;
|
||||
Document dom = request("/feeds/full_show_info.php", singletonMap("sid", series.getSeriesId()));
|
||||
Document dom = request("/feeds/full_show_info.php", singletonMap("sid", series.getId()));
|
||||
|
||||
String seriesName = selectString("Show/name", dom);
|
||||
SimpleDate seriesStartDate = SimpleDate.parse(selectString("Show/started", dom), "MMM/dd/yyyy");
|
||||
Locale language = Locale.ENGLISH;
|
||||
// parse series data
|
||||
Node seriesNode = selectNode("Show", dom);
|
||||
SeriesInfo seriesInfo = new SeriesInfo(getName(), sortOrder, locale, series.getId());
|
||||
seriesInfo.setAliasNames(searchResult.getEffectiveNames());
|
||||
|
||||
seriesInfo.setName(getTextContent("name", seriesNode));
|
||||
seriesInfo.setNetwork(getTextContent("network", seriesNode));
|
||||
seriesInfo.setRuntime(getIntegerContent("runtime", seriesNode));
|
||||
seriesInfo.setStatus(getTextContent("status", seriesNode));
|
||||
|
||||
seriesInfo.setGenres(getListContent("genre", null, getChild("genres", seriesNode)));
|
||||
seriesInfo.setStartDate(SimpleDate.parse(selectString("started", seriesNode), "MMM/dd/yyyy"));
|
||||
|
||||
// parse episode data
|
||||
List<Episode> episodes = new ArrayList<Episode>(25);
|
||||
List<Episode> specials = new ArrayList<Episode>(5);
|
||||
|
||||
|
@ -86,30 +111,26 @@ public class TVRageClient extends AbstractEpisodeListProvider {
|
|||
Integer seasonNumber = seasonIdentifier == null ? null : new Integer(seasonIdentifier);
|
||||
SimpleDate airdate = SimpleDate.parse(getTextContent("airdate", node), "yyyy-MM-dd");
|
||||
|
||||
SortOrder order = SortOrder.Airdate; // default order
|
||||
|
||||
// check if we have season and episode number, if not it must be a special episode
|
||||
if (episodeNumber == null || seasonNumber == null) {
|
||||
// handle as special episode
|
||||
seasonNumber = getIntegerContent("season", node);
|
||||
int specialNumber = filterBySeason(specials, seasonNumber).size() + 1;
|
||||
specials.add(new Episode(seriesName, seriesStartDate, seasonNumber, null, title, null, specialNumber, order, language, airdate, searchResult));
|
||||
specials.add(new Episode(seriesInfo.getName(), seasonNumber, null, title, null, specialNumber, airdate, new SeriesInfo(seriesInfo)));
|
||||
} else {
|
||||
// handle as normal episode
|
||||
if (sortOrder == SortOrder.Absolute) {
|
||||
episodeNumber = getIntegerContent("epnum", node);
|
||||
seasonNumber = null;
|
||||
order = SortOrder.Absolute;
|
||||
}
|
||||
|
||||
episodes.add(new Episode(seriesName, seriesStartDate, seasonNumber, episodeNumber, title, null, null, order, language, airdate, searchResult));
|
||||
episodes.add(new Episode(seriesInfo.getName(), seasonNumber, episodeNumber, title, null, null, airdate, new SeriesInfo(seriesInfo)));
|
||||
}
|
||||
}
|
||||
|
||||
// add specials at the end
|
||||
episodes.addAll(specials);
|
||||
|
||||
return episodes;
|
||||
return new SeriesData(seriesInfo, episodes);
|
||||
}
|
||||
|
||||
public Document request(String resource, Map<String, Object> parameters) throws IOException, SAXException {
|
||||
|
@ -121,6 +142,11 @@ public class TVRageClient extends AbstractEpisodeListProvider {
|
|||
return getDocument(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SearchResult createSearchResult(int id) {
|
||||
return new TVRageSearchResult(null, id, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getEpisodeListLink(SearchResult searchResult) {
|
||||
return URI.create(((TVRageSearchResult) searchResult).getLink() + "/episode_list/all");
|
||||
|
|
|
@ -29,7 +29,6 @@ import net.filebot.Cache;
|
|||
import net.filebot.ResourceManager;
|
||||
import net.filebot.util.FileUtilities;
|
||||
import net.filebot.web.TheTVDBClient.BannerDescriptor.BannerProperty;
|
||||
import net.filebot.web.TheTVDBClient.SeriesInfo.SeriesProperty;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
|
@ -60,13 +59,23 @@ public class TheTVDBClient extends AbstractEpisodeListProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSingleSeasonSupport() {
|
||||
public boolean hasSeasonSupport() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasLocaleSupport() {
|
||||
return true;
|
||||
protected SortOrder vetoRequestParameter(SortOrder order) {
|
||||
return order != null ? order : SortOrder.Airdate;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Locale vetoRequestParameter(Locale language) {
|
||||
return language != null ? language : Locale.ENGLISH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultCache getCache() {
|
||||
return new ResultCache(getName(), Cache.getCache("web-datasource"));
|
||||
}
|
||||
|
||||
public String getLanguageCode(Locale locale) {
|
||||
|
@ -85,11 +94,6 @@ public class TheTVDBClient extends AbstractEpisodeListProvider {
|
|||
return code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultCache getCache() {
|
||||
return new ResultCache(host, Cache.getCache("web-datasource"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SearchResult> fetchSearchResult(String query, Locale locale) throws Exception {
|
||||
// perform online search
|
||||
|
@ -120,14 +124,36 @@ public class TheTVDBClient extends AbstractEpisodeListProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<Episode> fetchEpisodeList(SearchResult searchResult, SortOrder sortOrder, Locale locale) throws Exception {
|
||||
protected SeriesData fetchSeriesData(SearchResult searchResult, SortOrder sortOrder, Locale locale) throws Exception {
|
||||
TheTVDBSearchResult series = (TheTVDBSearchResult) searchResult;
|
||||
Document dom = getXmlResource(MirrorType.XML, "/api/" + apikey + "/series/" + series.getSeriesId() + "/all/" + getLanguageCode(locale) + ".xml");
|
||||
|
||||
// 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", dom);
|
||||
SimpleDate seriesStartDate = SimpleDate.parse(selectString("Data/Series/FirstAired", dom), "yyyy-MM-dd");
|
||||
// parse series info
|
||||
Node seriesNode = selectNode("Data/Series", dom);
|
||||
TheTVDBSeriesInfo seriesInfo = new TheTVDBSeriesInfo(getName(), sortOrder, locale, series.getId());
|
||||
seriesInfo.setAliasNames(searchResult.getEffectiveNames());
|
||||
|
||||
seriesInfo.setName(getTextContent("SeriesName", seriesNode));
|
||||
seriesInfo.setAirsDayOfWeek(getTextContent("Airs_DayOfWeek", seriesNode));
|
||||
seriesInfo.setAirTime(getTextContent("Airs_Time", seriesNode));
|
||||
seriesInfo.setCertification(getTextContent("ContentRating", seriesNode));
|
||||
seriesInfo.setImdbId(getTextContent("IMDB_ID", seriesNode));
|
||||
seriesInfo.setNetwork(getTextContent("Network", seriesNode));
|
||||
seriesInfo.setOverview(getTextContent("Overview", seriesNode));
|
||||
seriesInfo.setStatus(getTextContent("Status", seriesNode));
|
||||
|
||||
seriesInfo.setRating(getDecimalContent("Rating", seriesNode));
|
||||
seriesInfo.setRatingCount(getIntegerContent("RatingCount", seriesNode));
|
||||
seriesInfo.setRuntime(getIntegerContent("Runtime", seriesNode));
|
||||
seriesInfo.setActors(getListContent("Actors", "\\|", seriesNode));
|
||||
seriesInfo.setGenres(getListContent("Genre", "\\|", seriesNode));
|
||||
seriesInfo.setStartDate(SimpleDate.parse(getTextContent("FirstAired", seriesNode), "yyyy-MM-dd"));
|
||||
|
||||
seriesInfo.setBannerUrl(getResourceURL(MirrorType.BANNER, "/banners/" + getTextContent("banner", seriesNode)));
|
||||
seriesInfo.setFanartUrl(getResourceURL(MirrorType.BANNER, "/banners/" + getTextContent("fanart", seriesNode)));
|
||||
seriesInfo.setPosterUrl(getResourceURL(MirrorType.BANNER, "/banners/" + getTextContent("poster", seriesNode)));
|
||||
|
||||
// parse episode data
|
||||
List<Node> nodes = selectNodes("Data/Episode", dom);
|
||||
|
||||
List<Episode> episodes = new ArrayList<Episode>(nodes.size());
|
||||
|
@ -143,7 +169,6 @@ public class TheTVDBClient extends AbstractEpisodeListProvider {
|
|||
// default numbering
|
||||
Integer episodeNumber = getIntegerContent("EpisodeNumber", node);
|
||||
Integer seasonNumber = getIntegerContent("SeasonNumber", node);
|
||||
SortOrder order = SortOrder.Airdate;
|
||||
|
||||
if (seasonNumber == null || seasonNumber == 0) {
|
||||
// handle as special episode
|
||||
|
@ -154,14 +179,13 @@ public class TheTVDBClient extends AbstractEpisodeListProvider {
|
|||
|
||||
// use given episode number as special number or count specials by ourselves
|
||||
Integer specialNumber = (episodeNumber != null) ? episodeNumber : filterBySeason(specials, seasonNumber).size() + 1;
|
||||
specials.add(new Episode(seriesName, seriesStartDate, seasonNumber, null, episodeName, null, specialNumber, order, locale, airdate, searchResult));
|
||||
specials.add(new Episode(seriesInfo.getName(), seasonNumber, null, episodeName, null, specialNumber, airdate, new SeriesInfo(seriesInfo)));
|
||||
} else {
|
||||
// handle as normal episode
|
||||
if (sortOrder == SortOrder.Absolute) {
|
||||
if (absoluteNumber != null) {
|
||||
episodeNumber = absoluteNumber;
|
||||
seasonNumber = null;
|
||||
order = SortOrder.Absolute;
|
||||
}
|
||||
} else if (sortOrder == SortOrder.DVD) {
|
||||
try {
|
||||
|
@ -171,13 +195,12 @@ public class TheTVDBClient extends AbstractEpisodeListProvider {
|
|||
// require both values to be successfully read
|
||||
episodeNumber = eno;
|
||||
seasonNumber = sno;
|
||||
order = SortOrder.DVD;
|
||||
} catch (Exception e) {
|
||||
// ignore, fallback to default numbering
|
||||
}
|
||||
}
|
||||
|
||||
episodes.add(new Episode(seriesName, seriesStartDate, seasonNumber, episodeNumber, episodeName, absoluteNumber, null, order, locale, airdate, searchResult));
|
||||
episodes.add(new Episode(seriesInfo.getName(), seasonNumber, episodeNumber, episodeName, absoluteNumber, null, airdate, new SeriesInfo(seriesInfo)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,7 +210,7 @@ public class TheTVDBClient extends AbstractEpisodeListProvider {
|
|||
// add specials at the end
|
||||
episodes.addAll(specials);
|
||||
|
||||
return episodes;
|
||||
return new SeriesData(seriesInfo, episodes);
|
||||
}
|
||||
|
||||
public TheTVDBSearchResult lookupByID(int id, Locale locale) throws Exception {
|
||||
|
@ -227,11 +250,6 @@ public class TheTVDBClient extends AbstractEpisodeListProvider {
|
|||
return series;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getEpisodeListLink(SearchResult searchResult) {
|
||||
return URI.create("http://" + host + "/?tab=seasonall&id=" + ((TheTVDBSearchResult) searchResult).getSeriesId());
|
||||
}
|
||||
|
||||
protected String getMirror(MirrorType mirrorType) throws IOException {
|
||||
synchronized (mirrors) {
|
||||
if (mirrors.isEmpty()) {
|
||||
|
@ -340,229 +358,18 @@ public class TheTVDBClient extends AbstractEpisodeListProvider {
|
|||
|
||||
}
|
||||
|
||||
public SeriesInfo getSeriesInfoByID(int thetvdbid, Locale locale) throws Exception {
|
||||
return getSeriesInfo(new TheTVDBSearchResult(null, thetvdbid), locale);
|
||||
}
|
||||
|
||||
public SeriesInfo getSeriesInfoByIMDbID(int imdbid, Locale locale) throws Exception {
|
||||
return getSeriesInfo(lookupByIMDbID(imdbid, locale), locale);
|
||||
}
|
||||
|
||||
public SeriesInfo getSeriesInfoByName(String name, Locale locale) throws Exception {
|
||||
for (SearchResult it : search(name, locale)) {
|
||||
if (name.equalsIgnoreCase(it.getName())) {
|
||||
return getSeriesInfo((TheTVDBSearchResult) it, locale);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
@Override
|
||||
protected SearchResult createSearchResult(int id) {
|
||||
return new TheTVDBSearchResult(null, id);
|
||||
}
|
||||
|
||||
public SeriesInfo getSeriesInfo(TheTVDBSearchResult searchResult, Locale locale) throws Exception {
|
||||
// check cache first
|
||||
SeriesInfo cachedItem = getCache().getData("seriesInfo", searchResult.seriesId, locale, SeriesInfo.class);
|
||||
if (cachedItem != null) {
|
||||
return cachedItem;
|
||||
}
|
||||
|
||||
Document dom = getXmlResource(MirrorType.XML, "/api/" + apikey + "/series/" + searchResult.seriesId + "/" + getLanguageCode(locale) + ".xml");
|
||||
|
||||
Node node = selectNode("//Series", dom);
|
||||
Map<SeriesProperty, String> fields = new EnumMap<SeriesProperty, String>(SeriesProperty.class);
|
||||
|
||||
// remember banner mirror
|
||||
fields.put(SeriesProperty.BannerMirror, getResourceURL(MirrorType.BANNER, "/banners/").toString());
|
||||
|
||||
// copy values from xml
|
||||
for (SeriesProperty key : SeriesProperty.values()) {
|
||||
String value = getTextContent(key.name(), node);
|
||||
if (value != null && value.length() > 0) {
|
||||
fields.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
SeriesInfo seriesInfo = new SeriesInfo(fields);
|
||||
getCache().putData("seriesInfo", searchResult.seriesId, locale, seriesInfo);
|
||||
return seriesInfo;
|
||||
}
|
||||
|
||||
public static class SeriesInfo implements Serializable {
|
||||
|
||||
public static enum SeriesProperty {
|
||||
id, Actors, Airs_DayOfWeek, Airs_Time, ContentRating, FirstAired, Genre, IMDB_ID, Language, Network, Overview, Rating, RatingCount, Runtime, SeriesName, Status, BannerMirror, banner, fanart, poster
|
||||
}
|
||||
|
||||
protected Map<SeriesProperty, String> fields;
|
||||
|
||||
protected SeriesInfo() {
|
||||
// used by serializer
|
||||
}
|
||||
|
||||
protected SeriesInfo(Map<SeriesProperty, String> fields) {
|
||||
this.fields = new EnumMap<SeriesProperty, String>(fields);
|
||||
}
|
||||
|
||||
public String get(Object key) {
|
||||
return fields.get(SeriesProperty.valueOf(key.toString()));
|
||||
}
|
||||
|
||||
public String get(SeriesProperty key) {
|
||||
return fields.get(key);
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
// e.g. 80348
|
||||
try {
|
||||
return Integer.parseInt(get(SeriesProperty.id));
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getActors() {
|
||||
// e.g. |Zachary Levi|Adam Baldwin|Yvonne Strzechowski|
|
||||
return split(get(SeriesProperty.Actors));
|
||||
}
|
||||
|
||||
public List<String> getGenres() {
|
||||
// e.g. |Comedy|
|
||||
return split(get(SeriesProperty.Genre));
|
||||
}
|
||||
|
||||
protected List<String> split(String values) {
|
||||
List<String> items = new ArrayList<String>();
|
||||
if (values != null && values.length() > 0) {
|
||||
for (String it : values.split("[|]")) {
|
||||
it = it.trim();
|
||||
if (it.length() > 0) {
|
||||
items.add(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
public String getAirDayOfWeek() {
|
||||
// e.g. Monday
|
||||
return get(SeriesProperty.Airs_DayOfWeek);
|
||||
}
|
||||
|
||||
public String getAirTime() {
|
||||
// e.g. 8:00 PM
|
||||
return get(SeriesProperty.Airs_Time);
|
||||
}
|
||||
|
||||
public SimpleDate getFirstAired() {
|
||||
// e.g. 2007-09-24
|
||||
return SimpleDate.parse(get(SeriesProperty.FirstAired), "yyyy-MM-dd");
|
||||
}
|
||||
|
||||
public String getContentRating() {
|
||||
// e.g. TV-PG
|
||||
return get(SeriesProperty.ContentRating);
|
||||
}
|
||||
|
||||
public String getCertification() {
|
||||
return getContentRating(); // another getter for compability reasons
|
||||
}
|
||||
|
||||
public Integer getImdbId() {
|
||||
// e.g. tt0934814
|
||||
try {
|
||||
return Integer.parseInt(get(SeriesProperty.IMDB_ID).substring(2));
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Locale getLanguage() {
|
||||
// e.g. en
|
||||
try {
|
||||
return new Locale(get(SeriesProperty.Language));
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getOverview() {
|
||||
// e.g. Zachary Levi (Less Than Perfect) plays Chuck...
|
||||
return get(SeriesProperty.Overview);
|
||||
}
|
||||
|
||||
public Double getRating() {
|
||||
// e.g. 9.0
|
||||
try {
|
||||
return Double.parseDouble(get(SeriesProperty.Rating));
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Integer getRatingCount() {
|
||||
// e.g. 696
|
||||
try {
|
||||
return Integer.parseInt(get(SeriesProperty.RatingCount));
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getRuntime() {
|
||||
// e.g. 30
|
||||
return get(SeriesProperty.Runtime);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
// e.g. Chuck
|
||||
return get(SeriesProperty.SeriesName);
|
||||
}
|
||||
|
||||
public String getNetwork() {
|
||||
// e.g. CBS
|
||||
return get(SeriesProperty.Network);
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
// e.g. Continuing
|
||||
return get(SeriesProperty.Status);
|
||||
}
|
||||
|
||||
public URL getBannerMirrorUrl() {
|
||||
try {
|
||||
return new URL(get(BannerProperty.BannerMirror));
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public URL getBannerUrl() throws MalformedURLException {
|
||||
try {
|
||||
return new URL(getBannerMirrorUrl(), get(SeriesProperty.banner));
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public URL getFanartUrl() {
|
||||
try {
|
||||
return new URL(getBannerMirrorUrl(), get(SeriesProperty.fanart));
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public URL getPosterUrl() {
|
||||
try {
|
||||
return new URL(getBannerMirrorUrl(), get(SeriesProperty.poster));
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return fields.toString();
|
||||
}
|
||||
@Override
|
||||
public URI getEpisodeListLink(SearchResult searchResult) {
|
||||
return URI.create("http://" + host + "/?tab=seasonall&id=" + ((TheTVDBSearchResult) searchResult).getSeriesId());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
package net.filebot.web;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.net.URL;
|
||||
import java.util.Locale;
|
||||
|
||||
public class TheTVDBSeriesInfo extends SeriesInfo implements Serializable {
|
||||
|
||||
protected String imdbId;
|
||||
protected String overview;
|
||||
|
||||
protected String airsDayOfWeek;
|
||||
protected String airTime;
|
||||
|
||||
protected String bannerUrl;
|
||||
protected String fanartUrl;
|
||||
protected String posterUrl;
|
||||
|
||||
protected TheTVDBSeriesInfo() {
|
||||
super();
|
||||
}
|
||||
|
||||
public TheTVDBSeriesInfo(TheTVDBSeriesInfo other) {
|
||||
super(other);
|
||||
this.imdbId = other.imdbId;
|
||||
this.overview = other.overview;
|
||||
this.airsDayOfWeek = other.airsDayOfWeek;
|
||||
this.airTime = other.airTime;
|
||||
this.bannerUrl = other.bannerUrl;
|
||||
this.fanartUrl = other.fanartUrl;
|
||||
this.posterUrl = other.posterUrl;
|
||||
}
|
||||
|
||||
public TheTVDBSeriesInfo(String database, SortOrder order, Locale language, Integer id) {
|
||||
super(database, order, language, id);
|
||||
}
|
||||
|
||||
public SimpleDate getFirstAired() {
|
||||
return getStartDate();
|
||||
}
|
||||
|
||||
public String getContentRating() {
|
||||
return getCertification();
|
||||
}
|
||||
|
||||
public String getImdbId() {
|
||||
return imdbId;
|
||||
}
|
||||
|
||||
public void setImdbId(String imdbId) {
|
||||
this.imdbId = imdbId;
|
||||
}
|
||||
|
||||
public String getOverview() {
|
||||
return overview;
|
||||
}
|
||||
|
||||
public void setOverview(String overview) {
|
||||
this.overview = overview;
|
||||
}
|
||||
|
||||
public String getAirsDayOfWeek() {
|
||||
return airsDayOfWeek;
|
||||
}
|
||||
|
||||
public void setAirsDayOfWeek(String airsDayOfWeek) {
|
||||
this.airsDayOfWeek = airsDayOfWeek;
|
||||
}
|
||||
|
||||
public String getAirTime() {
|
||||
return airTime;
|
||||
}
|
||||
|
||||
public void setAirTime(String airTime) {
|
||||
this.airTime = airTime;
|
||||
}
|
||||
|
||||
public String getBannerUrl() {
|
||||
return bannerUrl;
|
||||
}
|
||||
|
||||
public void setBannerUrl(URL bannerUrl) {
|
||||
this.bannerUrl = bannerUrl.toString();
|
||||
}
|
||||
|
||||
public URL getFanartUrl() {
|
||||
try {
|
||||
return new URL(fanartUrl);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setFanartUrl(URL fanartUrl) {
|
||||
this.fanartUrl = fanartUrl.toString();
|
||||
}
|
||||
|
||||
public URL getPosterUrl() {
|
||||
try {
|
||||
return new URL(posterUrl);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setPosterUrl(URL posterUrl) {
|
||||
this.posterUrl = posterUrl.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TheTVDBSeriesInfo clone() {
|
||||
return new TheTVDBSeriesInfo(this);
|
||||
}
|
||||
|
||||
}
|
|
@ -8,8 +8,6 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import net.filebot.web.Episode;
|
||||
import net.filebot.web.SimpleDate;
|
||||
import net.filebot.web.TheTVDBSearchResult;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -17,7 +15,7 @@ public class EpisodeMetricsTest {
|
|||
|
||||
@Test
|
||||
public void substringMetrics() {
|
||||
Episode eY1T1 = new Episode("Doctor Who", new SimpleDate(2005, 0, 0), 1, 1, "Rose", new TheTVDBSearchResult("Doctor Who", -1));
|
||||
Episode eY1T1 = new Episode("Doctor Who", 1, 1, "Rose");
|
||||
// Episode eY2T2 = new Episode("Doctor Who", new Date(1963, 0, 0), 1, 1, "An Unearthly Child");
|
||||
File fY1T1 = new File("Doctor Who (2005)/Doctor Who - 1x01 - Rose");
|
||||
File fY2T2 = new File("Doctor Who (1963)/Doctor Who - 1x01 - An Unearthly Child");
|
||||
|
@ -48,8 +46,8 @@ public class EpisodeMetricsTest {
|
|||
|
||||
files.add(new File("Greek/Greek - S01E19 - No Campus for Old Rules"));
|
||||
files.add(new File("Veronica Mars - Season 1/Veronica Mars [1x19] Hot Dogs"));
|
||||
episodes.add(new Episode("Veronica Mars", null, 1, 19, "Hot Dogs", new TheTVDBSearchResult("Veronica Mars", -1)));
|
||||
episodes.add(new Episode("Greek", null, 1, 19, "No Campus for Old Rules", new TheTVDBSearchResult("Greek", -1)));
|
||||
episodes.add(new Episode("Veronica Mars", 1, 19, "Hot Dogs"));
|
||||
episodes.add(new Episode("Greek", 1, 19, "No Campus for Old Rules"));
|
||||
|
||||
SimilarityMetric[] metrics = new SimilarityMetric[] { EpisodeIdentifier, SubstringFields };
|
||||
List<Match<File, Episode>> m = new Matcher<File, Episode>(files, episodes, true, metrics).match();
|
||||
|
@ -59,5 +57,4 @@ public class EpisodeMetricsTest {
|
|||
assertEquals("Veronica Mars [1x19] Hot Dogs", m.get(1).getValue().getName());
|
||||
assertEquals("Veronica Mars - 1x19 - Hot Dogs", m.get(1).getCandidate().toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ public class AnidbClientTest {
|
|||
|
||||
@Test
|
||||
public void search() throws Exception {
|
||||
List<SearchResult> results = anidb.search("one piece");
|
||||
List<SearchResult> results = anidb.search("one piece", Locale.ENGLISH);
|
||||
|
||||
AnidbSearchResult result = (AnidbSearchResult) results.get(0);
|
||||
assertEquals("One Piece", result.getName());
|
||||
|
@ -54,7 +54,7 @@ public class AnidbClientTest {
|
|||
|
||||
@Test
|
||||
public void searchNoMatch() throws Exception {
|
||||
List<SearchResult> results = anidb.search("i will not find anything for this query string");
|
||||
List<SearchResult> results = anidb.search("i will not find anything for this query string", Locale.ENGLISH);
|
||||
|
||||
assertTrue(results.isEmpty());
|
||||
}
|
||||
|
@ -62,23 +62,23 @@ public class AnidbClientTest {
|
|||
@Test
|
||||
public void searchTitleAlias() throws Exception {
|
||||
// Seikai no Senki (main title), Banner of the Stars (official English title)
|
||||
assertEquals("Seikai no Senki", anidb.search("banner of the stars").get(0).getName());
|
||||
assertEquals("Seikai no Senki", anidb.search("seikai no senki").get(0).getName());
|
||||
assertEquals("Seikai no Senki", anidb.search("banner of the stars", Locale.ENGLISH).get(0).getName());
|
||||
assertEquals("Seikai no Senki", anidb.search("seikai no senki", Locale.ENGLISH).get(0).getName());
|
||||
|
||||
// no matching title
|
||||
assertEquals("Naruto", anidb.search("naruto").get(0).getName());
|
||||
assertEquals("Naruto", anidb.search("naruto", Locale.ENGLISH).get(0).getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getEpisodeListAll() throws Exception {
|
||||
List<Episode> list = anidb.getEpisodeList(monsterSearchResult);
|
||||
List<Episode> list = anidb.getEpisodeList(monsterSearchResult, SortOrder.Airdate, Locale.ENGLISH);
|
||||
|
||||
assertEquals(77, list.size());
|
||||
|
||||
Episode first = list.get(0);
|
||||
|
||||
assertEquals("Monster", first.getSeriesName());
|
||||
assertEquals("2004-04-07", first.getSeriesStartDate().toString());
|
||||
assertEquals("2004-04-07", first.getSeriesInfo().getStartDate().toString());
|
||||
assertEquals("Herr Dr. Tenma", first.getTitle());
|
||||
assertEquals("1", first.getEpisode().toString());
|
||||
assertEquals("1", first.getAbsolute().toString());
|
||||
|
@ -88,14 +88,14 @@ public class AnidbClientTest {
|
|||
|
||||
@Test
|
||||
public void getEpisodeListAllShortLink() throws Exception {
|
||||
List<Episode> list = anidb.getEpisodeList(twelvekingdomsSearchResult);
|
||||
List<Episode> list = anidb.getEpisodeList(twelvekingdomsSearchResult, SortOrder.Airdate, Locale.ENGLISH);
|
||||
|
||||
assertEquals(46, list.size());
|
||||
|
||||
Episode first = list.get(0);
|
||||
|
||||
assertEquals("The Twelve Kingdoms", first.getSeriesName());
|
||||
assertEquals("2002-04-09", first.getSeriesStartDate().toString());
|
||||
assertEquals("2002-04-09", first.getSeriesInfo().getStartDate().toString());
|
||||
assertEquals("Shadow of the Moon, The Sea of Shadow - Chapter 1", first.getTitle());
|
||||
assertEquals("1", first.getEpisode().toString());
|
||||
assertEquals("1", first.getAbsolute().toString());
|
||||
|
@ -105,7 +105,7 @@ public class AnidbClientTest {
|
|||
|
||||
@Test
|
||||
public void getEpisodeListEncoding() throws Exception {
|
||||
assertEquals("Raven Princess - An der schönen blauen Donau", anidb.getEpisodeList(princessTutuSearchResult).get(6).getTitle());
|
||||
assertEquals("Raven Princess - An der schönen blauen Donau", anidb.getEpisodeList(princessTutuSearchResult, SortOrder.Airdate, Locale.ENGLISH).get(6).getTitle());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -114,7 +114,7 @@ public class AnidbClientTest {
|
|||
|
||||
Episode last = list.get(73);
|
||||
assertEquals("モンスター", last.getSeriesName());
|
||||
assertEquals("2004-04-07", last.getSeriesStartDate().toString());
|
||||
assertEquals("2004-04-07", last.getSeriesInfo().getStartDate().toString());
|
||||
assertEquals("本当の怪物", last.getTitle());
|
||||
assertEquals("74", last.getEpisode().toString());
|
||||
assertEquals("74", last.getAbsolute().toString());
|
||||
|
@ -124,7 +124,7 @@ public class AnidbClientTest {
|
|||
|
||||
@Test
|
||||
public void getEpisodeListTrimRecap() throws Exception {
|
||||
assertEquals("Sea God of the East, Azure Sea of the West - Transition Chapter", anidb.getEpisodeList(twelvekingdomsSearchResult).get(44).getTitle());
|
||||
assertEquals("Sea God of the East, Azure Sea of the West - Transition Chapter", anidb.getEpisodeList(twelvekingdomsSearchResult, SortOrder.Airdate, Locale.ENGLISH).get(44).getTitle());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -3,6 +3,7 @@ package net.filebot.web;
|
|||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -15,7 +16,7 @@ public class TVRageClientTest {
|
|||
|
||||
@Test
|
||||
public void search() throws Exception {
|
||||
List<SearchResult> results = tvrage.search("Buffy");
|
||||
List<SearchResult> results = tvrage.search("Buffy", Locale.ENGLISH);
|
||||
|
||||
TVRageSearchResult result = (TVRageSearchResult) results.get(0);
|
||||
|
||||
|
@ -28,14 +29,14 @@ public class TVRageClientTest {
|
|||
|
||||
@Test
|
||||
public void getEpisodeList() throws Exception {
|
||||
List<Episode> list = EpisodeUtilities.filterBySeason(tvrage.getEpisodeList(buffySearchResult), 7);
|
||||
List<Episode> list = EpisodeUtilities.filterBySeason(tvrage.getEpisodeList(buffySearchResult, SortOrder.Airdate, Locale.ENGLISH), 7);
|
||||
|
||||
assertEquals(22, list.size());
|
||||
|
||||
Episode chosen = list.get(21);
|
||||
|
||||
assertEquals("Buffy the Vampire Slayer", chosen.getSeriesName());
|
||||
assertEquals("1997-03-10", chosen.getSeriesStartDate().toString());
|
||||
assertEquals("1997-03-10", chosen.getSeriesInfo().getStartDate().toString());
|
||||
assertEquals("Chosen", chosen.getTitle());
|
||||
assertEquals("22", chosen.getEpisode().toString());
|
||||
assertEquals("7", chosen.getSeason().toString());
|
||||
|
@ -45,7 +46,7 @@ public class TVRageClientTest {
|
|||
|
||||
@Test
|
||||
public void getEpisodeListAll() throws Exception {
|
||||
List<Episode> list = tvrage.getEpisodeList(buffySearchResult);
|
||||
List<Episode> list = tvrage.getEpisodeList(buffySearchResult, SortOrder.Airdate, Locale.ENGLISH);
|
||||
|
||||
assertEquals(143, list.size());
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
package net.filebot.web;
|
||||
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
@ -12,23 +10,20 @@ import java.util.Map;
|
|||
|
||||
import net.filebot.web.TheTVDBClient.BannerDescriptor;
|
||||
import net.filebot.web.TheTVDBClient.MirrorType;
|
||||
import net.filebot.web.TheTVDBClient.SeriesInfo;
|
||||
import net.sf.ehcache.CacheManager;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
public class TheTVDBClientTest {
|
||||
|
||||
private TheTVDBClient thetvdb = new TheTVDBClient("BA864DEE427E384A");
|
||||
|
||||
|
||||
@Test
|
||||
public void search() throws Exception {
|
||||
// test default language and query escaping (blanks)
|
||||
List<SearchResult> results = thetvdb.search("babylon 5");
|
||||
List<SearchResult> results = thetvdb.search("babylon 5", Locale.ENGLISH);
|
||||
|
||||
assertEquals(2, results.size());
|
||||
|
||||
|
@ -38,7 +33,6 @@ public class TheTVDBClientTest {
|
|||
assertEquals(70726, first.getSeriesId());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void searchGerman() throws Exception {
|
||||
List<SearchResult> results = thetvdb.search("Buffy the Vampire Slayer", Locale.GERMAN);
|
||||
|
@ -51,17 +45,16 @@ public class TheTVDBClientTest {
|
|||
assertEquals(70327, first.getSeriesId());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void getEpisodeListAll() throws Exception {
|
||||
List<Episode> list = thetvdb.getEpisodeList(new TheTVDBSearchResult("Buffy the Vampire Slayer", 70327));
|
||||
List<Episode> list = thetvdb.getEpisodeList(new TheTVDBSearchResult("Buffy the Vampire Slayer", 70327), SortOrder.Airdate, Locale.ENGLISH);
|
||||
|
||||
assertTrue(list.size() >= 144);
|
||||
|
||||
// check ordinary episode
|
||||
Episode first = list.get(0);
|
||||
assertEquals("Buffy the Vampire Slayer", first.getSeriesName());
|
||||
assertEquals("1997-03-10", first.getSeriesStartDate().toString());
|
||||
assertEquals("1997-03-10", first.getSeriesInfo().getStartDate().toString());
|
||||
assertEquals("Welcome to the Hellmouth (1)", first.getTitle());
|
||||
assertEquals("1", first.getEpisode().toString());
|
||||
assertEquals("1", first.getSeason().toString());
|
||||
|
@ -79,15 +72,14 @@ public class TheTVDBClientTest {
|
|||
assertEquals(null, last.getAirdate());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void getEpisodeListSingleSeason() throws Exception {
|
||||
List<Episode> list = thetvdb.getEpisodeList(new TheTVDBSearchResult("Wonderfalls", 78845));
|
||||
List<Episode> list = thetvdb.getEpisodeList(new TheTVDBSearchResult("Wonderfalls", 78845), SortOrder.Airdate, Locale.ENGLISH);
|
||||
|
||||
Episode first = list.get(0);
|
||||
|
||||
assertEquals("Wonderfalls", first.getSeriesName());
|
||||
assertEquals("2004-03-12", first.getSeriesStartDate().toString());
|
||||
assertEquals("2004-03-12", first.getSeriesInfo().getStartDate().toString());
|
||||
assertEquals("Wax Lion", first.getTitle());
|
||||
assertEquals("1", first.getEpisode().toString());
|
||||
assertEquals("1", first.getSeason().toString());
|
||||
|
@ -95,14 +87,13 @@ public class TheTVDBClientTest {
|
|||
assertEquals("2004-03-12", first.getAirdate().toString());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void getEpisodeListNumbering() throws Exception {
|
||||
List<Episode> list = thetvdb.getEpisodeList(new TheTVDBSearchResult("Firefly", 78874), SortOrder.DVD, Locale.ENGLISH);
|
||||
|
||||
Episode first = list.get(0);
|
||||
assertEquals("Firefly", first.getSeriesName());
|
||||
assertEquals("2002-09-20", first.getSeriesStartDate().toString());
|
||||
assertEquals("2002-09-20", first.getSeriesInfo().getStartDate().toString());
|
||||
assertEquals("Serenity", first.getTitle());
|
||||
assertEquals("1", first.getEpisode().toString());
|
||||
assertEquals("1", first.getSeason().toString());
|
||||
|
@ -110,13 +101,11 @@ public class TheTVDBClientTest {
|
|||
assertEquals("2002-12-20", first.getAirdate().toString());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void getEpisodeListLink() {
|
||||
assertEquals("http://www.thetvdb.com/?tab=seasonall&id=78874", thetvdb.getEpisodeListLink(new TheTVDBSearchResult("Firefly", 78874)).toString());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void getMirror() throws Exception {
|
||||
assertNotNull(thetvdb.getMirror(MirrorType.XML));
|
||||
|
@ -124,7 +113,6 @@ public class TheTVDBClientTest {
|
|||
assertNotNull(thetvdb.getMirror(MirrorType.ZIP));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void resolveTypeMask() {
|
||||
// no flags set
|
||||
|
@ -137,7 +125,6 @@ public class TheTVDBClientTest {
|
|||
assertEquals(EnumSet.allOf(MirrorType.class), MirrorType.fromTypeMask(7));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void lookupByID() throws Exception {
|
||||
TheTVDBSearchResult series = thetvdb.lookupByID(78874, Locale.ENGLISH);
|
||||
|
@ -145,7 +132,6 @@ public class TheTVDBClientTest {
|
|||
assertEquals(78874, series.getSeriesId());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void lookupByIMDbID() throws Exception {
|
||||
TheTVDBSearchResult series = thetvdb.lookupByIMDbID(303461, Locale.ENGLISH);
|
||||
|
@ -153,23 +139,21 @@ public class TheTVDBClientTest {
|
|||
assertEquals(78874, series.getSeriesId());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void getSeriesInfo() throws Exception {
|
||||
SeriesInfo it = thetvdb.getSeriesInfo(new TheTVDBSearchResult(null, 80348), Locale.ENGLISH);
|
||||
TheTVDBSeriesInfo it = (TheTVDBSeriesInfo) thetvdb.getSeriesInfo(new TheTVDBSearchResult(null, 80348), Locale.ENGLISH);
|
||||
|
||||
assertEquals(80348, it.getId(), 0);
|
||||
assertEquals("TV-PG", it.getContentRating());
|
||||
assertEquals("2007-09-24", it.getFirstAired().toString());
|
||||
assertEquals("Action", it.getGenres().get(0));
|
||||
assertEquals(934814, it.getImdbId(), 0);
|
||||
assertEquals("English", it.getLanguage().getDisplayLanguage(Locale.ENGLISH));
|
||||
assertEquals("tt0934814", it.getImdbId());
|
||||
assertEquals("English", it.getLanguage());
|
||||
assertEquals(310, it.getOverview().length());
|
||||
assertEquals("60", it.getRuntime());
|
||||
assertEquals("Chuck", it.getName());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void getBanner() throws Exception {
|
||||
Map<String, String> filter = new HashMap<String, String>();
|
||||
|
@ -187,7 +171,6 @@ public class TheTVDBClientTest {
|
|||
assertEquals(99712, WebRequest.fetch(banner.getUrl()).remaining(), 0);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void getBannerList() throws Exception {
|
||||
List<BannerDescriptor> banners = thetvdb.getBannerList(new TheTVDBSearchResult("Buffy the Vampire Slayer", 70327));
|
||||
|
@ -197,7 +180,6 @@ public class TheTVDBClientTest {
|
|||
assertEquals(486993, WebRequest.fetch(banners.get(0).getUrl()).remaining(), 0);
|
||||
}
|
||||
|
||||
|
||||
@BeforeClass
|
||||
@AfterClass
|
||||
public static void clearCache() {
|
||||
|
|
Loading…
Reference in New Issue