mirror of
https://github.com/mitb-archive/filebot
synced 2024-12-24 16:58:51 -05:00
+ add addtional metadata (order, language) to episode and movie objects
This commit is contained in:
parent
8e80a02498
commit
a5398cc5e1
@ -50,7 +50,6 @@ import net.filebot.web.MoviePart;
|
||||
import net.filebot.web.MultiEpisode;
|
||||
import net.filebot.web.SearchResult;
|
||||
import net.filebot.web.SimpleDate;
|
||||
import net.filebot.web.SortOrder;
|
||||
import net.filebot.web.TheTVDBSearchResult;
|
||||
|
||||
import com.cedarsoftware.util.io.JsonWriter;
|
||||
@ -556,14 +555,13 @@ public class MediaBindingBean {
|
||||
if (metaInfo == null) {
|
||||
try {
|
||||
if (infoObject instanceof Episode)
|
||||
metaInfo = WebServices.TheTVDB.getSeriesInfoByName(((Episode) infoObject).getSeriesName(), Locale.ENGLISH);
|
||||
metaInfo = WebServices.TheTVDB.getSeriesInfoByName(getEpisode().getSeriesName(), getEpisode().getLanguage());
|
||||
if (infoObject instanceof Movie)
|
||||
metaInfo = WebServices.TheMovieDB.getMovieInfo(getMovie(), Locale.ENGLISH, true);
|
||||
metaInfo = WebServices.TheMovieDB.getMovieInfo(getMovie(), getMovie().getLanguage(), true);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to retrieve metadata: " + infoObject, e);
|
||||
}
|
||||
}
|
||||
|
||||
return createMapBindings(new PropertyBindings(metaInfo, null));
|
||||
}
|
||||
|
||||
@ -588,7 +586,7 @@ public class MediaBindingBean {
|
||||
|
||||
@Define("episodelist")
|
||||
public Object getEpisodeList() throws Exception {
|
||||
return ((EpisodeListProvider) getDatabase()).getEpisodeList(getSeriesObject(), SortOrder.Airdate, Locale.ENGLISH);
|
||||
return ((EpisodeListProvider) getDatabase()).getEpisodeList(getSeriesObject(), getEpisode().getOrder(), getEpisode().getLanguage());
|
||||
}
|
||||
|
||||
@Define("database")
|
||||
|
@ -92,7 +92,7 @@ public class AnidbClient extends AbstractEpisodeListProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Episode> fetchEpisodeList(SearchResult searchResult, SortOrder sortOrder, Locale language) throws Exception {
|
||||
public List<Episode> fetchEpisodeList(SearchResult searchResult, SortOrder sortOrder, Locale locale) throws Exception {
|
||||
AnidbSearchResult anime = (AnidbSearchResult) searchResult;
|
||||
|
||||
// e.g. http://api.anidb.net:9001/httpapi?request=anime&client=filebot&clientver=1&protover=1&aid=4521
|
||||
@ -112,7 +112,7 @@ public class AnidbClient extends AbstractEpisodeListProvider {
|
||||
|
||||
// select main title and anime start date
|
||||
SimpleDate seriesStartDate = SimpleDate.parse(selectString("//startdate", dom), "yyyy-MM-dd");
|
||||
String animeTitle = selectString("//titles/title[@type='official' and @lang='" + language.getLanguage() + "']", dom);
|
||||
String animeTitle = selectString("//titles/title[@type='official' and @lang='" + locale.getLanguage() + "']", dom);
|
||||
if (animeTitle.isEmpty()) {
|
||||
animeTitle = selectString("//titles/title[@type='main']", dom);
|
||||
}
|
||||
@ -126,15 +126,15 @@ public class AnidbClient extends AbstractEpisodeListProvider {
|
||||
|
||||
if (type == 1 || type == 2) {
|
||||
SimpleDate airdate = SimpleDate.parse(getTextContent("airdate", node), "yyyy-MM-dd");
|
||||
String title = selectString(".//title[@lang='" + language.getLanguage() + "']", node);
|
||||
String title = selectString(".//title[@lang='" + locale.getLanguage() + "']", node);
|
||||
if (title.isEmpty()) { // English language fall-back
|
||||
title = selectString(".//title[@lang='en']", node);
|
||||
}
|
||||
|
||||
if (type == 1) {
|
||||
episodes.add(new Episode(animeTitle, seriesStartDate, null, number, title, number, null, airdate, searchResult)); // normal episode, no seasons for anime
|
||||
episodes.add(new Episode(animeTitle, seriesStartDate, null, number, title, number, null, SortOrder.Absolute, locale, airdate, searchResult)); // normal episode, no seasons for anime
|
||||
} else {
|
||||
episodes.add(new Episode(animeTitle, seriesStartDate, null, null, title, null, number, airdate, searchResult)); // special episode
|
||||
episodes.add(new Episode(animeTitle, seriesStartDate, null, null, title, null, number, SortOrder.Absolute, locale, airdate, searchResult)); // special episode
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,41 +3,46 @@ package net.filebot.web;
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class Episode implements Serializable {
|
||||
|
||||
private String seriesName;
|
||||
private SimpleDate seriesStartDate;
|
||||
protected String seriesName;
|
||||
protected SimpleDate seriesStartDate;
|
||||
|
||||
private Integer season;
|
||||
private Integer episode;
|
||||
private String title;
|
||||
protected Integer season;
|
||||
protected Integer episode;
|
||||
protected String title;
|
||||
|
||||
// absolute episode number
|
||||
private Integer absolute;
|
||||
protected Integer absolute;
|
||||
|
||||
// special number
|
||||
private Integer special;
|
||||
protected Integer special;
|
||||
|
||||
// optional episode number order hint & episode name / title language hint
|
||||
protected String order;
|
||||
protected String language;
|
||||
|
||||
// episode airdate
|
||||
private SimpleDate airdate;
|
||||
protected SimpleDate airdate;
|
||||
|
||||
// original series descriptor
|
||||
private SearchResult series;
|
||||
protected SearchResult series;
|
||||
|
||||
protected Episode() {
|
||||
// used by serializer
|
||||
}
|
||||
|
||||
public Episode(Episode obj) {
|
||||
this(obj.seriesName, obj.seriesStartDate, obj.season, obj.episode, obj.title, obj.absolute, obj.special, obj.airdate, obj.series);
|
||||
this(obj.seriesName, obj.seriesStartDate, obj.season, obj.episode, obj.title, obj.absolute, obj.special, obj.getOrder(), obj.getLanguage(), obj.airdate, obj.series);
|
||||
}
|
||||
|
||||
public Episode(String seriesName, SimpleDate seriesStartDate, Integer season, Integer episode, String title, SearchResult series) {
|
||||
this(seriesName, seriesStartDate, season, episode, title, null, null, null, series);
|
||||
this(seriesName, seriesStartDate, season, episode, title, null, null, null, null, null, series);
|
||||
}
|
||||
|
||||
public Episode(String seriesName, SimpleDate seriesStartDate, Integer season, Integer episode, String title, Integer absolute, Integer special, SimpleDate airdate, SearchResult series) {
|
||||
public Episode(String seriesName, SimpleDate seriesStartDate, Integer season, Integer episode, String title, Integer absolute, Integer special, SortOrder order, Locale locale, SimpleDate airdate, SearchResult series) {
|
||||
this.seriesName = seriesName;
|
||||
this.seriesStartDate = (seriesStartDate == null ? null : seriesStartDate.clone());
|
||||
this.season = season;
|
||||
@ -45,6 +50,8 @@ public class Episode implements Serializable {
|
||||
this.title = title;
|
||||
this.absolute = absolute;
|
||||
this.special = special;
|
||||
this.order = (order == null ? null : order.name());
|
||||
this.language = (locale == null ? null : locale.getLanguage());
|
||||
this.airdate = (airdate == null ? null : airdate.clone());
|
||||
this.series = (series == null ? null : series.clone());
|
||||
}
|
||||
@ -77,6 +84,14 @@ public class Episode implements Serializable {
|
||||
return special;
|
||||
}
|
||||
|
||||
public SortOrder getOrder() {
|
||||
return order == null ? null : SortOrder.forName(order);
|
||||
}
|
||||
|
||||
public Locale getLanguage() {
|
||||
return language == null ? null : new Locale(language);
|
||||
}
|
||||
|
||||
public SimpleDate getAirdate() {
|
||||
return airdate;
|
||||
}
|
||||
|
@ -187,7 +187,7 @@ public class EpisodeFormat extends Format {
|
||||
|
||||
// did parse input
|
||||
pos.setIndex(source.length());
|
||||
return new Episode(name, null, season, episode, title, season == null ? episode : null, special, airdate, null);
|
||||
return new Episode(name, null, season, episode, title, season == null ? episode : null, special, null, null, airdate, null);
|
||||
}
|
||||
|
||||
// failed to parse input
|
||||
|
@ -1,13 +1,10 @@
|
||||
|
||||
package net.filebot.web;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public final class EpisodeUtilities {
|
||||
|
||||
public static List<Episode> filterBySeason(Iterable<Episode> episodes, int season) {
|
||||
@ -23,7 +20,6 @@ public final class EpisodeUtilities {
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
public static int getLastSeason(Iterable<Episode> episodes) {
|
||||
int lastSeason = 0;
|
||||
|
||||
@ -37,12 +33,10 @@ public final class EpisodeUtilities {
|
||||
return lastSeason;
|
||||
}
|
||||
|
||||
|
||||
public static void sortEpisodes(List<Episode> episodes) {
|
||||
Collections.sort(episodes, episodeComparator());
|
||||
}
|
||||
|
||||
|
||||
public static Comparator<Episode> episodeComparator() {
|
||||
return new Comparator<Episode>() {
|
||||
|
||||
@ -67,7 +61,6 @@ public final class EpisodeUtilities {
|
||||
return compareValue(a.getTitle(), b.getTitle());
|
||||
}
|
||||
|
||||
|
||||
private <T> int compareValue(Comparable<T> o1, T o2) {
|
||||
if (o1 == null && o2 == null)
|
||||
return 0;
|
||||
@ -81,7 +74,6 @@ public final class EpisodeUtilities {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private EpisodeUtilities() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
public class Movie extends SearchResult {
|
||||
@ -12,19 +13,27 @@ public class Movie extends SearchResult {
|
||||
protected int imdbId;
|
||||
protected int tmdbId;
|
||||
|
||||
// optional movie name language hint
|
||||
protected String language;
|
||||
|
||||
protected Movie() {
|
||||
// used by serializer
|
||||
}
|
||||
|
||||
public Movie(String name, int year, int imdbId, int tmdbId) {
|
||||
this(name, new String[0], year, imdbId, tmdbId);
|
||||
public Movie(Movie obj) {
|
||||
this(obj.name, obj.aliasNames, obj.year, obj.imdbId, obj.tmdbId, obj.getLanguage());
|
||||
}
|
||||
|
||||
public Movie(String name, String[] aliasNames, int year, int imdbId, int tmdbId) {
|
||||
public Movie(String name, int year, int imdbId, int tmdbId) {
|
||||
this(name, new String[0], year, imdbId, tmdbId, null);
|
||||
}
|
||||
|
||||
public Movie(String name, String[] aliasNames, int year, int imdbId, int tmdbId, Locale locale) {
|
||||
super(name, aliasNames);
|
||||
this.year = year;
|
||||
this.imdbId = imdbId;
|
||||
this.tmdbId = tmdbId;
|
||||
this.language = (locale == null ? null : locale.getLanguage());
|
||||
}
|
||||
|
||||
public int getYear() {
|
||||
@ -39,6 +48,10 @@ public class Movie extends SearchResult {
|
||||
return tmdbId;
|
||||
}
|
||||
|
||||
public Locale getLanguage() {
|
||||
return language == null ? null : new Locale(language);
|
||||
}
|
||||
|
||||
public String getNameWithYear() {
|
||||
return toString(name, year);
|
||||
}
|
||||
@ -86,7 +99,7 @@ public class Movie extends SearchResult {
|
||||
|
||||
@Override
|
||||
public Movie clone() {
|
||||
return new Movie(name, aliasNames, year, imdbId, tmdbId);
|
||||
return new Movie(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,40 +1,28 @@
|
||||
|
||||
package net.filebot.web;
|
||||
|
||||
|
||||
public class MoviePart extends Movie {
|
||||
|
||||
protected final int partIndex;
|
||||
protected final int partCount;
|
||||
|
||||
|
||||
public MoviePart(MoviePart obj) {
|
||||
this(obj.name, obj.year, obj.imdbId, obj.tmdbId, obj.partIndex, obj.partCount);
|
||||
this(obj, obj.partIndex, obj.partCount);
|
||||
}
|
||||
|
||||
|
||||
public MoviePart(Movie movie, int partIndex, int partCount) {
|
||||
this(movie.name, movie.year, movie.imdbId, movie.tmdbId, partIndex, partCount);
|
||||
}
|
||||
|
||||
|
||||
public MoviePart(String name, int year, int imdbId, int tmdbId, int partIndex, int partCount) {
|
||||
super(name, year, imdbId, tmdbId);
|
||||
super(movie);
|
||||
this.partIndex = partIndex;
|
||||
this.partCount = partCount;
|
||||
}
|
||||
|
||||
|
||||
public int getPartIndex() {
|
||||
return partIndex;
|
||||
}
|
||||
|
||||
|
||||
public int getPartCount() {
|
||||
return partCount;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (object instanceof MoviePart && super.equals(object)) {
|
||||
@ -45,13 +33,11 @@ public class MoviePart extends Movie {
|
||||
return super.equals(object);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public MoviePart clone() {
|
||||
return new MoviePart(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s (%d) [%d]", name, year, partIndex);
|
||||
|
@ -141,7 +141,11 @@ public class SerienjunkiesClient extends AbstractEpisodeListProvider {
|
||||
title = "";
|
||||
}
|
||||
|
||||
episodes.add(new Episode(seriesName, series.getStartDate(), season, episode, title, i + 1, null, airdate, searchResult));
|
||||
// additional metadata
|
||||
SortOrder order = SortOrder.Airdate;
|
||||
Locale language = Locale.GERMAN.equals(locale) ? Locale.GERMAN : Locale.ENGLISH;
|
||||
|
||||
episodes.add(new Episode(seriesName, series.getStartDate(), season, episode, title, i + 1, null, order, language, airdate, searchResult));
|
||||
}
|
||||
|
||||
// make sure episodes are in ordered correctly
|
||||
|
@ -1,11 +1,8 @@
|
||||
|
||||
package net.filebot.web;
|
||||
|
||||
|
||||
public enum SortOrder {
|
||||
Airdate,
|
||||
DVD,
|
||||
Absolute;
|
||||
|
||||
Airdate, DVD, Absolute;
|
||||
|
||||
public static SortOrder forName(String name) {
|
||||
for (SortOrder order : SortOrder.values()) {
|
||||
@ -17,7 +14,6 @@ public enum SortOrder {
|
||||
throw new IllegalArgumentException("Invalid SortOrder: " + name);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s Order", name());
|
||||
|
@ -129,7 +129,7 @@ public class TMDbClient implements MovieIdentificationService {
|
||||
// make sure main title is not in the set of alternative titles
|
||||
alternativeTitles.remove(title);
|
||||
|
||||
result.add(new Movie(title, alternativeTitles.toArray(new String[0]), year, -1, id));
|
||||
result.add(new Movie(title, alternativeTitles.toArray(new String[0]), year, -1, id, locale));
|
||||
} catch (Exception e) {
|
||||
// only print 'missing release date' warnings for matching movie titles
|
||||
if (query.equalsIgnoreCase(title) || query.equalsIgnoreCase(originalTitle)) {
|
||||
@ -157,7 +157,7 @@ public class TMDbClient implements MovieIdentificationService {
|
||||
String id = byIMDB ? String.format("tt%07d", imdbtmdbid) : String.valueOf(imdbtmdbid);
|
||||
try {
|
||||
MovieInfo info = getMovieInfo(id, locale, false, false);
|
||||
return new Movie(info.getName(), info.getReleased().getYear(), info.getImdbId(), info.getId());
|
||||
return new Movie(info.getName(), new String[0], info.getReleased().getYear(), info.getImdbId(), info.getId(), locale);
|
||||
} catch (FileNotFoundException e) {
|
||||
Logger.getLogger(getClass().getName()).log(Level.WARNING, "Movie not found: " + id);
|
||||
return null;
|
||||
|
@ -1,7 +1,5 @@
|
||||
|
||||
package net.filebot.web;
|
||||
|
||||
|
||||
import static net.filebot.util.XPathUtilities.*;
|
||||
import static net.filebot.web.EpisodeUtilities.*;
|
||||
import static net.filebot.web.WebRequest.*;
|
||||
@ -22,30 +20,25 @@ import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
|
||||
public class TVRageClient extends AbstractEpisodeListProvider {
|
||||
|
||||
private final String host = "services.tvrage.com";
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "TVRage";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
return ResourceManager.getIcon("search.tvrage");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ResultCache getCache() {
|
||||
return new ResultCache(host, Cache.getCache("web-datasource"));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<SearchResult> fetchSearchResult(String query, Locale locale) throws IOException, SAXException {
|
||||
URL searchUrl = new URL("http", host, "/feeds/full_search.php?show=" + encode(query, true));
|
||||
@ -65,7 +58,6 @@ public class TVRageClient extends AbstractEpisodeListProvider {
|
||||
return searchResults;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<Episode> fetchEpisodeList(SearchResult searchResult, SortOrder sortOrder, Locale locale) throws IOException, SAXException {
|
||||
TVRageSearchResult series = (TVRageSearchResult) searchResult;
|
||||
@ -75,6 +67,7 @@ public class TVRageClient extends AbstractEpisodeListProvider {
|
||||
|
||||
String seriesName = selectString("Show/name", dom);
|
||||
SimpleDate seriesStartDate = SimpleDate.parse(selectString("Show/started", dom), "MMM/dd/yyyy");
|
||||
Locale language = Locale.ENGLISH;
|
||||
|
||||
List<Episode> episodes = new ArrayList<Episode>(25);
|
||||
List<Episode> specials = new ArrayList<Episode>(5);
|
||||
@ -87,20 +80,23 @@ public class TVRageClient extends AbstractEpisodeListProvider {
|
||||
Integer seasonNumber = seasonIdentifier == null ? null : new Integer(seasonIdentifier);
|
||||
SimpleDate airdate = SimpleDate.parse(getTextContent("airdate", node), "yyyy-MM-dd");
|
||||
|
||||
SortOrder order = SortOrder.Airdate; // default order
|
||||
|
||||
// check if we have season and episode number, if not it must be a special episode
|
||||
if (episodeNumber == null || seasonNumber == null) {
|
||||
// handle as special episode
|
||||
seasonNumber = getIntegerContent("season", node);
|
||||
int specialNumber = filterBySeason(specials, seasonNumber).size() + 1;
|
||||
specials.add(new Episode(seriesName, seriesStartDate, seasonNumber, null, title, null, specialNumber, airdate, searchResult));
|
||||
specials.add(new Episode(seriesName, seriesStartDate, seasonNumber, null, title, null, specialNumber, order, language, airdate, searchResult));
|
||||
} else {
|
||||
// handle as normal episode
|
||||
if (sortOrder == SortOrder.Absolute) {
|
||||
episodeNumber = getIntegerContent("epnum", node);
|
||||
seasonNumber = null;
|
||||
order = SortOrder.Absolute;
|
||||
}
|
||||
|
||||
episodes.add(new Episode(seriesName, seriesStartDate, seasonNumber, episodeNumber, title, null, null, airdate, searchResult));
|
||||
episodes.add(new Episode(seriesName, seriesStartDate, seasonNumber, episodeNumber, title, null, null, order, language, airdate, searchResult));
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,7 +106,6 @@ public class TVRageClient extends AbstractEpisodeListProvider {
|
||||
return episodes;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public URI getEpisodeListLink(SearchResult searchResult) {
|
||||
return URI.create(((TVRageSearchResult) searchResult).getLink() + "/episode_list/all");
|
||||
|
@ -139,6 +139,7 @@ public class TheTVDBClient extends AbstractEpisodeListProvider {
|
||||
// default numbering
|
||||
Integer episodeNumber = getIntegerContent("EpisodeNumber", node);
|
||||
Integer seasonNumber = getIntegerContent("SeasonNumber", node);
|
||||
SortOrder order = SortOrder.Airdate;
|
||||
|
||||
if (seasonNumber == null || seasonNumber == 0) {
|
||||
// handle as special episode
|
||||
@ -149,24 +150,30 @@ public class TheTVDBClient extends AbstractEpisodeListProvider {
|
||||
|
||||
// use given episode number as special number or count specials by ourselves
|
||||
Integer specialNumber = (episodeNumber != null) ? episodeNumber : filterBySeason(specials, seasonNumber).size() + 1;
|
||||
specials.add(new Episode(seriesName, seriesStartDate, seasonNumber, null, episodeName, null, specialNumber, airdate, searchResult));
|
||||
specials.add(new Episode(seriesName, seriesStartDate, seasonNumber, null, episodeName, null, specialNumber, order, locale, airdate, searchResult));
|
||||
} else {
|
||||
// handle as normal episode
|
||||
if (sortOrder == SortOrder.Absolute) {
|
||||
if (absoluteNumber != null) {
|
||||
episodeNumber = absoluteNumber;
|
||||
seasonNumber = null;
|
||||
order = SortOrder.Absolute;
|
||||
}
|
||||
} else if (sortOrder == SortOrder.DVD) {
|
||||
try {
|
||||
episodeNumber = new Float(dvdEpisodeNumber).intValue();
|
||||
seasonNumber = new Integer(dvdSeasonNumber);
|
||||
int eno = new Float(dvdEpisodeNumber).intValue();
|
||||
int sno = new Float(dvdSeasonNumber).intValue();
|
||||
|
||||
// require both values to be successfully read
|
||||
episodeNumber = eno;
|
||||
seasonNumber = sno;
|
||||
order = SortOrder.DVD;
|
||||
} catch (Exception e) {
|
||||
// ignore, fallback to default numbering
|
||||
}
|
||||
}
|
||||
|
||||
episodes.add(new Episode(seriesName, seriesStartDate, seasonNumber, episodeNumber, episodeName, absoluteNumber, null, airdate, searchResult));
|
||||
episodes.add(new Episode(seriesName, seriesStartDate, seasonNumber, episodeNumber, episodeName, absoluteNumber, null, order, locale, airdate, searchResult));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user