From 98c3940297241c370770a1c971db5998b4c8dbcf Mon Sep 17 00:00:00 2001 From: Robert McRackan Date: Fri, 20 May 2022 16:20:28 -0400 Subject: [PATCH] New feature ( #153 ): in-place upgrade --- Source/AppScaffolding/AppScaffolding.csproj | 2 +- Source/AppScaffolding/LibationScaffolding.cs | 12 ++--- Source/AppScaffolding/UpgradeProperties.cs | 6 +++ Source/DataLayer/DataLayer.csproj | 4 +- Source/FileLiberator/DownloadFile.cs | 31 ------------ .../Options/_ProcessableOptionsBase.cs | 1 - Source/LibationCli/Setup.cs | 6 +-- Source/LibationFileManager/Configuration.cs | 12 ++++- .../LibationFileManager.csproj | 2 +- .../LibationWinForms/LibationWinForms.csproj | 1 + Source/LibationWinForms/Program.cs | 45 +++-------------- Source/LibationWinForms/Updater.cs | 50 +++++++++++++++++++ .../AudibleUtilities.Tests.csproj | 2 +- .../FileLiberator.Tests.csproj | 2 +- .../FileManager.Tests.csproj | 2 +- .../LibationFileManager.Tests.csproj | 2 +- .../LibationSearchEngine.Tests.csproj | 2 +- 17 files changed, 91 insertions(+), 91 deletions(-) create mode 100644 Source/AppScaffolding/UpgradeProperties.cs delete mode 100644 Source/FileLiberator/DownloadFile.cs create mode 100644 Source/LibationWinForms/Updater.cs diff --git a/Source/AppScaffolding/AppScaffolding.csproj b/Source/AppScaffolding/AppScaffolding.csproj index ece47643..3eee4757 100644 --- a/Source/AppScaffolding/AppScaffolding.csproj +++ b/Source/AppScaffolding/AppScaffolding.csproj @@ -3,7 +3,7 @@ net6.0-windows - 7.6.3.1 + 7.7.0.1 diff --git a/Source/AppScaffolding/LibationScaffolding.cs b/Source/AppScaffolding/LibationScaffolding.cs index 32171974..f12046bc 100644 --- a/Source/AppScaffolding/LibationScaffolding.cs +++ b/Source/AppScaffolding/LibationScaffolding.cs @@ -282,22 +282,20 @@ namespace AppScaffolding }); } - public static (bool hasUpgrade, string zipUrl, string htmlUrl, string zipName) GetLatestRelease() + public static UpgradeProperties GetLatestRelease() { - (bool, string, string, string) isFalse = (false, null, null, null); - // timed out var latest = getLatestRelease(TimeSpan.FromSeconds(10)); if (latest is null) - return isFalse; + return null; var latestVersionString = latest.TagName.Trim('v'); if (!Version.TryParse(latestVersionString, out var latestRelease)) - return isFalse; + return null; // we're up to date if (latestRelease <= BuildVersion) - return isFalse; + return null; // we have an update var zip = latest.Assets.FirstOrDefault(a => a.BrowserDownloadUrl.EndsWith(".zip")); @@ -310,7 +308,7 @@ namespace AppScaffolding zipUrl }); - return (true, zipUrl, latest.HtmlUrl, zip.Name); + return new(zipUrl, latest.HtmlUrl, zip.Name, latestRelease); } private static Octokit.Release getLatestRelease(TimeSpan timeout) { diff --git a/Source/AppScaffolding/UpgradeProperties.cs b/Source/AppScaffolding/UpgradeProperties.cs new file mode 100644 index 00000000..f1ca062f --- /dev/null +++ b/Source/AppScaffolding/UpgradeProperties.cs @@ -0,0 +1,6 @@ +using System; + +namespace AppScaffolding +{ + public record UpgradeProperties(string ZipUrl, string HtmlUrl, string ZipName, Version LatestRelease); +} diff --git a/Source/DataLayer/DataLayer.csproj b/Source/DataLayer/DataLayer.csproj index 51bbd9b1..35f0de9c 100644 --- a/Source/DataLayer/DataLayer.csproj +++ b/Source/DataLayer/DataLayer.csproj @@ -12,7 +12,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -29,7 +29,7 @@ - + PreserveNewest diff --git a/Source/FileLiberator/DownloadFile.cs b/Source/FileLiberator/DownloadFile.cs deleted file mode 100644 index b5939280..00000000 --- a/Source/FileLiberator/DownloadFile.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Net.Http; -using System.Threading.Tasks; -using Dinah.Core.Net.Http; - -namespace FileLiberator -{ - // currently only used to download the .zip flies for upgrade - public class DownloadFile : Streamable - { - public async Task PerformDownloadFileAsync(string downloadUrl, string proposedDownloadFilePath) - { - var client = new HttpClient(); - - var progress = new Progress(OnStreamingProgressChanged); - - OnStreamingBegin(proposedDownloadFilePath); - - try - { - var actualDownloadedFilePath = await client.DownloadFileAsync(downloadUrl, proposedDownloadFilePath, progress); - OnFileCreated("Upgrade", actualDownloadedFilePath); - return actualDownloadedFilePath; - } - finally - { - OnStreamingCompleted(proposedDownloadFilePath); - } - } - } -} diff --git a/Source/LibationCli/Options/_ProcessableOptionsBase.cs b/Source/LibationCli/Options/_ProcessableOptionsBase.cs index 6daab32b..0897c6b9 100644 --- a/Source/LibationCli/Options/_ProcessableOptionsBase.cs +++ b/Source/LibationCli/Options/_ProcessableOptionsBase.cs @@ -9,7 +9,6 @@ using FileLiberator; namespace LibationCli { - // streamlined, non-Forms copy of ProcessorAutomationController public abstract class ProcessableOptionsBase : OptionsBase { protected static TProcessable CreateProcessable(EventHandler completedAction = null) diff --git a/Source/LibationCli/Setup.cs b/Source/LibationCli/Setup.cs index 2ffc835b..dec0fff7 100644 --- a/Source/LibationCli/Setup.cs +++ b/Source/LibationCli/Setup.cs @@ -34,15 +34,15 @@ namespace LibationCli private static void checkForUpdate() { - var (hasUpgrade, zipUrl, htmlUrl, zipName) = LibationScaffolding.GetLatestRelease(); - if (!hasUpgrade) + var upgradeProperties = LibationScaffolding.GetLatestRelease(); + if (upgradeProperties is null) return; var origColor = Console.ForegroundColor; try { Console.ForegroundColor = ConsoleColor.Red; - Console.WriteLine($"UPDATE AVAILABLE @ {zipUrl}"); + Console.WriteLine($"UPDATE AVAILABLE @ {upgradeProperties.ZipUrl}"); } finally { diff --git a/Source/LibationFileManager/Configuration.cs b/Source/LibationFileManager/Configuration.cs index a95cc17c..a291daa5 100644 --- a/Source/LibationFileManager/Configuration.cs +++ b/Source/LibationFileManager/Configuration.cs @@ -421,7 +421,7 @@ namespace LibationFileManager return libationFilesPathCache; // FIRST: must write here before SettingsFilePath in next step reads cache - libationFilesPathCache = getLiberationFilesSettingFromJson(); + libationFilesPathCache = getLibationFilesSettingFromJson(); // SECOND. before setting to json file with SetWithJsonPath, PersistentDictionary must exist persistentDictionary = new PersistentDictionary(SettingsFilePath); @@ -443,7 +443,7 @@ namespace LibationFileManager private static string libationFilesPathCache; - private string getLiberationFilesSettingFromJson() + private string getLibationFilesSettingFromJson() { string startingContents = null; try @@ -482,6 +482,14 @@ namespace LibationFileManager { libationFilesPathCache = null; + // ensure exists + if (!File.Exists(APPSETTINGS_JSON)) + { + // getter creates new file, loads PersistentDictionary + var _ = LibationFiles; + System.Threading.Thread.Sleep(100); + } + var startingContents = File.ReadAllText(APPSETTINGS_JSON); var jObj = JObject.Parse(startingContents); diff --git a/Source/LibationFileManager/LibationFileManager.csproj b/Source/LibationFileManager/LibationFileManager.csproj index 422f94a6..4648a9ee 100644 --- a/Source/LibationFileManager/LibationFileManager.csproj +++ b/Source/LibationFileManager/LibationFileManager.csproj @@ -6,7 +6,7 @@ - + diff --git a/Source/LibationWinForms/LibationWinForms.csproj b/Source/LibationWinForms/LibationWinForms.csproj index 39796340..2ecd019b 100644 --- a/Source/LibationWinForms/LibationWinForms.csproj +++ b/Source/LibationWinForms/LibationWinForms.csproj @@ -28,6 +28,7 @@ + diff --git a/Source/LibationWinForms/Program.cs b/Source/LibationWinForms/Program.cs index 5e186a6f..1263f2a3 100644 --- a/Source/LibationWinForms/Program.cs +++ b/Source/LibationWinForms/Program.cs @@ -3,14 +3,9 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Windows.Forms; -using AudibleApi.Authorization; -using AudibleUtilities; -using DataLayer; using Dinah.Core; using LibationFileManager; using LibationWinForms.Dialogs; -using Microsoft.EntityFrameworkCore; -using Newtonsoft.Json.Linq; using Serilog; namespace LibationWinForms @@ -165,15 +160,12 @@ namespace LibationWinForms private static void checkForUpdate() { - string zipUrl; - string htmlUrl; - string zipName; + AppScaffolding.UpgradeProperties upgradeProperties; + try { - bool hasUpgrade; - (hasUpgrade, zipUrl, htmlUrl, zipName) = AppScaffolding.LibationScaffolding.GetLatestRelease(); - - if (!hasUpgrade) + upgradeProperties = AppScaffolding.LibationScaffolding.GetLatestRelease(); + if (upgradeProperties is null) return; } catch (Exception ex) @@ -182,36 +174,13 @@ namespace LibationWinForms return; } - if (zipUrl is null) + if (upgradeProperties.ZipUrl is null) { - MessageBox.Show(htmlUrl, "New version available"); + MessageBox.Show(upgradeProperties.HtmlUrl, "New version available"); return; } - var result = MessageBox.Show($"New version available @ {htmlUrl}\r\n\r\nWould you like to upgrade?", "New version available", MessageBoxButtons.YesNo, MessageBoxIcon.Question); - if (result != DialogResult.Yes) - return; - - try - { - //Download the upgrader app from github - string fileName = "ht" + "tps://github.com/Mbucari/Upgrader/raw/master/Upgrader/win-x86/Upgrader.exe"; - var cli = new System.Net.Http.HttpClient(); - var upgrader = cli.GetByteArrayAsync(fileName).GetAwaiter().GetResult(); - - - string upgraderPath = Path.Combine(Path.GetTempPath(), "Upgrader.exe"); - File.WriteAllBytes(upgraderPath, upgrader); - var thisExe = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName; - - //usage is Upgrader.exe [zip url] [extract directory] [exe to launch] - System.Diagnostics.Process.Start(upgraderPath, new string[] { zipUrl, Path.GetDirectoryName(thisExe), "Libation.exe" }); - Environment.Exit(0); - } - catch (Exception ex) - { - MessageBoxLib.ShowAdminAlert("Error downloading update", "Error downloading update", ex); - } + Updater.Run(upgradeProperties.LatestRelease, upgradeProperties.ZipUrl); } } } diff --git a/Source/LibationWinForms/Updater.cs b/Source/LibationWinForms/Updater.cs new file mode 100644 index 00000000..032ed07b --- /dev/null +++ b/Source/LibationWinForms/Updater.cs @@ -0,0 +1,50 @@ +using System; +using System.Windows.Forms; +using AutoUpdaterDotNET; + +namespace LibationWinForms +{ + public static class Updater + { + private const string REPO_URL = "https://github.com/rmcrackan/Libation/releases/latest"; + + public static void Run(Version latestVersionOnServer, string downloadZipUrl) + => Run(latestVersionOnServer.ToString(), downloadZipUrl); + public static void Run(string latestVersionOnServer, string downloadZipUrl) + { + AutoUpdater.ParseUpdateInfoEvent += + args => args.UpdateInfo = new() + { + CurrentVersion = latestVersionOnServer, + DownloadURL = downloadZipUrl, + ChangelogURL = REPO_URL + }; + AutoUpdater.CheckForUpdateEvent += AutoUpdaterOnCheckForUpdateEvent; + AutoUpdater.Start(REPO_URL); + } + + private static void AutoUpdaterOnCheckForUpdateEvent(UpdateInfoEventArgs args) + { + if (args is null || !args.IsUpdateAvailable) + return; + + var dialogResult = MessageBox.Show(string.Format( + $"There is a new version avilable. Would you like to update?\r\n\r\nAfter you close Libation, the upgrade will start automatically."), + "Update Available", + MessageBoxButtons.YesNo, + MessageBoxIcon.Information); + if (dialogResult != DialogResult.Yes) + return; + + try + { + Serilog.Log.Logger.Information("Start upgrade. {@DebugInfo}", new { CurrentlyInstalled = args.InstalledVersion, TargetVersion = args.CurrentVersion }); + AutoUpdater.DownloadUpdate(args); + } + catch (Exception ex) + { + MessageBoxLib.ShowAdminAlert("Error downloading update", "Error downloading update", ex); + } + } + } +} diff --git a/Source/_Tests/AudibleUtilities.Tests/AudibleUtilities.Tests.csproj b/Source/_Tests/AudibleUtilities.Tests/AudibleUtilities.Tests.csproj index 9ef62e7c..ef046649 100644 --- a/Source/_Tests/AudibleUtilities.Tests/AudibleUtilities.Tests.csproj +++ b/Source/_Tests/AudibleUtilities.Tests/AudibleUtilities.Tests.csproj @@ -7,7 +7,7 @@ - + diff --git a/Source/_Tests/FileLiberator.Tests/FileLiberator.Tests.csproj b/Source/_Tests/FileLiberator.Tests/FileLiberator.Tests.csproj index 671dcbfa..61822f5e 100644 --- a/Source/_Tests/FileLiberator.Tests/FileLiberator.Tests.csproj +++ b/Source/_Tests/FileLiberator.Tests/FileLiberator.Tests.csproj @@ -7,7 +7,7 @@ - + diff --git a/Source/_Tests/FileManager.Tests/FileManager.Tests.csproj b/Source/_Tests/FileManager.Tests/FileManager.Tests.csproj index 9a0213ab..2b20991e 100644 --- a/Source/_Tests/FileManager.Tests/FileManager.Tests.csproj +++ b/Source/_Tests/FileManager.Tests/FileManager.Tests.csproj @@ -7,7 +7,7 @@ - + diff --git a/Source/_Tests/LibationFileManager.Tests/LibationFileManager.Tests.csproj b/Source/_Tests/LibationFileManager.Tests/LibationFileManager.Tests.csproj index ab773781..df7b13a9 100644 --- a/Source/_Tests/LibationFileManager.Tests/LibationFileManager.Tests.csproj +++ b/Source/_Tests/LibationFileManager.Tests/LibationFileManager.Tests.csproj @@ -7,7 +7,7 @@ - + diff --git a/Source/_Tests/LibationSearchEngine.Tests/LibationSearchEngine.Tests.csproj b/Source/_Tests/LibationSearchEngine.Tests/LibationSearchEngine.Tests.csproj index 96780a33..f71d3964 100644 --- a/Source/_Tests/LibationSearchEngine.Tests/LibationSearchEngine.Tests.csproj +++ b/Source/_Tests/LibationSearchEngine.Tests/LibationSearchEngine.Tests.csproj @@ -7,7 +7,7 @@ - +