From df143e0305d09014c97fe217f83d1bd6eee7c3e5 Mon Sep 17 00:00:00 2001 From: Reinhard Pointner Date: Tue, 17 Mar 2009 21:59:19 +0000 Subject: [PATCH] * added episode list support for IMDb --- fw/search.imdb.png | Bin 31565 -> 31961 bytes .../filebot/resources/search.imdb.png | Bin 0 -> 308 bytes .../similarity/SeasonEpisodeMatcher.java | 4 +- .../panel/episodelist/EpisodeListPanel.java | 9 +- .../panel/rename/RenameListCellRenderer.java | 2 +- .../filebot/ui/panel/rename/RenamePanel.java | 2 + .../sourceforge/filebot/web/AnidbClient.java | 2 +- .../sourceforge/filebot/web/IMDbClient.java | 162 ++++++++++++++++++ .../filebot/web/SubsceneSubtitleClient.java | 2 +- .../filebot/web/TheTVDBClient.java | 11 +- .../filebot/web/IMDbClientTest.java | 79 +++++++++ .../sourceforge/filebot/web/WebTestSuite.java | 2 +- 12 files changed, 257 insertions(+), 18 deletions(-) create mode 100644 source/net/sourceforge/filebot/resources/search.imdb.png create mode 100644 source/net/sourceforge/filebot/web/IMDbClient.java create mode 100644 test/net/sourceforge/filebot/web/IMDbClientTest.java diff --git a/fw/search.imdb.png b/fw/search.imdb.png index aab7bc8afdcd5660dfb26a73a61a59d6d311a44d..d7adccad1cc411ac7168dec125813a940fecfb12 100644 GIT binary patch delta 8681 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 literal 0 HcmV?d00001 diff --git a/source/net/sourceforge/filebot/similarity/SeasonEpisodeMatcher.java b/source/net/sourceforge/filebot/similarity/SeasonEpisodeMatcher.java index f29d6239..1591c26b 100644 --- a/source/net/sourceforge/filebot/similarity/SeasonEpisodeMatcher.java +++ b/source/net/sourceforge/filebot/similarity/SeasonEpisodeMatcher.java @@ -16,10 +16,10 @@ public class SeasonEpisodeMatcher { public SeasonEpisodeMatcher() { patterns = new SeasonEpisodePattern[3]; - // match patterns like S01E01, s01e02, ... [s01]_[e02], s01.e02, ... + // match patterns like S01E01, s01e02, ... [s01]_[e02], s01.e02, s01e02a, ... patterns[0] = new SeasonEpisodePattern("(? search(String query) throws IOException, SAXException { + + URL searchUrl = new URL("http", host, "/find?s=tt&q=" + URLEncoder.encode(query, "UTF-8")); + + Document dom = getHtmlDocument(openConnection(searchUrl)); + + List nodes = selectNodes("//TABLE//A[following-sibling::SMALL[contains(.,'TV series')]]", dom); + + List results = new ArrayList(nodes.size()); + + for (Node node : nodes) { + String name = removeQuotationMarks(node.getTextContent().trim()); + String year = node.getNextSibling().getTextContent().trim(); + 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)); + } + + return results; + } + + + @Override + public List getEpisodeList(SearchResult searchResult) throws IOException, SAXException { + Document dom = getHtmlDocument(openConnection(getEpisodeListLink(searchResult).toURL())); + + String seriesName = removeQuotationMarks(selectString("//H1/A", dom)); + + List nodes = selectNodes("//TABLE//H3/A[preceding-sibling::text()]", dom); + + List episodes = new ArrayList(nodes.size()); + + for (Node node : nodes) { + String title = node.getTextContent().trim(); + + Scanner numberScanner = new Scanner(node.getPreviousSibling().getTextContent()).useDelimiter("\\D+"); + String season = numberScanner.next(); + String episode = numberScanner.next(); + + episodes.add(new Episode(seriesName, season, episode, title)); + } + + return episodes; + } + + + @Override + public List getEpisodeList(SearchResult searchResult, int season) throws Exception { + + List episodes = new ArrayList(25); + + // remember max. season, so we can throw a proper exception, in case an illegal season number was requested + int maxSeason = 0; + + // filter given season from all seasons + for (Episode episode : getEpisodeList(searchResult)) { + try { + int seasonNumber = Integer.parseInt(episode.getSeasonNumber()); + + if (season == seasonNumber) { + episodes.add(episode); + } + + if (seasonNumber > maxSeason) { + maxSeason = seasonNumber; + } + } catch (NumberFormatException e) { + Logger.getLogger(getClass().getName()).log(Level.WARNING, "Illegal season number", e); + } + } + + if (episodes.isEmpty()) { + throw new SeasonOutOfBoundsException(searchResult.getName(), season, maxSeason); + } + + return episodes; + } + + + protected URLConnection openConnection(URL url) throws IOException { + URLConnection connection = url.openConnection(); + + // IMDb refuses default user agent (Java/1.6.0_12) + connection.addRequestProperty("User-Agent", "Scraper"); + + return connection; + } + + + protected String removeQuotationMarks(String name) { + return name.replaceAll("^\"|\"$", ""); + } + + + @Override + public URI getEpisodeListLink(SearchResult searchResult) { + return URI.create("http://" + host + String.format("/title/tt%07d/episodes", ((MovieDescriptor) searchResult).getImdbId())); + } + + + @Override + public URI getEpisodeListLink(SearchResult searchResult, int season) { + return null; + } + +} diff --git a/source/net/sourceforge/filebot/web/SubsceneSubtitleClient.java b/source/net/sourceforge/filebot/web/SubsceneSubtitleClient.java index 81d7dbf5..23864322 100644 --- a/source/net/sourceforge/filebot/web/SubsceneSubtitleClient.java +++ b/source/net/sourceforge/filebot/web/SubsceneSubtitleClient.java @@ -117,7 +117,7 @@ public class SubsceneSubtitleClient implements SubtitleClient { Document subtitleListDocument = getSubtitleListDocument(subtitleListUrl, languageFilter); // let's update language filters if they are not known yet - if (languageFilterMap.isEmpty()) { + if (languageName != null && languageFilter == null) { synchronized (languageFilterMap) { languageFilterMap.putAll(getLanguageFilterMap(subtitleListDocument)); } diff --git a/source/net/sourceforge/filebot/web/TheTVDBClient.java b/source/net/sourceforge/filebot/web/TheTVDBClient.java index 624a4584..9974b6c3 100644 --- a/source/net/sourceforge/filebot/web/TheTVDBClient.java +++ b/source/net/sourceforge/filebot/web/TheTVDBClient.java @@ -10,7 +10,6 @@ import static net.sourceforge.tuned.XPathUtilities.selectString; import java.io.FileNotFoundException; import java.io.IOException; import java.net.URI; -import java.net.URISyntaxException; import java.net.URL; import java.net.URLEncoder; import java.util.ArrayList; @@ -205,11 +204,7 @@ public class TheTVDBClient implements EpisodeListClient { public URI getEpisodeListLink(SearchResult searchResult) { int seriesId = ((TheTVDBSearchResult) searchResult).getSeriesId(); - try { - return new URI("http://" + host + "/?tab=seasonall&id=" + seriesId); - } catch (URISyntaxException e) { - throw new RuntimeException(e); - } + return URI.create("http://" + host + "/?tab=seasonall&id=" + seriesId); } @@ -230,11 +225,9 @@ public class TheTVDBClient implements EpisodeListClient { } return new URI("http://" + host + "/?tab=season&seriesid=" + seriesId + "&seasonid=" + seasonId); - } catch (IOException e) { + } catch (Exception e) { // log and ignore any IOException Logger.getLogger(getClass().getName()).log(Level.WARNING, "Failed to retrieve season id", e); - } catch (Exception e) { - throw new RuntimeException(e); } return null; diff --git a/test/net/sourceforge/filebot/web/IMDbClientTest.java b/test/net/sourceforge/filebot/web/IMDbClientTest.java new file mode 100644 index 00000000..4a8bc1d0 --- /dev/null +++ b/test/net/sourceforge/filebot/web/IMDbClientTest.java @@ -0,0 +1,79 @@ + +package net.sourceforge.filebot.web; + + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.Test; + + +public class IMDbClientTest { + + private final IMDbClient imdb = new IMDbClient(); + + + @Test + public void search() throws Exception { + List results = imdb.search("battlestar"); + + MovieDescriptor movie = (MovieDescriptor) results.get(0); + + assertEquals("Battlestar Galactica (2004)", movie.getName()); + assertEquals(407362, movie.getImdbId(), 0); + + assertEquals(6, results.size(), 0); + } + + + @Test + public void getEpisodeList() throws Exception { + List list = imdb.getEpisodeList(new MovieDescriptor("Buffy", 118276)); + + assertEquals(145, list.size()); + + Episode first = list.get(0); + + assertEquals("Buffy the Vampire Slayer", first.getSeriesName()); + assertEquals("Unaired Pilot", first.getTitle()); + assertEquals("0", first.getEpisodeNumber()); + assertEquals("1", first.getSeasonNumber()); + + Episode last = list.get(144); + + assertEquals("Buffy the Vampire Slayer", last.getSeriesName()); + assertEquals("Chosen", last.getTitle()); + assertEquals("22", last.getEpisodeNumber()); + assertEquals("7", last.getSeasonNumber()); + } + + + @Test + public void getEpisodeListWithUnknownSeason() throws Exception { + List list = imdb.getEpisodeList(new MovieDescriptor("Mushishi", 807832)); + + assertEquals(26, list.size()); + + Episode first = list.get(0); + + assertEquals("Mushishi", first.getSeriesName()); + assertEquals("Midori no za", first.getTitle()); + assertEquals("1", first.getEpisodeNumber()); + assertEquals("1", first.getSeasonNumber()); + } + + + @Test + public void getEpisodeListLink() throws Exception { + assertEquals("http://www.imdb.com/title/tt0407362/episodes", imdb.getEpisodeListLink(new MovieDescriptor("Battlestar Galactica", 407362)).toString()); + } + + + @Test + public void removeQuotationMarks() throws Exception { + assertEquals("test", imdb.removeQuotationMarks("\"test\"")); + + assertEquals("inner \"quotation marks\"", imdb.removeQuotationMarks("\"inner \"quotation marks\"\"")); + } +} diff --git a/test/net/sourceforge/filebot/web/WebTestSuite.java b/test/net/sourceforge/filebot/web/WebTestSuite.java index 46c885a2..37993dc0 100644 --- a/test/net/sourceforge/filebot/web/WebTestSuite.java +++ b/test/net/sourceforge/filebot/web/WebTestSuite.java @@ -8,7 +8,7 @@ import org.junit.runners.Suite.SuiteClasses; @RunWith(Suite.class) -@SuiteClasses( { TVDotComClientTest.class, AnidbClientTest.class, TVRageClientTest.class, TheTVDBClientTest.class, SubsceneSubtitleClientTest.class, SubtitleSourceClientTest.class, OpenSubtitlesHasherTest.class }) +@SuiteClasses( { TVDotComClientTest.class, AnidbClientTest.class, TVRageClientTest.class, TheTVDBClientTest.class, IMDbClientTest.class, SubsceneSubtitleClientTest.class, SubtitleSourceClientTest.class, OpenSubtitlesHasherTest.class }) public class WebTestSuite { }