diff --git a/source/net/filebot/format/MediaBindingBean.java b/source/net/filebot/format/MediaBindingBean.java index efe47415..1d11fe17 100644 --- a/source/net/filebot/format/MediaBindingBean.java +++ b/source/net/filebot/format/MediaBindingBean.java @@ -151,7 +151,7 @@ public class MediaBindingBean { public Integer getSeasonNumber() { // look up season numbers via TheTVDB for AniDB episode data if (isAnime(getEpisode())) { - return getSeasonEpisode().getSeason(); + return trySeasonEpisodeForAnime(getEpisode()).getSeason(); } return getEpisode().getSeason(); @@ -179,12 +179,13 @@ public class MediaBindingBean { @Define("sxe") public String getSxE() { - return EpisodeFormat.SeasonEpisode.formatSxE(getSeasonEpisode()); // try to convert absolute numbers to SxE numbers + return EpisodeFormat.SeasonEpisode.formatSxE(trySeasonEpisodeForAnime(getEpisode())); // magically convert AniDB absolute numbers to TheTVDB SxE numbers + } @Define("s00e00") public String getS00E00() { - return EpisodeFormat.SeasonEpisode.formatS00E00(getSeasonEpisode()); // try to convert absolute numbers to SxE numbers + return EpisodeFormat.SeasonEpisode.formatS00E00(trySeasonEpisodeForAnime(getEpisode())); // magically convert AniDB absolute numbers to TheTVDB SxE numbers } @Define("t") @@ -1161,18 +1162,6 @@ public class MediaBindingBean { return new FFProbe().open(getInferredMediaFile()); } - public Episode getSeasonEpisode() { - // magically convert AniDB absolute numbers to TheTVDB SxE numbers if AniDB is selected with airdate SxE episode sort order - if (getEpisodes().stream().allMatch(it -> isAnime(it) && isRegular(it) && !isAbsolute(it))) { - try { - return getEpisodeByAbsoluteNumber(getEpisode(), TheTVDB, SortOrder.Airdate); - } catch (Exception e) { - debug.warning(e::toString); - } - } - return getEpisode(); - } - public SeriesInfo getPrimarySeriesInfo() { if (TheTVDB.getIdentifier().equals(getSeriesInfo().getDatabase())) { try { diff --git a/source/net/filebot/web/EpisodeUtilities.java b/source/net/filebot/web/EpisodeUtilities.java index ceffef6a..f5908aa9 100644 --- a/source/net/filebot/web/EpisodeUtilities.java +++ b/source/net/filebot/web/EpisodeUtilities.java @@ -2,23 +2,30 @@ package net.filebot.web; import static java.util.Collections.*; import static java.util.stream.Collectors.*; +import static net.filebot.Logging.*; import static net.filebot.WebServices.*; -import java.text.Collator; import java.util.Collection; import java.util.Comparator; import java.util.List; import java.util.Locale; -import java.util.Set; -import java.util.TreeSet; +import java.util.Optional; +import java.util.function.Function; public final class EpisodeUtilities { - public static Episode createEpisode(List episode) { - if (episode.isEmpty()) { - throw new IllegalArgumentException("No such Episode"); - } + private static Episode mapEpisode(Episode episode, Function mapper) { + return createEpisode(getMultiEpisodeList(episode).stream().map(mapper).sorted(EPISODE_NUMBERS_COMPARATOR).collect(toList())); + } + private static Episode selectEpisode(List episodelist, Episode selection) { + return createEpisode(episodelist.stream().filter(getMultiEpisodeList(selection)::contains).sorted(EPISODE_NUMBERS_COMPARATOR).collect(toList())); + } + + private static Episode createEpisode(List episode) { + if (episode.isEmpty()) { + throw new IllegalArgumentException("Invalid Episode: Empty"); + } return episode.size() == 1 ? episode.get(0) : new MultiEpisode(episode); } @@ -27,17 +34,13 @@ public final class EpisodeUtilities { } public static boolean isAnime(Episode e) { - return SortOrder.Absolute.name().equals(e.getSeriesInfo().getOrder()) || AniDB.getIdentifier().equals(e.getSeriesInfo().getDatabase()); + return AniDB.getIdentifier().equals(e.getSeriesInfo().getDatabase()); } public static boolean isRegular(Episode e) { return e.getEpisode() != null && e.getSpecial() == null; } - public static boolean isAbsolute(Episode e) { - return e.getAbsolute() != null && e.getSeriesInfo().getOrder() != null && SortOrder.Absolute == SortOrder.valueOf(e.getSeriesInfo().getOrder()); - } - public static List fetchEpisodeList(Episode episode) throws Exception { return fetchEpisodeList(episode, null, null); } @@ -45,69 +48,28 @@ public final class EpisodeUtilities { public static List fetchEpisodeList(Episode episode, SortOrder preferredSortOrder, Locale preferredLocale) throws Exception { SeriesInfo info = episode.getSeriesInfo(); - SortOrder order = preferredSortOrder; - if (order == null) { - order = SortOrder.valueOf(info.getOrder()); // default to original order - } - - Locale locale = preferredLocale; - if (locale == null) { - locale = new Locale(info.getLanguage()); // default to original locale - } + SortOrder order = Optional.ofNullable(preferredSortOrder).orElseGet(() -> SortOrder.valueOf(info.getOrder())); // default to original order + Locale locale = Optional.ofNullable(preferredLocale).orElseGet(() -> new Locale(info.getLanguage())); // default to original locale return getEpisodeListProvider(info.getDatabase()).getEpisodeList(info.getId(), order, locale); } public static Episode fetchEpisode(Episode episode, SortOrder preferredSortOrder, Locale preferredLocale) throws Exception { - List episodeList = fetchEpisodeList(episode, preferredSortOrder, preferredLocale); - List includes = getMultiEpisodeList(episode); - - return createEpisode(episodeList.stream().filter(includes::contains).sorted(EPISODE_NUMBERS_COMPARATOR).collect(toList())); + return selectEpisode(fetchEpisodeList(episode, preferredSortOrder, preferredLocale), episode); } - public static Episode getEpisodeByAbsoluteNumber(Episode e, EpisodeListProvider service, SortOrder order) throws Exception { - // e.g. match AniDB episode to TheTVDB episode - Set seriesNames = getLenientSeriesNameSet(e); - Locale locale = new Locale(e.getSeriesInfo().getLanguage()); - - // episode may be a multi-episode - List multiEpisode = getMultiEpisodeList(e); - - for (SearchResult series : service.search(e.getSeriesName(), locale)) { - // sanity check - if (!series.getEffectiveNames().stream().anyMatch(seriesNames::contains)) { - continue; - } - - // match by absolute number or airdate if possible, default to absolute number otherwise - List airdateEpisodeList = service.getEpisodeList(series, order, locale); - List airdateEpisode = multiEpisode.stream().flatMap(abs -> { - return airdateEpisodeList.stream().filter(sxe -> abs.getSpecial() == null && sxe.getSpecial() == null).filter(sxe -> { - return abs.getAbsolute() != null && abs.getAbsolute().equals(sxe.getAbsolute()); - }); - }).collect(toList()); - - // sanity check - if (airdateEpisode.size() != multiEpisode.size()) { - break; - } - - return createEpisode(airdateEpisode); + public static Episode trySeasonEpisodeForAnime(Episode episode) { + if (isAnime(episode) && isRegular(episode)) { + return mapEpisode(episode, e -> { + try { + return AnimeLists.forName(e.getSeriesInfo().getDatabase()).map(e, AnimeLists.TheTVDB).orElse(e); + } catch (Exception ioe) { + debug.warning(ioe::toString); + return e; + } + }); } - - // return episode object as is by default - return e; - } - - private static Set getLenientSeriesNameSet(Episode e) { - // use maximum strength collator by default - Collator collator = Collator.getInstance(new Locale(e.getSeriesInfo().getLanguage())); - collator.setDecomposition(Collator.FULL_DECOMPOSITION); - collator.setStrength(Collator.PRIMARY); - - Set seriesNames = new TreeSet(collator); - seriesNames.addAll(e.getSeriesNames()); - return seriesNames; + return episode; } public static List filterBySeason(Collection episodes, int season) {