From 08f39e5fad8f0c716d60125e42f8097bed315f4c Mon Sep 17 00:00:00 2001
From: lantzelot-swe <miklantz@gmail.com>
Date: Tue, 22 Dec 2020 23:47:39 +0100
Subject: [PATCH] Adds version check dialog. Adds year and genre to Moby games
 scraper

---
 .classpath                                    |  1 +
 pom.xml                                       |  5 ++
 src/main/java/se/lantz/gui/MenuManager.java   | 43 +++++-------
 .../se/lantz/gui/VersionDownloadDialog.java   | 24 +++++++
 .../se/lantz/gui/VersionDownloadPanel.java    | 68 +++++++++++++++++++
 .../gui/scraper/MobyGamesOptionsPanel.java    |  1 +
 .../se/lantz/gui/scraper/ScraperDialog.java   |  2 +-
 .../java/se/lantz/model/MainViewModel.java    | 20 +++++-
 .../java/se/lantz/util/MobyGamesScraper.java  | 38 +++++++++--
 .../java/se/lantz/util/VersionChecker.java    | 68 +++++++++++++++++++
 10 files changed, 234 insertions(+), 36 deletions(-)
 create mode 100644 src/main/java/se/lantz/gui/VersionDownloadDialog.java
 create mode 100644 src/main/java/se/lantz/gui/VersionDownloadPanel.java
 create mode 100644 src/main/java/se/lantz/util/VersionChecker.java

diff --git a/.classpath b/.classpath
index c767d43..613eae3 100644
--- a/.classpath
+++ b/.classpath
@@ -12,4 +12,5 @@
   <classpathentry kind="var" path="M2_REPO/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar" sourcepath="M2_REPO/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/org/jsoup/jsoup/1.11.3/jsoup-1.11.3.jar" sourcepath="M2_REPO/org/jsoup/jsoup/1.11.3/jsoup-1.11.3-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/com/jtattoo/JTattoo/1.6.7/JTattoo-1.6.7.jar" sourcepath="M2_REPO/com/jtattoo/JTattoo/1.6.7/JTattoo-1.6.7-sources.jar"/>
+  <classpathentry kind="var" path="M2_REPO/com/google/code/gson/gson/2.8.0/gson-2.8.0.jar" sourcepath="M2_REPO/com/google/code/gson/gson/2.8.0/gson-2.8.0-sources.jar"/>
 </classpath>
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index cad3f85..fdcee1f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -37,6 +37,11 @@
 			<artifactId>JTattoo</artifactId>
 			<version>1.6.7</version>
 		</dependency>
+		<dependency>
+			<groupId>com.google.code.gson</groupId>
+			<artifactId>gson</artifactId>
+			<version>2.8.0</version>
+		</dependency>
 	</dependencies>
 	<build>
 		<plugins>
diff --git a/src/main/java/se/lantz/gui/MenuManager.java b/src/main/java/se/lantz/gui/MenuManager.java
index 33c813b..1630680 100644
--- a/src/main/java/se/lantz/gui/MenuManager.java
+++ b/src/main/java/se/lantz/gui/MenuManager.java
@@ -43,6 +43,7 @@ import se.lantz.model.MainViewModel;
 import se.lantz.model.data.GameListData;
 import se.lantz.util.ExceptionHandler;
 import se.lantz.util.FileManager;
+import se.lantz.util.VersionChecker;
 
 public class MenuManager
 {
@@ -106,8 +107,8 @@ public class MenuManager
     dbMenu.add(getCreateEmptyDbItem());
     helpMenu = new JMenu("Help");
     helpMenu.add(getHelpItem());
+    helpMenu.add(getCheckVersionItem());
     helpMenu.add(getAboutItem());
-    helpMenu.add(getNewVersionItem());
   }
 
   public void intialize()
@@ -234,10 +235,10 @@ public class MenuManager
     });
     return aboutItem;
   }
-  
-  private JMenuItem getNewVersionItem()
+
+  private JMenuItem getCheckVersionItem()
   {
-    newVersionItem = new JMenuItem("Check for new version...");
+    newVersionItem = new JMenuItem("Check for updates");
     newVersionItem.addActionListener(e -> {
       checkForNewRelease();
     });
@@ -369,35 +370,25 @@ public class MenuManager
     }
   }
 
-  /**
-   * Fetches the latet version information from github
-   */
   private void checkForNewRelease()
   {
-    try
+    VersionChecker.fetchLatestVersionFromGithub();
+    if (VersionChecker.isNewVersionAvailable())
     {
-      URL url = new URL("https://lantzelot-swe@api.github.com/repos/lantzelot-swe/PCUGameManager/releases/latest");
-      HttpURLConnection con = (HttpURLConnection) url.openConnection();
-      con.setRequestProperty("accept", "application/vnd.github.v3+json");
-      con.setRequestMethod("GET");
-      StringBuilder builder = new StringBuilder();
-      Scanner scanner = new Scanner(url.openStream());
-      while (scanner.hasNext())
+      VersionDownloadDialog dialog = new VersionDownloadDialog(MainWindow.getInstance());
+      dialog.pack();
+      dialog.setLocationRelativeTo(MainWindow.getInstance());
+      if (dialog.showDialog())
       {
-        builder.append(scanner.nextLine() + "/n");
+        getExitItem().doClick();
       }
-      scanner.close();
-      con.disconnect();
-     
-      JsonReader reader = new JsonReader(new StringReader(builder.toString()));
-      reader.setLenient(true);
-      JsonElement root = new JsonParser().parse(reader);
-      String tagName = root.getAsJsonObject().get("tag_name").getAsString();
-      System.out.println("tagName = " + tagName);
     }
-    catch (IOException ex)
+    else
     {
-      ExceptionHandler.handleException(ex, "Could not check version");
+      JOptionPane.showMessageDialog(this.mainWindow,
+                                    "This is the latest version.",
+                                    "Version check",
+                                    JOptionPane.INFORMATION_MESSAGE);
     }
   }
 }
diff --git a/src/main/java/se/lantz/gui/VersionDownloadDialog.java b/src/main/java/se/lantz/gui/VersionDownloadDialog.java
new file mode 100644
index 0000000..9ce5bd0
--- /dev/null
+++ b/src/main/java/se/lantz/gui/VersionDownloadDialog.java
@@ -0,0 +1,24 @@
+package se.lantz.gui;
+
+import java.awt.Frame;
+
+public class VersionDownloadDialog extends BaseDialog
+{
+  private VersionDownloadPanel panel;
+
+  public VersionDownloadDialog(Frame owner)
+  {
+    super(owner);
+    setTitle("Version check");
+    addContent(getVersionDownloadPanel());
+    getOkButton().setText("Exit");
+  }
+
+  private VersionDownloadPanel getVersionDownloadPanel() {
+    if (panel == null) {
+    	panel = new VersionDownloadPanel();
+    }
+    return panel;
+  }
+ 
+}
diff --git a/src/main/java/se/lantz/gui/VersionDownloadPanel.java b/src/main/java/se/lantz/gui/VersionDownloadPanel.java
new file mode 100644
index 0000000..fa3479f
--- /dev/null
+++ b/src/main/java/se/lantz/gui/VersionDownloadPanel.java
@@ -0,0 +1,68 @@
+package se.lantz.gui;
+
+import java.awt.Desktop;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.io.IOException;
+import java.net.URISyntaxException;
+
+import javax.swing.JEditorPane;
+import javax.swing.JPanel;
+import javax.swing.UIManager;
+import javax.swing.event.HyperlinkEvent;
+
+import se.lantz.util.ExceptionHandler;
+import se.lantz.util.VersionChecker;
+
+public class VersionDownloadPanel extends JPanel
+{
+  private JEditorPane editorPane;
+
+  public VersionDownloadPanel()
+  {
+    GridBagLayout gridBagLayout = new GridBagLayout();
+    setLayout(gridBagLayout);
+    GridBagConstraints gbc_editorPane = new GridBagConstraints();
+    gbc_editorPane.weighty = 1.0;
+    gbc_editorPane.weightx = 1.0;
+    gbc_editorPane.insets = new Insets(10, 10, 10, 10);
+    gbc_editorPane.fill = GridBagConstraints.BOTH;
+    gbc_editorPane.gridx = 0;
+    gbc_editorPane.gridy = 0;
+    add(getEditorPane(), gbc_editorPane);
+  }
+
+  private JEditorPane getEditorPane()
+  {
+    if (editorPane == null)
+    {
+      String downloadUrl = VersionChecker.getDownloadUrl();
+      String info = "<html>There is a new version of PCU Game Manager available: <b>" +
+        VersionChecker.getLatestVersion() + "</b><p>" + "Go to <a href='" + downloadUrl + "'>" + downloadUrl +
+        "</a> and download PCUGameManager.exe.<br>" +
+        "Exit PCU Game Manager and replace the existing PCUGameManager.exe with the downloaded file to upgrade.</html>";
+
+      editorPane = new JEditorPane("text/html", info);
+      editorPane.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE);
+      editorPane.setFont(UIManager.getDefaults().getFont("Label.font"));
+      editorPane.setEditable(false);
+      editorPane.setOpaque(false);
+      editorPane.addHyperlinkListener((hle) -> {
+        if (HyperlinkEvent.EventType.ACTIVATED.equals(hle.getEventType()) && Desktop.isDesktopSupported() &&
+          Desktop.getDesktop().isSupported(Desktop.Action.BROWSE))
+        {
+          try
+          {
+            Desktop.getDesktop().browse(hle.getURL().toURI());
+          }
+          catch (IOException | URISyntaxException e)
+          {
+            ExceptionHandler.handleException(e, "Could not open default browser");
+          }
+        }
+      });
+    }
+    return editorPane;
+  }
+}
diff --git a/src/main/java/se/lantz/gui/scraper/MobyGamesOptionsPanel.java b/src/main/java/se/lantz/gui/scraper/MobyGamesOptionsPanel.java
index 839ab0d..848538a 100644
--- a/src/main/java/se/lantz/gui/scraper/MobyGamesOptionsPanel.java
+++ b/src/main/java/se/lantz/gui/scraper/MobyGamesOptionsPanel.java
@@ -101,6 +101,7 @@ public class MobyGamesOptionsPanel extends JPanel
         "(Example: https://www.mobygames.com/game/c64/arkanoid)</li></ol></html>";
 
       infoEditorPane = new JEditorPane("text/html", info);
+      infoEditorPane.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE);
       infoEditorPane.setFont(UIManager.getDefaults().getFont("Label.font"));
       infoEditorPane.setEditable(false);
       infoEditorPane.setOpaque(false);
diff --git a/src/main/java/se/lantz/gui/scraper/ScraperDialog.java b/src/main/java/se/lantz/gui/scraper/ScraperDialog.java
index af5381b..98d8a81 100644
--- a/src/main/java/se/lantz/gui/scraper/ScraperDialog.java
+++ b/src/main/java/se/lantz/gui/scraper/ScraperDialog.java
@@ -8,7 +8,6 @@ import javax.swing.JPanel;
 import se.lantz.gui.BaseDialog;
 import se.lantz.model.MainViewModel;
 import se.lantz.model.data.ScraperFields;
-import se.lantz.util.MobyGamesScraper;
 
 public class ScraperDialog extends BaseDialog
 {
@@ -23,6 +22,7 @@ public class ScraperDialog extends BaseDialog
     content.add(getMobyGamesPanel(), BorderLayout.CENTER);
     addContent(content);
     setTitle("Scrape game information");
+    this.setResizable(false);
   }
 
   private MobyGamesOptionsPanel getMobyGamesPanel()
diff --git a/src/main/java/se/lantz/model/MainViewModel.java b/src/main/java/se/lantz/model/MainViewModel.java
index 6b7e145..9f3ce56 100644
--- a/src/main/java/se/lantz/model/MainViewModel.java
+++ b/src/main/java/se/lantz/model/MainViewModel.java
@@ -6,6 +6,8 @@ import java.io.File;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import javax.swing.DefaultComboBoxModel;
 import javax.swing.ListModel;
@@ -436,13 +438,25 @@ public class MainViewModel extends AbstractModel
     }
     if (fields.isYear())
     {
-      //TODO: Parse properly
-     // infoModel.setYear(Integer.parseInt(scraper.scrapeYear()));
+      Pattern p = Pattern.compile("\\d+");
+      Matcher m = p.matcher(scraper.scrapeYear());
+      if (m.find())
+      {
+        infoModel.setYear(Integer.parseInt(m.group()));
+      }
     }
     if (fields.isDescription())
     {
       infoModel.setDescription(scraper.scrapeDescription());
     }
-    //TODO: Genre, cover, screenshots
+    if (fields.isGenre())
+    {
+      String genre = scraper.scrapeGenre();
+      if (!genre.isEmpty())
+      {
+        infoModel.setGenre(genre);
+      }
+    }
+    //TODO: cover, screenshots
   }
 }
