From c2f7def29b286bcdb57e711ce3e4d5b7ed6f4873 Mon Sep 17 00:00:00 2001 From: Reinhard Pointner Date: Mon, 5 Dec 2011 15:38:41 +0000 Subject: [PATCH] * auto-detect movie info via imdb id from nfo files --- .../filebot/cli/CmdlineOperations.java | 32 +++++++++++++++- .../filebot/mediainfo/ReleaseInfo.java | 29 +++++++++++++- .../filebot/ui/rename/MovieHashMatcher.java | 38 +++---------------- 3 files changed, 64 insertions(+), 35 deletions(-) diff --git a/source/net/sourceforge/filebot/cli/CmdlineOperations.java b/source/net/sourceforge/filebot/cli/CmdlineOperations.java index caeacefc..ffe8ba2d 100644 --- a/source/net/sourceforge/filebot/cli/CmdlineOperations.java +++ b/source/net/sourceforge/filebot/cli/CmdlineOperations.java @@ -259,6 +259,21 @@ public class CmdlineOperations implements CmdlineInterface { movieFiles = subtitleFiles; } + // fill in movie information from nfo file imdb when necessary + for (int i = 0; i < movieFiles.length; i++) { + if (movieDescriptors[i] == null) { + Set imdbid = grepImdbIdFor(movieFiles[i]); + if (imdbid.size() > 1) { + CLILogger.warning(String.format("Multiple imdb ids found for %s: %s", movieFiles[i].getName(), imdbid)); + } + + if (imdbid.size() == 1 || (imdbid.size() > 1 && !strict)) { + movieDescriptors[i] = db.getMovieDescriptor(imdbid.iterator().next(), locale); + CLILogger.fine(String.format("Identified %s as %s via imdb id", movieFiles[i].getName(), movieDescriptors[i])); + } + } + } + // use user query if search by hash did not return any results, only one query for one movie though if (query != null && movieDescriptors.length == 1 && movieDescriptors[0] == null) { CLILogger.fine(format("Looking up movie by query [%s]", query)); @@ -544,7 +559,7 @@ public class CmdlineOperations implements CmdlineInterface { SimilarityMetric sanity = EpisodeMetrics.verificationMetric(); for (Match it : matcher.match()) { - if (sanity.getSimilarity(it.getValue(), it.getCandidate()) >= 1) { + if (sanity.getSimilarity(it.getValue(), it.getCandidate()) >= 0.9) { CLILogger.finest(format("Matched [%s] to [%s] via filename", it.getValue().getName(), it.getCandidate().getName())); subtitleByVideo.put(it.getValue(), it.getCandidate()); } @@ -556,7 +571,20 @@ public class CmdlineOperations implements CmdlineInterface { private Collection detectQuery(Collection mediaFiles, boolean strict) throws Exception { - Collection names = detectSeriesNames(mediaFiles); + Collection names = new LinkedHashSet(); + + // detect by imdb id from nfo file in the same folder + for (List file : mapByFolder(mediaFiles).values()) { + for (int imdbid : grepImdbIdFor(file.get(0))) { + Movie movie = WebServices.TMDb.getMovieDescriptor(imdbid, Locale.ENGLISH); + if (movie != null) { + names.add(movie.getName()); + } + } + } + + // detect series name by common word sequence + names.addAll(detectSeriesNames(mediaFiles)); if (names.isEmpty() || (strict && names.size() > 1)) { throw new Exception("Unable to auto-select query: " + names); diff --git a/source/net/sourceforge/filebot/mediainfo/ReleaseInfo.java b/source/net/sourceforge/filebot/mediainfo/ReleaseInfo.java index 7d36ce8f..6b84053a 100644 --- a/source/net/sourceforge/filebot/mediainfo/ReleaseInfo.java +++ b/source/net/sourceforge/filebot/mediainfo/ReleaseInfo.java @@ -8,6 +8,7 @@ import static java.util.regex.Pattern.*; import static net.sourceforge.tuned.StringUtilities.*; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.charset.Charset; @@ -15,9 +16,12 @@ import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashSet; import java.util.List; +import java.util.Scanner; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; +import net.sourceforge.filebot.MediaTypes; import net.sourceforge.filebot.similarity.SeriesNameMatcher; import net.sourceforge.filebot.web.CachedResource; @@ -27,13 +31,36 @@ public class ReleaseInfo { public static Collection detectSeriesNames(Collection files) throws IOException { SeriesNameMatcher matcher = new SeriesNameMatcher(); ReleaseInfo cleaner = new ReleaseInfo(); - + // match common word sequence and clean detected word sequence from unwanted elements Collection names = matcher.matchAll(files.toArray(new File[files.size()])); return new LinkedHashSet(cleaner.cleanRG(names)); } + public static Set grepImdbIdFor(File movieFile) throws IOException { + Set collection = new LinkedHashSet(); + File movieFolder = movieFile.getParentFile(); // lookup imdb id from nfo files in this folder + + for (File file : movieFolder.listFiles(MediaTypes.getDefaultFilter("application/nfo"))) { + Scanner scanner = new Scanner(new FileInputStream(file), "UTF-8"); + + try { + // scan for imdb id patterns like tt1234567 + String imdb = null; + + while ((imdb = scanner.findWithinHorizon("(?<=tt)\\d{7}", 64 * 1024)) != null) { + collection.add(Integer.parseInt(imdb)); + } + } finally { + scanner.close(); + } + } + + return collection; + } + + public String getVideoSource(File file) { // check parent and itself for group names return matchLast(getVideoSourcePattern(), file.getParent(), file.getName()); diff --git a/source/net/sourceforge/filebot/ui/rename/MovieHashMatcher.java b/source/net/sourceforge/filebot/ui/rename/MovieHashMatcher.java index 414203b1..ebbeb8db 100644 --- a/source/net/sourceforge/filebot/ui/rename/MovieHashMatcher.java +++ b/source/net/sourceforge/filebot/ui/rename/MovieHashMatcher.java @@ -5,27 +5,23 @@ package net.sourceforge.filebot.ui.rename; import static java.util.Arrays.*; import static java.util.Collections.*; import static net.sourceforge.filebot.MediaTypes.*; +import static net.sourceforge.filebot.mediainfo.ReleaseInfo.*; import static net.sourceforge.tuned.FileUtilities.*; import static net.sourceforge.tuned.ui.TunedUtilities.*; import java.awt.Component; import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Scanner; -import java.util.Set; +import java.util.Map.Entry; import java.util.SortedSet; import java.util.TreeSet; -import java.util.Map.Entry; import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; import java.util.concurrent.RunnableFuture; @@ -46,12 +42,12 @@ class MovieHashMatcher implements AutoCompleteMatcher { private final MovieIdentificationService service; - + public MovieHashMatcher(MovieIdentificationService service) { this.service = service; } - + @Override public List> match(final List files, Locale locale, boolean autodetect, Component parent) throws Exception { // handle movie files @@ -138,29 +134,7 @@ class MovieHashMatcher implements AutoCompleteMatcher { return matches; } - - private Set grepImdbId(File... files) throws IOException { - Set collection = new HashSet(); - - for (File file : files) { - Scanner scanner = new Scanner(new FileInputStream(file), "UTF-8"); - - try { - // scan for imdb id patterns like tt1234567 - String imdb = null; - - while ((imdb = scanner.findWithinHorizon("(?<=tt)\\d{7}", 64 * 1024)) != null) { - collection.add(Integer.parseInt(imdb)); - } - } finally { - scanner.close(); - } - } - - return collection; - } - protected Movie grabMovieName(File movieFile, Locale locale, boolean autodetect, Component parent, Movie... suggestions) throws Exception { List options = new ArrayList(); @@ -172,7 +146,7 @@ class MovieHashMatcher implements AutoCompleteMatcher { } // try to grep imdb id from nfo files - for (int imdbid : grepImdbId(movieFile.getParentFile().listFiles(getDefaultFilter("application/nfo")))) { + for (int imdbid : grepImdbIdFor(movieFile)) { Movie movie = service.getMovieDescriptor(imdbid, locale); if (movie != null) { @@ -213,7 +187,7 @@ class MovieHashMatcher implements AutoCompleteMatcher { return options.isEmpty() ? null : selectMovie(options, parent); } - + protected Movie selectMovie(final List options, final Component parent) throws Exception { if (options.size() == 1) { return options.get(0);