diff --git a/pom.xml b/pom.xml index afe7b06d94a6de14ebe7a912d27e1859898f09b9..e0c155fd6e69129fe69cfbf9ecf7403e492fbcbf 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ <groupId>de.deadlocker8</groupId> <artifactId>BudgetMaster</artifactId> - <version>2.0.0-SNAPSHOT</version> + <version>2.0.0</version> <name>BudgetMaster</name> <repositories> @@ -63,6 +63,10 @@ <maven.build.timestamp.format>dd.MM.yy</maven.build.timestamp.format> <app.versionCode>14</app.versionCode> <app.author>Robert Goldmann</app.author> + + <project.outputDirectory>build/${project.version}</project.outputDirectory> + <project.artifactName>${project.artifactId}-v${project.version}</project.artifactName> + <project.exe>${project.outputDirectory}/${project.artifactName}.exe</project.exe> </properties> <dependencies> @@ -142,8 +146,8 @@ <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> - <outputDirectory>build/${project.version}</outputDirectory> - <finalName>${project.artifactId}-v${project.version}</finalName> + <outputDirectory>${project.outputDirectory}</outputDirectory> + <finalName>${project.artifactName}</finalName> </configuration> <executions> <execution> @@ -166,8 +170,8 @@ </goals> <configuration> <headerType>gui</headerType> - <jar>build/${project.version}/${project.artifactId}-v${project.version}.jar</jar> - <outfile>build/${project.version}/${project.artifactId}-v${project.version}.exe</outfile> + <jar>${project.outputDirectory}/${project.artifactName}.jar</jar> + <outfile>${project.exe}</outfile> <downloadUrl>http://java.com/download</downloadUrl> <classPath> <mainClass>${project.groupId}${project.artifactId}.Main</mainClass> @@ -194,6 +198,30 @@ <argLine>-Dfile.encoding=UTF-8</argLine> </configuration> </plugin> + + <!--Deploy Plugin--> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <version>1.10</version> + <executions> + <execution> + <id>attach-artifacts</id> + <phase>package</phase> + <goals> + <goal>attach-artifact</goal> + </goals> + <configuration> + <artifacts> + <artifact> + <file>${project.exe}</file> + <type>exe</type> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> </plugins> </build> diff --git a/src/main/java/de/deadlocker8/budgetmaster/controller/SettingsController.java b/src/main/java/de/deadlocker8/budgetmaster/controller/SettingsController.java index b8c07fabfceb5fcaec843dc2ce8690be9af1f5f6..bfaf4b68df5d6ae950923dbf992ed0711cdbd7b6 100644 --- a/src/main/java/de/deadlocker8/budgetmaster/controller/SettingsController.java +++ b/src/main/java/de/deadlocker8/budgetmaster/controller/SettingsController.java @@ -1,5 +1,6 @@ package de.deadlocker8.budgetmaster.controller; +import de.deadlocker8.budgetmaster.Build; import de.deadlocker8.budgetmaster.authentication.User; import de.deadlocker8.budgetmaster.authentication.UserRepository; import de.deadlocker8.budgetmaster.database.Database; @@ -16,6 +17,7 @@ import de.deadlocker8.budgetmaster.utils.LanguageType; import de.deadlocker8.budgetmaster.utils.Strings; import de.thecodelabs.utils.util.Localization; import de.thecodelabs.utils.util.RandomUtils; +import de.thecodelabs.versionizer.UpdateItem; import org.joda.time.DateTime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -71,7 +73,6 @@ public class SettingsController extends BaseController { model.addAttribute("settings", settingsRepository.findOne(0)); request.removeAttribute("database", WebRequest.SCOPE_SESSION); - model.addAttribute("availableVersion", budgetMasterUpdateService.getAvailableVersion()); return "settings"; } @@ -240,10 +241,11 @@ public class SettingsController extends BaseController } @RequestMapping("/settings/database/import") - public String importDatabase(WebRequest request, @ModelAttribute("Import") AccountMatchList accountMatchList) + public String importDatabase(WebRequest request, @ModelAttribute("Import") AccountMatchList accountMatchList, Model model) { importService.importDatabase((Database)request.getAttribute("database", WebRequest.SCOPE_SESSION), accountMatchList); request.removeAttribute("database", RequestAttributes.SCOPE_SESSION); + return "settings"; } @@ -253,4 +255,37 @@ public class SettingsController extends BaseController budgetMasterUpdateService.getUpdateService().fetchCurrentVersion(); return "redirect:/settings"; } + + @RequestMapping("/update") + public String update(Model model) + { + model.addAttribute("performUpdate", true); + model.addAttribute("updateString", Localization.getString("info.text.update", Build.getInstance().getVersionName(), budgetMasterUpdateService.getAvailableVersionString())); + return "settings"; + } + + @RequestMapping("/performUpdate") + public String performUpdate() + { + if(budgetMasterUpdateService.isRunningFromSource()) + { + LOGGER.debug("Running from source code: Skipping update check"); + return "redirect:/settings"; + } + + UpdateItem.Entry entry = new UpdateItem.Entry(budgetMasterUpdateService.getAvailableVersion(), budgetMasterUpdateService.getExecutablePath(), budgetMasterUpdateService.getFileType()); + try + { + budgetMasterUpdateService.getUpdateService().runVersionizerInstance(entry); + } + catch(IOException e) + { + e.printStackTrace(); + } + + LOGGER.info("Stopping BudgetMaster for update to version " + budgetMasterUpdateService.getAvailableVersionString()); + System.exit(0); + + return ""; + } } \ No newline at end of file diff --git a/src/main/java/de/deadlocker8/budgetmaster/services/HelpersService.java b/src/main/java/de/deadlocker8/budgetmaster/services/HelpersService.java index 45f2071ee5f1c184a579c234b7b5fcaf1275817d..380514d83a4fe80838ad9a974853720974333cef 100644 --- a/src/main/java/de/deadlocker8/budgetmaster/services/HelpersService.java +++ b/src/main/java/de/deadlocker8/budgetmaster/services/HelpersService.java @@ -296,4 +296,9 @@ public class HelpersService return false; } } + + public String getAvailableVersionString() + { + return budgetMasterUpdateService.getAvailableVersionString(); + } } \ No newline at end of file diff --git a/src/main/java/de/deadlocker8/budgetmaster/update/BudgetMasterUpdateService.java b/src/main/java/de/deadlocker8/budgetmaster/update/BudgetMasterUpdateService.java index b101a7a9fd38c1f4fd3cd5b230c5fcea7c9aefcd..ae53d67020418878b128bfcf5c92b5dd7cc0582b 100644 --- a/src/main/java/de/deadlocker8/budgetmaster/update/BudgetMasterUpdateService.java +++ b/src/main/java/de/deadlocker8/budgetmaster/update/BudgetMasterUpdateService.java @@ -1,5 +1,6 @@ package de.deadlocker8.budgetmaster.update; +import de.deadlocker8.budgetmaster.Build; import de.deadlocker8.budgetmaster.Main; import de.deadlocker8.budgetmaster.services.SettingsService; import de.thecodelabs.storage.settings.Storage; @@ -7,6 +8,7 @@ import de.thecodelabs.storage.settings.StorageTypes; import de.thecodelabs.versionizer.VersionizerItem; import de.thecodelabs.versionizer.config.Artifact; import de.thecodelabs.versionizer.config.Repository; +import de.thecodelabs.versionizer.model.RemoteFile; import de.thecodelabs.versionizer.model.Version; import de.thecodelabs.versionizer.service.UpdateService; import org.slf4j.Logger; @@ -14,10 +16,8 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.ApplicationHome; import org.springframework.context.ApplicationEventPublisher; -import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Bean; import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import java.io.File; @@ -39,16 +39,42 @@ public class BudgetMasterUpdateService @Autowired private ApplicationEventPublisher applicationEventPublisher; + private boolean isRunningFromSource = true; + private String executablePath; + private UpdateService.Strategy updateStrategy; + private RemoteFile.FileType fileType; + + public BudgetMasterUpdateService() + { + File source = new ApplicationHome().getSource(); + executablePath = null; + updateStrategy = UpdateService.Strategy.JAR; + fileType = RemoteFile.FileType.JAR; + + if(source != null) + { + isRunningFromSource = false; + executablePath = source.getAbsolutePath(); + if(executablePath.endsWith(".exe") || executablePath.endsWith(".EXE")) + { + updateStrategy = UpdateService.Strategy.EXE; + fileType = RemoteFile.FileType.EXE; + } + } + } + @Scheduled(cron = "${versionizer.service.cron}") public void updateSearchTask() { if(settingsService.getSettings().isAutoUpdateCheckEnabled()) { + LOGGER.info("Performing update check"); updateService.fetchCurrentVersion(); if(updateService.isUpdateAvailable()) { UpdateAvailableEvent customSpringEvent = new UpdateAvailableEvent(this, updateService); applicationEventPublisher.publishEvent(customSpringEvent); + LOGGER.info("Update available (installed: v" + Build.getInstance().getVersionName() + ", available: " + getAvailableVersionString() + ")"); } } } @@ -57,8 +83,7 @@ public class BudgetMasterUpdateService public Artifact artifact() { Artifact artifact = new Artifact(); -// artifact.setVersion(Build.getInstance().getVersionName()); - artifact.setVersion("0.0.0"); + artifact.setVersion(Build.getInstance().getVersionName()); artifact.setGroupId("de.deadlocker8"); artifact.setArtifactId("BudgetMaster"); return artifact; @@ -70,32 +95,8 @@ public class BudgetMasterUpdateService ClassLoader classLoader = Main.class.getClassLoader(); Repository repository = Storage.load(classLoader.getResourceAsStream("repositories.json"), StorageTypes.JSON, Repository.class); - File source = new ApplicationHome().getSource(); - String executablePath = null; - if(source == null) - { - LOGGER.debug("Running from source code: Skipping update check"); - } - else - { - executablePath = source.getAbsolutePath(); - } - VersionizerItem versionizerItem = new VersionizerItem(repository, artifact, executablePath); - return UpdateService.startVersionizer(versionizerItem, UpdateService.Strategy.JAR, UpdateService.InteractionType.HEADLESS); - } - - @Component - public class UpdateEventListener implements ApplicationListener<UpdateAvailableEvent> - { - @Override - public void onApplicationEvent(UpdateAvailableEvent updateAvailableEvent) - { - UpdateService updateService = updateAvailableEvent.getUpdateService(); - Version version = updateService.getRemoteVersionForArtifact(artifact); - - System.out.println(version); - } + return UpdateService.startVersionizer(versionizerItem, updateStrategy, UpdateService.InteractionType.HEADLESS, UpdateService.RepositoryType.RELEASE); } public UpdateService getUpdateService() @@ -103,15 +104,35 @@ public class BudgetMasterUpdateService return updateService; } - public String getAvailableVersion() + public String getAvailableVersionString() { - if(updateService.getRemoteVersionForArtifact(artifact) == null) + if(getAvailableVersion() == null) { return "-"; } else { - return "v" + updateService.getRemoteVersionForArtifact(artifact).toVersionString(); + return "v" + getAvailableVersion().toVersionString(); } } + + public Version getAvailableVersion() + { + return updateService.getRemoteVersionForArtifact(artifact); + } + + public String getExecutablePath() + { + return executablePath; + } + + public RemoteFile.FileType getFileType() + { + return fileType; + } + + public boolean isRunningFromSource() + { + return isRunningFromSource; + } } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 84bbccc4e060d6c3258198943168595f751acd53..669650711994dcc19caf93ed0c025ceb5ee73dd7 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -12,7 +12,7 @@ logging.level.root=INFO logging.level.de.deadlocker8=DEBUG -versionizer.service.cron=* * * */1 * * +versionizer.service.cron=0 0 12 * * * app.name=@project.artifactId@ app.version.code=@app.versionCode@ diff --git a/src/main/resources/languages/_de.properties b/src/main/resources/languages/_de.properties index f04b6047531720b0125a390795fccd7cb795ca4d..021c3fb5446f79eb712abebe657c4c489010e685 100644 --- a/src/main/resources/languages/_de.properties +++ b/src/main/resources/languages/_de.properties @@ -87,6 +87,8 @@ info.subtitle.database.import=Konten zuordnen info.database.import.source=Buchungen aus info.database.import.destination=importieren in info.database.import.or=oder +info.title.update=Update verf�gbar +info.text.update=Es ist ein Update f�r BudgetMaster verf�gbar<br><br>Installiert: {0}<br>Verf�gbar: {1}<br><br>M�chtest du das Update jetzt durchf�hren?<br><br>Hinweis: Das Aktualisieren kann je nach Internetverbindung eine Weile dauern. Der BudgetMaster Server wird danach automatisch nuegestartet. Bitte f�hre nach dem Start des Updates keine �nderungen an Konten, Buchungen, Kategorien, etc. durch. # WARNING warning.text.account.delete=Das Konto "{0}" kann nicht gel�scht werden, da mindestens ein Konto existieren muss. Um dieses Konto zu l�schen musst du zuerst ein neues anlegen. @@ -144,7 +146,9 @@ settings.updates.latest.version=Verf settings.database.import=Importieren settings.database.export=Exportieren settings.database.delete=L�schen -settings.database.delete.verification=Best�tigungscode +settings.database.delete.verification=Best�tigungscodes + +settings.update.start=Aktualisieren account.new.label.name=Name account.default.name=Standardkonto diff --git a/src/main/resources/languages/_en.properties b/src/main/resources/languages/_en.properties index ff5fba38b415740d82589d5301e202b5982718a7..043ae24f17ce19631774094d5e46fc2513cedbac 100644 --- a/src/main/resources/languages/_en.properties +++ b/src/main/resources/languages/_en.properties @@ -88,6 +88,8 @@ info.subtitle.database.import=Assign accounts info.database.import.source=Import transactions from info.database.import.destination=to info.database.import.or=or +info.title.update=Update available +info.text.update=An update for BudgetMaster is available<br><br>Installed: {0}<br>Available: {1}<br><br>Would you like to update now?<br><br>Note: The update may take a while depending on your internet connection. The BudgetMaster server will be restarted automatically. Please do not make any changes to accounts, transactions, categories, etc. after starting the update. # WARNING warning.text.account.delete=The account "{0}" could not be deleted, because at least one account must exist at all time. You have to create a new account in order to delete this one. @@ -147,6 +149,8 @@ settings.database.export=Export settings.database.delete=Delete settings.database.delete.verification=Verification Code +settings.update.start=Update + account.new.label.name=Name account.default.name=Default Account account.all=All Accounts diff --git a/src/main/resources/templates/settings.ftl b/src/main/resources/templates/settings.ftl index 91a5aa084973bfcc2e14d4238b068b9ccb7c38c3..a3c8fb5b2ef4e13d0b71e437c572bc374b335646 100644 --- a/src/main/resources/templates/settings.ftl +++ b/src/main/resources/templates/settings.ftl @@ -112,7 +112,7 @@ </tr> <tr> <td>${locale.getString("settings.updates.latest.version")}</td> - <td>${availableVersion}</td> + <td>${helpers.getAvailableVersionString()}</td> </tr> <tr> <td colspan="2"> @@ -244,6 +244,19 @@ </div> </#if> + <#if performUpdate??> + <div id="modelPerformUpdate" class="modal background-color"> + <div class="modal-content"> + <h4>${locale.getString("info.title.update")}</h4> + <p>${updateString}</p> + </div> + <div class="modal-footer background-color"> + <a href="/settings" class="modal-action modal-close waves-effect waves-light red btn-flat white-text">${locale.getString("cancel")}</a> + <a href="/performUpdate" class="modal-action modal-close waves-effect waves-light green btn-flat white-text">${locale.getString("settings.update.start")}</a> + </div> + </div> + </#if> + <!-- Scripts--> <#import "scripts.ftl" as scripts> <@scripts.scripts/>