Refactor MovieInfo

This commit is contained in:
Reinhard Pointner 2017-02-08 23:17:05 +08:00
parent 6b6e9d3f6b
commit b1557c7788
7 changed files with 240 additions and 228 deletions

View File

@ -62,12 +62,12 @@ import net.filebot.web.AudioTrack;
import net.filebot.web.Episode;
import net.filebot.web.EpisodeFormat;
import net.filebot.web.Movie;
import net.filebot.web.MovieInfo;
import net.filebot.web.MoviePart;
import net.filebot.web.MultiEpisode;
import net.filebot.web.SeriesInfo;
import net.filebot.web.SimpleDate;
import net.filebot.web.SortOrder;
import net.filebot.web.TMDbClient.MovieInfo;
import net.filebot.web.TheTVDBSeriesInfo;
public class MediaBindingBean {

View File

@ -0,0 +1,182 @@
package net.filebot.web;
import static java.util.Arrays.*;
import static java.util.Collections.*;
import static java.util.stream.Collectors.*;
import static net.filebot.Logging.*;
import java.io.Serializable;
import java.net.URL;
import java.util.EnumMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.logging.Level;
import net.filebot.CachedResource.Transform;
public class MovieInfo implements Crew, Serializable {
public enum Property {
adult, backdrop_path, budget, homepage, id, imdb_id, original_title, original_language, overview, popularity, poster_path, release_date, revenue, runtime, tagline, title, vote_average, vote_count, certification, collection
}
protected Map<Property, String> fields;
protected String[] alternativeTitles;
protected String[] genres;
protected String[] spokenLanguages;
protected String[] productionCountries;
protected String[] productionCompanies;
protected Map<String, String> certifications;
protected Person[] people;
protected Trailer[] trailers;
public MovieInfo() {
// used by serializer
}
public MovieInfo(Map<Property, String> fields, List<String> alternativeTitles, List<String> genres, Map<String, String> certifications, List<String> spokenLanguages, List<String> productionCountries, List<String> productionCompanies, List<Person> people, List<Trailer> trailers) {
this.fields = new EnumMap<Property, String>(fields);
this.alternativeTitles = alternativeTitles.toArray(new String[0]);
this.genres = genres.toArray(new String[0]);
this.certifications = new LinkedHashMap<String, String>(certifications);
this.spokenLanguages = spokenLanguages.toArray(new String[0]);
this.productionCountries = productionCountries.toArray(new String[0]);
this.productionCompanies = productionCompanies.toArray(new String[0]);
this.people = people.toArray(new Person[0]);
this.trailers = trailers.toArray(new Trailer[0]);
}
public String get(Object key) {
return fields.get(Property.valueOf(key.toString()));
}
public String get(Property key) {
return fields.get(key);
}
private <T> T get(Property key, Transform<String, T> cast) {
try {
String value = fields.get(key);
if (value != null && !value.isEmpty()) {
return cast.transform(value);
}
} catch (Exception e) {
debug.log(Level.WARNING, format("Failed to parse %s value: %s: %s", key, e, fields));
}
return null;
}
public String getName() {
return get(Property.title);
}
public String getOriginalName() {
return get(Property.original_title);
}
public String getOriginalLanguage() {
return get(Property.original_language);
}
public String getCollection() {
return get(Property.collection); // e.g. Star Wars Collection
}
public String getCertification() {
return get(Property.certification); // e.g. PG-13
}
public String getTagline() {
return get(Property.tagline);
}
public String getOverview() {
return get(Property.overview);
}
public Integer getId() {
return get(Property.id, Integer::new);
}
public Integer getImdbId() {
return get(Property.imdb_id, s -> new Integer(s.substring(2))); // e.g. tt0379786
}
public Integer getVotes() {
return get(Property.vote_count, Integer::new);
}
public Double getRating() {
return get(Property.vote_average, Double::new);
}
public SimpleDate getReleased() {
return get(Property.release_date, SimpleDate::parse); // e.g. 2005-09-30
}
public Integer getRuntime() {
return get(Property.runtime, Integer::new);
}
public Long getBudget() {
return get(Property.budget, Long::new);
}
public Long getRevenue() {
return get(Property.revenue, Long::new);
}
public Double getPopularity() {
return get(Property.popularity, Double::new);
}
public URL getHomepage() {
return get(Property.homepage, URL::new);
}
public URL getPoster() {
return get(Property.poster_path, URL::new);
}
public List<String> getGenres() {
return unmodifiableList(asList(genres));
}
public List<Locale> getSpokenLanguages() {
return stream(spokenLanguages).map(Locale::new).collect(toList());
}
public List<Person> getCrew() {
return unmodifiableList(asList(people));
}
public Map<String, String> getCertifications() {
return unmodifiableMap(certifications); // e.g. ['US': PG-13]
}
public List<String> getProductionCountries() {
return unmodifiableList(asList(productionCountries));
}
public List<String> getProductionCompanies() {
return unmodifiableList(asList(productionCompanies));
}
public List<Trailer> getTrailers() {
return unmodifiableList(asList(trailers));
}
public List<String> getAlternativeTitles() {
return unmodifiableList(asList(alternativeTitles));
}
@Override
public String toString() {
return fields.toString();
}
}

View File

@ -31,8 +31,6 @@ import javax.swing.Icon;
import net.filebot.Cache;
import net.filebot.CacheType;
import net.filebot.ResourceManager;
import net.filebot.web.TMDbClient.MovieInfo;
import net.filebot.web.TMDbClient.MovieProperty;
public class OMDbClient implements MovieIdentificationService {
@ -162,15 +160,15 @@ public class OMDbClient implements MovieIdentificationService {
throw new IllegalArgumentException("Movie not found: " + data);
}
Map<MovieProperty, String> fields = new EnumMap<MovieProperty, String>(MovieProperty.class);
fields.put(MovieProperty.title, data.get("title"));
fields.put(MovieProperty.certification, data.get("rated"));
fields.put(MovieProperty.runtime, getRuntimeMinutes(data.get("runtime")));
fields.put(MovieProperty.tagline, data.get("plot"));
fields.put(MovieProperty.vote_average, data.get("imdbRating"));
fields.put(MovieProperty.vote_count, data.get("imdbVotes").replaceAll("\\D", ""));
fields.put(MovieProperty.imdb_id, data.get("imdbID"));
fields.put(MovieProperty.poster_path, data.get("poster"));
Map<MovieInfo.Property, String> fields = new EnumMap<MovieInfo.Property, String>(MovieInfo.Property.class);
fields.put(MovieInfo.Property.title, data.get("title"));
fields.put(MovieInfo.Property.certification, data.get("rated"));
fields.put(MovieInfo.Property.runtime, getRuntimeMinutes(data.get("runtime")));
fields.put(MovieInfo.Property.tagline, data.get("plot"));
fields.put(MovieInfo.Property.vote_average, data.get("imdbRating"));
fields.put(MovieInfo.Property.vote_count, data.get("imdbVotes").replaceAll("\\D", ""));
fields.put(MovieInfo.Property.imdb_id, data.get("imdbID"));
fields.put(MovieInfo.Property.poster_path, data.get("poster"));
// convert release date to yyyy-MM-dd
SimpleDate release = parsePartialDate(data.get("released"), "d MMM yyyy");
@ -178,7 +176,7 @@ public class OMDbClient implements MovieIdentificationService {
release = parsePartialDate(data.get("released"), "yyyy");
}
if (release != null) {
fields.put(MovieProperty.release_date, release.toString());
fields.put(MovieInfo.Property.release_date, release.toString());
}
// convert lists

View File

@ -1,6 +1,5 @@
package net.filebot.web;
import static java.util.Arrays.*;
import static java.util.Collections.*;
import static java.util.stream.Collectors.*;
import static net.filebot.CachedResource.*;
@ -11,12 +10,10 @@ import static net.filebot.util.StringUtilities.*;
import static net.filebot.web.WebRequest.*;
import java.io.FileNotFoundException;
import java.io.Serializable;
import java.net.URI;
import java.net.URL;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
@ -35,7 +32,6 @@ import javax.swing.Icon;
import net.filebot.Cache;
import net.filebot.CacheType;
import net.filebot.CachedResource.Transform;
import net.filebot.ResourceManager;
public class TMDbClient implements MovieIdentificationService, ArtworkProvider {
@ -179,11 +175,11 @@ public class TMDbClient implements MovieIdentificationService, ArtworkProvider {
Object response = request("movie/" + id, extendedInfo ? singletonMap("append_to_response", "alternative_titles,releases,casts,trailers") : emptyMap(), locale);
// read all basic movie properties
Map<MovieProperty, String> fields = getEnumMap(response, MovieProperty.class);
Map<MovieInfo.Property, String> fields = getEnumMap(response, MovieInfo.Property.class);
// fix poster path
try {
fields.computeIfPresent(MovieProperty.poster_path, (k, v) -> extendedInfo ? resolveImage(v).toString() : null);
fields.computeIfPresent(MovieInfo.Property.poster_path, (k, v) -> extendedInfo ? resolveImage(v).toString() : null);
} catch (Exception e) {
// movie does not belong to any collection
debug.warning(format("Bad data: poster_path => %s", response));
@ -191,7 +187,7 @@ public class TMDbClient implements MovieIdentificationService, ArtworkProvider {
try {
Map<?, ?> collection = getMap(response, "belongs_to_collection");
fields.put(MovieProperty.collection, getString(collection, "name"));
fields.put(MovieInfo.Property.collection, getString(collection, "name"));
} catch (Exception e) {
// movie does not belong to any collection
debug.warning(format("Bad data: belongs_to_collection => %s", response));
@ -243,7 +239,7 @@ public class TMDbClient implements MovieIdentificationService, ArtworkProvider {
if (certification != null && certificationCountry != null) {
// add country specific certification code
if (countryCode.equals(certificationCountry)) {
fields.put(MovieProperty.certification, certification);
fields.put(MovieInfo.Property.certification, certification);
}
// collect all certification codes just in case
@ -405,208 +401,4 @@ public class TMDbClient implements MovieIdentificationService, ArtworkProvider {
return null;
}
public static enum MovieProperty {
adult, backdrop_path, budget, homepage, id, imdb_id, original_title, original_language, overview, popularity, poster_path, release_date, revenue, runtime, tagline, title, vote_average, vote_count, certification, collection
}
public static class MovieInfo implements Crew, Serializable {
protected Map<MovieProperty, String> fields;
protected String[] alternativeTitles;
protected String[] genres;
protected String[] spokenLanguages;
protected String[] productionCountries;
protected String[] productionCompanies;
protected Map<String, String> certifications;
protected Person[] people;
protected Trailer[] trailers;
public MovieInfo() {
// used by serializer
}
protected MovieInfo(Map<MovieProperty, String> fields, List<String> alternativeTitles, List<String> genres, Map<String, String> certifications, List<String> spokenLanguages, List<String> productionCountries, List<String> productionCompanies, List<Person> people, List<Trailer> trailers) {
this.fields = new EnumMap<MovieProperty, String>(fields);
this.alternativeTitles = alternativeTitles.toArray(new String[0]);
this.genres = genres.toArray(new String[0]);
this.certifications = new LinkedHashMap<String, String>(certifications);
this.spokenLanguages = spokenLanguages.toArray(new String[0]);
this.productionCountries = productionCountries.toArray(new String[0]);
this.productionCompanies = productionCompanies.toArray(new String[0]);
this.people = people.toArray(new Person[0]);
this.trailers = trailers.toArray(new Trailer[0]);
}
public String get(Object key) {
return fields.get(MovieProperty.valueOf(key.toString()));
}
public String get(MovieProperty key) {
return fields.get(key);
}
private <T> T get(MovieProperty key, Transform<String, T> cast) {
try {
String value = fields.get(key);
if (value != null && !value.isEmpty()) {
return cast.transform(value);
}
} catch (Exception e) {
debug.log(Level.WARNING, format("Failed to parse %s value: %s: %s", key, e, fields));
}
return null;
}
public String getName() {
return get(MovieProperty.title);
}
public String getOriginalName() {
return get(MovieProperty.original_title);
}
public String getOriginalLanguage() {
return get(MovieProperty.original_language);
}
public String getCollection() {
return get(MovieProperty.collection); // e.g. Star Wars Collection
}
public String getCertification() {
return get(MovieProperty.certification); // e.g. PG-13
}
public String getTagline() {
return get(MovieProperty.tagline);
}
public String getOverview() {
return get(MovieProperty.overview);
}
public Integer getId() {
return get(MovieProperty.id, Integer::new);
}
public Integer getImdbId() {
return get(MovieProperty.imdb_id, s -> new Integer(s.substring(2))); // e.g. tt0379786
}
public Integer getVotes() {
return get(MovieProperty.vote_count, Integer::new);
}
public Double getRating() {
return get(MovieProperty.vote_average, Double::new);
}
public SimpleDate getReleased() {
return get(MovieProperty.release_date, SimpleDate::parse); // e.g. 2005-09-30
}
public Integer getRuntime() {
return get(MovieProperty.runtime, Integer::new);
}
public Long getBudget() {
return get(MovieProperty.budget, Long::new);
}
public Long getRevenue() {
return get(MovieProperty.revenue, Long::new);
}
public Double getPopularity() {
return get(MovieProperty.popularity, Double::new);
}
public URL getHomepage() {
return get(MovieProperty.homepage, URL::new);
}
public URL getPoster() {
return get(MovieProperty.poster_path, URL::new);
}
public List<String> getGenres() {
return unmodifiableList(asList(genres));
}
public List<Locale> getSpokenLanguages() {
return stream(spokenLanguages).map(Locale::new).collect(toList());
}
public List<Person> getCrew() {
return unmodifiableList(asList(people));
}
public Map<String, String> getCertifications() {
return unmodifiableMap(certifications); // e.g. ['US': PG-13]
}
public List<String> getProductionCountries() {
return unmodifiableList(asList(productionCountries));
}
public List<String> getProductionCompanies() {
return unmodifiableList(asList(productionCompanies));
}
public List<Trailer> getTrailers() {
return unmodifiableList(asList(trailers));
}
public List<String> getAlternativeTitles() {
return unmodifiableList(asList(alternativeTitles));
}
@Override
public String toString() {
return fields.toString();
}
}
public static class Trailer implements Serializable {
protected String type;
protected String name;
protected Map<String, String> sources;
public Trailer() {
// used by serializer
}
public Trailer(String type, String name, Map<String, String> sources) {
this.type = type;
this.name = name;
this.sources = sources;
}
public String getType() {
return type;
}
public String getName() {
return name;
}
public Map<String, String> getSources() {
return sources;
}
public String getSource(String size) {
return sources.containsKey(size) ? sources.get(size) : sources.values().iterator().next();
}
@Override
public String toString() {
return String.format("%s %s (%s)", name, sources.keySet(), type);
}
}
}

View File

@ -0,0 +1,43 @@
package net.filebot.web;
import java.io.Serializable;
import java.util.Map;
public class Trailer implements Serializable {
protected String type;
protected String name;
protected Map<String, String> sources;
public Trailer() {
// used by serializer
}
public Trailer(String type, String name, Map<String, String> sources) {
this.type = type;
this.name = name;
this.sources = sources;
}
public String getType() {
return type;
}
public String getName() {
return name;
}
public Map<String, String> getSources() {
return sources;
}
public String getSource(String size) {
return sources.containsKey(size) ? sources.get(size) : sources.values().iterator().next();
}
@Override
public String toString() {
return String.format("%s %s (%s)", name, sources.keySet(), type);
}
}

View File

@ -6,8 +6,6 @@ import java.util.List;
import org.junit.Test;
import net.filebot.web.TMDbClient.MovieInfo;
public class OMDbClientTest {
private final OMDbClient client = new OMDbClient();

View File

@ -17,7 +17,6 @@ import org.junit.Test;
import net.filebot.Cache;
import net.filebot.CacheType;
import net.filebot.CachedResource;
import net.filebot.web.TMDbClient.MovieInfo;
public class TMDbClientTest {