com.omertron.thetvdbapi.TheTVDBApi.java Source code

Java tutorial

Introduction

Here is the source code for com.omertron.thetvdbapi.TheTVDBApi.java

Source

/*
 *      Copyright (c) 2004-2014 Matthew Altman & Stuart Boston
 *
 *      This file is part of TheTVDB API.
 *
 *      TheTVDB 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.
 *
 *      TheTVDB 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 TheTVDB API.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
package com.omertron.thetvdbapi;

import com.omertron.thetvdbapi.model.Actor;
import com.omertron.thetvdbapi.model.Banners;
import com.omertron.thetvdbapi.model.Episode;
import com.omertron.thetvdbapi.model.Mirrors;
import com.omertron.thetvdbapi.model.Series;
import com.omertron.thetvdbapi.model.TVDBUpdates;
import com.omertron.thetvdbapi.tools.DOMHelper;
import com.omertron.thetvdbapi.tools.TvdbParser;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import javax.xml.ws.WebServiceException;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yamj.api.common.http.CommonHttpClient;
import org.yamj.api.common.http.DefaultPoolingHttpClient;

/**
 * @author altman.matthew
 * @author stuart.boston
 */
public class TheTVDBApi {

    private static final Logger LOG = LoggerFactory.getLogger(TheTVDBApi.class);
    private String apiKey = null;
    private CommonHttpClient httpClient;
    private static String xmlMirror = "http://thetvdb.com/api/";
    private static String bannerMirror = "http://thetvdb.com/banners/";
    private static final String XML_EXTENSION = ".xml";
    private static final String SERIES_URL = "/series/";
    private static final String ALL_URL = "/all/";
    private static final String WEEKLY_UPDATES_URL = "/updates/updates_week.xml";
    private static final String URL = "URL: {}";

    /**
     * Create an API object with the passed API Key
     *
     * @param apiKey Must be valid
     */
    public TheTVDBApi(String apiKey) {
        // No HttpClient passed, so use a default
        this(apiKey, new DefaultPoolingHttpClient());
    }

    /**
     * Create an API object with the passed API key and using the supplied
     * HttpClient
     *
     * @param apiKey Must not be null or empty
     * @param httpClient
     */
    public TheTVDBApi(String apiKey, CommonHttpClient httpClient) {
        if (StringUtils.isBlank(apiKey)) {
            return;
        }

        this.apiKey = apiKey;
        this.httpClient = httpClient;
        DOMHelper.setHttpClient(this.httpClient);
    }

    /**
     * Get the mirror information from TheTVDb
     *
     * @return True if everything is OK, false otherwise.
     */
    private static void getMirrors(String apiKey) {
        // If we don't need to get the mirrors, then just return
        if (xmlMirror != null && bannerMirror != null) {
            return;
        }

        Mirrors mirrors = new Mirrors(apiKey);
        xmlMirror = mirrors.getMirror(Mirrors.TYPE_XML);
        bannerMirror = mirrors.getMirror(Mirrors.TYPE_BANNER);

        if (xmlMirror == null) {
            throw new WebServiceException(
                    "There is a problem getting the xmlMirror data from TheTVDB, this means it is likely to be down.");
        } else {
            xmlMirror += "/api/";
        }

        if (bannerMirror == null) {
            throw new WebServiceException(
                    "There is a problem getting the bannerMirror data from TheTVDB, this means it is likely to be down.");
        } else {
            bannerMirror += "/banners/";
        }
    }

    /**
     * Set the web browser proxy information
     *
     * @param host
     * @param port
     * @param username
     * @param password
     */
    public void setProxy(String host, int port, String username, String password) {
        if (httpClient == null) {
            throw new WebServiceException("Failed to set proxy information");
        } else {
            httpClient.setProxy(host, port, username, password);
        }
    }

    /**
     * Set the web browser timeout settings
     *
     * @param webTimeoutConnect
     * @param webTimeoutRead
     */
    public void setTimeout(int webTimeoutConnect, int webTimeoutRead) {
        if (httpClient == null) {
            throw new WebServiceException("Failed to set timeout information");
        } else {
            httpClient.setTimeouts(webTimeoutConnect, webTimeoutRead);
        }
    }

    /**
     * Get the series information
     *
     * @param id
     * @param language
     * @return
     */
    public Series getSeries(String id, String language) {
        StringBuilder urlBuilder = new StringBuilder();
        try {
            urlBuilder.append(getXmlMirror(apiKey));
            urlBuilder.append(apiKey);
            urlBuilder.append(SERIES_URL);
            urlBuilder.append(id);
            urlBuilder.append("/");
            if (language != null) {
                urlBuilder.append(language).append(XML_EXTENSION);
            }
        } catch (WebServiceException ex) {
            LOG.warn(ex.getMessage(), ex);
            return null;
        }

        LOG.trace(URL, urlBuilder.toString());
        List<Series> seriesList = TvdbParser.getSeriesList(urlBuilder.toString(), getBannerMirror(apiKey));
        if (seriesList.isEmpty()) {
            return null;
        } else {
            return seriesList.get(0);
        }
    }

    /**
     * Get all the episodes for a series. Note: This could be a lot of records
     *
     * @param id
     * @param language
     * @return
     */
    public List<Episode> getAllEpisodes(String id, String language) {
        List<Episode> episodeList = Collections.emptyList();

        if (isValidNumber(id)) {
            StringBuilder urlBuilder = new StringBuilder();
            try {
                urlBuilder.append(getXmlMirror(apiKey));
            } catch (WebServiceException ex) {
                LOG.warn(ex.getMessage(), ex);
                urlBuilder.append("http://thetvdb.com/api/");
            }
            urlBuilder.append(apiKey);
            urlBuilder.append(SERIES_URL);
            urlBuilder.append(id);
            urlBuilder.append(ALL_URL);
            if (StringUtils.isNotBlank(language)) {
                urlBuilder.append(language).append(XML_EXTENSION);
            }

            LOG.trace(URL, urlBuilder.toString());
            episodeList = TvdbParser.getAllEpisodes(urlBuilder.toString(), -1, getBannerMirror(apiKey));
        }
        return episodeList;
    }

    /**
     * Get all the episodes from a specific season for a series. Note: This
     * could be a lot of records
     *
     * @param id
     * @param season
     * @param language
     * @return
     */
    public List<Episode> getSeasonEpisodes(String id, int season, String language) {
        StringBuilder urlBuilder = new StringBuilder();
        try {
            urlBuilder.append(getXmlMirror(apiKey));
            urlBuilder.append(apiKey);
            urlBuilder.append(SERIES_URL);
            urlBuilder.append(id);
            urlBuilder.append(ALL_URL);
            if (language != null) {
                urlBuilder.append(language).append(XML_EXTENSION);
            }
        } catch (WebServiceException ex) {
            LOG.warn(ex.getMessage(), ex);
            return Collections.emptyList();
        }

        LOG.trace(URL, urlBuilder.toString());
        return TvdbParser.getAllEpisodes(urlBuilder.toString(), season, getBannerMirror(apiKey));
    }

    /**
     * Get a specific episode's information
     *
     * @param seriesId
     * @param seasonNbr
     * @param episodeNbr
     * @param language
     * @return
     */
    public Episode getEpisode(String seriesId, int seasonNbr, int episodeNbr, String language) {
        return getTVEpisode(seriesId, seasonNbr, episodeNbr, language, "/default/");
    }

    /**
     * Get a specific DVD episode's information
     *
     * @param seriesId
     * @param seasonNbr
     * @param episodeNbr
     * @param language
     * @return
     */
    public Episode getDVDEpisode(String seriesId, int seasonNbr, int episodeNbr, String language) {
        return getTVEpisode(seriesId, seasonNbr, episodeNbr, language, "/dvd/");
    }

    /**
     * Generic function to get either the standard TV episode list or the DVD
     * list
     *
     * @param seriesId
     * @param seasonNbr
     * @param episodeNbr
     * @param language
     * @param episodeType
     * @return
     */
    private Episode getTVEpisode(String seriesId, int seasonNbr, int episodeNbr, String language,
            String episodeType) {
        if (!isValidNumber(seriesId) || !isValidNumber(seasonNbr) || !isValidNumber(episodeNbr)) {
            // Invalid number passed
            return new Episode();
        }

        StringBuilder urlBuilder = new StringBuilder();
        try {
            urlBuilder.append(getXmlMirror(apiKey));
            urlBuilder.append(apiKey);
            urlBuilder.append(SERIES_URL);
            urlBuilder.append(seriesId);
            urlBuilder.append(episodeType);
            urlBuilder.append(seasonNbr);
            urlBuilder.append("/");
            urlBuilder.append(episodeNbr);
            urlBuilder.append("/");
            if (language != null) {
                urlBuilder.append(language).append(XML_EXTENSION);
            }
        } catch (WebServiceException ex) {
            LOG.warn(ex.getMessage(), ex);
            return new Episode();
        }

        LOG.trace(URL, urlBuilder.toString());
        return TvdbParser.getEpisode(urlBuilder.toString(), getBannerMirror(apiKey));
    }

    /**
     * Get a specific absolute episode's information
     *
     * @param seriesId
     * @param episodeNbr
     * @param language
     * @return
     */
    public Episode getAbsoluteEpisode(String seriesId, int episodeNbr, String language) {
        StringBuilder urlBuilder = new StringBuilder();
        try {
            urlBuilder.append(getXmlMirror(apiKey));
            urlBuilder.append(apiKey);
            urlBuilder.append(SERIES_URL);
            urlBuilder.append(seriesId);
            urlBuilder.append("/absolute/");
            urlBuilder.append(episodeNbr);
            urlBuilder.append("/");
            if (language != null) {
                urlBuilder.append(language).append(XML_EXTENSION);
            }
        } catch (WebServiceException ex) {
            LOG.warn(ex.getMessage(), ex);
            return new Episode();
        }

        LOG.trace(URL, urlBuilder.toString());
        return TvdbParser.getEpisode(urlBuilder.toString(), getBannerMirror(apiKey));
    }

    /**
     * Get a list of banners for the series id
     *
     * @param id
     * @param seasonNbr
     * @param language
     * @return
     */
    public String getSeasonYear(String id, int seasonNbr, String language) {
        String year = null;

        Episode episode = getEpisode(id, seasonNbr, 1, language);
        if (episode != null && StringUtils.isNotBlank(episode.getFirstAired())) {
            Date date;

            try {
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                date = dateFormat.parse(episode.getFirstAired());
            } catch (ParseException ex) {
                LOG.trace("Failed to transform date: " + episode.getFirstAired(), ex);
                date = null;
            }

            if (date != null) {
                Calendar cal = Calendar.getInstance();
                cal.setTime(date);
                year = String.valueOf(cal.get(Calendar.YEAR));
            }
        }

        return year;
    }

    public Banners getBanners(String seriesId) {
        StringBuilder urlBuilder = new StringBuilder();
        try {
            urlBuilder.append(getXmlMirror(apiKey));
            urlBuilder.append(apiKey);
            urlBuilder.append(SERIES_URL);
            urlBuilder.append(seriesId);
            urlBuilder.append("/banners.xml");
        } catch (WebServiceException ex) {
            LOG.warn(ex.getMessage(), ex);
            return new Banners();
        }

        LOG.trace(URL, urlBuilder.toString());
        Banners b = TvdbParser.getBanners(urlBuilder.toString(), getBannerMirror(apiKey));

        if (b != null) {
            b.setSeriesId(NumberUtils.toInt(seriesId));
        }

        return b;
    }

