diff --git a/source/net/filebot/format/MediaBindingBean.java b/source/net/filebot/format/MediaBindingBean.java index fc0f05f3..8aad8138 100644 --- a/source/net/filebot/format/MediaBindingBean.java +++ b/source/net/filebot/format/MediaBindingBean.java @@ -15,7 +15,7 @@ import static net.filebot.subtitle.SubtitleUtilities.*; import static net.filebot.util.FileUtilities.*; import static net.filebot.util.RegularExpressions.*; import static net.filebot.util.StringUtilities.*; -import static net.filebot.web.EpisodeFormat.*; +import static net.filebot.web.EpisodeUtilities.*; import java.io.File; import java.io.FileNotFoundException; @@ -56,11 +56,10 @@ import net.filebot.util.FileUtilities; import net.filebot.util.WeakValueHashMap; import net.filebot.web.AudioTrack; import net.filebot.web.Episode; +import net.filebot.web.EpisodeFormat; import net.filebot.web.EpisodeListProvider; import net.filebot.web.Movie; import net.filebot.web.MoviePart; -import net.filebot.web.MultiEpisode; -import net.filebot.web.SearchResult; import net.filebot.web.SeriesInfo; import net.filebot.web.SimpleDate; import net.filebot.web.SortOrder; @@ -155,17 +154,12 @@ public class MediaBindingBean { @Define("sxe") public String getSxE() { - return SeasonEpisode.formatSxE(getEpisode()); + return EpisodeFormat.SeasonEpisode.formatSxE(getSeasonEpisode()); // try to convert absolute numbers to SxE numbers } @Define("s00e00") public String getS00E00() { - try { - return SeasonEpisode.formatS00E00(getSeasonEpisode()); // try to convert absolute numbers to SxE numbers - } catch (Exception e) { - debug.warning(e::toString); - } - return SeasonEpisode.formatS00E00(getEpisode()); + return EpisodeFormat.SeasonEpisode.formatS00E00(getSeasonEpisode()); // try to convert absolute numbers to SxE numbers } @Define("t") @@ -175,7 +169,7 @@ public class MediaBindingBean { } // enforce title length limit by default - return truncateText(SeasonEpisode.formatMultiTitle(getEpisodes()), NamingStandard.TITLE_MAX_LENGTH); + return truncateText(EpisodeFormat.SeasonEpisode.formatMultiTitle(getEpisodes()), NamingStandard.TITLE_MAX_LENGTH); } @Define("d") @@ -693,48 +687,23 @@ public class MediaBindingBean { @Define("anime") public boolean isAnimeEpisode() { - return WebServices.AniDB.getIdentifier().equals(getEpisode().getSeriesInfo().getDatabase()); + return getEpisodes().stream().anyMatch(it -> isAnime(it)); } @Define("regular") public boolean isRegularEpisode() { - return getEpisodes().stream().allMatch(it -> it.getEpisode() != null && it.getSpecial() == null); + return getEpisodes().stream().anyMatch(it -> isRegular(it)); } @Define("abs2sxe") - public Episode getSeasonEpisode() throws Exception { - // match AniDB episode to TheTVDB episode - if (isAnimeEpisode()) { - SeriesInfo seriesInfo = getEpisode().getSeriesInfo(); - Locale locale = new Locale(seriesInfo.getLanguage()); - - // episode may be a multi-episode - List episode = getEpisodes(); - - for (SearchResult series : WebServices.TheTVDB.search(seriesInfo.getName(), locale)) { - // sanity check - if (!series.getEffectiveNames().contains(seriesInfo.getName())) { - continue; - } - - // match by absolute number or airdate if possible, default to absolute number otherwise - List airdateEpisodeList = WebServices.TheTVDB.getEpisodeList(series, SortOrder.Airdate, locale); - List airdateEpisode = episode.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() != episode.size()) { - break; - } - - return airdateEpisode.size() == 1 ? airdateEpisode.get(0) : new MultiEpisode(airdateEpisode); + public Episode getSeasonEpisode() { + if (getEpisodes().stream().allMatch(it -> isAnime(it) && isRegular(it) && !isAbsolute(it))) { + try { + return getEpisodeByAbsoluteNumber(getEpisode(), WebServices.TheTVDB, SortOrder.Airdate); + } catch (Exception e) { + debug.warning(e::toString); } } - - // return episode object as is by default return getEpisode(); } @@ -846,7 +815,7 @@ public class MediaBindingBean { @Define("episodes") public List getEpisodes() { - return infoObject instanceof MultiEpisode ? ((MultiEpisode) infoObject).getEpisodes() : singletonList(getEpisode()); + return getMultiEpisodeList(getEpisode()); } @Define("movie") diff --git a/source/net/filebot/web/AnidbClient.java b/source/net/filebot/web/AnidbClient.java index cab01d16..09fca336 100644 --- a/source/net/filebot/web/AnidbClient.java +++ b/source/net/filebot/web/AnidbClient.java @@ -66,7 +66,7 @@ public class AnidbClient extends AbstractEpisodeListProvider { @Override protected SortOrder vetoRequestParameter(SortOrder order) { - return SortOrder.Absolute; + return order == null ? SortOrder.Absolute : order; } @Override diff --git a/source/net/filebot/web/EpisodeUtilities.java b/source/net/filebot/web/EpisodeUtilities.java index f49422f2..94cc54e1 100644 --- a/source/net/filebot/web/EpisodeUtilities.java +++ b/source/net/filebot/web/EpisodeUtilities.java @@ -1,42 +1,84 @@ package net.filebot.web; -import java.util.ArrayList; +import static java.util.Collections.*; +import static java.util.stream.Collectors.*; + +import java.util.Collection; import java.util.Comparator; import java.util.List; +import java.util.Locale; + +import net.filebot.WebServices; public final class EpisodeUtilities { - public static List filterBySeason(Iterable episodes, int season) { - List results = new ArrayList(25); - - // filter given season from all seasons - for (Episode episode : episodes) { - if (episode.getSeason() != null && season == episode.getSeason()) { - results.add(episode); - } - } - - return results; + public static List getMultiEpisodeList(Episode e) { + return e instanceof MultiEpisode ? ((MultiEpisode) e).getEpisodes() : singletonList(e); } - public static int getLastSeason(Iterable episodes) { - int lastSeason = 0; + public static boolean isAnime(Episode e) { + return WebServices.AniDB.getIdentifier().equals(e.getSeriesInfo().getDatabase()); + } - // filter given season from all seasons - for (Episode episode : episodes) { - if (episode.getSeason() != null && episode.getSeason() > lastSeason) { - lastSeason = episode.getSeason(); + 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 Episode getEpisodeByAbsoluteNumber(Episode e, EpisodeListProvider service, SortOrder order) throws Exception { + // e.g. match AniDB episode to TheTVDB episode + SeriesInfo seriesInfo = e.getSeriesInfo(); + Locale locale = new Locale(seriesInfo.getLanguage()); + + // episode may be a multi-episode + List multiEpisode = getMultiEpisodeList(e); + + for (SearchResult series : service.search(seriesInfo.getName(), locale)) { + // sanity check + if (!series.getEffectiveNames().contains(seriesInfo.getName())) { + 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 airdateEpisode.size() == 1 ? airdateEpisode.get(0) : new MultiEpisode(airdateEpisode); } - return lastSeason; + // return episode object as is by default + return e; + } + + public static List filterBySeason(Collection episodes, int season) { + return episodes.stream().filter(it -> { + return it.getSeason() != null && season == it.getSeason(); + }).collect(toList()); + } + + public static int getLastSeason(Collection episodes) { + return episodes.stream().mapToInt(it -> { + return it.getSeason() == null ? 0 : it.getSeason(); + }).max().orElse(0); } public static Comparator episodeComparator() { - return NUMBERS_COMPARATOR; + return EPISODE_NUMBERS_COMPARATOR; } - public static final Comparator NUMBERS_COMPARATOR = new Comparator() { + public static final Comparator EPISODE_NUMBERS_COMPARATOR = new Comparator() { @Override public int compare(Episode a, Episode b) { @@ -70,4 +112,5 @@ public final class EpisodeUtilities { private EpisodeUtilities() { throw new UnsupportedOperationException(); } + }