diff --git a/src/main/java/se/lantz/util/MobyGamesScraper.java b/src/main/java/se/lantz/util/MobyGamesScraper.java
index 557a280..a2279ec 100644
--- a/src/main/java/se/lantz/util/MobyGamesScraper.java
+++ b/src/main/java/se/lantz/util/MobyGamesScraper.java
@@ -6,7 +6,9 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.URL;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import javax.imageio.ImageIO;
 import javax.swing.ImageIcon;
@@ -44,6 +46,8 @@ public class MobyGamesScraper
 
   private long startTime = 0L;
 
+  Map<String, String> genreMap = new HashMap<>();
+  
   public MobyGamesScraper()
   {
     // TODO Auto-generated constructor stub
@@ -53,6 +57,14 @@ public class MobyGamesScraper
   //*[@id="main"]/div/div[3]/div[1]/h2[1]
     
     //*[@id="coreGameCover"]/a/img
+    
+    //Keys are Genres defined on MobyGames, values are supported genres in the tool
+    genreMap.put("Adventure, Role-Playing (RPG)", "adventure");
+    genreMap.put("Racing / driving", "driving");
+    genreMap.put("Puzzle, Strategy / tactics", "puzzle");
+    genreMap.put("Educational", "programming");
+    genreMap.put("Simulation", "simulation");
+    genreMap.put("Sports", "sport");
   }
 
   public static void main(String[] args)
@@ -100,12 +112,7 @@ public class MobyGamesScraper
   {
     return scarpeElementValue(yearCssQuery);
   }
-
-  public String scrapeGenre()
-  {
-    return scarpeElementValue(genreCssQuery);
-  }
-
+  
   private void scrapeMobyGames()
   {
     startTime = System.currentTimeMillis();
@@ -150,6 +157,25 @@ public class MobyGamesScraper
     }
     return "";
   }
+  
+  public String scrapeGenre()
+  {
+    String genreFromMobyGames = scarpeElementValue(genreCssQuery);
+    String[] split = genreFromMobyGames.split(", ");
+    for (int i = 0; i < split.length; i++)
+    {
+      //Map towards available genres, return first one found
+      for (Map.Entry<String, String> entry : genreMap.entrySet()) {
+        if (entry.getKey().contains(split[i]))
+        {
+          System.out.println(entry.getKey() + "/" + entry.getValue());
+          return entry.getValue();
+        } 
+      }
+    }
+    
+    return "";
+  }
 
   private String scarpeElementValue(String cssQuery)
   {
diff --git a/src/main/java/se/lantz/util/VersionChecker.java b/src/main/java/se/lantz/util/VersionChecker.java
new file mode 100644
index 0000000..a8705fb
--- /dev/null
+++ b/src/main/java/se/lantz/util/VersionChecker.java
@@ -0,0 +1,68 @@
+package se.lantz.util;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Scanner;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParser;
+import com.google.gson.stream.JsonReader;
+
+public class VersionChecker
+{
+  private static String latestVersion = "";
+  private static String downloadUrl = "";
+  private VersionChecker()
+  {
+    //Empty
+  }
+  
+  public static void fetchLatestVersionFromGithub()
+  {
+    try
+    {
+      URL url = new URL("https://lantzelot-swe@api.github.com/repos/lantzelot-swe/PCUGameManager/releases/latest");
+      HttpURLConnection con = (HttpURLConnection) url.openConnection();
+      con.setRequestProperty("accept", "application/vnd.github.v3+json");
+      con.setRequestMethod("GET");
+      StringBuilder builder = new StringBuilder();
+      Scanner scanner = new Scanner(url.openStream());
+      while (scanner.hasNext())
+      {
+        builder.append(scanner.nextLine() + "/n");
+      }
+      scanner.close();
+      con.disconnect();
+     
+      JsonReader reader = new JsonReader(new StringReader(builder.toString()));
+      reader.setLenient(true);
+      JsonElement root = new JsonParser().parse(reader);
+      latestVersion = root.getAsJsonObject().get("tag_name").getAsString();
+      System.out.println("tagName = " + latestVersion);
+      downloadUrl = root.getAsJsonObject().get("html_url").getAsString();
+      System.out.println("html url = " + downloadUrl);
+    }
+    catch (IOException ex)
+    {
+      ExceptionHandler.handleException(ex, "Could not check version");
+    }
+  }
+  
+  public static boolean isNewVersionAvailable()
+  {
+    return !FileManager.getPcuVersionFromManifest().equals(latestVersion);
+  }
+
+  public static String getLatestVersion()
+  {
+    return latestVersion;
+  }
+
+  public static String getDownloadUrl()
+  {
+    return downloadUrl;
+  }
+
+}