    /**
     * Get a list of actors from the series id
     *
     * @param seriesId
     * @return
     */
    public List<Actor> getActors(String seriesId) {
        StringBuilder urlBuilder = new StringBuilder();
        try {
            urlBuilder.append(getXmlMirror(apiKey));
            urlBuilder.append(apiKey);
            urlBuilder.append(SERIES_URL);
            urlBuilder.append(seriesId);
            urlBuilder.append("/actors.xml");
        } catch (WebServiceException ex) {
            LOG.warn(ex.getMessage(), ex);
            return new ArrayList<Actor>();
        }

        LOG.trace(URL, urlBuilder.toString());
        return TvdbParser.getActors(urlBuilder.toString(), getBannerMirror(apiKey));
    }

    public List<Series> searchSeries(String title, String language) {
        StringBuilder urlBuilder = new StringBuilder();

        try {
            urlBuilder.append(getXmlMirror(apiKey));
            urlBuilder.append("GetSeries.php?seriesname=");
            urlBuilder.append(URLEncoder.encode(title, "UTF-8"));
            if (language != null) {
                urlBuilder.append("&language=").append(language);
            }
        } catch (UnsupportedEncodingException ex) {
            LOG.trace("Failed to encode title: " + title, ex);
            // Try and use the raw title
            urlBuilder.append(title);
        } catch (WebServiceException ex) {
            LOG.warn(ex.getMessage(), ex);
            return new ArrayList<Series>();
        }

        LOG.trace(URL, urlBuilder.toString());
        return TvdbParser.getSeriesList(urlBuilder.toString(), getBannerMirror(apiKey));
    }

    /**
     * Get information for a specific episode
     *
     * @param episodeId
     * @param language
     * @return
     */
    public Episode getEpisodeById(String episodeId, String language) {
        StringBuilder urlBuilder = new StringBuilder();

        try {
            urlBuilder.append(getXmlMirror(apiKey));
            urlBuilder.append(apiKey);
            urlBuilder.append("/episodes/");
            urlBuilder.append(episodeId);
            urlBuilder.append("/");
            if (StringUtils.isNotBlank(language)) {
                urlBuilder.append(language);
                urlBuilder.append(XML_EXTENSION);
            }
        } catch (WebServiceException ex) {
            LOG.warn(ex.getMessage(), ex);
            return new Episode();
        }

        LOG.trace(URL, urlBuilder.toString());
        return TvdbParser.getEpisode(urlBuilder.toString(), getBannerMirror(apiKey));
    }

    /**
     * Get the weekly updates
     *
     * @return
     */
    public TVDBUpdates getWeeklyUpdates() {
        StringBuilder urlBuilder = new StringBuilder();

        urlBuilder.append(getXmlMirror(apiKey));
        urlBuilder.append(apiKey);
        urlBuilder.append(WEEKLY_UPDATES_URL);

        LOG.trace(URL, urlBuilder.toString());
        return TvdbParser.getUpdates(urlBuilder.toString());
    }

    /**
     * Get the XML Mirror URL
     *
     * @param apiKey
     * @return
     */
    public static String getXmlMirror(String apiKey) {
        // Force a load of the mirror information if it doesn't exist
        getMirrors(apiKey);
        return xmlMirror;
    }

    /**
     * Get the Banner Mirror URL
     *
     * @param apiKey
     * @return
     */
    public static String getBannerMirror(String apiKey) {
        // Force a load of the mirror information if it doesn't exist
        getMirrors(apiKey);
        return bannerMirror;
    }

    /**
     * Convert a string to a number and then validate it
     *
     * @param number
     * @return
     */
    private boolean isValidNumber(String number) {
        return isValidNumber(NumberUtils.toInt(number, 0));
    }

    /**
     * Validate the number, i.e. ensure it is greater than zero
     *
     * @param number
     * @return
     */
    private boolean isValidNumber(int number) {
        return number >= 0;
    }
}