* added fallback for movie identification by scanning .nfo files for an imdb id
This commit is contained in:
parent
7a87ea9573
commit
5519c1440d
|
@ -13,7 +13,11 @@
|
||||||
<extension>txt</extension>
|
<extension>txt</extension>
|
||||||
</type>
|
</type>
|
||||||
|
|
||||||
|
<type name="application/nfo">
|
||||||
|
<extension>nfo</extension>
|
||||||
|
</type>
|
||||||
|
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Verification
|
Verification
|
||||||
-->
|
-->
|
||||||
|
|
|
@ -3,12 +3,24 @@ package net.sourceforge.filebot.ui.panel.rename;
|
||||||
|
|
||||||
|
|
||||||
import static net.sourceforge.filebot.MediaTypes.*;
|
import static net.sourceforge.filebot.MediaTypes.*;
|
||||||
|
import static net.sourceforge.tuned.ui.TunedUtilities.*;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
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.similarity.Match;
|
||||||
|
import net.sourceforge.filebot.ui.SelectDialog;
|
||||||
import net.sourceforge.filebot.web.MovieDescriptor;
|
import net.sourceforge.filebot.web.MovieDescriptor;
|
||||||
import net.sourceforge.filebot.web.MovieIdentificationService;
|
import net.sourceforge.filebot.web.MovieIdentificationService;
|
||||||
import net.sourceforge.tuned.FileUtilities;
|
import net.sourceforge.tuned.FileUtilities;
|
||||||
|
@ -35,10 +47,84 @@ class MovieHashMatcher implements AutoCompleteMatcher {
|
||||||
for (int i = 0; i < movieDescriptors.length; i++) {
|
for (int i = 0; i < movieDescriptors.length; i++) {
|
||||||
if (movieDescriptors[i] != null) {
|
if (movieDescriptors[i] != null) {
|
||||||
matches.add(new Match<File, MovieDescriptor>(movieFiles[i], movieDescriptors[i]));
|
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;
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,5 +7,9 @@ import java.io.File;
|
||||||
|
|
||||||
public interface MovieIdentificationService {
|
public interface MovieIdentificationService {
|
||||||
|
|
||||||
|
public MovieDescriptor getMovieDescriptor(int imdbid) throws Exception;
|
||||||
|
|
||||||
|
|
||||||
public MovieDescriptor[] getMovieDescriptors(File[] movieFiles) throws Exception;
|
public MovieDescriptor[] getMovieDescriptors(File[] movieFiles) throws Exception;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
@Override
|
||||||
public MovieDescriptor[] getMovieDescriptors(File[] movieFiles) throws Exception {
|
public MovieDescriptor[] getMovieDescriptors(File[] movieFiles) throws Exception {
|
||||||
// create result array
|
// create result array
|
||||||
|
|
|
@ -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")
|
@SuppressWarnings("unchecked")
|
||||||
public Map<String, String> getSubLanguages(String languageCode) throws XmlRpcFault {
|
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);
|
Map<String, List<Map<String, String>>> response = (Map<String, List<Map<String, String>>>) invoke("GetSubLanguages", languageCode);
|
||||||
|
|
|
@ -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
|
@Override
|
||||||
public MovieDescriptor[] getMovieDescriptors(File[] movieFiles) throws Exception {
|
public MovieDescriptor[] getMovieDescriptors(File[] movieFiles) throws Exception {
|
||||||
MovieDescriptor[] movies = new MovieDescriptor[movieFiles.length];
|
MovieDescriptor[] movies = new MovieDescriptor[movieFiles.length];
|
||||||
|
|
|
@ -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
|
@Test
|
||||||
public void detectLanguage() throws Exception {
|
public void detectLanguage() throws Exception {
|
||||||
String text = "Only those that are prepared to fire should be fired at.";
|
String text = "Only those that are prepared to fire should be fired at.";
|
||||||
|
|
|
@ -36,4 +36,14 @@ public class TMDbClientTest {
|
||||||
assertEquals(371746, movie.getImdbId());
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue