/** * Project-HomeFlix * * Copyright 2018 <@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 kellerkinder.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 com.eclipsesource.json.Json; import com.eclipsesource.json.JsonObject; import com.eclipsesource.json.JsonValue; import javafx.application.Platform; import kellerkinder.HomeFlix.application.Main; import kellerkinder.HomeFlix.application.MainWindowController; import kellerkinder.HomeFlix.datatypes.FilmTabelDataType; import kellerkinder.HomeFlix.datatypes.OMDbAPIResponseDataType; public class OMDbAPIController implements Runnable { private Main main; private DBController dbController; private FilmTabelDataType currentTableFilm; private String omdbAPIKey; private String URL = "https://www.omdbapi.com/?apikey="; private boolean useEpisode = true; private boolean refresh; private static final Logger LOGGER = LogManager.getLogger(MainWindowController.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(Main main, DBController dbController, FilmTabelDataType currentTableFilm, String omdbAPIKey, boolean refresh) { this.main = main; this.dbController = dbController; this.currentTableFilm = currentTableFilm; this.omdbAPIKey = omdbAPIKey; this.refresh = refresh; } @Override public void run() { LOGGER.info("Querying omdbAPI ..."); JsonObject object; object = getByTitle(currentTableFilm.getTitle()); 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 on answer, get info by title now object = getByTitle(title); // if we still have nothing found, get info by title without episode if(object.getString("Error", "").contains("Series or episode not found!")) { useEpisode = false; object = getByTitle(title); } } else { 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", "")); // resize the image to fit in the posterImageView and add it to the cache try { BufferedImage originalImage = ImageIO.read(new URL(object.getString("Poster", ""))); // change path to where file is located omdbResponse.setPoster(main.getPosterCache() + "/" + omdbResponse.getTitle() + ".png"); ImageIO.write(originalImage, "png", new File(omdbResponse.getPoster())); LOGGER.info("adding poster to cache: " + omdbResponse.getPoster()); } catch (Exception e) { LOGGER.error(e); } synchronized (this) { // adding to cache dbController.addCache(currentTableFilm.getStreamUrl(), omdbResponse); dbController.setCached(currentTableFilm.getStreamUrl()); // load data to the MainWindowController if (refresh) { Platform.runLater(() -> { dbController.readCache(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) { String output = null; URL apiUrl; try { if (currentTableFilm.getSeason().length() > 0 && useEpisode) { apiUrl = new URL(URL + omdbAPIKey + "&t=" + title.replace(" ", "%20") + "&Season=" + currentTableFilm.getSeason() + "&Episode=" + currentTableFilm.getEpisode()); } else { apiUrl = new URL(URL + omdbAPIKey + "&t=" + title.replace(" ", "%20")); } 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 // TODO if the search was successful, we should add the wrong and correct title to a list, for later speedup return movie.asObject().getString("Title", ""); } } else { // TODO set cached 1 and set the HomeFlix logo as picture // System.out.println("Object is: " + searchObject); LOGGER.warn("Movie \"{}\" not found! Not adding cache!", title); } return ""; } }