All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.moviejukebox.plugin.AllocinePlugin Maven / Gradle / Ivy

There is a newer version: 2.9
Show newest version
/*
 *      Copyright (c) 2004-2012 YAMJ Members
 *      http://code.google.com/p/moviejukebox/people/list
 *
 *      Web: http://code.google.com/p/moviejukebox/
 *
 *      This software is licensed under a Creative Commons License
 *      See this page: http://code.google.com/p/moviejukebox/wiki/License
 *
 *      For any reuse or distribution, you must make clear to others the
 *      license terms of this work.
 */
package com.moviejukebox.plugin;

import com.moviejukebox.allocine.*;
import com.moviejukebox.allocine.jaxb.Episode;
import com.moviejukebox.allocine.jaxb.Tvseries;
import com.moviejukebox.model.Movie;
import com.moviejukebox.model.MovieFile;
import com.moviejukebox.scanner.artwork.FanartScanner;
import com.moviejukebox.tools.*;
import static com.moviejukebox.tools.PropertiesUtil.FALSE;
import static com.moviejukebox.tools.StringTools.*;
import com.moviejukebox.tools.cache.CacheMemory;
import java.net.URLEncoder;
import java.text.ParseException;
import java.util.List;
import javax.xml.bind.JAXBException;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.log4j.Logger;

public class AllocinePlugin extends ImdbPlugin {

    private static final Logger logger = Logger.getLogger(AllocinePlugin.class);
    public static final String CACHE_SEARCH_MOVIE = "AllocineSearchMovie";
    public static final String CACHE_SEARCH_SERIES = "AllocineSearchSeries";
    public static final String CACHE_MOVIE = "AllocineMovie";
    public static final String CACHE_SERIES = "AllocineSeries";
    private XMLAllocineAPIHelper allocineAPI;
    private boolean includeEpisodePlots;
    private boolean includeVideoImages;
    private int preferredPlotLength = PropertiesUtil.getIntProperty("plugin.plot.maxlength", "500");
    protected TheTvDBPlugin tvdb = null;
    public static String ALLOCINE_PLUGIN_ID = "allocine";

    public AllocinePlugin() {
        super();
        allocineAPI = new XMLAllocineAPIHelper(PropertiesUtil.getProperty("API_KEY_Allocine"));
        preferredCountry = PropertiesUtil.getProperty("imdb.preferredCountry", "France");
        includeEpisodePlots = PropertiesUtil.getBooleanProperty("mjb.includeEpisodePlots", FALSE);
        includeVideoImages = PropertiesUtil.getBooleanProperty("mjb.includeVideoImages", FALSE);
        downloadFanart = PropertiesUtil.getBooleanProperty("fanart.tv.download", FALSE);
    }

    @Override
    public String getPluginID() {
        return ALLOCINE_PLUGIN_ID;
    }

    /**
     * Scan Allocine html page for the specified TV Show
     */
    @Override
    protected void updateTVShowInfo(Movie movie) {

        String allocineId = movie.getId(ALLOCINE_PLUGIN_ID);
        if (!movie.isTVShow() || !movie.hasNewMovieFiles() || isNotValidString(allocineId)) {
            return;
        }

        try {
            String cacheKey = CacheMemory.generateCacheKey(CACHE_SERIES, allocineId);
            TvSeriesInfos tvSeriesInfos = (TvSeriesInfos) CacheMemory.getFromCache(cacheKey);
            if (tvSeriesInfos == null) {
                tvSeriesInfos = allocineAPI.getTvSeriesInfos(allocineId);
                // Add to the cache
                CacheMemory.addToCache(cacheKey, tvSeriesInfos);
            }

            if (tvSeriesInfos.isNotValid()) {
                logger.error("AllocinePlugin: Can't find informations for TvShow with id: " + allocineId);
                return;
            }

            // Check Title
            if (!movie.isOverrideTitle() && isValidString(tvSeriesInfos.getTitle())) {
                movie.setTitle(tvSeriesInfos.getTitle());
            }

            // Check Rating
            if (movie.getRating() == -1) {
                int rating = tvSeriesInfos.getRating();
                if (rating >= 0) {
                    movie.addRating(ALLOCINE_PLUGIN_ID, rating);
                }
            }

            // Check Year Start and End
            if (!movie.isOverrideYear() && isNotValidString(movie.getYear()) && isValidString(tvSeriesInfos.getYearStart())) {
                if (isValidString(tvSeriesInfos.getYearEnd())) {
                    movie.setYear(tvSeriesInfos.getYearStart() + "-" + tvSeriesInfos.getYearEnd());
                } else {
                    movie.setYear(tvSeriesInfos.getYearStart());
                }
            }

            // Check Plot
            if (isNotValidString(movie.getPlot())) {
                String synopsis = tvSeriesInfos.getSynopsis();
                if (isValidString(synopsis)) {
                    String plot = trimToLength(synopsis, preferredPlotLength, true, plotEnding);
                    movie.setPlot(plot);
                }
            }

            // Check ReleaseDate and Company
            //if (tvSeriesInfos.getRelease() != null) {
            //   if (isNotValidString(movie.getReleaseDate()) && isValidString(tvSeriesInfos.getRelease().getReleaseDate())) {
            //        movie.setReleaseDate(tvSeriesInfos.getRelease().getReleaseDate());
            //    }
            //}

            if (isNotValidString(movie.getCompany()) && isValidString(tvSeriesInfos.getOriginalChannel())) {
                movie.setCompany(tvSeriesInfos.getOriginalChannel());
            }

            // Check country
            if (isNotValidString(movie.getCountry()) && !tvSeriesInfos.getNationalityList().isEmpty()) {
                String firstCountry = tvSeriesInfos.getNationalityList().get(0);
                movie.setCountry(firstCountry);
            }

            // Check Genres
            if (movie.getGenres().isEmpty()) {
                for (String genre : tvSeriesInfos.getGenreList()) {
                    movie.addGenre(genre);
                }
            }

            // Check Casting
            if (movie.getDirectors().isEmpty()) {
                movie.setDirectors(tvSeriesInfos.getDirectors());
            }
            if (movie.getCast().isEmpty()) {
                movie.setCast(tvSeriesInfos.getActors());
            }
            if (movie.getWriters().isEmpty()) {
                movie.setWriters(tvSeriesInfos.getWriters());
            }

            int currentSeason = movie.getSeason();
            try {
                if (currentSeason <= 0 || currentSeason > tvSeriesInfos.getSeasonCount()) {
                    throw new Exception();
                }
                TvSeasonInfos tvSeasonInfos = null;
                for (MovieFile file : movie.getFiles()) {
                    if (!file.isNewFile() && file.hasTitle()) {
                        // don't scan episode title if it exists in XML data
                        continue;
                    }
                    if (tvSeasonInfos == null) {
                        tvSeasonInfos = allocineAPI.getTvSeasonInfos(tvSeriesInfos.getSeasonCode(currentSeason));
                    }
                    if (tvSeasonInfos.isNotValid()) {
                        continue;
                    }
                    // A file can have multiple episodes in it
                    for (int numEpisode = file.getFirstPart(); numEpisode <= file.getLastPart(); ++numEpisode) {
                        logger.debug("AllocinePlugin: Setting filename for episode Nb " + numEpisode);
                        Episode episode = tvSeasonInfos.getEpisode(numEpisode);
                        if (episode != null) {
                            // Set the title of the episode
                            if (isNotValidString(file.getTitle(numEpisode))) {
                                file.setTitle(numEpisode, episode.getTitle());
                            }

                            if (includeEpisodePlots && isNotValidString(file.getPlot(numEpisode))) {
                                String episodePlot =
                                        trimToLength(episode.getSynopsis(), preferredPlotLength, true, plotEnding);
                                file.setPlot(numEpisode, episodePlot);
                            }
                        }
                    }
                }
            } catch (Exception e) {
                logger.warn("AllocinePlugin: Can't find informations for season " + currentSeason
                        + " for TvSeries with id " + allocineId + " (" + movie.getBaseName() + ")");
            }

            // Call the TvDBPlugin to download fanart and/or videoimages
            if (downloadFanart || includeVideoImages) {
                if (tvdb == null) {
                    tvdb = new TheTvDBPlugin();
                }
                String tvDBid = TheTvDBPlugin.findId(movie);
                if (StringTools.isValidString(tvDBid)) {
                    // This needs to check if we should overwrite the artwork or not.
                    movie.setFanartURL(FanartScanner.getFanartURL(movie));
                    tvdb.scanTVShowTitles(movie);
                }
            }
        } catch (JAXBException error) {
            logger.error("AllocinePlugin: Failed retrieving allocine infos for TvShow "
                    + allocineId + ". Perhaps the allocine XML API has changed ...");
            logger.error(SystemTools.getStackTrace(error));
        } catch (Exception error) {
            logger.error("AllocinePlugin: Failed retrieving allocine infos for TvShow : " + allocineId);
            logger.error(SystemTools.getStackTrace(error));
        }
    }

    /**
     * Get Movie Informations from Allocine ID
     *
     * @param allocineId The allocine ID of the Movie
     * @return The MovieInfo object
     */
    public MovieInfos getMovieInfos(String allocineId) {
        MovieInfos movieInfos;

        String cacheKey = CacheMemory.generateCacheKey(CACHE_MOVIE, allocineId);
        movieInfos = (MovieInfos) CacheMemory.getFromCache(cacheKey);
        if (movieInfos == null) {
            try {
                movieInfos = allocineAPI.getMovieInfos(allocineId);
            } catch (JAXBException error) {
                logger.error("AllocinePlugin: Failed retrieving allocine infos for movie "
                        + allocineId + ". Perhaps the allocine XML API has changed ...");
                logger.error(SystemTools.getStackTrace(error));
            } catch (Exception error) {
                logger.error("AllocinePlugin: Failed retrieving allocine infos for movie : " + allocineId);
                logger.error(SystemTools.getStackTrace(error));
            }
            // Add to the cache
            CacheMemory.addToCache(cacheKey, movieInfos);
        }

        return movieInfos;
    }

    /**
     * Scan Allocine html page for the specified movie
     */
    private boolean updateMovieInfo(Movie movie) {

        String allocineId = movie.getId(ALLOCINE_PLUGIN_ID);

        MovieInfos movieInfos = getMovieInfos(allocineId);
        if (movieInfos == null) {
            logger.error("AllocinePlugin: Can't find informations for movie with id: " + allocineId);
            return false;
        }

        // Check Title
        if (!movie.isOverrideTitle() && isValidString(movieInfos.getTitle())) {
            movie.setTitle(movieInfos.getTitle());
        }

        // Check OriginalTitle
        if (isValidString(movieInfos.getOriginalTitle())) {
            movie.setOriginalTitle(movieInfos.getOriginalTitle());
        }

        // Check Rating
        if (movie.getRating() == -1) {
            int rating = movieInfos.getRating();
            if (rating >= 0) {
                movie.addRating(ALLOCINE_PLUGIN_ID, rating);
            }
        }

        // Check Year
        if (!movie.isOverrideYear() && isNotValidString(movie.getYear()) && isValidString(movieInfos.getProductionYear())) {
            movie.setYear(movieInfos.getProductionYear());
        }

        // Check Plot
        if (isNotValidString(movie.getPlot())) {
            String synopsis = movieInfos.getSynopsis();
            if (isValidString(synopsis)) {
                String plot = trimToLength(synopsis, preferredPlotLength, true, plotEnding);
                movie.setPlot(plot);
            }
        }

        // Check ReleaseDate and Company
        if (movieInfos.getRelease() != null) {
            if (isNotValidString(movie.getReleaseDate()) && isValidString(movieInfos.getRelease().getReleaseDate())) {
                movie.setReleaseDate(movieInfos.getRelease().getReleaseDate());
            }
            if (isNotValidString(movie.getCompany()) && movieInfos.getRelease().getDistributor() != null
                    && isValidString(movieInfos.getRelease().getDistributor().getName())) {
                movie.setCompany(movieInfos.getRelease().getDistributor().getName());
            }
        }

        // Check Runtime
        if (isNotValidString(movie.getRuntime())) {
            int runtime = movieInfos.getRuntime();
            if (runtime > 0) {
                movie.setRuntime(StringTools.formatDuration(runtime));
            }
        }

        // Check country
        if (isNotValidString(movie.getCountry()) && !movieInfos.getNationalityList().isEmpty()) {
            String firstCountry = movieInfos.getNationalityList().get(0);
            movie.setCountry(firstCountry);
        }

        // Check Genres
        if (movie.getGenres().isEmpty()) {
            for (String genre : movieInfos.getGenreList()) {
                movie.addGenre(genre);
            }
        }

        // Check certification
        if (isNotValidString(movie.getCertification())) {
            movie.setCertification(movieInfos.getCertification());
        }

        // Check Casting
        if (movie.getDirectors().isEmpty()) {
            movie.setDirectors(movieInfos.getDirectors());
        }
        if (movie.getCast().isEmpty()) {
            movie.setCast(movieInfos.getActors());
        }
        if (movie.getWriters().isEmpty()) {
            movie.setWriters(movieInfos.getWriters());
        }

        // Get Fanart
        if (isNotValidString(movie.getFanartURL()) && downloadFanart) {
            movie.setFanartURL(getFanartURL(movie));
            if (isValidString(movie.getFanartURL())) {
                movie.setFanartFilename(movie.getBaseName() + fanartToken + "." + fanartExtension);
            }
        }

        return true;
    }

    @Override
    public boolean scan(Movie mediaFile) {
        boolean retval;
        try {
            String allocineId = mediaFile.getId(ALLOCINE_PLUGIN_ID);
            if (isNotValidString(allocineId)) {
                allocineId = getAllocineId(mediaFile.getTitle(), mediaFile.getYear(), mediaFile.isTVShow() ? 0 : -1);
            }

            // we also get imdb Id for extra infos
            if (isNotValidString(mediaFile.getId(IMDB_PLUGIN_ID))) {
                mediaFile.setId(IMDB_PLUGIN_ID, imdbInfo.getImdbId(mediaFile.getOriginalTitle(), mediaFile.getYear()));
                logger.debug("AllocinePlugin: Found imdbId = " + mediaFile.getId(IMDB_PLUGIN_ID));
            }

            if (isValidString(allocineId)) {
                mediaFile.setId(ALLOCINE_PLUGIN_ID, allocineId);
                if (mediaFile.isTVShow()) {
                    updateTVShowInfo(mediaFile);
                    retval = true;
                } else {
                    retval = updateMovieInfo(mediaFile);
                }
            } else {
                // If no AllocineId found fallback to Imdb
                logger.debug("AllocinePlugin: No Allocine Id available, we fall back to ImdbPlugin");
                retval = super.scan(mediaFile);
            }
        } catch (ParseException error) {
            // If no AllocineId found fallback to Imdb
            logger.debug("AllocinePlugin: Parse error. Now using ImdbPlugin");
            retval = super.scan(mediaFile);
        }
        return retval;
    }

    /**
     * retrieve the allocineId matching the specified movie name.
     *
     * @throws ParseException
     */
    public String getAllocineId(String movieName, String year, int tvSeason) throws ParseException {
        String allocineId = Movie.UNKNOWN;
        try {
            if (tvSeason > -1) {
                allocineId = getAllocineSerieId(movieName, year);
            } else {
                allocineId = getAllocineMovieId(movieName, year);
            }
            if (isNotValidString(allocineId) && isValidString(year)) {
                // Try to find the allocine id with google
                return getAllocineIdFromGoogle(movieName, year);
            }

            return allocineId;

        } catch (Exception error) {
            logger.error("AllocinePlugin: Failed to retrieve alloCine Id for movie : " + movieName);
            logger.error("AllocinePlugin: Now using ImdbPlugin");
            throw new ParseException(allocineId, 0);
        }
    }

    private String getAllocineSerieId(String movieName, String year) throws Exception {
        String cacheKey = CacheMemory.generateCacheKey(CACHE_SEARCH_SERIES, movieName);
        Search searchInfos = (Search) CacheMemory.getFromCache(cacheKey);
        if (searchInfos == null) {
            searchInfos = allocineAPI.searchTvseriesInfos(movieName);
            // Add to the cache
            CacheMemory.addToCache(cacheKey, searchInfos);
        }
        if (searchInfos.isValid() && searchInfos.getTotalResults() > 0) {
            int totalResults = searchInfos.getTotalResults();
            // If we have a valid year try to find the first serie that match
            if (totalResults > 1 && isValidString(year)) {
                int yearSerie = NumberUtils.toInt(year, -1);
                for (Tvseries serie : searchInfos.getTvseries()) {
                    if (serie != null) {
                        int serieStart = NumberUtils.toInt(serie.getYearStart(), -1);
                        if (serieStart == -1) {
                            continue;
                        }
                        int serieEnd = NumberUtils.toInt(serie.getYearEnd(), -1);
                        if (serieEnd == -1) {
                            serieEnd = serieStart;
                        }
                        if (yearSerie >= serieStart && yearSerie <= serieEnd) {
                            return String.valueOf(serie.getCode());
                        }
                    }
                }
            }
            // We don't find a serie or there only one result, return the first
            List serieList = searchInfos.getTvseries();
            if (!serieList.isEmpty()) {
                Tvseries serie = serieList.get(0);
                if (serie != null) {
                    return String.valueOf(serie.getCode());
                }
            }
        }
        return Movie.UNKNOWN;
    }

