Refactor info.* bindings

This commit is contained in:
Reinhard Pointner 2016-10-31 02:06:15 +08:00
parent 7fe54cbb92
commit 9e98b2e106
4 changed files with 175 additions and 177 deletions

View File

@ -36,6 +36,7 @@ import net.filebot.web.SubtitleSearchResult;
import net.filebot.web.TMDbClient; import net.filebot.web.TMDbClient;
import net.filebot.web.TMDbTVClient; import net.filebot.web.TMDbTVClient;
import net.filebot.web.TVMazeClient; import net.filebot.web.TVMazeClient;
import net.filebot.web.TheTVDBClient;
import net.filebot.web.TheTVDBClientV1; import net.filebot.web.TheTVDBClientV1;
import net.filebot.web.VideoHashSubtitleService; import net.filebot.web.VideoHashSubtitleService;
import one.util.streamex.StreamEx; import one.util.streamex.StreamEx;
@ -57,6 +58,9 @@ public final class WebServices {
public static final TheTVDBClientWithLocalSearch TheTVDB = new TheTVDBClientWithLocalSearch(getApiKey("thetvdb")); public static final TheTVDBClientWithLocalSearch TheTVDB = new TheTVDBClientWithLocalSearch(getApiKey("thetvdb"));
public static final TMDbTVClient TheMovieDB_TV = new TMDbTVClient(TheMovieDB); public static final TMDbTVClient TheMovieDB_TV = new TMDbTVClient(TheMovieDB);
// TheTVDB v2 implementation used for internal purposes and testing
public static final TheTVDBClient TheTVDBv2 = new TheTVDBClient(getApiKey("thetvdb"));
// subtitle sources // subtitle sources
public static final OpenSubtitlesClient OpenSubtitles = new OpenSubtitlesClientWithLocalSearch(getApiKey("opensubtitles"), getApplicationVersion()); public static final OpenSubtitlesClient OpenSubtitles = new OpenSubtitlesClientWithLocalSearch(getApiKey("opensubtitles"), getApplicationVersion());
public static final ShooterSubtitles Shooter = new ShooterSubtitles(); public static final ShooterSubtitles Shooter = new ShooterSubtitles();

View File

@ -1,29 +1,29 @@
package net.filebot.format; package net.filebot.format;
import java.util.Arrays; import java.util.Collection;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Stream; import java.util.function.Supplier;
import groovy.lang.GroovyObjectSupport; import groovy.lang.GroovyObjectSupport;
public class DynamicBindings extends GroovyObjectSupport { public class DynamicBindings extends GroovyObjectSupport {
private Function<String, Object> map; private Supplier<Collection<?>> keys;
private String[] keys; private Function<String, Object> properties;
public DynamicBindings(Function<String, Object> map, Stream<String> keys) { public DynamicBindings(Supplier<Collection<?>> keys, Function<String, Object> properties) {
this.map = map; this.keys = keys;
this.keys = keys.toArray(String[]::new); this.properties = properties;
} }
@Override @Override
public Object getProperty(String property) { public Object getProperty(String property) {
return map.apply(property); return properties.apply(property);
} }
@Override @Override
public String toString() { public String toString() {
return Arrays.toString(keys); return keys.get().toString();
} }
} }

View File

@ -5,6 +5,7 @@ import static java.util.Collections.*;
import static java.util.stream.Collectors.*; import static java.util.stream.Collectors.*;
import static net.filebot.Logging.*; import static net.filebot.Logging.*;
import static net.filebot.MediaTypes.*; import static net.filebot.MediaTypes.*;
import static net.filebot.WebServices.*;
import static net.filebot.format.Define.*; import static net.filebot.format.Define.*;
import static net.filebot.format.ExpressionFormatMethods.*; import static net.filebot.format.ExpressionFormatMethods.*;
import static net.filebot.hash.VerificationUtilities.*; import static net.filebot.hash.VerificationUtilities.*;
@ -18,7 +19,6 @@ import static net.filebot.util.StringUtilities.*;
import static net.filebot.web.EpisodeUtilities.*; import static net.filebot.web.EpisodeUtilities.*;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
@ -45,7 +45,6 @@ import net.filebot.Language;
import net.filebot.MediaTypes; import net.filebot.MediaTypes;
import net.filebot.MetaAttributeView; import net.filebot.MetaAttributeView;
import net.filebot.Settings; import net.filebot.Settings;
import net.filebot.WebServices;
import net.filebot.hash.HashType; import net.filebot.hash.HashType;
import net.filebot.media.MetaAttributes; import net.filebot.media.MetaAttributes;
import net.filebot.media.NamingStandard; import net.filebot.media.NamingStandard;
@ -59,10 +58,10 @@ import net.filebot.util.WeakValueHashMap;
import net.filebot.web.AudioTrack; import net.filebot.web.AudioTrack;
import net.filebot.web.Episode; import net.filebot.web.Episode;
import net.filebot.web.EpisodeFormat; import net.filebot.web.EpisodeFormat;
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.Person;
import net.filebot.web.SeriesInfo; import net.filebot.web.SeriesInfo;
import net.filebot.web.SimpleDate; import net.filebot.web.SimpleDate;
import net.filebot.web.SortOrder; import net.filebot.web.SortOrder;
@ -76,7 +75,6 @@ public class MediaBindingBean {
private final Map<File, ?> context; private final Map<File, ?> context;
private MediaInfo mediaInfo; private MediaInfo mediaInfo;
private Object metaInfo;
public MediaBindingBean(Object infoObject, File mediaFile) { public MediaBindingBean(Object infoObject, File mediaFile) {
this(infoObject, mediaFile, singletonMap(mediaFile, infoObject)); this(infoObject, mediaFile, singletonMap(mediaFile, infoObject));
@ -127,7 +125,7 @@ public class MediaBindingBean {
if (infoObject instanceof Movie) if (infoObject instanceof Movie)
return getMovie().getYear(); return getMovie().getYear();
if (infoObject instanceof AudioTrack) if (infoObject instanceof AudioTrack)
return getReleaseDate().getYear(); return getMusic().getAlbumReleaseDate().getYear();
return null; return null;
} }
@ -136,7 +134,9 @@ public class MediaBindingBean {
public String getNameWithYear() { public String getNameWithYear() {
String n = getName().toString(); String n = getName().toString();
String y = " (" + getYear().toString() + ")"; String y = " (" + getYear().toString() + ")";
return n.endsWith(y) ? n : n + y; // account for TV Shows that contain the year in the series name, e.g. Doctor Who (2005)
// account for TV Shows that contain the year in the series name, e.g. Doctor Who (2005)
return n.endsWith(y) ? n : n + y;
} }
@Define("s") @Define("s")
@ -197,21 +197,16 @@ public class MediaBindingBean {
} }
@Define("d") @Define("d")
public SimpleDate getReleaseDate() { public SimpleDate getReleaseDate() throws Exception {
if (infoObject instanceof Episode) { if (infoObject instanceof Episode)
return getEpisode().getAirdate(); return getEpisode().getAirdate();
} if (infoObject instanceof Movie)
if (infoObject instanceof Movie) { return getMovieInfo().getReleased();
return (SimpleDate) getMetaInfo().getProperty("released"); if (infoObject instanceof AudioTrack)
}
if (infoObject instanceof AudioTrack) {
return getMusic().getAlbumReleaseDate(); return getMusic().getAlbumReleaseDate();
} if (infoObject instanceof File)
if (infoObject instanceof File) {
return new SimpleDate(getCreationDate(((File) infoObject))); return new SimpleDate(getCreationDate(((File) infoObject)));
}
// no date info for the model
return null; return null;
} }
@ -221,14 +216,16 @@ public class MediaBindingBean {
} }
@Define("age") @Define("age")
public Long getAgeInDays() { public Long getAgeInDays() throws Exception {
SimpleDate releaseDate = getReleaseDate(); SimpleDate releaseDate = getReleaseDate();
if (releaseDate != null) { if (releaseDate != null) {
long days = ChronoUnit.DAYS.between(releaseDate.toLocalDate(), LocalDateTime.now()); long days = ChronoUnit.DAYS.between(releaseDate.toLocalDate(), LocalDateTime.now());
if (days >= 0) { if (days >= 0) {
return days; return days;
} }
} }
return null; return null;
} }
@ -254,30 +251,20 @@ public class MediaBindingBean {
@Define("alias") @Define("alias")
public List<String> getAliasNames() { public List<String> getAliasNames() {
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 getSeriesInfo().getAliasNames(); return getSeriesInfo().getAliasNames();
}
return emptyList(); return null;
} }
@Define("primaryTitle") @Define("primaryTitle")
public String getPrimaryTitle() throws Exception { public String getPrimaryTitle() throws Exception {
if (infoObject instanceof Movie) { if (infoObject instanceof Movie)
return WebServices.TheMovieDB.getMovieInfo(getMovie(), Locale.ENGLISH, false).getOriginalName(); return getPrimaryMovieInfo().getOriginalName();
} if (infoObject instanceof Episode)
return getPrimarySeriesInfo().getName(); // force English series name for TheTVDB data or default to SeriesInfo name (for AniDB episode data this would be the primary title)
if (infoObject instanceof Episode) {
// force English series name for TheTVDB data
if (WebServices.TheTVDB.getIdentifier().equals(getSeriesInfo().getDatabase())) {
return WebServices.TheTVDB.getSeriesInfo(getSeriesInfo().getId(), Locale.ENGLISH).getName();
}
// default to series info name (for Anime this would be the primary title)
return getSeriesInfo().getName();
}
return null; return null;
} }
@ -296,44 +283,24 @@ public class MediaBindingBean {
@Define("tmdbid") @Define("tmdbid")
public String getTmdbId() throws Exception { public String getTmdbId() throws Exception {
int tmdbid = getMovie().getTmdbId(); if (getMovie().getTmdbId() > 0)
return String.valueOf(getMovie().getTmdbId());
if (getMovie().getImdbId() > 0)
return getPrimaryMovieInfo().getId().toString(); // lookup IMDbID for TMDbID
if (tmdbid <= 0) {
if (getMovie().getImdbId() <= 0) {
return null; return null;
} }
// lookup IMDbID for TMDbID
try {
tmdbid = WebServices.TheMovieDB.getMovieInfo(getMovie(), Locale.ENGLISH, false).getId();
} catch (FileNotFoundException e) {
debug.warning(e::toString);
}
}
return String.valueOf(tmdbid);
}
@Define("imdbid") @Define("imdbid")
public String getImdbId() throws Exception { public String getImdbId() throws Exception {
Integer imdbid = getMovie().getImdbId(); if (getMovie().getImdbId() > 0)
return String.format("tt%07d", getMovie().getImdbId());
if (getMovie().getTmdbId() > 0)
return String.format("tt%07d", getPrimaryMovieInfo().getImdbId()); // lookup IMDbID for TMDbID
if (imdbid <= 0) {
if (getMovie().getTmdbId() <= 0) {
return null; return null;
} }
// lookup IMDbID for TMDbID
try {
imdbid = WebServices.TheMovieDB.getMovieInfo(getMovie(), Locale.ENGLISH, false).getImdbId();
} catch (FileNotFoundException e) {
return null;
}
}
return imdbid != null ? String.format("tt%07d", imdbid) : null;
}
@Define("vc") @Define("vc")
public String getVideoCodec() { public String getVideoCodec() {
// e.g. XviD, x264, DivX 5, MPEG-4 Visual, AVC, etc. // e.g. XviD, x264, DivX 5, MPEG-4 Visual, AVC, etc.
@ -417,13 +384,7 @@ public class MediaBindingBean {
@Define("resolution") @Define("resolution")
public String getVideoResolution() { public String getVideoResolution() {
List<Integer> dim = getDimension(); return join(getDimension(), "x"); // e.g. 1280x720
if (dim.contains(null))
return null;
// e.g. 1280x720
return join(dim, "x");
} }
@Define("bitdepth") @Define("bitdepth")
@ -460,7 +421,8 @@ public class MediaBindingBean {
@Define("original") @Define("original")
public String getOriginalFileName() { public String getOriginalFileName() {
String name = xattr.getOriginalName(getMediaFile()); String name = xattr.getOriginalName(getMediaFile());
return name == null ? null : getNameWithoutExtension(name);
return name != null ? getNameWithoutExtension(name) : null;
} }
@Define("xattr") @Define("xattr")
@ -590,9 +552,9 @@ public class MediaBindingBean {
} }
@Define("languages") @Define("languages")
public List<Language> getSpokenLanguages() { public List<Language> getSpokenLanguages() throws Exception {
if (infoObject instanceof Movie) { if (infoObject instanceof Movie) {
List<Locale> languages = (List<Locale>) getMetaInfo().getProperty("spokenLanguages"); List<Locale> languages = getMovieInfo().getSpokenLanguages();
return languages.stream().map(Language::getLanguage).filter(Objects::nonNull).collect(toList()); return languages.stream().map(Language::getLanguage).filter(Objects::nonNull).collect(toList());
} }
if (infoObject instanceof Episode) { if (infoObject instanceof Episode) {
@ -603,102 +565,132 @@ public class MediaBindingBean {
} }
@Define("runtime") @Define("runtime")
public Integer getRuntime() { public Integer getRuntime() throws Exception {
return (Integer) getMetaInfo().getProperty("runtime"); if (infoObject instanceof Movie)
return getMovieInfo().getRuntime();
if (infoObject instanceof Episode)
return getSeriesInfo().getRuntime();
return null;
} }
@Define("actors") @Define("actors")
public Object getActors() { public List<String> getActors() throws Exception {
return getMetaInfo().getProperty("actors"); if (infoObject instanceof Movie)
return getMovieInfo().getActors();
if (infoObject instanceof Episode)
return TheTVDBv2.getActors(getSeriesInfo().getId(), Locale.ENGLISH).stream().map(Person::getName).collect(toList()); // use TheTVDB API v2 to retrieve actors info
return null;
} }
@Define("genres") @Define("genres")
public Object getGenres() { public List<String> getGenres() throws Exception {
return getMetaInfo().getProperty("genres"); if (infoObject instanceof Movie)
return getMovieInfo().getGenres();
if (infoObject instanceof Episode)
return getSeriesInfo().getGenres();
return null;
} }
@Define("genre") @Define("genre")
public String getPrimaryGenre() { public String getPrimaryGenre() throws Exception {
return ((Iterable<?>) getGenres()).iterator().next().toString(); return getGenres().iterator().next();
} }
@Define("director") @Define("director")
public Object getDirector() { public Object getDirector() throws Exception {
return getMetaInfo().getProperty("director"); if (infoObject instanceof Movie)
return getMovieInfo().getDirector();
return null;
} }
@Define("certification") @Define("certification")
public Object getCertification() { public String getCertification() throws Exception {
return getMetaInfo().getProperty("certification"); if (infoObject instanceof Movie)
return getMovieInfo().getCertification();
if (infoObject instanceof Episode)
return getSeriesInfo().getCertification();
return null;
} }
@Define("rating") @Define("rating")
public Object getRating() { public Double getRating() throws Exception {
return getMetaInfo().getProperty("rating"); if (infoObject instanceof Movie)
return getMovieInfo().getRating();
if (infoObject instanceof Episode)
return getSeriesInfo().getRating();
return null;
} }
@Define("collection") @Define("collection")
public Object getCollection() { public String getCollection() throws Exception {
return getMetaInfo().getProperty("collection"); if (infoObject instanceof Movie)
return getMovieInfo().getCollection();
return null;
} }
@Define("info") @Define("info")
public synchronized AssociativeScriptObject getMetaInfo() { public synchronized AssociativeScriptObject getMetaInfo() throws Exception {
if (metaInfo == null) { if (infoObject instanceof Movie)
try { return createPropertyBindings(getMovieInfo());
if (infoObject instanceof Episode) { if (infoObject instanceof Episode)
metaInfo = getSeriesInfo(); return createPropertyBindings(getSeriesInfo());
} else if (infoObject instanceof Movie) {
if (getMovie().getTmdbId() > 0) {
metaInfo = WebServices.TheMovieDB.getMovieInfo(getMovie(), getMovie().getLanguage() == null ? Locale.ENGLISH : getMovie().getLanguage(), true);
} else if (getMovie().getImdbId() > 0) {
metaInfo = WebServices.OMDb.getMovieInfo(getMovie());
}
}
} catch (Exception e) {
throw new RuntimeException("Failed to retrieve extended metadata: " + infoObject, e);
}
}
if (metaInfo == null) { return null;
throw new UnsupportedOperationException("Extended metadata not available");
}
return createPropertyBindings(metaInfo);
} }
@Define("omdb") @Define("omdb")
public synchronized AssociativeScriptObject getOmdbApiInfo() { public synchronized AssociativeScriptObject getOmdbApiInfo() throws Exception {
Object metaInfo = null; if (infoObject instanceof Movie) {
if (getMovie().getImdbId() > 0) {
return createPropertyBindings(OMDb.getMovieInfo(getMovie()));
}
if (getMovie().getTmdbId() > 0) {
Integer imdbId = getPrimaryMovieInfo().getImdbId();
return createPropertyBindings(OMDb.getMovieInfo(new Movie(imdbId)));
}
}
if (infoObject instanceof Episode) {
TheTVDBSeriesInfo info = (TheTVDBSeriesInfo) getPrimarySeriesInfo();
int imdbId = matchInteger(info.getImdbId());
return createPropertyBindings(OMDb.getMovieInfo(new Movie(imdbId)));
}
return null;
}
@Define("localize")
public Object getLocalizedInfoObject() throws Exception {
return new DynamicBindings(Language::availableLanguages, k -> {
Language language = Language.findLanguage(k);
if (language == null) {
return undefined(k);
}
try { try {
if (infoObject instanceof Episode) {
if (WebServices.TheTVDB.getIdentifier().equals(getSeriesInfo().getDatabase())) {
TheTVDBSeriesInfo extendedSeriesInfo = WebServices.TheTVDB.getSeriesInfo(getSeriesInfo().getId(), Locale.ENGLISH);
if (extendedSeriesInfo.getImdbId() != null) {
metaInfo = WebServices.OMDb.getMovieInfo(new Movie(grepImdbId(extendedSeriesInfo.getImdbId()).iterator().next()));
}
}
}
if (infoObject instanceof Movie) { if (infoObject instanceof Movie) {
if (getMovie().getTmdbId() > 0) { MovieInfo m = getMovieInfo(language.getLocale(), true);
MovieInfo movieInfo = WebServices.TheMovieDB.getMovieInfo(getMovie(), Locale.ENGLISH, false); return createPropertyBindings(m);
if (movieInfo.getImdbId() != null) {
metaInfo = WebServices.OMDb.getMovieInfo(new Movie(movieInfo.getImdbId()));
}
} else if (getMovie().getImdbId() > 0) {
metaInfo = WebServices.OMDb.getMovieInfo(getMovie());
} }
if (infoObject instanceof Episode) {
SeriesInfo i = getSeriesInfo();
List<Episode> es = getEpisodeListProvider(i.getDatabase()).getEpisodeList(i.getId(), SortOrder.forName(i.getOrder()), language.getLocale());
Episode e = es.stream().filter(it -> getEpisode().getNumbers().equals(it.getNumbers())).findFirst().get();
return createPropertyBindings(e);
} }
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException("Failed to retrieve extended metadata: " + infoObject, e); throw new BindingException(k, e);
} }
if (metaInfo == null) { return undefined(k);
throw new UnsupportedOperationException("Extended metadata not available"); });
}
return createPropertyBindings(metaInfo);
} }
@Define("az") @Define("az")
@ -724,7 +716,7 @@ public class MediaBindingBean {
public Episode getSeasonEpisode() { public Episode getSeasonEpisode() {
if (getEpisodes().stream().allMatch(it -> isAnime(it) && isRegular(it) && !isAbsolute(it))) { if (getEpisodes().stream().allMatch(it -> isAnime(it) && isRegular(it) && !isAbsolute(it))) {
try { try {
return getEpisodeByAbsoluteNumber(getEpisode(), WebServices.TheTVDB, SortOrder.Airdate); return getEpisodeByAbsoluteNumber(getEpisode(), TheTVDB, SortOrder.Airdate);
} catch (Exception e) { } catch (Exception e) {
debug.warning(e::toString); debug.warning(e::toString);
} }
@ -734,7 +726,9 @@ public class MediaBindingBean {
@Define("episodelist") @Define("episodelist")
public List<Episode> getEpisodeList() throws Exception { public List<Episode> getEpisodeList() throws Exception {
return WebServices.getEpisodeListProvider(getSeriesInfo().getDatabase()).getEpisodeList(getSeriesInfo().getId(), SortOrder.forName(getSeriesInfo().getOrder()), new Locale(getSeriesInfo().getLanguage())); SeriesInfo i = getSeriesInfo();
return getEpisodeListProvider(i.getDatabase()).getEpisodeList(i.getId(), SortOrder.forName(i.getOrder()), new Locale(i.getLanguage()));
} }
@Define("sy") @Define("sy")
@ -747,32 +741,6 @@ public class MediaBindingBean {
return getEpisodeList().stream().filter(e -> isRegular(e) && e.getSeason() != null).map(Episode::getSeason).max(Integer::compare).get(); return getEpisodeList().stream().filter(e -> isRegular(e) && e.getSeason() != null).map(Episode::getSeason).max(Integer::compare).get();
} }
@Define("localize")
public Object getLocalizedInfoObject() throws Exception {
return new DynamicBindings(key -> {
Language language = Language.findLanguage(key);
if (language != null) {
Object localizedInfo = null;
try {
if (infoObject instanceof Movie) {
localizedInfo = WebServices.TheMovieDB.getMovieInfo(getMovie(), language.getLocale(), true);
} else if (infoObject instanceof Episode) {
EpisodeListProvider db = WebServices.getEpisodeListProvider(getSeriesInfo().getDatabase());
List<Episode> episodes = db.getEpisodeList(getSeriesInfo().getId(), SortOrder.forName(getSeriesInfo().getOrder()), language.getLocale());
localizedInfo = episodes.stream().filter(it -> getEpisode().getNumbers().equals(it.getNumbers())).findFirst().orElse(null);
}
} catch (Exception e) {
throw new BindingException(key, e);
}
if (localizedInfo != null) {
return createPropertyBindings(localizedInfo);
}
}
return undefined(key);
}, Language.availableLanguages().stream().map(Language::getName));
}
@Define("mediaTitle") @Define("mediaTitle")
public String getMediaTitle() { public String getMediaTitle() {
return getMediaInfo(StreamKind.General, 0, "Title", "Movie"); return getMediaInfo(StreamKind.General, 0, "Title", "Movie");
@ -1012,6 +980,32 @@ public class MediaBindingBean {
return MetaAttributes.toJson(infoObject); return MetaAttributes.toJson(infoObject);
} }
public MovieInfo getPrimaryMovieInfo() throws Exception {
return TheMovieDB.getMovieInfo(getMovie(), Locale.ENGLISH, false);
}
public SeriesInfo getPrimarySeriesInfo() throws Exception {
if (TheTVDB.getIdentifier().equals(getSeriesInfo().getDatabase()))
return TheTVDB.getSeriesInfo(getSeriesInfo().getId(), Locale.ENGLISH);
return getSeriesInfo();
}
public MovieInfo getMovieInfo() throws Exception {
return getMovieInfo(getMovie().getLanguage(), true);
}
public synchronized MovieInfo getMovieInfo(Locale locale, boolean extendedInfo) throws Exception {
Movie m = getMovie();
if (m.getTmdbId() > 0)
return TheMovieDB.getMovieInfo(m, locale == null ? Locale.ENGLISH : locale, extendedInfo);
if (m.getImdbId() > 0)
return OMDb.getMovieInfo(m);
return null;
}
public File getInferredMediaFile() { public File getInferredMediaFile() {
if (getMediaFile().isDirectory()) { if (getMediaFile().isDirectory()) {
// just select the first video file in the folder as media sample // just select the first video file in the folder as media sample

View File

@ -40,7 +40,7 @@ public class TheTVDBClient extends AbstractEpisodeListProvider implements Artwor
@Override @Override
public String getName() { public String getName() {
return "TheTVDB"; return "TheTVDBv2";
} }
@Override @Override
@ -285,7 +285,7 @@ public class TheTVDBClient extends AbstractEpisodeListProvider implements Artwor
Integer order = getInteger(it, "sortOrder"); Integer order = getInteger(it, "sortOrder");
URL image = getStringValue(it, "image", this::resolveImage); URL image = getStringValue(it, "image", this::resolveImage);
return new Person(name, character, null, null, order, image); return new Person(name, character, Person.ACTOR, null, order, image);
}).sorted(Person.CREDIT_ORDER).collect(toList()); }).sorted(Person.CREDIT_ORDER).collect(toList());
} }