1
0
mirror of https://github.com/mitb-archive/filebot synced 2024-11-11 20:05:04 -05:00

Refactor Anime SxE support hack

This commit is contained in:
Reinhard Pointner 2019-06-08 04:32:20 +07:00
parent 480c16b0f8
commit 9360bc9e65
2 changed files with 33 additions and 82 deletions

View File

@ -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 {

View File

@ -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> episode) {
if (episode.isEmpty()) {
throw new IllegalArgumentException("No such Episode");
private static Episode mapEpisode(Episode episode, Function<Episode, Episode> mapper) {
return createEpisode(getMultiEpisodeList(episode).stream().map(mapper).sorted(EPISODE_NUMBERS_COMPARATOR).collect(toList()));
}
private static Episode selectEpisode(List<Episode> episodelist, Episode selection) {
return createEpisode(episodelist.stream().filter(getMultiEpisodeList(selection)::contains).sorted(EPISODE_NUMBERS_COMPARATOR).collect(toList()));
}
private static Episode createEpisode(List<Episode> 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<Episode> fetchEpisodeList(Episode episode) throws Exception {
return fetchEpisodeList(episode, null, null);
}
@ -45,69 +48,28 @@ public final class EpisodeUtilities {
public static List<Episode> 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<Episode> episodeList = fetchEpisodeList(episode, preferredSortOrder, preferredLocale);
List<Episode> 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<String> seriesNames = getLenientSeriesNameSet(e);
Locale locale = new Locale(e.getSeriesInfo().getLanguage());
// episode may be a multi-episode
List<Episode> 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<Episode> airdateEpisodeList = service.getEpisodeList(series, order, locale);
List<Episode> 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);
}
// return episode object as is by default
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;
}
private static Set<String> 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<String> seriesNames = new TreeSet<String>(collator);
seriesNames.addAll(e.getSeriesNames());
return seriesNames;
});
}
return episode;
}
public static List<Episode> filterBySeason(Collection<Episode> episodes, int season) {