* added fallback for movie identification by scanning .nfo files for an imdb id

This commit is contained in:
Reinhard Pointner 2009-11-22 01:27:05 +00:00
parent 7a87ea9573
commit 5519c1440d
8 changed files with 167 additions and 1 deletions

View File

@ -13,6 +13,10 @@
<extension>txt</extension>
</type>
<type name="application/nfo">
<extension>nfo</extension>
</type>
<!--
Verification

View File

@ -3,12 +3,24 @@ package net.sourceforge.filebot.ui.panel.rename;
import static net.sourceforge.filebot.MediaTypes.*;
import static net.sourceforge.tuned.ui.TunedUtilities.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.RunnableFuture;
import javax.swing.Action;
import javax.swing.SwingUtilities;
import net.sourceforge.filebot.similarity.Match;
import net.sourceforge.filebot.ui.SelectDialog;
import net.sourceforge.filebot.web.MovieDescriptor;
import net.sourceforge.filebot.web.MovieIdentificationService;
import net.sourceforge.tuned.FileUtilities;
@ -35,10 +47,84 @@ class MovieHashMatcher implements AutoCompleteMatcher {
for (int i = 0; i < movieDescriptors.length; i++) {
if (movieDescriptors[i] != null) {
matches.add(new Match<File, MovieDescriptor>(movieFiles[i], movieDescriptors[i]));
} else {
// unknown hash, try via imdb id from nfo file
MovieDescriptor movie = determineMovie(movieFiles[i]);
if (movie != null) {
matches.add(new Match<File, MovieDescriptor>(movieFiles[i], movie));
}
}
}
return matches;
}
protected Set<Integer> grepImdbId(File... files) throws IOException {
Set<Integer> collection = new HashSet<Integer>();
for (File file : files) {
Scanner scanner = new Scanner(file);
String imdb = null;
// scan for imdb id patterns like tt1234567
while ((imdb = scanner.findWithinHorizon("(?<=tt)\\d{7}", 32 * 1024)) != null) {
collection.add(Integer.parseInt(imdb));
}
}
return collection;
}
protected MovieDescriptor determineMovie(File movieFile) throws Exception {
List<MovieDescriptor> options = new ArrayList<MovieDescriptor>();
for (int imdbid : grepImdbId(movieFile.getParentFile().listFiles(getDefaultFilter("application/nfo")))) {
MovieDescriptor movie = service.getMovieDescriptor(imdbid);
if (movie != null) {
options.add(movie);
}
}
return options.isEmpty() ? null : selectMovie(options);
}
protected MovieDescriptor selectMovie(final List<MovieDescriptor> options) throws Exception {
if (options.size() == 1) {
return options.get(0);
}
// show selection dialog on EDT
final RunnableFuture<MovieDescriptor> showSelectDialog = new FutureTask<MovieDescriptor>(new Callable<MovieDescriptor>() {
@Override
public MovieDescriptor call() throws Exception {
// multiple results have been found, user must select one
SelectDialog<MovieDescriptor> selectDialog = new SelectDialog<MovieDescriptor>(null, options);
selectDialog.getHeaderLabel().setText("Select Movie:");
selectDialog.getCancelAction().putValue(Action.NAME, "Ignore");
// show dialog
selectDialog.setLocation(getOffsetLocation(selectDialog.getOwner()));
selectDialog.setVisible(true);
// selected value or null if the dialog was canceled by the user
return selectDialog.getSelectedValue();
}
});
// allow only one select dialog at a time
synchronized (this) {
SwingUtilities.invokeAndWait(showSelectDialog);
}
// selected value or null
return showSelectDialog.get();
}
}

View File

@ -7,5 +7,9 @@ import java.io.File;
public interface MovieIdentificationService {
public MovieDescriptor getMovieDescriptor(int imdbid) throws Exception;
public MovieDescriptor[] getMovieDescriptors(File[] movieFiles) throws Exception;
}

View File

@ -146,6 +146,15 @@ public class OpenSubtitlesClient implements SubtitleProvider, VideoHashSubtitleS
}
@Override
public MovieDescriptor getMovieDescriptor(int imdbid) throws Exception {
// require login
login();
return xmlrpc.getIMDBMovieDetails(imdbid);
}
@Override
public MovieDescriptor[] getMovieDescriptors(File[] movieFiles) throws Exception {
// create result array

View File

@ -243,6 +243,25 @@ public class OpenSubtitlesXmlRpc {
}
@SuppressWarnings("unchecked")
public MovieDescriptor getIMDBMovieDetails(int imdbid) throws XmlRpcFault {
Map<?, ?> response = invoke("GetIMDBMovieDetails", token, imdbid);
try {
Map<String, String> data = (Map<String, String>) response.get("data");
String name = data.get("title");
int year = Integer.parseInt(data.get("year"));
return new MovieDescriptor(name, year, imdbid);
} catch (RuntimeException e) {
// ignore, invalid response
}
return null;
}
@SuppressWarnings("unchecked")
public Map<String, String> getSubLanguages(String languageCode) throws XmlRpcFault {
Map<String, List<Map<String, String>>> response = (Map<String, List<Map<String, String>>>) invoke("GetSubLanguages", languageCode);

View File

@ -54,6 +54,20 @@ public class TMDbClient implements MovieIdentificationService {
}
public MovieDescriptor getMovieDescriptor(int imdbid) throws Exception {
URL resource = getResource("Movie.imdbLookup", String.format("tt%07d", imdbid));
Node movie = selectNode("//movie", getDocument(resource));
if (movie == null)
return null;
String name = getTextContent("name", movie);
int year = new Scanner(getTextContent("released", movie)).useDelimiter("\\D+").nextInt();
return new MovieDescriptor(name, year, imdbid);
}
@Override
public MovieDescriptor[] getMovieDescriptors(File[] movieFiles) throws Exception {
MovieDescriptor[] movies = new MovieDescriptor[movieFiles.length];

View File

@ -140,6 +140,26 @@ public class OpenSubtitlesXmlRpcTest {
}
@Test
public void getIMDBMovieDetails() throws Exception {
MovieDescriptor movie = xmlrpc.getIMDBMovieDetails(371746);
assertEquals("Iron Man", movie.getName());
assertEquals(2008, movie.getYear());
assertEquals(371746, movie.getImdbId());
}
@Test
public void getIMDBMovieDetailsInvalid() throws Exception {
MovieDescriptor movie = xmlrpc.getIMDBMovieDetails(371746);
assertEquals("Iron Man", movie.getName());
assertEquals(2008, movie.getYear());
assertEquals(371746, movie.getImdbId());
}
@Test
public void detectLanguage() throws Exception {
String text = "Only those that are prepared to fire should be fired at.";

View File

@ -36,4 +36,14 @@ public class TMDbClientTest {
assertEquals(371746, movie.getImdbId());
}
@Test
public void searchByIMDB() throws Exception {
MovieDescriptor movie = tmdb.getMovieDescriptor(418279);
assertEquals("Transformers", movie.getName());
assertEquals(2007, movie.getYear());
assertEquals(418279, movie.getImdbId());
}
}