* fix issues with multi-episode anime default numbering bindings {sxe} and {s00e00}

This commit is contained in:
Reinhard Pointner 2014-03-24 17:11:56 +00:00
parent 8f31ed3977
commit f61f30e862
1 changed files with 46 additions and 55 deletions

View File

@ -1,7 +1,5 @@
package net.sourceforge.filebot.web; package net.sourceforge.filebot.web;
import static net.sourceforge.tuned.StringUtilities.*; import static net.sourceforge.tuned.StringUtilities.*;
import java.text.FieldPosition; import java.text.FieldPosition;
@ -13,40 +11,37 @@ import java.util.Set;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
public class EpisodeFormat extends Format { public class EpisodeFormat extends Format {
public static final EpisodeFormat SeasonEpisode = new EpisodeFormat(true, false); public static final EpisodeFormat SeasonEpisode = new EpisodeFormat(true, false);
private final boolean includeAirdate; private final boolean includeAirdate;
private final boolean includeSpecial; private final boolean includeSpecial;
public EpisodeFormat(boolean includeSpecial, boolean includeAirdate) { public EpisodeFormat(boolean includeSpecial, boolean includeAirdate) {
this.includeSpecial = includeSpecial; this.includeSpecial = includeSpecial;
this.includeAirdate = includeAirdate; this.includeAirdate = includeAirdate;
} }
@Override @Override
public StringBuffer format(Object obj, StringBuffer sb, FieldPosition pos) { public StringBuffer format(Object obj, StringBuffer sb, FieldPosition pos) {
if (obj instanceof MultiEpisode) { if (obj instanceof MultiEpisode) {
return sb.append(formatMultiEpisode(((MultiEpisode) obj).getEpisodes())); return sb.append(formatMultiEpisode(((MultiEpisode) obj).getEpisodes()));
} }
// format episode object, e.g. Dark Angel - 3x01 - Labyrinth [2009-06-01] // format episode object, e.g. Dark Angel - 3x01 - Labyrinth [2009-06-01]
Episode episode = (Episode) obj; Episode episode = (Episode) obj;
// episode number is most likely a number but could also be some kind of special identifier (e.g. Special) // episode number is most likely a number but could also be some kind of special identifier (e.g. Special)
String episodeNumber = episode.getEpisode() != null ? String.format("%02d", episode.getEpisode()) : null; String episodeNumber = episode.getEpisode() != null ? String.format("%02d", episode.getEpisode()) : null;
// series name should not be empty or null // series name should not be empty or null
sb.append(episode.getSeriesName()); sb.append(episode.getSeriesName());
if (episode.getSeason() != null) { if (episode.getSeason() != null) {
// season and episode // season and episode
sb.append(" - ").append(episode.getSeason()).append('x'); sb.append(" - ").append(episode.getSeason()).append('x');
if (episode.getEpisode() != null) { if (episode.getEpisode() != null) {
sb.append(String.format("%02d", episode.getEpisode())); sb.append(String.format("%02d", episode.getEpisode()));
} else if (includeSpecial && episode.getSpecial() != null) { } else if (includeSpecial && episode.getSpecial() != null) {
@ -60,55 +55,52 @@ public class EpisodeFormat extends Format {
sb.append(" - ").append("Special " + episode.getSpecial()); sb.append(" - ").append("Special " + episode.getSpecial());
} }
} }
sb.append(" - ").append(episode.getTitle()); sb.append(" - ").append(episode.getTitle());
if (includeAirdate && episode.getAirdate() != null) { if (includeAirdate && episode.getAirdate() != null) {
sb.append(" [").append(episode.getAirdate().format("yyyy-MM-dd")).append("]"); sb.append(" [").append(episode.getAirdate().format("yyyy-MM-dd")).append("]");
} }
return sb; return sb;
} }
public String formatSxE(Episode episode) { public String formatSxE(Episode episode) {
if (episode instanceof MultiEpisode) { if (episode instanceof MultiEpisode) {
return formatMultiSxE(((MultiEpisode) episode).getEpisodes()); return formatMultiSxE(((MultiEpisode) episode).getEpisodes());
} }
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
if (episode.getSeason() != null || episode.getSpecial() != null) { if (episode.getSeason() != null || episode.getSpecial() != null) {
sb.append(episode.getSpecial() == null ? episode.getSeason() : 0).append('x'); sb.append(episode.getSpecial() == null ? episode.getSeason() : 0).append('x');
} }
if (episode.getEpisode() != null || episode.getSpecial() != null) { if (episode.getEpisode() != null || episode.getSpecial() != null) {
sb.append(String.format("%02d", episode.getSpecial() == null ? episode.getEpisode() : episode.getSpecial())); sb.append(String.format("%02d", episode.getSpecial() == null ? episode.getEpisode() : episode.getSpecial()));
} }
return sb.toString(); return sb.toString();
} }
public String formatS00E00(Episode episode) { public String formatS00E00(Episode episode) {
if (episode instanceof MultiEpisode) { if (episode instanceof MultiEpisode) {
return formatMultiS00E00(((MultiEpisode) episode).getEpisodes()); return formatMultiS00E00(((MultiEpisode) episode).getEpisodes());
} }
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
if (episode.getSeason() != null || episode.getSpecial() != null) { if (episode.getSeason() != null || episode.getSpecial() != null) {
sb.append(String.format("S%02d", episode.getSpecial() == null ? episode.getSeason() : 0)); sb.append(String.format("S%02d", episode.getSpecial() == null ? episode.getSeason() : 0));
} }
if (episode.getEpisode() != null || episode.getSpecial() != null) { if (episode.getEpisode() != null || episode.getSpecial() != null) {
sb.append(String.format("E%02d", episode.getSpecial() == null ? episode.getEpisode() : episode.getSpecial())); sb.append(String.format("E%02d", episode.getSpecial() == null ? episode.getEpisode() : episode.getSpecial()));
} }
return sb.toString(); return sb.toString();
} }
public String formatMultiEpisode(Iterable<Episode> episodes) { public String formatMultiEpisode(Iterable<Episode> episodes) {
Set<String> name = new LinkedHashSet<String>(); Set<String> name = new LinkedHashSet<String>();
Set<String> sxe = new LinkedHashSet<String>(); Set<String> sxe = new LinkedHashSet<String>();
@ -118,30 +110,31 @@ public class EpisodeFormat extends Format {
sxe.add(formatSxE(it)); sxe.add(formatSxE(it));
title.add(it.getTitle().replaceAll("[(]([^)]*)[)]$", "").trim()); title.add(it.getTitle().replaceAll("[(]([^)]*)[)]$", "").trim());
} }
return String.format("%s - %s - %s", join(name, " & "), join(sxe, " & "), join(title, " & ")); return String.format("%s - %s - %s", join(name, " & "), join(sxe, " & "), join(title, " & "));
} }
public String formatMultiSxE(Iterable<Episode> episodes) { public String formatMultiSxE(Iterable<Episode> episodes) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
Integer ps = null; Integer ps = null;
for (Episode it : episodes) { for (Episode it : episodes) {
if (!it.getSeason().equals(ps)) { if (it.getSeason() != null && !it.getSeason().equals(ps)) {
if (sb.length() > 0) { if (sb.length() > 0) {
sb.append(' '); sb.append(' ');
} }
sb.append(it.getSeason()).append('x').append(String.format("%02d", it.getEpisode())); sb.append(it.getSeason()).append('x').append(String.format("%02d", it.getEpisode()));
} else { } else {
sb.append('-').append(String.format("%02d", it.getEpisode())); if (sb.length() > 0) {
sb.append('-');
}
sb.append(String.format("%02d", it.getEpisode()));
} }
ps = it.getSeason(); ps = it.getSeason();
} }
return sb.toString(); return sb.toString();
} }
public String formatMultiS00E00(Iterable<Episode> episodes) { public String formatMultiS00E00(Iterable<Episode> episodes) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
Integer ps = null; Integer ps = null;
@ -149,64 +142,62 @@ public class EpisodeFormat extends Format {
if (sb.length() > 0) { if (sb.length() > 0) {
sb.append("-"); sb.append("-");
} }
if (!it.getSeason().equals(ps)) { if (it.getSeason() != null && !it.getSeason().equals(ps)) {
sb.append(String.format("S%02d", it.getSeason())).append(String.format("E%02d", it.getEpisode())); sb.append(String.format("S%02d", it.getSeason())).append(String.format("E%02d", it.getEpisode()));
} else { } else {
sb.append(String.format("E%02d", it.getEpisode())); sb.append(String.format("E%02d", it.getEpisode()));
} }
ps = it.getSeason(); ps = it.getSeason();
} }
return sb.toString(); return sb.toString();
} }
private final Pattern sxePattern = Pattern.compile("- (?:(\\d{1,2})x)?(Special )?(\\d{1,3}) -"); private final Pattern sxePattern = Pattern.compile("- (?:(\\d{1,2})x)?(Special )?(\\d{1,3}) -");
private final Pattern airdatePattern = Pattern.compile("\\[(\\d{4}-\\d{1,2}-\\d{1,2})\\]"); private final Pattern airdatePattern = Pattern.compile("\\[(\\d{4}-\\d{1,2}-\\d{1,2})\\]");
@Override @Override
public Episode parseObject(String s, ParsePosition pos) { public Episode parseObject(String s, ParsePosition pos) {
StringBuilder source = new StringBuilder(s); StringBuilder source = new StringBuilder(s);
Integer season = null; Integer season = null;
Integer episode = null; Integer episode = null;
Integer special = null; Integer special = null;
Date airdate = null; Date airdate = null;
Matcher m; Matcher m;
if ((m = airdatePattern.matcher(source)).find()) { if ((m = airdatePattern.matcher(source)).find()) {
airdate = Date.parse(m.group(1), "yyyy-MM-dd"); airdate = Date.parse(m.group(1), "yyyy-MM-dd");
source.replace(m.start(), m.end(), ""); // remove matched part from text source.replace(m.start(), m.end(), ""); // remove matched part from text
} }
if ((m = sxePattern.matcher(source)).find()) { if ((m = sxePattern.matcher(source)).find()) {
season = (m.group(1) == null) ? null : new Integer(m.group(1)); season = (m.group(1) == null) ? null : new Integer(m.group(1));
if (m.group(2) == null) if (m.group(2) == null)
episode = new Integer(m.group(3)); episode = new Integer(m.group(3));
else else
special = new Integer(m.group(3)); special = new Integer(m.group(3));
source.replace(m.start(), m.end(), ""); // remove matched part from text source.replace(m.start(), m.end(), ""); // remove matched part from text
// assume that all the remaining text is series name and title // assume that all the remaining text is series name and title
String name = source.substring(0, m.start()).trim(); String name = source.substring(0, m.start()).trim();
String title = source.substring(m.start()).trim(); String title = source.substring(m.start()).trim();
// did parse input // did parse input
pos.setIndex(source.length()); 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, airdate, null);
} }
// failed to parse input // failed to parse input
pos.setErrorIndex(0); pos.setErrorIndex(0);
return null; return null;
} }
@Override @Override
public Episode parseObject(String source) throws ParseException { public Episode parseObject(String source) throws ParseException {
return (Episode) super.parseObject(source); return (Episode) super.parseObject(source);
} }
} }