diff --git a/source/net/filebot/format/MediaBindingBean.java b/source/net/filebot/format/MediaBindingBean.java index 4d3295cb..ac414e25 100644 --- a/source/net/filebot/format/MediaBindingBean.java +++ b/source/net/filebot/format/MediaBindingBean.java @@ -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 { diff --git a/source/net/filebot/web/MovieInfo.java b/source/net/filebot/web/MovieInfo.java new file mode 100644 index 00000000..b2786739 --- /dev/null +++ b/source/net/filebot/web/MovieInfo.java @@ -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 fields; + + protected String[] alternativeTitles; + protected String[] genres; + protected String[] spokenLanguages; + protected String[] productionCountries; + protected String[] productionCompanies; + protected Map certifications; + + protected Person[] people; + protected Trailer[] trailers; + + public MovieInfo() { + // used by serializer + } + + public MovieInfo(Map fields, List alternativeTitles, List genres, Map certifications, List spokenLanguages, List productionCountries, List productionCompanies, List people, List trailers) { + this.fields = new EnumMap(fields); + this.alternativeTitles = alternativeTitles.toArray(new String[0]); + this.genres = genres.toArray(new String[0]); + this.certifications = new LinkedHashMap(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 get(Property key, Transform 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 getGenres() { + return unmodifiableList(asList(genres)); + } + + public List getSpokenLanguages() { + return stream(spokenLanguages).map(Locale::new).collect(toList()); + } + + public List getCrew() { + return unmodifiableList(asList(people)); + } + + public Map getCertifications() { + return unmodifiableMap(certifications); // e.g. ['US': PG-13] + } + + public List getProductionCountries() { + return unmodifiableList(asList(productionCountries)); + } + + public List getProductionCompanies() { + return unmodifiableList(asList(productionCompanies)); + } + + public List getTrailers() { + return unmodifiableList(asList(trailers)); + } + + public List getAlternativeTitles() { + return unmodifiableList(asList(alternativeTitles)); + } + + @Override + public String toString() { + return fields.toString(); + } + +} \ No newline at end of file diff --git a/source/net/filebot/web/OMDbClient.java b/source/net/filebot/web/OMDbClient.java index 00329611..2e2d782a 100644 --- a/source/net/filebot/web/OMDbClient.java +++ b/source/net/filebot/web/OMDbClient.java @@ -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 fields = new EnumMap(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 fields = new EnumMap(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 diff --git a/source/net/filebot/web/TMDbClient.java b/source/net/filebot/web/TMDbClient.java index 6bf4a14b..9cf388e1 100644 --- a/source/net/filebot/web/TMDbClient.java +++ b/source/net/filebot/web/TMDbClient.java @@ -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 fields = getEnumMap(response, MovieProperty.class); + Map 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 fields; - - protected String[] alternativeTitles; - protected String[] genres; - protected String[] spokenLanguages; - protected String[] productionCountries; - protected String[] productionCompanies; - protected Map certifications; - - protected Person[] people; - protected Trailer[] trailers; - - public MovieInfo() { - // used by serializer - } - - protected MovieInfo(Map fields, List alternativeTitles, List genres, Map certifications, List spokenLanguages, List productionCountries, List productionCompanies, List people, List trailers) { - this.fields = new EnumMap(fields); - this.alternativeTitles = alternativeTitles.toArray(new String[0]); - this.genres = genres.toArray(new String[0]); - this.certifications = new LinkedHashMap(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 get(MovieProperty key, Transform 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 getGenres() { - return unmodifiableList(asList(genres)); - } - - public List getSpokenLanguages() { - return stream(spokenLanguages).map(Locale::new).collect(toList()); - } - - public List getCrew() { - return unmodifiableList(asList(people)); - } - - public Map getCertifications() { - return unmodifiableMap(certifications); // e.g. ['US': PG-13] - } - - public List getProductionCountries() { - return unmodifiableList(asList(productionCountries)); - } - - public List getProductionCompanies() { - return unmodifiableList(asList(productionCompanies)); - } - - public List getTrailers() { - return unmodifiableList(asList(trailers)); - } - - public List 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 sources; - - public Trailer() { - // used by serializer - } - - public Trailer(String type, String name, Map sources) { - this.type = type; - this.name = name; - this.sources = sources; - } - - public String getType() { - return type; - } - - public String getName() { - return name; - } - - public Map 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); - } - - } - } diff --git a/source/net/filebot/web/Trailer.java b/source/net/filebot/web/Trailer.java new file mode 100644 index 00000000..d157ba51 --- /dev/null +++ b/source/net/filebot/web/Trailer.java @@ -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 sources; + + public Trailer() { + // used by serializer + } + + public Trailer(String type, String name, Map sources) { + this.type = type; + this.name = name; + this.sources = sources; + } + + public String getType() { + return type; + } + + public String getName() { + return name; + } + + public Map 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); + } + +} diff --git a/test/net/filebot/web/OMDbClientTest.java b/test/net/filebot/web/OMDbClientTest.java index da8bd14c..85a6575f 100644 --- a/test/net/filebot/web/OMDbClientTest.java +++ b/test/net/filebot/web/OMDbClientTest.java @@ -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(); diff --git a/test/net/filebot/web/TMDbClientTest.java b/test/net/filebot/web/TMDbClientTest.java index d5df4bfa..2d542df4 100644 --- a/test/net/filebot/web/TMDbClientTest.java +++ b/test/net/filebot/web/TMDbClientTest.java @@ -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 {