* internal support for fetching complete movie info including artwork
This commit is contained in:
parent
cb1aa12201
commit
05a7fbb1af
|
@ -2,17 +2,21 @@
|
||||||
package net.sourceforge.filebot.web;
|
package net.sourceforge.filebot.web;
|
||||||
|
|
||||||
|
|
||||||
|
import static java.util.Arrays.*;
|
||||||
|
import static java.util.Collections.*;
|
||||||
import static net.sourceforge.filebot.web.WebRequest.*;
|
import static net.sourceforge.filebot.web.WebRequest.*;
|
||||||
import static net.sourceforge.tuned.XPathUtilities.*;
|
import static net.sourceforge.tuned.XPathUtilities.*;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.Serializable;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.EnumMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
@ -23,6 +27,8 @@ import org.w3c.dom.Node;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
import net.sourceforge.filebot.ResourceManager;
|
import net.sourceforge.filebot.ResourceManager;
|
||||||
|
import net.sourceforge.filebot.web.TMDbClient.Artwork.ArtworkProperty;
|
||||||
|
import net.sourceforge.filebot.web.TMDbClient.MovieInfo.MovieProperty;
|
||||||
|
|
||||||
|
|
||||||
public class TMDbClient implements MovieIdentificationService {
|
public class TMDbClient implements MovieIdentificationService {
|
||||||
|
@ -57,12 +63,15 @@ public class TMDbClient implements MovieIdentificationService {
|
||||||
} catch (SAXException e) {
|
} catch (SAXException e) {
|
||||||
// TMDb output is sometimes malformed xml
|
// TMDb output is sometimes malformed xml
|
||||||
Logger.getLogger(getClass().getName()).log(Level.WARNING, e.getMessage());
|
Logger.getLogger(getClass().getName()).log(Level.WARNING, e.getMessage());
|
||||||
return Collections.emptyList();
|
return emptyList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public List<Movie> searchMovie(File file, Locale locale) throws IOException, SAXException {
|
public List<Movie> searchMovie(File file, Locale locale) throws IOException, SAXException {
|
||||||
|
if (file.length() < OpenSubtitlesHasher.HASH_CHUNK_SIZE)
|
||||||
|
return emptyList();
|
||||||
|
|
||||||
return searchMovie(OpenSubtitlesHasher.computeHash(file), file.length(), locale);
|
return searchMovie(OpenSubtitlesHasher.computeHash(file), file.length(), locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,4 +139,242 @@ public class TMDbClient implements MovieIdentificationService {
|
||||||
return new URL("http", host, "/" + version + "/" + method + "/" + locale.getLanguage() + "/xml/" + apikey + "/" + parameter);
|
return new URL("http", host, "/" + version + "/" + method + "/" + locale.getLanguage() + "/xml/" + apikey + "/" + parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public MovieInfo getMovieInfo(Movie movie, Locale locale) throws Exception {
|
||||||
|
URL resource = getResource("Movie.imdbLookup", String.format("tt%07d", movie.getImdbId()), locale);
|
||||||
|
Node node = selectNode("//movie", getDocument(resource));
|
||||||
|
|
||||||
|
Map<MovieProperty, String> movieProperties = new EnumMap<MovieProperty, String>(MovieProperty.class);
|
||||||
|
for (MovieProperty property : MovieProperty.values()) {
|
||||||
|
movieProperties.put(property, getTextContent(property.name(), node));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> genres = new ArrayList<String>();
|
||||||
|
for (Node category : selectNodes("//category[@type='genre']", node)) {
|
||||||
|
genres.add(getAttribute("name", category));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Artwork> artwork = new ArrayList<Artwork>();
|
||||||
|
for (Node image : selectNodes("//image", node)) {
|
||||||
|
Map<ArtworkProperty, String> artworkProperties = new EnumMap<ArtworkProperty, String>(ArtworkProperty.class);
|
||||||
|
for (ArtworkProperty property : ArtworkProperty.values()) {
|
||||||
|
artworkProperties.put(property, getAttribute(property.name(), image));
|
||||||
|
}
|
||||||
|
artwork.add(new Artwork(artworkProperties));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new MovieInfo(movieProperties, genres, artwork);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class MovieInfo implements Serializable {
|
||||||
|
|
||||||
|
public static enum MovieProperty {
|
||||||
|
translated,
|
||||||
|
adult,
|
||||||
|
language,
|
||||||
|
name,
|
||||||
|
type,
|
||||||
|
id,
|
||||||
|
imdb_id,
|
||||||
|
url,
|
||||||
|
overview,
|
||||||
|
votes,
|
||||||
|
rating,
|
||||||
|
certification,
|
||||||
|
released,
|
||||||
|
runtime
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected Map<MovieProperty, String> fields;
|
||||||
|
protected String[] genres;
|
||||||
|
protected Artwork[] images;
|
||||||
|
|
||||||
|
|
||||||
|
protected MovieInfo() {
|
||||||
|
// used by serializer
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected MovieInfo(Map<MovieProperty, String> fields, List<String> genres, List<Artwork> images) {
|
||||||
|
this.fields = new EnumMap<MovieProperty, String>(fields);
|
||||||
|
this.genres = genres.toArray(new String[0]);
|
||||||
|
this.images = images.toArray(new Artwork[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String get(Object key) {
|
||||||
|
return fields.get(MovieProperty.valueOf(key.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String get(MovieProperty key) {
|
||||||
|
return fields.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isTranslated() {
|
||||||
|
return Boolean.valueOf(get(MovieProperty.translated));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isAdult() {
|
||||||
|
return Boolean.valueOf(get(MovieProperty.adult));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Locale getLanguage() {
|
||||||
|
return new Locale(get(MovieProperty.language));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return get(MovieProperty.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return get(MovieProperty.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return Integer.parseInt(get(MovieProperty.id));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getImdbId() {
|
||||||
|
// e.g. tt0379786
|
||||||
|
return Integer.parseInt(get(MovieProperty.imdb_id).substring(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public URL getUrl() {
|
||||||
|
try {
|
||||||
|
return new URL(get(MovieProperty.url));
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getOverview() {
|
||||||
|
return get(MovieProperty.overview);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getVotes() {
|
||||||
|
return Integer.parseInt(get(MovieProperty.votes));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public double getRating() {
|
||||||
|
return Double.parseDouble(get(MovieProperty.rating));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getCertification() {
|
||||||
|
// e.g. PG-13
|
||||||
|
return get(MovieProperty.certification);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Date getReleased() {
|
||||||
|
// e.g. 2005-09-30
|
||||||
|
return Date.parse(get(MovieProperty.released), "yyyy-MM-dd");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getRuntime() {
|
||||||
|
return Integer.parseInt(get(MovieProperty.runtime));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<String> getGenres() {
|
||||||
|
return unmodifiableList(asList(genres));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<Artwork> getImages() {
|
||||||
|
return unmodifiableList(asList(images));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return fields.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class Artwork implements Serializable {
|
||||||
|
|
||||||
|
public static enum ArtworkProperty {
|
||||||
|
type,
|
||||||
|
url,
|
||||||
|
size,
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected Map<ArtworkProperty, String> fields;
|
||||||
|
|
||||||
|
|
||||||
|
protected Artwork() {
|
||||||
|
// used by serializer
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected Artwork(Map<ArtworkProperty, String> fields) {
|
||||||
|
this.fields = new EnumMap<ArtworkProperty, String>(fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String get(Object key) {
|
||||||
|
return fields.get(ArtworkProperty.valueOf(key.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String get(ArtworkProperty key) {
|
||||||
|
return fields.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return get(ArtworkProperty.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public URL getUrl() {
|
||||||
|
try {
|
||||||
|
return new URL(get(ArtworkProperty.url));
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getSize() {
|
||||||
|
return get(ArtworkProperty.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getWidth() {
|
||||||
|
return Integer.parseInt(get(ArtworkProperty.width));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getHeight() {
|
||||||
|
return Integer.parseInt(get(ArtworkProperty.height));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return fields.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,8 @@ import java.util.Locale;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import net.sourceforge.filebot.web.TMDbClient.MovieInfo;
|
||||||
|
|
||||||
|
|
||||||
public class TMDbClientTest {
|
public class TMDbClientTest {
|
||||||
|
|
||||||
|
@ -33,8 +35,8 @@ public class TMDbClientTest {
|
||||||
Movie movie = results.get(0);
|
Movie movie = results.get(0);
|
||||||
|
|
||||||
assertEquals("Sin City", movie.getName());
|
assertEquals("Sin City", movie.getName());
|
||||||
assertEquals(2005, movie.getYear());
|
assertEquals(2005, movie.getYear(), 0);
|
||||||
assertEquals(401792, movie.getImdbId());
|
assertEquals(401792, movie.getImdbId(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,8 +45,19 @@ public class TMDbClientTest {
|
||||||
Movie movie = tmdb.getMovieDescriptor(418279, Locale.ENGLISH);
|
Movie movie = tmdb.getMovieDescriptor(418279, Locale.ENGLISH);
|
||||||
|
|
||||||
assertEquals("Transformers", movie.getName());
|
assertEquals("Transformers", movie.getName());
|
||||||
assertEquals(2007, movie.getYear());
|
assertEquals(2007, movie.getYear(), 0);
|
||||||
assertEquals(418279, movie.getImdbId());
|
assertEquals(418279, movie.getImdbId(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getMovieInfo() throws Exception {
|
||||||
|
MovieInfo movie = tmdb.getMovieInfo(new Movie(null, 0, 418279), Locale.ENGLISH);
|
||||||
|
|
||||||
|
assertEquals("Transformers", movie.getName());
|
||||||
|
assertEquals("2007-07-03", movie.getReleased().toString());
|
||||||
|
assertEquals("Adventure", movie.getGenres().get(0));
|
||||||
|
assertEquals("thumb", movie.getImages().get(0).getSize());
|
||||||
|
assertEquals("http://cf2.imgobject.com/t/p/w92/bgSHbGEA1OM6qDs3Qba4VlSZsNG.jpg", movie.getImages().get(0).getUrl().toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue