diff --git a/pom.xml b/pom.xml
index c994912..3718fba 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
de.lars.remotelightweb
remotelightweb
RemoteLightWeb
- 1.0-SNAPSHOT2
+ 1.0.1
jar
@@ -134,6 +134,11 @@
remotelight
0.2.0.7.2
+
+ de.lars
+ updater
+ 1.1
+
diff --git a/src/main/java/de/lars/remotelightweb/RemoteLightWeb.java b/src/main/java/de/lars/remotelightweb/RemoteLightWeb.java
index 8092ecd..1e76215 100644
--- a/src/main/java/de/lars/remotelightweb/RemoteLightWeb.java
+++ b/src/main/java/de/lars/remotelightweb/RemoteLightWeb.java
@@ -1,5 +1,6 @@
package de.lars.remotelightweb;
+import java.io.File;
import java.io.InputStream;
import java.nio.file.Paths;
import java.util.Properties;
@@ -8,10 +9,16 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration;
+import org.springframework.boot.system.ApplicationHome;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import de.lars.remotelightclient.api.RemoteLightAPI;
+import de.lars.remotelightclient.settings.SettingsManager;
+import de.lars.remotelightclient.settings.SettingsManager.SettingCategory;
+import de.lars.remotelightclient.settings.types.SettingBoolean;
+import de.lars.remotelightclient.settings.types.SettingString;
import de.lars.remotelightweb.backend.ConfigFile;
+import de.lars.remotelightweb.backend.utils.UpdateUtil;
/**
* The entry point of the Spring Boot application.
@@ -25,6 +32,7 @@ public class RemoteLightWeb extends SpringBootServletInitializer {
private static ConfigurableApplicationContext context;
private static RemoteLightWeb instance;
private RemoteLightAPI rlApi;
+ private UpdateUtil updateUtil;
private boolean closing;
public static void main(String[] args) {
@@ -39,6 +47,8 @@ public RemoteLightWeb() {
RemoteLightAPI.setRootDirectory(Paths.get(".").toAbsolutePath().normalize().toString()); // directory where the jar was executed
RemoteLightAPI.setRootName(ROOT_FOLDER_NAME);
rlApi = new RemoteLightAPI();
+ updateUtil = new UpdateUtil(VERSION);
+ setup(); // initial some settings and check for updates
}
@@ -93,5 +103,26 @@ private static String getVersion() {
}
return "?";
}
+
+ public UpdateUtil getUpdateUtil() {
+ return updateUtil;
+ }
+
+ private void setup() {
+ SettingsManager s = getAPI().getSettingsManager();
+ // disable standard updater
+ ((SettingBoolean) s.getSettingFromId("main.checkupdates")).setValue(false);
+ // add RemoteLightWeb updater setting
+ s.addSetting(new SettingBoolean("rlweb.updater", "Updater", SettingCategory.General, "Check for updates at startup", true));
+
+ File jarDir = new ApplicationHome(RemoteLightWeb.class).getSource();
+ String runCommand = "java -jar " + jarDir.getAbsolutePath();
+ s.addSetting(new SettingString("rlweb.runcmd", "Run command after update", SettingCategory.Others, "This command is executed after an update", runCommand));
+
+ // check for updates
+ if(((SettingBoolean) s.getSettingFromId("rlweb.updater")).getValue() && !VERSION.equals("?")) {
+ updateUtil.check();
+ }
+ }
}
diff --git a/src/main/java/de/lars/remotelightweb/backend/ConfigFile.java b/src/main/java/de/lars/remotelightweb/backend/ConfigFile.java
index 7fc8527..b69a7f0 100644
--- a/src/main/java/de/lars/remotelightweb/backend/ConfigFile.java
+++ b/src/main/java/de/lars/remotelightweb/backend/ConfigFile.java
@@ -19,8 +19,10 @@ public class ConfigFile {
public ConfigFile() {
// copy config file from classpath if not exists
- if(!new File(RemoteLightWeb.ROOT_FOLDER_NAME + File.separator + CONFIG_FILE_NAME).exists()) {
+ File config = new File(RemoteLightWeb.ROOT_FOLDER_NAME + File.separator + CONFIG_FILE_NAME);
+ if(!config.exists()) {
try {
+ config.getParentFile().mkdirs();
InputStream input = getClass().getClassLoader().getResourceAsStream(CONFIG_CLASSPATH);
Files.copy(input, new File(RemoteLightWeb.ROOT_FOLDER_NAME + File.separator + CONFIG_FILE_NAME).toPath());
} catch (IOException e) {
diff --git a/src/main/java/de/lars/remotelightweb/backend/utils/UpdateUtil.java b/src/main/java/de/lars/remotelightweb/backend/utils/UpdateUtil.java
new file mode 100644
index 0000000..63b6dd1
--- /dev/null
+++ b/src/main/java/de/lars/remotelightweb/backend/utils/UpdateUtil.java
@@ -0,0 +1,98 @@
+package de.lars.remotelightweb.backend.utils;
+
+import java.io.File;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.nio.file.Paths;
+
+import org.springframework.boot.system.ApplicationHome;
+import org.tinylog.Logger;
+
+import de.lars.remotelightclient.settings.types.SettingString;
+import de.lars.remotelightclient.utils.DirectoryUtil;
+import de.lars.remotelightweb.RemoteLightWeb;
+import de.lars.updater.sites.GitHubParser;
+import de.lars.updater.utils.FileDownloader;
+
+public class UpdateUtil {
+
+ public final String API_URL = "https://api.github.com/repos/Drumber/RemoteLightWeb/releases";
+ private final String UPDATER_NAME = "updater.jar";
+ private GitHubParser parser;
+
+ public UpdateUtil(String currentVersion) {
+ parser = new GitHubParser(currentVersion, API_URL);
+ }
+
+ public void check() {
+ try {
+ parser.check();
+ } catch (Exception e) {
+ Logger.error(e, "Error while checking for updates.");
+ }
+ }
+
+ public GitHubParser getParser() {
+ return parser;
+ }
+
+
+ /**
+ * Download latest release and replace current jar file
+ * This method will EXIT the application!
+ * @param shutdown Should the system be shut down after the update?
+ * @throws Exception
+ */
+ public void install(boolean shutdown) throws Exception {
+ File jarDir = new ApplicationHome(RemoteLightWeb.class).getSource();
+
+ String rootDir = DirectoryUtil.getRootPath();
+ rootDir = Paths.get(".").toAbsolutePath().normalize().toString();
+
+ //download updater jar
+ File updaterFile = downloadUpdater(rootDir);
+
+ // execute updater
+ String args = "-cv " + RemoteLightWeb.VERSION + " -o \"" + jarDir.getAbsolutePath() +
+ "\" -u " + API_URL + " -w -cmd \"";
+
+ if(shutdown) {
+ args += "\"shutdown -h now\"";
+ } else {
+ String runCmd = ((SettingString) RemoteLightWeb.getInstance().getAPI().getSettingsManager().getSettingFromId("rlweb.runcmd")).getValue();
+ if(runCmd == null || runCmd.isEmpty()) {
+ runCmd = "\"java -jar " + jarDir.getAbsolutePath() + "\"";
+ }
+ args += runCmd;
+ }
+ args += "\"";
+
+ String command = String.format("java -jar %s %s", updaterFile.getAbsoluteFile(), args);
+ Logger.info("Run Updater with the following command: " + command);
+ Runtime.getRuntime().exec(command);
+
+ RemoteLightWeb.exitApplication();
+ }
+
+ private File downloadUpdater(String rootDir) throws Exception {
+ File updaterFile = new File(rootDir + File.separator + UPDATER_NAME);
+ if(!updaterFile.exists()) {
+ GitHubParser parser = new GitHubParser("0", "Drumber", "Updater");
+ try {
+
+ parser.check();
+ Logger.info("Downloading Uploader version " + parser.getNewestVersionTag() +" to " + updaterFile.getAbsolutePath());
+ FileDownloader downloader = new FileDownloader(parser.getNewestDownloadUrl(), updaterFile.getAbsolutePath());
+ if(downloader.isDownloadSuccessful()) {
+ return updaterFile;
+ }
+
+ } catch (Exception e) {
+ throw new Exception("Could not download Updater.", e);
+ }
+ return null;
+ }
+ return updaterFile;
+ }
+
+}
diff --git a/src/main/java/de/lars/remotelightweb/ui/components/UpdateDialog.java b/src/main/java/de/lars/remotelightweb/ui/components/UpdateDialog.java
new file mode 100644
index 0000000..45f2eb2
--- /dev/null
+++ b/src/main/java/de/lars/remotelightweb/ui/components/UpdateDialog.java
@@ -0,0 +1,108 @@
+package de.lars.remotelightweb.ui.components;
+
+import org.tinylog.Logger;
+
+import com.vaadin.flow.component.button.Button;
+import com.vaadin.flow.component.dialog.Dialog;
+import com.vaadin.flow.component.html.Anchor;
+import com.vaadin.flow.component.html.H3;
+import com.vaadin.flow.component.html.Label;
+import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+
+import de.lars.remotelightweb.RemoteLightWeb;
+import de.lars.remotelightweb.backend.utils.UpdateUtil;
+import de.lars.remotelightweb.ui.utils.UIUtils;
+import de.lars.updater.sites.GitHubParser;
+
+public class UpdateDialog extends Dialog {
+
+ public UpdateDialog(GitHubParser parser) {
+ VerticalLayout l = new VerticalLayout();
+ l.setSizeFull();
+ add(l);
+ l.add(new H3("Updater"));
+
+ l.add(new Label(parser.isNewVersionAvailable() ? "New version available!" : "No new version available."));
+ l.add(new Label("Installed: " + RemoteLightWeb.VERSION));
+ l.add(new Label("Latest: " + parser.getNewestVersionTag()));
+ l.add(new Anchor(parser.getNewestUrl(), parser.getNewestUrl()));
+
+ if(parser.isNewVersionAvailable()) {
+ Button btnIgnore = UIUtils.createButton("Ignore", "5px 5px");
+ btnIgnore.addClickListener(e -> ignore());
+ add(btnIgnore);
+
+ Button btnUpdate = UIUtils.createButton("Update now", "5px 5px");
+ btnUpdate.addClickListener(e -> update());
+ add(btnUpdate);
+ } else {
+ add(new Button("Close", e -> close()));
+ }
+ }
+
+
+ private void ignore() {
+ close();
+ removeAll();
+ VerticalLayout l = new VerticalLayout();
+ l.setSizeFull();
+ add(l);
+
+ l.add(new Label("The update can also be installed later in the settings."));
+ l.add(new Button("Ok", e -> close()));
+ open();
+ }
+
+
+ private void update() {
+ close();
+ removeAll();
+ VerticalLayout l = new VerticalLayout();
+ l.setSizeFull();
+ add(l);
+
+ l.add(new H3("Important information"));
+ l.add(new Label("The program will be closed while the new version is downloaded in the background. "
+ + "Please do not power off the system! RemoteLightWeb will automatically restart after the update is complete."));
+ l.add(new Label("You can choose between two options:"));
+ l.add(new Label("1. (Update and restart) RemoteLightWeb will automatically restart after the update is complete."));
+ l.add(new Label("2. (Update and shutdown) The system will shut down after the update has been successfully completed."));
+
+ UpdateUtil updateUtil = RemoteLightWeb.getInstance().getUpdateUtil();
+
+ add(UIUtils.createButton("Cancel", "5px 5px", e -> close()));
+ add(UIUtils.createButton("Update and restart", "5px 5px", e -> {
+ try {
+ updateUtil.install(false);
+ } catch (Exception e1) {
+ Logger.error(e1, "Error while updating");
+ error("Error while updating", e1);
+ }
+ }));
+ add(UIUtils.createButton("Update and shutdown", "5px 5px", e -> {
+ try {
+ updateUtil.install(true);
+ } catch (Exception e1) {
+ Logger.error("Error while updating", e);
+ error("Error while updating", e1);
+ }
+ }));
+ open();
+ }
+
+
+ private void error(String message, Exception ex) {
+ close();
+ removeAll();
+ VerticalLayout l = new VerticalLayout();
+ l.setSizeFull();
+ add(l);
+
+ l.add(new H3("An error has occurred"));
+ l.add(new Label(message));
+ l.add(new Label(ex.getMessage()));
+ l.add(new Button("Close", e -> close()));
+ open();
+ }
+
+}
diff --git a/src/main/java/de/lars/remotelightweb/ui/utils/UIUtils.java b/src/main/java/de/lars/remotelightweb/ui/utils/UIUtils.java
index 657271d..e82a6f0 100644
--- a/src/main/java/de/lars/remotelightweb/ui/utils/UIUtils.java
+++ b/src/main/java/de/lars/remotelightweb/ui/utils/UIUtils.java
@@ -1,5 +1,7 @@
package de.lars.remotelightweb.ui.utils;
+import com.vaadin.flow.component.ClickEvent;
+import com.vaadin.flow.component.ComponentEventListener;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.icon.VaadinIcon;
@@ -35,6 +37,12 @@ public static Button createButton(String text, String marginArg) {
return button;
}
+ public static Button createButton(String text, String marginArg, ComponentEventListener> listener) {
+ Button button = createButton(text, marginArg);
+ button.addClickListener(listener);
+ return button;
+ }
+
public static Button addMargin(Button button, String marginArg) {
button.getStyle().set("margin", marginArg);
return button;
diff --git a/src/main/java/de/lars/remotelightweb/ui/views/SettingsView.java b/src/main/java/de/lars/remotelightweb/ui/views/SettingsView.java
index bc16d08..2ee85fa 100644
--- a/src/main/java/de/lars/remotelightweb/ui/views/SettingsView.java
+++ b/src/main/java/de/lars/remotelightweb/ui/views/SettingsView.java
@@ -22,7 +22,9 @@
import de.lars.remotelightclient.settings.SettingsManager.SettingCategory;
import de.lars.remotelightclient.settings.types.SettingSelection;
import de.lars.remotelightweb.RemoteLightWeb;
+import de.lars.remotelightweb.backend.utils.UpdateUtil;
import de.lars.remotelightweb.ui.MainLayout;
+import de.lars.remotelightweb.ui.components.UpdateDialog;
import de.lars.remotelightweb.ui.components.custom.PaperSlider;
import de.lars.remotelightweb.ui.components.settingpanels.SettingPanel;
import de.lars.remotelightweb.ui.utils.SettingPanelUtil;
@@ -52,6 +54,12 @@ public SettingsView() {
});
add(new Label("Brightness"), brightness);
+ add(new Button("Check for updates", e -> {
+ UpdateUtil updater = RemoteLightWeb.getInstance().getUpdateUtil();
+ updater.check();
+ new UpdateDialog(updater.getParser()).open();;
+ }));
+
Button close = new Button("Shutdown");
add(close);
close.addClickListener(e -> {