+ 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.AcoustIDClient;
|
||||||
import net.filebot.web.AnidbClient;
|
import net.filebot.web.AnidbClient;
|
||||||
import net.filebot.web.AnidbSearchResult;
|
import net.filebot.web.AnidbSearchResult;
|
||||||
import net.filebot.web.AudioTrack;
|
|
||||||
import net.filebot.web.EpisodeListProvider;
|
import net.filebot.web.EpisodeListProvider;
|
||||||
import net.filebot.web.FanartTVClient;
|
import net.filebot.web.FanartTVClient;
|
||||||
import net.filebot.web.ID3Lookup;
|
import net.filebot.web.ID3Lookup;
|
||||||
|
@ -40,10 +39,9 @@ import net.filebot.web.SubtitleDescriptor;
|
||||||
import net.filebot.web.SubtitleProvider;
|
import net.filebot.web.SubtitleProvider;
|
||||||
import net.filebot.web.TMDbClient;
|
import net.filebot.web.TMDbClient;
|
||||||
import net.filebot.web.TVRageClient;
|
import net.filebot.web.TVRageClient;
|
||||||
import net.filebot.web.TVRageSearchResult;
|
|
||||||
import net.filebot.web.TheTVDBClient;
|
import net.filebot.web.TheTVDBClient;
|
||||||
import net.filebot.web.TheTVDBClient.SeriesInfo;
|
|
||||||
import net.filebot.web.TheTVDBSearchResult;
|
import net.filebot.web.TheTVDBSearchResult;
|
||||||
|
import net.filebot.web.TheTVDBSeriesInfo;
|
||||||
import net.filebot.web.VideoHashSubtitleService;
|
import net.filebot.web.VideoHashSubtitleService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -114,21 +112,6 @@ public final class WebServices {
|
||||||
return null; // default
|
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 final ExecutorService requestThreadPool = Executors.newCachedThreadPool();
|
||||||
|
|
||||||
public static class TheTVDBClientWithLocalSearch extends TheTVDBClient {
|
public static class TheTVDBClientWithLocalSearch extends TheTVDBClient {
|
||||||
|
@ -161,14 +144,6 @@ public final class WebServices {
|
||||||
return localIndex;
|
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
|
@Override
|
||||||
public List<SearchResult> fetchSearchResult(final String query, final Locale locale) throws Exception {
|
public List<SearchResult> fetchSearchResult(final String query, final Locale locale) throws Exception {
|
||||||
Callable<List<SearchResult>> apiSearch = () -> TheTVDBClientWithLocalSearch.super.fetchSearchResult(query, locale);
|
Callable<List<SearchResult>> apiSearch = () -> TheTVDBClientWithLocalSearch.super.fetchSearchResult(query, locale);
|
||||||
|
@ -258,10 +233,11 @@ public final class WebServices {
|
||||||
|
|
||||||
public Movie getIMDbID(SearchResult result) throws Exception {
|
public Movie getIMDbID(SearchResult result) throws Exception {
|
||||||
if (result instanceof TheTVDBSearchResult) {
|
if (result instanceof TheTVDBSearchResult) {
|
||||||
TheTVDBSearchResult s = (TheTVDBSearchResult) result;
|
TheTVDBSearchResult searchResult = (TheTVDBSearchResult) result;
|
||||||
SeriesInfo seriesInfo = ((TheTVDBClient) seriesIndex).getSeriesInfo(s, Locale.ENGLISH);
|
TheTVDBSeriesInfo seriesInfo = (TheTVDBSeriesInfo) ((TheTVDBClient) seriesIndex).getSeriesInfo(searchResult, Locale.ENGLISH);
|
||||||
if (seriesInfo.getImdbId() != null) {
|
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) {
|
if (result instanceof Movie) {
|
||||||
|
|
|
@ -44,16 +44,15 @@ import net.filebot.mediainfo.MediaInfo.StreamKind;
|
||||||
import net.filebot.similarity.SimilarityComparator;
|
import net.filebot.similarity.SimilarityComparator;
|
||||||
import net.filebot.util.FileUtilities;
|
import net.filebot.util.FileUtilities;
|
||||||
import net.filebot.util.FileUtilities.ExtensionFileFilter;
|
import net.filebot.util.FileUtilities.ExtensionFileFilter;
|
||||||
import net.filebot.web.AnidbSearchResult;
|
|
||||||
import net.filebot.web.AudioTrack;
|
import net.filebot.web.AudioTrack;
|
||||||
import net.filebot.web.Episode;
|
import net.filebot.web.Episode;
|
||||||
import net.filebot.web.EpisodeListProvider;
|
import net.filebot.web.EpisodeListProvider;
|
||||||
import net.filebot.web.Movie;
|
import net.filebot.web.Movie;
|
||||||
import net.filebot.web.MoviePart;
|
import net.filebot.web.MoviePart;
|
||||||
import net.filebot.web.MultiEpisode;
|
import net.filebot.web.MultiEpisode;
|
||||||
import net.filebot.web.SearchResult;
|
import net.filebot.web.SeriesInfo;
|
||||||
import net.filebot.web.SimpleDate;
|
import net.filebot.web.SimpleDate;
|
||||||
import net.filebot.web.TheTVDBSearchResult;
|
import net.filebot.web.SortOrder;
|
||||||
|
|
||||||
import com.cedarsoftware.util.io.JsonWriter;
|
import com.cedarsoftware.util.io.JsonWriter;
|
||||||
|
|
||||||
|
@ -99,7 +98,7 @@ public class MediaBindingBean {
|
||||||
@Define("y")
|
@Define("y")
|
||||||
public Integer getYear() {
|
public Integer getYear() {
|
||||||
if (infoObject instanceof Episode)
|
if (infoObject instanceof Episode)
|
||||||
return getEpisode().getSeriesStartDate().getYear();
|
return getEpisode().getSeriesInfo().getStartDate().getYear();
|
||||||
if (infoObject instanceof Movie)
|
if (infoObject instanceof Movie)
|
||||||
return getMovie().getYear();
|
return getMovie().getYear();
|
||||||
if (infoObject instanceof AudioTrack)
|
if (infoObject instanceof AudioTrack)
|
||||||
|
@ -191,7 +190,7 @@ public class MediaBindingBean {
|
||||||
|
|
||||||
@Define("startdate")
|
@Define("startdate")
|
||||||
public SimpleDate startdate() {
|
public SimpleDate startdate() {
|
||||||
return getEpisode().getSeriesStartDate();
|
return getEpisode().getSeriesInfo().getStartDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Define("absolute")
|
@Define("absolute")
|
||||||
|
@ -205,8 +204,8 @@ public class MediaBindingBean {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Define("series")
|
@Define("series")
|
||||||
public SearchResult getSeriesObject() {
|
public SeriesInfo getSeriesInfo() {
|
||||||
return getEpisode().getSeries();
|
return getEpisode().getSeriesInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Define("alias")
|
@Define("alias")
|
||||||
|
@ -214,11 +213,9 @@ public class MediaBindingBean {
|
||||||
if (infoObject instanceof Movie) {
|
if (infoObject instanceof Movie) {
|
||||||
return asList(getMovie().getAliasNames());
|
return asList(getMovie().getAliasNames());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (infoObject instanceof Episode) {
|
if (infoObject instanceof Episode) {
|
||||||
return asList(getSeriesObject().getAliasNames());
|
return getSeriesInfo().getAliasNames();
|
||||||
}
|
}
|
||||||
|
|
||||||
return emptyList();
|
return emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,13 +226,13 @@ public class MediaBindingBean {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (infoObject instanceof Episode) {
|
if (infoObject instanceof Episode) {
|
||||||
if (getSeriesObject() instanceof TheTVDBSearchResult) {
|
// force English series name for TheTVDB data
|
||||||
return WebServices.TheTVDB.getSeriesInfo((TheTVDBSearchResult) getSeriesObject(), Locale.ENGLISH).getName();
|
if (WebServices.TheTVDB.getName().equals(getSeriesInfo().getDatabase())) {
|
||||||
|
return WebServices.TheTVDB.getSeriesInfo(getSeriesInfo().getId(), Locale.ENGLISH).getName();
|
||||||
}
|
}
|
||||||
if (getSeriesObject() instanceof AnidbSearchResult) {
|
|
||||||
return ((AnidbSearchResult) getSeriesObject()).getPrimaryTitle();
|
// default to series info name (for anime this would be the primary title)
|
||||||
}
|
return getSeriesInfo().getName();
|
||||||
return getSeriesObject().getName(); // default to original search result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -558,10 +555,7 @@ public class MediaBindingBean {
|
||||||
if (metaInfo == null) {
|
if (metaInfo == null) {
|
||||||
try {
|
try {
|
||||||
if (infoObject instanceof Episode) {
|
if (infoObject instanceof Episode) {
|
||||||
Episode episode = (Episode) infoObject;
|
metaInfo = getSeriesInfo();
|
||||||
if (episode.getSeries() instanceof TheTVDBSearchResult) {
|
|
||||||
metaInfo = WebServices.TheTVDB.getSeriesInfo((TheTVDBSearchResult) episode.getSeries(), episode.getLanguage() == null ? Locale.ENGLISH : episode.getLanguage());
|
|
||||||
}
|
|
||||||
} else if (infoObject instanceof Movie) {
|
} else if (infoObject instanceof Movie) {
|
||||||
if (getMovie().getTmdbId() > 0) {
|
if (getMovie().getTmdbId() > 0) {
|
||||||
metaInfo = WebServices.TheMovieDB.getMovieInfo(getMovie(), getMovie().getLanguage() == null ? Locale.ENGLISH : getMovie().getLanguage(), true);
|
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");
|
throw new UnsupportedOperationException("Extended metadata not available");
|
||||||
}
|
}
|
||||||
|
|
||||||
return createMapBindings(new PropertyBindings(metaInfo, null));
|
return createMapBindings(new PropertyBindings(metaInfo, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Define("imdb")
|
@Define("omdb")
|
||||||
public synchronized AssociativeScriptObject getImdbApiInfo() {
|
public synchronized AssociativeScriptObject getOmdbApiInfo() {
|
||||||
Object metaInfo = null;
|
Object metaInfo = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (infoObject instanceof Episode) {
|
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) {
|
if (infoObject instanceof Movie) {
|
||||||
metaInfo = WebServices.OMDb.getMovieInfo(getMovie());
|
metaInfo = WebServices.OMDb.getMovieInfo(getMovie());
|
||||||
|
@ -605,19 +599,10 @@ public class MediaBindingBean {
|
||||||
|
|
||||||
@Define("episodelist")
|
@Define("episodelist")
|
||||||
public Object getEpisodeList() throws Exception {
|
public Object getEpisodeList() throws Exception {
|
||||||
return ((EpisodeListProvider) getDatabase()).getEpisodeList(getSeriesObject(), getEpisode().getOrder(), getEpisode().getLanguage());
|
for (EpisodeListProvider service : WebServices.getEpisodeListProviders()) {
|
||||||
}
|
if (getSeriesInfo().getDatabase().equals(service.getName())) {
|
||||||
|
return service.getEpisodeList(getSeriesInfo().getId(), SortOrder.forName(getSeriesInfo().getOrder()), new Locale(getSeriesInfo().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());
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,8 +65,8 @@ import net.filebot.web.Episode;
|
||||||
import net.filebot.web.Movie;
|
import net.filebot.web.Movie;
|
||||||
import net.filebot.web.MovieIdentificationService;
|
import net.filebot.web.MovieIdentificationService;
|
||||||
import net.filebot.web.SearchResult;
|
import net.filebot.web.SearchResult;
|
||||||
|
import net.filebot.web.SeriesInfo;
|
||||||
import net.filebot.web.SimpleDate;
|
import net.filebot.web.SimpleDate;
|
||||||
import net.filebot.web.TheTVDBClient.SeriesInfo;
|
|
||||||
import net.filebot.web.TheTVDBSearchResult;
|
import net.filebot.web.TheTVDBSearchResult;
|
||||||
|
|
||||||
public class MediaDetection {
|
public class MediaDetection {
|
||||||
|
@ -1259,7 +1259,9 @@ public class MediaDetection {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SeriesInfo grepSeries(File nfo, Locale locale) throws Exception {
|
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) {
|
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.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import net.filebot.WebServices;
|
|
||||||
import net.filebot.media.MediaDetection;
|
import net.filebot.media.MediaDetection;
|
||||||
import net.filebot.media.SmartSeasonEpisodeMatcher;
|
import net.filebot.media.SmartSeasonEpisodeMatcher;
|
||||||
import net.filebot.similarity.SeasonEpisodeMatcher.SxE;
|
import net.filebot.similarity.SeasonEpisodeMatcher.SxE;
|
||||||
|
@ -34,9 +33,8 @@ import net.filebot.vfs.FileInfo;
|
||||||
import net.filebot.web.Episode;
|
import net.filebot.web.Episode;
|
||||||
import net.filebot.web.EpisodeFormat;
|
import net.filebot.web.EpisodeFormat;
|
||||||
import net.filebot.web.Movie;
|
import net.filebot.web.Movie;
|
||||||
|
import net.filebot.web.SeriesInfo;
|
||||||
import net.filebot.web.SimpleDate;
|
import net.filebot.web.SimpleDate;
|
||||||
import net.filebot.web.TheTVDBClient.SeriesInfo;
|
|
||||||
import net.filebot.web.TheTVDBSearchResult;
|
|
||||||
|
|
||||||
import com.ibm.icu.text.Transliterator;
|
import com.ibm.icu.text.Transliterator;
|
||||||
|
|
||||||
|
@ -212,7 +210,7 @@ public enum EpisodeMetrics implements SimilarityMetric {
|
||||||
LinkedHashSet<String> keywords = new LinkedHashSet<String>(4);
|
LinkedHashSet<String> keywords = new LinkedHashSet<String>(4);
|
||||||
keywords.add(removeTrailingBrackets(episode.getSeriesName()));
|
keywords.add(removeTrailingBrackets(episode.getSeriesName()));
|
||||||
keywords.add(removeTrailingBrackets(episode.getTitle()));
|
keywords.add(removeTrailingBrackets(episode.getTitle()));
|
||||||
for (String it : episode.getSeries().getEffectiveNames()) {
|
for (String it : episode.getSeriesInfo().getAliasNames()) {
|
||||||
keywords.add(removeTrailingBrackets(it));
|
keywords.add(removeTrailingBrackets(it));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,7 +275,7 @@ public enum EpisodeMetrics implements SimilarityMetric {
|
||||||
|
|
||||||
protected List<?> getEffectiveIdentifiers(Object object) {
|
protected List<?> getEffectiveIdentifiers(Object object) {
|
||||||
if (object instanceof Episode) {
|
if (object instanceof Episode) {
|
||||||
return ((Episode) object).getSeries().getEffectiveNames();
|
return ((Episode) object).getSeriesInfo().getAliasNames();
|
||||||
} else if (object instanceof Movie) {
|
} else if (object instanceof Movie) {
|
||||||
return ((Movie) object).getEffectiveNames();
|
return ((Movie) object).getEffectiveNames();
|
||||||
} else if (object instanceof File) {
|
} else if (object instanceof File) {
|
||||||
|
@ -346,7 +344,7 @@ public enum EpisodeMetrics implements SimilarityMetric {
|
||||||
List<String> names = null;
|
List<String> names = null;
|
||||||
|
|
||||||
if (object instanceof Episode) {
|
if (object instanceof Episode) {
|
||||||
names = ((Episode) object).getSeries().getEffectiveNames();
|
names = ((Episode) object).getSeriesInfo().getAliasNames();
|
||||||
} else if (object instanceof File) {
|
} else if (object instanceof File) {
|
||||||
File file = (File) object;
|
File file = (File) object;
|
||||||
|
|
||||||
|
@ -558,39 +556,20 @@ public enum EpisodeMetrics implements SimilarityMetric {
|
||||||
return max(r1, r2);
|
return max(r1, r2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Map<String, SeriesInfo> seriesInfoCache = new HashMap<String, SeriesInfo>();
|
public float getRating(Object object) {
|
||||||
|
if (object instanceof Episode) {
|
||||||
public float getRating(Object o) {
|
SeriesInfo seriesInfo = ((Episode) object).getSeriesInfo();
|
||||||
if (o instanceof Episode) {
|
if (seriesInfo != null && seriesInfo.getRating() != null && seriesInfo.getRatingCount() != null) {
|
||||||
try {
|
if (seriesInfo.getRatingCount() >= 100) {
|
||||||
synchronized (seriesInfoCache) {
|
return (float) floor(seriesInfo.getRating() / 3) + 1; // BOOST POPULAR SHOWS
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
if (seriesInfo.getRatingCount() >= 10) {
|
||||||
Logger.getLogger(EpisodeMetrics.class.getName()).log(Level.WARNING, e.getMessage());
|
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;
|
return 0;
|
||||||
|
|
|
@ -20,7 +20,7 @@ import net.filebot.util.FileUtilities;
|
||||||
import net.filebot.util.ui.LoadingOverlayPane;
|
import net.filebot.util.ui.LoadingOverlayPane;
|
||||||
import net.filebot.web.Episode;
|
import net.filebot.web.Episode;
|
||||||
import net.filebot.web.Movie;
|
import net.filebot.web.Movie;
|
||||||
import net.filebot.web.SearchResult;
|
import net.filebot.web.SeriesInfo;
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
|
||||||
class AttributeTool extends Tool<TableModel> {
|
class AttributeTool extends Tool<TableModel> {
|
||||||
|
@ -59,20 +59,17 @@ class AttributeTool extends Tool<TableModel> {
|
||||||
originalName = attributes.getOriginalName();
|
originalName = attributes.getOriginalName();
|
||||||
metaObject = attributes.getObject();
|
metaObject = attributes.getObject();
|
||||||
|
|
||||||
String format = "%s::%d";
|
|
||||||
if (metaObject instanceof Episode) {
|
if (metaObject instanceof Episode) {
|
||||||
Object seriesObject = ((Episode) metaObject).getSeries();
|
SeriesInfo seriesInfo = ((Episode) metaObject).getSeriesInfo();
|
||||||
if (seriesObject != null) {
|
if (seriesInfo != null) {
|
||||||
String type = seriesObject.getClass().getSimpleName().replace(SearchResult.class.getSimpleName(), "");
|
metaId = String.format("%s::%d", seriesInfo.getDatabase(), seriesInfo.getId());
|
||||||
Integer code = (Integer) seriesObject.getClass().getMethod("getId").invoke(seriesObject);
|
|
||||||
metaId = String.format(format, type, code);
|
|
||||||
}
|
}
|
||||||
} else if (metaObject instanceof Movie) {
|
} else if (metaObject instanceof Movie) {
|
||||||
Movie movie = (Movie) metaObject;
|
Movie movie = (Movie) metaObject;
|
||||||
if (movie.getTmdbId() > 0) {
|
if (movie.getTmdbId() > 0) {
|
||||||
metaId = String.format(format, "TheMovieDB", movie.getTmdbId());
|
metaId = String.format("%s::%d", "TheMovieDB", movie.getTmdbId());
|
||||||
} else if (movie.getImdbId() > 0) {
|
} else if (movie.getImdbId() > 0) {
|
||||||
metaId = String.format(format, "IMDB", movie.getImdbId());
|
metaId = String.format("%s::%d", "OMDb", movie.getImdbId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
@ -124,7 +124,7 @@ public class EpisodeListPanel extends AbstractSearchPanel<EpisodeListProvider, E
|
||||||
EpisodeListProvider provider = searchTextField.getSelectButton().getSelectedValue();
|
EpisodeListProvider provider = searchTextField.getSelectButton().getSelectedValue();
|
||||||
|
|
||||||
// lock season spinner on "All Seasons" if provider doesn't support fetching of single seasons
|
// 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);
|
seasonSpinnerModel.lock(ALL_SEASONS);
|
||||||
} else {
|
} else {
|
||||||
seasonSpinnerModel.unlock();
|
seasonSpinnerModel.unlock();
|
||||||
|
|
|
@ -60,8 +60,8 @@ import net.filebot.util.ui.EmptySelectionModel;
|
||||||
import net.filebot.web.Movie;
|
import net.filebot.web.Movie;
|
||||||
import net.filebot.web.OpenSubtitlesClient;
|
import net.filebot.web.OpenSubtitlesClient;
|
||||||
import net.filebot.web.SearchResult;
|
import net.filebot.web.SearchResult;
|
||||||
import net.filebot.web.TheTVDBClient.SeriesInfo;
|
|
||||||
import net.filebot.web.TheTVDBSearchResult;
|
import net.filebot.web.TheTVDBSearchResult;
|
||||||
|
import net.filebot.web.TheTVDBSeriesInfo;
|
||||||
import net.filebot.web.VideoHashSubtitleService.CheckResult;
|
import net.filebot.web.VideoHashSubtitleService.CheckResult;
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
|
||||||
|
@ -689,10 +689,10 @@ public class SubtitleUploadDialog extends JDialog {
|
||||||
for (String name : seriesNames) {
|
for (String name : seriesNames) {
|
||||||
List<SearchResult> options = WebServices.TheTVDB.search(name, Locale.ENGLISH);
|
List<SearchResult> options = WebServices.TheTVDB.search(name, Locale.ENGLISH);
|
||||||
for (SearchResult entry : options) {
|
for (SearchResult entry : options) {
|
||||||
SeriesInfo seriesInfo = WebServices.TheTVDB.getSeriesInfo((TheTVDBSearchResult) entry, Locale.ENGLISH);
|
TheTVDBSeriesInfo seriesInfo = (TheTVDBSeriesInfo) WebServices.TheTVDB.getSeriesInfo((TheTVDBSearchResult) entry, Locale.ENGLISH);
|
||||||
Integer imdbid = seriesInfo.getImdbId();
|
if (seriesInfo.getImdbId() != null) {
|
||||||
if (imdbid != null && imdbid > 0) {
|
int imdbId = grepImdbId(seriesInfo.getImdbId()).iterator().next();
|
||||||
mapping.setIdentity(WebServices.OpenSubtitles.getMovieDescriptor(new Movie(null, 0, imdbid, -1), Locale.ENGLISH));
|
mapping.setIdentity(WebServices.OpenSubtitles.getMovieDescriptor(new Movie(null, 0, imdbId, -1), Locale.ENGLISH));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
|
|
||||||
package net.filebot.util;
|
package net.filebot.util;
|
||||||
|
|
||||||
|
|
||||||
import java.util.AbstractList;
|
import java.util.AbstractList;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
import javax.xml.xpath.XPathConstants;
|
import javax.xml.xpath.XPathConstants;
|
||||||
import javax.xml.xpath.XPathExpression;
|
import javax.xml.xpath.XPathExpression;
|
||||||
|
@ -14,9 +13,8 @@ import javax.xml.xpath.XPathFactory;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
import org.w3c.dom.NodeList;
|
import org.w3c.dom.NodeList;
|
||||||
|
|
||||||
|
|
||||||
public final class XPathUtilities {
|
public final class XPathUtilities {
|
||||||
|
|
||||||
public static Node selectNode(String xpath, Object node) {
|
public static Node selectNode(String xpath, Object node) {
|
||||||
try {
|
try {
|
||||||
return (Node) getXPath(xpath).evaluate(node, XPathConstants.NODE);
|
return (Node) getXPath(xpath).evaluate(node, XPathConstants.NODE);
|
||||||
|
@ -24,7 +22,6 @@ public final class XPathUtilities {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static List<Node> selectNodes(String xpath, Object node) {
|
public static List<Node> selectNodes(String xpath, Object node) {
|
||||||
try {
|
try {
|
||||||
|
@ -33,7 +30,6 @@ public final class XPathUtilities {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static String selectString(String xpath, Object node) {
|
public static String selectString(String xpath, Object node) {
|
||||||
try {
|
try {
|
||||||
|
@ -42,11 +38,27 @@ public final class XPathUtilities {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 nodeName
|
||||||
* @param parentNode search in the child nodes of this nodes
|
* 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
|
* @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) {
|
public static Node getChild(String nodeName, Node parentNode) {
|
||||||
|
@ -54,77 +66,98 @@ public final class XPathUtilities {
|
||||||
if (nodeName.equals(child.getNodeName()))
|
if (nodeName.equals(child.getNodeName()))
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static List<Node> getChildren(String nodeName, Node parentNode) {
|
public static List<Node> getChildren(String nodeName, Node parentNode) {
|
||||||
List<Node> children = new ArrayList<Node>();
|
List<Node> children = new ArrayList<Node>();
|
||||||
|
|
||||||
for (Node child : new NodeListDecorator(parentNode.getChildNodes())) {
|
for (Node child : new NodeListDecorator(parentNode.getChildNodes())) {
|
||||||
if (nodeName.equals(child.getNodeName()))
|
if (nodeName.equals(child.getNodeName()))
|
||||||
children.add(child);
|
children.add(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
return children;
|
return children;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static String getAttribute(String attribute, Node node) {
|
public static String getAttribute(String attribute, Node node) {
|
||||||
Node attributeNode = node.getAttributes().getNamedItem(attribute);
|
Node attributeNode = node.getAttributes().getNamedItem(attribute);
|
||||||
|
|
||||||
if (attributeNode != null)
|
if (attributeNode != null)
|
||||||
return attributeNode.getNodeValue().trim();
|
return attributeNode.getNodeValue().trim();
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get text content of the first child node matching the given node name. Use this method
|
* 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.
|
||||||
* 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 childName
|
||||||
* @param parentNode search in the child nodes of this nodes
|
* 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
|
* @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) {
|
public static String getTextContent(String childName, Node parentNode) {
|
||||||
Node child = getChild(childName, parentNode);
|
Node child = getChild(childName, parentNode);
|
||||||
|
|
||||||
if (child == null) {
|
if (child == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return getTextContent(child);
|
return getTextContent(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static String getTextContent(Node node) {
|
public static String getTextContent(Node node) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
for (Node textNode : getChildren("#text", node)) {
|
for (Node textNode : getChildren("#text", node)) {
|
||||||
sb.append(textNode.getNodeValue());
|
sb.append(textNode.getNodeValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb.toString().trim();
|
return sb.toString().trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static Integer getIntegerContent(String childName, Node parentNode) {
|
public static Integer getIntegerContent(String childName, Node parentNode) {
|
||||||
try {
|
try {
|
||||||
return new Integer(getTextContent(childName, parentNode));
|
return new Scanner(getTextContent(childName, parentNode)).useDelimiter("\\D+").nextInt();
|
||||||
} catch (NumberFormatException e) {
|
} catch (Exception e) {
|
||||||
return null;
|
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 {
|
private static XPathExpression getXPath(String xpath) throws XPathExpressionException {
|
||||||
return XPathFactory.newInstance().newXPath().compile(xpath);
|
return XPathFactory.newInstance().newXPath().compile(xpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dummy constructor to prevent instantiation.
|
* Dummy constructor to prevent instantiation.
|
||||||
|
@ -132,29 +165,25 @@ public final class XPathUtilities {
|
||||||
private XPathUtilities() {
|
private XPathUtilities() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected static class NodeListDecorator extends AbstractList<Node> {
|
protected static class NodeListDecorator extends AbstractList<Node> {
|
||||||
|
|
||||||
private final NodeList nodes;
|
private final NodeList nodes;
|
||||||
|
|
||||||
|
|
||||||
public NodeListDecorator(NodeList nodes) {
|
public NodeListDecorator(NodeList nodes) {
|
||||||
this.nodes = nodes;
|
this.nodes = nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node get(int index) {
|
public Node get(int index) {
|
||||||
return nodes.item(index);
|
return nodes.item(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int size() {
|
public int size() {
|
||||||
return nodes.getLength();
|
return nodes.getLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package net.filebot.web;
|
package net.filebot.web;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import static java.util.Arrays.*;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
@ -11,69 +13,86 @@ import net.filebot.Cache.Key;
|
||||||
|
|
||||||
public abstract class AbstractEpisodeListProvider implements EpisodeListProvider {
|
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<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 {
|
protected abstract SearchResult createSearchResult(int id);
|
||||||
return search(query, getDefaultLocale());
|
|
||||||
}
|
protected abstract ResultCache getCache();
|
||||||
|
|
||||||
|
protected abstract SortOrder vetoRequestParameter(SortOrder order);
|
||||||
|
|
||||||
|
protected abstract Locale vetoRequestParameter(Locale language);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<SearchResult> search(String query, Locale locale) throws Exception {
|
public List<SearchResult> search(String query, Locale language) throws Exception {
|
||||||
ResultCache cache = getCache();
|
List<SearchResult> results = getCache().getSearchResult(query, language);
|
||||||
List<SearchResult> results = (cache != null) ? cache.getSearchResult(query, locale) : null;
|
|
||||||
if (results != null) {
|
if (results != null) {
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
// perform actual search
|
// perform actual search
|
||||||
results = fetchSearchResult(query, locale);
|
results = fetchSearchResult(query, language);
|
||||||
|
|
||||||
// cache results and return
|
// cache results and return
|
||||||
return (cache != null) ? cache.putSearchResult(query, locale, results) : results;
|
return getCache().putSearchResult(query, language, 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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Episode> getEpisodeList(SearchResult searchResult, SortOrder sortOrder, Locale locale) throws Exception {
|
public List<Episode> getEpisodeList(SearchResult searchResult, SortOrder sortOrder, Locale language) throws Exception {
|
||||||
ResultCache cache = getCache();
|
return getSeriesData(searchResult, sortOrder, language).getEpisodeList();
|
||||||
List<Episode> episodes = (cache != null) ? cache.getEpisodeList(searchResult, sortOrder, locale) : null;
|
}
|
||||||
if (episodes != null) {
|
|
||||||
return episodes;
|
@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
|
// perform actual lookup
|
||||||
episodes = fetchEpisodeList(searchResult, sortOrder, locale);
|
data = fetchSeriesData(searchResult, order, language);
|
||||||
|
|
||||||
// cache results and return
|
// cache results and return
|
||||||
return (cache != null) ? cache.putEpisodeList(searchResult, sortOrder, locale, episodes) : episodes;
|
return getCache().putSeriesData(searchResult, order, language, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Locale getDefaultLocale() {
|
protected static class SeriesData implements Serializable {
|
||||||
return Locale.ENGLISH;
|
|
||||||
}
|
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 {
|
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) {
|
public <T extends SearchResult> List<T> putSearchResult(String query, Locale locale, List<T> value) {
|
||||||
try {
|
putData("SearchResult", normalize(query), locale, value.toArray(new SearchResult[value.size()]));
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<SearchResult> getSearchResult(String query, Locale locale) {
|
public List<SearchResult> getSearchResult(String query, Locale locale) {
|
||||||
try {
|
SearchResult[] data = getData("SearchResult", normalize(query), locale, SearchResult[].class);
|
||||||
SearchResult[] results = cache.get(new Key(id, normalize(query), locale), SearchResult[].class);
|
return data == null ? null : asList(data);
|
||||||
if (results != null) {
|
|
||||||
return Arrays.asList(results);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
Logger.getLogger(AbstractEpisodeListProvider.class.getName()).log(Level.WARNING, e.getMessage(), e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Episode> putEpisodeList(SearchResult key, SortOrder sortOrder, Locale locale, List<Episode> episodes) {
|
public SeriesData putSeriesData(SearchResult key, SortOrder sortOrder, Locale locale, SeriesData seriesData) {
|
||||||
try {
|
putData("SeriesData." + sortOrder.name(), key, locale, seriesData);
|
||||||
cache.put(new Key(id, key, sortOrder, locale), episodes.toArray(new Episode[0]));
|
return seriesData;
|
||||||
} catch (Exception e) {
|
|
||||||
Logger.getLogger(AbstractEpisodeListProvider.class.getName()).log(Level.WARNING, e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
return episodes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Episode> getEpisodeList(SearchResult key, SortOrder sortOrder, Locale locale) {
|
public SeriesData getSeriesData(SearchResult key, SortOrder sortOrder, Locale locale) {
|
||||||
try {
|
return getData("SeriesData." + sortOrder.name(), key, locale, SeriesData.class);
|
||||||
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 void putData(Object category, Object key, Locale locale, Object object) {
|
public <T> T putData(Object category, Object key, Locale locale, T object) {
|
||||||
try {
|
try {
|
||||||
cache.put(new Key(id, category, locale, key), object);
|
cache.put(new Key(id, category, locale, key), object);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Logger.getLogger(AbstractEpisodeListProvider.class.getName()).log(Level.WARNING, e.getMessage());
|
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) {
|
public <T> T getData(Object category, Object key, Locale locale, Class<T> type) {
|
||||||
try {
|
try {
|
||||||
T value = cache.get(new Key(id, category, locale, key), type);
|
return cache.get(new Key(id, category, locale, key), type);
|
||||||
if (value != null) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Logger.getLogger(AbstractEpisodeListProvider.class.getName()).log(Level.WARNING, e.getMessage(), e);
|
Logger.getLogger(AbstractEpisodeListProvider.class.getName()).log(Level.WARNING, e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package net.filebot.web;
|
package net.filebot.web;
|
||||||
|
|
||||||
|
import static java.util.Collections.*;
|
||||||
import static net.filebot.util.XPathUtilities.*;
|
import static net.filebot.util.XPathUtilities.*;
|
||||||
import static net.filebot.web.EpisodeUtilities.*;
|
import static net.filebot.web.EpisodeUtilities.*;
|
||||||
import static net.filebot.web.WebRequest.*;
|
import static net.filebot.web.WebRequest.*;
|
||||||
|
@ -58,18 +59,23 @@ public class AnidbClient extends AbstractEpisodeListProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasSingleSeasonSupport() {
|
public boolean hasSeasonSupport() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasLocaleSupport() {
|
protected SortOrder vetoRequestParameter(SortOrder order) {
|
||||||
return true;
|
return SortOrder.Absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Locale vetoRequestParameter(Locale language) {
|
||||||
|
return language != null ? language : Locale.ENGLISH;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResultCache getCache() {
|
public ResultCache getCache() {
|
||||||
return new ResultCache(host, Cache.getCache("web-datasource-lv2"));
|
return new ResultCache(getName(), Cache.getCache("web-datasource-lv2"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -87,12 +93,11 @@ public class AnidbClient extends AbstractEpisodeListProvider {
|
||||||
return set(it.getEffectiveNames());
|
return set(it.getEffectiveNames());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return new ArrayList<SearchResult>(index.search(query));
|
return new ArrayList<SearchResult>(index.search(query));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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;
|
AnidbSearchResult anime = (AnidbSearchResult) searchResult;
|
||||||
|
|
||||||
// e.g. http://api.anidb.net:9001/httpapi?request=anime&client=filebot&clientver=1&protover=1&aid=4521
|
// 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
|
// get anime page as xml
|
||||||
Document dom = getDocument(url);
|
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
|
// AniDB types: Movie, Music Video, Other, OVA, TV Series, TV Special, Web, unknown
|
||||||
String animeType = selectString("//type", dom);
|
String animeType = selectString("//type", dom);
|
||||||
if (animeType != null && animeType.matches("(?i:music.video|unkown|other)")) {
|
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
|
seriesInfo.setName(selectString("anime/titles/title[@type='main']", dom));
|
||||||
SimpleDate seriesStartDate = SimpleDate.parse(selectString("//startdate", dom), "yyyy-MM-dd");
|
seriesInfo.setRating(new Double(selectString("anime/ratings/permanent", dom)));
|
||||||
String animeTitle = selectString("//titles/title[@type='official' and @lang='" + locale.getLanguage() + "']", dom);
|
seriesInfo.setRatingCount(new Integer(selectString("anime/ratings/permanent/@count", dom)));
|
||||||
if (animeTitle.isEmpty()) {
|
seriesInfo.setStartDate(SimpleDate.parse(selectString("anime/startdate", dom), "yyyy-MM-dd"));
|
||||||
animeTitle = selectString("//titles/title[@type='main']", dom);
|
|
||||||
|
// 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);
|
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);
|
Node epno = getChild("epno", node);
|
||||||
int number = Integer.parseInt(getTextContent(epno).replaceAll("\\D", ""));
|
int number = Integer.parseInt(getTextContent(epno).replaceAll("\\D", ""));
|
||||||
int type = Integer.parseInt(getAttribute("type", epno));
|
int type = Integer.parseInt(getAttribute("type", epno));
|
||||||
|
@ -132,9 +145,9 @@ public class AnidbClient extends AbstractEpisodeListProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == 1) {
|
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 {
|
} 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)));
|
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
|
@Override
|
||||||
|
|
|
@ -3,13 +3,10 @@ package net.filebot.web;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
public class Episode implements Serializable {
|
public class Episode implements Serializable {
|
||||||
|
|
||||||
protected String seriesName;
|
protected String seriesName;
|
||||||
protected SimpleDate seriesStartDate;
|
|
||||||
|
|
||||||
protected Integer season;
|
protected Integer season;
|
||||||
protected Integer episode;
|
protected Integer episode;
|
||||||
protected String title;
|
protected String title;
|
||||||
|
@ -20,50 +17,39 @@ public class Episode implements Serializable {
|
||||||
// special number
|
// special number
|
||||||
protected Integer special;
|
protected Integer special;
|
||||||
|
|
||||||
// optional episode number order hint & episode name / title language hint
|
|
||||||
protected String order;
|
|
||||||
protected String language;
|
|
||||||
|
|
||||||
// episode airdate
|
// episode airdate
|
||||||
protected SimpleDate airdate;
|
protected SimpleDate airdate;
|
||||||
|
|
||||||
// original series descriptor
|
// extended series metadata
|
||||||
protected SearchResult series;
|
protected SeriesInfo seriesInfo;
|
||||||
|
|
||||||
protected Episode() {
|
protected Episode() {
|
||||||
// used by serializer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Episode(Episode obj) {
|
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) {
|
public Episode(String seriesName, Integer season, Integer episode, String title) {
|
||||||
this(seriesName, seriesStartDate, season, episode, title, null, null, null, null, null, series);
|
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.seriesName = seriesName;
|
||||||
this.seriesStartDate = (seriesStartDate == null ? null : seriesStartDate.clone());
|
|
||||||
this.season = season;
|
this.season = season;
|
||||||
this.episode = episode;
|
this.episode = episode;
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.absolute = absolute;
|
this.absolute = absolute;
|
||||||
this.special = special;
|
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.airdate = (airdate == null ? null : airdate.clone());
|
||||||
this.series = (series == null ? null : series.clone());
|
this.seriesInfo = (seriesInfo == null ? null : seriesInfo.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSeriesName() {
|
public String getSeriesName() {
|
||||||
return seriesName;
|
return seriesName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SimpleDate getSeriesStartDate() {
|
|
||||||
return seriesStartDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getEpisode() {
|
public Integer getEpisode() {
|
||||||
return episode;
|
return episode;
|
||||||
}
|
}
|
||||||
|
@ -84,20 +70,12 @@ public class Episode implements Serializable {
|
||||||
return special;
|
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() {
|
public SimpleDate getAirdate() {
|
||||||
return airdate;
|
return airdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SearchResult getSeries() {
|
public SeriesInfo getSeriesInfo() {
|
||||||
return series;
|
return seriesInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Integer> getNumbers() {
|
public List<Integer> getNumbers() {
|
||||||
|
|
|
@ -187,7 +187,7 @@ public class EpisodeFormat extends Format {
|
||||||
|
|
||||||
// did parse input
|
// did parse input
|
||||||
pos.setIndex(source.length());
|
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
|
// failed to parse input
|
||||||
|
|
|
@ -1,34 +1,29 @@
|
||||||
|
|
||||||
package net.filebot.web;
|
package net.filebot.web;
|
||||||
|
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import javax.swing.Icon;
|
import javax.swing.Icon;
|
||||||
|
|
||||||
|
|
||||||
public interface EpisodeListProvider {
|
public interface EpisodeListProvider {
|
||||||
|
|
||||||
public String getName();
|
public String getName();
|
||||||
|
|
||||||
|
|
||||||
public Icon getIcon();
|
public Icon getIcon();
|
||||||
|
|
||||||
|
public boolean hasSeasonSupport();
|
||||||
public boolean hasSingleSeasonSupport();
|
|
||||||
|
|
||||||
|
|
||||||
public boolean hasLocaleSupport();
|
|
||||||
|
|
||||||
|
|
||||||
public List<SearchResult> search(String query, Locale locale) throws Exception;
|
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(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);
|
public URI getEpisodeListLink(SearchResult searchResult);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ public class OpenSubtitlesClient implements SubtitleProvider, VideoHashSubtitleS
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResultCache getCache() {
|
public ResultCache getCache() {
|
||||||
return new ResultCache("opensubtitles.org", Cache.getCache("web-datasource"));
|
return new ResultCache(getName(), Cache.getCache("web-datasource"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package net.filebot.web;
|
package net.filebot.web;
|
||||||
|
|
||||||
|
import static java.util.Collections.*;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.AbstractList;
|
import java.util.AbstractList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public abstract class SearchResult implements Serializable {
|
public abstract class SearchResult implements Serializable {
|
||||||
|
@ -28,10 +29,12 @@ public abstract class SearchResult implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getEffectiveNames() {
|
public List<String> getEffectiveNames() {
|
||||||
if (aliasNames == null || aliasNames.length == 0) {
|
if (name == null || name.length() == 0) {
|
||||||
return Collections.singletonList(name);
|
return emptyList();
|
||||||
|
}
|
||||||
|
if (aliasNames == null || aliasNames.length == 0) {
|
||||||
|
return singletonList(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new AbstractList<String>() {
|
return new AbstractList<String>() {
|
||||||
|
|
||||||
@Override
|
@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");
|
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
|
@Override
|
||||||
public ResultCache getCache() {
|
public ResultCache getCache() {
|
||||||
return new ResultCache(host, Cache.getCache("web-datasource"));
|
return new ResultCache(getName(), Cache.getCache("web-datasource"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -67,14 +82,24 @@ public class TVRageClient extends AbstractEpisodeListProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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;
|
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);
|
// parse series data
|
||||||
SimpleDate seriesStartDate = SimpleDate.parse(selectString("Show/started", dom), "MMM/dd/yyyy");
|
Node seriesNode = selectNode("Show", dom);
|
||||||
Locale language = Locale.ENGLISH;
|
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> episodes = new ArrayList<Episode>(25);
|
||||||
List<Episode> specials = new ArrayList<Episode>(5);
|
List<Episode> specials = new ArrayList<Episode>(5);
|
||||||
|
|
||||||
|
@ -86,30 +111,26 @@ public class TVRageClient extends AbstractEpisodeListProvider {
|
||||||
Integer seasonNumber = seasonIdentifier == null ? null : new Integer(seasonIdentifier);
|
Integer seasonNumber = seasonIdentifier == null ? null : new Integer(seasonIdentifier);
|
||||||
SimpleDate airdate = SimpleDate.parse(getTextContent("airdate", node), "yyyy-MM-dd");
|
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
|
// check if we have season and episode number, if not it must be a special episode
|
||||||
if (episodeNumber == null || seasonNumber == null) {
|
if (episodeNumber == null || seasonNumber == null) {
|
||||||
// handle as special episode
|
// handle as special episode
|
||||||
seasonNumber = getIntegerContent("season", node);
|
seasonNumber = getIntegerContent("season", node);
|
||||||
int specialNumber = filterBySeason(specials, seasonNumber).size() + 1;
|
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 {
|
} else {
|
||||||
// handle as normal episode
|
// handle as normal episode
|
||||||
if (sortOrder == SortOrder.Absolute) {
|
if (sortOrder == SortOrder.Absolute) {
|
||||||
episodeNumber = getIntegerContent("epnum", node);
|
episodeNumber = getIntegerContent("epnum", node);
|
||||||
seasonNumber = null;
|
seasonNumber = null;
|
||||||
order = SortOrder.Absolute;
|
|
||||||
}
|
}
|
||||||
|
episodes.add(new Episode(seriesInfo.getName(), seasonNumber, episodeNumber, title, null, null, airdate, new SeriesInfo(seriesInfo)));
|
||||||
episodes.add(new Episode(seriesName, seriesStartDate, seasonNumber, episodeNumber, title, null, null, order, language, airdate, searchResult));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add specials at the end
|
// add specials at the end
|
||||||
episodes.addAll(specials);
|
episodes.addAll(specials);
|
||||||
|
|
||||||
return episodes;
|
return new SeriesData(seriesInfo, episodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Document request(String resource, Map<String, Object> parameters) throws IOException, SAXException {
|
public Document request(String resource, Map<String, Object> parameters) throws IOException, SAXException {
|
||||||
|
@ -121,6 +142,11 @@ public class TVRageClient extends AbstractEpisodeListProvider {
|
||||||
return getDocument(url);
|
return getDocument(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SearchResult createSearchResult(int id) {
|
||||||
|
return new TVRageSearchResult(null, id, null);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public URI getEpisodeListLink(SearchResult searchResult) {
|
public URI getEpisodeListLink(SearchResult searchResult) {
|
||||||
return URI.create(((TVRageSearchResult) searchResult).getLink() + "/episode_list/all");
|
return URI.create(((TVRageSearchResult) searchResult).getLink() + "/episode_list/all");
|
||||||
|
|
|
@ -29,7 +29,6 @@ import net.filebot.Cache;
|
||||||
import net.filebot.ResourceManager;
|
import net.filebot.ResourceManager;
|
||||||
import net.filebot.util.FileUtilities;
|
import net.filebot.util.FileUtilities;
|
||||||
import net.filebot.web.TheTVDBClient.BannerDescriptor.BannerProperty;
|
import net.filebot.web.TheTVDBClient.BannerDescriptor.BannerProperty;
|
||||||
import net.filebot.web.TheTVDBClient.SeriesInfo.SeriesProperty;
|
|
||||||
|
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
|
@ -60,13 +59,23 @@ public class TheTVDBClient extends AbstractEpisodeListProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasSingleSeasonSupport() {
|
public boolean hasSeasonSupport() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasLocaleSupport() {
|
protected SortOrder vetoRequestParameter(SortOrder order) {
|
||||||
return true;
|
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) {
|
public String getLanguageCode(Locale locale) {
|
||||||
|
@ -85,11 +94,6 @@ public class TheTVDBClient extends AbstractEpisodeListProvider {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResultCache getCache() {
|
|
||||||
return new ResultCache(host, Cache.getCache("web-datasource"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<SearchResult> fetchSearchResult(String query, Locale locale) throws Exception {
|
public List<SearchResult> fetchSearchResult(String query, Locale locale) throws Exception {
|
||||||
// perform online search
|
// perform online search
|
||||||
|
@ -120,14 +124,36 @@ public class TheTVDBClient extends AbstractEpisodeListProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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;
|
TheTVDBSearchResult series = (TheTVDBSearchResult) searchResult;
|
||||||
Document dom = getXmlResource(MirrorType.XML, "/api/" + apikey + "/series/" + series.getSeriesId() + "/all/" + getLanguageCode(locale) + ".xml");
|
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
|
// parse series info
|
||||||
String seriesName = selectString("Data/Series/SeriesName", dom);
|
Node seriesNode = selectNode("Data/Series", dom);
|
||||||
SimpleDate seriesStartDate = SimpleDate.parse(selectString("Data/Series/FirstAired", dom), "yyyy-MM-dd");
|
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<Node> nodes = selectNodes("Data/Episode", dom);
|
||||||
|
|
||||||
List<Episode> episodes = new ArrayList<Episode>(nodes.size());
|
List<Episode> episodes = new ArrayList<Episode>(nodes.size());
|
||||||
|
@ -143,7 +169,6 @@ public class TheTVDBClient extends AbstractEpisodeListProvider {
|
||||||
// default numbering
|
// default numbering
|
||||||
Integer episodeNumber = getIntegerContent("EpisodeNumber", node);
|
Integer episodeNumber = getIntegerContent("EpisodeNumber", node);
|
||||||
Integer seasonNumber = getIntegerContent("SeasonNumber", node);
|
Integer seasonNumber = getIntegerContent("SeasonNumber", node);
|
||||||
SortOrder order = SortOrder.Airdate;
|
|
||||||
|
|
||||||
if (seasonNumber == null || seasonNumber == 0) {
|
if (seasonNumber == null || seasonNumber == 0) {
|
||||||
// handle as special episode
|
// 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
|
// use given episode number as special number or count specials by ourselves
|
||||||
Integer specialNumber = (episodeNumber != null) ? episodeNumber : filterBySeason(specials, seasonNumber).size() + 1;
|
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 {
|
} else {
|
||||||
// handle as normal episode
|
// handle as normal episode
|
||||||
if (sortOrder == SortOrder.Absolute) {
|
if (sortOrder == SortOrder.Absolute) {
|
||||||
if (absoluteNumber != null) {
|
if (absoluteNumber != null) {
|
||||||
episodeNumber = absoluteNumber;
|
episodeNumber = absoluteNumber;
|
||||||
seasonNumber = null;
|
seasonNumber = null;
|
||||||
order = SortOrder.Absolute;
|
|
||||||
}
|
}
|
||||||
} else if (sortOrder == SortOrder.DVD) {
|
} else if (sortOrder == SortOrder.DVD) {
|
||||||
try {
|
try {
|
||||||
|
@ -171,13 +195,12 @@ public class TheTVDBClient extends AbstractEpisodeListProvider {
|
||||||
// require both values to be successfully read
|
// require both values to be successfully read
|
||||||
episodeNumber = eno;
|
episodeNumber = eno;
|
||||||
seasonNumber = sno;
|
seasonNumber = sno;
|
||||||
order = SortOrder.DVD;
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// ignore, fallback to default numbering
|
// 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
|
// add specials at the end
|
||||||
episodes.addAll(specials);
|
episodes.addAll(specials);
|
||||||
|
|
||||||
return episodes;
|
return new SeriesData(seriesInfo, episodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TheTVDBSearchResult lookupByID(int id, Locale locale) throws Exception {
|
public TheTVDBSearchResult lookupByID(int id, Locale locale) throws Exception {
|
||||||
|
@ -227,11 +250,6 @@ public class TheTVDBClient extends AbstractEpisodeListProvider {
|
||||||
return series;
|
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 {
|
protected String getMirror(MirrorType mirrorType) throws IOException {
|
||||||
synchronized (mirrors) {
|
synchronized (mirrors) {
|
||||||
if (mirrors.isEmpty()) {
|
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 {
|
public SeriesInfo getSeriesInfoByIMDbID(int imdbid, Locale locale) throws Exception {
|
||||||
return getSeriesInfo(lookupByIMDbID(imdbid, locale), locale);
|
return getSeriesInfo(lookupByIMDbID(imdbid, locale), locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SeriesInfo getSeriesInfoByName(String name, Locale locale) throws Exception {
|
@Override
|
||||||
for (SearchResult it : search(name, locale)) {
|
protected SearchResult createSearchResult(int id) {
|
||||||
if (name.equalsIgnoreCase(it.getName())) {
|
return new TheTVDBSearchResult(null, id);
|
||||||
return getSeriesInfo((TheTVDBSearchResult) it, locale);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public SeriesInfo getSeriesInfo(TheTVDBSearchResult searchResult, Locale locale) throws Exception {
|
@Override
|
||||||
// check cache first
|
public URI getEpisodeListLink(SearchResult searchResult) {
|
||||||
SeriesInfo cachedItem = getCache().getData("seriesInfo", searchResult.seriesId, locale, SeriesInfo.class);
|
return URI.create("http://" + host + "/?tab=seasonall&id=" + ((TheTVDBSearchResult) searchResult).getSeriesId());
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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 java.util.List;
|
||||||
|
|
||||||
import net.filebot.web.Episode;
|
import net.filebot.web.Episode;
|
||||||
import net.filebot.web.SimpleDate;
|
|
||||||
import net.filebot.web.TheTVDBSearchResult;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@ -17,7 +15,7 @@ public class EpisodeMetricsTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void substringMetrics() {
|
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");
|
// 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 fY1T1 = new File("Doctor Who (2005)/Doctor Who - 1x01 - Rose");
|
||||||
File fY2T2 = new File("Doctor Who (1963)/Doctor Who - 1x01 - An Unearthly Child");
|
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("Greek/Greek - S01E19 - No Campus for Old Rules"));
|
||||||
files.add(new File("Veronica Mars - Season 1/Veronica Mars [1x19] Hot Dogs"));
|
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("Veronica Mars", 1, 19, "Hot Dogs"));
|
||||||
episodes.add(new Episode("Greek", null, 1, 19, "No Campus for Old Rules", new TheTVDBSearchResult("Greek", -1)));
|
episodes.add(new Episode("Greek", 1, 19, "No Campus for Old Rules"));
|
||||||
|
|
||||||
SimilarityMetric[] metrics = new SimilarityMetric[] { EpisodeIdentifier, SubstringFields };
|
SimilarityMetric[] metrics = new SimilarityMetric[] { EpisodeIdentifier, SubstringFields };
|
||||||
List<Match<File, Episode>> m = new Matcher<File, Episode>(files, episodes, true, metrics).match();
|
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).getValue().getName());
|
||||||
assertEquals("Veronica Mars - 1x19 - Hot Dogs", m.get(1).getCandidate().toString());
|
assertEquals("Veronica Mars - 1x19 - Hot Dogs", m.get(1).getCandidate().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ public class AnidbClientTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void search() throws Exception {
|
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);
|
AnidbSearchResult result = (AnidbSearchResult) results.get(0);
|
||||||
assertEquals("One Piece", result.getName());
|
assertEquals("One Piece", result.getName());
|
||||||
|
@ -54,7 +54,7 @@ public class AnidbClientTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void searchNoMatch() throws Exception {
|
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());
|
assertTrue(results.isEmpty());
|
||||||
}
|
}
|
||||||
|
@ -62,23 +62,23 @@ public class AnidbClientTest {
|
||||||
@Test
|
@Test
|
||||||
public void searchTitleAlias() throws Exception {
|
public void searchTitleAlias() throws Exception {
|
||||||
// Seikai no Senki (main title), Banner of the Stars (official English title)
|
// 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("banner of the stars", Locale.ENGLISH).get(0).getName());
|
||||||
assertEquals("Seikai no Senki", anidb.search("seikai no senki").get(0).getName());
|
assertEquals("Seikai no Senki", anidb.search("seikai no senki", Locale.ENGLISH).get(0).getName());
|
||||||
|
|
||||||
// no matching title
|
// no matching title
|
||||||
assertEquals("Naruto", anidb.search("naruto").get(0).getName());
|
assertEquals("Naruto", anidb.search("naruto", Locale.ENGLISH).get(0).getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getEpisodeListAll() throws Exception {
|
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());
|
assertEquals(77, list.size());
|
||||||
|
|
||||||
Episode first = list.get(0);
|
Episode first = list.get(0);
|
||||||
|
|
||||||
assertEquals("Monster", first.getSeriesName());
|
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("Herr Dr. Tenma", first.getTitle());
|
||||||
assertEquals("1", first.getEpisode().toString());
|
assertEquals("1", first.getEpisode().toString());
|
||||||
assertEquals("1", first.getAbsolute().toString());
|
assertEquals("1", first.getAbsolute().toString());
|
||||||
|
@ -88,14 +88,14 @@ public class AnidbClientTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getEpisodeListAllShortLink() throws Exception {
|
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());
|
assertEquals(46, list.size());
|
||||||
|
|
||||||
Episode first = list.get(0);
|
Episode first = list.get(0);
|
||||||
|
|
||||||
assertEquals("The Twelve Kingdoms", first.getSeriesName());
|
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("Shadow of the Moon, The Sea of Shadow - Chapter 1", first.getTitle());
|
||||||
assertEquals("1", first.getEpisode().toString());
|
assertEquals("1", first.getEpisode().toString());
|
||||||
assertEquals("1", first.getAbsolute().toString());
|
assertEquals("1", first.getAbsolute().toString());
|
||||||
|
@ -105,7 +105,7 @@ public class AnidbClientTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getEpisodeListEncoding() throws Exception {
|
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
|
@Test
|
||||||
|
@ -114,7 +114,7 @@ public class AnidbClientTest {
|
||||||
|
|
||||||
Episode last = list.get(73);
|
Episode last = list.get(73);
|
||||||
assertEquals("モンスター", last.getSeriesName());
|
assertEquals("モンスター", last.getSeriesName());
|
||||||
assertEquals("2004-04-07", last.getSeriesStartDate().toString());
|
assertEquals("2004-04-07", last.getSeriesInfo().getStartDate().toString());
|
||||||
assertEquals("本当の怪物", last.getTitle());
|
assertEquals("本当の怪物", last.getTitle());
|
||||||
assertEquals("74", last.getEpisode().toString());
|
assertEquals("74", last.getEpisode().toString());
|
||||||
assertEquals("74", last.getAbsolute().toString());
|
assertEquals("74", last.getAbsolute().toString());
|
||||||
|
@ -124,7 +124,7 @@ public class AnidbClientTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getEpisodeListTrimRecap() throws Exception {
|
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
|
@Test
|
||||||
|
|
|
@ -3,6 +3,7 @@ package net.filebot.web;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@ -15,7 +16,7 @@ public class TVRageClientTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void search() throws Exception {
|
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);
|
TVRageSearchResult result = (TVRageSearchResult) results.get(0);
|
||||||
|
|
||||||
|
@ -28,14 +29,14 @@ public class TVRageClientTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getEpisodeList() throws Exception {
|
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());
|
assertEquals(22, list.size());
|
||||||
|
|
||||||
Episode chosen = list.get(21);
|
Episode chosen = list.get(21);
|
||||||
|
|
||||||
assertEquals("Buffy the Vampire Slayer", chosen.getSeriesName());
|
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("Chosen", chosen.getTitle());
|
||||||
assertEquals("22", chosen.getEpisode().toString());
|
assertEquals("22", chosen.getEpisode().toString());
|
||||||
assertEquals("7", chosen.getSeason().toString());
|
assertEquals("7", chosen.getSeason().toString());
|
||||||
|
@ -45,7 +46,7 @@ public class TVRageClientTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getEpisodeListAll() throws Exception {
|
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());
|
assertEquals(143, list.size());
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
|
|
||||||
package net.filebot.web;
|
package net.filebot.web;
|
||||||
|
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
|
@ -12,62 +10,57 @@ import java.util.Map;
|
||||||
|
|
||||||
import net.filebot.web.TheTVDBClient.BannerDescriptor;
|
import net.filebot.web.TheTVDBClient.BannerDescriptor;
|
||||||
import net.filebot.web.TheTVDBClient.MirrorType;
|
import net.filebot.web.TheTVDBClient.MirrorType;
|
||||||
import net.filebot.web.TheTVDBClient.SeriesInfo;
|
|
||||||
import net.sf.ehcache.CacheManager;
|
import net.sf.ehcache.CacheManager;
|
||||||
|
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
|
||||||
public class TheTVDBClientTest {
|
public class TheTVDBClientTest {
|
||||||
|
|
||||||
private TheTVDBClient thetvdb = new TheTVDBClient("BA864DEE427E384A");
|
private TheTVDBClient thetvdb = new TheTVDBClient("BA864DEE427E384A");
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void search() throws Exception {
|
public void search() throws Exception {
|
||||||
// test default language and query escaping (blanks)
|
// 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());
|
assertEquals(2, results.size());
|
||||||
|
|
||||||
TheTVDBSearchResult first = (TheTVDBSearchResult) results.get(0);
|
TheTVDBSearchResult first = (TheTVDBSearchResult) results.get(0);
|
||||||
|
|
||||||
assertEquals("Babylon 5", first.getName());
|
assertEquals("Babylon 5", first.getName());
|
||||||
assertEquals(70726, first.getSeriesId());
|
assertEquals(70726, first.getSeriesId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void searchGerman() throws Exception {
|
public void searchGerman() throws Exception {
|
||||||
List<SearchResult> results = thetvdb.search("Buffy the Vampire Slayer", Locale.GERMAN);
|
List<SearchResult> results = thetvdb.search("Buffy the Vampire Slayer", Locale.GERMAN);
|
||||||
|
|
||||||
assertEquals(2, results.size());
|
assertEquals(2, results.size());
|
||||||
|
|
||||||
TheTVDBSearchResult first = (TheTVDBSearchResult) results.get(0);
|
TheTVDBSearchResult first = (TheTVDBSearchResult) results.get(0);
|
||||||
|
|
||||||
assertEquals("Buffy the Vampire Slayer", first.getName());
|
assertEquals("Buffy the Vampire Slayer", first.getName());
|
||||||
assertEquals(70327, first.getSeriesId());
|
assertEquals(70327, first.getSeriesId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getEpisodeListAll() throws Exception {
|
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);
|
assertTrue(list.size() >= 144);
|
||||||
|
|
||||||
// check ordinary episode
|
// check ordinary episode
|
||||||
Episode first = list.get(0);
|
Episode first = list.get(0);
|
||||||
assertEquals("Buffy the Vampire Slayer", first.getSeriesName());
|
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("Welcome to the Hellmouth (1)", first.getTitle());
|
||||||
assertEquals("1", first.getEpisode().toString());
|
assertEquals("1", first.getEpisode().toString());
|
||||||
assertEquals("1", first.getSeason().toString());
|
assertEquals("1", first.getSeason().toString());
|
||||||
assertEquals("1", first.getAbsolute().toString());
|
assertEquals("1", first.getAbsolute().toString());
|
||||||
assertEquals("1997-03-10", first.getAirdate().toString());
|
assertEquals("1997-03-10", first.getAirdate().toString());
|
||||||
|
|
||||||
// check special episode
|
// check special episode
|
||||||
Episode last = list.get(list.size() - 1);
|
Episode last = list.get(list.size() - 1);
|
||||||
assertEquals("Buffy the Vampire Slayer", last.getSeriesName());
|
assertEquals("Buffy the Vampire Slayer", last.getSeriesName());
|
||||||
|
@ -78,98 +71,89 @@ public class TheTVDBClientTest {
|
||||||
assertEquals("1", last.getSpecial().toString());
|
assertEquals("1", last.getSpecial().toString());
|
||||||
assertEquals(null, last.getAirdate());
|
assertEquals(null, last.getAirdate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getEpisodeListSingleSeason() throws Exception {
|
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);
|
Episode first = list.get(0);
|
||||||
|
|
||||||
assertEquals("Wonderfalls", first.getSeriesName());
|
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("Wax Lion", first.getTitle());
|
||||||
assertEquals("1", first.getEpisode().toString());
|
assertEquals("1", first.getEpisode().toString());
|
||||||
assertEquals("1", first.getSeason().toString());
|
assertEquals("1", first.getSeason().toString());
|
||||||
assertEquals(null, first.getAbsolute()); // should be "1" but data has not yet been entered
|
assertEquals(null, first.getAbsolute()); // should be "1" but data has not yet been entered
|
||||||
assertEquals("2004-03-12", first.getAirdate().toString());
|
assertEquals("2004-03-12", first.getAirdate().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getEpisodeListNumbering() throws Exception {
|
public void getEpisodeListNumbering() throws Exception {
|
||||||
List<Episode> list = thetvdb.getEpisodeList(new TheTVDBSearchResult("Firefly", 78874), SortOrder.DVD, Locale.ENGLISH);
|
List<Episode> list = thetvdb.getEpisodeList(new TheTVDBSearchResult("Firefly", 78874), SortOrder.DVD, Locale.ENGLISH);
|
||||||
|
|
||||||
Episode first = list.get(0);
|
Episode first = list.get(0);
|
||||||
assertEquals("Firefly", first.getSeriesName());
|
assertEquals("Firefly", first.getSeriesName());
|
||||||
assertEquals("2002-09-20", first.getSeriesStartDate().toString());
|
assertEquals("2002-09-20", first.getSeriesInfo().getStartDate().toString());
|
||||||
assertEquals("Serenity", first.getTitle());
|
assertEquals("Serenity", first.getTitle());
|
||||||
assertEquals("1", first.getEpisode().toString());
|
assertEquals("1", first.getEpisode().toString());
|
||||||
assertEquals("1", first.getSeason().toString());
|
assertEquals("1", first.getSeason().toString());
|
||||||
assertEquals("1", first.getAbsolute().toString());
|
assertEquals("1", first.getAbsolute().toString());
|
||||||
assertEquals("2002-12-20", first.getAirdate().toString());
|
assertEquals("2002-12-20", first.getAirdate().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getEpisodeListLink() {
|
public void getEpisodeListLink() {
|
||||||
assertEquals("http://www.thetvdb.com/?tab=seasonall&id=78874", thetvdb.getEpisodeListLink(new TheTVDBSearchResult("Firefly", 78874)).toString());
|
assertEquals("http://www.thetvdb.com/?tab=seasonall&id=78874", thetvdb.getEpisodeListLink(new TheTVDBSearchResult("Firefly", 78874)).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getMirror() throws Exception {
|
public void getMirror() throws Exception {
|
||||||
assertNotNull(thetvdb.getMirror(MirrorType.XML));
|
assertNotNull(thetvdb.getMirror(MirrorType.XML));
|
||||||
assertNotNull(thetvdb.getMirror(MirrorType.BANNER));
|
assertNotNull(thetvdb.getMirror(MirrorType.BANNER));
|
||||||
assertNotNull(thetvdb.getMirror(MirrorType.ZIP));
|
assertNotNull(thetvdb.getMirror(MirrorType.ZIP));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void resolveTypeMask() {
|
public void resolveTypeMask() {
|
||||||
// no flags set
|
// no flags set
|
||||||
assertEquals(EnumSet.noneOf(MirrorType.class), MirrorType.fromTypeMask(0));
|
assertEquals(EnumSet.noneOf(MirrorType.class), MirrorType.fromTypeMask(0));
|
||||||
|
|
||||||
// xml and zip flags set
|
// xml and zip flags set
|
||||||
assertEquals(EnumSet.of(MirrorType.ZIP, MirrorType.XML, MirrorType.SEARCH), MirrorType.fromTypeMask(5));
|
assertEquals(EnumSet.of(MirrorType.ZIP, MirrorType.XML, MirrorType.SEARCH), MirrorType.fromTypeMask(5));
|
||||||
|
|
||||||
// all flags set
|
// all flags set
|
||||||
assertEquals(EnumSet.allOf(MirrorType.class), MirrorType.fromTypeMask(7));
|
assertEquals(EnumSet.allOf(MirrorType.class), MirrorType.fromTypeMask(7));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void lookupByID() throws Exception {
|
public void lookupByID() throws Exception {
|
||||||
TheTVDBSearchResult series = thetvdb.lookupByID(78874, Locale.ENGLISH);
|
TheTVDBSearchResult series = thetvdb.lookupByID(78874, Locale.ENGLISH);
|
||||||
assertEquals("Firefly", series.getName());
|
assertEquals("Firefly", series.getName());
|
||||||
assertEquals(78874, series.getSeriesId());
|
assertEquals(78874, series.getSeriesId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void lookupByIMDbID() throws Exception {
|
public void lookupByIMDbID() throws Exception {
|
||||||
TheTVDBSearchResult series = thetvdb.lookupByIMDbID(303461, Locale.ENGLISH);
|
TheTVDBSearchResult series = thetvdb.lookupByIMDbID(303461, Locale.ENGLISH);
|
||||||
assertEquals("Firefly", series.getName());
|
assertEquals("Firefly", series.getName());
|
||||||
assertEquals(78874, series.getSeriesId());
|
assertEquals(78874, series.getSeriesId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getSeriesInfo() throws Exception {
|
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(80348, it.getId(), 0);
|
||||||
assertEquals("TV-PG", it.getContentRating());
|
assertEquals("TV-PG", it.getContentRating());
|
||||||
assertEquals("2007-09-24", it.getFirstAired().toString());
|
assertEquals("2007-09-24", it.getFirstAired().toString());
|
||||||
assertEquals("Action", it.getGenres().get(0));
|
assertEquals("Action", it.getGenres().get(0));
|
||||||
assertEquals(934814, it.getImdbId(), 0);
|
assertEquals("tt0934814", it.getImdbId());
|
||||||
assertEquals("English", it.getLanguage().getDisplayLanguage(Locale.ENGLISH));
|
assertEquals("English", it.getLanguage());
|
||||||
assertEquals(310, it.getOverview().length());
|
assertEquals(310, it.getOverview().length());
|
||||||
assertEquals("60", it.getRuntime());
|
assertEquals("60", it.getRuntime());
|
||||||
assertEquals("Chuck", it.getName());
|
assertEquals("Chuck", it.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getBanner() throws Exception {
|
public void getBanner() throws Exception {
|
||||||
Map<String, String> filter = new HashMap<String, String>();
|
Map<String, String> filter = new HashMap<String, String>();
|
||||||
|
@ -177,31 +161,29 @@ public class TheTVDBClientTest {
|
||||||
filter.put("BannerType2", "seasonwide");
|
filter.put("BannerType2", "seasonwide");
|
||||||
filter.put("Season", "7");
|
filter.put("Season", "7");
|
||||||
filter.put("Language", "en");
|
filter.put("Language", "en");
|
||||||
|
|
||||||
BannerDescriptor banner = thetvdb.getBanner(new TheTVDBSearchResult("Buffy the Vampire Slayer", 70327), filter);
|
BannerDescriptor banner = thetvdb.getBanner(new TheTVDBSearchResult("Buffy the Vampire Slayer", 70327), filter);
|
||||||
|
|
||||||
assertEquals(857660, banner.getId(), 0);
|
assertEquals(857660, banner.getId(), 0);
|
||||||
assertEquals("season", banner.getBannerType());
|
assertEquals("season", banner.getBannerType());
|
||||||
assertEquals("seasonwide", banner.getBannerType2());
|
assertEquals("seasonwide", banner.getBannerType2());
|
||||||
assertEquals("http://thetvdb.com/banners/seasonswide/70327-7.jpg", banner.getUrl().toString());
|
assertEquals("http://thetvdb.com/banners/seasonswide/70327-7.jpg", banner.getUrl().toString());
|
||||||
assertEquals(99712, WebRequest.fetch(banner.getUrl()).remaining(), 0);
|
assertEquals(99712, WebRequest.fetch(banner.getUrl()).remaining(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getBannerList() throws Exception {
|
public void getBannerList() throws Exception {
|
||||||
List<BannerDescriptor> banners = thetvdb.getBannerList(new TheTVDBSearchResult("Buffy the Vampire Slayer", 70327));
|
List<BannerDescriptor> banners = thetvdb.getBannerList(new TheTVDBSearchResult("Buffy the Vampire Slayer", 70327));
|
||||||
|
|
||||||
assertEquals("fanart", banners.get(0).getBannerType());
|
assertEquals("fanart", banners.get(0).getBannerType());
|
||||||
assertEquals("1280x720", banners.get(0).getBannerType2());
|
assertEquals("1280x720", banners.get(0).getBannerType2());
|
||||||
assertEquals(486993, WebRequest.fetch(banners.get(0).getUrl()).remaining(), 0);
|
assertEquals(486993, WebRequest.fetch(banners.get(0).getUrl()).remaining(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
@AfterClass
|
@AfterClass
|
||||||
public static void clearCache() {
|
public static void clearCache() {
|
||||||
CacheManager.getInstance().clearAll();
|
CacheManager.getInstance().clearAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue