From 9f135c3ca73d19672cb0db9c33b9210f960f8f14 Mon Sep 17 00:00:00 2001 From: Stuart Boston Date: Tue, 14 May 2013 16:01:25 +0100 Subject: [PATCH] Removed reliance on MovieDb object from ApiBuilder --- .../omertron/themoviedbapi/TheMovieDbApi.java | 3046 +++++++++-------- .../omertron/themoviedbapi/model/MovieDb.java | 709 ++-- .../omertron/themoviedbapi/tools/ApiUrl.java | 437 +-- 3 files changed, 2103 insertions(+), 2089 deletions(-) diff --git a/src/main/java/com/omertron/themoviedbapi/TheMovieDbApi.java b/src/main/java/com/omertron/themoviedbapi/TheMovieDbApi.java index 4c75f5c67..264a4529d 100644 --- a/src/main/java/com/omertron/themoviedbapi/TheMovieDbApi.java +++ b/src/main/java/com/omertron/themoviedbapi/TheMovieDbApi.java @@ -1,1522 +1,1524 @@ -/* - * Copyright (c) 2004-2013 Stuart Boston - * - * This file is part of TheMovieDB API. - * - * TheMovieDB API is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * TheMovieDB API is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with TheMovieDB API. If not, see . - * - */ -package com.omertron.themoviedbapi; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.omertron.themoviedbapi.MovieDbException.MovieDbExceptionType; -import com.omertron.themoviedbapi.model.*; -import com.omertron.themoviedbapi.tools.ApiUrl; -import static com.omertron.themoviedbapi.tools.ApiUrl.*; -import com.omertron.themoviedbapi.tools.WebBrowser; -import com.omertron.themoviedbapi.wrapper.*; -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * The MovieDb API

