diff --git a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java index df5ed4a..efa48af 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java +++ b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java @@ -32,13 +32,12 @@ import java.io.InputStreamReader; import java.io.Writer; import java.math.BigInteger; import java.net.URLConnection; +import java.time.LocalDate; import java.util.Locale; import java.util.ResourceBundle; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import javax.swing.SwingUtilities; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.kellerkinder.Alerts.JFXInfoAlert; @@ -149,7 +148,7 @@ public class MainWindowController { @FXML private JFXTextField searchTextField; @FXML private TreeTableView filmsTreeTable; - @FXML private TreeItem filmRoot = new TreeItem<>(new FilmTabelDataType("", "", "", "", false, false, null)); + @FXML private TreeItem filmRoot = new TreeItem<>(new FilmTabelDataType("", "", "", "", false, null, null)); @FXML private ScrollPane textScrollPane; @@ -182,7 +181,7 @@ public class MainWindowController { private int indexTable; private int indexList; private int next; - private FilmTabelDataType currentTableFilm = new FilmTabelDataType("", "", "", "", false, false, null); + private FilmTabelDataType currentTableFilm = new FilmTabelDataType("", "", "", "", false, null, null); private ObservableList languages = FXCollections.observableArrayList("English (en_US)", "Deutsch (de_DE)"); private ObservableList branches = FXCollections.observableArrayList("stable", "beta"); @@ -192,6 +191,7 @@ public class MainWindowController { private MenuItem like = new MenuItem("like"); private MenuItem dislike = new MenuItem("dislike"); // TODO one option (like or dislike) private ContextMenu menu = new ContextMenu(like, dislike); + private LocalDate lastValidCache = LocalDate.now().minusDays(30); // current date - 30 days is the last valid cache date public MainWindowController() { // the constructor @@ -425,11 +425,15 @@ public class MainWindowController { last = indexTable - 1; next = indexTable + 1; + - if (currentTableFilm.getCached() || dbController.searchCacheByURL(getCurrentStreamUrl())) { + if ((currentTableFilm.getCached().isAfter(lastValidCache) )|| dbController.searchCacheByURL(getCurrentStreamUrl())) { LOGGER.info("loading from cache: " + getCurrentTitle()); setSelectedFilmInfo(dbController.readCache(getCurrentStreamUrl())); + System.out.println("cache date is: " + currentTableFilm.getCached().toString()); } else { + System.out.println("either not cached or to old!"); + System.out.println("cache date is: " + currentTableFilm.getCached().toString()); // this is not perfect! new Thread(new Runnable() { public void run() { @@ -640,7 +644,7 @@ public class MainWindowController { // if no root node exists, create one and add element as child TreeItem seriesRootNode = new TreeItem<>(new FilmTabelDataType( element.getTitle() + "_rootNode", element.getTitle(), "", "", element.getFavorite(), - false, element.getImage())); + element.getCached() , element.getImage())); filmRoot.getChildren().add(seriesRootNode); } } @@ -829,7 +833,7 @@ public class MainWindowController { nameText[18] = new Text(XMLController.getLocalBundle().getString("boxOffice") + ": "); nameText[19] = new Text(XMLController.getLocalBundle().getString("website") + ": "); // *** - + // set the correct font for the nameText for (Text text : nameText) { text.setFont(font); @@ -850,11 +854,15 @@ public class MainWindowController { getTextFlow().setStyle("-fx-font-size : " + ((int) Math.round(XMLController.getFontSize()) + 1) + "px;"); // add the image - try { - posterImageView.setImage(new Image(new File(cacheData[20]).toURI().toString())); - } catch (Exception e) { - posterImageView.setImage(new Image("icons/close_black_2048x2048.png")); - LOGGER.error("No Poster found, useing default."); + if (new File(cacheData[20]).isFile()) { + try { + posterImageView.setImage(new Image(new File(cacheData[20]).toURI().toString())); + } catch (Exception e) { + posterImageView.setImage(new Image(cacheData[20])); + LOGGER.error("No Poster found, useing default."); + } + } else { + posterImageView.setImage(new Image(cacheData[20])); } } diff --git a/src/main/java/kellerkinder/HomeFlix/controller/DBController.java b/src/main/java/kellerkinder/HomeFlix/controller/DBController.java index 6e87e16..bba1c71 100644 --- a/src/main/java/kellerkinder/HomeFlix/controller/DBController.java +++ b/src/main/java/kellerkinder/HomeFlix/controller/DBController.java @@ -25,6 +25,7 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.net.URLConnection; import java.sql.Connection; +import java.sql.Date; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -50,7 +51,7 @@ public class DBController { private String DB_PATH; private Image favorite_black = new Image("icons/ic_favorite_black_18dp_1x.png"); private Image favorite_border_black = new Image("icons/ic_favorite_border_black_18dp_1x.png"); - private List databaseStream = new ArrayList(); // contains all films stored in the database + private List databaseStreams = new ArrayList(); // contains all films stored in the database private List sourceStreams = new ArrayList(); // contains all films from the sources private Connection connection = null; private static final Logger LOGGER = LogManager.getLogger(DBController.class.getName()); @@ -79,11 +80,8 @@ public class DBController { * refresh the database */ public void init() { - LOGGER.info("<========== starting loading sql ==========>"); initDatabaseConnection(); createDatabase(); - refreshDataBase(); - LOGGER.info("<========== finished loading sql ==========>"); } /** @@ -98,9 +96,9 @@ public class DBController { connection.setAutoCommit(false); } catch (SQLException e) { // if the error message is "out of memory", it probably means no database file is found - LOGGER.error("error while loading the ROM database", e); + LOGGER.error("error while loading the HomeFlix database", e); } - LOGGER.info("ROM database loaded successfull"); + LOGGER.info("HomeFlix database loaded successfull"); } /** @@ -131,9 +129,9 @@ public class DBController { Statement stmt = connection.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM films"); while (rs.next()) { - databaseStream.add(new DatabaseDataType(rs.getString("streamUrl"), + databaseStreams.add(new DatabaseDataType(rs.getString("streamUrl"), rs.getString("title"), rs.getString("season"), rs.getString("episode"), - rs.getInt("favorite"), rs.getBoolean("cached"), rs.getDouble("currentTime"))); + rs.getInt("favorite"), rs.getDate("cached"), rs.getDouble("currentTime"))); } stmt.close(); rs.close(); @@ -157,17 +155,17 @@ public class DBController { */ public ObservableList getDatabaseFilmsList() { ObservableList filmsList = FXCollections.observableArrayList(); - LOGGER.info("loading data to mwc ..."); + LOGGER.info("loading data from database ..."); try { //load local Data Statement stmt = connection.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM films ORDER BY title"); - while (rs.next()) { + while (rs.next()) { ImageView imageView = rs.getBoolean("favorite") ? new ImageView(favorite_black) : new ImageView(favorite_border_black); filmsList.add(new FilmTabelDataType(rs.getString("streamUrl"), rs.getString("title"), rs.getString("season"), rs.getString("episode") ,rs.getBoolean("favorite"), - rs.getBoolean("cached"), imageView)); + rs.getDate("cached").toLocalDate(), imageView)); } stmt.close(); rs.close(); @@ -175,8 +173,6 @@ public class DBController { LOGGER.error("Ups! an error occured!", e); } - LOGGER.info("loading data to the GUI ..."); - return filmsList; } @@ -197,7 +193,7 @@ public class DBController { ImageView imageView = rs.getBoolean("favorite") ? new ImageView(favorite_black) : new ImageView(favorite_border_black); film = new FilmTabelDataType(rs.getString("streamUrl"), rs.getString("title"), rs.getString("season"), rs.getString("episode"), rs.getBoolean("favorite"), - rs.getBoolean("cached"), imageView); + rs.getDate("cached").toLocalDate(), imageView); } rs.close(); ps.close(); @@ -212,16 +208,16 @@ public class DBController { * refresh database to contain all (new added) entries */ public void refreshDataBase() { - LOGGER.info("refreshing the Database ..."); + LOGGER.info("<========== starting refreshing database ==========>"); // clean all ArraLists - databaseStream.clear(); + databaseStreams.clear(); sourceStreams.clear(); loadSources(); // reload all sources loadDatabase(); // reload all films saved in the DB - LOGGER.info("filme in db: " + databaseStream.size()); + LOGGER.info("filme in db: " + databaseStreams.size()); try { checkAddEntry(); @@ -229,6 +225,8 @@ public class DBController { } catch (Exception e) { LOGGER.error("Error while refreshing the database", e); } + + LOGGER.info("<========== finished refreshing database ==========>"); } /** @@ -239,7 +237,7 @@ public class DBController { PreparedStatement ps = connection.prepareStatement("DELETE FROM films WHERE streamUrl = ?"); LOGGER.info("checking for entrys to remove to DB ..."); - for (DatabaseDataType dbStreamEntry : databaseStream) { + for (DatabaseDataType dbStreamEntry : databaseStreams) { // if the directory doen't contain the entry form the database, remove it // if sourceStreams has a item where StreamUrl equals dbStreamEntry.getStreamUrl() return it, else null @@ -275,7 +273,7 @@ public class DBController { for (DatabaseDataType sourceStreamEntry : sourceStreams) { // if databaseStream has a item where StreamUrl equals sourceStreamEntry.getStreamUrl() return it, else null - DatabaseDataType result = databaseStream.stream() + DatabaseDataType result = databaseStreams.stream() .filter(x -> sourceStreamEntry.getStreamUrl().equals(x.getStreamUrl())) .findAny() .orElse(null); @@ -287,11 +285,11 @@ public class DBController { ps.setString(3, sourceStreamEntry.getSeason()); ps.setString(4, sourceStreamEntry.getEpisode()); ps.setInt(5, sourceStreamEntry.getFavorite()); - ps.setBoolean(6, sourceStreamEntry.getCached()); + ps.setDate(6, sourceStreamEntry.getCached()); ps.setDouble(7, sourceStreamEntry.getCurrentTime()); ps.addBatch(); // adds the entry LOGGER.info("Added \"" + sourceStreamEntry.getTitle() + "\" to database"); - databaseStream.add(sourceStreamEntry); + databaseStreams.add(sourceStreamEntry); } } @@ -365,8 +363,9 @@ public class DBController { */ public void setCached(String streamUrl) { try { - PreparedStatement ps = connection.prepareStatement("UPDATE films SET cached = 1 WHERE streamUrl = ?"); - ps.setString(1, streamUrl); + PreparedStatement ps = connection.prepareStatement("UPDATE films SET cached = ? WHERE streamUrl = ?"); + ps.setDate(1, new Date(System.currentTimeMillis())); + ps.setString(2, streamUrl); ps.executeUpdate(); connection.commit(); ps.close(); @@ -501,7 +500,7 @@ public class DBController { while (rs.next()) { notCachedEntries.add(new FilmTabelDataType(rs.getString("streamUrl"), rs.getString("title"), rs.getString("season"), rs.getString("episode"), rs.getBoolean("favorite"), - rs.getBoolean("cached"), new ImageView(favorite_border_black))); + rs.getDate("cached").toLocalDate(), new ImageView(favorite_border_black))); } stmt.close(); rs.close(); @@ -519,7 +518,7 @@ public class DBController { * @return {@link Double} currentTime in ms */ public double getCurrentTime(String streamUrl) { - LOGGER.info("get currentTime: " + streamUrl); + LOGGER.info("get currentTime for " + streamUrl); double currentTime = 0; try { PreparedStatement ps = connection.prepareStatement("SELECT * FROM films WHERE streamUrl = ?"); @@ -541,7 +540,7 @@ public class DBController { * @param currentTime currentTime in ms of the film */ public void setCurrentTime(String streamUrl, double currentTime) { - LOGGER.info("set currentTime: " + streamUrl); + LOGGER.info("set currentTime = " + currentTime + " for " + streamUrl); try { PreparedStatement ps = connection.prepareStatement("UPDATE films SET currentTime = ? WHERE streamUrl = ?"); ps.setDouble(1, currentTime); @@ -586,7 +585,7 @@ public class DBController { // at this point we have found the correct episode nextFilm = new FilmTabelDataType(rs.getString("streamUrl"), rs.getString("title"), rs.getString("season"), rs.getString("episode"), rs.getBoolean("favorite"), - rs.getBoolean("cached"), new ImageView()); + rs.getDate("cached").toLocalDate(), new ImageView()); rs.close(); ps.close(); @@ -596,7 +595,7 @@ public class DBController { return nextFilm; } - /** + /** TODO rework, we should save the next episode in the root entry * get the last watched episode * @param title the title of the series * @return the last watched episode as {@link FilmTabelDataType} object @@ -612,12 +611,9 @@ public class DBController { while (rs.next()) { nextFilm = new FilmTabelDataType(rs.getString("streamUrl"), rs.getString("title"), rs.getString("season"), rs.getString("episode"), rs.getBoolean("favorite"), - rs.getBoolean("cached"), new ImageView()); + rs.getDate("cached").toLocalDate(), new ImageView()); + // get the first episode where currentTime != 0 if (rs.getDouble("currentTime") > lastCurrentTime) { - lastCurrentTime = rs.getDouble("currentTime"); - nextFilm = new FilmTabelDataType(rs.getString("streamUrl"), rs.getString("title"), - rs.getString("season"), rs.getString("episode"), rs.getBoolean("favorite"), - rs.getBoolean("cached"), new ImageView()); break; } } @@ -626,7 +622,7 @@ public class DBController { } catch (Exception e) { LOGGER.error("Ups! error while getting the last watched episode!", e); } - + return nextFilm; } diff --git a/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java b/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java index 3ab3219..f598446 100644 --- a/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java +++ b/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java @@ -85,6 +85,20 @@ public class OMDbAPIController implements Runnable { object = getByTitle(title); } } 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()); + omdbResponse.setPoster("icons/Homeflix_Poster.png"); + + synchronized (this) { + // adding to cache + dbController.addCache(currentTableFilm.getStreamUrl(), omdbResponse); + dbController.setCached(currentTableFilm.getStreamUrl()); + } + return; } } @@ -198,13 +212,10 @@ public class OMDbAPIController implements Runnable { 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); + LOGGER.warn("Movie \"{}\" not found!", title); } return ""; } diff --git a/src/main/java/kellerkinder/HomeFlix/controller/SourcesController.java b/src/main/java/kellerkinder/HomeFlix/controller/SourcesController.java index dc2f6ff..ef07925 100644 --- a/src/main/java/kellerkinder/HomeFlix/controller/SourcesController.java +++ b/src/main/java/kellerkinder/HomeFlix/controller/SourcesController.java @@ -26,6 +26,7 @@ import java.io.File; import java.io.FileReader; import java.io.IOException; import java.nio.file.Files; +import java.sql.Date; import java.util.ArrayList; import java.util.List; @@ -88,7 +89,7 @@ public class SourcesController { for (File file : new File(path).listFiles()) { // if it's valid file add it to the sourceStreams if (isValidFile(file)) { - sourceStreams.add(new DatabaseDataType(file.getPath(), cutOffEnd(file.getName()), "", "", 0, false, 0.0)); + sourceStreams.add(new DatabaseDataType(file.getPath(), cutOffEnd(file.getName()), "", "", 0, new Date(0), 0.0)); } else if(file.isDirectory()) { // get all directories (series), root and season must be directories int sn = 1; @@ -99,7 +100,7 @@ public class SourcesController { // check whether the episode is a valid file if (isValidFile(episode)) { sourceStreams.add(new DatabaseDataType(episode.getPath(), cutOffEnd(file.getName()), - Integer.toString(sn), Integer.toString(ep), 0, false, 0.0)); + Integer.toString(sn), Integer.toString(ep), 0, new Date(0), 0.0)); ep++; } } @@ -121,7 +122,7 @@ public class SourcesController { sourceStreams.add(new DatabaseDataType(item.asObject().getString("streamUrl", ""), item.asObject().getString("title", ""), item.asObject().getString("season", ""), - item.asObject().getString("episode", ""), 0, false, 0.0)); + item.asObject().getString("episode", ""), 0, new Date(0), 0.0)); } LOGGER.info("added " + items.size() +" stream entries from: " + path); } catch (IOException e) { diff --git a/src/main/java/kellerkinder/HomeFlix/datatypes/DatabaseDataType.java b/src/main/java/kellerkinder/HomeFlix/datatypes/DatabaseDataType.java index 31c089f..e22548c 100644 --- a/src/main/java/kellerkinder/HomeFlix/datatypes/DatabaseDataType.java +++ b/src/main/java/kellerkinder/HomeFlix/datatypes/DatabaseDataType.java @@ -22,6 +22,8 @@ package kellerkinder.HomeFlix.datatypes; +import java.sql.Date; + public class DatabaseDataType { private String streamUrl; @@ -29,10 +31,10 @@ public class DatabaseDataType { private String season; private String episode; private int favorite; - private Boolean cached; + private Date cached; private double currentTime; - public DatabaseDataType(String streamUrl, String title, String season, String episode, int favorite, Boolean cached, double currentTime) { + public DatabaseDataType(String streamUrl, String title, String season, String episode, int favorite, Date cached, double currentTime) { this.streamUrl = streamUrl; this.title = title; this.season = season; @@ -82,11 +84,11 @@ public class DatabaseDataType { this.favorite = favorite; } - public Boolean getCached() { + public Date getCached() { return cached; } - public void setCached(Boolean cached) { + public void setCached(Date cached) { this.cached = cached; } diff --git a/src/main/java/kellerkinder/HomeFlix/datatypes/FilmTabelDataType.java b/src/main/java/kellerkinder/HomeFlix/datatypes/FilmTabelDataType.java index b019752..0d7301c 100644 --- a/src/main/java/kellerkinder/HomeFlix/datatypes/FilmTabelDataType.java +++ b/src/main/java/kellerkinder/HomeFlix/datatypes/FilmTabelDataType.java @@ -20,6 +20,8 @@ */ package kellerkinder.HomeFlix.datatypes; +import java.time.LocalDate; + import javafx.beans.property.BooleanProperty; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleObjectProperty; @@ -33,7 +35,7 @@ public class FilmTabelDataType { private final StringProperty season = new SimpleStringProperty(); private final StringProperty episode = new SimpleStringProperty(); private final BooleanProperty favorite = new SimpleBooleanProperty(); - private final BooleanProperty cached = new SimpleBooleanProperty(); + private final SimpleObjectProperty cached = new SimpleObjectProperty<>(); private final SimpleObjectProperty image = new SimpleObjectProperty<>(); /** @@ -47,7 +49,7 @@ public class FilmTabelDataType { * @param image favorite icon */ public FilmTabelDataType(final String streamUrl, final String title, final String season, final String episode, - final boolean favorite, final boolean cached, final ImageView image) { + final boolean favorite, final LocalDate cached, final ImageView image) { this.streamUrl.set(streamUrl); this.title.set(title); this.season.set(season); @@ -77,7 +79,7 @@ public class FilmTabelDataType { return favorite; } - public BooleanProperty cachedProperty(){ + public SimpleObjectProperty cachedProperty(){ return cached; } @@ -106,7 +108,7 @@ public class FilmTabelDataType { return favoriteProperty().get(); } - public final boolean getCached(){ + public final LocalDate getCached(){ return cachedProperty().get(); } @@ -135,7 +137,7 @@ public class FilmTabelDataType { favoriteProperty().set(favorite); } - public final void setCached(boolean cached){ + public final void setCached(LocalDate cached){ cachedProperty().set(cached); }