From d9be265abe72b636d9ffc4b422005ceb2e06ff6f Mon Sep 17 00:00:00 2001 From: "Jamie.Rees" Date: Thu, 22 Jun 2017 14:32:46 +0100 Subject: [PATCH] More work on the Updater --- src/Ombi.Core/Update/UpdateEngine.cs | 98 +++++++++++++++++++ src/Ombi.Core/Update/UpdateOptions.cs | 12 +++ src/Ombi.Core/Update/UpdateStatus.cs | 8 ++ src/Ombi.Updater/Installer.cs | 46 ++++++++- src/Ombi.Updater/Ombi.Updater.csproj | 2 +- src/Ombi.Updater/Program.cs | 6 +- .../Properties/launchSettings.json | 9 ++ src/Ombi/Controllers/StatusController.cs | 10 ++ 8 files changed, 187 insertions(+), 4 deletions(-) create mode 100644 src/Ombi.Core/Update/UpdateEngine.cs create mode 100644 src/Ombi.Core/Update/UpdateOptions.cs create mode 100644 src/Ombi.Core/Update/UpdateStatus.cs create mode 100644 src/Ombi.Updater/Properties/launchSettings.json diff --git a/src/Ombi.Core/Update/UpdateEngine.cs b/src/Ombi.Core/Update/UpdateEngine.cs new file mode 100644 index 000000000..bdf618498 --- /dev/null +++ b/src/Ombi.Core/Update/UpdateEngine.cs @@ -0,0 +1,98 @@ +using System; +using System.IO; +using System.IO.Compression; +using System.Linq; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading.Tasks; + +namespace Ombi.Core.Update +{ + public class UpdateEngine + { + public async Task Update(UpdateOptions options) + { + if (options.Status == UpdateStatus.UptoDate) + { + // We don't need to update... + return; + } + // Download zip into temp location + var path = await Download(options); + + Extract(path); + + + // TODO Run the Update.exe and pass in the args + } + + private void Extract(string path) + { + using (var zip = ZipFile.OpenRead(path)) + { + path = Path.GetDirectoryName(path); + foreach (var entry in zip.Entries.Skip(1)) + { + var fullname = string.Empty; + if (entry.FullName.Contains("publish/")) // Don't extract the publish folder, we are already in there + { + fullname = entry.FullName.Replace("publish/", string.Empty); + } + + var fullPath = Path.Combine(path, fullname); + + if (string.IsNullOrEmpty(entry.Name)) + { + Directory.CreateDirectory(fullPath); + } + else + { + entry.ExtractToFile(fullPath, true); + Console.WriteLine("Restored {0}", entry.FullName); + } + } + } + } + + /// + /// Downloads the specified zip from the options and returns the zip path. + /// + /// The options. + /// + private async Task Download(UpdateOptions options) + { + + // Create temp path + var location = System.Reflection.Assembly.GetEntryAssembly().Location; + var current = Path.GetDirectoryName(location); + var tempDir = Directory.CreateDirectory(Path.Combine(current, "UpdateTemp")); + var tempZip = Path.Combine(tempDir.FullName, "Ombi.zip"); + + if (File.Exists(tempZip)) + { + return tempZip; + } + + using (var httpClient = new HttpClient()) + using (var contentStream = await httpClient.GetStreamAsync(options.DownloadUrl)) + using (var fileStream = new FileStream(tempZip, FileMode.Create, FileAccess.Write, FileShare.None, 1048576, true)) + { + await contentStream.CopyToAsync(fileStream); + } + + return tempZip; + } + + + public UpdateOptions CheckForUpdate() + { + return new UpdateOptions + { + Status = UpdateStatus.Available, + DownloadUrl = "https://ci.appveyor.com/api/buildjobs/tsghsfcaoqin2wbk/artifacts/Ombi_windows.zip", + UpdateDate = DateTime.Now, + Version = "3.0.0" + }; + } + } +} \ No newline at end of file diff --git a/src/Ombi.Core/Update/UpdateOptions.cs b/src/Ombi.Core/Update/UpdateOptions.cs new file mode 100644 index 000000000..f5822601b --- /dev/null +++ b/src/Ombi.Core/Update/UpdateOptions.cs @@ -0,0 +1,12 @@ +using System; + +namespace Ombi.Core.Update +{ + public class UpdateOptions + { + public UpdateStatus Status { get; set; } + public string DownloadUrl { get; set; } + public string Version { get; set; } + public DateTime UpdateDate { get; set; } + } +} \ No newline at end of file diff --git a/src/Ombi.Core/Update/UpdateStatus.cs b/src/Ombi.Core/Update/UpdateStatus.cs new file mode 100644 index 000000000..866bc501f --- /dev/null +++ b/src/Ombi.Core/Update/UpdateStatus.cs @@ -0,0 +1,8 @@ +namespace Ombi.Core.Update +{ + public enum UpdateStatus + { + Available, + UptoDate + } +} \ No newline at end of file diff --git a/src/Ombi.Updater/Installer.cs b/src/Ombi.Updater/Installer.cs index a667e3117..47c114c10 100644 --- a/src/Ombi.Updater/Installer.cs +++ b/src/Ombi.Updater/Installer.cs @@ -1,5 +1,8 @@ using System; using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; using System.Text; namespace Ombi.Updater @@ -13,8 +16,49 @@ namespace Ombi.Updater p.Kill(options.OmbiProcessId); + + // Make sure the process has been killed + if (p.FindProcessByName("Ombi").Any()) + { + // throw + } + + MoveFiles(options); + + // Start Ombi + StartOmbi(options); + } + + private void StartOmbi(StartupOptions options) + { + var start = new ProcessStartInfo + { + UseShellExecute = false, + CreateNoWindow = true, + FileName = Path.Combine(options.ApplicationPath,"Ombi.exe") + }; + using (var proc = new Process { StartInfo = start }) + { + proc.Start(); + } + + Environment.Exit(0); } - + private void MoveFiles(StartupOptions options) + { + var location = System.Reflection.Assembly.GetEntryAssembly().Location; + location = Path.GetDirectoryName(location); + + //Now Create all of the directories + foreach (string dirPath in Directory.GetDirectories(location, "*", + SearchOption.AllDirectories)) + Directory.CreateDirectory(dirPath.Replace(location, options.ApplicationPath)); + + //Copy all the files & Replaces any files with the same name + foreach (string newPath in Directory.GetFiles(location, "*.*", + SearchOption.AllDirectories)) + File.Copy(newPath, newPath.Replace(location, options.ApplicationPath), true); + } } } diff --git a/src/Ombi.Updater/Ombi.Updater.csproj b/src/Ombi.Updater/Ombi.Updater.csproj index 6d25f413b..b7baef7b3 100644 --- a/src/Ombi.Updater/Ombi.Updater.csproj +++ b/src/Ombi.Updater/Ombi.Updater.csproj @@ -1,4 +1,4 @@ - + Exe diff --git a/src/Ombi.Updater/Program.cs b/src/Ombi.Updater/Program.cs index 0893ea635..f361c69ef 100644 --- a/src/Ombi.Updater/Program.cs +++ b/src/Ombi.Updater/Program.cs @@ -14,6 +14,8 @@ namespace Ombi.Updater var options = CheckArgs(args); + var install = new Installer(); + install.Start(options); } @@ -26,12 +28,12 @@ namespace Ombi.Updater } var p = new ProcessProvider(); - var ombiProc = p.FindProcessByName("Ombi").FirstOrDefault().Id; + var ombiProc = p.FindProcessByName("Ombi").FirstOrDefault(); return new StartupOptions { ApplicationPath = args[0], - OmbiProcessId = ombiProc + OmbiProcessId = ombiProc?.Id ?? -1 }; } } diff --git a/src/Ombi.Updater/Properties/launchSettings.json b/src/Ombi.Updater/Properties/launchSettings.json new file mode 100644 index 000000000..ba6773a0c --- /dev/null +++ b/src/Ombi.Updater/Properties/launchSettings.json @@ -0,0 +1,9 @@ +{ + "profiles": { + "Ombi.Updater": { + "commandName": "Project", + "commandLineArgs": "C:\\Users\\Jamie.Rees\\Source\\Repos\\PlexRequests.Net\\src\\Ombi\\bin\\Debug\\netcoreapp1.1", + "workingDirectory": "C:\\Users\\Jamie.Rees\\Source\\Repos\\PlexRequests.Net\\src\\Ombi\\bin\\Debug\\netcoreapp1.1\\UpdateTemp" + } + } +} \ No newline at end of file diff --git a/src/Ombi/Controllers/StatusController.cs b/src/Ombi/Controllers/StatusController.cs index 510cd5e0e..761216ddf 100644 --- a/src/Ombi/Controllers/StatusController.cs +++ b/src/Ombi/Controllers/StatusController.cs @@ -31,6 +31,7 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Ombi.Core.Settings; using Ombi.Core.Settings.Models; +using Ombi.Core.Update; namespace Ombi.Controllers { @@ -70,5 +71,14 @@ namespace Ombi.Controllers return new { Result = settings?.Wizard ?? false}; } + [AllowAnonymous] + [HttpGet("Update")] + public async Task Update() + { + var u = new UpdateEngine(); + var result = u.CheckForUpdate(); + await u.Update(result); + } + } } \ No newline at end of file