diff --git a/source/net/filebot/cli/ScriptShellMethods.java b/source/net/filebot/cli/ScriptShellMethods.java index 4fb19e41..73f0e085 100644 --- a/source/net/filebot/cli/ScriptShellMethods.java +++ b/source/net/filebot/cli/ScriptShellMethods.java @@ -28,6 +28,7 @@ import com.cedarsoftware.util.io.JsonWriter; import groovy.lang.Closure; import net.filebot.MediaTypes; import net.filebot.MetaAttributeView; +import net.filebot.WebServices; import net.filebot.media.MediaDetection; import net.filebot.similarity.NameSimilarityMetric; import net.filebot.similarity.Normalization; @@ -401,7 +402,11 @@ public class ScriptShellMethods { } public static boolean isEpisode(File self) { - return MediaDetection.isEpisode(String.join("/", self.getParent(), self.getName()), true); + return MediaDetection.isEpisode(self, true); + } + + public static boolean isMovie(File self) { + return MediaDetection.isMovie(self, true, WebServices.TheMovieDB); } } diff --git a/source/net/filebot/format/MediaBindingBean.java b/source/net/filebot/format/MediaBindingBean.java index 332b4277..3c004419 100644 --- a/source/net/filebot/format/MediaBindingBean.java +++ b/source/net/filebot/format/MediaBindingBean.java @@ -632,7 +632,7 @@ public class MediaBindingBean { if (WebServices.TheTVDB.getIdentifier().equals(getSeriesInfo().getDatabase())) { TheTVDBSeriesInfo extendedSeriesInfo = (TheTVDBSeriesInfo) WebServices.TheTVDB.getSeriesInfo(getSeriesInfo().getId(), Locale.ENGLISH); if (extendedSeriesInfo.getImdbId() != null) { - metaInfo = WebServices.OMDb.getMovieInfo(new Movie(null, -1, grepImdbId(extendedSeriesInfo.getImdbId()).iterator().next(), -1)); + metaInfo = WebServices.OMDb.getMovieInfo(new Movie(grepImdbId(extendedSeriesInfo.getImdbId()).iterator().next())); } } } @@ -640,7 +640,7 @@ public class MediaBindingBean { if (getMovie().getTmdbId() > 0) { MovieInfo movieInfo = WebServices.TheMovieDB.getMovieInfo(getMovie(), Locale.ENGLISH, false); if (movieInfo.getImdbId() != null) { - metaInfo = WebServices.OMDb.getMovieInfo(new Movie(null, -1, movieInfo.getImdbId(), -1)); + metaInfo = WebServices.OMDb.getMovieInfo(new Movie(movieInfo.getImdbId())); } } else if (getMovie().getImdbId() > 0) { metaInfo = WebServices.OMDb.getMovieInfo(getMovie()); diff --git a/source/net/filebot/media/MediaDetection.java b/source/net/filebot/media/MediaDetection.java index 17e0b860..3feb8ead 100644 --- a/source/net/filebot/media/MediaDetection.java +++ b/source/net/filebot/media/MediaDetection.java @@ -1,5 +1,6 @@ package net.filebot.media; +import static java.util.Arrays.*; import static java.util.Collections.*; import static java.util.regex.Pattern.*; import static java.util.stream.Collectors.*; @@ -33,6 +34,7 @@ import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.NoSuchElementException; +import java.util.Objects; import java.util.Set; import java.util.SortedSet; import java.util.TreeMap; @@ -79,7 +81,7 @@ public class MediaDetection { try { return releaseInfo.getClutterFileFilter(); } catch (Exception e) { - debug.log(Level.SEVERE, "Unable to access clutter file filter: " + e.getMessage(), e); + debug.log(Level.SEVERE, "Failed to access clutter file filter: " + e.getMessage(), e); } return f -> false; } @@ -113,6 +115,35 @@ public class MediaDetection { return releaseInfo.getSubtitleLanguageTag(getName(file)); } + public static boolean isEpisode(File file, boolean strict) { + if (xattr.getMetaInfo(file) instanceof Episode) + return true; + + return MediaDetection.isEpisode(String.join("/", file.getParent(), file.getName()), strict); + } + + public static boolean isMovie(File file, boolean strict) { + if (xattr.getMetaInfo(file) instanceof Movie) + return true; + if (isEpisode(file, strict)) + return false; + + try { + return matchMovieName(asList(file.getName(), file.getParent()), strict, 0).size() > 0; + } catch (Exception e) { + debug.log(Level.SEVERE, "Failed to access movie index: " + e.getMessage(), e); + } + + // check for valid imdb id patterns + return grepImdbId(file.getPath()).stream().map(Movie::new).filter(m -> { + try { + return strict ? WebServices.TheMovieDB.getMovieDescriptor(m, Locale.ENGLISH).getId() > 0 : true; + } catch (Exception e) { + return false; + } + }).filter(Objects::nonNull).findFirst().isPresent(); + } + private static final SeasonEpisodeMatcher seasonEpisodeMatcherStrict = new SmartSeasonEpisodeMatcher(SeasonEpisodeMatcher.DEFAULT_SANITY, true); private static final SeasonEpisodeMatcher seasonEpisodeMatcherNonStrict = new SmartSeasonEpisodeMatcher(SeasonEpisodeMatcher.DEFAULT_SANITY, false); private static final DateMatcher dateMatcher = new DateMatcher(DateMatcher.DEFAULT_SANITY, Locale.ENGLISH, Locale.getDefault()); @@ -513,9 +544,7 @@ public class MediaDetection { HighPerformanceMatcher nameMatcher = new HighPerformanceMatcher(maxStartIndex); List matches = new ArrayList(); - List names = HighPerformanceMatcher.prepare(files); - - for (CollationKey[] name : names) { + for (CollationKey[] name : HighPerformanceMatcher.prepare(files)) { IndexEntry bestMatch = null; for (IndexEntry it : index) { CollationKey[] commonName = nameMatcher.matchFirstCommonSequence(new CollationKey[][] { name, it.getLenientKey() }); @@ -529,15 +558,9 @@ public class MediaDetection { } // sort by length of name match (descending) - sort(matches, new Comparator() { - - @Override - public int compare(String a, String b) { - return Integer.valueOf(b.length()).compareTo(Integer.valueOf(a.length())); - } - }); - - return matches; + return matches.stream().sorted((a, b) -> { + return Integer.compare(b.length(), a.length()); + }).collect(toList()); } public static List matchSeriesFromStringWithoutSpacing(Collection names, boolean strict, List> index) throws IOException { @@ -583,7 +606,7 @@ public class MediaDetection { // lookup by id from nfo file if (service != null) { for (int imdbid : grepImdbId(movieFile.getPath())) { - Movie movie = service.getMovieDescriptor(new Movie(null, 0, imdbid, -1), locale); + Movie movie = service.getMovieDescriptor(new Movie(imdbid), locale); if (movie != null) { options.add(movie); } @@ -591,7 +614,7 @@ public class MediaDetection { // try to grep imdb id from nfo files for (int imdbid : grepImdbIdFor(movieFile)) { - Movie movie = service.getMovieDescriptor(new Movie(null, 0, imdbid, -1), locale); + Movie movie = service.getMovieDescriptor(new Movie(imdbid), locale); if (movie != null) { options.add(movie); } @@ -879,16 +902,9 @@ public class MediaDetection { } // sort by length of name match (descending) - List results = new ArrayList(matchMap.keySet()); - sort(results, new Comparator() { - - @Override - public int compare(Movie a, Movie b) { - return Integer.valueOf(matchMap.get(b).length()).compareTo(Integer.valueOf(matchMap.get(a).length())); - } - }); - - return results; + return matchMap.keySet().stream().sorted((a, b) -> { + return Integer.compare(matchMap.get(b).length(), matchMap.get(a).length()); + }).collect(toList()); } public static List matchMovieFromStringWithoutSpacing(Collection names, boolean strict) throws IOException { @@ -1223,14 +1239,11 @@ public class MediaDetection { public static Set grepImdbId(CharSequence text) { // scan for imdb id patterns like tt1234567 - Matcher imdbMatch = Pattern.compile("(?<=tt)\\d{7}").matcher(text); + Matcher imdbMatch = Pattern.compile("(? collection = new LinkedHashSet(); while (imdbMatch.find()) { - int imdbid = Integer.parseInt(imdbMatch.group()); - if (imdbid > 0) { - collection.add(imdbid); - } + collection.add(Integer.parseInt(imdbMatch.group(1))); } return collection; @@ -1259,7 +1272,7 @@ public class MediaDetection { public static Movie grepMovie(File nfo, MovieIdentificationService resolver, Locale locale) throws Exception { String contents = new String(readFile(nfo), "UTF-8"); int imdbid = grepImdbId(contents).iterator().next(); - return resolver.getMovieDescriptor(new Movie(null, 0, imdbid, -1), locale); + return resolver.getMovieDescriptor(new Movie(imdbid), locale); } public static SeriesInfo grepSeries(File nfo, Locale locale) throws Exception { @@ -1374,11 +1387,9 @@ public class MediaDetection { } public static List prepare(Collection sequences) { - List result = new ArrayList(sequences.size()); - for (String it : sequences) { - result.add(prepare(normalizePunctuation(it))); - } - return result; + return sequences.stream().filter(Objects::nonNull).map(s -> { + return prepare(normalizePunctuation(s)); + }).collect(toList()); } public static List> prepare(Movie m) { diff --git a/source/net/filebot/ui/filter/TypeTool.java b/source/net/filebot/ui/filter/TypeTool.java index 134a198d..ec554e39 100644 --- a/source/net/filebot/ui/filter/TypeTool.java +++ b/source/net/filebot/ui/filter/TypeTool.java @@ -1,8 +1,6 @@ package net.filebot.ui.filter; -import static java.util.Arrays.*; import static java.util.Collections.*; -import static net.filebot.MediaTypes.*; import static net.filebot.util.FileUtilities.*; import java.io.File; @@ -72,8 +70,8 @@ class TypeTool extends Tool { public Map getMetaTypes() { Map types = new LinkedHashMap(); - types.put("Episode", new EpisodeFilter()); - types.put("Movie", new MovieFilter()); + types.put("Movie", (f) -> MediaDetection.isMovie(f, true)); + types.put("Episode", (f) -> MediaDetection.isEpisode(f, true)); types.put("Video", MediaTypes.VIDEO_FILES); types.put("Subtitle", MediaTypes.SUBTITLE_FILES); types.put("Audio", MediaTypes.AUDIO_FILES); @@ -84,30 +82,6 @@ class TypeTool extends Tool { return types; } - private static class EpisodeFilter implements FileFilter { - - private final static long MAX_SIZE = 50 * MEGA; - - @Override - public boolean accept(File file) { - return file.length() > MAX_SIZE && VIDEO_FILES.accept(file) && MediaDetection.isEpisode(file.getPath(), true); - } - } - - private static class MovieFilter implements FileFilter { - - private final static long MAX_SIZE = 500 * MEGA; - - @Override - public boolean accept(File file) { - try { - return file.length() > MAX_SIZE && VIDEO_FILES.accept(file) && !MediaDetection.isEpisode(file.getPath(), true) && MediaDetection.matchMovieName(asList(file.getName(), file.getParent()), true, 0).size() > 0; - } catch (Exception e) { - return false; - } - } - } - @Override protected void setModel(TreeModel model) { tree.setModel(model); diff --git a/source/net/filebot/ui/subtitle/upload/SubtitleUploadDialog.java b/source/net/filebot/ui/subtitle/upload/SubtitleUploadDialog.java index c1bcd9c0..1ebff998 100644 --- a/source/net/filebot/ui/subtitle/upload/SubtitleUploadDialog.java +++ b/source/net/filebot/ui/subtitle/upload/SubtitleUploadDialog.java @@ -169,7 +169,7 @@ public class SubtitleUploadDialog extends JDialog { TheTVDBSeriesInfo seriesInfo = (TheTVDBSeriesInfo) WebServices.TheTVDB.getSeriesInfo(entry, Locale.ENGLISH); if (seriesInfo.getImdbId() != null) { int imdbId = grepImdbId(seriesInfo.getImdbId()).iterator().next(); - mapping.setIdentity(WebServices.OpenSubtitles.getMovieDescriptor(new Movie(null, 0, imdbId, -1), Locale.ENGLISH)); + mapping.setIdentity(WebServices.OpenSubtitles.getMovieDescriptor(new Movie(imdbId), Locale.ENGLISH)); break NAMES; } } diff --git a/source/net/filebot/web/Movie.java b/source/net/filebot/web/Movie.java index d3502312..e36e2739 100644 --- a/source/net/filebot/web/Movie.java +++ b/source/net/filebot/web/Movie.java @@ -20,6 +20,10 @@ public class Movie extends SearchResult { // used by serializer } + public Movie(int imdbId) { + this(null, 0, imdbId, -1); + } + public Movie(String name, int year, int imdbId, int tmdbId) { this(name, null, year, imdbId, tmdbId, null); } diff --git a/test/net/filebot/web/OMDbClientTest.java b/test/net/filebot/web/OMDbClientTest.java index bde4dd1e..da8bd14c 100644 --- a/test/net/filebot/web/OMDbClientTest.java +++ b/test/net/filebot/web/OMDbClientTest.java @@ -64,7 +64,7 @@ public class OMDbClientTest { @Test public void getMovieDescriptor1() throws Exception { - Movie movie = client.getMovieDescriptor(new Movie(null, 0, 499549, -1), null); + Movie movie = client.getMovieDescriptor(new Movie(499549), null); assertEquals("Avatar", movie.getName()); assertEquals(2009, movie.getYear()); @@ -73,7 +73,7 @@ public class OMDbClientTest { @Test public void getMovieDescriptor2() throws Exception { - Movie movie = client.getMovieDescriptor(new Movie(null, 0, 211915, -1), null); + Movie movie = client.getMovieDescriptor(new Movie(211915), null); assertEquals("Amélie", movie.getName()); assertEquals(2001, movie.getYear()); @@ -82,7 +82,7 @@ public class OMDbClientTest { @Test public void getMovieDescriptor3() throws Exception { - Movie movie = client.getMovieDescriptor(new Movie(null, 0, 75610, -1), null); + Movie movie = client.getMovieDescriptor(new Movie(75610), null); assertEquals("21 Up", movie.getName()); assertEquals(1977, movie.getYear()); @@ -91,7 +91,7 @@ public class OMDbClientTest { @Test public void getMovieDescriptor4() throws Exception { - Movie movie = client.getMovieDescriptor(new Movie(null, 0, 369702, -1), null); + Movie movie = client.getMovieDescriptor(new Movie(369702), null); assertEquals("The Sea Inside", movie.getName()); assertEquals(2004, movie.getYear()); @@ -100,7 +100,7 @@ public class OMDbClientTest { @Test public void getMovieDescriptor5() throws Exception { - Movie movie = client.getMovieDescriptor(new Movie(null, 0, 1020960, -1), null); + Movie movie = client.getMovieDescriptor(new Movie(1020960), null); assertEquals("God, the Universe and Everything Else", movie.getName()); assertEquals(1988, movie.getYear()); @@ -109,7 +109,7 @@ public class OMDbClientTest { @Test public void getImdbApiMovieInfoReleasedNA() throws Exception { - MovieInfo movie = client.getMovieInfo(new Movie(null, -1, 1287357, -1)); + MovieInfo movie = client.getMovieInfo(new Movie(1287357)); assertEquals("Sommersonntag", movie.getName()); assertEquals(2008, movie.getReleased().getYear()); assertEquals("2008-06-07", movie.getReleased().toString()); diff --git a/test/net/filebot/web/TMDbClientTest.java b/test/net/filebot/web/TMDbClientTest.java index 0b97ffbc..75fb7cdf 100644 --- a/test/net/filebot/web/TMDbClientTest.java +++ b/test/net/filebot/web/TMDbClientTest.java @@ -67,7 +67,7 @@ public class TMDbClientTest { @Test public void searchByIMDB() throws Exception { - Movie movie = tmdb.getMovieDescriptor(new Movie(null, 0, 418279, -1), Locale.ENGLISH); + Movie movie = tmdb.getMovieDescriptor(new Movie(418279), Locale.ENGLISH); assertEquals("Transformers", movie.getName()); assertEquals(2007, movie.getYear(), 0); @@ -77,7 +77,7 @@ public class TMDbClientTest { @Test public void getMovieInfo() throws Exception { - MovieInfo movie = tmdb.getMovieInfo(new Movie(null, 0, 418279, -1), Locale.ENGLISH, true); + MovieInfo movie = tmdb.getMovieInfo(new Movie(418279), Locale.ENGLISH, true); assertEquals("Transformers", movie.getName()); assertEquals("2007-06-27", movie.getReleased().toString());