Project-HomeFlix/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java

223 lines
8.0 KiB
Java

/**
* 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 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.MainWindowController;
import kellerkinder.HomeFlix.datatypes.FilmTabelDataType;
import kellerkinder.HomeFlix.datatypes.OMDbAPIResponseDataType;
public class OMDbAPIController implements Runnable {
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(DBController dbController, FilmTabelDataType currentTableFilm, String omdbAPIKey, boolean refresh) {
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(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.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 "";
}
}