This is for version 3 of the API as specified here: http://help.themoviedb.org/kb/api/about-3 - * - * @author stuart.boston - */ -public class TheMovieDbApi { - - private static final Logger LOG = LoggerFactory.getLogger(TheMovieDbApi.class); - private String apiKey; - private TmdbConfiguration tmdbConfig; - /* - * API Methods - * - * These are not set to static so that multiple instances of - * the API can co-exist - */ - private static final String BASE_MOVIE = "movie/"; - private static final String BASE_PERSON = "person/"; - private static final String BASE_COMPANY = "company/"; - private static final String BASE_GENRE = "genre/"; - private static final String BASE_AUTH = "authentication/"; - private static final String BASE_COLLECTION = "collection/"; -// private static final String BASE_ACCOUNT = "account/"; - private static final String BASE_SEARCH = "search/"; - private static final String BASE_LIST = "list/"; - private static final String BASE_KEYWORD = "keyword/"; - // Account - /* - private final ApiUrl tmdbAccount = new ApiUrl(this, BASE_ACCOUNT); - private final ApiUrl tmdbFavouriteMovies = new ApiUrl(this, BASE_ACCOUNT, "/favorite_movies"); - private final ApiUrl tmdbPostFavourite = new ApiUrl(this, BASE_ACCOUNT, "/favorite"); - private final ApiUrl tmdbRatedMovies = new ApiUrl(this, BASE_ACCOUNT, "/rated_movies"); - private final ApiUrl tmdbMovieWatchList = new ApiUrl(this, BASE_ACCOUNT, "/movie_watchlist"); - private final ApiUrl tmdbPostMovieWatchList = new ApiUrl(this, BASE_ACCOUNT, "/movie_watchlist"); - */ - /* - * Jackson JSON configuration - */ - private static ObjectMapper mapper = new ObjectMapper(); - - /** - * API for The Movie Db. - * - * @param apiKey - * @throws MovieDbException - */ - public TheMovieDbApi(String apiKey) throws MovieDbException { - this.apiKey = apiKey; - ApiUrl apiUrl = new ApiUrl(this, "configuration"); - URL configUrl = apiUrl.buildUrl(); - String webpage = WebBrowser.request(configUrl); - - try { - WrapperConfig wc = mapper.readValue(webpage, WrapperConfig.class); - tmdbConfig = wc.getTmdbConfiguration(); - } catch (IOException ex) { - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, "Failed to read configuration", ex); - } - } - - /** - * Get the API key that is to be used - * - */ - public String getApiKey() { - return apiKey; - } - - /** - * Set the proxy information - * - * @param host - * @param port - * @param username - * @param password - */ - public void setProxy(String host, String port, String username, String password) { - WebBrowser.setProxyHost(host); - WebBrowser.setProxyPort(port); - WebBrowser.setProxyUsername(username); - WebBrowser.setProxyPassword(password); - } - - /** - * Set the connection and read time out values - * - * @param connect - * @param read - */ - public void setTimeout(int connect, int read) { - WebBrowser.setWebTimeoutConnect(connect); - WebBrowser.setWebTimeoutRead(read); - } - - /** - * Compare the MovieDB object with a title & year - * - * @param moviedb The moviedb object to compare too - * @param title The title of the movie to compare - * @param year The year of the movie to compare exact match - * @return True if there is a match, False otherwise. - */ - public static boolean compareMovies(MovieDb moviedb, String title, String year) { - return compareMovies(moviedb, title, year, 0); - } - - /** - * Compare the MovieDB object with a title & year - * - * @param moviedb The moviedb object to compare too - * @param title The title of the movie to compare - * @param year The year of the movie to compare - * @param maxDistance The Levenshtein Distance between the two titles. 0 = exact match - * @return True if there is a match, False otherwise. - */ - public static boolean compareMovies(MovieDb moviedb, String title, String year, int maxDistance) { - if ((moviedb == null) || (StringUtils.isBlank(title))) { - return Boolean.FALSE; - } - - if (isValidYear(year) && isValidYear(moviedb.getReleaseDate())) { - // Compare with year - String movieYear = moviedb.getReleaseDate().substring(0, 4); - if (movieYear.equals(year)) { - if (compareDistance(moviedb.getOriginalTitle(), title, maxDistance)) { - return Boolean.TRUE; - } - - if (compareDistance(moviedb.getTitle(), title, maxDistance)) { - return Boolean.TRUE; - } - } - } - - // Compare without year - if (compareDistance(moviedb.getOriginalTitle(), title, maxDistance)) { - return Boolean.TRUE; - } - - if (compareDistance(moviedb.getTitle(), title, maxDistance)) { - return Boolean.TRUE; - } - - return Boolean.FALSE; - } - - /** - * Compare the Levenshtein Distance between the two strings - * - * @param title1 - * @param title2 - * @param distance - */ - private static boolean compareDistance(String title1, String title2, int distance) { - return (StringUtils.getLevenshteinDistance(title1, title2) <= distance); - } - - /** - * Check the year is not blank or UNKNOWN - * - * @param year - */ - private static boolean isValidYear(String year) { - return (StringUtils.isNotBlank(year) && !year.equals("UNKNOWN")); - } - - // - /** - * Get the configuration information - */ - public TmdbConfiguration getConfiguration() { - return tmdbConfig; - } - - /** - * Generate the full image URL from the size and image path - * - * @param imagePath - * @param requiredSize - * @throws MovieDbException - */ - public URL createImageUrl(String imagePath, String requiredSize) throws MovieDbException { - if (!tmdbConfig.isValidSize(requiredSize)) { - throw new MovieDbException(MovieDbExceptionType.INVALID_IMAGE, requiredSize); - } - - StringBuilder sb = new StringBuilder(tmdbConfig.getBaseUrl()); - sb.append(requiredSize); - sb.append(imagePath); - try { - return (new URL(sb.toString())); - } catch (MalformedURLException ex) { - LOG.warn("Failed to create image URL: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.INVALID_URL, sb.toString(), ex); - } - } - - // - // - // - /** - * This method is used to generate a valid request token for user based authentication. - * - * A request token is required in order to request a session id. - * - * You can generate any number of request tokens but they will expire after 60 minutes. - * - * As soon as a valid session id has been created the token will be destroyed. - * - * @throws MovieDbException - */ - public TokenAuthorisation getAuthorisationToken() throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_AUTH, "token/new"); - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - return mapper.readValue(webpage, TokenAuthorisation.class); - } catch (IOException ex) { - LOG.warn("Failed to get Authorisation Token: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.AUTHORISATION_FAILURE, webpage, ex); - } - } - - /** - * This method is used to generate a session id for user based authentication. - * - * A session id is required in order to use any of the write methods. - * - * @param token - * @throws MovieDbException - */ - public TokenSession getSessionToken(TokenAuthorisation token) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_AUTH, "session/new"); - - if (!token.getSuccess()) { - LOG.warn("Authorisation token was not successful!"); - throw new MovieDbException(MovieDbExceptionType.AUTHORISATION_FAILURE, "Authorisation token was not successful!"); - } - - apiUrl.addArgument(PARAM_TOKEN, token.getRequestToken()); - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - return mapper.readValue(webpage, TokenSession.class); - } catch (IOException ex) { - LOG.warn("Failed to get Session Token: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - /** - * This method is used to generate a guest session id. - * - * A guest session can be used to rate movies without having a registered TMDb user account. - * - * You should only generate a single guest session per user (or device) as you will be able to attach the ratings to a TMDb user - * account in the future. - * - * There are also IP limits in place so you should always make sure it's the end user doing the guest session actions. - * - * If a guest session is not used for the first time within 24 hours, it will be automatically discarded. - * - * @throws MovieDbException - */ - public TokenSession getGuestSessionToken() throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_AUTH, "guest_session/new"); - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - return mapper.readValue(webpage, TokenSession.class); - } catch (IOException ex) { - LOG.warn("Failed to get Session Token: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - // - // - // - // - // - // - /** - * This method is used to retrieve all of the basic movie information. - * - * It will return the single highest rated poster and backdrop. - * - * @param movieId - * @param language - * @throws MovieDbException - */ - public MovieDb getMovieInfo(int movieId, String language) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_MOVIE); - - apiUrl.addArgument(PARAM_ID, movieId); - - if (StringUtils.isNotBlank(language)) { - apiUrl.addArgument(PARAM_LANGUAGE, language); - } - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - try { - return mapper.readValue(webpage, MovieDb.class); - } catch (IOException ex) { - LOG.warn("Failed to get movie info: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - /** - * This method is used to retrieve all of the basic movie information. - * - * It will return the single highest rated poster and backdrop. - * - * @param imdbId - * @param language - * @throws MovieDbException - */ - public MovieDb getMovieInfoImdb(String imdbId, String language) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_MOVIE); - - apiUrl.addArgument(PARAM_ID, imdbId); - - if (StringUtils.isNotBlank(language)) { - apiUrl.addArgument(PARAM_LANGUAGE, language); - } - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - try { - return mapper.readValue(webpage, MovieDb.class); - } catch (IOException ex) { - LOG.warn("Failed to get movie info: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - /** - * This method is used to retrieve all of the alternative titles we have for a particular movie. - * - * @param movieId - * @param country - * @throws MovieDbException - */ - public List getMovieAlternativeTitles(int movieId, String country) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_MOVIE, "/alternative_titles"); - apiUrl.addArgument(PARAM_ID, movieId); - - if (StringUtils.isNotBlank(country)) { - apiUrl.addArgument(PARAM_COUNTRY, country); - } - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - try { - WrapperAlternativeTitles wrapper = mapper.readValue(webpage, WrapperAlternativeTitles.class); - return wrapper.getTitles(); - } catch (IOException ex) { - LOG.warn("Failed to get movie alternative titles: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - /** - * Get the cast information for a specific movie id. - * - * TODO: Add a function to enrich the data with the people methods - * - * @param movieId - * @throws MovieDbException - */ - public List getMovieCasts(int movieId) throws MovieDbException { - List people = new ArrayList(); - - ApiUrl apiUrl = new ApiUrl(this, BASE_MOVIE, "/casts"); - apiUrl.addArgument(PARAM_ID, movieId); - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - WrapperMovieCasts wrapper = mapper.readValue(webpage, WrapperMovieCasts.class); - - // Add a cast member - for (PersonCast cast : wrapper.getCast()) { - Person person = new Person(); - person.addCast(cast.getId(), cast.getName(), cast.getProfilePath(), cast.getCharacter(), cast.getOrder()); - people.add(person); - } - - // Add a crew member - for (PersonCrew crew : wrapper.getCrew()) { - Person person = new Person(); - person.addCrew(crew.getId(), crew.getName(), crew.getProfilePath(), crew.getDepartment(), crew.getJob()); - people.add(person); - } - - return people; - } catch (IOException ex) { - LOG.warn("Failed to get movie casts: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - /** - * This method should be used when you’re wanting to retrieve all of the images for a particular movie. - * - * @param movieId - * @param language - * @throws MovieDbException - */ - public List getMovieImages(int movieId, String language) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_MOVIE, "/images"); - apiUrl.addArgument(PARAM_ID, movieId); - - if (StringUtils.isNotBlank(language)) { - apiUrl.addArgument(PARAM_LANGUAGE, language); - } - - List artwork = new ArrayList(); - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - try { - WrapperImages wrapper = mapper.readValue(webpage, WrapperImages.class); - - // Add all the posters to the list - for (Artwork poster : wrapper.getPosters()) { - poster.setArtworkType(ArtworkType.POSTER); - artwork.add(poster); - } - - // Add all the backdrops to the list - for (Artwork backdrop : wrapper.getBackdrops()) { - backdrop.setArtworkType(ArtworkType.BACKDROP); - artwork.add(backdrop); - } - - return artwork; - } catch (IOException ex) { - LOG.warn("Failed to get movie images: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - /** - * This method is used to retrieve all of the keywords that have been added to a particular movie. - * - * Currently, only English keywords exist. - * - * @param movieId - * @throws MovieDbException - */ - public List getMovieKeywords(int movieId) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_MOVIE, "/keywords"); - apiUrl.addArgument(PARAM_ID, movieId); - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - WrapperMovieKeywords wrapper = mapper.readValue(webpage, WrapperMovieKeywords.class); - return wrapper.getKeywords(); - } catch (IOException ex) { - LOG.warn("Failed to get movie keywords: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - /** - * This method is used to retrieve all of the release and certification data we have for a specific movie. - * - * @param movieId - * @param language - * @throws MovieDbException - */ - public List getMovieReleaseInfo(int movieId, String language) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_MOVIE, "/releases"); - apiUrl.addArgument(PARAM_ID, movieId); - apiUrl.addArgument(PARAM_LANGUAGE, language); - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - WrapperReleaseInfo wrapper = mapper.readValue(webpage, WrapperReleaseInfo.class); - return wrapper.getCountries(); - } catch (IOException ex) { - LOG.warn("Failed to get movie release information: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - /** - * This method is used to retrieve all of the trailers for a particular movie. - * - * Supported sites are YouTube and QuickTime. - * - * @param movieId - * @param language - * @throws MovieDbException - */ - public List getMovieTrailers(int movieId, String language) throws MovieDbException { - List trailers = new ArrayList(); - - ApiUrl apiUrl = new ApiUrl(this, BASE_MOVIE, "/trailers"); - apiUrl.addArgument(PARAM_ID, movieId); - - if (StringUtils.isNotBlank(language)) { - apiUrl.addArgument(PARAM_LANGUAGE, language); - } - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - WrapperTrailers wrapper = mapper.readValue(webpage, WrapperTrailers.class); - - // Add the trailer to the return list along with it's source - for (Trailer trailer : wrapper.getQuicktime()) { - trailer.setWebsite(Trailer.WEBSITE_QUICKTIME); - trailers.add(trailer); - } - // Add the trailer to the return list along with it's source - for (Trailer trailer : wrapper.getYoutube()) { - trailer.setWebsite(Trailer.WEBSITE_YOUTUBE); - trailers.add(trailer); - } - return trailers; - } catch (IOException ex) { - LOG.warn("Failed to get movie trailers: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - /** - * This method is used to retrieve a list of the available translations for a specific movie. - * - * @param movieId - * @throws MovieDbException - */ - public List getMovieTranslations(int movieId) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_MOVIE, "/translations"); - apiUrl.addArgument(PARAM_ID, movieId); - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - WrapperTranslations wrapper = mapper.readValue(webpage, WrapperTranslations.class); - return wrapper.getTranslations(); - } catch (IOException ex) { - LOG.warn("Failed to get movie tranlations: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - /** - * The similar movies method will let you retrieve the similar movies for a particular movie. - * - * This data is created dynamically but with the help of users votes on TMDb. - * - * The data is much better with movies that have more keywords - * - * @param movieId - * @param language - * @param page - * @throws MovieDbException - */ - public List getSimilarMovies(int movieId, String language, int page) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_MOVIE, "/similar_movies"); - apiUrl.addArgument(PARAM_ID, movieId); - - if (StringUtils.isNotBlank(language)) { - apiUrl.addArgument(PARAM_LANGUAGE, language); - } - - if (page > 0) { - apiUrl.addArgument(PARAM_PAGE, page); - } - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); - return wrapper.getMovies(); - } catch (IOException ex) { - LOG.warn("Failed to get similar movies: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - /** - * Get the lists that the movie belongs to - * - * @param movieId - * @param language - * @param page - * @throws MovieDbException - */ - public List getMovieLists(int movieId, String language, int page) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_MOVIE, "/lists"); - apiUrl.addArgument(PARAM_ID, movieId); - - if (StringUtils.isNotBlank(language)) { - apiUrl.addArgument(PARAM_LANGUAGE, language); - } - - if (page > 0) { - apiUrl.addArgument(PARAM_PAGE, page); - } - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - WrapperMovieList wrapper = mapper.readValue(webpage, WrapperMovieList.class); - return wrapper.getMovieList(); - } catch (IOException ex) { - LOG.warn("Failed to get movie lists: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - /** - * Get the changes for a specific movie id. - * - * Changes are grouped by key, and ordered by date in descending order. - * - * By default, only the last 24 hours of changes are returned. - * - * The maximum number of days that can be returned in a single request is 14. - * - * The language is present on fields that are translatable. - * - * TODO: DOES NOT WORK AT THE MOMENT. This is due to the "value" item changing type in the ChangeItem - * - * @param movieId - * @param startDate the start date of the changes, optional - * @param endDate the end date of the changes, optional - * @throws MovieDbException - */ - @Deprecated - public List getMovieChanges(int movieId, String startDate, String endDate) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_MOVIE, "/changes"); - apiUrl.addArgument(PARAM_ID, movieId); - - if (StringUtils.isNotBlank(startDate)) { - apiUrl.addArgument("start_date", startDate); - } - - if (StringUtils.isNotBlank(endDate)) { - apiUrl.addArgument("end_date", endDate); - } - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - WrapperChanges wrapper = mapper.readValue(webpage, WrapperChanges.class); - return wrapper.getChanges(); - } catch (IOException ex) { - LOG.warn("Failed to get movie changes: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - - } - - /** - * This method is used to retrieve the newest movie that was added to TMDb. - * - */ - public MovieDb getLatestMovie() throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_MOVIE, "/latest"); - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - return mapper.readValue(webpage, MovieDb.class); - } catch (IOException ex) { - LOG.warn("Failed to get latest movie: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - /** - * Get the list of upcoming movies. - * - * This list refreshes every day. - * - * The maximum number of items this list will include is 100. - * - * @throws MovieDbException - */ - public List getUpcoming(String language, int page) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_MOVIE, "upcoming"); - - if (StringUtils.isNotBlank(language)) { - apiUrl.addArgument(PARAM_LANGUAGE, language); - } - - if (page > 0) { - apiUrl.addArgument(PARAM_PAGE, page); - } - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); - return wrapper.getMovies(); - } catch (IOException ex) { - LOG.warn("Failed to get upcoming movies: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - - } - - /** - * This method is used to retrieve the movies currently in theatres. - * - * This is a curated list that will normally contain 100 movies. The default response will return 20 movies. - * - * TODO: Implement more than 20 movies - * - * @param language - * @param page - * @throws MovieDbException - */ - public List getNowPlayingMovies(String language, int page) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_MOVIE, "now-playing"); - - if (StringUtils.isNotBlank(language)) { - apiUrl.addArgument(PARAM_LANGUAGE, language); - } - - if (page > 0) { - apiUrl.addArgument(PARAM_PAGE, page); - } - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); - return wrapper.getMovies(); - } catch (IOException ex) { - LOG.warn("Failed to get now playing movies: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - /** - * This method is used to retrieve the daily movie popularity list. - * - * This list is updated daily. The default response will return 20 movies. - * - * TODO: Implement more than 20 movies - * - * @param language - * @param page - * @throws MovieDbException - */ - public List getPopularMovieList(String language, int page) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_MOVIE, "popular"); - - if (StringUtils.isNotBlank(language)) { - apiUrl.addArgument(PARAM_LANGUAGE, language); - } - - if (page > 0) { - apiUrl.addArgument(PARAM_PAGE, page); - } - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); - return wrapper.getMovies(); - } catch (IOException ex) { - LOG.warn("Failed to get popular movie list: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - /** - * This method is used to retrieve the top rated movies that have over 10 votes on TMDb. - * - * The default response will return 20 movies. - * - * TODO: Implement more than 20 movies - * - * @param language - * @param page - * @throws MovieDbException - */ - public List getTopRatedMovies(String language, int page) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_MOVIE, "top-rated"); - - if (StringUtils.isNotBlank(language)) { - apiUrl.addArgument(PARAM_LANGUAGE, language); - } - - if (page > 0) { - apiUrl.addArgument(PARAM_PAGE, page); - } - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); - return wrapper.getMovies(); - } catch (IOException ex) { - LOG.warn("Failed to get top rated movies: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - /** - * This method lets users rate a movie. - * - * A valid session id is required. - * - * @param sessionId - * @param rating - * @throws MovieDbException - */ - public boolean postMovieRating(String sessionId, String rating) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_MOVIE, "/rating"); - - apiUrl.addArgument(PARAM_SESSION, sessionId); - apiUrl.addArgument(PARAM_VALUE, rating); - - throw new MovieDbException(MovieDbExceptionType.UNKNOWN_CAUSE, "Not implemented yet"); - } - - // - // - // - /** - * This method is used to retrieve all of the basic information about a movie collection. - * - * You can get the ID needed for this method by making a getMovieInfo request for the belongs_to_collection. - * - * @param collectionId - * @param language - * @throws MovieDbException - */ - public CollectionInfo getCollectionInfo(int collectionId, String language) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_COLLECTION); - apiUrl.addArgument(PARAM_ID, collectionId); - - if (StringUtils.isNotBlank(language)) { - apiUrl.addArgument(PARAM_LANGUAGE, language); - } - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - return mapper.readValue(webpage, CollectionInfo.class); - } catch (IOException ex) { - LOG.warn("Failed to get collection information: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - /** - * Get all of the images for a particular collection by collection id. - * - * @param collectionId - * @param language - * @throws MovieDbException - */ - public List getCollectionImages(int collectionId, String language) throws MovieDbException { - List artwork = new ArrayList(); - ApiUrl apiUrl = new ApiUrl(this, BASE_COLLECTION, "/images"); - apiUrl.addArgument(PARAM_ID, collectionId); - - if (StringUtils.isNotBlank(language)) { - apiUrl.addArgument(PARAM_LANGUAGE, language); - } - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - WrapperImages wrapper = mapper.readValue(webpage, WrapperImages.class); - - // Add all the posters to the list - for (Artwork poster : wrapper.getPosters()) { - poster.setArtworkType(ArtworkType.POSTER); - artwork.add(poster); - } - - // Add all the backdrops to the list - for (Artwork backdrop : wrapper.getBackdrops()) { - backdrop.setArtworkType(ArtworkType.BACKDROP); - artwork.add(backdrop); - } - - return artwork; - } catch (IOException ex) { - LOG.warn("Failed to get collection images: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - - } - - // - // - // - /** - * This method is used to retrieve all of the basic person information. - * - * It will return the single highest rated profile image. - * - * @param personId - * @throws MovieDbException - */ - public Person getPersonInfo(int personId) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_PERSON); - - apiUrl.addArgument(PARAM_ID, personId); - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - return mapper.readValue(webpage, Person.class); - } catch (IOException ex) { - LOG.warn("Failed to get movie info: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - /** - * This method is used to retrieve all of the cast & crew information for the person. - * - * It will return the single highest rated poster for each movie record. - * - * @param personId - * @throws MovieDbException - */ - public List getPersonCredits(int personId) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_PERSON, "/credits"); - - List personCredits = new ArrayList(); - - apiUrl.addArgument(PARAM_ID, personId); - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - WrapperPersonCredits wrapper = mapper.readValue(webpage, WrapperPersonCredits.class); - - // Add a cast member - for (PersonCredit cast : wrapper.getCast()) { - cast.setPersonType(PersonType.CAST); - personCredits.add(cast); - } - // Add a crew member - for (PersonCredit crew : wrapper.getCrew()) { - crew.setPersonType(PersonType.CREW); - personCredits.add(crew); - } - return personCredits; - } catch (IOException ex) { - LOG.warn("Failed to get person credits: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - /** - * This method is used to retrieve all of the profile images for a person. - * - * @param personId - * @throws MovieDbException - */ - public List getPersonImages(int personId) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_PERSON, "/images"); - - List personImages = new ArrayList(); - - apiUrl.addArgument(PARAM_ID, personId); - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - WrapperImages wrapper = mapper.readValue(webpage, WrapperImages.class); - - // Update the image type - for (Artwork artwork : wrapper.getProfiles()) { - artwork.setArtworkType(ArtworkType.PROFILE); - personImages.add(artwork); - } - return personImages; - } catch (IOException ex) { - LOG.warn("Failed to get person images: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - /** - * Get the changes for a specific person id. - * - * Changes are grouped by key, and ordered by date in descending order. - * - * By default, only the last 24 hours of changes are returned. - * - * The maximum number of days that can be returned in a single request is 14. - * - * The language is present on fields that are translatable. - * - * @param personId - * @param startDate - * @param endDate - * @throws MovieDbException - */ - public void getPersonChanges(int personId, String startDate, String endDate) throws MovieDbException { - throw new MovieDbException(MovieDbExceptionType.UNKNOWN_CAUSE, "Not implemented yet"); - } - - /** - * Get the latest person id. - * - * @throws MovieDbException - */ - public Person getPersonLatest() throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_PERSON, "/latest"); - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - return mapper.readValue(webpage, Person.class); - } catch (IOException ex) { - LOG.warn("Failed to get latest person: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - // - // - // - /** - * This method is used to retrieve the basic information about a production company on TMDb. - * - * @param companyId - * @throws MovieDbException - */ - public Company getCompanyInfo(int companyId) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_COMPANY); - - apiUrl.addArgument(PARAM_ID, companyId); - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - return mapper.readValue(webpage, Company.class); - } catch (IOException ex) { - LOG.warn("Failed to get company information: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - /** - * This method is used to retrieve the movies associated with a company. - * - * These movies are returned in order of most recently released to oldest. The default response will return 20 movies per page. - * - * TODO: Implement more than 20 movies - * - * @param companyId - * @param language - * @param page - * @throws MovieDbException - */ - public List getCompanyMovies(int companyId, String language, int page) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_COMPANY, "/movies"); - - apiUrl.addArgument(PARAM_ID, companyId); - - if (StringUtils.isNotBlank(language)) { - apiUrl.addArgument(PARAM_LANGUAGE, language); - } - - if (page > 0) { - apiUrl.addArgument(PARAM_PAGE, page); - } - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - WrapperCompanyMovies wrapper = mapper.readValue(webpage, WrapperCompanyMovies.class); - return wrapper.getResults(); - } catch (IOException ex) { - LOG.warn("Failed to get company movies: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - // - // - // - /** - * You can use this method to retrieve the list of genres used on TMDb. - * - * These IDs will correspond to those found in movie calls. - * - * @param language - */ - public List getGenreList(String language) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_GENRE, "/list"); - apiUrl.addArgument(PARAM_LANGUAGE, language); - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - WrapperGenres wrapper = mapper.readValue(webpage, WrapperGenres.class); - return wrapper.getGenres(); - } catch (IOException ex) { - LOG.warn("Failed to get genre list: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - @Deprecated - public List getGenreMovies(int genreId, String language, int page) throws MovieDbException { - return getGenreMovies(genreId, language, page, Boolean.TRUE); - } - - /** - * Get a list of movies per genre. - * - * It is important to understand that only movies with more than 10 votes get listed. - * - * This prevents movies from 1 10/10 rating from being listed first and for the first 5 pages. - * - * @param genreId - * @param language - * @param page - */ - public List getGenreMovies(int genreId, String language, int page, boolean includeAllMovies) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_GENRE, "/movies"); - apiUrl.addArgument(PARAM_ID, genreId); - - if (StringUtils.isNotBlank(language)) { - apiUrl.addArgument(PARAM_LANGUAGE, language); - } - - if (page > 0) { - apiUrl.addArgument(PARAM_PAGE, page); - } - - apiUrl.addArgument(PARAM_INCLUDE_ALL_MOVIES, includeAllMovies); - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); - return wrapper.getMovies(); - } catch (IOException ex) { - LOG.warn("Failed to get genre movie list: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - // - // - // - - /** - * Search Movies This is a good starting point to start finding movies on TMDb. - * - * @param movieName - * @param searchYear Limit the search to the provided year. Zero (0) will get all years - * @param language The language to include. Can be blank/null. - * @param includeAdult true or false to include adult titles in the search - * @param page The page of results to return. 0 to get the default (first page) - * @throws MovieDbException - */ - public List searchMovie(String movieName, int searchYear, String language, boolean includeAdult, int page) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_SEARCH, "movie"); - if (StringUtils.isNotBlank(movieName)) { - apiUrl.addArgument(PARAM_QUERY, movieName); - } - - if (searchYear > 0) { - apiUrl.addArgument(PARAM_YEAR, Integer.toString(searchYear)); - } - - if (StringUtils.isNotBlank(language)) { - apiUrl.addArgument(PARAM_LANGUAGE, language); - } - - apiUrl.addArgument(PARAM_ADULT, Boolean.toString(includeAdult)); - - if (page > 0) { - apiUrl.addArgument(PARAM_PAGE, Integer.toString(page)); - } - - URL url = apiUrl.buildUrl(); - - String webpage = WebBrowser.request(url); - try { - WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); - return wrapper.getMovies(); - } catch (IOException ex) { - LOG.warn("Failed to find movie: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - - } - - /** - * Search for collections by name. - * - * @param query - * @param language - * @param page - * @throws MovieDbException - */ - public List searchCollection(String query, String language, int page) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_SEARCH, "collections"); - - if (StringUtils.isNotBlank(query)) { - apiUrl.addArgument(PARAM_QUERY, query); - } - - if (StringUtils.isNotBlank(language)) { - apiUrl.addArgument(PARAM_LANGUAGE, language); - } - - if (page > 0) { - apiUrl.addArgument(PARAM_PAGE, Integer.toString(page)); - } - - URL url = apiUrl.buildUrl(); - - String webpage = WebBrowser.request(url); - try { - WrapperCollection wrapper = mapper.readValue(webpage, WrapperCollection.class); - return wrapper.getResults(); - } catch (IOException ex) { - LOG.warn("Failed to find collection: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - /** - * This is a good starting point to start finding people on TMDb. - * - * The idea is to be a quick and light method so you can iterate through people quickly. - * - * @param personName - * @param includeAdult - * @param page - * @throws MovieDbException - */ - public List searchPeople(String personName, boolean includeAdult, int page) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_SEARCH, "person"); - apiUrl.addArgument(PARAM_QUERY, personName); - apiUrl.addArgument(PARAM_ADULT, includeAdult); - - if (page > 0) { - apiUrl.addArgument(PARAM_PAGE, page); - } - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - WrapperPerson wrapper = mapper.readValue(webpage, WrapperPerson.class); - return wrapper.getResults(); - } catch (IOException ex) { - LOG.warn("Failed to find person: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - /** - * Search for lists by name and description. - * - * @param query - * @param language - * @param page - * @throws MovieDbException - */ - public List searchList(String query, String language, int page) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_SEARCH, "list"); - - if (StringUtils.isNotBlank(query)) { - apiUrl.addArgument(PARAM_QUERY, query); - } - - if (StringUtils.isNotBlank(language)) { - apiUrl.addArgument(PARAM_LANGUAGE, language); - } - - if (page > 0) { - apiUrl.addArgument(PARAM_PAGE, Integer.toString(page)); - } - - URL url = apiUrl.buildUrl(); - - String webpage = WebBrowser.request(url); - try { - WrapperMovieList wrapper = mapper.readValue(webpage, WrapperMovieList.class); - return wrapper.getMovieList(); - } catch (IOException ex) { - LOG.warn("Failed to find list: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - /** - * Search Companies. - * - * You can use this method to search for production companies that are part of TMDb. The company IDs will map to those returned - * on movie calls. - * - * http://help.themoviedb.org/kb/api/search-companies - * - * @param companyName - * @param page - * @throws MovieDbException - */ - public List searchCompanies(String companyName, int page) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_SEARCH, "company"); - apiUrl.addArgument(PARAM_QUERY, companyName); - - if (page > 0) { - apiUrl.addArgument(PARAM_PAGE, page); - } - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - try { - WrapperCompany wrapper = mapper.readValue(webpage, WrapperCompany.class); - return wrapper.getResults(); - } catch (IOException ex) { - LOG.warn("Failed to find company: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - /** - * Search for keywords by name - * - * @param query - * @param page - * @throws MovieDbException - */ - public List searchKeyword(String query, int page) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_SEARCH, "keyword"); - - if (StringUtils.isNotBlank(query)) { - apiUrl.addArgument(PARAM_QUERY, query); - } - - if (page > 0) { - apiUrl.addArgument(PARAM_PAGE, Integer.toString(page)); - } - - URL url = apiUrl.buildUrl(); - - String webpage = WebBrowser.request(url); - try { - WrapperKeywords wrapper = mapper.readValue(webpage, WrapperKeywords.class); - return wrapper.getResults(); - } catch (IOException ex) { - LOG.warn("Failed to find keyword: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - // - // - // - - /** - * Get a list by its ID - * - * @param listId - * @return The list and its items - * @throws MovieDbException - */ - public MovieDbList getList(String listId) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_LIST); - apiUrl.addArgument(PARAM_ID, listId); - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - return mapper.readValue(webpage, MovieDbList.class); - } catch (IOException ex) { - LOG.warn("Failed to get list: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - // - // - // - - /** - * Get the basic information for a specific keyword id. - * - * @param keywordId - * @return - * @throws MovieDbException - */ - public Keyword getKeyword(String keywordId) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_KEYWORD); - apiUrl.addArgument(PARAM_ID, keywordId); - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - return mapper.readValue(webpage, Keyword.class); - } catch (IOException ex) { - LOG.warn("Failed to get keyword: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - - } - - /** - * Get the list of movies for a particular keyword by id. - * - * @param keywordId - * @param language - * @param page - * @return List of movies with the keyword - * @throws MovieDbException - */ - public List getKeywordMovies(String keywordId, String language, int page) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(this, BASE_KEYWORD, "/movies"); - apiUrl.addArgument(PARAM_ID, keywordId); - - if (StringUtils.isNotBlank(language)) { - apiUrl.addArgument(PARAM_LANGUAGE, language); - } - - if (page > 0) { - apiUrl.addArgument(PARAM_PAGE, page); - } - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url); - - try { - WrapperKeywordMovies wrapper = mapper.readValue(webpage, WrapperKeywordMovies.class); - return wrapper.getResults(); - } catch (IOException ex) { - LOG.warn("Failed to get top rated movies: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - - } - // - // - // - - public void getMovieChangesList(int page, String startDate, String endDate) throws MovieDbException { - throw new MovieDbException(MovieDbExceptionType.UNKNOWN_CAUSE, "Not implemented yet"); - } - - public void getPersonChangesList(int page, String startDate, String endDate) throws MovieDbException { - throw new MovieDbException(MovieDbExceptionType.UNKNOWN_CAUSE, "Not implemented yet"); - } - // -} +/* + * Copyright (c) 2004-2013 Stuart Boston + * + * This file is part of TheMovieDB API. + * + * TheMovieDB API is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * TheMovieDB API is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with TheMovieDB API. If not, see . + * + */ +package com.omertron.themoviedbapi; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.omertron.themoviedbapi.MovieDbException.MovieDbExceptionType; +import com.omertron.themoviedbapi.model.*; +import com.omertron.themoviedbapi.tools.ApiUrl; +import static com.omertron.themoviedbapi.tools.ApiUrl.*; +import com.omertron.themoviedbapi.tools.WebBrowser; +import com.omertron.themoviedbapi.wrapper.*; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The MovieDb API

