Refactor MediaDetection isEpisode/isMovie and update Filter/Types tool

This commit is contained in:
Reinhard Pointner 2016-03-28 14:46:33 +00:00
parent 64f88f16ce
commit cd592834fe
8 changed files with 70 additions and 76 deletions

View File

@ -28,6 +28,7 @@ import com.cedarsoftware.util.io.JsonWriter;
import groovy.lang.Closure; import groovy.lang.Closure;
import net.filebot.MediaTypes; import net.filebot.MediaTypes;
import net.filebot.MetaAttributeView; import net.filebot.MetaAttributeView;
import net.filebot.WebServices;
import net.filebot.media.MediaDetection; import net.filebot.media.MediaDetection;
import net.filebot.similarity.NameSimilarityMetric; import net.filebot.similarity.NameSimilarityMetric;
import net.filebot.similarity.Normalization; import net.filebot.similarity.Normalization;
@ -401,7 +402,11 @@ public class ScriptShellMethods {
} }
public static boolean isEpisode(File self) { 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);
} }
} }

View File

@ -632,7 +632,7 @@ public class MediaBindingBean {
if (WebServices.TheTVDB.getIdentifier().equals(getSeriesInfo().getDatabase())) { if (WebServices.TheTVDB.getIdentifier().equals(getSeriesInfo().getDatabase())) {
TheTVDBSeriesInfo extendedSeriesInfo = (TheTVDBSeriesInfo) WebServices.TheTVDB.getSeriesInfo(getSeriesInfo().getId(), Locale.ENGLISH); TheTVDBSeriesInfo extendedSeriesInfo = (TheTVDBSeriesInfo) WebServices.TheTVDB.getSeriesInfo(getSeriesInfo().getId(), Locale.ENGLISH);
if (extendedSeriesInfo.getImdbId() != null) { 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) { if (getMovie().getTmdbId() > 0) {
MovieInfo movieInfo = WebServices.TheMovieDB.getMovieInfo(getMovie(), Locale.ENGLISH, false); MovieInfo movieInfo = WebServices.TheMovieDB.getMovieInfo(getMovie(), Locale.ENGLISH, false);
if (movieInfo.getImdbId() != null) { 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) { } else if (getMovie().getImdbId() > 0) {
metaInfo = WebServices.OMDb.getMovieInfo(getMovie()); metaInfo = WebServices.OMDb.getMovieInfo(getMovie());

View File

@ -1,5 +1,6 @@
package net.filebot.media; package net.filebot.media;
import static java.util.Arrays.*;
import static java.util.Collections.*; import static java.util.Collections.*;
import static java.util.regex.Pattern.*; import static java.util.regex.Pattern.*;
import static java.util.stream.Collectors.*; import static java.util.stream.Collectors.*;
@ -33,6 +34,7 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeMap; import java.util.TreeMap;
@ -79,7 +81,7 @@ public class MediaDetection {
try { try {
return releaseInfo.getClutterFileFilter(); return releaseInfo.getClutterFileFilter();
} catch (Exception e) { } 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; return f -> false;
} }
@ -113,6 +115,35 @@ public class MediaDetection {
return releaseInfo.getSubtitleLanguageTag(getName(file)); 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 seasonEpisodeMatcherStrict = new SmartSeasonEpisodeMatcher(SeasonEpisodeMatcher.DEFAULT_SANITY, true);
private static final SeasonEpisodeMatcher seasonEpisodeMatcherNonStrict = new SmartSeasonEpisodeMatcher(SeasonEpisodeMatcher.DEFAULT_SANITY, false); 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()); 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); HighPerformanceMatcher nameMatcher = new HighPerformanceMatcher(maxStartIndex);
List<String> matches = new ArrayList<String>(); List<String> matches = new ArrayList<String>();
List<CollationKey[]> names = HighPerformanceMatcher.prepare(files); for (CollationKey[] name : HighPerformanceMatcher.prepare(files)) {
for (CollationKey[] name : names) {
IndexEntry<SearchResult> bestMatch = null; IndexEntry<SearchResult> bestMatch = null;
for (IndexEntry<SearchResult> it : index) { for (IndexEntry<SearchResult> it : index) {
CollationKey[] commonName = nameMatcher.matchFirstCommonSequence(new CollationKey[][] { name, it.getLenientKey() }); CollationKey[] commonName = nameMatcher.matchFirstCommonSequence(new CollationKey[][] { name, it.getLenientKey() });
@ -529,15 +558,9 @@ public class MediaDetection {
} }
// sort by length of name match (descending) // sort by length of name match (descending)
sort(matches, new Comparator<String>() { return matches.stream().sorted((a, b) -> {
return Integer.compare(b.length(), a.length());
@Override }).collect(toList());
public int compare(String a, String b) {
return Integer.valueOf(b.length()).compareTo(Integer.valueOf(a.length()));
}
});
return matches;
} }
public static List<SearchResult> matchSeriesFromStringWithoutSpacing(Collection<String> names, boolean strict, List<IndexEntry<SearchResult>> index) throws IOException { public static List<SearchResult> matchSeriesFromStringWithoutSpacing(Collection<String> names, boolean strict, List<IndexEntry<SearchResult>> index) throws IOException {
@ -583,7 +606,7 @@ public class MediaDetection {
// lookup by id from nfo file // lookup by id from nfo file
if (service != null) { if (service != null) {
for (int imdbid : grepImdbId(movieFile.getPath())) { 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) { if (movie != null) {
options.add(movie); options.add(movie);
} }
@ -591,7 +614,7 @@ public class MediaDetection {
// try to grep imdb id from nfo files // try to grep imdb id from nfo files
for (int imdbid : grepImdbIdFor(movieFile)) { 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) { if (movie != null) {
options.add(movie); options.add(movie);
} }
@ -879,16 +902,9 @@ public class MediaDetection {
} }
// sort by length of name match (descending) // sort by length of name match (descending)
List<Movie> results = new ArrayList<Movie>(matchMap.keySet()); return matchMap.keySet().stream().sorted((a, b) -> {
sort(results, new Comparator<Movie>() { return Integer.compare(matchMap.get(b).length(), matchMap.get(a).length());
}).collect(toList());
@Override
public int compare(Movie a, Movie b) {
return Integer.valueOf(matchMap.get(b).length()).compareTo(Integer.valueOf(matchMap.get(a).length()));
}
});
return results;
} }
public static List<Movie> matchMovieFromStringWithoutSpacing(Collection<String> names, boolean strict) throws IOException { public static List<Movie> matchMovieFromStringWithoutSpacing(Collection<String> names, boolean strict) throws IOException {
@ -1223,14 +1239,11 @@ public class MediaDetection {
public static Set<Integer> grepImdbId(CharSequence text) { public static Set<Integer> grepImdbId(CharSequence text) {
// scan for imdb id patterns like tt1234567 // scan for imdb id patterns like tt1234567
Matcher imdbMatch = Pattern.compile("(?<=tt)\\d{7}").matcher(text); Matcher imdbMatch = Pattern.compile("(?<!\\p{Alnum})tt(\\d{7})(?!\\p{Alnum})", Pattern.CASE_INSENSITIVE).matcher(text);
Set<Integer> collection = new LinkedHashSet<Integer>(); Set<Integer> collection = new LinkedHashSet<Integer>();
while (imdbMatch.find()) { while (imdbMatch.find()) {
int imdbid = Integer.parseInt(imdbMatch.group()); collection.add(Integer.parseInt(imdbMatch.group(1)));
if (imdbid > 0) {
collection.add(imdbid);
}
} }
return collection; return collection;
@ -1259,7 +1272,7 @@ public class MediaDetection {
public static Movie grepMovie(File nfo, MovieIdentificationService resolver, Locale locale) throws Exception { public static Movie grepMovie(File nfo, MovieIdentificationService resolver, Locale locale) throws Exception {
String contents = new String(readFile(nfo), "UTF-8"); String contents = new String(readFile(nfo), "UTF-8");
int imdbid = grepImdbId(contents).iterator().next(); 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 { public static SeriesInfo grepSeries(File nfo, Locale locale) throws Exception {
@ -1374,11 +1387,9 @@ public class MediaDetection {
} }
public static List<CollationKey[]> prepare(Collection<String> sequences) { public static List<CollationKey[]> prepare(Collection<String> sequences) {
List<CollationKey[]> result = new ArrayList<CollationKey[]>(sequences.size()); return sequences.stream().filter(Objects::nonNull).map(s -> {
for (String it : sequences) { return prepare(normalizePunctuation(s));
result.add(prepare(normalizePunctuation(it))); }).collect(toList());
}
return result;
} }
public static List<IndexEntry<Movie>> prepare(Movie m) { public static List<IndexEntry<Movie>> prepare(Movie m) {

View File

@ -1,8 +1,6 @@
package net.filebot.ui.filter; package net.filebot.ui.filter;
import static java.util.Arrays.*;
import static java.util.Collections.*; import static java.util.Collections.*;
import static net.filebot.MediaTypes.*;
import static net.filebot.util.FileUtilities.*; import static net.filebot.util.FileUtilities.*;
import java.io.File; import java.io.File;
@ -72,8 +70,8 @@ class TypeTool extends Tool<TreeModel> {
public Map<String, FileFilter> getMetaTypes() { public Map<String, FileFilter> getMetaTypes() {
Map<String, FileFilter> types = new LinkedHashMap<String, FileFilter>(); Map<String, FileFilter> types = new LinkedHashMap<String, FileFilter>();
types.put("Episode", new EpisodeFilter()); types.put("Movie", (f) -> MediaDetection.isMovie(f, true));
types.put("Movie", new MovieFilter()); types.put("Episode", (f) -> MediaDetection.isEpisode(f, true));
types.put("Video", MediaTypes.VIDEO_FILES); types.put("Video", MediaTypes.VIDEO_FILES);
types.put("Subtitle", MediaTypes.SUBTITLE_FILES); types.put("Subtitle", MediaTypes.SUBTITLE_FILES);
types.put("Audio", MediaTypes.AUDIO_FILES); types.put("Audio", MediaTypes.AUDIO_FILES);
@ -84,30 +82,6 @@ class TypeTool extends Tool<TreeModel> {
return types; 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 @Override
protected void setModel(TreeModel model) { protected void setModel(TreeModel model) {
tree.setModel(model); tree.setModel(model);

View File

@ -169,7 +169,7 @@ public class SubtitleUploadDialog extends JDialog {
TheTVDBSeriesInfo seriesInfo = (TheTVDBSeriesInfo) WebServices.TheTVDB.getSeriesInfo(entry, Locale.ENGLISH); TheTVDBSeriesInfo seriesInfo = (TheTVDBSeriesInfo) WebServices.TheTVDB.getSeriesInfo(entry, Locale.ENGLISH);
if (seriesInfo.getImdbId() != null) { if (seriesInfo.getImdbId() != null) {
int imdbId = grepImdbId(seriesInfo.getImdbId()).iterator().next(); 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; break NAMES;
} }
} }

View File

@ -20,6 +20,10 @@ public class Movie extends SearchResult {
// used by serializer // used by serializer
} }
public Movie(int imdbId) {
this(null, 0, imdbId, -1);
}
public Movie(String name, int year, int imdbId, int tmdbId) { public Movie(String name, int year, int imdbId, int tmdbId) {
this(name, null, year, imdbId, tmdbId, null); this(name, null, year, imdbId, tmdbId, null);
} }

View File

@ -64,7 +64,7 @@ public class OMDbClientTest {
@Test @Test
public void getMovieDescriptor1() throws Exception { 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("Avatar", movie.getName());
assertEquals(2009, movie.getYear()); assertEquals(2009, movie.getYear());
@ -73,7 +73,7 @@ public class OMDbClientTest {
@Test @Test
public void getMovieDescriptor2() throws Exception { 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("Amélie", movie.getName());
assertEquals(2001, movie.getYear()); assertEquals(2001, movie.getYear());
@ -82,7 +82,7 @@ public class OMDbClientTest {
@Test @Test
public void getMovieDescriptor3() throws Exception { 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("21 Up", movie.getName());
assertEquals(1977, movie.getYear()); assertEquals(1977, movie.getYear());
@ -91,7 +91,7 @@ public class OMDbClientTest {
@Test @Test
public void getMovieDescriptor4() throws Exception { 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("The Sea Inside", movie.getName());
assertEquals(2004, movie.getYear()); assertEquals(2004, movie.getYear());
@ -100,7 +100,7 @@ public class OMDbClientTest {
@Test @Test
public void getMovieDescriptor5() throws Exception { 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("God, the Universe and Everything Else", movie.getName());
assertEquals(1988, movie.getYear()); assertEquals(1988, movie.getYear());
@ -109,7 +109,7 @@ public class OMDbClientTest {
@Test @Test
public void getImdbApiMovieInfoReleasedNA() throws Exception { 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("Sommersonntag", movie.getName());
assertEquals(2008, movie.getReleased().getYear()); assertEquals(2008, movie.getReleased().getYear());
assertEquals("2008-06-07", movie.getReleased().toString()); assertEquals("2008-06-07", movie.getReleased().toString());

View File

@ -67,7 +67,7 @@ public class TMDbClientTest {
@Test @Test
public void searchByIMDB() throws Exception { 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("Transformers", movie.getName());
assertEquals(2007, movie.getYear(), 0); assertEquals(2007, movie.getYear(), 0);
@ -77,7 +77,7 @@ public class TMDbClientTest {
@Test @Test
public void getMovieInfo() throws Exception { 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("Transformers", movie.getName());
assertEquals("2007-06-27", movie.getReleased().toString()); assertEquals("2007-06-27", movie.getReleased().toString());