/** * Project-HomeFlix * * Copyright 2018-2019 <@Seil0> * * This program 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 * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. * */ package org.mosad.homeflix.controller; import java.awt.image.BufferedImage; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; import javax.imageio.ImageIO; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.mosad.homeflix.datatypes.FilmTabelDataType; import org.mosad.homeflix.datatypes.OMDbAPIResponseDataType; import com.eclipsesource.json.Json; import com.eclipsesource.json.JsonObject; import com.eclipsesource.json.JsonValue; public class OMDbAPIController implements Runnable { private DBController dbController; private FilmTabelDataType currentTableFilm; private String omdbAPIKey; private String URL = "https://www.omdbapi.com/?apikey="; private static final Logger LOGGER = LogManager.getLogger(OMDbAPIController.class.getName()); /** * constructor for the OMDbAPIController * @param main the Main object * @param dbController the DBController object * @param currentTableFilm the current film object * @param omdbAPIKey the omdbAPI key */ public OMDbAPIController(FilmTabelDataType currentTableFilm) { this.currentTableFilm = currentTableFilm; omdbAPIKey = XMLController.getOmdbAPIKey(); dbController = DBController.getInstance(); } @Override public void run() { LOGGER.info("Querying omdbAPI ..."); JsonObject object; if (currentTableFilm.getSeason() != null && Integer.parseInt(currentTableFilm.getSeason() + 0) > 0) { object = getByTitle(currentTableFilm.getTitle(), true); } else { object = getByTitle(currentTableFilm.getTitle(), false); } if (object == null) { LOGGER.error("Fatal error while querying omdbAPI!"); return; } // if the answer contains "not found!" try to search by title if (object.getString("Error", "").contains("not found!")) { String title = searchByTitle(currentTableFilm.getTitle()); if (title.length() > 0) { // we have at least one answer, get info by search title now if (currentTableFilm.getSeason() != null && Integer.parseInt(currentTableFilm.getSeason() + 0) > 0) { object = getByTitle(title, true); } else { object = getByTitle(title, false); } } else { // add default poster and cache LOGGER.warn("Adding default poster and cache entries for \"{}\"!", currentTableFilm.getTitle()); OMDbAPIResponseDataType omdbResponse = new OMDbAPIResponseDataType(); omdbResponse.setTitle(currentTableFilm.getTitle()); omdbResponse.setSeason(currentTableFilm.getSeason()); omdbResponse.setEpisode(currentTableFilm.getEpisode()); synchronized (this) { // adding to cache dbController.addCache(currentTableFilm.getStreamUrl(), omdbResponse); dbController.setCached(currentTableFilm.getStreamUrl()); } return; } } OMDbAPIResponseDataType omdbResponse = new OMDbAPIResponseDataType(); omdbResponse.setTitle(object.getString("Title", "")); omdbResponse.setYear(object.getString("Year", "")); omdbResponse.setRated(object.getString("Rated", "")); omdbResponse.setReleased(object.getString("Release", "")); omdbResponse.setSeason(object.getString("Season", "")); omdbResponse.setEpisode(object.getString("Episode", "")); omdbResponse.setRuntime(object.getString("Runtime", "")); omdbResponse.setGenre(object.getString("Genre", "")); omdbResponse.setDirector(object.getString("Director", "")); omdbResponse.setWriter(object.getString("Writer", "")); omdbResponse.setActors(object.getString("Actors", "")); omdbResponse.setPlot(object.getString("Plot", "")); omdbResponse.setLanguage(object.getString("Language", "")); omdbResponse.setCountry(object.getString("Country", "")); omdbResponse.setAwards(object.getString("Awards", "")); omdbResponse.setMetascore(object.getString("Metascore", "")); omdbResponse.setImdbRating(object.getString("imdbRating", "")); omdbResponse.setImdbVotes(object.getString("imdbVotes", "")); omdbResponse.setImdbID(object.getString("imdbID", "")); omdbResponse.setType(object.getString("Type", "")); omdbResponse.setDvd(object.getString("DVD", "")); omdbResponse.setBoxOffice(object.getString("BoxOffice", "")); omdbResponse.setProduction(object.getString("Production", "")); omdbResponse.setWebsite(object.getString("Website", "")); omdbResponse.setResponse(object.getString("Response", "")); // if a poster exist try resizing it to fit in the posterImageView and add it to the cache, else use the default try { BufferedImage originalImage = ImageIO.read(new URL(object.getString("Poster", ""))); // change path to where file is located omdbResponse.setPoster(XMLController.getPosterCache() + "/" + omdbResponse.getTitle() + ".png"); ImageIO.write(originalImage, "png", new File(omdbResponse.getPoster())); LOGGER.info("adding poster to cache: " + omdbResponse.getPoster()); } catch (Exception e) { LOGGER.warn("could not load poster, seting null -> using default"); } synchronized (this) { // adding to cache dbController.addCache(currentTableFilm.getStreamUrl(), omdbResponse); dbController.setCached(currentTableFilm.getStreamUrl()); } return; } /** * get a movie/series by its title * @param title of the movie/series * @return a jsonObject of the API answer */ private JsonObject getByTitle(String title, boolean useEpisode) { String output = null; URL apiUrl; try { if (useEpisode) { apiUrl = new URL(URL + omdbAPIKey + "&t=" + title.replace(" ", "%20") + "&Season=" + currentTableFilm.getSeason() + "&Episode=" + currentTableFilm.getEpisode() + "&plot=full"); } else { apiUrl = new URL(URL + omdbAPIKey + "&t=" + title.replace(" ", "%20") + "&plot=full"); } BufferedReader ina = new BufferedReader(new InputStreamReader(apiUrl.openStream())); output = ina.readLine(); ina.close(); LOGGER.info("response from '" + URL + "&t=" + title + "' was:" + output); } catch (IOException e) { LOGGER.error("error while making api request or reading response"); LOGGER.error("response from '" + URL + "&t=" + title + "' was:" + output, e); return null; } return Json.parse(output).asObject(); } /** * search for a movie/series title * @param title the movie/series title * @return the correct title if found */ private String searchByTitle(String title) { String output = null; // if the movie was not found try to search it LOGGER.warn("Movie was not found at first try, searching again!"); /** * TODO split the name intelligent as it may contain the film title search for * English name use tmdb */ try { URL apiUrl = new URL(URL + omdbAPIKey + "&s=" + title.replace(" ", "%20")); BufferedReader ina = new BufferedReader(new InputStreamReader(apiUrl.openStream())); output = ina.readLine(); ina.close(); LOGGER.info("response from '" + URL + "&s=" + title + "' was:" + output); } catch (Exception e) { LOGGER.error("error while making api request or reading response"); LOGGER.error("response from '" + URL + "&s=" + title + "' was:" + output, e); return ""; } JsonObject searchObject = Json.parse(output).asObject(); if (searchObject.getString("Response", "").equals("True")) { for (JsonValue movie : searchObject.get("Search").asArray()) { // get first entry from the array and set object = movie return movie.asObject().getString("Title", ""); } } else { LOGGER.warn("Movie \"{}\" not found!", title); } return ""; } }