+ EpressionFormat: format Double objects with integer values as integers

+ Matching: allow partial match with season number OR episode number
+ AutoFetchEpisodeListMatcher: abort if one or more shows cannot be found

* support specials in TVRage, TVDotCom and TheTVDB Client
* account for IMDB search-to-info-page redirect
This commit is contained in:
Reinhard Pointner 2009-05-03 15:21:04 +00:00
parent 416384901b
commit 1ed4d2b495
28 changed files with 320 additions and 194 deletions

View File

@ -57,13 +57,13 @@ public class EpisodeFormatBindingBean {
@Define("s")
public String getSeasonNumber() {
return episode.getSeasonNumber();
return episode.getSeason();
}
@Define("e")
public String getEpisodeNumber() {
return episode.getEpisodeNumber();
return episode.getEpisode();
}
@ -123,29 +123,31 @@ public class EpisodeFormatBindingBean {
@Define("crc32")
public String getCRC32() throws IOException, InterruptedException {
if (mediaFile != null) {
// try to get checksum from file name
String checksum = FileBotUtilities.getEmbeddedChecksum(mediaFile.getName());
if (checksum != null)
return checksum;
// try to get checksum from sfv file
checksum = getChecksumFromSfvFile(mediaFile);
if (checksum != null)
return checksum;
// calculate checksum from file
return crc32(mediaFile);
}
// make sure media file is defined
checkMediaFile();
return null;
// try to get checksum from file name
String checksum = FileBotUtilities.getEmbeddedChecksum(mediaFile.getName());
if (checksum != null)
return checksum;
// try to get checksum from sfv file
checksum = getChecksumFromSfvFile(mediaFile);
if (checksum != null)
return checksum;
// calculate checksum from file
return crc32(mediaFile);
}
@Define("ext")
public String getContainerExtension() {
// make sure media file is defined
checkMediaFile();
// file extension
return FileUtilities.getExtension(mediaFile);
}
@ -193,12 +195,21 @@ public class EpisodeFormatBindingBean {
}
private synchronized MediaInfo getMediaInfo() {
if (mediaFile == null) {
throw new NullPointerException("Media file is null");
}
private void checkMediaFile() {
// make sure file is not null
if (mediaFile == null)
throw new NullPointerException("Media file is not defined");
// file may not exist at this point but if an existing file is required,
// an exception will be thrown later anyway
}
private synchronized MediaInfo getMediaInfo() {
if (mediaInfo == null) {
// make sure media file is defined
checkMediaFile();
mediaInfo = new MediaInfo();
if (!mediaInfo.open(mediaFile)) {

View File

@ -1,4 +1,6 @@
/**
* Convenience method to pad strings or numbers with given characters ('0' by default)
*/
String.prototype.pad = Number.prototype.pad = function(length, padding) {
var s = this.toString();
@ -13,6 +15,9 @@ String.prototype.pad = Number.prototype.pad = function(length, padding) {
}
/**
* Convenience method to replace space characters with a given characters
*/
String.prototype.space = function(replacement) {
return this.replace(/\s/g, replacement);
}

View File

@ -18,6 +18,7 @@ import java.security.PrivilegedExceptionAction;
import java.security.ProtectionDomain;
import java.text.FieldPosition;
import java.text.Format;
import java.text.NumberFormat;
import java.text.ParsePosition;
import java.util.ArrayList;
import java.util.List;
@ -125,6 +126,11 @@ public class ExpressionFormat extends Format {
Object value = ((CompiledScript) snipped).eval(context);
if (value != null) {
if (value instanceof Double && value.equals(Math.floor((Double) value))) {
// value is really an integer, not a decimal (number literals -1, 0 and 1 are interpreted as decimal by rhino)
value = NumberFormat.getIntegerInstance().format(value);
}
sb.append(value);
}
} catch (ScriptException e) {

View File

@ -64,6 +64,8 @@ public class SeasonEpisodeMatcher {
public static class SxE {
public static final int UNDEFINED = -1;
public final int season;
public final int episode;
@ -81,7 +83,11 @@ public class SeasonEpisodeMatcher {
protected int parse(String number) {
return number == null || number.isEmpty() ? 0 : Integer.parseInt(number);
try {
return Integer.parseInt(number);
} catch (Exception e) {
return UNDEFINED;
}
}

View File

@ -27,12 +27,12 @@ public class SeasonEpisodeSimilarityMetric implements SimilarityMetric {
for (SxE sxe1 : sxeVector1) {
for (SxE sxe2 : sxeVector2) {
if (sxe1.episode == sxe2.episode) {
if (sxe1.season == sxe2.season) {
// vectors have at least one perfect episode match in common
return 1;
}
if (sxe1.episode == sxe2.episode && sxe1.season == sxe2.season) {
// vectors have at least one perfect episode match in common
return 1;
}
if (sxe1.episode == sxe2.episode || sxe1.season == sxe2.season) {
// at least we have a partial match
similarity = 0.5f;
}

View File

@ -54,7 +54,7 @@ import net.sourceforge.filebot.Settings;
import net.sourceforge.filebot.format.EpisodeFormatBindingBean;
import net.sourceforge.filebot.format.ExpressionFormat;
import net.sourceforge.filebot.web.Episode;
import net.sourceforge.filebot.web.Episode.EpisodeFormat;
import net.sourceforge.filebot.web.EpisodeFormat;
import net.sourceforge.tuned.DefaultThreadFactory;
import net.sourceforge.tuned.ExceptionUtilities;
import net.sourceforge.tuned.ui.GradientStyle;
@ -392,10 +392,13 @@ public class EpisodeFormatDialog extends JDialog {
try {
preview.setText(get());
// check internal script exception and empty output
// check internal script exception
if (format.scriptException() != null) {
throw format.scriptException();
} else if (get().trim().isEmpty()) {
}
// check empty output
if (get().trim().isEmpty()) {
throw new RuntimeException("Formatted value is empty");
}
@ -406,7 +409,7 @@ public class EpisodeFormatDialog extends JDialog {
status.setIcon(ResourceManager.getIcon("status.warning"));
status.setVisible(true);
} finally {
preview.setVisible(true);
preview.setVisible(preview.getText().trim().length() > 0);
editor.setForeground(defaultColor);
progressIndicatorTimer.stop();

View File

@ -81,12 +81,14 @@ class AutoFetchEpisodeListMatcher extends SwingWorker<List<Match<File, Episode>>
public Collection<Episode> call() throws Exception {
Collection<SearchResult> results = provider.search(seriesName);
if (results.size() > 0) {
SearchResult selectedSearchResult = selectSearchResult(seriesName, results);
if (selectedSearchResult != null) {
return provider.getEpisodeList(selectedSearchResult);
}
if (results.isEmpty()) {
throw new RuntimeException(String.format("'%s' has not been found.", seriesName));
}
SearchResult selectedSearchResult = selectSearchResult(seriesName, results);
if (selectedSearchResult != null) {
return provider.getEpisodeList(selectedSearchResult);
}
return Collections.emptyList();

View File

@ -10,7 +10,7 @@ import net.sourceforge.filebot.format.EpisodeFormatBindingBean;
import net.sourceforge.filebot.format.ExpressionFormat;
import net.sourceforge.filebot.similarity.Match;
import net.sourceforge.filebot.web.Episode;
import net.sourceforge.filebot.web.Episode.EpisodeFormat;
import net.sourceforge.filebot.web.EpisodeFormat;
public class EpisodeExpressionFormatter extends ExpressionFormat implements MatchFormatter {

View File

@ -79,13 +79,8 @@ class MatchAction extends AbstractAction {
if (o instanceof Episode) {
Episode episode = (Episode) o;
try {
// create SxE from episode
return Collections.singleton(new SxE(episode.getSeasonNumber(), episode.getEpisodeNumber()));
} catch (NumberFormatException e) {
// some kind of special episode, no SxE
return null;
}
// create SxE from episode
return Collections.singleton(new SxE(episode.getSeason(), episode.getEpisode()));
}
return super.parse(o);

View File

@ -180,12 +180,12 @@ public class RenamePanel extends JComponent {
protected ActionPopup createSettingsPopup() {
ActionPopup actionPopup = new ActionPopup("Settings", ResourceManager.getIcon("action.rename.small"));
ActionPopup actionPopup = new ActionPopup("Rename Settings", ResourceManager.getIcon("action.rename.small"));
actionPopup.addDescription(new JLabel("Extension:"));
actionPopup.add(new PreserveExtensionAction(true, "Preserve", ResourceManager.getIcon("action.extension.preserve")));
actionPopup.add(new PreserveExtensionAction(false, "Include", ResourceManager.getIcon("action.extension.include")));
actionPopup.add(new PreserveExtensionAction(false, "Override", ResourceManager.getIcon("action.extension.override")));
return actionPopup;
}

View File

@ -113,7 +113,7 @@ public class AnidbClient implements EpisodeListProvider {
// if number does not match, episode is probably some kind of special (S1, S2, ...)
if (number.matches("\\d+")) {
// no seasons for anime
episodes.add(new Episode(searchResult.getName(), number, title));
episodes.add(new Episode(searchResult.getName(), null, number, title));
}
}

View File

@ -3,42 +3,54 @@ package net.sourceforge.filebot.web;
import java.io.Serializable;
import java.text.FieldPosition;
import java.text.Format;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Episode implements Serializable {
private String seriesName;
private String seasonNumber;
private String episodeNumber;
private String title;
private final String seriesName;
private final String season;
private final String episode;
private final String title;
public Episode(String seriesName, String seasonNumber, String episodeNumber, String title) {
public Episode(String seriesName, Integer season, Integer episode, String title) {
this(seriesName, season.toString(), episode.toString(), title);
}
public Episode(String seriesName, String season, String episode, String title) {
this.seriesName = seriesName;
this.seasonNumber = seasonNumber;
this.episodeNumber = episodeNumber;
this.season = season;
this.episode = episode;
this.title = title;
}
public Episode(String seriesName, String episodeNumber, String title) {
this(seriesName, null, episodeNumber, title);
public String getEpisode() {
return episode;
}
public String getEpisodeNumber() {
return episodeNumber;
public Integer getEpisodeNumber() {
try {
return Integer.valueOf(episode);
} catch (NumberFormatException e) {
return null;
}
}
public String getSeasonNumber() {
return seasonNumber;
public String getSeason() {
return season;
}
public Integer getSeasonNumber() {
try {
return Integer.valueOf(season);
} catch (NumberFormatException e) {
return null;
}
}
@ -57,66 +69,4 @@ public class Episode implements Serializable {
return EpisodeFormat.getInstance().format(this);
}
public static class EpisodeFormat extends Format {
private static final EpisodeFormat instance = new EpisodeFormat();
public static EpisodeFormat getInstance() {
return instance;
}
@Override
public StringBuffer format(Object obj, StringBuffer sb, FieldPosition pos) {
Episode episode = (Episode) obj;
sb.append(episode.getSeriesName()).append(" - ");
if (episode.getSeasonNumber() != null) {
sb.append(episode.getSeasonNumber()).append('x');
}
try {
// try to format episode number
sb.append(String.format("%02d", Integer.parseInt(episode.getEpisodeNumber())));
} catch (NumberFormatException e) {
// use episode "number" as is
sb.append(episode.getEpisodeNumber());
}
return sb.append(" - ").append(episode.getTitle());
}
@Override
public Episode parseObject(String source, ParsePosition pos) {
Pattern pattern = Pattern.compile("(.*) - (?:(\\w+?)x)?(\\w+)? - (.*)");
Matcher matcher = pattern.matcher(source).region(pos.getIndex(), source.length());
if (!matcher.matches()) {
pos.setErrorIndex(matcher.regionStart());
return null;
}
// episode number must not be null
if (matcher.group(3) == null) {
pos.setErrorIndex(matcher.start(3));
return null;
}
pos.setIndex(matcher.end());
return new Episode(matcher.group(1), matcher.group(2), matcher.group(3), matcher.group(4));
}
@Override
public Episode parseObject(String source) throws ParseException {
return (Episode) super.parseObject(source);
}
}
}

View File

@ -0,0 +1,69 @@
package net.sourceforge.filebot.web;
import java.text.FieldPosition;
import java.text.Format;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class EpisodeFormat extends Format {
private static final EpisodeFormat instance = new EpisodeFormat();
public static EpisodeFormat getInstance() {
return instance;
}
@Override
public StringBuffer format(Object obj, StringBuffer sb, FieldPosition pos) {
Episode episode = (Episode) obj;
sb.append(episode.getSeriesName()).append(" - ");
if (episode.getSeason() != null) {
sb.append(episode.getSeason()).append('x');
}
Integer episodeNumber = episode.getEpisodeNumber();
// try to format episode number, or use episode "number" string as is
sb.append(episodeNumber != null ? String.format("%02d", episodeNumber) : episode.getEpisode());
return sb.append(" - ").append(episode.getTitle());
}
@Override
public Episode parseObject(String source, ParsePosition pos) {
Pattern pattern = Pattern.compile("(.*) - (?:(\\w+?)x)?(\\w+)? - (.*)");
Matcher matcher = pattern.matcher(source).region(pos.getIndex(), source.length());
if (!matcher.matches()) {
pos.setErrorIndex(matcher.regionStart());
return null;
}
// episode number must not be null
if (matcher.group(3) == null) {
pos.setErrorIndex(matcher.start(3));
return null;
}
pos.setIndex(matcher.end());
return new Episode(matcher.group(1), matcher.group(2), matcher.group(3), matcher.group(4));
}
@Override
public Episode parseObject(String source) throws ParseException {
return (Episode) super.parseObject(source);
}
}

View File

@ -15,7 +15,7 @@ public final class EpisodeListUtilities {
// filter given season from all seasons
for (Episode episode : episodes) {
try {
if (season == Integer.parseInt(episode.getSeasonNumber())) {
if (season == Integer.parseInt(episode.getSeason())) {
results.add(episode);
}
} catch (NumberFormatException e) {
@ -33,7 +33,7 @@ public final class EpisodeListUtilities {
// filter given season from all seasons
for (Episode episode : episodes) {
try {
lastSeason = Math.max(lastSeason, Integer.parseInt(episode.getSeasonNumber()));
lastSeason = Math.max(lastSeason, Integer.parseInt(episode.getSeason()));
} catch (NumberFormatException e) {
// ignore illegal episodes
}

View File

@ -18,6 +18,8 @@ import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.Icon;
@ -68,9 +70,16 @@ public class IMDbClient implements EpisodeListProvider {
String href = getAttribute("href", node);
String nameAndYear = String.format("%s %s", name, year).trim();
int imdbId = new Scanner(href).useDelimiter("\\D+").nextInt();
results.add(new MovieDescriptor(nameAndYear, imdbId));
results.add(new MovieDescriptor(nameAndYear, getImdbId(href)));
}
// we might have been redirected to the movie page
if (results.isEmpty()) {
String name = removeQuotationMarks(selectString("//H1/text()", dom));
String url = selectString("//LINK[@rel='canonical']/@href", dom);
results.add(new MovieDescriptor(name, getImdbId(url)));
}
return results;
@ -129,6 +138,30 @@ public class IMDbClient implements EpisodeListProvider {
}
protected int getImdbId(String link) {
try {
// try to extract path
link = new URI(link).getPath();
} catch (URISyntaxException e) {
// cannot extract path component, just move on
}
Matcher matcher = Pattern.compile("tt(\\d{7})").matcher(link);
String imdbId = null;
// find last match
while (matcher.find()) {
imdbId = matcher.group(1);
}
if (imdbId == null)
throw new IllegalArgumentException(String.format("Cannot find imdb id: %s", link));
return Integer.parseInt(imdbId);
}
@Override
public URI getEpisodeListLink(SearchResult searchResult) {
return getEpisodeListLink(searchResult, 0);

View File

@ -144,23 +144,34 @@ public class TVDotComClient implements EpisodeListProvider {
List<Node> nodes = selectNodes("id('episode_guide_list')//*[@class='info']", dom);
Pattern seasonEpisodePattern = Pattern.compile("Season (\\d+), Episode (\\d+)");
Pattern episodePattern = Pattern.compile("Season (\\d+). Episode (\\d+)");
Pattern specialPattern = Pattern.compile("Special. Season (\\d+)");
List<Episode> episodes = new ArrayList<Episode>(nodes.size());
for (Node node : nodes) {
String meta = selectString("./*[@class='meta']", node);
String title = selectString("./H3/A/text()", node);
String meta = selectString("./*[@class='meta']", node).replaceAll("\\p{Space}+", " ");
// normalize space and then match season and episode numbers
Matcher matcher = seasonEpisodePattern.matcher(meta.replaceAll("\\p{Space}+", " "));
String season = null;
String episode = null;
if (matcher.find()) {
String title = selectString("./H3/A/text()", node);
String season = matcher.group(1);
String episode = matcher.group(2);
episodes.add(new Episode(searchResult.getName(), season, episode, title));
Matcher matcher;
if ((matcher = episodePattern.matcher(meta)).find()) {
// matches episode
season = matcher.group(1);
episode = matcher.group(2);
} else if ((matcher = specialPattern.matcher(meta)).find()) {
// matches special
season = matcher.group(1);
episode = "Special";
} else {
// no episode match
continue;
}
episodes.add(new Episode(searchResult.getName(), season, episode, title));
}
return episodes;

View File

@ -5,6 +5,7 @@ package net.sourceforge.filebot.web;
import static net.sourceforge.filebot.web.EpisodeListUtilities.filterBySeason;
import static net.sourceforge.filebot.web.EpisodeListUtilities.getLastSeason;
import static net.sourceforge.filebot.web.WebRequest.getDocument;
import static net.sourceforge.tuned.XPathUtilities.getAttribute;
import static net.sourceforge.tuned.XPathUtilities.getTextContent;
import static net.sourceforge.tuned.XPathUtilities.selectNodes;
import static net.sourceforge.tuned.XPathUtilities.selectString;
@ -94,14 +95,20 @@ public class TVRageClient implements EpisodeListProvider {
Document dom = getDocument(episodeListUrl);
String seriesName = selectString("Show/name", dom);
List<Node> nodes = selectNodes("Show/Episodelist/Season/episode", dom);
List<Episode> episodes = new ArrayList<Episode>(nodes.size());
List<Episode> episodes = new ArrayList<Episode>(25);
for (Node node : nodes) {
// episodes and specials
for (Node node : selectNodes("//episode", dom)) {
String title = getTextContent("title", node);
String episodeNumber = getTextContent("seasonnum", node);
String seasonNumber = node.getParentNode().getAttributes().getNamedItem("no").getTextContent();
String seasonNumber = getAttribute("no", node.getParentNode());
// check if we have season and episode number, if not it must be a special episode
if (episodeNumber == null || seasonNumber == null) {
episodeNumber = "Special";
seasonNumber = getTextContent("season", node);
}
episodes.add(new Episode(seriesName, seasonNumber, episodeNumber, title));
}

View File

@ -144,6 +144,13 @@ public class TheTVDBClient implements EpisodeListProvider {
String episodeNumber = getTextContent("EpisodeNumber", node);
String seasonNumber = getTextContent("SeasonNumber", node);
if (seasonNumber.equals("0")) {
String airsBefore = getTextContent("airsbefore_season", node);
seasonNumber = airsBefore.isEmpty() ? null : airsBefore;
episodeNumber = "Special";
}
episodes.add(new Episode(seriesName, seasonNumber, episodeNumber, episodeName));
if (episodeNumber.equals("1")) {

View File

@ -77,7 +77,12 @@ public final class XPathUtilities {
public static String getAttribute(String attribute, Node node) {
return node.getAttributes().getNamedItem(attribute).getNodeValue().trim();
Node attributeNode = node.getAttributes().getNamedItem(attribute);
if (attributeNode != null)
return attributeNode.getNodeValue().trim();
return null;
}

View File

@ -15,7 +15,7 @@ public class ArgumentBeanTest {
@Test
public void clear() throws Exception {
ArgumentBean bean = parse("-clear", "--analyze", "One Piece", "Naruto");
ArgumentBean bean = parse("-clear", "--sfv", "One Piece", "Naruto");
assertTrue(bean.clear());
assertFalse(bean.help());

View File

@ -2,7 +2,9 @@
package net.sourceforge.filebot.similarity;
import static net.sourceforge.filebot.similarity.SeasonEpisodeMatcher.SxE.UNDEFINED;
import static org.junit.Assert.assertEquals;
import net.sourceforge.filebot.similarity.SeasonEpisodeMatcher.SxE;
import org.junit.Test;
@ -15,52 +17,52 @@ public class SeasonEpisodeMatcherTest {
@Test
public void patternPrecedence() {
// S01E01 pattern has highest precedence
assertEquals("1x03", matcher.match("Test.101.1x02.S01E03").get(0).toString());
assertEquals(new SxE(1, 3), matcher.match("Test.101.1x02.S01E03").get(0));
// multiple values
assertEquals("1x02", matcher.match("Test.42.s01e01.s01e02.300").get(1).toString());
assertEquals(new SxE(1, 2), matcher.match("Test.42.s01e01.s01e02.300").get(1));
}
@Test
public void pattern_1x01() {
assertEquals("1x01", matcher.match("1x01").get(0).toString());
assertEquals(new SxE(1, 1), matcher.match("1x01").get(0));
// test multiple matches
assertEquals("1x02", matcher.match("Test - 1x01 and 1.02 - Multiple MatchCollection").get(1).toString());
assertEquals(new SxE(1, 2), matcher.match("Test - 1x01 and 1.02 - Multiple MatchCollection").get(1));
// test high values
assertEquals("12x345", matcher.match("Test - 12x345 - High Values").get(0).toString());
assertEquals(new SxE(12, 345), matcher.match("Test - 12x345 - High Values").get(0));
// test lookahead and lookbehind
assertEquals("1x03", matcher.match("Test_-_103_[1280x720]").get(0).toString());
assertEquals(new SxE(1, 3), matcher.match("Test_-_103_[1280x720]").get(0));
}
@Test
public void pattern_S01E01() {
assertEquals("1x01", matcher.match("S01E01").get(0).toString());
assertEquals(new SxE(1, 1), matcher.match("S01E01").get(0));
// test multiple matches
assertEquals("1x02", matcher.match("S01E01 and S01E02 - Multiple MatchCollection").get(1).toString());
assertEquals(new SxE(1, 2), matcher.match("S01E01 and S01E02 - Multiple MatchCollection").get(1));
// test separated values
assertEquals("1x03", matcher.match("[s01]_[e03]").get(0).toString());
assertEquals(new SxE(1, 3), matcher.match("[s01]_[e03]").get(0));
// test high values
assertEquals("12x345", matcher.match("Test - S12E345 - High Values").get(0).toString());
assertEquals(new SxE(12, 345), matcher.match("Test - S12E345 - High Values").get(0));
}
@Test
public void pattern_101() {
assertEquals("1x01", matcher.match("Test.101").get(0).toString());
assertEquals(new SxE(1, 1), matcher.match("Test.101").get(0));
// test 2-digit number
assertEquals("0x02", matcher.match("02").get(0).toString());
assertEquals(new SxE(UNDEFINED, 2), matcher.match("02").get(0));
// test high values
assertEquals("10x01", matcher.match("[Test]_1001_High_Values").get(0).toString());
assertEquals(new SxE(10, 1), matcher.match("[Test]_1001_High_Values").get(0));
// first two digits <= 29
assertEquals(null, matcher.match("The 4400"));

View File

@ -20,8 +20,8 @@ public class SeasonEpisodeSimilarityMetricTest {
// multiple pattern matches, single episode match
assertEquals(1.0, metric.getSimilarity("1x02a", "101 102 103"), 0);
// multiple pattern matches, no episode match
assertEquals(0.0, metric.getSimilarity("1x03b", "104 105 106"), 0);
// multiple pattern matches, only partial match (season)
assertEquals(0.5, metric.getSimilarity("1x03b", "104 105 106"), 0);
// no pattern match, no episode match
assertEquals(0.0, metric.getSimilarity("abc", "xyz"), 0);

View File

@ -67,8 +67,8 @@ public class AnidbClientTest {
assertEquals("Monster", first.getSeriesName());
assertEquals("Herr Dr. Tenma", first.getTitle());
assertEquals("1", first.getEpisodeNumber());
assertEquals(null, first.getSeasonNumber());
assertEquals("1", first.getEpisode());
assertEquals(null, first.getSeason());
}
@ -82,8 +82,8 @@ public class AnidbClientTest {
assertEquals("Juuni Kokuki", first.getSeriesName());
assertEquals("Shadow of the Moon, The Sea of Shadow - Chapter 1", first.getTitle());
assertEquals("1", first.getEpisodeNumber());
assertEquals(null, first.getSeasonNumber());
assertEquals("1", first.getEpisode());
assertEquals(null, first.getSeason());
}

View File

@ -27,6 +27,20 @@ public class IMDbClientTest {
}
@Test
public void searchResultPageRedirect() throws Exception {
List<SearchResult> results = imdb.search("my name is earl");
// exactly one search result
assertEquals(1, results.size(), 0);
MovieDescriptor movie = (MovieDescriptor) results.get(0);
assertEquals("My Name Is Earl", movie.getName());
assertEquals(460091, movie.getImdbId(), 0);
}
@Test
public void getEpisodeList() throws Exception {
List<Episode> list = imdb.getEpisodeList(new MovieDescriptor("Buffy", 118276));
@ -37,15 +51,15 @@ public class IMDbClientTest {
assertEquals("Buffy the Vampire Slayer", first.getSeriesName());
assertEquals("Unaired Pilot", first.getTitle());
assertEquals("0", first.getEpisodeNumber());
assertEquals("1", first.getSeasonNumber());
assertEquals("0", first.getEpisode());
assertEquals("1", first.getSeason());
Episode last = list.get(144);
assertEquals("Buffy the Vampire Slayer", last.getSeriesName());
assertEquals("Chosen", last.getTitle());
assertEquals("22", last.getEpisodeNumber());
assertEquals("7", last.getSeasonNumber());
assertEquals("22", last.getEpisode());
assertEquals("7", last.getSeason());
}
@ -59,8 +73,8 @@ public class IMDbClientTest {
assertEquals("Mushishi", first.getSeriesName());
assertEquals("Midori no za", first.getTitle());
assertEquals("1", first.getEpisodeNumber());
assertEquals("1", first.getSeasonNumber());
assertEquals("1", first.getEpisode());
assertEquals("1", first.getSeason());
}

View File

@ -49,8 +49,8 @@ public class TVDotComClientTest {
assertEquals("Buffy the Vampire Slayer", chosen.getSeriesName());
assertEquals("Chosen", chosen.getTitle());
assertEquals("22", chosen.getEpisodeNumber());
assertEquals("7", chosen.getSeasonNumber());
assertEquals("22", chosen.getEpisode());
assertEquals("7", chosen.getSeason());
}
@ -65,8 +65,8 @@ public class TVDotComClientTest {
assertEquals("Buffy the Vampire Slayer", first.getSeriesName());
assertEquals("Welcome to the Hellmouth (1)", first.getTitle());
assertEquals("1", first.getEpisodeNumber());
assertEquals("1", first.getSeasonNumber());
assertEquals("1", first.getEpisode());
assertEquals("1", first.getSeason());
}
@ -81,8 +81,8 @@ public class TVDotComClientTest {
assertEquals("Firefly", fourth.getSeriesName());
assertEquals("Jaynestown", fourth.getTitle());
assertEquals("4", fourth.getEpisodeNumber());
assertEquals("1", fourth.getSeasonNumber());
assertEquals("4", fourth.getEpisode());
assertEquals("1", fourth.getSeason());
}
@ -104,8 +104,8 @@ public class TVDotComClientTest {
assertEquals("Lost", episode.getSeriesName());
assertEquals("Exposé", episode.getTitle());
assertEquals("14", episode.getEpisodeNumber());
assertEquals("3", episode.getSeasonNumber());
assertEquals("14", episode.getEpisode());
assertEquals("3", episode.getSeason());
}

View File

@ -43,8 +43,8 @@ public class TVRageClientTest {
assertEquals("Buffy the Vampire Slayer", chosen.getSeriesName());
assertEquals("Chosen", chosen.getTitle());
assertEquals("22", chosen.getEpisodeNumber());
assertEquals("7", chosen.getSeasonNumber());
assertEquals("22", chosen.getEpisode());
assertEquals("7", chosen.getSeason());
}
@ -58,8 +58,8 @@ public class TVRageClientTest {
assertEquals("Buffy the Vampire Slayer", first.getSeriesName());
assertEquals("Unaired Pilot", first.getTitle());
assertEquals("00", first.getEpisodeNumber());
assertEquals("0", first.getSeasonNumber());
assertEquals("00", first.getEpisode());
assertEquals("0", first.getSeason());
}

View File

@ -72,8 +72,8 @@ public class TheTVDBClientTest {
assertEquals("Buffy the Vampire Slayer", first.getSeriesName());
assertEquals("Unaired Pilot", first.getTitle());
assertEquals("1", first.getEpisodeNumber());
assertEquals("0", first.getSeasonNumber());
assertEquals("Special", first.getEpisode());
assertEquals("1", first.getSeason());
}
@ -87,8 +87,8 @@ public class TheTVDBClientTest {
assertEquals("Buffy the Vampire Slayer", chosen.getSeriesName());
assertEquals("Chosen", chosen.getTitle());
assertEquals("22", chosen.getEpisodeNumber());
assertEquals("7", chosen.getSeasonNumber());
assertEquals("22", chosen.getEpisode());
assertEquals("7", chosen.getSeason());
}