diff --git a/lib/ehcache.jar b/lib/ehcache.jar index bd44940f..e8a86628 100644 Binary files a/lib/ehcache.jar and b/lib/ehcache.jar differ diff --git a/lib/jna.jar b/lib/jna.jar index 4853c81e..be403140 100644 Binary files a/lib/jna.jar and b/lib/jna.jar differ diff --git a/lib/native/darwin/libmediainfo.dylib b/lib/native/darwin/libmediainfo.dylib deleted file mode 100644 index 6608b819..00000000 Binary files a/lib/native/darwin/libmediainfo.dylib and /dev/null differ diff --git a/lib/native/linux-amd64/libmediainfo.so b/lib/native/linux-amd64/libmediainfo.so index 6569f796..4f2203c9 100644 Binary files a/lib/native/linux-amd64/libmediainfo.so and b/lib/native/linux-amd64/libmediainfo.so differ diff --git a/lib/native/linux-amd64/libzen.so b/lib/native/linux-amd64/libzen.so index e25b338a..c5a7ebd1 100644 Binary files a/lib/native/linux-amd64/libzen.so and b/lib/native/linux-amd64/libzen.so differ diff --git a/lib/native/linux-i386/libmediainfo.so b/lib/native/linux-i386/libmediainfo.so index 99e7d77f..3bd8f90e 100644 Binary files a/lib/native/linux-i386/libmediainfo.so and b/lib/native/linux-i386/libmediainfo.so differ diff --git a/lib/native/linux-i386/libzen.so b/lib/native/linux-i386/libzen.so index 8b783467..0ccd9288 100644 Binary files a/lib/native/linux-i386/libzen.so and b/lib/native/linux-i386/libzen.so differ diff --git a/lib/native/win32-amd64/MediaInfo.dll b/lib/native/win32-amd64/MediaInfo.dll index 52b82cfd..4f617dc8 100644 Binary files a/lib/native/win32-amd64/MediaInfo.dll and b/lib/native/win32-amd64/MediaInfo.dll differ diff --git a/lib/native/win32-x86/MediaInfo.dll b/lib/native/win32-x86/MediaInfo.dll index 9b79f860..598f29bf 100644 Binary files a/lib/native/win32-x86/MediaInfo.dll and b/lib/native/win32-x86/MediaInfo.dll differ diff --git a/lib/nekohtml.jar b/lib/nekohtml.jar index 5b61ccf2..a8081d29 100644 Binary files a/lib/nekohtml.jar and b/lib/nekohtml.jar differ diff --git a/source/ehcache.xml b/source/ehcache.xml index f4f4c6f0..d60fa647 100644 --- a/source/ehcache.xml +++ b/source/ehcache.xml @@ -137,8 +137,11 @@ --> @@ -152,7 +155,7 @@ eternal="false" timeToIdleSeconds="7200" timeToLiveSeconds="7200" - overflowToDisk="false" + overflowToDisk="false" diskPersistent="false" memoryStoreEvictionPolicy="LRU" /> @@ -162,7 +165,7 @@ Short-lived memory cache for resources like icons. This cache is used by ResourceManager. --> replaceAll(/\s*[( /** - * Replace 'part section'. + * Replace 'part identifier'. * * e.g. "Today Is the Day: Part 1" -> "Today Is the Day, Part 1" * "Today Is the Day (1)" -> "Today Is the Day, Part 1" diff --git a/source/net/sourceforge/filebot/ui/panel/subtitle/SubtitleDropTarget.java b/source/net/sourceforge/filebot/ui/panel/subtitle/SubtitleDropTarget.java index bdde7e94..5268d6d8 100644 --- a/source/net/sourceforge/filebot/ui/panel/subtitle/SubtitleDropTarget.java +++ b/source/net/sourceforge/filebot/ui/panel/subtitle/SubtitleDropTarget.java @@ -144,7 +144,7 @@ abstract class SubtitleDropTarget extends JButton { throw new UnsupportedOperationException("Not implemented yet"); } - if (filter(files, VIDEO_FILES).size() == filter(files, SUBTITLE_FILES).size()) { + if (containsOnlyVideoSubtitleMatches(files)) { // TODO implement upload throw new UnsupportedOperationException("Not implemented yet"); } diff --git a/source/net/sourceforge/filebot/web/AnidbClient.java b/source/net/sourceforge/filebot/web/AnidbClient.java index 857c46fa..4cb5e5ce 100644 --- a/source/net/sourceforge/filebot/web/AnidbClient.java +++ b/source/net/sourceforge/filebot/web/AnidbClient.java @@ -74,9 +74,12 @@ public class AnidbClient implements EpisodeListProvider { for (AnidbSearchResult anime : getAnimeTitles()) { for (String name : new String[] { anime.getMainTitle(), anime.getEnglishTitle() }) { if (name != null) { - float similarity = metric.getSimilarity(name.toLowerCase(), query); + // normalize + name = name.toLowerCase(); - if (similarity > 0.5 || name.toLowerCase().contains(query)) { + float similarity = metric.getSimilarity(name, query); + + if (similarity > 0.5 || name.contains(query)) { resultSet.add(new SimpleEntry(anime, similarity)); // add only once diff --git a/source/net/sourceforge/filebot/web/OpenSubtitlesClient.java b/source/net/sourceforge/filebot/web/OpenSubtitlesClient.java index 28070dd8..84c9e1df 100644 --- a/source/net/sourceforge/filebot/web/OpenSubtitlesClient.java +++ b/source/net/sourceforge/filebot/web/OpenSubtitlesClient.java @@ -8,6 +8,7 @@ import java.net.URI; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.LinkedList; import java.util.List; @@ -61,25 +62,26 @@ public class OpenSubtitlesClient implements SubtitleProvider, VideoHashSubtitleS // require login login(); - @SuppressWarnings("unchecked") - List results = (List) xmlrpc.searchMoviesOnIMDB(query); + // search for movies / series + SearchResult[] result = xmlrpc.searchMoviesOnIMDB(query).toArray(new SearchResult[0]); - return results; + return Arrays.asList(result); } @Override public List getSubtitleList(SearchResult searchResult, String languageName) throws Exception { // singleton array with or empty array + int imdbid = ((MovieDescriptor) searchResult).getImdbId(); String[] languageFilter = languageName != null ? new String[] { getSubLanguageID(languageName) } : new String[0]; // require login login(); - @SuppressWarnings("unchecked") - List subtitles = (List) xmlrpc.searchSubtitles(((MovieDescriptor) searchResult).getImdbId(), languageFilter); + // get subtitle list + SubtitleDescriptor[] subtitles = xmlrpc.searchSubtitles(imdbid, languageFilter).toArray(new SubtitleDescriptor[0]); - return subtitles; + return Arrays.asList(subtitles); } diff --git a/source/net/sourceforge/filebot/web/TMDbClient.java b/source/net/sourceforge/filebot/web/TMDbClient.java new file mode 100644 index 00000000..556b0050 --- /dev/null +++ b/source/net/sourceforge/filebot/web/TMDbClient.java @@ -0,0 +1,86 @@ + +package net.sourceforge.filebot.web; + + +import static net.sourceforge.filebot.web.WebRequest.*; +import static net.sourceforge.tuned.XPathUtilities.*; + +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +import org.w3c.dom.Node; +import org.xml.sax.SAXException; + + +public class TMDbClient implements MovieIdentificationService { + + private static final String host = "api.themoviedb.org"; + private static final String version = "2.1"; + + private final String apikey; + + + public TMDbClient(String apikey) { + this.apikey = apikey; + } + + + public List searchMovie(String query) throws IOException, SAXException { + return getMovies("Movie.search", query); + } + + + public List searchMovie(File file) throws IOException, SAXException { + return getMovies("Hash.getInfo", OpenSubtitlesHasher.computeHash(file)); + } + + + @Override + public MovieDescriptor[] getMovieDescriptors(File[] movieFiles) throws Exception { + MovieDescriptor[] movies = new MovieDescriptor[movieFiles.length]; + + for (int i = 0; i < movies.length; i++) { + List options = searchMovie(movieFiles[i]); + + // just use first result, if possible + movies[i] = options.isEmpty() ? null : options.get(0); + } + + return movies; + } + + + protected List getMovies(String method, String parameter) throws IOException, SAXException { + List result = new ArrayList(); + + for (Node node : selectNodes("//movie", getDocument(getResource(method, parameter)))) { + try { + String name = getTextContent("name", node); + + // release date format will be YYYY-MM-DD, but we only care about the year + int year = new Scanner(getTextContent("released", node)).useDelimiter("\\D+").nextInt(); + + // imdb id will be tt1234567, but we only care about the number + int imdbid = new Scanner(getTextContent("imdb_id", node)).useDelimiter("\\D+").nextInt(); + + result.add(new MovieDescriptor(name, year, imdbid)); + } catch (RuntimeException e) { + // release date or imdb id are undefined + } + } + + return result; + } + + + protected URL getResource(String method, String parameter) throws MalformedURLException { + // e.g. http://api.themoviedb.org/2.1/Movie.search/en/xml/{apikey}/serenity + return new URL("http", host, "/" + version + "/" + method + "/en/xml/" + apikey + "/" + parameter); + } + +} diff --git a/source/net/sourceforge/tuned/TemporaryFolder.java b/source/net/sourceforge/tuned/TemporaryFolder.java index 9bce8809..0ccffd44 100644 --- a/source/net/sourceforge/tuned/TemporaryFolder.java +++ b/source/net/sourceforge/tuned/TemporaryFolder.java @@ -13,11 +13,11 @@ import java.util.UUID; public final class TemporaryFolder { - private static final String tmpdir = System.getProperty("java.io.tmpdir"); + private static final File tmpdir = new File(System.getProperty("java.io.tmpdir")); private static final Map folders = new HashMap(); - + /** * Get a {@link TemporaryFolder} instance for a given name. The actual directory will be * created lazily (e.g. when a file is created). The name of the directory will start with @@ -43,6 +43,7 @@ public final class TemporaryFolder { } } + /** * Delete all temporary folders on shutdown */ @@ -62,7 +63,7 @@ public final class TemporaryFolder { private final File root; - + private TemporaryFolder(File root) { this.root = root; } diff --git a/source/net/sourceforge/tuned/ui/ActionPopup.java b/source/net/sourceforge/tuned/ui/ActionPopup.java index 3130e8de..4e6d4fa8 100644 --- a/source/net/sourceforge/tuned/ui/ActionPopup.java +++ b/source/net/sourceforge/tuned/ui/ActionPopup.java @@ -26,7 +26,7 @@ public class ActionPopup extends JPopupMenu { protected final JPanel actionPanel = new JPanel(new MigLayout("nogrid, insets 0, fill")); - + public ActionPopup(String label, Icon icon) { headerLabel.setText(label); headerLabel.setIcon(icon); @@ -53,7 +53,7 @@ public class ActionPopup extends JPopupMenu { public void addAction(JComponent component) { - actionPanel.add(component, "gapx 12px 12px, wrap"); + actionPanel.add(component, "gapx 12px 12px, growx, wrap"); } @@ -109,6 +109,7 @@ public class ActionPopup extends JPopupMenu { return statusLabel.getText(); } + private final ActionListener closeListener = new ActionListener() { @Override diff --git a/source/net/sourceforge/tuned/ui/LinkButton.java b/source/net/sourceforge/tuned/ui/LinkButton.java index 9e276e0d..979bb3d4 100644 --- a/source/net/sourceforge/tuned/ui/LinkButton.java +++ b/source/net/sourceforge/tuned/ui/LinkButton.java @@ -25,7 +25,7 @@ public class LinkButton extends JButton { private Color color = getForeground(); private Color rolloverColor = SystemColor.textHighlight; - + public LinkButton(String text, Icon icon, URI uri) { this(new OpenUriAction(text, icon, uri)); } @@ -39,6 +39,7 @@ public class LinkButton extends JButton { setContentAreaFilled(false); setBorder(null); + setHorizontalAlignment(LEFT); setIconTextGap(6); setRolloverEnabled(true); @@ -80,6 +81,7 @@ public class LinkButton extends JButton { this.rolloverColor = rolloverColor; } + protected final MouseListener rolloverListener = new MouseAdapter() { @Override @@ -94,12 +96,12 @@ public class LinkButton extends JButton { } }; - + protected static class OpenUriAction extends AbstractAction { public static final String URI = "uri"; - + public OpenUriAction(String text, Icon icon, URI uri) { super(text, icon); putValue(URI, uri); diff --git a/test/net/sourceforge/filebot/web/AnidbClientTest.java b/test/net/sourceforge/filebot/web/AnidbClientTest.java index 1a243a3d..7ec8b96d 100644 --- a/test/net/sourceforge/filebot/web/AnidbClientTest.java +++ b/test/net/sourceforge/filebot/web/AnidbClientTest.java @@ -6,9 +6,11 @@ import static org.junit.Assert.*; import java.util.List; +import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; +import net.sf.ehcache.CacheManager; import net.sourceforge.filebot.web.AnidbClient.AnidbSearchResult; @@ -118,4 +120,11 @@ public class AnidbClientTest { assertEquals("http://anidb.net/a1539", anidb.getEpisodeListLink(monsterSearchResult).toURL().toString()); } + + @BeforeClass + @AfterClass + public static void clearCache() { + CacheManager.getInstance().clearAll(); + } + } diff --git a/test/net/sourceforge/filebot/web/OpenSubtitlesXmlRpcTest.java b/test/net/sourceforge/filebot/web/OpenSubtitlesXmlRpcTest.java index 1973b98e..ddf8272c 100644 --- a/test/net/sourceforge/filebot/web/OpenSubtitlesXmlRpcTest.java +++ b/test/net/sourceforge/filebot/web/OpenSubtitlesXmlRpcTest.java @@ -3,6 +3,7 @@ package net.sourceforge.filebot.web; import static java.util.Collections.*; +import static net.sourceforge.filebot.Settings.*; import static org.junit.Assert.*; import java.nio.ByteBuffer; @@ -21,7 +22,7 @@ import net.sourceforge.filebot.web.OpenSubtitlesXmlRpc.TryUploadResponse; public class OpenSubtitlesXmlRpcTest { - private static OpenSubtitlesXmlRpc xmlrpc = new OpenSubtitlesXmlRpc("FileBot 0.0"); + private static OpenSubtitlesXmlRpc xmlrpc = new OpenSubtitlesXmlRpc(String.format("%s %s", getApplicationName(), getApplicationVersion())); @BeforeClass diff --git a/test/net/sourceforge/filebot/web/SublightSubtitleClientTest.java b/test/net/sourceforge/filebot/web/SublightSubtitleClientTest.java index 22e1111f..95ef33dc 100644 --- a/test/net/sourceforge/filebot/web/SublightSubtitleClientTest.java +++ b/test/net/sourceforge/filebot/web/SublightSubtitleClientTest.java @@ -2,6 +2,7 @@ package net.sourceforge.filebot.web; +import static net.sourceforge.filebot.Settings.*; import static org.junit.Assert.*; import java.io.ByteArrayInputStream; @@ -18,7 +19,7 @@ import net.sublight.webservice.Subtitle; public class SublightSubtitleClientTest { - private static SublightSubtitleClient client = new SublightSubtitleClient("FileBot", "afa9ecb2-a3ee-42b1-9225-000b4038bc85"); + private static SublightSubtitleClient client = new SublightSubtitleClient(getApplicationName(), getApplicationProperty("sublight.apikey")); @BeforeClass diff --git a/test/net/sourceforge/filebot/web/TMDbClientTest.java b/test/net/sourceforge/filebot/web/TMDbClientTest.java new file mode 100644 index 00000000..da027f46 --- /dev/null +++ b/test/net/sourceforge/filebot/web/TMDbClientTest.java @@ -0,0 +1,39 @@ + +package net.sourceforge.filebot.web; + + +import static net.sourceforge.filebot.Settings.*; +import static org.junit.Assert.*; + +import java.util.List; + +import org.junit.Test; + + +public class TMDbClientTest { + + private final TMDbClient tmdb = new TMDbClient(getApplicationProperty("themoviedb.apikey")); + + + @Test + public void searchByName() throws Exception { + List result = tmdb.searchMovie("transformers"); + MovieDescriptor movie = result.get(0); + + assertEquals("Transformers", movie.getName()); + assertEquals(2007, movie.getYear()); + assertEquals(418279, movie.getImdbId()); + } + + + @Test + public void searchByHash() throws Exception { + List results = tmdb.getMovies("Hash.getInfo", "d7aa0275cace4410"); + MovieDescriptor movie = results.get(0); + + assertEquals("Iron Man", movie.getName()); + assertEquals(2008, movie.getYear()); + assertEquals(371746, movie.getImdbId()); + } + +} diff --git a/test/net/sourceforge/filebot/web/TheTVDBClientTest.java b/test/net/sourceforge/filebot/web/TheTVDBClientTest.java index 8b41594d..65b3cd60 100644 --- a/test/net/sourceforge/filebot/web/TheTVDBClientTest.java +++ b/test/net/sourceforge/filebot/web/TheTVDBClientTest.java @@ -8,7 +8,8 @@ import java.util.EnumSet; import java.util.List; import java.util.Locale; -import org.junit.After; +import org.junit.AfterClass; +import org.junit.BeforeClass; import org.junit.Test; import net.sf.ehcache.CacheManager; @@ -21,12 +22,6 @@ public class TheTVDBClientTest { private TheTVDBClient thetvdb = new TheTVDBClient("BA864DEE427E384A"); - @After - public void clearCache() { - CacheManager.getInstance().clearAll(); - } - - @Test public void search() throws Exception { // test default language and query escaping (blanks) @@ -122,4 +117,11 @@ public class TheTVDBClientTest { assertEquals(EnumSet.allOf(MirrorType.class), MirrorType.fromTypeMask(7)); } + + @BeforeClass + @AfterClass + public static void clearCache() { + CacheManager.getInstance().clearAll(); + } + } diff --git a/test/net/sourceforge/filebot/web/WebTestSuite.java b/test/net/sourceforge/filebot/web/WebTestSuite.java index 42a97311..6f98d5b8 100644 --- a/test/net/sourceforge/filebot/web/WebTestSuite.java +++ b/test/net/sourceforge/filebot/web/WebTestSuite.java @@ -8,7 +8,8 @@ import org.junit.runners.Suite.SuiteClasses; @RunWith(Suite.class) -@SuiteClasses( { TVDotComClientTest.class, AnidbClientTest.class, TVRageClientTest.class, TheTVDBClientTest.class, IMDbClientTest.class, SubsceneSubtitleClientTest.class, SubtitleSourceClientTest.class, SublightSubtitleClientTest.class, OpenSubtitlesXmlRpcTest.class }) +@SuiteClasses( { TVDotComClientTest.class, AnidbClientTest.class, TVRageClientTest.class, TheTVDBClientTest.class, TMDbClientTest.class, IMDbClientTest.class, SubsceneSubtitleClientTest.class, SubtitleSourceClientTest.class, + SublightSubtitleClientTest.class, OpenSubtitlesXmlRpcTest.class }) public class WebTestSuite { }