    private String getAllocineMovieId(String movieName, String year) throws Exception {
        String cacheKey = CacheMemory.generateCacheKey(CACHE_SEARCH_MOVIE, movieName);
        Search searchInfos = (Search) CacheMemory.getFromCache(cacheKey);
        if (searchInfos == null) {
            searchInfos = allocineAPI.searchMovieInfos(movieName);
            // Add to the cache
            CacheMemory.addToCache(cacheKey, searchInfos);
        }
        if (searchInfos.isValid() && searchInfos.getTotalResults() > 0) {
            int totalResults = searchInfos.getTotalResults();
            // If we have a valid year try to find the first movie that match
            if (totalResults > 1 && isValidString(year)) {
                int yearMovie = NumberUtils.toInt(year, -1);
                for (com.moviejukebox.allocine.jaxb.Movie movie : searchInfos.getMovie()) {
                    if (movie != null) {
                        int movieProductionYear = NumberUtils.toInt(movie.getProductionYear(), -1);
                        if (movieProductionYear == -1) {
                            continue;
                        }
                        if (movieProductionYear == yearMovie) {
                            return String.valueOf(movie.getCode());
                        }
                    }
                }
            }
            // We don't find a movie or there only one result, return the first
            List movieList = searchInfos.getMovie();
            if (!movieList.isEmpty()) {
                com.moviejukebox.allocine.jaxb.Movie movie = movieList.get(0);
                if (movie != null) {
                    return String.valueOf(movie.getCode());
                }
            }
        }
        return Movie.UNKNOWN;
    }

    /**
     * Retrieve the AllocineId matching the specified movie name and year. This
     * routine is base on a Google request.
     *
     * @param movieName The name of the Movie to search for
     * @param year The year of the movie
     * @return The AllocineId if it was found
     */
    private String getAllocineIdFromGoogle(String movieName, String year) {
        try {
            StringBuilder sb = new StringBuilder("http://www.google.fr/search?hl=fr&q=");
            sb.append(URLEncoder.encode(movieName, "UTF-8"));

            if (isValidString(year)) {
                sb.append("+%28").append(year).append("%29");
            }
            sb.append("+site%3Awww.allocine.fr&meta=");
//            logger.debug("AllocinePlugin: Allocine request via Google : " + sb.toString());
            String xml = webBrowser.request(sb.toString());
            String allocineId = HTMLTools.extractTag(xml, "film/fichefilm_gen_cfilm=", ".html");
//            logger.debug("AllocinePlugin: Allocine found via Google : " + allocineId);
            return allocineId;
        } catch (Exception error) {
            logger.error("AllocinePlugin Failed retreiving AlloCine Id for movie : " + movieName);
            logger.error("AllocinePlugin Error : " + error.getMessage());
            return Movie.UNKNOWN;
        }
    }

    protected String removeHtmlTags(String src) {
        String result = src.replaceAll("\\<.*?>", "").trim();
        // logger.debug("AllocinePlugin: removeHtmlTags before=[" + src + "], after=["+ result + "]");
        return result;
    }

    protected String removeOpenedHtmlTags(String src) {
        String result = src.replaceAll("^.*?>", "");
        result = result.replaceAll("<.*?$", "");
        result = result.trim();
        // logger.debug("AllocinePlugin: removeOpenedHtmlTags before=[" + src + "], after=["+ result + "]");
        return result;
    }

    @Override
    public boolean scanNFO(String nfo, Movie movie) {
        // Always look for imdb id look for ttXXXXXX
        super.scanNFO(nfo, movie);

        boolean result = false;
        // If we use allocine plugin look for
        // http://www.allocine.fr/...=XXXXX.html
        logger.debug("AllocinePlugin: Scanning NFO for Allocine Id");
        int beginIndex = nfo.indexOf("http://www.allocine.fr/");
        if (beginIndex != -1) {
            int beginIdIndex = nfo.indexOf('=', beginIndex);
            if (beginIdIndex != -1) {
                int endIdIndex = nfo.indexOf('.', beginIdIndex);
                if (endIdIndex != -1) {
                    logger.debug("AllocinePlugin: Allocine Id found in nfo = " + new String(nfo.substring(beginIdIndex + 1, endIdIndex)));
                    movie.setId(AllocinePlugin.ALLOCINE_PLUGIN_ID, new String(nfo.substring(beginIdIndex + 1, endIdIndex)));
                    result = true;
                } else {
                    logger.debug("AllocinePlugin: No Allocine Id found in nfo !");
                }
            } else {
                logger.debug("AllocinePlugin: No Allocine Id found in nfo !");
            }
        } else {
            logger.debug("AllocinePlugin: No Allocine Id found in nfo !");
        }
        return result;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy