From ac57816b1d3aa8306ab90a94aac067be3916907d Mon Sep 17 00:00:00 2001 From: Stuart Boston Date: Tue, 20 Aug 2013 20:47:24 +0100 Subject: [PATCH] Merge pull request #6 from holgerbrandl/master "List" and "Account" implemenation --- .../omertron/themoviedbapi/TheMovieDbApi.java | 3725 +++++++++-------- .../model/AbstractJsonMapping.java | 58 + .../omertron/themoviedbapi/model/Account.java | 66 + .../themoviedbapi/model/AlternativeTitle.java | 26 +- .../omertron/themoviedbapi/model/Artwork.java | 29 +- .../themoviedbapi/model/ChangeKeyItem.java | 14 +- .../themoviedbapi/model/ChangedItem.java | 14 +- .../themoviedbapi/model/Collection.java | 36 +- .../themoviedbapi/model/CollectionInfo.java | 37 +- .../omertron/themoviedbapi/model/Company.java | 32 +- .../themoviedbapi/model/Discover.java | 28 +- .../omertron/themoviedbapi/model/Genre.java | 35 +- .../themoviedbapi/model/JobDepartment.java | 29 +- .../omertron/themoviedbapi/model/Keyword.java | 35 +- .../themoviedbapi/model/KeywordMovie.java | 32 +- .../themoviedbapi/model/Language.java | 35 +- .../themoviedbapi/model/ListItemStatus.java | 51 + .../omertron/themoviedbapi/model/MovieDb.java | 54 +- .../themoviedbapi/model/MovieDbList.java | 32 +- .../model/MovieDbListStatus.java | 36 + .../themoviedbapi/model/MovieList.java | 32 +- .../omertron/themoviedbapi/model/Person.java | 36 +- .../themoviedbapi/model/PersonCast.java | 37 +- .../themoviedbapi/model/PersonCredit.java | 36 +- .../themoviedbapi/model/PersonCrew.java | 35 +- .../themoviedbapi/model/PersonType.java | 5 +- .../model/ProductionCompany.java | 35 +- .../model/ProductionCountry.java | 35 +- .../themoviedbapi/model/ReleaseInfo.java | 35 +- .../omertron/themoviedbapi/model/Reviews.java | 32 +- .../themoviedbapi/model/StatusCode.java | 35 +- .../model/TmdbConfiguration.java | 35 +- .../model/TokenAuthorisation.java | 30 +- .../themoviedbapi/model/TokenSession.java | 29 - .../omertron/themoviedbapi/model/Trailer.java | 36 +- .../themoviedbapi/model/Translation.java | 32 +- .../themoviedbapi/tools/WebBrowser.java | 641 +-- .../wrapper/WrapperMovieDbList.java | 25 + .../themoviedbapi/TheMovieDbApiTest.java | 100 +- 39 files changed, 2730 insertions(+), 2955 deletions(-) create mode 100644 src/main/java/com/omertron/themoviedbapi/model/AbstractJsonMapping.java create mode 100644 src/main/java/com/omertron/themoviedbapi/model/Account.java create mode 100644 src/main/java/com/omertron/themoviedbapi/model/ListItemStatus.java create mode 100644 src/main/java/com/omertron/themoviedbapi/model/MovieDbListStatus.java create mode 100644 src/main/java/com/omertron/themoviedbapi/wrapper/WrapperMovieDbList.java diff --git a/src/main/java/com/omertron/themoviedbapi/TheMovieDbApi.java b/src/main/java/com/omertron/themoviedbapi/TheMovieDbApi.java index b123edb3b..e912e1bc9 100644 --- a/src/main/java/com/omertron/themoviedbapi/TheMovieDbApi.java +++ b/src/main/java/com/omertron/themoviedbapi/TheMovieDbApi.java @@ -1,1732 +1,1993 @@ -/* - * 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.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.omertron.themoviedbapi.MovieDbException.MovieDbExceptionType; -import com.omertron.themoviedbapi.model.*; -import com.omertron.themoviedbapi.results.TmdbResultsList; -import com.omertron.themoviedbapi.results.TmdbResultsMap; -import com.omertron.themoviedbapi.tools.ApiUrl; -import com.omertron.themoviedbapi.tools.WebBrowser; -import com.omertron.themoviedbapi.wrapper.*; -import org.apache.commons.lang3.StringUtils; -import org.apache.http.client.methods.HttpGet; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.yamj.api.common.http.CommonHttpClient; - -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static com.omertron.themoviedbapi.tools.ApiUrl.*; - -/** - * 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 CommonHttpClient httpClient; - private TmdbConfiguration tmdbConfig; - // API Methods - 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/"; - private static final String BASE_JOB = "job/"; - private static final String BASE_DISCOVER = "discover/"; - // 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, null); - } - - /** - * API for The Movie Db. - * - * @param apiKey - * @param httpClient The httpClient to use for web requests. - * @throws MovieDbException - */ - public TheMovieDbApi(String apiKey, CommonHttpClient httpClient) throws MovieDbException { - this.apiKey = apiKey; - this.httpClient = httpClient; - - ApiUrl apiUrl = new ApiUrl(apiKey, "configuration"); - URL configUrl = apiUrl.buildUrl(); - String webpage = requestWebPage(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; - } - - private String requestWebPage(URL url) throws MovieDbException { - // use HTTP client implementation - if (httpClient != null) { - try { - HttpGet httpGet = new HttpGet(url.toURI()); - httpGet.addHeader("accept", "application/json"); - return httpClient.requestContent(httpGet); - } catch (URISyntaxException ex) { - throw new MovieDbException(MovieDbException.MovieDbExceptionType.CONNECTION_ERROR, null, ex); - } catch (IOException ex) { - throw new MovieDbException(MovieDbException.MovieDbExceptionType.CONNECTION_ERROR, null, ex); - } catch (RuntimeException ex) { - throw new MovieDbException(MovieDbException.MovieDbExceptionType.HTTP_503_ERROR, "Service Unavailable", ex); - } - } - - // use web browser - return WebBrowser.request(url); - } - - /** - * Set the proxy information - * - * @param host - * @param port - * @param username - * @param password - */ - public void setProxy(String host, String port, String username, String password) { - // should be set in HTTP client already - if (httpClient != null) { - return; - } - - 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) { - // should be set in HTTP client already - if (httpClient != null) { - return; - } - - 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 = requestWebPage(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 = requestWebPage(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 = requestWebPage(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 = requestWebPage(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, String... appendToResponse) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE); - - apiUrl.addArgument(PARAM_ID, imdbId); - - if (StringUtils.isNotBlank(language)) { - apiUrl.addArgument(PARAM_LANGUAGE, language); - } - - apiUrl.appendToResponse(appendToResponse); - - URL url = apiUrl.buildUrl(); - String webpage = requestWebPage(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 TmdbResultsList getMovieAlternativeTitles(int movieId, String country, String... appendToResponse) 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); - } - - apiUrl.appendToResponse(appendToResponse); - - URL url = apiUrl.buildUrl(); - String webpage = requestWebPage(url); - try { - WrapperAlternativeTitles wrapper = mapper.readValue(webpage, WrapperAlternativeTitles.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getTitles()); - results.copyWrapper(wrapper); - return results; - } 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 TmdbResultsList getMovieCasts(int movieId, String... appendToResponse) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "/casts"); - apiUrl.addArgument(PARAM_ID, movieId); - - apiUrl.appendToResponse(appendToResponse); - - URL url = apiUrl.buildUrl(); - String webpage = requestWebPage(url); - - try { - WrapperMovieCasts wrapper = mapper.readValue(webpage, WrapperMovieCasts.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getAll()); - results.copyWrapper(wrapper); - return results; - } 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 TmdbResultsList getMovieImages(int movieId, String language, String... appendToResponse) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "/images"); - apiUrl.addArgument(PARAM_ID, movieId); - - if (StringUtils.isNotBlank(language)) { - apiUrl.addArgument(PARAM_LANGUAGE, language); - } - - apiUrl.appendToResponse(appendToResponse); - - URL url = apiUrl.buildUrl(); - String webpage = requestWebPage(url); - - try { - WrapperImages wrapper = mapper.readValue(webpage, WrapperImages.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getAll()); - results.copyWrapper(wrapper); - return results; - } 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 TmdbResultsList getMovieKeywords(int movieId, String... appendToResponse) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "/keywords"); - apiUrl.addArgument(PARAM_ID, movieId); - - apiUrl.appendToResponse(appendToResponse); - - URL url = apiUrl.buildUrl(); - String webpage = requestWebPage(url); - - try { - WrapperMovieKeywords wrapper = mapper.readValue(webpage, WrapperMovieKeywords.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getKeywords()); - results.copyWrapper(wrapper); - return results; - } 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 TmdbResultsList getMovieReleaseInfo(int movieId, String language, String... appendToResponse) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "/releases"); - apiUrl.addArgument(PARAM_ID, movieId); - apiUrl.addArgument(PARAM_LANGUAGE, language); - - apiUrl.appendToResponse(appendToResponse); - - URL url = apiUrl.buildUrl(); - String webpage = requestWebPage(url); - - try { - WrapperReleaseInfo wrapper = mapper.readValue(webpage, WrapperReleaseInfo.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getCountries()); - results.copyWrapper(wrapper); - return results; - } 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 TmdbResultsList getMovieTrailers(int movieId, String language, String... appendToResponse) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "/trailers"); - apiUrl.addArgument(PARAM_ID, movieId); - - if (StringUtils.isNotBlank(language)) { - apiUrl.addArgument(PARAM_LANGUAGE, language); - } - - apiUrl.appendToResponse(appendToResponse); - - URL url = apiUrl.buildUrl(); - String webpage = requestWebPage(url); - - try { - WrapperTrailers wrapper = mapper.readValue(webpage, WrapperTrailers.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getAll()); - results.copyWrapper(wrapper); - return results; - } 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 TmdbResultsList getMovieTranslations(int movieId, String... appendToResponse) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "/translations"); - apiUrl.addArgument(PARAM_ID, movieId); - - apiUrl.appendToResponse(appendToResponse); - - URL url = apiUrl.buildUrl(); - String webpage = requestWebPage(url); - - try { - WrapperTranslations wrapper = mapper.readValue(webpage, WrapperTranslations.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getTranslations()); - results.copyWrapper(wrapper); - return results; - } 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 TmdbResultsList getSimilarMovies(int movieId, String language, int page, String... appendToResponse) 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); - } - - apiUrl.appendToResponse(appendToResponse); - - URL url = apiUrl.buildUrl(); - String webpage = requestWebPage(url); - - try { - WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getMovies()); - results.copyWrapper(wrapper); - return results; - } catch (IOException ex) { - LOG.warn("Failed to get similar movies: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - public TmdbResultsList getReviews(int movieId, String language, int page, String... appendToResponse) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "/reviews"); - apiUrl.addArgument(PARAM_ID, movieId); - - if (StringUtils.isNotBlank(language)) { - apiUrl.addArgument(PARAM_LANGUAGE, language); - } - - if (page > 0) { - apiUrl.addArgument(PARAM_PAGE, page); - } - - apiUrl.appendToResponse(appendToResponse); - - URL url = apiUrl.buildUrl(); - String webpage = requestWebPage(url); - - try { - WrapperReviews wrapper = mapper.readValue(webpage, WrapperReviews.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getReviews()); - results.copyWrapper(wrapper); - return results; - } catch (IOException ex) { - LOG.warn("Failed to get reviews: {}", 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 TmdbResultsList getMovieLists(int movieId, String language, int page, String... appendToResponse) 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); - } - - apiUrl.appendToResponse(appendToResponse); - - URL url = apiUrl.buildUrl(); - String webpage = requestWebPage(url); - - try { - WrapperMovieList wrapper = mapper.readValue(webpage, WrapperMovieList.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getMovieList()); - results.copyWrapper(wrapper); - return results; - } 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 - */ - public TmdbResultsMap> 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(PARAM_START_DATE, startDate); - } - - if (StringUtils.isNotBlank(endDate)) { - apiUrl.addArgument(PARAM_END_DATE, endDate); - } - - URL url = apiUrl.buildUrl(); - String webpage = requestWebPage(url); - try { - WrapperChanges wrapper = mapper.readValue(webpage, WrapperChanges.class); - - Map> results = new HashMap>(); - for (ChangeKeyItem changeItem : wrapper.getChangedItems()) { - results.put(changeItem.getKey(), changeItem.getChangedItems()); - } - - return new TmdbResultsMap>(results); - } 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 = requestWebPage(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 TmdbResultsList 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 = requestWebPage(url); - - try { - WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getMovies()); - results.copyWrapper(wrapper); - return results; - } 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 TmdbResultsList 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 = requestWebPage(url); - - try { - WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getMovies()); - results.copyWrapper(wrapper); - return results; - } 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 TmdbResultsList 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 = requestWebPage(url); - - try { - WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getMovies()); - results.copyWrapper(wrapper); - return results; - } 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 TmdbResultsList 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 = requestWebPage(url); - - try { - WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getMovies()); - results.copyWrapper(wrapper); - return results; - } 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 movieId - * @param rating - * @throws MovieDbException - * @throws JsonProcessingException - */ - public boolean postMovieRating(String sessionId, Integer movieId, Integer rating) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, movieId+ "/rating"); - - apiUrl.addArgument(PARAM_SESSION, sessionId); - - if(rating <0 || rating > 10) { - throw new MovieDbException(MovieDbExceptionType.UNKNOWN_CAUSE, "rating out of range"); - } - - String jsonBody; - - // note exception will never be thrown - try { - jsonBody = new ObjectMapper().writeValueAsString(Collections.singletonMap("value", (double) rating)); - } catch (JsonProcessingException ignored) { - throw new RuntimeException(ignored); - } - - URL url = apiUrl.buildUrl(); - String webpage = WebBrowser.request(url, jsonBody); - - return webpage.contains("The item/record was updated successfully"); - } - - // - - // - /** - * 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 = requestWebPage(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 TmdbResultsList getCollectionImages(int collectionId, String language) throws MovieDbException { - 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 = requestWebPage(url); - - try { - WrapperImages wrapper = mapper.readValue(webpage, WrapperImages.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getAll(ArtworkType.POSTER, ArtworkType.BACKDROP)); - results.copyWrapper(wrapper); - return results; - } 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, String... appendToResponse) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(apiKey, BASE_PERSON); - - apiUrl.addArgument(PARAM_ID, personId); - apiUrl.appendToResponse(appendToResponse); - - URL url = apiUrl.buildUrl(); - String webpage = requestWebPage(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 TmdbResultsList getPersonCredits(int personId, String... appendToResponse) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(apiKey, BASE_PERSON, "/credits"); - - apiUrl.addArgument(PARAM_ID, personId); - apiUrl.appendToResponse(appendToResponse); - - URL url = apiUrl.buildUrl(); - String webpage = requestWebPage(url); - - try { - WrapperPersonCredits wrapper = mapper.readValue(webpage, WrapperPersonCredits.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getAll()); - results.copyWrapper(wrapper); - return results; - } 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 TmdbResultsList getPersonImages(int personId) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(apiKey, BASE_PERSON, "/images"); - - apiUrl.addArgument(PARAM_ID, personId); - - URL url = apiUrl.buildUrl(); - String webpage = requestWebPage(url); - - try { - WrapperImages wrapper = mapper.readValue(webpage, WrapperImages.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getAll(ArtworkType.PROFILE)); - results.copyWrapper(wrapper); - return results; - } 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 list of popular people on The Movie Database. - * - * This list refreshes every day. - * - * @return - * @throws MovieDbException - */ - public TmdbResultsList getPersonPopular() throws MovieDbException { - return getPersonPopular(0); - } - - /** - * Get the list of popular people on The Movie Database. - * - * This list refreshes every day. - * - * @param page - * @return - * @throws MovieDbException - */ - public TmdbResultsList getPersonPopular(int page) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(apiKey, BASE_PERSON, "/popular"); - - if (page > 0) { - apiUrl.addArgument(PARAM_PAGE, page); - } - - URL url = apiUrl.buildUrl(); - String webpage = requestWebPage(url); - - try { - WrapperPersonList wrapper = mapper.readValue(webpage, WrapperPersonList.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getPersonList()); - results.copyWrapper(wrapper); - return results; - } catch (IOException ex) { - LOG.warn("Failed to get person images: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - /** - * 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 = requestWebPage(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 = requestWebPage(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 TmdbResultsList 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 = requestWebPage(url); - - try { - WrapperCompanyMovies wrapper = mapper.readValue(webpage, WrapperCompanyMovies.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getResults()); - results.copyWrapper(wrapper); - return results; - } 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 TmdbResultsList getGenreList(String language) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(apiKey, BASE_GENRE, "/list"); - apiUrl.addArgument(PARAM_LANGUAGE, language); - - URL url = apiUrl.buildUrl(); - String webpage = requestWebPage(url); - - try { - WrapperGenres wrapper = mapper.readValue(webpage, WrapperGenres.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getGenres()); - results.copyWrapper(wrapper); - return results; - } catch (IOException ex) { - LOG.warn("Failed to get genre list: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - - /** - * 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 TmdbResultsList 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 = requestWebPage(url); - - try { - WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getMovies()); - results.copyWrapper(wrapper); - return results; - } 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 TmdbResultsList 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 = requestWebPage(url); - try { - WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getMovies()); - results.copyWrapper(wrapper); - return results; - } 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 TmdbResultsList 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 = requestWebPage(url); - try { - WrapperCollection wrapper = mapper.readValue(webpage, WrapperCollection.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getResults()); - results.copyWrapper(wrapper); - return results; - } 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 TmdbResultsList 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 = requestWebPage(url); - - try { - WrapperPerson wrapper = mapper.readValue(webpage, WrapperPerson.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getResults()); - results.copyWrapper(wrapper); - return results; - } 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 TmdbResultsList 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 = requestWebPage(url); - try { - WrapperMovieList wrapper = mapper.readValue(webpage, WrapperMovieList.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getMovieList()); - results.copyWrapper(wrapper); - return results; - } 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 TmdbResultsList 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 = requestWebPage(url); - try { - WrapperCompany wrapper = mapper.readValue(webpage, WrapperCompany.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getResults()); - results.copyWrapper(wrapper); - return results; - } 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 TmdbResultsList 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 = requestWebPage(url); - try { - WrapperKeywords wrapper = mapper.readValue(webpage, WrapperKeywords.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getResults()); - results.copyWrapper(wrapper); - return results; - } 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 = requestWebPage(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 = requestWebPage(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 TmdbResultsList 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 = requestWebPage(url); - - try { - WrapperKeywordMovies wrapper = mapper.readValue(webpage, WrapperKeywordMovies.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getResults()); - results.copyWrapper(wrapper); - return results; - } 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"); - } - // - - // - public TmdbResultsList getJobs() throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(apiKey, BASE_JOB, "/list"); - - URL url = apiUrl.buildUrl(); - String webpage = requestWebPage(url); - - try { - WrapperJobList wrapper = mapper.readValue(webpage, WrapperJobList.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getJobs()); - results.copyWrapper(wrapper); - return results; - } catch (IOException ex) { - LOG.warn("Failed to get job list: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - // - - // - /** - * Discover movies by different types of data like average rating, number of votes, genres and certifications. - * - * You can alternatively create a "discover" object and pass it to this method to cut out the requirement for all of these - * parameters - * - * @param page Minimum value is 1 - * @param language ISO 639-1 code. - * @param sortBy Available options are vote_average.desc, vote_average.asc, release_date.desc, release_date.asc, - * popularity.desc, popularity.asc - * @param includeAdult Toggle the inclusion of adult titles - * @param year Filter the results release dates to matches that include this value - * @param primaryReleaseYear Filter the results so that only the primary release date year has this value - * @param voteCountGte Only include movies that are equal to, or have a vote count higher than this value - * @param voteAverageGte Only include movies that are equal to, or have a higher average rating than this value - * @param withGenres Only include movies with the specified genres. Expected value is an integer (the id of a genre). Multiple - * values can be specified. Comma separated indicates an 'AND' query, while a pipe (|) separated value indicates an 'OR'. - * @param releaseDateGte The minimum release to include. Expected format is YYYY-MM-DD - * @param releaseDateLte The maximum release to include. Expected format is YYYY-MM-DD - * @param certificationCountry Only include movies with certifications for a specific country. When this value is specified, - * 'certificationLte' is required. A ISO 3166-1 is expected. - * @param certificationLte Only include movies with this certification and lower. Expected value is a valid certification for - * the specified 'certificationCountry'. - * @param withCompanies Filter movies to include a specific company. Expected value is an integer (the id of a company). They - * can be comma separated to indicate an 'AND' query. - * @return - * @throws MovieDbException - */ - public TmdbResultsList getDiscover(int page, String language, String sortBy, boolean includeAdult, int year, - int primaryReleaseYear, int voteCountGte, float voteAverageGte, String withGenres, String releaseDateGte, - String releaseDateLte, String certificationCountry, String certificationLte, String withCompanies) throws MovieDbException { - - Discover discover = new Discover(); - discover.page(page) - .language(language) - .sortBy(sortBy) - .includeAdult(includeAdult) - .year(year) - .primaryReleaseYear(primaryReleaseYear) - .voteCountGte(voteCountGte) - .voteAverageGte(voteAverageGte) - .withGenres(withGenres) - .releaseDateGte(releaseDateGte) - .releaseDateLte(releaseDateLte) - .certificationCountry(certificationCountry) - .certificationLte(certificationLte) - .withCompanies(withCompanies); - - return getDiscover(discover); - } - - /** - * Discover movies by different types of data like average rating, number of votes, genres and certifications. - * - * @param discover A discover object containing the search criteria required - * @return - * @throws MovieDbException - */ - public TmdbResultsList getDiscover(Discover discover) throws MovieDbException { - ApiUrl apiUrl = new ApiUrl(apiKey, BASE_DISCOVER, "/movie"); - - apiUrl.setArguments(discover.getParams()); - - URL url = apiUrl.buildUrl(); - String webpage = requestWebPage(url); - - try { - WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); - TmdbResultsList results = new TmdbResultsList(wrapper.getMovies()); - results.copyWrapper(wrapper); - return results; - } catch (IOException ex) { - LOG.warn("Failed to get discover list: {}", ex.getMessage()); - throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); - } - } - // -} +/* + * 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.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.omertron.themoviedbapi.MovieDbException.MovieDbExceptionType; +import com.omertron.themoviedbapi.model.*; +import com.omertron.themoviedbapi.results.TmdbResultsList; +import com.omertron.themoviedbapi.results.TmdbResultsMap; +import com.omertron.themoviedbapi.tools.ApiUrl; +import com.omertron.themoviedbapi.tools.WebBrowser; +import com.omertron.themoviedbapi.wrapper.*; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.client.methods.HttpGet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.yamj.api.common.http.CommonHttpClient; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static com.omertron.themoviedbapi.tools.ApiUrl.*; + +/** + * 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 CommonHttpClient httpClient; + private TmdbConfiguration tmdbConfig; + // API Methods + 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/"; + private static final String BASE_JOB = "job/"; + private static final String BASE_DISCOVER = "discover/"; + // 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, null); + } + + /** + * API for The Movie Db. + * + * @param apiKey + * @param httpClient The httpClient to use for web requests. + * @throws MovieDbException + */ + public TheMovieDbApi(String apiKey, CommonHttpClient httpClient) throws MovieDbException { + this.apiKey = apiKey; + this.httpClient = httpClient; + + ApiUrl apiUrl = new ApiUrl(apiKey, "configuration"); + URL configUrl = apiUrl.buildUrl(); + String webpage = requestWebPage(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; + } + + private String requestWebPage(URL url) throws MovieDbException { + // use HTTP client implementation + if (httpClient != null) { + try { + HttpGet httpGet = new HttpGet(url.toURI()); + httpGet.addHeader("accept", "application/json"); + return httpClient.requestContent(httpGet); + } catch (URISyntaxException ex) { + throw new MovieDbException(MovieDbException.MovieDbExceptionType.CONNECTION_ERROR, null, ex); + } catch (IOException ex) { + throw new MovieDbException(MovieDbException.MovieDbExceptionType.CONNECTION_ERROR, null, ex); + } catch (RuntimeException ex) { + throw new MovieDbException(MovieDbException.MovieDbExceptionType.HTTP_503_ERROR, "Service Unavailable", ex); + } + } + + // use web browser + return WebBrowser.request(url); + } + + /** + * Set the proxy information + * + * @param host + * @param port + * @param username + * @param password + */ + public void setProxy(String host, String port, String username, String password) { + // should be set in HTTP client already + if (httpClient != null) { + return; + } + + 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) { + // should be set in HTTP client already + if (httpClient != null) { + return; + } + + 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 = requestWebPage(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 = requestWebPage(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 = requestWebPage(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); + } + } + + /** + * Get the basic information for an account. You will need to have a valid session id. * + * @throws MovieDbException + */ + public Account getAccount(String sessionId) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_ACCOUNT.replace("/", "")); + + apiUrl.addArgument(PARAM_SESSION, sessionId); + + + URL url = apiUrl.buildUrl(); + String webpage = requestWebPage(url); + + try { + return mapper.readValue(webpage, Account.class); + } catch (IOException ex) { + LOG.warn("Failed to get Session Token: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + + + public List getFavoriteMovies(String sessionId, int accountId) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_ACCOUNT, accountId+ "/favorite_movies"); + apiUrl.addArgument(PARAM_SESSION, sessionId); + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + return mapper.readValue(webpage, WrapperMovie.class).getMovies(); + } catch (IOException ex) { + LOG.warn("Failed to get keyword: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + public StatusCode changeFavoriteStatus(String sessionId, int accountId, Integer movieId, boolean isFavorite) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_ACCOUNT, accountId+ "/favorite"); + + apiUrl.addArgument(PARAM_SESSION, sessionId); + + HashMap body = new HashMap(); + body.put("movie_id", movieId); + body.put("favorite", isFavorite); + String jsonBody = WebBrowser.convertToJson(body); + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url, jsonBody); + + try { + return mapper.readValue(webpage, StatusCode.class); + } catch (IOException ex) { + LOG.warn("Failed to get keyword: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * Add a movie to an account's watch list. + */ + public StatusCode addToWatchList(String sessionId, int accountId, Integer movieId) throws MovieDbException { + return modifyWatchList(sessionId, accountId, movieId, true); + } + + /** + * Remove a movie from an account's watch list. + */ + public StatusCode removeFromWatchList(String sessionId, int accountId, Integer movieId) throws MovieDbException { + return modifyWatchList(sessionId, accountId, movieId, false); + } + + private StatusCode modifyWatchList(String sessionId, int accountId, Integer movieId, boolean add) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_ACCOUNT, accountId+ "/movie_watchlist"); + + apiUrl.addArgument(PARAM_SESSION, sessionId); + + HashMap body = new HashMap(); + body.put("movie_id", movieId); + body.put("movie_watchlist", add); + String jsonBody = WebBrowser.convertToJson(body); + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url, jsonBody); + + try { + return mapper.readValue(webpage, StatusCode.class); + } catch (IOException ex) { + LOG.warn("Failed to get keyword: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + // + // No account functions + // + // + // + /** + * 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 = requestWebPage(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, String... appendToResponse) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE); + + apiUrl.addArgument(PARAM_ID, imdbId); + + if (StringUtils.isNotBlank(language)) { + apiUrl.addArgument(PARAM_LANGUAGE, language); + } + + apiUrl.appendToResponse(appendToResponse); + + URL url = apiUrl.buildUrl(); + String webpage = requestWebPage(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 TmdbResultsList getMovieAlternativeTitles(int movieId, String country, String... appendToResponse) 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); + } + + apiUrl.appendToResponse(appendToResponse); + + URL url = apiUrl.buildUrl(); + String webpage = requestWebPage(url); + try { + WrapperAlternativeTitles wrapper = mapper.readValue(webpage, WrapperAlternativeTitles.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getTitles()); + results.copyWrapper(wrapper); + return results; + } 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 TmdbResultsList getMovieCasts(int movieId, String... appendToResponse) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "/casts"); + apiUrl.addArgument(PARAM_ID, movieId); + + apiUrl.appendToResponse(appendToResponse); + + URL url = apiUrl.buildUrl(); + String webpage = requestWebPage(url); + + try { + WrapperMovieCasts wrapper = mapper.readValue(webpage, WrapperMovieCasts.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getAll()); + results.copyWrapper(wrapper); + return results; + } 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 TmdbResultsList getMovieImages(int movieId, String language, String... appendToResponse) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "/images"); + apiUrl.addArgument(PARAM_ID, movieId); + + if (StringUtils.isNotBlank(language)) { + apiUrl.addArgument(PARAM_LANGUAGE, language); + } + + apiUrl.appendToResponse(appendToResponse); + + URL url = apiUrl.buildUrl(); + String webpage = requestWebPage(url); + + try { + WrapperImages wrapper = mapper.readValue(webpage, WrapperImages.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getAll()); + results.copyWrapper(wrapper); + return results; + } 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 TmdbResultsList getMovieKeywords(int movieId, String... appendToResponse) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "/keywords"); + apiUrl.addArgument(PARAM_ID, movieId); + + apiUrl.appendToResponse(appendToResponse); + + URL url = apiUrl.buildUrl(); + String webpage = requestWebPage(url); + + try { + WrapperMovieKeywords wrapper = mapper.readValue(webpage, WrapperMovieKeywords.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getKeywords()); + results.copyWrapper(wrapper); + return results; + } 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 TmdbResultsList getMovieReleaseInfo(int movieId, String language, String... appendToResponse) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "/releases"); + apiUrl.addArgument(PARAM_ID, movieId); + apiUrl.addArgument(PARAM_LANGUAGE, language); + + apiUrl.appendToResponse(appendToResponse); + + URL url = apiUrl.buildUrl(); + String webpage = requestWebPage(url); + + try { + WrapperReleaseInfo wrapper = mapper.readValue(webpage, WrapperReleaseInfo.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getCountries()); + results.copyWrapper(wrapper); + return results; + } 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 TmdbResultsList getMovieTrailers(int movieId, String language, String... appendToResponse) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "/trailers"); + apiUrl.addArgument(PARAM_ID, movieId); + + if (StringUtils.isNotBlank(language)) { + apiUrl.addArgument(PARAM_LANGUAGE, language); + } + + apiUrl.appendToResponse(appendToResponse); + + URL url = apiUrl.buildUrl(); + String webpage = requestWebPage(url); + + try { + WrapperTrailers wrapper = mapper.readValue(webpage, WrapperTrailers.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getAll()); + results.copyWrapper(wrapper); + return results; + } 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 TmdbResultsList getMovieTranslations(int movieId, String... appendToResponse) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "/translations"); + apiUrl.addArgument(PARAM_ID, movieId); + + apiUrl.appendToResponse(appendToResponse); + + URL url = apiUrl.buildUrl(); + String webpage = requestWebPage(url); + + try { + WrapperTranslations wrapper = mapper.readValue(webpage, WrapperTranslations.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getTranslations()); + results.copyWrapper(wrapper); + return results; + } 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 TmdbResultsList getSimilarMovies(int movieId, String language, int page, String... appendToResponse) 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); + } + + apiUrl.appendToResponse(appendToResponse); + + URL url = apiUrl.buildUrl(); + String webpage = requestWebPage(url); + + try { + WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getMovies()); + results.copyWrapper(wrapper); + return results; + } catch (IOException ex) { + LOG.warn("Failed to get similar movies: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + public TmdbResultsList getReviews(int movieId, String language, int page, String... appendToResponse) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, "/reviews"); + apiUrl.addArgument(PARAM_ID, movieId); + + if (StringUtils.isNotBlank(language)) { + apiUrl.addArgument(PARAM_LANGUAGE, language); + } + + if (page > 0) { + apiUrl.addArgument(PARAM_PAGE, page); + } + + apiUrl.appendToResponse(appendToResponse); + + URL url = apiUrl.buildUrl(); + String webpage = requestWebPage(url); + + try { + WrapperReviews wrapper = mapper.readValue(webpage, WrapperReviews.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getReviews()); + results.copyWrapper(wrapper); + return results; + } catch (IOException ex) { + LOG.warn("Failed to get reviews: {}", 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 TmdbResultsList getMovieLists(int movieId, String language, int page, String... appendToResponse) 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); + } + + apiUrl.appendToResponse(appendToResponse); + + URL url = apiUrl.buildUrl(); + String webpage = requestWebPage(url); + + try { + WrapperMovieList wrapper = mapper.readValue(webpage, WrapperMovieList.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getMovieList()); + results.copyWrapper(wrapper); + return results; + } 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 + */ + public TmdbResultsMap> 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(PARAM_START_DATE, startDate); + } + + if (StringUtils.isNotBlank(endDate)) { + apiUrl.addArgument(PARAM_END_DATE, endDate); + } + + URL url = apiUrl.buildUrl(); + String webpage = requestWebPage(url); + try { + WrapperChanges wrapper = mapper.readValue(webpage, WrapperChanges.class); + + Map> results = new HashMap>(); + for (ChangeKeyItem changeItem : wrapper.getChangedItems()) { + results.put(changeItem.getKey(), changeItem.getChangedItems()); + } + + return new TmdbResultsMap>(results); + } 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 = requestWebPage(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 TmdbResultsList 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 = requestWebPage(url); + + try { + WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getMovies()); + results.copyWrapper(wrapper); + return results; + } 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 TmdbResultsList 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 = requestWebPage(url); + + try { + WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getMovies()); + results.copyWrapper(wrapper); + return results; + } 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 TmdbResultsList 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 = requestWebPage(url); + + try { + WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getMovies()); + results.copyWrapper(wrapper); + return results; + } 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 TmdbResultsList 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 = requestWebPage(url); + + try { + WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getMovies()); + results.copyWrapper(wrapper); + return results; + } catch (IOException ex) { + LOG.warn("Failed to get top rated movies: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + public List getRatedMovies(String sessionId, int accountId) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_ACCOUNT, accountId+ "/rated_movies"); + apiUrl.addArgument(PARAM_SESSION, sessionId); + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + return mapper.readValue(webpage, WrapperMovie.class).getMovies(); + } catch (IOException ex) { + LOG.warn("Failed to get keyword: {}", 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 movieId + * @param rating + * @throws MovieDbException + * @throws JsonProcessingException + */ + public boolean postMovieRating(String sessionId, Integer movieId, Integer rating) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_MOVIE, movieId+ "/rating"); + + apiUrl.addArgument(PARAM_SESSION, sessionId); + + if(rating <0 || rating > 10) { + throw new MovieDbException(MovieDbExceptionType.UNKNOWN_CAUSE, "rating out of range"); + } + + String jsonBody = WebBrowser.convertToJson(Collections.singletonMap("value", rating)); + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url, jsonBody); + + try { + return mapper.readValue(webpage, StatusCode.class).getStatusCode()==12; + } catch (IOException ex) { + LOG.warn("Failed to get keyword: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + // + + // + /** + * 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 = requestWebPage(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 TmdbResultsList getCollectionImages(int collectionId, String language) throws MovieDbException { + 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 = requestWebPage(url); + + try { + WrapperImages wrapper = mapper.readValue(webpage, WrapperImages.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getAll(ArtworkType.POSTER, ArtworkType.BACKDROP)); + results.copyWrapper(wrapper); + return results; + } 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, String... appendToResponse) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_PERSON); + + apiUrl.addArgument(PARAM_ID, personId); + apiUrl.appendToResponse(appendToResponse); + + URL url = apiUrl.buildUrl(); + String webpage = requestWebPage(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 TmdbResultsList getPersonCredits(int personId, String... appendToResponse) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_PERSON, "/credits"); + + apiUrl.addArgument(PARAM_ID, personId); + apiUrl.appendToResponse(appendToResponse); + + URL url = apiUrl.buildUrl(); + String webpage = requestWebPage(url); + + try { + WrapperPersonCredits wrapper = mapper.readValue(webpage, WrapperPersonCredits.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getAll()); + results.copyWrapper(wrapper); + return results; + } 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 TmdbResultsList getPersonImages(int personId) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_PERSON, "/images"); + + apiUrl.addArgument(PARAM_ID, personId); + + URL url = apiUrl.buildUrl(); + String webpage = requestWebPage(url); + + try { + WrapperImages wrapper = mapper.readValue(webpage, WrapperImages.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getAll(ArtworkType.PROFILE)); + results.copyWrapper(wrapper); + return results; + } 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 list of popular people on The Movie Database. + * + * This list refreshes every day. + * + * @return + * @throws MovieDbException + */ + public TmdbResultsList getPersonPopular() throws MovieDbException { + return getPersonPopular(0); + } + + /** + * Get the list of popular people on The Movie Database. + * + * This list refreshes every day. + * + * @param page + * @return + * @throws MovieDbException + */ + public TmdbResultsList getPersonPopular(int page) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_PERSON, "/popular"); + + if (page > 0) { + apiUrl.addArgument(PARAM_PAGE, page); + } + + URL url = apiUrl.buildUrl(); + String webpage = requestWebPage(url); + + try { + WrapperPersonList wrapper = mapper.readValue(webpage, WrapperPersonList.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getPersonList()); + results.copyWrapper(wrapper); + return results; + } catch (IOException ex) { + LOG.warn("Failed to get person images: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * 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 = requestWebPage(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 = requestWebPage(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 TmdbResultsList 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 = requestWebPage(url); + + try { + WrapperCompanyMovies wrapper = mapper.readValue(webpage, WrapperCompanyMovies.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getResults()); + results.copyWrapper(wrapper); + return results; + } 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 TmdbResultsList getGenreList(String language) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_GENRE, "/list"); + apiUrl.addArgument(PARAM_LANGUAGE, language); + + URL url = apiUrl.buildUrl(); + String webpage = requestWebPage(url); + + try { + WrapperGenres wrapper = mapper.readValue(webpage, WrapperGenres.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getGenres()); + results.copyWrapper(wrapper); + return results; + } catch (IOException ex) { + LOG.warn("Failed to get genre list: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * 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 TmdbResultsList 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 = requestWebPage(url); + + try { + WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getMovies()); + results.copyWrapper(wrapper); + return results; + } 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 TmdbResultsList 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 = requestWebPage(url); + try { + WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getMovies()); + results.copyWrapper(wrapper); + return results; + } 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 TmdbResultsList 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 = requestWebPage(url); + try { + WrapperCollection wrapper = mapper.readValue(webpage, WrapperCollection.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getResults()); + results.copyWrapper(wrapper); + return results; + } 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 TmdbResultsList 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 = requestWebPage(url); + + try { + WrapperPerson wrapper = mapper.readValue(webpage, WrapperPerson.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getResults()); + results.copyWrapper(wrapper); + return results; + } 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 TmdbResultsList 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 = requestWebPage(url); + try { + WrapperMovieList wrapper = mapper.readValue(webpage, WrapperMovieList.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getMovieList()); + results.copyWrapper(wrapper); + return results; + } 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 TmdbResultsList 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 = requestWebPage(url); + try { + WrapperCompany wrapper = mapper.readValue(webpage, WrapperCompany.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getResults()); + results.copyWrapper(wrapper); + return results; + } 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 TmdbResultsList 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 = requestWebPage(url); + try { + WrapperKeywords wrapper = mapper.readValue(webpage, WrapperKeywords.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getResults()); + results.copyWrapper(wrapper); + return results; + } 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 = requestWebPage(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 all lists of a given user + * + * @return The lists + * @throws MovieDbException + */ + public List getUserLists(String sessionId, int accountID) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_ACCOUNT, accountID +"/lists"); + apiUrl.addArgument(PARAM_SESSION, sessionId); + + URL url = apiUrl.buildUrl(); + String webpage = requestWebPage(url); + + try { + return mapper.readValue(webpage, WrapperMovieDbList.class).getLists(); + } catch (IOException ex) { + LOG.warn("Failed to get lists: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + + /** + * This method lets users create a new list. A valid session id is required. + * + * @return The list id + * @throws MovieDbException + */ + public String createList(String sessionId, String name, String description) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, "list"); + apiUrl.addArgument(PARAM_SESSION, sessionId); + + HashMap body = new HashMap(); + body.put("name", StringUtils.trimToEmpty(name)); + body.put("description", StringUtils.trimToEmpty(description)); + + String jsonBody = WebBrowser.convertToJson(body); + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url, jsonBody); + + + try { + return mapper.readValue(webpage, MovieDbListStatus.class).getListId(); + } catch (IOException ex) { + LOG.warn("Failed to get keyword: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * Check to see if a movie ID is already added to a list. + * + * @return true if the movie is on the list + * @throws MovieDbException + */ + public boolean isMovieOnList(String listId, Integer movieId) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_LIST, listId+"/item_status"); + apiUrl.addArgument("movie_id", movieId); + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + return mapper.readValue(webpage, ListItemStatus.class).isItemPresent(); + } catch (IOException ex) { + LOG.warn("Failed to get keyword: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + + /** + * This method lets users add new movies to a list that they created. A valid session id is required. + * + * @return true if the movie is on the list + * @throws MovieDbException + */ + public StatusCode addMovieToList(String sessionId, String listId, Integer movieId) throws MovieDbException { + return modifyMovieList(sessionId, listId, movieId, "/add_item"); + } + + /** + * This method lets users remove movies from a list that they created. A valid session id is required. + * + * @return true if the movie is on the list + * @throws MovieDbException + */ + public StatusCode removeMovieFromList(String sessionId, String listId, Integer movieId) throws MovieDbException { + return modifyMovieList(sessionId, listId, movieId, "/remove_item"); + } + + private StatusCode modifyMovieList(String sessionId, String listId, Integer movieId, String operation) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_LIST, listId+ operation); + + apiUrl.addArgument(PARAM_SESSION, sessionId); + + String jsonBody = WebBrowser.convertToJson(Collections.singletonMap("media_id", movieId + "")); + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url, jsonBody); + + try { + return mapper.readValue(webpage, StatusCode.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 on an accounts watchlist. + * + * @return The watchlist of the user + * @throws MovieDbException + */ + public List getWatchList(String sessionId, int accountId) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_ACCOUNT, accountId+ "/movie_watchlist"); + apiUrl.addArgument(PARAM_SESSION, sessionId); + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url); + + try { + return mapper.readValue(webpage, WrapperMovie.class).getMovies(); + } catch (IOException ex) { + LOG.warn("Failed to get keyword: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + + /** + * This method lets users delete a list that they created. A valid session id is required. + * @throws MovieDbException + */ + public StatusCode deleteMovieList(String sessionId, String listId) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_LIST, listId); + + apiUrl.addArgument(PARAM_SESSION, sessionId); + + URL url = apiUrl.buildUrl(); + String webpage = WebBrowser.request(url, null, true); + + + try { + return mapper.readValue(webpage, StatusCode.class); + } catch (IOException ex) { + LOG.warn("Failed to get keyword: {}", 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 = requestWebPage(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 TmdbResultsList 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 = requestWebPage(url); + + try { + WrapperKeywordMovies wrapper = mapper.readValue(webpage, WrapperKeywordMovies.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getResults()); + results.copyWrapper(wrapper); + return results; + } 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"); + } + // + + // + public TmdbResultsList getJobs() throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_JOB, "/list"); + + URL url = apiUrl.buildUrl(); + String webpage = requestWebPage(url); + + try { + WrapperJobList wrapper = mapper.readValue(webpage, WrapperJobList.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getJobs()); + results.copyWrapper(wrapper); + return results; + } catch (IOException ex) { + LOG.warn("Failed to get job list: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + // + + // + /** + * Discover movies by different types of data like average rating, number of votes, genres and certifications. + * + * You can alternatively create a "discover" object and pass it to this method to cut out the requirement for all of these + * parameters + * + * @param page Minimum value is 1 + * @param language ISO 639-1 code. + * @param sortBy Available options are vote_average.desc, vote_average.asc, release_date.desc, release_date.asc, + * popularity.desc, popularity.asc + * @param includeAdult Toggle the inclusion of adult titles + * @param year Filter the results release dates to matches that include this value + * @param primaryReleaseYear Filter the results so that only the primary release date year has this value + * @param voteCountGte Only include movies that are equal to, or have a vote count higher than this value + * @param voteAverageGte Only include movies that are equal to, or have a higher average rating than this value + * @param withGenres Only include movies with the specified genres. Expected value is an integer (the id of a genre). Multiple + * values can be specified. Comma separated indicates an 'AND' query, while a pipe (|) separated value indicates an 'OR'. + * @param releaseDateGte The minimum release to include. Expected format is YYYY-MM-DD + * @param releaseDateLte The maximum release to include. Expected format is YYYY-MM-DD + * @param certificationCountry Only include movies with certifications for a specific country. When this value is specified, + * 'certificationLte' is required. A ISO 3166-1 is expected. + * @param certificationLte Only include movies with this certification and lower. Expected value is a valid certification for + * the specified 'certificationCountry'. + * @param withCompanies Filter movies to include a specific company. Expected value is an integer (the id of a company). They + * can be comma separated to indicate an 'AND' query. + * @return + * @throws MovieDbException + */ + public TmdbResultsList getDiscover(int page, String language, String sortBy, boolean includeAdult, int year, + int primaryReleaseYear, int voteCountGte, float voteAverageGte, String withGenres, String releaseDateGte, + String releaseDateLte, String certificationCountry, String certificationLte, String withCompanies) throws MovieDbException { + + Discover discover = new Discover(); + discover.page(page) + .language(language) + .sortBy(sortBy) + .includeAdult(includeAdult) + .year(year) + .primaryReleaseYear(primaryReleaseYear) + .voteCountGte(voteCountGte) + .voteAverageGte(voteAverageGte) + .withGenres(withGenres) + .releaseDateGte(releaseDateGte) + .releaseDateLte(releaseDateLte) + .certificationCountry(certificationCountry) + .certificationLte(certificationLte) + .withCompanies(withCompanies); + + return getDiscover(discover); + } + + /** + * Discover movies by different types of data like average rating, number of votes, genres and certifications. + * + * @param discover A discover object containing the search criteria required + * @return + * @throws MovieDbException + */ + public TmdbResultsList getDiscover(Discover discover) throws MovieDbException { + ApiUrl apiUrl = new ApiUrl(apiKey, BASE_DISCOVER, "/movie"); + + apiUrl.setArguments(discover.getParams()); + + URL url = apiUrl.buildUrl(); + String webpage = requestWebPage(url); + + try { + WrapperMovie wrapper = mapper.readValue(webpage, WrapperMovie.class); + TmdbResultsList results = new TmdbResultsList(wrapper.getMovies()); + results.copyWrapper(wrapper); + return results; + } catch (IOException ex) { + LOG.warn("Failed to get discover list: {}", ex.getMessage()); + throw new MovieDbException(MovieDbExceptionType.MAPPING_FAILED, webpage, ex); + } + } + // +} diff --git a/src/main/java/com/omertron/themoviedbapi/model/AbstractJsonMapping.java b/src/main/java/com/omertron/themoviedbapi/model/AbstractJsonMapping.java new file mode 100644 index 000000000..dda797465 --- /dev/null +++ b/src/main/java/com/omertron/themoviedbapi/model/AbstractJsonMapping.java @@ -0,0 +1,58 @@ +/* + * 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;private either version 3 of the License;private or + * any later version. + * + * TheMovieDB API is distributed in the hope that it will be useful;private + * 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;private see . + * + */ +package com.omertron.themoviedbapi.model; + +import com.fasterxml.jackson.annotation.JsonAnySetter; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.Serializable; + +/** + * @author Holger Brandl + */ +public abstract class AbstractJsonMapping implements Serializable { + + private static Logger getLogger(Class aClass) { + return LoggerFactory.getLogger(aClass); + } + + /** + * 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("'"); + + getLogger(this.getClass()).warn(sb.toString()); + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.SIMPLE_STYLE); + } +} diff --git a/src/main/java/com/omertron/themoviedbapi/model/Account.java b/src/main/java/com/omertron/themoviedbapi/model/Account.java new file mode 100644 index 000000000..fb4519296 --- /dev/null +++ b/src/main/java/com/omertron/themoviedbapi/model/Account.java @@ -0,0 +1,66 @@ +/* + * 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;private either version 3 of the License;private or + * any later version. + * + * TheMovieDB API is distributed in the hope that it will be useful;private + * 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;private see . + * + */ +package com.omertron.themoviedbapi.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class Account extends AbstractJsonMapping { + + @JsonProperty("id") + private int id; + @JsonProperty("name") + private String name; + @JsonProperty("username") + private String userName; + @JsonProperty("include_adult") + private boolean includeAdult; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public boolean isIncludeAdult() { + return includeAdult; + } + + public void setIncludeAdult(boolean includeAdult) { + this.includeAdult = includeAdult; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } +} diff --git a/src/main/java/com/omertron/themoviedbapi/model/AlternativeTitle.java b/src/main/java/com/omertron/themoviedbapi/model/AlternativeTitle.java index e47f2a6fb..65b98d13f 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/AlternativeTitle.java +++ b/src/main/java/com/omertron/themoviedbapi/model/AlternativeTitle.java @@ -19,16 +19,13 @@ */ package com.omertron.themoviedbapi.model; -import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonProperty; -import java.io.Serializable; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.Serializable; + /** - * * @author Stuart */ public class AlternativeTitle implements Serializable { @@ -67,20 +64,6 @@ public class AlternativeTitle implements Serializable { } // - /** - * 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) { @@ -106,9 +89,4 @@ public class AlternativeTitle implements Serializable { hash = 89 * hash + (this.title != null ? this.title.hashCode() : 0); return hash; } - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } } diff --git a/src/main/java/com/omertron/themoviedbapi/model/Artwork.java b/src/main/java/com/omertron/themoviedbapi/model/Artwork.java index cebb053ad..8aababbf3 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/Artwork.java +++ b/src/main/java/com/omertron/themoviedbapi/model/Artwork.java @@ -19,11 +19,7 @@ */ package com.omertron.themoviedbapi.model; -import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonProperty; -import java.io.Serializable; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,7 +28,7 @@ import org.slf4j.LoggerFactory; * * @author Stuart */ -public class Artwork implements Serializable { +public class Artwork extends AbstractJsonMapping { private static final long serialVersionUID = 1L; @@ -97,7 +93,6 @@ public class Artwork implements Serializable { public String getFlag() { return flag; } - // // @@ -133,26 +128,11 @@ public class Artwork implements Serializable { this.voteCount = voteCount; } - public void setFlag(String flag) { + public void setFlag(String flag) { this.flag = flag; } - // - /** - * 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) { @@ -194,9 +174,4 @@ public class Artwork implements Serializable { hash = 71 * hash + (this.artworkType != null ? this.artworkType.hashCode() : 0); return hash; } - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } } diff --git a/src/main/java/com/omertron/themoviedbapi/model/ChangeKeyItem.java b/src/main/java/com/omertron/themoviedbapi/model/ChangeKeyItem.java index d13b741f7..face5802a 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/ChangeKeyItem.java +++ b/src/main/java/com/omertron/themoviedbapi/model/ChangeKeyItem.java @@ -1,14 +1,13 @@ package com.omertron.themoviedbapi.model; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonProperty; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import com.fasterxml.jackson.annotation.JsonAnyGetter; -import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.fasterxml.jackson.annotation.JsonProperty; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; public class ChangeKeyItem { @@ -44,9 +43,4 @@ public class ChangeKeyItem { public void setNewItems(String name, Object value) { this.newItems.put(name, value); } - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } } diff --git a/src/main/java/com/omertron/themoviedbapi/model/ChangedItem.java b/src/main/java/com/omertron/themoviedbapi/model/ChangedItem.java index 329651cdb..9c57c359f 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/ChangedItem.java +++ b/src/main/java/com/omertron/themoviedbapi/model/ChangedItem.java @@ -1,14 +1,13 @@ package com.omertron.themoviedbapi.model; -import java.util.HashMap; -import java.util.Map; import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonProperty; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -public class ChangedItem { +import java.util.HashMap; +import java.util.Map; + +public class ChangedItem extends AbstractJsonMapping { private static final long serialVersionUID = 1L; @JsonProperty("id") @@ -72,9 +71,4 @@ public class ChangedItem { public void setNewItems(String name, Object value) { this.newItems.put(name, value); } - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } } diff --git a/src/main/java/com/omertron/themoviedbapi/model/Collection.java b/src/main/java/com/omertron/themoviedbapi/model/Collection.java index 5f157059c..91a97389c 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/Collection.java +++ b/src/main/java/com/omertron/themoviedbapi/model/Collection.java @@ -19,28 +19,18 @@ */ package com.omertron.themoviedbapi.model; -import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonRootName; -import java.io.Serializable; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** - * * @author stuart.boston */ @JsonRootName("collection") -public class Collection implements Serializable { +public class Collection extends AbstractJsonMapping { private static final long serialVersionUID = 1L; - /* - * Logger - */ - private static final Logger LOG = LoggerFactory.getLogger(Collection.class); + /* * Properties */ @@ -87,9 +77,7 @@ public class Collection implements Serializable { } return name; } - // - // public void setBackdropPath(String backdropPath) { this.backdropPath = backdropPath; } @@ -113,21 +101,6 @@ public class Collection implements Serializable { public void setName(String name) { this.name = name; } - // - - /** - * 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) { @@ -164,9 +137,4 @@ public class Collection implements Serializable { hash = 19 * hash + (this.releaseDate != null ? this.releaseDate.hashCode() : 0); return hash; } - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } } diff --git a/src/main/java/com/omertron/themoviedbapi/model/CollectionInfo.java b/src/main/java/com/omertron/themoviedbapi/model/CollectionInfo.java index 8d5140edf..9d4f296b4 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/CollectionInfo.java +++ b/src/main/java/com/omertron/themoviedbapi/model/CollectionInfo.java @@ -19,27 +19,18 @@ */ package com.omertron.themoviedbapi.model; -import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonProperty; -import java.io.Serializable; + import java.util.ArrayList; import java.util.List; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** - * * @author Stuart */ -public class CollectionInfo implements Serializable { +public class CollectionInfo extends AbstractJsonMapping { private static final long serialVersionUID = 1L; - /* - * Logger - */ - private static final Logger LOG = LoggerFactory.getLogger(CollectionInfo.class); + /* * Properties */ @@ -80,9 +71,7 @@ public class CollectionInfo implements Serializable { public String getPosterPath() { return posterPath; } - // - // public void setBackdropPath(String backdropPath) { this.backdropPath = backdropPath; } @@ -106,24 +95,4 @@ public class CollectionInfo implements Serializable { public void setPosterPath(String posterPath) { this.posterPath = posterPath; } - // - - /** - * 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 String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } } diff --git a/src/main/java/com/omertron/themoviedbapi/model/Company.java b/src/main/java/com/omertron/themoviedbapi/model/Company.java index afbb3a504..01eda6db2 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/Company.java +++ b/src/main/java/com/omertron/themoviedbapi/model/Company.java @@ -19,24 +19,16 @@ */ package com.omertron.themoviedbapi.model; -import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonProperty; -import java.io.Serializable; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Company information * * @author Stuart */ -public class Company implements Serializable { +public class Company extends AbstractJsonMapping { private static final long serialVersionUID = 1L; - // Logger - private static final Logger LOG = LoggerFactory.getLogger(Company.class); private static final String DEFAULT_STRING = ""; // Properties @JsonProperty("id") @@ -82,9 +74,7 @@ public class Company implements Serializable { public Company getParentCompany() { return parentCompany; } - // - // public void setCompanyId(int companyId) { this.companyId = companyId; } @@ -120,24 +110,4 @@ public class Company implements Serializable { parent.setLogoPath(logoPath); this.parentCompany = parent; } - // - - /** - * 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 String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } } diff --git a/src/main/java/com/omertron/themoviedbapi/model/Discover.java b/src/main/java/com/omertron/themoviedbapi/model/Discover.java index f803afb51..71e8efdc3 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/Discover.java +++ b/src/main/java/com/omertron/themoviedbapi/model/Discover.java @@ -19,14 +19,16 @@ */ package com.omertron.themoviedbapi.model; +import org.apache.commons.lang3.StringUtils; + import java.util.HashMap; import java.util.Map; + import static com.omertron.themoviedbapi.tools.ApiUrl.*; -import org.apache.commons.lang3.StringUtils; /** * Generate a discover object for use in the MovieDbApi - * + *

* This allows you to just add the search components you are concerned with * * @author stuart.boston @@ -49,7 +51,7 @@ public class Discover { /** * Get the parameters - * + *

* This will be used to construct the URL in the API * * @return @@ -160,11 +162,11 @@ public class Discover { /** * Only include movies with the specified genres. - * + *

* Expected value is an integer (the id of a genre). - * + *

* Multiple values can be specified. - * + *

* Comma separated indicates an 'AND' query, while a pipe (|) separated value indicates an 'OR' * * @param withGenres @@ -178,7 +180,7 @@ public class Discover { /** * The minimum release to include. - * + *

* Expected format is YYYY-MM-DD. * * @param releaseDateGte @@ -192,7 +194,7 @@ public class Discover { /** * The maximum release to include. - * + *

* Expected format is YYYY-MM-DD. * * @param releaseDateLte @@ -206,9 +208,9 @@ public class Discover { /** * Only include movies with certifications for a specific country. - * + *

* When this value is specified, 'certificationLte' is required. - * + *

* A ISO 3166-1 is expected * * @param certificationCountry @@ -222,7 +224,7 @@ public class Discover { /** * Only include movies with this certification and lower. - * + *

* Expected value is a valid certification for the specified 'certificationCountry'. * * @param certificationLte @@ -236,9 +238,9 @@ public class Discover { /** * Filter movies to include a specific company. - * + *

* Expected value is an integer (the id of a company). - * + *

* They can be comma separated to indicate an 'AND' query * * @param withCompanies diff --git a/src/main/java/com/omertron/themoviedbapi/model/Genre.java b/src/main/java/com/omertron/themoviedbapi/model/Genre.java index 2d7cff0ee..4c21ebb63 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/Genre.java +++ b/src/main/java/com/omertron/themoviedbapi/model/Genre.java @@ -19,27 +19,16 @@ */ package com.omertron.themoviedbapi.model; -import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonRootName; -import java.io.Serializable; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** - * * @author stuart.boston */ @JsonRootName("genre") -public class Genre implements Serializable { +public class Genre extends AbstractJsonMapping { private static final long serialVersionUID = 1L; - /* - * Logger - */ - private static final Logger LOG = LoggerFactory.getLogger(Genre.class); /* * Properties */ @@ -56,9 +45,7 @@ public class Genre implements Serializable { public String getName() { return name; } - // - // public void setId(int id) { this.id = id; } @@ -66,21 +53,6 @@ public class Genre implements Serializable { public void setName(String name) { this.name = name; } - // - - /** - * 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) { @@ -107,9 +79,4 @@ public class Genre implements Serializable { hash = 53 * hash + (this.name != null ? this.name.hashCode() : 0); return hash; } - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } } diff --git a/src/main/java/com/omertron/themoviedbapi/model/JobDepartment.java b/src/main/java/com/omertron/themoviedbapi/model/JobDepartment.java index a340d92c2..1292d4c05 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/JobDepartment.java +++ b/src/main/java/com/omertron/themoviedbapi/model/JobDepartment.java @@ -19,19 +19,13 @@ */ package com.omertron.themoviedbapi.model; -import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonProperty; + import java.util.List; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public class JobDepartment { private static final long serialVersionUID = 1L; - // Logger - private static final Logger LOG = LoggerFactory.getLogger(JobDepartment.class); // Properties @JsonProperty("department") private String department; @@ -46,7 +40,6 @@ public class JobDepartment { public List getJobs() { return jobs; } - // // public void setDepartment(String department) { @@ -56,24 +49,4 @@ public class JobDepartment { public void setJobs(List jobs) { this.jobs = jobs; } - // - - /** - * 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 String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } } diff --git a/src/main/java/com/omertron/themoviedbapi/model/Keyword.java b/src/main/java/com/omertron/themoviedbapi/model/Keyword.java index 65011c7fb..34711cbea 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/Keyword.java +++ b/src/main/java/com/omertron/themoviedbapi/model/Keyword.java @@ -19,28 +19,17 @@ */ package com.omertron.themoviedbapi.model; -import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonRootName; -import java.io.Serializable; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** - * * @author stuart.boston */ @JsonRootName("keyword") -public class Keyword implements Serializable { +public class Keyword extends AbstractJsonMapping { private static final long serialVersionUID = 1L; - /* - * Logger - */ - private static final Logger LOG = LoggerFactory.getLogger(Keyword.class); /* * Properties */ @@ -57,9 +46,7 @@ public class Keyword implements Serializable { public String getName() { return name; } - // - // public void setId(int id) { this.id = id; } @@ -67,21 +54,6 @@ public class Keyword implements Serializable { public void setName(String name) { this.name = name; } - // - - /** - * 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) { @@ -108,9 +80,4 @@ public class Keyword implements Serializable { hash = 83 * hash + (this.name != null ? this.name.hashCode() : 0); return hash; } - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } } diff --git a/src/main/java/com/omertron/themoviedbapi/model/KeywordMovie.java b/src/main/java/com/omertron/themoviedbapi/model/KeywordMovie.java index c4c1d13d0..3730d2d5d 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/KeywordMovie.java +++ b/src/main/java/com/omertron/themoviedbapi/model/KeywordMovie.java @@ -19,26 +19,15 @@ */ package com.omertron.themoviedbapi.model; -import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonProperty; -import java.io.Serializable; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** - * * @author Stuart */ -public class KeywordMovie implements Serializable { +public class KeywordMovie extends AbstractJsonMapping { private static final long serialVersionUID = 1L; - /* - * Logger - */ - private static final Logger LOG = LoggerFactory.getLogger(KeywordMovie.class); /* * Properties */ @@ -150,23 +139,4 @@ public class KeywordMovie implements Serializable { this.popularity = popularity; } // - - /** - * 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 String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } } diff --git a/src/main/java/com/omertron/themoviedbapi/model/Language.java b/src/main/java/com/omertron/themoviedbapi/model/Language.java index 738b5a16f..326e2b559 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/Language.java +++ b/src/main/java/com/omertron/themoviedbapi/model/Language.java @@ -19,27 +19,16 @@ */ package com.omertron.themoviedbapi.model; -import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonRootName; -import java.io.Serializable; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** - * * @author stuart.boston */ @JsonRootName("spoken_language") -public class Language implements Serializable { +public class Language extends AbstractJsonMapping { private static final long serialVersionUID = 1L; - /* - * Logger - */ - private static final Logger LOG = LoggerFactory.getLogger(Language.class); /* * Properties */ @@ -56,9 +45,7 @@ public class Language implements Serializable { public String getName() { return name; } - // - // public void setIsoCode(String isoCode) { this.isoCode = isoCode; } @@ -66,21 +53,6 @@ public class Language implements Serializable { public void setName(String name) { this.name = name; } - // - - /** - * 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) { @@ -107,9 +79,4 @@ public class Language implements Serializable { hash = 71 * hash + (this.name != null ? this.name.hashCode() : 0); return hash; } - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } } diff --git a/src/main/java/com/omertron/themoviedbapi/model/ListItemStatus.java b/src/main/java/com/omertron/themoviedbapi/model/ListItemStatus.java new file mode 100644 index 000000000..02b890b27 --- /dev/null +++ b/src/main/java/com/omertron/themoviedbapi/model/ListItemStatus.java @@ -0,0 +1,51 @@ +/* + * 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.JsonProperty; + +/** + * @author Holger Brandl + */ +public class ListItemStatus extends AbstractJsonMapping { + + private static final long serialVersionUID = 1L; + + @JsonProperty("status_code") + private int statusCode; + @JsonProperty("item_present") + private boolean itemPresent; + + public int getStatusCode() { + return statusCode; + } + + public void setStatusCode(int statusCode) { + this.statusCode = statusCode; + } + + public boolean isItemPresent() { + return itemPresent; + } + + public void setItemPresent(boolean itemPresent) { + this.itemPresent = itemPresent; + } +} diff --git a/src/main/java/com/omertron/themoviedbapi/model/MovieDb.java b/src/main/java/com/omertron/themoviedbapi/model/MovieDb.java index 3cc325e67..9976f28c5 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/MovieDb.java +++ b/src/main/java/com/omertron/themoviedbapi/model/MovieDb.java @@ -19,37 +19,19 @@ */ package com.omertron.themoviedbapi.model; -import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonProperty; -import com.omertron.themoviedbapi.wrapper.WrapperAlternativeTitles; -import com.omertron.themoviedbapi.wrapper.WrapperImages; -import com.omertron.themoviedbapi.wrapper.WrapperMovie; -import com.omertron.themoviedbapi.wrapper.WrapperMovieCasts; -import com.omertron.themoviedbapi.wrapper.WrapperMovieKeywords; -import com.omertron.themoviedbapi.wrapper.WrapperMovieList; -import com.omertron.themoviedbapi.wrapper.WrapperReleaseInfo; -import com.omertron.themoviedbapi.wrapper.WrapperReviews; -import com.omertron.themoviedbapi.wrapper.WrapperTrailers; -import com.omertron.themoviedbapi.wrapper.WrapperTranslations; -import java.io.Serializable; +import com.omertron.themoviedbapi.wrapper.*; + import java.util.List; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Movie Bean * * @author stuart.boston */ -public class MovieDb implements Serializable { +public class MovieDb extends AbstractJsonMapping { private static final long serialVersionUID = 1L; - /* - * Logger - */ - private static final Logger LOG = LoggerFactory.getLogger(MovieDb.class); /* * Properties */ @@ -93,6 +75,8 @@ public class MovieDb implements Serializable { private List spokenLanguages; @JsonProperty("tagline") private String tagline; + @JsonProperty("rating") + private float userRating; @JsonProperty("vote_average") private float voteAverage; @JsonProperty("vote_count") @@ -309,7 +293,6 @@ public class MovieDb implements Serializable { } // - // public List getAlternativeTitles() { return alternativeTitles.getTitles(); @@ -354,7 +337,6 @@ public class MovieDb implements Serializable { public List getReviews() { return reviews.getReviews(); } - // // public void setAlternativeTitles(WrapperAlternativeTitles alternativeTitles) { @@ -397,22 +379,6 @@ public class MovieDb implements Serializable { this.reviews = reviews; } - // - - /** - * 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) { @@ -443,10 +409,12 @@ public class MovieDb implements Serializable { hash = 89 * hash + this.runtime; return hash; } - // - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); + public float getUserRating() { + return userRating; + } + + public void setUserRating(float userRating) { + this.userRating = userRating; } } diff --git a/src/main/java/com/omertron/themoviedbapi/model/MovieDbList.java b/src/main/java/com/omertron/themoviedbapi/model/MovieDbList.java index 3d61c9687..3f7689577 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/MovieDbList.java +++ b/src/main/java/com/omertron/themoviedbapi/model/MovieDbList.java @@ -19,14 +19,10 @@ */ package com.omertron.themoviedbapi.model; -import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonProperty; + import java.util.Collections; import java.util.List; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Wrapper for the MovieDbList function @@ -34,11 +30,7 @@ import org.slf4j.LoggerFactory; * @author stuart.boston */ public class MovieDbList { - /* - * Logger - */ - private static final Logger LOG = LoggerFactory.getLogger(MovieDbList.class); /* * Properties */ @@ -97,9 +89,7 @@ public class MovieDbList { public String getPosterPath() { return posterPath; } - // - // public void setId(String id) { this.id = id; } @@ -135,24 +125,4 @@ public class MovieDbList { public void setPosterPath(String posterPath) { this.posterPath = posterPath; } - // - - /** - * 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 String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } } diff --git a/src/main/java/com/omertron/themoviedbapi/model/MovieDbListStatus.java b/src/main/java/com/omertron/themoviedbapi/model/MovieDbListStatus.java new file mode 100644 index 000000000..228b85822 --- /dev/null +++ b/src/main/java/com/omertron/themoviedbapi/model/MovieDbListStatus.java @@ -0,0 +1,36 @@ +/* + * 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;private either version 3 of the License;private or + * any later version. + * + * TheMovieDB API is distributed in the hope that it will be useful;private + * 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;private see . + * + */ +package com.omertron.themoviedbapi.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class MovieDbListStatus extends StatusCode { + + @JsonProperty("list_id") + private String listId; + + public String getListId() { + return listId; + } + + public void setListId(String listId) { + this.listId = listId; + } +} diff --git a/src/main/java/com/omertron/themoviedbapi/model/MovieList.java b/src/main/java/com/omertron/themoviedbapi/model/MovieList.java index 0f4709af2..b882810cb 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/MovieList.java +++ b/src/main/java/com/omertron/themoviedbapi/model/MovieList.java @@ -19,26 +19,15 @@ */ package com.omertron.themoviedbapi.model; -import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonProperty; -import java.io.Serializable; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** - * * @author Stuart */ -public class MovieList implements Serializable { +public class MovieList extends AbstractJsonMapping { private static final long serialVersionUID = 1L; - /* - * Logger - */ - private static final Logger LOG = LoggerFactory.getLogger(MovieList.class); /* * Properties */ @@ -126,23 +115,4 @@ public class MovieList implements Serializable { this.listType = listType; } // - - /** - * 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 String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } } diff --git a/src/main/java/com/omertron/themoviedbapi/model/Person.java b/src/main/java/com/omertron/themoviedbapi/model/Person.java index b0b86d782..527a6df8b 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/Person.java +++ b/src/main/java/com/omertron/themoviedbapi/model/Person.java @@ -19,30 +19,19 @@ */ package com.omertron.themoviedbapi.model; -import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonProperty; -import java.io.Serializable; +import org.apache.commons.lang3.StringUtils; + import java.util.ArrayList; import java.util.List; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** - * * @author stuart.boston */ -public class Person implements Serializable { +public class Person extends AbstractJsonMapping { private static final long serialVersionUID = 1L; - /* - * Logger - */ - private static final Logger LOG = LoggerFactory.getLogger(Person.class); - /* * Static fields for default cast information */ @@ -262,20 +251,6 @@ public class Person implements Serializable { } // - /** - * 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) { @@ -321,9 +296,4 @@ public class Person implements Serializable { hash = 37 * hash + (this.character != null ? this.character.hashCode() : 0); return hash; } - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } } diff --git a/src/main/java/com/omertron/themoviedbapi/model/PersonCast.java b/src/main/java/com/omertron/themoviedbapi/model/PersonCast.java index 9e40c93b1..9431240fa 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/PersonCast.java +++ b/src/main/java/com/omertron/themoviedbapi/model/PersonCast.java @@ -19,27 +19,16 @@ */ package com.omertron.themoviedbapi.model; -import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonProperty; -import java.io.Serializable; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** - * * @author Stuart */ -public class PersonCast implements Serializable { +public class PersonCast extends AbstractJsonMapping { private static final long serialVersionUID = 1L; - /* - * Logger - */ - private static final Logger LOG = LoggerFactory.getLogger(PersonCast.class); /* * Properties */ @@ -81,9 +70,6 @@ public class PersonCast implements Serializable { return castId; } - // - - // public void setCharacter(String character) { this.character = StringUtils.trimToEmpty(character); } @@ -108,22 +94,6 @@ public class PersonCast implements Serializable { this.castId = castId; } - // - - /** - * 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) { @@ -161,9 +131,4 @@ public class PersonCast implements Serializable { hash = 41 * hash + (this.profilePath != null ? this.profilePath.hashCode() : 0); return hash; } - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } } diff --git a/src/main/java/com/omertron/themoviedbapi/model/PersonCredit.java b/src/main/java/com/omertron/themoviedbapi/model/PersonCredit.java index e37543a85..de83ff73b 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/PersonCredit.java +++ b/src/main/java/com/omertron/themoviedbapi/model/PersonCredit.java @@ -19,27 +19,15 @@ */ package com.omertron.themoviedbapi.model; -import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonProperty; -import java.io.Serializable; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** - * * @author stuart.boston */ -public class PersonCredit implements Serializable { +public class PersonCredit extends AbstractJsonMapping { private static final long serialVersionUID = 1L; - - /* - * Logger - */ - private static final Logger LOG = LoggerFactory.getLogger(PersonCredit.class); private static final String DEFAULT_STRING = ""; /* * Properties @@ -104,9 +92,7 @@ public class PersonCredit implements Serializable { public String getAdult() { return adult; } - // - // public void setCharacter(String character) { this.character = StringUtils.trimToEmpty(character); } @@ -146,24 +132,4 @@ public class PersonCredit implements Serializable { public void setAdult(String adult) { this.adult = StringUtils.trimToEmpty(adult); } - // - - /** - * 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 String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } } diff --git a/src/main/java/com/omertron/themoviedbapi/model/PersonCrew.java b/src/main/java/com/omertron/themoviedbapi/model/PersonCrew.java index 334158a45..6414a7b07 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/PersonCrew.java +++ b/src/main/java/com/omertron/themoviedbapi/model/PersonCrew.java @@ -19,27 +19,16 @@ */ package com.omertron.themoviedbapi.model; -import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonProperty; -import java.io.Serializable; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** - * * @author Stuart */ -public class PersonCrew implements Serializable { +public class PersonCrew extends AbstractJsonMapping { private static final long serialVersionUID = 1L; - /* - * Logger - */ - private static final Logger LOG = LoggerFactory.getLogger(PersonCrew.class); /* * Properties */ @@ -74,9 +63,7 @@ public class PersonCrew implements Serializable { public String getProfilePath() { return profilePath; } - // - // public void setDepartment(String department) { this.department = StringUtils.trimToEmpty(department); } @@ -96,21 +83,6 @@ public class PersonCrew implements Serializable { public void setProfilePath(String profilePath) { this.profilePath = StringUtils.trimToEmpty(profilePath); } - // - - /** - * 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) { @@ -146,9 +118,4 @@ public class PersonCrew implements Serializable { hash = 59 * hash + (this.profilePath != null ? this.profilePath.hashCode() : 0); return hash; } - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } } diff --git a/src/main/java/com/omertron/themoviedbapi/model/PersonType.java b/src/main/java/com/omertron/themoviedbapi/model/PersonType.java index 1145578f8..3256eb3f0 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/PersonType.java +++ b/src/main/java/com/omertron/themoviedbapi/model/PersonType.java @@ -20,12 +20,11 @@ package com.omertron.themoviedbapi.model; /** - * * @author stuart.boston */ public enum PersonType { - CAST, // A member of the cast - CREW, // A member of the crew + CAST, // A member of the cast + CREW, // A member of the crew PERSON // No specific type } diff --git a/src/main/java/com/omertron/themoviedbapi/model/ProductionCompany.java b/src/main/java/com/omertron/themoviedbapi/model/ProductionCompany.java index 1bbbe9a3c..41859cc54 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/ProductionCompany.java +++ b/src/main/java/com/omertron/themoviedbapi/model/ProductionCompany.java @@ -19,28 +19,17 @@ */ package com.omertron.themoviedbapi.model; -import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonRootName; -import java.io.Serializable; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** - * * @author stuart.boston */ @JsonRootName("production_company") -public class ProductionCompany implements Serializable { +public class ProductionCompany extends AbstractJsonMapping { private static final long serialVersionUID = 1L; - /* - * Logger - */ - private static final Logger LOG = LoggerFactory.getLogger(ProductionCompany.class); /* * Properties */ @@ -57,9 +46,7 @@ public class ProductionCompany implements Serializable { public String getName() { return name; } - // - // public void setId(int id) { this.id = id; } @@ -67,21 +54,6 @@ public class ProductionCompany implements Serializable { public void setName(String name) { this.name = name; } - // - - /** - * 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) { @@ -108,9 +80,4 @@ public class ProductionCompany implements Serializable { hash = 37 * hash + (this.name != null ? this.name.hashCode() : 0); return hash; } - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } } diff --git a/src/main/java/com/omertron/themoviedbapi/model/ProductionCountry.java b/src/main/java/com/omertron/themoviedbapi/model/ProductionCountry.java index f475c20a3..824cf6a52 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/ProductionCountry.java +++ b/src/main/java/com/omertron/themoviedbapi/model/ProductionCountry.java @@ -19,28 +19,17 @@ */ package com.omertron.themoviedbapi.model; -import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonRootName; -import java.io.Serializable; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** - * * @author stuart.boston */ @JsonRootName("production_country") -public class ProductionCountry implements Serializable { +public class ProductionCountry extends AbstractJsonMapping { private static final long serialVersionUID = 1L; - /* - * Logger - */ - private static final Logger LOG = LoggerFactory.getLogger(ProductionCountry.class); /* * Properties */ @@ -57,9 +46,7 @@ public class ProductionCountry implements Serializable { public String getName() { return name; } - // - // public void setIsoCode(String isoCode) { this.isoCode = isoCode; } @@ -67,21 +54,6 @@ public class ProductionCountry implements Serializable { public void setName(String name) { this.name = name; } - // - - /** - * 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) { @@ -108,9 +80,4 @@ public class ProductionCountry implements Serializable { hash = 47 * hash + (this.name != null ? this.name.hashCode() : 0); return hash; } - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } } diff --git a/src/main/java/com/omertron/themoviedbapi/model/ReleaseInfo.java b/src/main/java/com/omertron/themoviedbapi/model/ReleaseInfo.java index aed8b7d61..0def47954 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/ReleaseInfo.java +++ b/src/main/java/com/omertron/themoviedbapi/model/ReleaseInfo.java @@ -19,26 +19,15 @@ */ package com.omertron.themoviedbapi.model; -import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonProperty; -import java.io.Serializable; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** - * * @author Stuart */ -public class ReleaseInfo implements Serializable { +public class ReleaseInfo extends AbstractJsonMapping { private static final long serialVersionUID = 1L; - /* - * Logger - */ - private static final Logger LOG = LoggerFactory.getLogger(ReleaseInfo.class); /* * Properties */ @@ -61,9 +50,7 @@ public class ReleaseInfo implements Serializable { public String getReleaseDate() { return releaseDate; } - // - // public void setCertification(String certification) { this.certification = certification; } @@ -75,21 +62,6 @@ public class ReleaseInfo implements Serializable { public void setReleaseDate(String releaseDate) { this.releaseDate = releaseDate; } - // - - /** - * 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) { @@ -120,9 +92,4 @@ public class ReleaseInfo implements Serializable { hash = 89 * hash + (this.releaseDate != null ? this.releaseDate.hashCode() : 0); return hash; } - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } } diff --git a/src/main/java/com/omertron/themoviedbapi/model/Reviews.java b/src/main/java/com/omertron/themoviedbapi/model/Reviews.java index 974cf9751..e9c722dea 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/Reviews.java +++ b/src/main/java/com/omertron/themoviedbapi/model/Reviews.java @@ -19,26 +19,15 @@ */ package com.omertron.themoviedbapi.model; -import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonProperty; -import java.io.Serializable; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** - * * @author Stuart */ -public class Reviews implements Serializable { +public class Reviews extends AbstractJsonMapping { private static final long serialVersionUID = 1L; - /* - * Logger - */ - private static final Logger LOG = LoggerFactory.getLogger(Reviews.class); /* * Properties */ @@ -86,23 +75,4 @@ public class Reviews implements Serializable { this.url = url; } // - - /** - * 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 String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } } diff --git a/src/main/java/com/omertron/themoviedbapi/model/StatusCode.java b/src/main/java/com/omertron/themoviedbapi/model/StatusCode.java index a54888080..3c86d14a6 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/StatusCode.java +++ b/src/main/java/com/omertron/themoviedbapi/model/StatusCode.java @@ -19,26 +19,15 @@ */ package com.omertron.themoviedbapi.model; -import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonProperty; -import java.io.Serializable; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** - * * @author Stuart */ -public class StatusCode implements Serializable { +public class StatusCode extends AbstractJsonMapping { private static final long serialVersionUID = 1L; - /* - * Logger - */ - private static final Logger LOG = LoggerFactory.getLogger(StatusCode.class); /* * Properties */ @@ -55,9 +44,7 @@ public class StatusCode implements Serializable { public void setStatusCode(int statusCode) { this.statusCode = statusCode; } - // - // public String getStatusMessage() { return statusMessage; } @@ -65,24 +52,4 @@ public class StatusCode implements Serializable { public void setStatusMessage(String statusMessage) { this.statusMessage = statusMessage; } - // - - /** - * 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 String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } } diff --git a/src/main/java/com/omertron/themoviedbapi/model/TmdbConfiguration.java b/src/main/java/com/omertron/themoviedbapi/model/TmdbConfiguration.java index a006f28a3..acd77699c 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/TmdbConfiguration.java +++ b/src/main/java/com/omertron/themoviedbapi/model/TmdbConfiguration.java @@ -19,27 +19,17 @@ */ 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.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; + +import java.util.List; /** - * * @author stuart.boston */ -public class TmdbConfiguration implements Serializable { +public class TmdbConfiguration extends AbstractJsonMapping { private static final long serialVersionUID = 1L; - /* - * Logger - */ - private static final Logger LOG = LoggerFactory.getLogger(TmdbConfiguration.class); /* * Properties */ @@ -180,23 +170,4 @@ public class TmdbConfiguration implements Serializable { || isValidProfileSize(sizeToCheck) || isValidLogoSize(sizeToCheck)); } - - /** - * 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 String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } } diff --git a/src/main/java/com/omertron/themoviedbapi/model/TokenAuthorisation.java b/src/main/java/com/omertron/themoviedbapi/model/TokenAuthorisation.java index 147860080..1b88d0e88 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/TokenAuthorisation.java +++ b/src/main/java/com/omertron/themoviedbapi/model/TokenAuthorisation.java @@ -19,18 +19,10 @@ */ package com.omertron.themoviedbapi.model; -import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonProperty; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public class TokenAuthorisation { - /* - * Logger - */ - private static final Logger LOG = LoggerFactory.getLogger(TokenAuthorisation.class); + /* * Properties */ @@ -68,24 +60,4 @@ public class TokenAuthorisation { this.success = success; } // - - /** - * 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 String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } - } diff --git a/src/main/java/com/omertron/themoviedbapi/model/TokenSession.java b/src/main/java/com/omertron/themoviedbapi/model/TokenSession.java index a0d5ba13a..e03b9f4e1 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/TokenSession.java +++ b/src/main/java/com/omertron/themoviedbapi/model/TokenSession.java @@ -19,19 +19,10 @@ */ package com.omertron.themoviedbapi.model; -import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonProperty; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public class TokenSession { - /* - * Logger - */ - private static final Logger LOG = LoggerFactory.getLogger(TokenSession.class); /* * Properties */ @@ -98,25 +89,5 @@ public class TokenSession { public void setExpiresAt(String expiresAt) { this.expiresAt = expiresAt; } - // - - /** - * 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 String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } } diff --git a/src/main/java/com/omertron/themoviedbapi/model/Trailer.java b/src/main/java/com/omertron/themoviedbapi/model/Trailer.java index fc2b446cc..bb57d2ead 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/Trailer.java +++ b/src/main/java/com/omertron/themoviedbapi/model/Trailer.java @@ -19,25 +19,13 @@ */ package com.omertron.themoviedbapi.model; -import com.fasterxml.jackson.annotation.JsonAnySetter; -import java.io.Serializable; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - /** - * * @author Stuart */ -public class Trailer implements Serializable { +public class Trailer extends AbstractJsonMapping { private static final long serialVersionUID = 1L; - /* - * Logger - */ - private static final Logger LOG = LoggerFactory.getLogger(Trailer.class); /* * Website sources */ @@ -67,9 +55,7 @@ public class Trailer implements Serializable { public String getWebsite() { return website; } - // - // public void setName(String name) { this.name = name; } @@ -85,21 +71,6 @@ public class Trailer implements Serializable { public void setWebsite(String website) { this.website = website; } - // - - /** - * 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) { @@ -131,9 +102,4 @@ public class Trailer implements Serializable { hash = 61 * hash + (this.website != null ? this.website.hashCode() : 0); return hash; } - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } } diff --git a/src/main/java/com/omertron/themoviedbapi/model/Translation.java b/src/main/java/com/omertron/themoviedbapi/model/Translation.java index c76c2ee7e..42d4a7979 100644 --- a/src/main/java/com/omertron/themoviedbapi/model/Translation.java +++ b/src/main/java/com/omertron/themoviedbapi/model/Translation.java @@ -19,26 +19,17 @@ */ package com.omertron.themoviedbapi.model; -import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonProperty; -import java.io.Serializable; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** - * * @author Stuart */ -public class Translation implements Serializable { +public class Translation extends AbstractJsonMapping { private static final long serialVersionUID = 1L; - /* - * Logger - */ - private static final Logger LOG = LoggerFactory.getLogger(Translation.class); /* * Properties */ @@ -61,9 +52,7 @@ public class Translation implements Serializable { public String getName() { return name; } - // - // public void setEnglishName(String englishName) { this.englishName = englishName; } @@ -75,21 +64,6 @@ public class Translation implements Serializable { public void setName(String name) { this.name = name; } - // - - /** - * 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) { @@ -123,6 +97,6 @@ public class Translation implements Serializable { @Override public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } + return ToStringBuilder.reflectionToString(this, ToStringStyle.SIMPLE_STYLE); + } } diff --git a/src/main/java/com/omertron/themoviedbapi/tools/WebBrowser.java b/src/main/java/com/omertron/themoviedbapi/tools/WebBrowser.java index 2de44eb8a..671fa4398 100644 --- a/src/main/java/com/omertron/themoviedbapi/tools/WebBrowser.java +++ b/src/main/java/com/omertron/themoviedbapi/tools/WebBrowser.java @@ -1,305 +1,336 @@ -/* - * 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.MovieDbException; -import org.apache.commons.codec.binary.Base64; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.*; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLConnection; -import java.nio.charset.Charset; -import java.nio.charset.UnsupportedCharsetException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Web browser with simple cookies support - */ -public final class WebBrowser { - - private static final Logger LOG = LoggerFactory.getLogger(WebBrowser.class); - private static Map browserProperties = new HashMap(); - private static Map> cookies = new HashMap>(); - private static String proxyHost = null; - private static String proxyPort = null; - private static String proxyUsername = null; - private static String proxyPassword = null; - private static String proxyEncodedPassword = null; - private static int webTimeoutConnect = 25000; // 25 second timeout - private static int webTimeoutRead = 90000; // 90 second timeout - - // Hide the constructor - protected WebBrowser() { - // prevents calls from subclass - throw new UnsupportedOperationException(); - } - - /** - * Populate the browser properties - */ - private static void populateBrowserProperties() { - if (browserProperties.isEmpty()) { - browserProperties.put("User-Agent", "Mozilla/5.25 Netscape/5.0 (Windows; I; Win95)"); - browserProperties.put("Accept", "application/json"); - browserProperties.put("Content-type", "application/json"); - } - } - - public static String request(String url) throws MovieDbException { - try { - return request(new URL(url)); - } catch (MalformedURLException ex) { - throw new MovieDbException(MovieDbException.MovieDbExceptionType.INVALID_URL, null, ex); - } - } - - public static URLConnection openProxiedConnection(URL url) throws MovieDbException { - try { - if (proxyHost != null) { - System.getProperties().put("proxySet", "true"); - System.getProperties().put("proxyHost", proxyHost); - System.getProperties().put("proxyPort", proxyPort); - } - - URLConnection cnx = url.openConnection(); - - if (proxyUsername != null) { - cnx.setRequestProperty("Proxy-Authorization", proxyEncodedPassword); - } - - return cnx; - } catch (IOException ex) { - throw new MovieDbException(MovieDbException.MovieDbExceptionType.INVALID_URL, null, ex); - } - } - - public static String request(URL url) throws MovieDbException { - return request(url, null); - } - - public static String request(URL url, String jsonBody) throws MovieDbException { - StringWriter content = null; - - try { - content = new StringWriter(); - - BufferedReader in = null; - URLConnection cnx = null; - OutputStreamWriter wr = null; - try { - cnx = openProxiedConnection(url); - - sendHeader(cnx); - - if (jsonBody != null) { - cnx.setDoOutput(true); - wr = new OutputStreamWriter(cnx.getOutputStream()); - wr.write(jsonBody); - } - - readHeader(cnx); - - in = new BufferedReader(new InputStreamReader(cnx.getInputStream(), getCharset(cnx))); - String line; - while ((line = in.readLine()) != null) { - content.write(line); - } - } finally { - if (wr != null) { - wr.flush(); - wr.close(); - } - - if (in != null) { - in.close(); - } - - if (cnx instanceof HttpURLConnection) { - ((HttpURLConnection) cnx).disconnect(); - } - } - return content.toString(); - } catch (IOException ex) { - throw new MovieDbException(MovieDbException.MovieDbExceptionType.CONNECTION_ERROR, null, ex); - } finally { - if (content != null) { - try { - content.close(); - } catch (IOException ex) { - LOG.debug("Failed to close connection: " + ex.getMessage()); - } - } - } - } - - private static void sendHeader(URLConnection cnx) { - populateBrowserProperties(); - - // send browser properties - for (Map.Entry browserProperty : browserProperties.entrySet()) { - cnx.setRequestProperty(browserProperty.getKey(), browserProperty.getValue()); - } - // send cookies - String cookieHeader = createCookieHeader(cnx); - if (!cookieHeader.isEmpty()) { - cnx.setRequestProperty("Cookie", cookieHeader); - } - } - - private static String createCookieHeader(URLConnection cnx) { - String host = cnx.getURL().getHost(); - StringBuilder cookiesHeader = new StringBuilder(); - for (Map.Entry> domainCookies : cookies.entrySet()) { - if (host.endsWith(domainCookies.getKey())) { - for (Map.Entry cookie : domainCookies.getValue().entrySet()) { - cookiesHeader.append(cookie.getKey()); - cookiesHeader.append("="); - cookiesHeader.append(cookie.getValue()); - cookiesHeader.append(";"); - } - } - } - if (cookiesHeader.length() > 0) { - // remove last ; char - cookiesHeader.deleteCharAt(cookiesHeader.length() - 1); - } - return cookiesHeader.toString(); - } - - private static void readHeader(URLConnection cnx) { - // read new cookies and update our cookies - for (Map.Entry> header : cnx.getHeaderFields().entrySet()) { - if ("Set-Cookie".equals(header.getKey())) { - for (String cookieHeader : header.getValue()) { - String[] cookieElements = cookieHeader.split(" *; *"); - if (cookieElements.length >= 1) { - String[] firstElem = cookieElements[0].split(" *= *"); - String cookieName = firstElem[0]; - String cookieValue = firstElem.length > 1 ? firstElem[1] : null; - String cookieDomain = null; - // find cookie domain - for (int i = 1; i < cookieElements.length; i++) { - String[] cookieElement = cookieElements[i].split(" *= *"); - if ("domain".equals(cookieElement[0])) { - cookieDomain = cookieElement.length > 1 ? cookieElement[1] : null; - break; - } - } - if (cookieDomain == null) { - // if domain isn't set take current host - cookieDomain = cnx.getURL().getHost(); - } - Map domainCookies = cookies.get(cookieDomain); - if (domainCookies == null) { - domainCookies = new HashMap(); - cookies.put(cookieDomain, domainCookies); - } - // add or replace cookie - domainCookies.put(cookieName, cookieValue); - } - } - } - } - } - - private static Charset getCharset(URLConnection cnx) { - Charset charset = null; - // content type will be string like "text/html; charset=UTF-8" or "text/html" - String contentType = cnx.getContentType(); - if (contentType != null) { - // changed 'charset' to 'harset' in regexp because some sites send 'Charset' - Matcher m = Pattern.compile("harset *=[ '\"]*([^ ;'\"]+)[ ;'\"]*").matcher(contentType); - if (m.find()) { - String encoding = m.group(1); - try { - charset = Charset.forName(encoding); - } catch (UnsupportedCharsetException e) { - // there will be used default charset - } - } - } - if (charset == null) { - charset = Charset.defaultCharset(); - } - - return charset; - } - - public static String getProxyHost() { - return proxyHost; - } - - public static void setProxyHost(String myProxyHost) { - WebBrowser.proxyHost = myProxyHost; - } - - public static String getProxyPort() { - return proxyPort; - } - - public static void setProxyPort(String myProxyPort) { - WebBrowser.proxyPort = myProxyPort; - } - - public static String getProxyUsername() { - return proxyUsername; - } - - public static void setProxyUsername(String myProxyUsername) { - WebBrowser.proxyUsername = myProxyUsername; - } - - public static String getProxyPassword() { - return proxyPassword; - } - - public static void setProxyPassword(String myProxyPassword) { - WebBrowser.proxyPassword = myProxyPassword; - - if (proxyUsername != null) { - proxyEncodedPassword = proxyUsername + ":" + proxyPassword; - proxyEncodedPassword = "Basic " + new String(Base64.encodeBase64((proxyUsername + ":" + proxyPassword).getBytes())); - } - } - - public static int getWebTimeoutConnect() { - return webTimeoutConnect; - } - - public static int getWebTimeoutRead() { - return webTimeoutRead; - } - - public static void setWebTimeoutConnect(int webTimeoutConnect) { - WebBrowser.webTimeoutConnect = webTimeoutConnect; - } - - public static void setWebTimeoutRead(int webTimeoutRead) { - WebBrowser.webTimeoutRead = webTimeoutRead; - } -} +/* + * 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.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.omertron.themoviedbapi.MovieDbException; +import org.apache.commons.codec.binary.Base64; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.*; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.nio.charset.Charset; +import java.nio.charset.UnsupportedCharsetException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Web browser with simple cookies support + */ +public final class WebBrowser { + + private static final Logger LOG = LoggerFactory.getLogger(WebBrowser.class); + private static Map browserProperties = new HashMap(); + private static Map> cookies = new HashMap>(); + private static String proxyHost = null; + private static String proxyPort = null; + private static String proxyUsername = null; + private static String proxyPassword = null; + private static String proxyEncodedPassword = null; + private static int webTimeoutConnect = 25000; // 25 second timeout + private static int webTimeoutRead = 90000; // 90 second timeout + + // Hide the constructor + protected WebBrowser() { + // prevents calls from subclass + throw new UnsupportedOperationException(); + } + + /** + * Populate the browser properties + */ + private static void populateBrowserProperties() { + if (browserProperties.isEmpty()) { + browserProperties.put("User-Agent", "Mozilla/5.25 Netscape/5.0 (Windows; I; Win95)"); + browserProperties.put("Accept", "application/json"); + browserProperties.put("Content-type", "application/json"); + } + } + + public static String request(String url) throws MovieDbException { + try { + return request(new URL(url)); + } catch (MalformedURLException ex) { + throw new MovieDbException(MovieDbException.MovieDbExceptionType.INVALID_URL, null, ex); + } + } + + public static URLConnection openProxiedConnection(URL url) throws MovieDbException { + try { + if (proxyHost != null) { + System.getProperties().put("proxySet", "true"); + System.getProperties().put("proxyHost", proxyHost); + System.getProperties().put("proxyPort", proxyPort); + } + + URLConnection cnx = url.openConnection(); + + if (proxyUsername != null) { + cnx.setRequestProperty("Proxy-Authorization", proxyEncodedPassword); + } + + return cnx; + } catch (IOException ex) { + throw new MovieDbException(MovieDbException.MovieDbExceptionType.INVALID_URL, null, ex); + } + } + + public static String request(URL url) throws MovieDbException { + return request(url, null); + } + + public static String request(URL url, String jsonBody) throws MovieDbException { + return request(url, jsonBody, false); + } + + public static String request(URL url, String jsonBody, boolean isDeleteRequest) throws MovieDbException { + + StringWriter content = null; + + try { + content = new StringWriter(); + + BufferedReader in = null; + HttpURLConnection cnx = null; + OutputStreamWriter wr = null; + try { + cnx = (HttpURLConnection) openProxiedConnection(url); + + if (isDeleteRequest) { + cnx.setDoOutput(true); + cnx.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + cnx.setRequestMethod("DELETE"); + } + + sendHeader(cnx); + + if (jsonBody != null) { + cnx.setDoOutput(true); + wr = new OutputStreamWriter(cnx.getOutputStream()); + wr.write(jsonBody); + } + + readHeader(cnx); + + // http://stackoverflow.com/questions/4633048/httpurlconnection-reading-response-content-on-403-error + if (cnx.getResponseCode() >= 400) { + in = new BufferedReader(new InputStreamReader(cnx.getErrorStream(), getCharset(cnx))); + } else { + in = new BufferedReader(new InputStreamReader(cnx.getInputStream(), getCharset(cnx))); + } + + String line; + while ((line = in.readLine()) != null) { + content.write(line); + } + } finally { + if (wr != null) { + wr.flush(); + wr.close(); + } + + if (in != null) { + in.close(); + } + + if (cnx instanceof HttpURLConnection) { + ((HttpURLConnection) cnx).disconnect(); + } + } + return content.toString(); + } catch (IOException ex) { + throw new MovieDbException(MovieDbException.MovieDbExceptionType.CONNECTION_ERROR, null, ex); + } finally { + if (content != null) { + try { + content.close(); + } catch (IOException ex) { + LOG.debug("Failed to close connection: " + ex.getMessage()); + } + } + } + } + + private static void sendHeader(URLConnection cnx) { + populateBrowserProperties(); + + // send browser properties + for (Map.Entry browserProperty : browserProperties.entrySet()) { + cnx.setRequestProperty(browserProperty.getKey(), browserProperty.getValue()); + } + // send cookies + String cookieHeader = createCookieHeader(cnx); + if (!cookieHeader.isEmpty()) { + cnx.setRequestProperty("Cookie", cookieHeader); + } + } + + private static String createCookieHeader(URLConnection cnx) { + String host = cnx.getURL().getHost(); + StringBuilder cookiesHeader = new StringBuilder(); + for (Map.Entry> domainCookies : cookies.entrySet()) { + if (host.endsWith(domainCookies.getKey())) { + for (Map.Entry cookie : domainCookies.getValue().entrySet()) { + cookiesHeader.append(cookie.getKey()); + cookiesHeader.append("="); + cookiesHeader.append(cookie.getValue()); + cookiesHeader.append(";"); + } + } + } + if (cookiesHeader.length() > 0) { + // remove last ; char + cookiesHeader.deleteCharAt(cookiesHeader.length() - 1); + } + return cookiesHeader.toString(); + } + + private static void readHeader(URLConnection cnx) { + // read new cookies and update our cookies + for (Map.Entry> header : cnx.getHeaderFields().entrySet()) { + if ("Set-Cookie".equals(header.getKey())) { + for (String cookieHeader : header.getValue()) { + String[] cookieElements = cookieHeader.split(" *; *"); + if (cookieElements.length >= 1) { + String[] firstElem = cookieElements[0].split(" *= *"); + String cookieName = firstElem[0]; + String cookieValue = firstElem.length > 1 ? firstElem[1] : null; + String cookieDomain = null; + // find cookie domain + for (int i = 1; i < cookieElements.length; i++) { + String[] cookieElement = cookieElements[i].split(" *= *"); + if ("domain".equals(cookieElement[0])) { + cookieDomain = cookieElement.length > 1 ? cookieElement[1] : null; + break; + } + } + if (cookieDomain == null) { + // if domain isn't set take current host + cookieDomain = cnx.getURL().getHost(); + } + Map domainCookies = cookies.get(cookieDomain); + if (domainCookies == null) { + domainCookies = new HashMap(); + cookies.put(cookieDomain, domainCookies); + } + // add or replace cookie + domainCookies.put(cookieName, cookieValue); + } + } + } + } + } + + private static Charset getCharset(URLConnection cnx) { + Charset charset = null; + // content type will be string like "text/html; charset=UTF-8" or "text/html" + String contentType = cnx.getContentType(); + if (contentType != null) { + // changed 'charset' to 'harset' in regexp because some sites send 'Charset' + Matcher m = Pattern.compile("harset *=[ '\"]*([^ ;'\"]+)[ ;'\"]*").matcher(contentType); + if (m.find()) { + String encoding = m.group(1); + try { + charset = Charset.forName(encoding); + } catch (UnsupportedCharsetException e) { + // there will be used default charset + } + } + } + if (charset == null) { + charset = Charset.defaultCharset(); + } + + return charset; + } + + public static String getProxyHost() { + return proxyHost; + } + + public static void setProxyHost(String myProxyHost) { + WebBrowser.proxyHost = myProxyHost; + } + + public static String getProxyPort() { + return proxyPort; + } + + public static void setProxyPort(String myProxyPort) { + WebBrowser.proxyPort = myProxyPort; + } + + public static String getProxyUsername() { + return proxyUsername; + } + + public static void setProxyUsername(String myProxyUsername) { + WebBrowser.proxyUsername = myProxyUsername; + } + + public static String getProxyPassword() { + return proxyPassword; + } + + public static void setProxyPassword(String myProxyPassword) { + WebBrowser.proxyPassword = myProxyPassword; + + if (proxyUsername != null) { + proxyEncodedPassword = proxyUsername + ":" + proxyPassword; + proxyEncodedPassword = "Basic " + new String(Base64.encodeBase64((proxyUsername + ":" + proxyPassword).getBytes())); + } + } + + public static int getWebTimeoutConnect() { + return webTimeoutConnect; + } + + public static int getWebTimeoutRead() { + return webTimeoutRead; + } + + public static void setWebTimeoutConnect(int webTimeoutConnect) { + WebBrowser.webTimeoutConnect = webTimeoutConnect; + } + + public static void setWebTimeoutRead(int webTimeoutRead) { + WebBrowser.webTimeoutRead = webTimeoutRead; + } + + /** + * Use Jackson to convert Map to json string. + */ + public static String convertToJson(Map map) { + try { + return new ObjectMapper().writeValueAsString(map); + } catch (JsonProcessingException jpe) { + throw new RuntimeException("json conversion failed", jpe); + } + + } +} diff --git a/src/main/java/com/omertron/themoviedbapi/wrapper/WrapperMovieDbList.java b/src/main/java/com/omertron/themoviedbapi/wrapper/WrapperMovieDbList.java new file mode 100644 index 000000000..08740a319 --- /dev/null +++ b/src/main/java/com/omertron/themoviedbapi/wrapper/WrapperMovieDbList.java @@ -0,0 +1,25 @@ +package com.omertron.themoviedbapi.wrapper; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.omertron.themoviedbapi.model.MovieDbList; + +import java.util.List; + +public class WrapperMovieDbList extends AbstractWrapperAll { + + + @JsonProperty("results") + private List lists; + + public WrapperMovieDbList() { + super(WrapperMovieDbList.class); + } + + public List getLists() { + return lists; + } + + public void setLists(List lists) { + this.lists = lists; + } +} diff --git a/src/test/java/com/omertron/themoviedbapi/TheMovieDbApiTest.java b/src/test/java/com/omertron/themoviedbapi/TheMovieDbApiTest.java index 3303700ea..ad63b58ae 100644 --- a/src/test/java/com/omertron/themoviedbapi/TheMovieDbApiTest.java +++ b/src/test/java/com/omertron/themoviedbapi/TheMovieDbApiTest.java @@ -29,6 +29,7 @@ import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.List; +import java.util.Random; import static org.junit.Assert.*; @@ -58,8 +59,9 @@ public class TheMovieDbApiTest { private static final String LANGUAGE_ENGLISH = "en"; private static final String LANGUAGE_RUSSIAN = "ru"; - // session id of test users named 'apitests' + // session and account id of test users named 'apitests' private static final String SESSION_ID_APITESTS = "63c85deb39337e29b69d78265eb28d639cbd6f72"; + private static final int ACCOUNT_ID_APITESTS = 6065849; public TheMovieDbApiTest() throws MovieDbException { } @@ -98,6 +100,50 @@ public class TheMovieDbApiTest { LOG.info(tmdbConfig.toString()); } + + @Test + public void testAccount() throws MovieDbException { + Account account = tmdb.getAccount(SESSION_ID_APITESTS); + + // Make sure properties are extracted correctly + assertEquals(account.getUserName(), "apitests"); + assertEquals(account.getId(), ACCOUNT_ID_APITESTS); + } + + @Test + public void testWatchList() throws MovieDbException { + // make sure it's empty (because it's just a test account + Assert.assertTrue(tmdb.getWatchList(SESSION_ID_APITESTS, ACCOUNT_ID_APITESTS).isEmpty()); + + // add a movie + tmdb.addToWatchList(SESSION_ID_APITESTS, ACCOUNT_ID_APITESTS, 550); + + List watchList = tmdb.getWatchList(SESSION_ID_APITESTS, ACCOUNT_ID_APITESTS); + assertTrue(watchList.size()==1); + + // clean up again + tmdb.removeFromWatchList(SESSION_ID_APITESTS, ACCOUNT_ID_APITESTS, 550); + + Assert.assertTrue(tmdb.getWatchList(SESSION_ID_APITESTS, ACCOUNT_ID_APITESTS).isEmpty()); + } + + @Test + public void testFavorites() throws MovieDbException { + // make sure it's empty (because it's just a test account + Assert.assertTrue(tmdb.getFavoriteMovies(SESSION_ID_APITESTS, ACCOUNT_ID_APITESTS).isEmpty()); + + // add a movie + tmdb.changeFavoriteStatus(SESSION_ID_APITESTS, ACCOUNT_ID_APITESTS, 550, true); + + List watchList = tmdb.getFavoriteMovies(SESSION_ID_APITESTS, ACCOUNT_ID_APITESTS); + assertTrue(watchList.size()==1); + + // clean up again + tmdb.changeFavoriteStatus(SESSION_ID_APITESTS, ACCOUNT_ID_APITESTS, 550, false); + + Assert.assertTrue(tmdb.getFavoriteMovies(SESSION_ID_APITESTS, ACCOUNT_ID_APITESTS).isEmpty()); + } + /** * Test of searchMovie method, of class TheMovieDbApi. */ @@ -597,20 +643,60 @@ public class TheMovieDbApiTest { * TODO: Cannot be tested without a HTTP authorisation: http://help.themoviedb.org/kb/api/user-authentication */ @Test - public void testPostMovieRating() throws Exception { + public void testMovieRating() throws Exception { LOG.info("postMovieRating"); Integer movieID = 68724; - Integer rating = 3; + Integer rating = new Random().nextInt(10)+1; boolean wasPosted = tmdb.postMovieRating(SESSION_ID_APITESTS, movieID, rating); assertTrue(wasPosted); + + // get all rated movies + + List ratedMovies = tmdb.getRatedMovies(SESSION_ID_APITESTS, ACCOUNT_ID_APITESTS); + assertTrue(ratedMovies.size()>0); + + // make sure that we find the movie and it is rated correctly + boolean foundMovie = false; + for (MovieDb movie : ratedMovies) { + if(movie.getId()==movieID){ + assertEquals(movie.getUserRating(), (float) rating, 0); + foundMovie = true; + } + } + assertTrue(foundMovie); } - /** - * Test of getPersonChanges method, of class TheMovieDbApi. - * - */ + @Test + public void testMovieLists() throws Exception { + Integer movieID = 68724; + + // use a random name to avoid that we clash we leftovers of incomplete test runs + String name = "test list " + new Random().nextInt(100); + + // create the list + String listId = tmdb.createList(SESSION_ID_APITESTS, name, "api testing only"); + + // add a movie, and test that it is on the list now + tmdb.addMovieToList(SESSION_ID_APITESTS, listId, movieID); + MovieDbList list = tmdb.getList(listId); + Assert.assertEquals(list.getItemCount(), 1); + Assert.assertEquals(list.getItems().get(0).getId(), (int) movieID); + + // now remove the movie + tmdb.removeMovieFromList(SESSION_ID_APITESTS, listId, movieID); + Assert.assertEquals(tmdb.getList(listId).getItemCount(), 0); + + // delete the test list + StatusCode statusCode = tmdb.deleteMovieList(SESSION_ID_APITESTS, listId); + assertEquals(statusCode.getStatusCode(), 13); + } + + /** + * Test of getPersonChanges method, of class TheMovieDbApi. + * + */ @Ignore("Not ready yet") public void testGetPersonChanges() throws Exception { LOG.info("getPersonChanges");