diff options
Diffstat (limited to 'UVtools.WPF/Structures/AppVersionChecker.cs')
-rw-r--r-- | UVtools.WPF/Structures/AppVersionChecker.cs | 188 |
1 files changed, 183 insertions, 5 deletions
diff --git a/UVtools.WPF/Structures/AppVersionChecker.cs b/UVtools.WPF/Structures/AppVersionChecker.cs index 3d843f1..0d9f333 100644 --- a/UVtools.WPF/Structures/AppVersionChecker.cs +++ b/UVtools.WPF/Structures/AppVersionChecker.cs @@ -6,19 +6,72 @@ * of this license document, but changing it is not allowed. */ using System; +using System.Collections.Specialized; using System.Diagnostics; +using System.IO; +using System.IO.Compression; using System.Net; +using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; +using ABI.Windows.Data.Json; using Avalonia.Threading; +using Newtonsoft.Json; using UVtools.Core; using UVtools.Core.Objects; +using UVtools.Core.Operations; +using UVtools.WPF.Extensions; namespace UVtools.WPF.Structures { public class AppVersionChecker : BindableBase { + public const string GitHubReleaseApi = "https://api.github.com/repos/sn4k3/UVtools/releases/latest"; private string _version; private string _url; + public string Filename + { + get + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + return $"{About.Software}_win-x64_v{_version}.msi"; + } + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + return $"{About.Software}_linux-x64_v{_version}.zip"; + } + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + return $"{About.Software}_osx-x64_v{_version}.zip"; + } + + return $"{About.Software}_universal-x86-x64_v{_version}.zip"; + } + } + + public string Runtime + { + get + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + return "win-x64"; + } + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + return "linux-x64"; + } + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + return "osx-x64"; + } + + return "universal-x86-x64"; + } + } + public string Version { get => _version; @@ -30,19 +83,46 @@ namespace UVtools.WPF.Structures } } - public string VersionAnnouncementText => $"New version {_version} is available!"; + public string VersionAnnouncementText => $"New version v{_version} is available!"; - public string Url => $"{About.Website}/releases/tag/{_version}"; + public string UrlLatestRelease => $"{About.Website}/releases/latest"; + + public string DownloadLink => string.IsNullOrEmpty(Filename) ? null : $"{About.Website}/releases/download/v{_version}/{Filename}"; public bool HaveNewVersion => !string.IsNullOrEmpty(Version); + public string DownloadedFile { get; private set; } + public bool Check() { try { - using (WebClient client = new WebClient()) + using (WebClient client = new WebClient { - string htmlCode = client.DownloadString($"{About.Website}/releases"); + Headers = new WebHeaderCollection + { + {HttpRequestHeader.Accept, "application/json"}, + {HttpRequestHeader.UserAgent, "Request"} + } + }) + { + var response = client.DownloadString(GitHubReleaseApi); + dynamic json = JsonConvert.DeserializeObject(response); + string tag_name = json.tag_name; + if (string.IsNullOrEmpty(tag_name)) return false; + tag_name = tag_name.Trim(' ', 'v', 'V'); + Debug.WriteLine($"Version checker: v{AppSettings.VersionStr} <=> v{tag_name}"); + + if (string.Compare(tag_name, AppSettings.VersionStr, StringComparison.OrdinalIgnoreCase) > 0) + { + Dispatcher.UIThread.InvokeAsync(() => + { + Version = tag_name; + Debug.WriteLine($"New version detected: {DownloadLink}"); + }); + return true; + } + /*string htmlCode = client.DownloadString($"{About.Website}/releases"); const string searchFor = "/releases/tag/"; var startIndex = htmlCode.IndexOf(searchFor, StringComparison.InvariantCultureIgnoreCase) + searchFor.Length; @@ -55,7 +135,7 @@ namespace UVtools.WPF.Structures Version = version;; }); return true; - } + }*/ } } catch (Exception e) @@ -65,5 +145,103 @@ namespace UVtools.WPF.Structures return false; } + + public bool AutoUpgrade(OperationProgress progress) + { + if (!HaveNewVersion) return false; + progress.ItemName = "Megabytes"; + try + { + using (var client = new WebClient()) + { + var path = Path.GetTempPath(); + DownloadedFile = Path.Combine(path, Filename); + Debug.WriteLine($"Downloading to: {DownloadedFile}"); + + + client.DownloadProgressChanged += (sender, e) => + { + progress.Reset("Megabytes", (uint)e.TotalBytesToReceive / 1048576, (uint)e.BytesReceived / 1048576); + }; + client.DownloadFileCompleted += (sender, e) => + { + progress.Reset("Extracting"); + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + App.StartProcess(DownloadedFile); + Environment.Exit(0); + } + else + { + string upgradeFolder = "UPDATED_VERSION"; + var targetDir = Path.Combine(App.ApplicationPath, upgradeFolder); + using (var stream = File.Open(DownloadedFile, FileMode.Open)) + { + using (ZipArchive zip = new ZipArchive(stream, ZipArchiveMode.Read)) + { + zip.ExtractToDirectory(targetDir, true); + } + } + + File.Delete(DownloadedFile); + + string upgradeFileName = $"{About.Software}_upgrade.sh"; + var upgradeFile = Path.Combine(App.ApplicationPath, upgradeFileName); + using (var stream = File.CreateText(upgradeFile)) + { + stream.WriteLine("#!/bin/bash"); + stream.WriteLine($"echo {About.Software} v{AppSettings.Version} updater script"); + stream.WriteLine($"cd '{App.ApplicationPath}'"); + stream.WriteLine($"killall {About.Software}"); + stream.WriteLine("sleep 0.5"); + stream.WriteLine($"cp -fR {upgradeFolder}/* ."); + stream.WriteLine($"rm -fr {upgradeFolder}"); + stream.WriteLine("sleep 0.5"); + //stream.WriteLine($"[ -f {About.Software} ] && {App.AppExecutableQuoted} & || dotnet {About.Software}.dll &"); + stream.WriteLine($"if [ -f '{About.Software}' ]; then"); + stream.WriteLine($" ./{About.Software} &"); + stream.WriteLine("else"); + stream.WriteLine($" dotnet {About.Software}.dll &"); + stream.WriteLine("fi"); + stream.WriteLine($"rm -f {upgradeFileName}"); + //stream.WriteLine("exit"); + stream.Close(); + } + + App.StartProcess("bash", $"\"{upgradeFile}\""); + + //App.NewInstance(App.MainWindow.SlicerFile?.FileFullPath); + Environment.Exit(0); + } + + lock (e.UserState) + { + //releases blocked thread + Monitor.Pulse(e.UserState); + } + }; + + + var syncObject = new object(); + + lock (syncObject) + { + client.DownloadFileAsync(new Uri(DownloadLink), DownloadedFile, syncObject); + //This would block the thread until download completes + Monitor.Wait(syncObject); + } + + } + } + catch (Exception e) + { + Dispatcher.UIThread.InvokeAsync(async () => + await App.MainWindow.MessageBoxError(e.ToString(), "Error downloading the file")); + return false; + } + + + return false; + } } } |