This is for version 3 of the API as specified here: http://help.themoviedb.org/kb/api/about-3 + * + * @author stuart.boston + */ +public class TheMovieDbApi { + + private static final Logger LOG = LoggerFactory.getLogger(TheMovieDbApi.class); + private String apiKey; + private TmdbConfiguration tmdbConfig; + /* + * API Methods + * + * These are not set to static so that multiple instances of + * the API can co-exist + */ + private static final String BASE_MOVIE = "movie/"; + private static final String BASE_PERSON = "person/"; + private static final String BASE_COMPANY = "company/"; + private static final String BASE_GENRE = "genre/"; + private static final String BASE_AUTH = "authentication/"; + private static final String BASE_COLLECTION = "collection/"; +// private static final String BASE_ACCOUNT = "account/"; + private static final String BASE_SEARCH = "search/"; + private static final String BASE_LIST = "list/"; + private static final String BASE_KEYWORD = "keyword/"; + // Account + /* + private final ApiUrl tmdbAccount = new ApiUrl(apiKey, BASE_ACCOUNT); + private final ApiUrl tmdbFavouriteMovies = new ApiUrl(apiKey, BASE_ACCOUNT, "/favorite_movies"); + private final ApiUrl tmdbPostFavourite = new ApiUrl(apiKey, BASE_ACCOUNT, "/favorite"); + private final ApiUrl tmdbRatedMovies = new ApiUrl(apiKey, BASE_ACCOUNT, "/rated_movies"); + private final ApiUrl tmdbMovieWatchList = new ApiUrl(apiKey, BASE_ACCOUNT, "/movie_watchlist"); + private final ApiUrl tmdbPostMovieWatchList = new ApiUrl(apiKey, BASE_ACCOUNT, "/movie_watchlist"); + */ + /* + * Jackson JSON configuration + */ + private static ObjectMapper mapper = new ObjectMapper(); + + /** + * API for The Movie Db. + * + * @param apiKey + * @throws MovieDbException + */ + public TheMovieDbApi(String apiKey) throws MovieDbException { + this.apiKey = apiKey; + ApiUrl apiUrl = new ApiUrl(apiKey, "configuration"); + URL configUrl = apiUrl.buildUrl(); + String webpage = WebBrowser.request(configUrl); + + try { + WrapperConfig wc = mapper.readValue(webpage, WrapperConfig.class); + tmdbConfig = wc.getTmdbConfiguration(); + } catch (IOException ex) { + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, "Failed to read configuration", ex); + } + } + + /** + * Get the API key that is to be used + * + */ + public String getApiKey() { + return apiKey; + } + + /** + * Set the proxy information + * + * @param host + * @param port + * @param username + * @param password + */ + public void setProxy(String host, String port, String username, String password) { + WebBrowser.setProxyHost(host); + WebBrowser.setProxyPort(port); + WebBrowser.setProxyUsername(username); + WebBrowser.setProxyPassword(password); + } + + /** + * Set the connection and read time out values + * + * @param connect + * @param read + */ + public void setTimeout(int connect, int read) { + WebBrowser.setWebTimeoutConnect(connect); + WebBrowser.setWebTimeoutRead(read); + } + + /** + * Compare the MovieDB object with a title & year + * + * @param moviedb The moviedb object to compare too + * @param title The title of the movie to compare + * @param year The year of the movie to compare exact match + * @return True if there is a match, False otherwise. + */ + public static boolean compareMovies(MovieDb moviedb, String title, String year) { + return compareMovies(moviedb, title, year, 0); + } + + /** + * Compare the MovieDB object with a title & year + * + * @param moviedb The moviedb object to compare too + * @param title The title of the movie to compare + * @param year The year of the movie to compare + * @param maxDistance The Levenshtein Distance between the two titles. 0 = exact match + * @return True if there is a match, False otherwise. + */ + public static boolean compareMovies(MovieDb moviedb, String title, String year, int maxDistance) { + if ((moviedb == null) || (StringUtils.isBlank(title))) { + return Boolean.FALSE; + } + + if (isValidYear(year) && isValidYear(moviedb.getReleaseDate())) { + // Compare with year + String movieYear = moviedb.getReleaseDate().substring(0, 4); + if (movieYear.equals(year)) { + if (compareDistance(moviedb.getOriginalTitle(), title, maxDistance)) { + return Boolean.TRUE; + } + + if (compareDistance(moviedb.getTitle(), title, maxDistance)) { + return Boolean.TRUE; + } + } + } + + // Compare without year + if (compareDistance(moviedb.getOriginalTitle(), title, maxDistance)) { + return Boolean.TRUE; + } + + if (compareDistance(moviedb.getTitle(), title, maxDistance)) { + return Boolean.TRUE; + } + + return Boolean.FALSE; + } + + /** + * Compare the Levenshtein Distance between the two strings + * + * @param title1 + * @param title2 + * @param distance + */ + private static boolean compareDistance(String title1, String title2, int distance) { + return (StringUtils.getLevenshteinDistance(title1, title2) <= distance); + } + + /** + * Check the year is not blank or UNKNOWN + * + * @param year + */ + private static boolean isValidYear(String year) { + return (StringUtils.isNotBlank(year) && !year.equals("UNKNOWN")); + } + + // + /** + * Get the configuration information + */ + public TmdbConfiguration getConfiguration() { + return tmdbConfig; + } + + /** + * Generate the full image URL from the size and image path + * + * @param imagePath + * @param requiredSize + * @throws MovieDbException + */ + public URL createImageUrl(String imagePath, String requiredSize) throws MovieDbException { + if (!tmdbConfig.isValidSize(requiredSize)) { + throw new MovieDbException(MovieDbExceptionType.INVALID_IMAGE, requiredSize); + } + + StringBuilder sb = new StringBuilder(tmdbConfig.getBaseUrl()); + sb.append(requiredSize); + sb.append(imagePath); + try { + return (new URL(sb.toString())); + } catch (MalformedURLException ex) { + LOG.warn("Failed to create image URL: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.INVALID_URL, sb.toString(), ex); + } + } + + // + // + // + /** + * This method is used to generate a valid request token for user based authentication. + * + * A request token is required in order to request a session id. + * + * You can generate any number of request tokens but they will expire after 60 minutes. + * + * As soon as a valid session id has been created the token will be destroyed. + * + * @throws MovieDbException + */ + public TokenAuthorisation getAuthorisationToken() throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_AUTH, "token/new"); + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + return mapper.readValue(webpage, TokenAuthorisation.class); + } catch (IOException ex) { + LOG.warn("Failed to get Authorisation Token: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.AUTHORISATION_FAILURE, webpage, ex); + } + } + + /** + * This method is used to generate a session id for user based authentication. + * + * A session id is required in order to use any of the write methods. + * + * @param token + * @throws MovieDbException + */ + public TokenSession getSessionToken(TokenAuthorisation token) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_AUTH, "session/new"); + + if (!token.getSuccess()) { + LOG.warn("Authorisation token was not successful!"); + throw new MovieDbException(MovieDbExceptionType.AUTHORISATION_FAILURE, "Authorisation token was not successful!"); + } + + apiUrl.addArgument(PARAM_TOKEN, token.getRequestToken()); + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + return mapper.readValue(webpage, TokenSession.class); + } catch (IOException ex) { + LOG.warn("Failed to get Session Token: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * This method is used to generate a guest session id. + * + * A guest session can be used to rate movies without having a registered TMDb user account. + * + * You should only generate a single guest session per user (or device) as you will be able to attach the ratings to a TMDb user + * account in the future. + * + * There are also IP limits in place so you should always make sure it's the end user doing the guest session actions. + * + * If a guest session is not used for the first time within 24 hours, it will be automatically discarded. + * + * @throws MovieDbException + */ + public TokenSession getGuestSessionToken() throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_AUTH, "guest_session/new"); + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + return mapper.readValue(webpage, TokenSession.class); + } catch (IOException ex) { + LOG.warn("Failed to get Session Token: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + // + // + // + // + // + // + /** + * This method is used to retrieve all of the basic movie information. + * + * It will return the single highest rated poster and backdrop. + * + * @param movieId + * @param language + * @throws MovieDbException + */ + public MovieDb getMovieInfo(int movieId, String language, String... appendToResponse) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE); + + apiUrl.addArgument(PARAM_ID, movieId); + + if (StringUtils.isNotBlank(language)) { + apiUrl.addArgument(PARAM_LANGUAGE, language); + } + + apiUrl.appendToResponse(appendToResponse); + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + try { + return mapper.readValue(webpage, MovieDb.class); + } catch (IOException ex) { + LOG.warn("Failed to get movie info: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * This method is used to retrieve all of the basic movie information. + * + * It will return the single highest rated poster and backdrop. + * + * @param imdbId + * @param language + * @throws MovieDbException + */ + public MovieDb getMovieInfoImdb(String imdbId, String language) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE); + + apiUrl.addArgument(PARAM_ID, imdbId); + + if (StringUtils.isNotBlank(language)) { + apiUrl.addArgument(PARAM_LANGUAGE, language); + } + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + try { + return mapper.readValue(webpage, MovieDb.class); + } catch (IOException ex) { + LOG.warn("Failed to get movie info: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * This method is used to retrieve all of the alternative titles we have for a particular movie. + * + * @param movieId + * @param country + * @throws MovieDbException + */ + public List getMovieAlternativeTitles(int movieId, String country) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "/alternative_titles"); + apiUrl.addArgument(PARAM_ID, movieId); + + if (StringUtils.isNotBlank(country)) { + apiUrl.addArgument(PARAM_COUNTRY, country); + } + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + try { + WrapperAlternativeTitles wrapper = mapper.readValue(webpage, WrapperAlternativeTitles.class); + return wrapper.getTitles(); + } catch (IOException ex) { + LOG.warn("Failed to get movie alternative titles: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * Get the cast information for a specific movie id. + * + * TODO: Add a function to enrich the data with the people methods + * + * @param movieId + * @throws MovieDbException + */ + public List getMovieCasts(int movieId) throws MovieDbException { + List people = new ArrayList(); + + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "/casts"); + apiUrl.addArgument(PARAM_ID, movieId); + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + WrapperMovieCasts wrapper = mapper.readValue(webpage, WrapperMovieCasts.class); + + // Add a cast member + for (PersonCast cast : wrapper.getCast()) { + Person person = new Person(); + person.addCast(cast.getId(), cast.getName(), cast.getProfilePath(), cast.getCharacter(), cast.getOrder()); + people.add(person); + } + + // Add a crew member + for (PersonCrew crew : wrapper.getCrew()) { + Person person = new Person(); + person.addCrew(crew.getId(), crew.getName(), crew.getProfilePath(), crew.getDepartment(), crew.getJob()); + people.add(person); + } + + return people; + } catch (IOException ex) { + LOG.warn("Failed to get movie casts: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * This method should be used when you’re wanting to retrieve all of the images for a particular movie. + * + * @param movieId + * @param language + * @throws MovieDbException + */ + public List getMovieImages(int movieId, String language) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "/images"); + apiUrl.addArgument(PARAM_ID, movieId); + + if (StringUtils.isNotBlank(language)) { + apiUrl.addArgument(PARAM_LANGUAGE, language); + } + + List artwork = new ArrayList(); + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + try { + WrapperImages wrapper = mapper.readValue(webpage, WrapperImages.class); + + // Add all the posters to the list + for (Artwork poster : wrapper.getPosters()) { + poster.setArtworkType(ArtworkType.POSTER); + artwork.add(poster); + } + + // Add all the backdrops to the list + for (Artwork backdrop : wrapper.getBackdrops()) { + backdrop.setArtworkType(ArtworkType.BACKDROP); + artwork.add(backdrop); + } + + return artwork; + } catch (IOException ex) { + LOG.warn("Failed to get movie images: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * This method is used to retrieve all of the keywords that have been added to a particular movie. + * + * Currently, only English keywords exist. + * + * @param movieId + * @throws MovieDbException + */ + public List getMovieKeywords(int movieId) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "/keywords"); + apiUrl.addArgument(PARAM_ID, movieId); + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + WrapperMovieKeywords wrapper = mapper.readValue(webpage, WrapperMovieKeywords.class); + return wrapper.getKeywords(); + } catch (IOException ex) { + LOG.warn("Failed to get movie keywords: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * This method is used to retrieve all of the release and certification data we have for a specific movie. + * + * @param movieId + * @param language + * @throws MovieDbException + */ + public List getMovieReleaseInfo(int movieId, String language) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "/releases"); + apiUrl.addArgument(PARAM_ID, movieId); + apiUrl.addArgument(PARAM_LANGUAGE, language); + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + WrapperReleaseInfo wrapper = mapper.readValue(webpage, WrapperReleaseInfo.class); + return wrapper.getCountries(); + } catch (IOException ex) { + LOG.warn("Failed to get movie release information: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * This method is used to retrieve all of the trailers for a particular movie. + * + * Supported sites are YouTube and QuickTime. + * + * @param movieId + * @param language + * @throws MovieDbException + */ + public List getMovieTrailers(int movieId, String language) throws MovieDbException { + List trailers = new ArrayList(); + + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "/trailers"); + apiUrl.addArgument(PARAM_ID, movieId); + + if (StringUtils.isNotBlank(language)) { + apiUrl.addArgument(PARAM_LANGUAGE, language); + } + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + WrapperTrailers wrapper = mapper.readValue(webpage, WrapperTrailers.class); + + // Add the trailer to the return list along with it's source + for (Trailer trailer : wrapper.getQuicktime()) { + trailer.setWebsite(Trailer.WEBSITE_QUICKTIME); + trailers.add(trailer); + } + // Add the trailer to the return list along with it's source + for (Trailer trailer : wrapper.getYoutube()) { + trailer.setWebsite(Trailer.WEBSITE_YOUTUBE); + trailers.add(trailer); + } + return trailers; + } catch (IOException ex) { + LOG.warn("Failed to get movie trailers: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * This method is used to retrieve a list of the available translations for a specific movie. + * + * @param movieId + * @throws MovieDbException + */ + public List getMovieTranslations(int movieId) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "/translations"); + apiUrl.addArgument(PARAM_ID, movieId); + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + WrapperTranslations wrapper = mapper.readValue(webpage, WrapperTranslations.class); + return wrapper.getTranslations(); + } catch (IOException ex) { + LOG.warn("Failed to get movie tranlations: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * The similar movies method will let you retrieve the similar movies for a particular movie. + * + * This data is created dynamically but with the help of users votes on TMDb. + * + * The data is much better with movies that have more keywords + * + * @param movieId + * @param language + * @param page + * @throws MovieDbException + */ + public List getSimilarMovies(int movieId, String language, int page) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "/similar_movies"); + apiUrl.addArgument(PARAM_ID, movieId); + + if (StringUtils.isNotBlank(language)) { + apiUrl.addArgument(PARAM_LANGUAGE, language); + } + + if (page > 0) { + apiUrl.addArgument(PARAM_PAGE, page); + } + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); + return wrapper.getMovies(); + } catch (IOException ex) { + LOG.warn("Failed to get similar movies: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * Get the lists that the movie belongs to + * + * @param movieId + * @param language + * @param page + * @throws MovieDbException + */ + public List getMovieLists(int movieId, String language, int page) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "/lists"); + apiUrl.addArgument(PARAM_ID, movieId); + + if (StringUtils.isNotBlank(language)) { + apiUrl.addArgument(PARAM_LANGUAGE, language); + } + + if (page > 0) { + apiUrl.addArgument(PARAM_PAGE, page); + } + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + WrapperMovieList wrapper = mapper.readValue(webpage, WrapperMovieList.class); + return wrapper.getMovieList(); + } catch (IOException ex) { + LOG.warn("Failed to get movie lists: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * Get the changes for a specific movie id. + * + * Changes are grouped by key, and ordered by date in descending order. + * + * By default, only the last 24 hours of changes are returned. + * + * The maximum number of days that can be returned in a single request is 14. + * + * The language is present on fields that are translatable. + * + * TODO: DOES NOT WORK AT THE MOMENT. This is due to the "value" item changing type in the ChangeItem + * + * @param movieId + * @param startDate the start date of the changes, optional + * @param endDate the end date of the changes, optional + * @throws MovieDbException + */ + @Deprecated + public List getMovieChanges(int movieId, String startDate, String endDate) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "/changes"); + apiUrl.addArgument(PARAM_ID, movieId); + + if (StringUtils.isNotBlank(startDate)) { + apiUrl.addArgument("start_date", startDate); + } + + if (StringUtils.isNotBlank(endDate)) { + apiUrl.addArgument("end_date", endDate); + } + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + WrapperChanges wrapper = mapper.readValue(webpage, WrapperChanges.class); + return wrapper.getChanges(); + } catch (IOException ex) { + LOG.warn("Failed to get movie changes: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + + } + + /** + * This method is used to retrieve the newest movie that was added to TMDb. + * + */ + public MovieDb getLatestMovie() throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "/latest"); + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + return mapper.readValue(webpage, MovieDb.class); + } catch (IOException ex) { + LOG.warn("Failed to get latest movie: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * Get the list of upcoming movies. + * + * This list refreshes every day. + * + * The maximum number of items this list will include is 100. + * + * @throws MovieDbException + */ + public List getUpcoming(String language, int page) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "upcoming"); + + if (StringUtils.isNotBlank(language)) { + apiUrl.addArgument(PARAM_LANGUAGE, language); + } + + if (page > 0) { + apiUrl.addArgument(PARAM_PAGE, page); + } + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); + return wrapper.getMovies(); + } catch (IOException ex) { + LOG.warn("Failed to get upcoming movies: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + + } + + /** + * This method is used to retrieve the movies currently in theatres. + * + * This is a curated list that will normally contain 100 movies. The default response will return 20 movies. + * + * TODO: Implement more than 20 movies + * + * @param language + * @param page + * @throws MovieDbException + */ + public List getNowPlayingMovies(String language, int page) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "now-playing"); + + if (StringUtils.isNotBlank(language)) { + apiUrl.addArgument(PARAM_LANGUAGE, language); + } + + if (page > 0) { + apiUrl.addArgument(PARAM_PAGE, page); + } + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); + return wrapper.getMovies(); + } catch (IOException ex) { + LOG.warn("Failed to get now playing movies: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * This method is used to retrieve the daily movie popularity list. + * + * This list is updated daily. The default response will return 20 movies. + * + * TODO: Implement more than 20 movies + * + * @param language + * @param page + * @throws MovieDbException + */ + public List getPopularMovieList(String language, int page) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "popular"); + + if (StringUtils.isNotBlank(language)) { + apiUrl.addArgument(PARAM_LANGUAGE, language); + } + + if (page > 0) { + apiUrl.addArgument(PARAM_PAGE, page); + } + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); + return wrapper.getMovies(); + } catch (IOException ex) { + LOG.warn("Failed to get popular movie list: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * This method is used to retrieve the top rated movies that have over 10 votes on TMDb. + * + * The default response will return 20 movies. + * + * TODO: Implement more than 20 movies + * + * @param language + * @param page + * @throws MovieDbException + */ + public List getTopRatedMovies(String language, int page) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "top-rated"); + + if (StringUtils.isNotBlank(language)) { + apiUrl.addArgument(PARAM_LANGUAGE, language); + } + + if (page > 0) { + apiUrl.addArgument(PARAM_PAGE, page); + } + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); + return wrapper.getMovies(); + } catch (IOException ex) { + LOG.warn("Failed to get top rated movies: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * This method lets users rate a movie. + * + * A valid session id is required. + * + * @param sessionId + * @param rating + * @throws MovieDbException + */ + public boolean postMovieRating(String sessionId, String rating) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "/rating"); + + apiUrl.addArgument(PARAM_SESSION, sessionId); + apiUrl.addArgument(PARAM_VALUE, rating); + + throw new MovieDbException(MovieDbExceptionType.UNKNOWN_CAUSE, "Not implemented yet"); + } + + // + // + // + /** + * This method is used to retrieve all of the basic information about a movie collection. + * + * You can get the ID needed for this method by making a getMovieInfo request for the belongs_to_collection. + * + * @param collectionId + * @param language + * @throws MovieDbException + */ + public CollectionInfo getCollectionInfo(int collectionId, String language) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_COLLECTION); + apiUrl.addArgument(PARAM_ID, collectionId); + + if (StringUtils.isNotBlank(language)) { + apiUrl.addArgument(PARAM_LANGUAGE, language); + } + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + return mapper.readValue(webpage, CollectionInfo.class); + } catch (IOException ex) { + LOG.warn("Failed to get collection information: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * Get all of the images for a particular collection by collection id. + * + * @param collectionId + * @param language + * @throws MovieDbException + */ + public List getCollectionImages(int collectionId, String language) throws MovieDbException { + List artwork = new ArrayList(); + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_COLLECTION, "/images"); + apiUrl.addArgument(PARAM_ID, collectionId); + + if (StringUtils.isNotBlank(language)) { + apiUrl.addArgument(PARAM_LANGUAGE, language); + } + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + WrapperImages wrapper = mapper.readValue(webpage, WrapperImages.class); + + // Add all the posters to the list + for (Artwork poster : wrapper.getPosters()) { + poster.setArtworkType(ArtworkType.POSTER); + artwork.add(poster); + } + + // Add all the backdrops to the list + for (Artwork backdrop : wrapper.getBackdrops()) { + backdrop.setArtworkType(ArtworkType.BACKDROP); + artwork.add(backdrop); + } + + return artwork; + } catch (IOException ex) { + LOG.warn("Failed to get collection images: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + + } + + // + // + // + /** + * This method is used to retrieve all of the basic person information. + * + * It will return the single highest rated profile image. + * + * @param personId + * @throws MovieDbException + */ + public Person getPersonInfo(int personId) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_PERSON); + + apiUrl.addArgument(PARAM_ID, personId); + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + return mapper.readValue(webpage, Person.class); + } catch (IOException ex) { + LOG.warn("Failed to get movie info: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * This method is used to retrieve all of the cast & crew information for the person. + * + * It will return the single highest rated poster for each movie record. + * + * @param personId + * @throws MovieDbException + */ + public List getPersonCredits(int personId) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_PERSON, "/credits"); + + List personCredits = new ArrayList(); + + apiUrl.addArgument(PARAM_ID, personId); + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + WrapperPersonCredits wrapper = mapper.readValue(webpage, WrapperPersonCredits.class); + + // Add a cast member + for (PersonCredit cast : wrapper.getCast()) { + cast.setPersonType(PersonType.CAST); + personCredits.add(cast); + } + // Add a crew member + for (PersonCredit crew : wrapper.getCrew()) { + crew.setPersonType(PersonType.CREW); + personCredits.add(crew); + } + return personCredits; + } catch (IOException ex) { + LOG.warn("Failed to get person credits: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * This method is used to retrieve all of the profile images for a person. + * + * @param personId + * @throws MovieDbException + */ + public List getPersonImages(int personId) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_PERSON, "/images"); + + List personImages = new ArrayList(); + + apiUrl.addArgument(PARAM_ID, personId); + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + WrapperImages wrapper = mapper.readValue(webpage, WrapperImages.class); + + // Update the image type + for (Artwork artwork : wrapper.getProfiles()) { + artwork.setArtworkType(ArtworkType.PROFILE); + personImages.add(artwork); + } + return personImages; + } catch (IOException ex) { + LOG.warn("Failed to get person images: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * Get the changes for a specific person id. + * + * Changes are grouped by key, and ordered by date in descending order. + * + * By default, only the last 24 hours of changes are returned. + * + * The maximum number of days that can be returned in a single request is 14. + * + * The language is present on fields that are translatable. + * + * @param personId + * @param startDate + * @param endDate + * @throws MovieDbException + */ + public void getPersonChanges(int personId, String startDate, String endDate) throws MovieDbException { + throw new MovieDbException(MovieDbExceptionType.UNKNOWN_CAUSE, "Not implemented yet"); + } + + /** + * Get the latest person id. + * + * @throws MovieDbException + */ + public Person getPersonLatest() throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_PERSON, "/latest"); + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + return mapper.readValue(webpage, Person.class); + } catch (IOException ex) { + LOG.warn("Failed to get latest person: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + // + // + // + /** + * This method is used to retrieve the basic information about a production company on TMDb. + * + * @param companyId + * @throws MovieDbException + */ + public Company getCompanyInfo(int companyId) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_COMPANY); + + apiUrl.addArgument(PARAM_ID, companyId); + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + return mapper.readValue(webpage, Company.class); + } catch (IOException ex) { + LOG.warn("Failed to get company information: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * This method is used to retrieve the movies associated with a company. + * + * These movies are returned in order of most recently released to oldest. The default response will return 20 movies per page. + * + * TODO: Implement more than 20 movies + * + * @param companyId + * @param language + * @param page + * @throws MovieDbException + */ + public List getCompanyMovies(int companyId, String language, int page) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_COMPANY, "/movies"); + + apiUrl.addArgument(PARAM_ID, companyId); + + if (StringUtils.isNotBlank(language)) { + apiUrl.addArgument(PARAM_LANGUAGE, language); + } + + if (page > 0) { + apiUrl.addArgument(PARAM_PAGE, page); + } + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + WrapperCompanyMovies wrapper = mapper.readValue(webpage, WrapperCompanyMovies.class); + return wrapper.getResults(); + } catch (IOException ex) { + LOG.warn("Failed to get company movies: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + // + // + // + /** + * You can use this method to retrieve the list of genres used on TMDb. + * + * These IDs will correspond to those found in movie calls. + * + * @param language + */ + public List getGenreList(String language) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_GENRE, "/list"); + apiUrl.addArgument(PARAM_LANGUAGE, language); + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + WrapperGenres wrapper = mapper.readValue(webpage, WrapperGenres.class); + return wrapper.getGenres(); + } catch (IOException ex) { + LOG.warn("Failed to get genre list: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + @Deprecated + public List getGenreMovies(int genreId, String language, int page) throws MovieDbException { + return getGenreMovies(genreId, language, page, Boolean.TRUE); + } + + /** + * Get a list of movies per genre. + * + * It is important to understand that only movies with more than 10 votes get listed. + * + * This prevents movies from 1 10/10 rating from being listed first and for the first 5 pages. + * + * @param genreId + * @param language + * @param page + */ + public List getGenreMovies(int genreId, String language, int page, boolean includeAllMovies) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_GENRE, "/movies"); + apiUrl.addArgument(PARAM_ID, genreId); + + if (StringUtils.isNotBlank(language)) { + apiUrl.addArgument(PARAM_LANGUAGE, language); + } + + if (page > 0) { + apiUrl.addArgument(PARAM_PAGE, page); + } + + apiUrl.addArgument(PARAM_INCLUDE_ALL_MOVIES, includeAllMovies); + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); + return wrapper.getMovies(); + } catch (IOException ex) { + LOG.warn("Failed to get genre movie list: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + // + // + // + + /** + * Search Movies This is a good starting point to start finding movies on TMDb. + * + * @param movieName + * @param searchYear Limit the search to the provided year. Zero (0) will get all years + * @param language The language to include. Can be blank/null. + * @param includeAdult true or false to include adult titles in the search + * @param page The page of results to return. 0 to get the default (first page) + * @throws MovieDbException + */ + public List searchMovie(String movieName, int searchYear, String language, boolean includeAdult, int page) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_SEARCH, "movie"); + if (StringUtils.isNotBlank(movieName)) { + apiUrl.addArgument(PARAM_QUERY, movieName); + } + + if (searchYear > 0) { + apiUrl.addArgument(PARAM_YEAR, Integer.toString(searchYear)); + } + + if (StringUtils.isNotBlank(language)) { + apiUrl.addArgument(PARAM_LANGUAGE, language); + } + + apiUrl.addArgument(PARAM_ADULT, Boolean.toString(includeAdult)); + + if (page > 0) { + apiUrl.addArgument(PARAM_PAGE, Integer.toString(page)); + } + + URL url = apiUrl.buildUrl(); + + String webpage = WebBrowser.request(url); + try { + WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); + return wrapper.getMovies(); + } catch (IOException ex) { + LOG.warn("Failed to find movie: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + + } + + /** + * Search for collections by name. + * + * @param query + * @param language + * @param page + * @throws MovieDbException + */ + public List searchCollection(String query, String language, int page) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_SEARCH, "collections"); + + if (StringUtils.isNotBlank(query)) { + apiUrl.addArgument(PARAM_QUERY, query); + } + + if (StringUtils.isNotBlank(language)) { + apiUrl.addArgument(PARAM_LANGUAGE, language); + } + + if (page > 0) { + apiUrl.addArgument(PARAM_PAGE, Integer.toString(page)); + } + + URL url = apiUrl.buildUrl(); + + String webpage = WebBrowser.request(url); + try { + WrapperCollection wrapper = mapper.readValue(webpage, WrapperCollection.class); + return wrapper.getResults(); + } catch (IOException ex) { + LOG.warn("Failed to find collection: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * This is a good starting point to start finding people on TMDb. + * + * The idea is to be a quick and light method so you can iterate through people quickly. + * + * @param personName + * @param includeAdult + * @param page + * @throws MovieDbException + */ + public List searchPeople(String personName, boolean includeAdult, int page) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_SEARCH, "person"); + apiUrl.addArgument(PARAM_QUERY, personName); + apiUrl.addArgument(PARAM_ADULT, includeAdult); + + if (page > 0) { + apiUrl.addArgument(PARAM_PAGE, page); + } + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + WrapperPerson wrapper = mapper.readValue(webpage, WrapperPerson.class); + return wrapper.getResults(); + } catch (IOException ex) { + LOG.warn("Failed to find person: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * Search for lists by name and description. + * + * @param query + * @param language + * @param page + * @throws MovieDbException + */ + public List searchList(String query, String language, int page) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_SEARCH, "list"); + + if (StringUtils.isNotBlank(query)) { + apiUrl.addArgument(PARAM_QUERY, query); + } + + if (StringUtils.isNotBlank(language)) { + apiUrl.addArgument(PARAM_LANGUAGE, language); + } + + if (page > 0) { + apiUrl.addArgument(PARAM_PAGE, Integer.toString(page)); + } + + URL url = apiUrl.buildUrl(); + + String webpage = WebBrowser.request(url); + try { + WrapperMovieList wrapper = mapper.readValue(webpage, WrapperMovieList.class); + return wrapper.getMovieList(); + } catch (IOException ex) { + LOG.warn("Failed to find list: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * Search Companies. + * + * You can use this method to search for production companies that are part of TMDb. The company IDs will map to those returned + * on movie calls. + * + * http://help.themoviedb.org/kb/api/search-companies + * + * @param companyName + * @param page + * @throws MovieDbException + */ + public List searchCompanies(String companyName, int page) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_SEARCH, "company"); + apiUrl.addArgument(PARAM_QUERY, companyName); + + if (page > 0) { + apiUrl.addArgument(PARAM_PAGE, page); + } + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + try { + WrapperCompany wrapper = mapper.readValue(webpage, WrapperCompany.class); + return wrapper.getResults(); + } catch (IOException ex) { + LOG.warn("Failed to find company: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * Search for keywords by name + * + * @param query + * @param page + * @throws MovieDbException + */ + public List searchKeyword(String query, int page) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_SEARCH, "keyword"); + + if (StringUtils.isNotBlank(query)) { + apiUrl.addArgument(PARAM_QUERY, query); + } + + if (page > 0) { + apiUrl.addArgument(PARAM_PAGE, Integer.toString(page)); + } + + URL url = apiUrl.buildUrl(); + + String webpage = WebBrowser.request(url); + try { + WrapperKeywords wrapper = mapper.readValue(webpage, WrapperKeywords.class); + return wrapper.getResults(); + } catch (IOException ex) { + LOG.warn("Failed to find keyword: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + // + // + // + + /** + * Get a list by its ID + * + * @param listId + * @return The list and its items + * @throws MovieDbException + */ + public MovieDbList getList(String listId) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_LIST); + apiUrl.addArgument(PARAM_ID, listId); + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + return mapper.readValue(webpage, MovieDbList.class); + } catch (IOException ex) { + LOG.warn("Failed to get list: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + // + // + // + + /** + * Get the basic information for a specific keyword id. + * + * @param keywordId + * @return + * @throws MovieDbException + */ + public Keyword getKeyword(String keywordId) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_KEYWORD); + apiUrl.addArgument(PARAM_ID, keywordId); + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + return mapper.readValue(webpage, Keyword.class); + } catch (IOException ex) { + LOG.warn("Failed to get keyword: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + + } + + /** + * Get the list of movies for a particular keyword by id. + * + * @param keywordId + * @param language + * @param page + * @return List of movies with the keyword + * @throws MovieDbException + */ + public List getKeywordMovies(String keywordId, String language, int page) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_KEYWORD, "/movies"); + apiUrl.addArgument(PARAM_ID, keywordId); + + if (StringUtils.isNotBlank(language)) { + apiUrl.addArgument(PARAM_LANGUAGE, language); + } + + if (page > 0) { + apiUrl.addArgument(PARAM_PAGE, page); + } + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + WrapperKeywordMovies wrapper = mapper.readValue(webpage, WrapperKeywordMovies.class); + return wrapper.getResults(); + } catch (IOException ex) { + LOG.warn("Failed to get top rated movies: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + + } + // + // + // + + public void getMovieChangesList(int page, String startDate, String endDate) throws MovieDbException { + throw new MovieDbException(MovieDbExceptionType.UNKNOWN_CAUSE, "Not implemented yet"); + } + + public void getPersonChangesList(int page, String startDate, String endDate) throws MovieDbException { + throw new MovieDbException(MovieDbExceptionType.UNKNOWN_CAUSE, "Not implemented yet"); + } + // +} diff --git a/src/main/java/com/omertron/themoviedbapi/model/MovieDb.java b/src/main/java/com/omertron/themoviedbapi/model/MovieDb.java index e61d05a97..dbe9eee7f 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/MovieDb.java +++ b/src/main/java/com/omertron/themoviedbapi/model/MovieDb.java @@ -1,354 +1,355 @@ -/* - * Copyright (c) 2004-2013 Stuart Boston - * - * This file is part of TheMovieDB API. - * - * TheMovieDB API is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * TheMovieDB API is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with TheMovieDB API. If not, see . - * - */ -package com.omertron.themoviedbapi.model; - -import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.fasterxml.jackson.annotation.JsonProperty; -import java.io.Serializable; -import java.util.List; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Movie Bean - * - * @author stuart.boston - */ -public class MovieDb implements Serializable { - - private static final long serialVersionUID = 1L; - /* - * Logger - */ - private static final Logger LOG = LoggerFactory.getLogger(MovieDb.class); - /* - * Properties - */ - @JsonProperty("backdrop_path") - private String backdropPath; - @JsonProperty("id") - private int id; - @JsonProperty("original_title") - private String originalTitle; - @JsonProperty("popularity") - private float popularity; - @JsonProperty("poster_path") - private String posterPath; - @JsonProperty("release_date") - private String releaseDate; - @JsonProperty("title") - private String title; - @JsonProperty("adult") - private boolean adult; - @JsonProperty("belongs_to_collection") - private Collection belongsToCollection; - @JsonProperty("budget") - private long budget; - @JsonProperty("genres") - private List genres; - @JsonProperty("homepage") - private String homepage; - @JsonProperty("imdb_id") - private String imdbID; - @JsonProperty("overview") - private String overview; - @JsonProperty("production_companies") - private List productionCompanies; - @JsonProperty("production_countries") - private List productionCountries; - @JsonProperty("revenue") - private long revenue; - @JsonProperty("runtime") - private int runtime; - @JsonProperty("spoken_languages") - private List spokenLanguages; - @JsonProperty("tagline") - private String tagline; - @JsonProperty("vote_average") - private float voteAverage; - @JsonProperty("vote_count") - private int voteCount; - @JsonProperty("status") - private String status; - - // - public String getBackdropPath() { - return backdropPath; - } - - public int getId() { - return id; - } - - public String getOriginalTitle() { - return originalTitle; - } - - public float getPopularity() { - return popularity; - } - - public String getPosterPath() { - return posterPath; - } - - public String getReleaseDate() { - return releaseDate; - } - - public String getTitle() { - return title; - } - - public boolean isAdult() { - return adult; - } - - public Collection getBelongsToCollection() { - return belongsToCollection; - } - - public long getBudget() { - return budget; - } - - public List getGenres() { - return genres; - } - - public String getHomepage() { - return homepage; - } - - public String getImdbID() { - return imdbID; - } - - public String getOverview() { - return overview; - } - - public List getProductionCompanies() { - return productionCompanies; - } - - public List getProductionCountries() { - return productionCountries; - } - - public long getRevenue() { - return revenue; - } - - public int getRuntime() { - return runtime; - } - - public List getSpokenLanguages() { - return spokenLanguages; - } - - public String getTagline() { - return tagline; - } - - public float getVoteAverage() { - return voteAverage; - } - - public int getVoteCount() { - return voteCount; - } - - public String getStatus() { - return status; - } - // - - // - public void setBackdropPath(String backdropPath) { - this.backdropPath = backdropPath; - } - - public void setId(int id) { - this.id = id; - } - - public void setOriginalTitle(String originalTitle) { - this.originalTitle = originalTitle; - } - - public void setPopularity(float popularity) { - this.popularity = popularity; - } - - public void setPosterPath(String posterPath) { - this.posterPath = posterPath; - } - - public void setReleaseDate(String releaseDate) { - this.releaseDate = releaseDate; - } - - public void setTitle(String title) { - this.title = title; - } - - public void setAdult(boolean adult) { - this.adult = adult; - } - - public void setBelongsToCollection(Collection belongsToCollection) { - this.belongsToCollection = belongsToCollection; - } - - public void setBudget(long budget) { - this.budget = budget; - } - - public void setGenres(List genres) { - this.genres = genres; - } - - public void setHomepage(String homepage) { - this.homepage = homepage; - } - - public void setImdbID(String imdbID) { - this.imdbID = imdbID; - } - - public void setOverview(String overview) { - this.overview = overview; - } - - public void setProductionCompanies(List productionCompanies) { - this.productionCompanies = productionCompanies; - } - - public void setProductionCountries(List productionCountries) { - this.productionCountries = productionCountries; - } - - public void setRevenue(long revenue) { - this.revenue = revenue; - } - - public void setRuntime(int runtime) { - this.runtime = runtime; - } - - public void setSpokenLanguages(List spokenLanguages) { - this.spokenLanguages = spokenLanguages; - } - - public void setTagline(String tagline) { - this.tagline = tagline; - } - - public void setVoteAverage(float voteAverage) { - this.voteAverage = voteAverage; - } - - public void setVoteCount(int voteCount) { - this.voteCount = voteCount; - } - - public void setStatus(String status) { - this.status = status; - } - - // - /** - * Handle unknown properties and print a message - * - * @param key - * @param value - */ - @JsonAnySetter - public void handleUnknown(String key, Object value) { - StringBuilder sb = new StringBuilder(); - sb.append("Unknown property: '").append(key); - sb.append("' value: '").append(value).append("'"); - LOG.trace(sb.toString()); - } - - // - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final MovieDb other = (MovieDb) obj; - if (this.id != other.id) { - return false; - } - if ((this.imdbID == null) ? (other.imdbID != null) : !this.imdbID.equals(other.imdbID)) { - return false; - } - if (this.runtime != other.runtime) { - return false; - } - return true; - } - - @Override - public int hashCode() { - int hash = 5; - hash = 89 * hash + this.id; - hash = 89 * hash + (this.imdbID != null ? this.imdbID.hashCode() : 0); - hash = 89 * hash + this.runtime; - return hash; - } - // - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("[MovieDB="); - sb.append("[backdropPath=").append(backdropPath); - sb.append("],[id=").append(id); - sb.append("],[originalTitle=").append(originalTitle); - sb.append("],[popularity=").append(popularity); - sb.append("],[posterPath=").append(posterPath); - sb.append("],[releaseDate=").append(releaseDate); - sb.append("],[title=").append(title); - sb.append("],[adult=").append(adult); - sb.append("],[belongsToCollection=").append(belongsToCollection); - sb.append("],[budget=").append(budget); - sb.append("],[genres=").append(genres); - sb.append("],[homepage=").append(homepage); - sb.append("],[imdbID=").append(imdbID); - sb.append("],[overview=").append(overview); - sb.append("],[productionCompanies=").append(productionCompanies); - sb.append("],[productionCountries=").append(productionCountries); - sb.append("],[revenue=").append(revenue); - sb.append("],[runtime=").append(runtime); - sb.append("],[spokenLanguages=").append(spokenLanguages); - sb.append("],[tagline=").append(tagline); - sb.append("],[voteAverage=").append(voteAverage); - sb.append("],[voteCount=").append(voteCount); - sb.append("],[status=").append(status); - sb.append("]]"); - return sb.toString(); - } -} +/* + * Copyright (c) 2004-2013 Stuart Boston + * + * This file is part of TheMovieDB API. + * + * TheMovieDB API is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * TheMovieDB API is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with TheMovieDB API. If not, see . + * + */ +package com.omertron.themoviedbapi.model; + +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.io.Serializable; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Movie Bean + * + * @author stuart.boston + */ +public class MovieDb implements Serializable { + + private static final long serialVersionUID = 1L; + /* + * Logger + */ + private static final Logger LOG = LoggerFactory.getLogger(MovieDb.class); + /* + * Properties + */ + @JsonProperty("backdrop_path") + private String backdropPath; + @JsonProperty("id") + private int id; + @JsonProperty("original_title") + private String originalTitle; + @JsonProperty("popularity") + private float popularity; + @JsonProperty("poster_path") + private String posterPath; + @JsonProperty("release_date") + private String releaseDate; + @JsonProperty("title") + private String title; + @JsonProperty("adult") + private boolean adult; + @JsonProperty("belongs_to_collection") + private Collection belongsToCollection; + @JsonProperty("budget") + private long budget; + @JsonProperty("genres") + private List genres; + @JsonProperty("homepage") + private String homepage; + @JsonProperty("imdb_id") + private String imdbID; + @JsonProperty("overview") + private String overview; + @JsonProperty("production_companies") + private List productionCompanies; + @JsonProperty("production_countries") + private List productionCountries; + @JsonProperty("revenue") + private long revenue; + @JsonProperty("runtime") + private int runtime; + @JsonProperty("spoken_languages") + private List spokenLanguages; + @JsonProperty("tagline") + private String tagline; + @JsonProperty("vote_average") + private float voteAverage; + @JsonProperty("vote_count") + private int voteCount; + @JsonProperty("status") + private String status; + + // + public String getBackdropPath() { + return backdropPath; + } + + public int getId() { + return id; + } + + public String getOriginalTitle() { + return originalTitle; + } + + public float getPopularity() { + return popularity; + } + + public String getPosterPath() { + return posterPath; + } + + public String getReleaseDate() { + return releaseDate; + } + + public String getTitle() { + return title; + } + + public boolean isAdult() { + return adult; + } + + public Collection getBelongsToCollection() { + return belongsToCollection; + } + + public long getBudget() { + return budget; + } + + public List getGenres() { + return genres; + } + + public String getHomepage() { + return homepage; + } + + public String getImdbID() { + return imdbID; + } + + public String getOverview() { + return overview; + } + + public List getProductionCompanies() { + return productionCompanies; + } + + public List getProductionCountries() { + return productionCountries; + } + + public long getRevenue() { + return revenue; + } + + public int getRuntime() { + return runtime; + } + + public List getSpokenLanguages() { + return spokenLanguages; + } + + public String getTagline() { + return tagline; + } + + public float getVoteAverage() { + return voteAverage; + } + + public int getVoteCount() { + return voteCount; + } + + public String getStatus() { + return status; + } + // + + // + public void setBackdropPath(String backdropPath) { + this.backdropPath = backdropPath; + } + + public void setId(int id) { + this.id = id; + } + + public void setOriginalTitle(String originalTitle) { + this.originalTitle = originalTitle; + } + + public void setPopularity(float popularity) { + this.popularity = popularity; + } + + public void setPosterPath(String posterPath) { + this.posterPath = posterPath; + } + + public void setReleaseDate(String releaseDate) { + this.releaseDate = releaseDate; + } + + public void setTitle(String title) { + this.title = title; + } + + public void setAdult(boolean adult) { + this.adult = adult; + } + + public void setBelongsToCollection(Collection belongsToCollection) { + this.belongsToCollection = belongsToCollection; + } + + public void setBudget(long budget) { + this.budget = budget; + } + + public void setGenres(List genres) { + this.genres = genres; + } + + public void setHomepage(String homepage) { + this.homepage = homepage; + } + + public void setImdbID(String imdbID) { + this.imdbID = imdbID; + } + + public void setOverview(String overview) { + this.overview = overview; + } + + public void setProductionCompanies(List productionCompanies) { + this.productionCompanies = productionCompanies; + } + + public void setProductionCountries(List productionCountries) { + this.productionCountries = productionCountries; + } + + public void setRevenue(long revenue) { + this.revenue = revenue; + } + + public void setRuntime(int runtime) { + this.runtime = runtime; + } + + public void setSpokenLanguages(List spokenLanguages) { + this.spokenLanguages = spokenLanguages; + } + + public void setTagline(String tagline) { + this.tagline = tagline; + } + + public void setVoteAverage(float voteAverage) { + this.voteAverage = voteAverage; + } + + public void setVoteCount(int voteCount) { + this.voteCount = voteCount; + } + + public void setStatus(String status) { + this.status = status; + } + + // + // + /** + * Handle unknown properties and print a message + * + * @param key + * @param value + */ + @JsonAnySetter + public void handleUnknown(String key, Object value) { + StringBuilder sb = new StringBuilder(); + sb.append("Unknown property: '").append(key); + sb.append("' value: '").append(value).append("'"); + LOG.trace(sb.toString()); + } + + // + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final MovieDb other = (MovieDb) obj; + if (this.id != other.id) { + return false; + } + if ((this.imdbID == null) ? (other.imdbID != null) : !this.imdbID.equals(other.imdbID)) { + return false; + } + if (this.runtime != other.runtime) { + return false; + } + return true; + } + + @Override + public int hashCode() { + int hash = 5; + hash = 89 * hash + this.id; + hash = 89 * hash + (this.imdbID != null ? this.imdbID.hashCode() : 0); + hash = 89 * hash + this.runtime; + return hash; + } + // + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("[MovieDB="); + sb.append("[backdropPath=").append(backdropPath); + sb.append("],[id=").append(id); + sb.append("],[originalTitle=").append(originalTitle); + sb.append("],[popularity=").append(popularity); + sb.append("],[posterPath=").append(posterPath); + sb.append("],[releaseDate=").append(releaseDate); + sb.append("],[title=").append(title); + sb.append("],[adult=").append(adult); + sb.append("],[belongsToCollection=").append(belongsToCollection); + sb.append("],[budget=").append(budget); + sb.append("],[genres=").append(genres); + sb.append("],[homepage=").append(homepage); + sb.append("],[imdbID=").append(imdbID); + sb.append("],[overview=").append(overview); + sb.append("],[productionCompanies=").append(productionCompanies); + sb.append("],[productionCountries=").append(productionCountries); + sb.append("],[revenue=").append(revenue); + sb.append("],[runtime=").append(runtime); + sb.append("],[spokenLanguages=").append(spokenLanguages); + sb.append("],[tagline=").append(tagline); + sb.append("],[voteAverage=").append(voteAverage); + sb.append("],[voteCount=").append(voteCount); + sb.append("],[status=").append(status); + sb.append("]]"); + return sb.toString(); + } +} diff --git a/src/main/java/com/omertron/themoviedbapi/tools/ApiUrl.java b/src/main/java/com/omertron/themoviedbapi/tools/ApiUrl.java index b443ff122..cee0855b3 100644 --- a/src/main/java/com/omertron/themoviedbapi/tools/ApiUrl.java +++ b/src/main/java/com/omertron/themoviedbapi/tools/ApiUrl.java @@ -1,213 +1,224 @@ -/* - * Copyright (c) 2004-2013 Stuart Boston - * - * This file is part of TheMovieDB API. - * - * TheMovieDB API is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * TheMovieDB API is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with TheMovieDB API. If not, see . - * - */ -package com.omertron.themoviedbapi.tools; - -import com.omertron.themoviedbapi.TheMovieDbApi; -import java.io.UnsupportedEncodingException; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLEncoder; -import java.util.HashMap; -import java.util.Map; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * The API URL that is used to construct the API call - * - * @author Stuart - */ -public class ApiUrl { - - /* - * Logger - */ - private static final Logger LOG = LoggerFactory.getLogger(ApiUrl.class); - /* - * TheMovieDbApi API Base URL - */ - private static final String TMDB_API_BASE = "http://api.themoviedb.org/3/"; - /* - * Parameter configuration - */ - private static final String DELIMITER_FIRST = "?"; - private static final String DELIMITER_SUBSEQUENT = "&"; - private static final String DEFAULT_STRING = ""; - /* - * Properties - */ - private TheMovieDbApi tmdb; - private String method; - private String submethod; - private Map arguments = new HashMap(); - /* - * API Parameters - */ - public static final String PARAM_ADULT = "include_adult="; - public static final String PARAM_API_KEY = "api_key="; - public static final String PARAM_COUNTRY = "country="; - public static final String PARAM_FAVORITE = "favorite="; - public static final String PARAM_ID = "id="; - public static final String PARAM_LANGUAGE = "language="; - public static final String PARAM_INCLUDE_ALL_MOVIES = "include_all_movies="; -// public static final String PARAM_MOVIE_ID = "movie_id="; - public static final String PARAM_MOVIE_WATCHLIST = "movie_watchlist="; - public static final String PARAM_PAGE = "page="; - public static final String PARAM_QUERY = "query="; - public static final String PARAM_SESSION = "session_id="; - public static final String PARAM_TOKEN = "request_token="; - public static final String PARAM_VALUE = "value="; - public static final String PARAM_YEAR = "year="; - - // - /** - * Constructor for the simple API URL method without a sub-method - * - * @param method - */ - public ApiUrl(TheMovieDbApi tmdb, String method) { - this.tmdb = tmdb; - this.method = method; - this.submethod = DEFAULT_STRING; - } - - /** - * Constructor for the API URL with a sub-method - * - * @param method - * @param submethod - */ - public ApiUrl(TheMovieDbApi tmdb, String method, String submethod) { - this.tmdb = tmdb; - this.method = method; - this.submethod = submethod; - } - // - - /** - * Build the URL from the pre-created arguments. - */ - public URL buildUrl() { - StringBuilder urlString = new StringBuilder(TMDB_API_BASE); - - // Get the start of the URL - urlString.append(method); - - // We have either a queury, or a direct request - if (arguments.containsKey(PARAM_QUERY)) { - // Append the suffix of the API URL - urlString.append(submethod); - - // Append the key information - urlString.append(DELIMITER_FIRST).append(PARAM_API_KEY); - urlString.append(tmdb.getApiKey()); - - // Append the search term - urlString.append(DELIMITER_SUBSEQUENT); - urlString.append(PARAM_QUERY); - - String query = arguments.get(PARAM_QUERY); - - try { - urlString.append(URLEncoder.encode(query, "UTF-8")); - } catch (UnsupportedEncodingException ex) { - LOG.trace("Unable to encode query: '" + query + "' trying raw."); - // If we can't encode it, try it raw - urlString.append(query); - } - - arguments.remove(PARAM_QUERY); - } else { - // Append the ID if provided - if (arguments.containsKey(PARAM_ID)) { - urlString.append(arguments.get(PARAM_ID)); - arguments.remove(PARAM_ID); - } - - // Append the suffix of the API URL - urlString.append(submethod); - - // Append the key information - urlString.append(DELIMITER_FIRST).append(PARAM_API_KEY); - urlString.append(tmdb.getApiKey()); - } - - for (Map.Entry argEntry : arguments.entrySet()) { - urlString.append(DELIMITER_SUBSEQUENT).append(argEntry.getKey()); - urlString.append(argEntry.getValue()); - } - - try { - LOG.trace("URL: {}", urlString.toString()); - return new URL(urlString.toString()); - } catch (MalformedURLException ex) { - LOG.warn("Failed to create URL {} - {}", urlString.toString(), ex.toString()); - return null; - } finally { - arguments.clear(); - } - } - - /** - * Add arguments individually - * - * @param key - * @param value - */ - public void addArgument(String key, String value) { - arguments.put(key, value); - } - - /** - * Add arguments individually - * - * @param key - * @param value - */ - public void addArgument(String key, int value) { - arguments.put(key, Integer.toString(value)); - } - - /** - * Add arguments individually - * - * @param key - * @param value - */ - public void addArgument(String key, boolean value) { - arguments.put(key, Boolean.toString(value)); - } - - /** - * Clear the arguments - */ - public void clearArguments() { - arguments.clear(); - } - - /** - * Set the arguments directly - * - * @param args - */ - public void setArguments(Map args) { - arguments.putAll(args); - } -} +/* + * Copyright (c) 2004-2013 Stuart Boston + * + * This file is part of TheMovieDB API. + * + * TheMovieDB API is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * TheMovieDB API is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with TheMovieDB API. If not, see . + * + */ +package com.omertron.themoviedbapi.tools; + +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLEncoder; +import java.util.HashMap; +import java.util.Map; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The API URL that is used to construct the API call + * + * @author Stuart + */ +public class ApiUrl { + + /* + * Logger + */ + private static final Logger LOG = LoggerFactory.getLogger(ApiUrl.class); + /* + * TheMovieDbApi API Base URL + */ + private static final String TMDB_API_BASE = "http://api.themoviedb.org/3/"; + /* + * Parameter configuration + */ + private static final String DELIMITER_FIRST = "?"; + private static final String DELIMITER_SUBSEQUENT = "&"; + private static final String DEFAULT_STRING = ""; + /* + * Properties + */ + private String apiKey; + private String method; + private String submethod; + private Map arguments = new HashMap(); + /* + * API Parameters + */ + public static final String PARAM_ADULT = "include_adult="; + public static final String PARAM_API_KEY = "api_key="; + public static final String PARAM_COUNTRY = "country="; + public static final String PARAM_FAVORITE = "favorite="; + public static final String PARAM_ID = "id="; + public static final String PARAM_LANGUAGE = "language="; + public static final String PARAM_INCLUDE_ALL_MOVIES = "include_all_movies="; +// public static final String PARAM_MOVIE_ID = "movie_id="; + public static final String PARAM_MOVIE_WATCHLIST = "movie_watchlist="; + public static final String PARAM_PAGE = "page="; + public static final String PARAM_QUERY = "query="; + public static final String PARAM_SESSION = "session_id="; + public static final String PARAM_TOKEN = "request_token="; + public static final String PARAM_VALUE = "value="; + public static final String PARAM_YEAR = "year="; + private static final String APPEND_TO_RESPONSE = "append_to_response="; + + // + /** + * Constructor for the simple API URL method without a sub-method + * + * @param method + */ + public ApiUrl(String apiKey, String method) { + this.apiKey = apiKey; + this.method = method; + this.submethod = DEFAULT_STRING; + } + + /** + * Constructor for the API URL with a sub-method + * + * @param method + * @param submethod + */ + public ApiUrl(String apiKey, String method, String submethod) { + this.apiKey = apiKey; + this.method = method; + this.submethod = submethod; + } + // + + /** + * Build the URL from the pre-created arguments. + */ + public URL buildUrl() { + StringBuilder urlString = new StringBuilder(TMDB_API_BASE); + + // Get the start of the URL + urlString.append(method); + + // We have either a queury, or a direct request + if (arguments.containsKey(PARAM_QUERY)) { + // Append the suffix of the API URL + urlString.append(submethod); + + // Append the key information + urlString.append(DELIMITER_FIRST).append(PARAM_API_KEY); + urlString.append(apiKey); + + // Append the search term + urlString.append(DELIMITER_SUBSEQUENT); + urlString.append(PARAM_QUERY); + + String query = arguments.get(PARAM_QUERY); + + try { + urlString.append(URLEncoder.encode(query, "UTF-8")); + } catch (UnsupportedEncodingException ex) { + LOG.trace("Unable to encode query: '{}' trying raw.", query); + // If we can't encode it, try it raw + urlString.append(query); + } + + arguments.remove(PARAM_QUERY); + } else { + // Append the ID if provided + if (arguments.containsKey(PARAM_ID)) { + urlString.append(arguments.get(PARAM_ID)); + arguments.remove(PARAM_ID); + } + + // Append the suffix of the API URL + urlString.append(submethod); + + // Append the key information + urlString.append(DELIMITER_FIRST).append(PARAM_API_KEY); + urlString.append(apiKey); + } + + for (Map.Entry argEntry : arguments.entrySet()) { + urlString.append(DELIMITER_SUBSEQUENT).append(argEntry.getKey()); + urlString.append(argEntry.getValue()); + } + + try { + LOG.trace("URL: {}", urlString.toString()); + return new URL(urlString.toString()); + } catch (MalformedURLException ex) { + LOG.warn("Failed to create URL {} - {}", urlString.toString(), ex.toString()); + return null; + } finally { + arguments.clear(); + } + } + + /** + * Add arguments individually + * + * @param key + * @param value + */ + public void addArgument(String key, String value) { + arguments.put(key, value); + } + + /** + * Add arguments individually + * + * @param key + * @param value + */ + public void addArgument(String key, int value) { + arguments.put(key, Integer.toString(value)); + } + + /** + * Add arguments individually + * + * @param key + * @param value + */ + public void addArgument(String key, boolean value) { + arguments.put(key, Boolean.toString(value)); + } + + /** + * Clear the arguments + */ + public void clearArguments() { + arguments.clear(); + } + + /** + * Set the arguments directly + * + * @param args + */ + public void setArguments(Map args) { + arguments.putAll(args); + } + + /** + * Append any optional parameters to the URL + * + * @param appendToResponse + */ + public void appendToResponse(String[] appendToResponse) { + if (appendToResponse.length > 0) { + addArgument(APPEND_TO_RESPONSE, appendToResponse[0]); + } + } +}