added a check for new releases

This commit is contained in:
hneemann 2018-01-02 13:12:47 +01:00
parent 1286a36688
commit cd6e39dd4f
8 changed files with 195 additions and 8 deletions

View File

@ -240,6 +240,12 @@
<version>${version.org.slf4j}</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20171018</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>

View File

@ -31,6 +31,7 @@ import de.neemann.digital.gui.components.table.TableDialog;
import de.neemann.digital.gui.components.testing.ValueTableDialog;
import de.neemann.digital.gui.components.tree.LibraryTreeModel;
import de.neemann.digital.gui.components.tree.SelectTree;
import de.neemann.digital.gui.release.CheckForNewRelease;
import de.neemann.digital.gui.remote.DigitalHandler;
import de.neemann.digital.gui.remote.RemoteException;
import de.neemann.digital.gui.remote.RemoteSever;
@ -1571,6 +1572,8 @@ public final class Main extends JFrame implements ClosingWindowListener.ConfirmS
SwingUtilities.invokeLater(() -> main.statusLabel.setText(Lang.get("err_portIsInUse")));
}
main.setVisible(true);
CheckForNewRelease.getInstance().showReleaseDialog(main);
});
}

View File

@ -0,0 +1,85 @@
package de.neemann.digital.gui.release;
import de.neemann.digital.lang.Lang;
import de.neemann.gui.InfoDialog;
import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.util.prefs.Preferences;
/**
* Helper to check for a new release.
*/
public final class CheckForNewRelease {
private static class InstanceHolder {
private static final CheckForNewRelease INSTANCE = new CheckForNewRelease();
}
/**
* @return the instance
*/
public static CheckForNewRelease getInstance() {
return InstanceHolder.INSTANCE;
}
private static final long ADAY = 24L * 60 * 60 * 1000;
private static final String PREF_LAST = "last";
private static final String PREF_ASKED = "asked";
private static final Preferences PREFS = Preferences.userRoot().node("dig").node("rev");
private String actual;
private CheckForNewRelease() {
}
/**
* Returns true if there is a new release.
* Connects the server only once a day and returns true only once for every new release.
*
* @param runnable started if there is a new release!
*/
private void startIfNewRelease(Runnable runnable) {
long lastAsked = PREFS.getLong(PREF_LAST, -1);
long time = System.currentTimeMillis();
if (time - lastAsked < ADAY) return;
PREFS.putLong(PREF_LAST, time);
Thread thread = new Thread(() -> {
String rev = InfoDialog.getInstance().getRevision();
if (rev.equals(InfoDialog.UNKNOWN)) return;
try {
ReleaseInfo info = new ReleaseInfo();
actual = info.getVersion();
if (actual != null) {
String asked = PREFS.get(PREF_ASKED, "none");
if (asked.equals(actual))
return;
PREFS.put(PREF_ASKED, actual);
SwingUtilities.invokeLater(runnable);
}
} catch (IOException e) {
e.printStackTrace();
}
});
thread.setDaemon(true);
thread.start();
}
/**
* Shows a new release pop up
*
* @param parent the parent window
*/
public void showReleaseDialog(Component parent) {
startIfNewRelease(() -> {
String msg = Lang.get("msg_newRelease_N", actual);
InfoDialog.showInfo(parent, msg, "");
});
}
}

View File

@ -0,0 +1,52 @@
package de.neemann.digital.gui.release;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
/**
* Checks for new releases
*/
public final class ReleaseInfo {
private static final String RELEASE_URL = "https://api.github.com/repos/hneemann/Digital/releases/latest";
private String version;
private String url;
/**
* Creates a new instance
*
* @throws IOException IOException
*/
ReleaseInfo() throws IOException {
try (InputStream in = new URL(RELEASE_URL).openStream()) {
JSONTokener tok = new JSONTokener(in);
JSONObject obj = new JSONObject(tok);
version = obj.get("tag_name").toString();
url = obj.get("html_url").toString();
} catch (JSONException e) {
throw new IOException(e);
}
}
/**
* @return the actual version
*/
public String getVersion() {
return version;
}
/**
* @return the url of the release page
*/
public String getUrl() {
return url;
}
}

View File

@ -0,0 +1,4 @@
/**
* Helpers to check for a new release.
*/
package de.neemann.digital.gui.release;

View File

@ -23,9 +23,13 @@ import java.util.jar.JarFile;
* Created by hneemann on 23.03.15.
*/
public final class InfoDialog implements Iterable<InfoDialog.Manifest> {
/**
* Unknown release
*/
public static final String UNKNOWN = "unknown";
private static InfoDialog instance;
private final ArrayList<Manifest> infos;
private String revision = "unknown";
private String revision = UNKNOWN;
/**
* @return the singleton instance
@ -69,16 +73,17 @@ public final class InfoDialog implements Iterable<InfoDialog.Manifest> {
}
/**
* Shows the message in a JOptioPane dialog
* Shows the message in a dialog
*
* @param parent the parent component
* @param message the message
* @param parent the parent component
* @param message the message
* @param revision the "{{version}}" url version replacement
*/
private void showInfo(Component parent, String message) {
public static void showInfo(Component parent, String message, String revision) {
final JDialog dialog = new JDialog(SwingUtilities.getWindowAncestor(parent), Lang.get("menu_about"), Dialog.ModalityType.APPLICATION_MODAL);
dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
JEditorPane ta = new JEditorPane("text/html", createMessage(message));
JEditorPane ta = new JEditorPane("text/html", message);
ta.setCaretPosition(0);
ta.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, true);
ta.setEditable(false);
@ -137,7 +142,7 @@ public final class InfoDialog implements Iterable<InfoDialog.Manifest> {
help.add(new AbstractAction(Lang.get("menu_about")) {
@Override
public void actionPerformed(ActionEvent actionEvent) {
showInfo(frame, message);
showInfo(frame, createMessage(message), revision);
}
});
return help;
@ -148,6 +153,13 @@ public final class InfoDialog implements Iterable<InfoDialog.Manifest> {
return infos.iterator();
}
/**
* @return the revision
*/
public String getRevision() {
return revision;
}
/**
* A simple Manifest parser
*/

View File

@ -1184,7 +1184,9 @@ Geschrieben von H. Neemann 2016-2018
Die Icons stammen aus dem &lt;a href=&quot;http://tango.freedesktop.org&quot;&gt;Tango Desktop Project&lt;/a&gt;.
Besuche das Projekt auf &lt;a href=&quot;https://github.com/hneemann/Digital&quot;&gt;GitHub&lt;/a&gt;.
Dort kann auch ein &lt;a href=&quot;https://github.com/hneemann/Digital/issues/new?body=version:%20{{version}}&amp;labels=bug&quot;&gt;Fehler&lt;/a&gt; gemeldet oder
Die jeweils neueste Version steht dort ebenfalls zum &lt;a href=&quot;https://github.com/hneemann/Digital/releases/latest&quot;&gt;Download&lt;/a&gt; bereit.
Per GitHub kann auch ein &lt;a href=&quot;https://github.com/hneemann/Digital/issues/new?body=version:%20{{version}}&amp;labels=bug&quot;&gt;Fehler&lt;/a&gt; gemeldet oder
eine &lt;a href=&quot;https://github.com/hneemann/Digital/issues/new?labels=enhancement&quot;&gt;Verbesserung&lt;/a&gt; vorgeschlagen werden.
</string>
<string name="msg_N_nodes">{0} aktive Elemente</string>
@ -1282,6 +1284,17 @@ eine &lt;a href=&quot;https://github.com/hneemann/Digital/issues/new?labels=enha
<string name="win_karnaughMap">Karnaugh-Veitch Tafel</string>
<string name="btn_help">Hilfe</string>
<string name="msg_newRelease_N"><![CDATA[
<html>
<h1>Neue Version {0} Verfügbar</h1>
<p>Es ist eine neue Version des Simulators verfügbar.</p>
<p>In den <a href="https://github.com/hneemann/Digital/releases/latest">Release Notes</a>
können Sie nachlesen, was sich in der Version {0} verändert hat.</p>
<p>Hier geht es zum <a href="https://github.com/hneemann/Digital/releases/latest">Download</a>.</p>
</html>
]]></string>
<string name="msg_expressionHelpTitle">Ausdrücke</string>
<string name="msg_expressionHelp">Zur Definition eines Ausdruckes können alle üblichen
Notationen verwendet werden:

View File

@ -1174,6 +1174,8 @@ Written by H. Neemann in 2016-2018.
The icons are taken from the &lt;a href=&quot;http://tango.freedesktop.org&quot;&gt;Tango Desktop Project&lt;/a&gt;.
Visit the project at &lt;a href=&quot;https://github.com/hneemann/Digital&quot;&gt;GitHub&lt;/a&gt;.
At Github you can also &lt;a href=&quot;https://github.com/hneemann/Digital/releases/latest&quot;&gt;download&lt;/a&gt; the latest release.
There you also can file an &lt;a href=&quot;https://github.com/hneemann/Digital/issues/new?body=version:%20{{version}}&amp;labels=bug&quot;&gt;issue&lt;/a&gt; or suggest
an &lt;a href=&quot;https://github.com/hneemann/Digital/issues/new?labels=enhancement&quot;&gt;enhancement&lt;/a&gt;.
</string>
@ -1271,6 +1273,16 @@ an &lt;a href=&quot;https://github.com/hneemann/Digital/issues/new?labels=enhanc
<string name="btn_help">Help</string>
<string name="msg_newRelease_N"><![CDATA[
<html>
<h1>New Version {0} Available</h1>
<p>There is a new release of the simulator available.</p>
<p>In the <a href="https://github.com/hneemann/Digital/releases/latest">release notes</a>
you can find the changes and improvements.</p>
<p>Here you can <a href="https://github.com/hneemann/Digital/releases/latest">download</a> the new release.</p>
</html>
]]></string>
<string name="msg_expressionHelpTitle">Expressions</string>
<string name="msg_expressionHelp">To define an expression you can use all most common notations: