diff --git a/Ombi.Common/ContainerBuilder.cs b/Ombi.Common/ContainerBuilder.cs new file mode 100644 index 000000000..c0b10f125 --- /dev/null +++ b/Ombi.Common/ContainerBuilder.cs @@ -0,0 +1,53 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2017 Jamie Rees +// File: ContainerBuilder.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + +using System; +using System.Collections.Generic; +using System.Reflection; +using Ombi.Common.EnvironmentInfo; + +namespace Ombi.Common +{ + public class ContainerBuilder + { + + private readonly List _loadedTypes; + public ContainerBuilder() + { + _loadedTypes = new List(); + + var assemblies = new List(); + assemblies.Add(OsInfo.IsWindows ? "Ombi.Windows" : "Ombi.Mono"); + assemblies.Add("Ombi.Common"); + + foreach (var assembly in assemblies) + { + _loadedTypes.AddRange(Assembly.Load(assembly).GetTypes()); + } + } + } +} \ No newline at end of file diff --git a/Ombi.Common/Disk/DiskTransferService.cs b/Ombi.Common/Disk/DiskTransferService.cs new file mode 100644 index 000000000..452cc6073 --- /dev/null +++ b/Ombi.Common/Disk/DiskTransferService.cs @@ -0,0 +1,88 @@ +//#region Copyright +//// /************************************************************************ +//// Copyright (c) 2017 Jamie Rees +//// File: DiskTransferService.cs +//// Created By: Jamie Rees +//// +//// Permission is hereby granted, free of charge, to any person obtaining +//// a copy of this software and associated documentation files (the +//// "Software"), to deal in the Software without restriction, including +//// without limitation the rights to use, copy, modify, merge, publish, +//// distribute, sublicense, and/or sell copies of the Software, and to +//// permit persons to whom the Software is furnished to do so, subject to +//// the following conditions: +//// +//// The above copyright notice and this permission notice shall be +//// included in all copies or substantial portions of the Software. +//// +//// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +//// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +//// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +//// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +//// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +//// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +//// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +//// ************************************************************************/ +//#endregion +//namespace Ombi.Common.Disk +//{ +// public class DiskTransferService +// { +// private readonly IDiskProvider _diskProvider; +// public int MirrorFolder(string sourcePath, string targetPath) +// { +// var filesCopied = 0; + +// _logger.Debug("Mirror [{0}] > [{1}]", sourcePath, targetPath); + +// if (!_diskProvider.FolderExists(targetPath)) +// { +// _diskProvider.CreateFolder(targetPath); +// } + +// var sourceFolders = _diskProvider.GetDirectoryInfos(sourcePath); +// var targetFolders = _diskProvider.GetDirectoryInfos(targetPath); + +// foreach (var subDir in targetFolders.Where(v => !sourceFolders.Any(d => d.Name == v.Name))) +// { +// if (ShouldIgnore(subDir)) continue; + +// _diskProvider.DeleteFolder(subDir.FullName, true); +// } + +// foreach (var subDir in sourceFolders) +// { +// if (ShouldIgnore(subDir)) continue; + +// filesCopied += MirrorFolder(subDir.FullName, Path.Combine(targetPath, subDir.Name)); +// } + +// var sourceFiles = _diskProvider.GetFileInfos(sourcePath); +// var targetFiles = _diskProvider.GetFileInfos(targetPath); + +// foreach (var targetFile in targetFiles.Where(v => !sourceFiles.Any(d => d.Name == v.Name))) +// { +// if (ShouldIgnore(targetFile)) continue; + +// _diskProvider.DeleteFile(targetFile.FullName); +// } + +// foreach (var sourceFile in sourceFiles) +// { +// if (ShouldIgnore(sourceFile)) continue; + +// var targetFile = Path.Combine(targetPath, sourceFile.Name); + +// if (CompareFiles(sourceFile.FullName, targetFile)) +// { +// continue; +// } + +// TransferFile(sourceFile.FullName, targetFile, TransferMode.Copy, true, true); +// filesCopied++; +// } + +// return filesCopied; +// } +// } +//} \ No newline at end of file diff --git a/Ombi.Common/Ombi.Common.csproj b/Ombi.Common/Ombi.Common.csproj index c8c1a53ef..35591d83a 100644 --- a/Ombi.Common/Ombi.Common.csproj +++ b/Ombi.Common/Ombi.Common.csproj @@ -46,6 +46,8 @@ + + diff --git a/Ombi.Mono/Class1.cs b/Ombi.Mono/Class1.cs new file mode 100644 index 000000000..22c8af026 --- /dev/null +++ b/Ombi.Mono/Class1.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Ombi.Mono +{ + public class Class1 + { + } +} diff --git a/Ombi.Mono/Ombi.Mono.csproj b/Ombi.Mono/Ombi.Mono.csproj new file mode 100644 index 000000000..889753e51 --- /dev/null +++ b/Ombi.Mono/Ombi.Mono.csproj @@ -0,0 +1,53 @@ + + + + + Debug + AnyCPU + 96c89180-1fb5-48b7-9d35-6eb5f11c9d95 + Library + Properties + Ombi.Mono + Ombi.Mono + v4.5.2 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Ombi.Mono/Properties/AssemblyInfo.cs b/Ombi.Mono/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..805c60a4e --- /dev/null +++ b/Ombi.Mono/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Ombi.Mono")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Ombi.Mono")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("96c89180-1fb5-48b7-9d35-6eb5f11c9d95")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Ombi.Services/Jobs/EmbyContentCacher.cs b/Ombi.Services/Jobs/EmbyContentCacher.cs index ce8acdc0e..8e1011aec 100644 --- a/Ombi.Services/Jobs/EmbyContentCacher.cs +++ b/Ombi.Services/Jobs/EmbyContentCacher.cs @@ -105,7 +105,13 @@ namespace Ombi.Services.Jobs try { var movies = GetMovies(); - + // Delete everything + EmbyContent.Custom(connection => + { + connection.Open(); + connection.Query("delete from EmbyContent where type = @type", new { type = 0 }); + return new List(); + }); foreach (var m in movies) { if (m.Type.Equals("boxset", StringComparison.CurrentCultureIgnoreCase)) @@ -129,7 +135,13 @@ namespace Ombi.Services.Jobs } var tv = GetTvShows(); - + // Delete everything + EmbyContent.Custom(connection => + { + connection.Open(); + connection.Query("delete from EmbyContent where type = @type", new { type = 1 }); + return new List(); + }); foreach (var t in tv) { var tvInfo = EmbyApi.GetInformation(t.Id, EmbyMediaType.Series, embySettings.ApiKey, diff --git a/Ombi.Services/Jobs/FaultQueueHandler.cs b/Ombi.Services/Jobs/FaultQueueHandler.cs index 6d18efa2a..70660c7fa 100644 --- a/Ombi.Services/Jobs/FaultQueueHandler.cs +++ b/Ombi.Services/Jobs/FaultQueueHandler.cs @@ -158,6 +158,15 @@ namespace Ombi.Services.Jobs } else { + // Make sure it's been requested + var existingRequests = RequestService.GetAll(); + var thisItem = existingRequests.Any(x => x.Title.Equals(tvModel.Title)); + if (!thisItem) + { + tvModel.Approved = true; + RequestService.AddRequest(tvModel); + } + // Successful, remove from the fault queue Repo.Delete(t); } @@ -261,7 +270,6 @@ namespace Ombi.Services.Jobs { var sonarrSettings = SonarrSettings.GetSettings(); var sickrageSettings = SickrageSettings.GetSettings(); - var cpSettings = CpSettings.GetSettings(); var hpSettings = HeadphoneSettings.GetSettings(); if (!requests.Any()) diff --git a/Ombi.Services/Jobs/PlexContentCacher.cs b/Ombi.Services/Jobs/PlexContentCacher.cs index f370b7b36..6878c3367 100644 --- a/Ombi.Services/Jobs/PlexContentCacher.cs +++ b/Ombi.Services/Jobs/PlexContentCacher.cs @@ -239,13 +239,13 @@ namespace Ombi.Services.Jobs var movies = GetPlexMovies(results); - //// Time to destroy the plex movies from the DB - //PlexContent.Custom(connection => - //{ - // connection.Open(); - // connection.Query("delete from PlexContent where type = @type", new { type = 0 }); - // return new List(); - //}); + // Time to destroy the plex movies from the DB + PlexContent.Custom(connection => + { + connection.Open(); + connection.Query("delete from PlexContent where type = @type", new { type = 0 }); + return new List(); + }); foreach (var m in movies) { @@ -280,13 +280,13 @@ namespace Ombi.Services.Jobs } var tv = GetPlexTvShows(results); - //// Time to destroy the plex tv from the DB - //PlexContent.Custom(connection => - //{ - // connection.Open(); - // connection.Query("delete from PlexContent where type = @type", new { type = 1 }); - // return new List(); - //}); + // Time to destroy the plex tv from the DB + PlexContent.Custom(connection => + { + connection.Open(); + connection.Query("delete from PlexContent where type = @type", new { type = 1 }); + return new List(); + }); foreach (var t in tv) { if (string.IsNullOrEmpty(t.ProviderId)) @@ -321,13 +321,13 @@ namespace Ombi.Services.Jobs } var albums = GetPlexAlbums(results); - //// Time to destroy the plex movies from the DB - //PlexContent.Custom(connection => - //{ - // connection.Open(); - // connection.Query("delete from PlexContent where type = @type", new { type = 2 }); - // return new List(); - //}); + // Time to destroy the plex movies from the DB + PlexContent.Custom(connection => + { + connection.Open(); + connection.Query("delete from PlexContent where type = @type", new { type = 2 }); + return new List(); + }); foreach (var a in albums) { diff --git a/Ombi.UI/Modules/Admin/FaultQueueModule.cs b/Ombi.UI/Modules/Admin/FaultQueueModule.cs index aacd5b992..096ce69b1 100644 --- a/Ombi.UI/Modules/Admin/FaultQueueModule.cs +++ b/Ombi.UI/Modules/Admin/FaultQueueModule.cs @@ -25,7 +25,10 @@ // ************************************************************************/ #endregion +using System; using System.Linq; +using System.Threading.Tasks; +using Nancy; using Nancy.Responses.Negotiation; using Ombi.Core; using Ombi.Core.SettingModels; @@ -48,6 +51,7 @@ namespace Ombi.UI.Modules.Admin Before += (ctx) => Security.AdminLoginRedirect(Permissions.Administrator, ctx); Get["Index", "/faultqueue"] = x => Index(); + Get["DeleteFault", "/deleteFault", true] = async (x,ct) => await DeleteFault(Convert.ToInt32(Request.Form.id)); } private IRepository RequestQueue { get; } @@ -69,5 +73,35 @@ namespace Ombi.UI.Modules.Admin return View["RequestFaultQueue", model]; } + + public async Task DeleteFault(int faultId) + { + + if (faultId == 0) + { + return Response.AsJson(new JsonResponseModel + { + Result = true, + Message = "Fault does not exist" + }); + } + + var fault = await RequestQueue.GetAsync(faultId); + if (fault == null) + { + return Response.AsJson(new JsonResponseModel + { + Result = true, + Message = "Fault does not exist" + }); + } + + await RequestQueue.DeleteAsync(fault); + + return Response.AsJson(new JsonResponseModel + { + Result = true + }); + } } } \ No newline at end of file diff --git a/Ombi.UI/Modules/Admin/SystemStatusModule.cs b/Ombi.UI/Modules/Admin/SystemStatusModule.cs index 876597490..cce157985 100644 --- a/Ombi.UI/Modules/Admin/SystemStatusModule.cs +++ b/Ombi.UI/Modules/Admin/SystemStatusModule.cs @@ -35,6 +35,7 @@ using MarkdownSharp; using Nancy; using Nancy.ModelBinding; using Nancy.Responses.Negotiation; +using Ombi.Common.Processes; using Ombi.Core; using Ombi.Core.SettingModels; using Ombi.Core.StatusChecker; @@ -123,7 +124,7 @@ namespace Ombi.UI.Modules.Admin var url = Request.Form["url"]; var args = (string)Request.Form["args"].ToString(); var lowered = args.ToLower(); - var appPath = Path.Combine(Path.GetDirectoryName(Assembly.GetAssembly(typeof(SystemStatusModule)).Location ?? string.Empty) ?? string.Empty, "Ombi.Updater.exe"); + var appPath = Path.Combine(Path.GetDirectoryName(Assembly.GetAssembly(typeof(SystemStatusModule)).Location ?? string.Empty) ?? string.Empty, Path.Combine("UpdateService", "Ombi.Updater.exe")); if (!string.IsNullOrEmpty(lowered)) { @@ -133,7 +134,7 @@ namespace Ombi.UI.Modules.Admin } } - var startArgs = string.IsNullOrEmpty(lowered) ? appPath : $"{lowered} Ombi.Updater.exe"; + var startArgs = string.IsNullOrEmpty(lowered) || lowered == "Nancy.DynamicDictionaryValue".ToLower() ? appPath : $"{lowered} Ombi.Updater.exe"; var startInfo = Type.GetType("Mono.Runtime") != null ? new ProcessStartInfo(startArgs) { Arguments = $"{url} {lowered}", } @@ -141,7 +142,7 @@ namespace Ombi.UI.Modules.Admin Process.Start(startInfo); - Environment.Exit(0); + //Environment.Exit(0); return Nancy.Response.NoBody; } diff --git a/Ombi.UI/Modules/SearchModule.cs b/Ombi.UI/Modules/SearchModule.cs index d1cf52473..dcc2b13d2 100644 --- a/Ombi.UI/Modules/SearchModule.cs +++ b/Ombi.UI/Modules/SearchModule.cs @@ -982,7 +982,7 @@ namespace Ombi.UI.Modules return Response.AsJson(new JsonResponseModel { - Message = "Could not add movie, please contract your administrator", + Message = "Could not add movie, please contact your administrator", Result = false }); } @@ -1420,9 +1420,7 @@ namespace Ombi.UI.Modules private bool ShouldSendNotification(RequestType type, PlexRequestSettings prSettings) { - var sendNotification = ShouldAutoApprove(type) - ? !prSettings.IgnoreNotifyForAutoApprovedRequests - : true; + var sendNotification = !ShouldAutoApprove(type) || !prSettings.IgnoreNotifyForAutoApprovedRequests; if (IsAdmin) { diff --git a/Ombi.UI/Ombi.UI.csproj b/Ombi.UI/Ombi.UI.csproj index ea07ce214..1118a196f 100644 --- a/Ombi.UI/Ombi.UI.csproj +++ b/Ombi.UI/Ombi.UI.csproj @@ -941,6 +941,10 @@ {8CB8D235-2674-442D-9C6A-35FCAEEB160D} Ombi.Api + + {BFD45569-90CF-47CA-B575-C7B0FF97F67B} + Ombi.Common + {8406EE57-D533-47C0-9302-C6B5F8C31E55} Ombi.Core.Migration diff --git a/Ombi.UI/Program.cs b/Ombi.UI/Program.cs index 2dc1ef5a8..9373fd3ba 100644 --- a/Ombi.UI/Program.cs +++ b/Ombi.UI/Program.cs @@ -29,6 +29,7 @@ using System; using System.Diagnostics; using System.IO; using System.Linq; +using System.Reflection; using System.Windows.Forms; using CommandLine; using Microsoft.Owin.Hosting; @@ -41,6 +42,7 @@ using Ombi.Core.SettingModels; using Ombi.Helpers; using Ombi.Store; using Ombi.Store.Repository; +using Ombi.UI.Modules.Admin; using Ombi.UI.Start; namespace Ombi.UI @@ -50,7 +52,6 @@ namespace Ombi.UI private static Logger Log = LogManager.GetCurrentClassLogger(); static void Main(string[] args) { - var result = Parser.Default.ParseArguments(args); var baseUrl = result.MapResult( o => o.BaseUrl, diff --git a/Ombi.UI/Views/Admin/SchedulerSettings.cshtml b/Ombi.UI/Views/Admin/SchedulerSettings.cshtml index ac2e0f4b8..e1083ba10 100644 --- a/Ombi.UI/Views/Admin/SchedulerSettings.cshtml +++ b/Ombi.UI/Views/Admin/SchedulerSettings.cshtml @@ -87,7 +87,7 @@
- +
@@ -175,13 +175,19 @@ success: function (response) { if (response.result === true) { generateNotify("Success!", "success"); + ev.removeClass("fa-spin"); + ev.addClass("fa-check"); } else { generateNotify(response.message, "warning"); + ev.removeClass("fa-spin"); + ev.addClass("fa-times"); } }, error: function (e) { console.log(e); generateNotify("Something went wrong!", "danger"); + ev.removeClass("fa-spin"); + ev.addClass("fa-times"); } }); diff --git a/Ombi.UI/Views/FaultQueue/RequestFaultQueue.cshtml b/Ombi.UI/Views/FaultQueue/RequestFaultQueue.cshtml index f5df31e65..451734902 100644 --- a/Ombi.UI/Views/FaultQueue/RequestFaultQueue.cshtml +++ b/Ombi.UI/Views/FaultQueue/RequestFaultQueue.cshtml @@ -22,6 +22,9 @@ Error Description + + Delete + @@ -44,6 +47,7 @@ @m.Message + } @@ -52,57 +56,42 @@
-@**@ \ No newline at end of file + + }); + \ No newline at end of file diff --git a/Ombi.UI/Views/SystemStatus/Status.cshtml b/Ombi.UI/Views/SystemStatus/Status.cshtml index 71c960a6a..8be76882a 100644 --- a/Ombi.UI/Views/SystemStatus/Status.cshtml +++ b/Ombi.UI/Views/SystemStatus/Status.cshtml @@ -50,9 +50,9 @@ {
- @**@ +
- @**@ + } else { diff --git a/Ombi.Updater/DetectApplicationType.cs b/Ombi.Updater/DetectApplicationType.cs index 73e50231a..4dbf5192d 100644 --- a/Ombi.Updater/DetectApplicationType.cs +++ b/Ombi.Updater/DetectApplicationType.cs @@ -22,8 +22,7 @@ namespace Ombi.Updater return AppType.Normal; } - if (_serviceProvider.ServiceExist(ServiceProvider.OmbiServiceName) - ) + if (_serviceProvider.ServiceExist(ServiceProvider.OmbiServiceName)) { return AppType.Service; } diff --git a/Ombi.Updater/InstallService.cs b/Ombi.Updater/InstallService.cs index 502f2ae39..ca1935f7d 100644 --- a/Ombi.Updater/InstallService.cs +++ b/Ombi.Updater/InstallService.cs @@ -25,7 +25,14 @@ // ************************************************************************/ #endregion +using System; +using System.IO; +using System.IO.Compression; using System.Linq; +using System.Net; +using System.Reflection; +using System.Windows.Forms; +using NLog; using Ombi.Common; using Ombi.Common.EnvironmentInfo; using Ombi.Common.Processes; @@ -34,24 +41,249 @@ namespace Ombi.Updater { public class InstallService { - public void Start(string installFolder) + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + private readonly IProcessProvider _processProvider = new ProcessProvider(); + private string BackupPath { get; set; } + private string TempPath { get; set; } + public void Start(UpdateStartupContext ctx) { var dector = new DetectApplicationType(); - var processProvider = new ProcessProvider(); - var processId = processProvider.FindProcessByName(ProcessProvider.OmbiProcessName)?.FirstOrDefault()?.Id ?? -1; + var processId = _processProvider.FindProcessByName(ProcessProvider.OmbiProcessName)?.FirstOrDefault()?.Id ?? -1; // Log if process is -1 - var appType = dector.GetAppType(); - processProvider.FindProcessByName(ProcessProvider.OmbiProcessName); + var dir = CreateTempPath(); + TempPath = Path.Combine(dir.FullName, "OmbiUpdate.zip"); + using (var client = new WebClient()) + { + client.DownloadProgressChanged += (s, e) => + { + Console.WriteLine($"{e.ProgressPercentage}%"); + }; + client.DownloadFile(ctx.DownloadPath, TempPath); + } + var appType = dector.GetAppType(); + _processProvider.FindProcessByName(ProcessProvider.OmbiProcessName); + var installationFolder = GetInstallationDirectory(ctx); + var terminator = new TerminateOmbi(new ServiceProvider(_processProvider), _processProvider); if (OsInfo.IsWindows) { - var terminator = new TerminateOmbi(new ServiceProvider(processProvider), processProvider); terminator.Terminate(processId); } + try + { + BackupCurrentVersion(); + EmptyInstallationFolder(); + + using (var archive = ZipFile.OpenRead(TempPath)) + { + foreach (var entry in archive.Entries) + { + var fullname = string.Empty; + if (entry.FullName.Contains("Release/")) // Don't extract the release folder, we are already in there + { + fullname = entry.FullName.Replace("Release/", string.Empty); + } + if (entry.Name.Contains("UpdateService")) + { + fullname = entry.FullName.Replace("UpdateService", "UpdateService_New"); + } + + var fullPath = Path.Combine(PathUp(Path.GetDirectoryName(Application.ExecutablePath),1),fullname); + + + + if (string.IsNullOrEmpty(entry.Name)) + { + Directory.CreateDirectory(fullPath); + } + else + { + if (entry.Name.Contains("Updater")) + { + continue; + } + + entry.ExtractToFile(fullPath, true); + Console.WriteLine("Restored {0}", entry.FullName); + } + } + } + + // Need to install here + } + catch (Exception e) + { + Console.WriteLine(e); + RestoreBackup(); + throw; + } + finally + { + var startOmbi = new StartOmbi(new ServiceProvider(_processProvider), _processProvider); + if (OsInfo.IsWindows) + { + startOmbi.Start(appType, installationFolder); + } + else + { + terminator.Terminate(processId); + + Logger.Info("Waiting for external auto-restart."); + for (int i = 0; i < 5; i++) + { + System.Threading.Thread.Sleep(1000); + if (_processProvider.Exists(ProcessProvider.OmbiProcessName)) + { + Logger.Info("Ombi was restarted by external process."); + break; + } + } + + if (!_processProvider.Exists(ProcessProvider.OmbiProcessName)) + { + startOmbi.Start(appType, installationFolder, ctx.StartupArgs); + } + } + } + + } + + private DirectoryInfo CreateTempPath() + { + try + { + var location = Path.GetDirectoryName(Assembly.GetAssembly(typeof(Updater)).Location ?? string.Empty); + var path = Path.Combine(location, "UpdateTemp"); + return Directory.CreateDirectory(path); + } + catch (Exception e) + { + Console.WriteLine(e.Message); + Console.WriteLine(); + Environment.Exit(1); + return null; + } + } + public void RestoreBackup() + { + Console.WriteLine("Update failed, restoring backup"); + using (var archive = ZipFile.OpenRead(BackupPath)) + { + foreach (var entry in archive.Entries) + { + var fullPath = Path.Combine(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath)), entry.FullName); + + if (string.IsNullOrEmpty(entry.Name)) + { + Directory.CreateDirectory(fullPath); + } + if (entry.Name.Contains("UpdateService")) + { + continue; + } + else + { + if (entry.Name.Contains("Ombi.Updater")) + { + entry.ExtractToFile(fullPath + "_Updated", true); + continue; + } + + entry.ExtractToFile(fullPath, true); + Console.WriteLine("Update failed, restoring backup"); + } + } + } } + private string GetInstallationDirectory(UpdateStartupContext startupContext) + { + + Logger.Debug("Using process ID to find installation directory: {0}", startupContext.ProcessId); + var exeFileInfo = new FileInfo(_processProvider.GetProcessById(startupContext.ProcessId).StartPath); + Logger.Debug("Executable location: {0}", exeFileInfo.FullName); + + return exeFileInfo.DirectoryName; + + + } + + private void BackupCurrentVersion() + { + Console.WriteLine("Backing up the current version"); + try + { + var applicationPath = Path.GetDirectoryName(Assembly.GetAssembly(typeof(InstallService)).Location ?? string.Empty) ?? string.Empty; + + var dir = Directory.CreateDirectory(Path.Combine(applicationPath, "BackupSystem")); + + var allfiles = Directory.GetFiles(applicationPath, "*.*", SearchOption.AllDirectories); + BackupPath = Path.Combine(dir.FullName, "OmbiBackup.zip"); + + CheckAndDelete(BackupPath); + using (var fileStream = new FileStream(BackupPath, FileMode.CreateNew)) + using (var archive = new ZipArchive(fileStream, ZipArchiveMode.Create, true)) + { + foreach (var file in allfiles) + { + if (file.Contains("BackupSystem")) + continue; + var info = Path.GetFileName(file); + archive.CreateEntryFromFile(file, info); + } + } + Console.WriteLine("All backed up!"); + } + catch (Exception e) + { + Console.WriteLine(e.Message); + Console.WriteLine(); + Environment.Exit(1); + } + } + private void CheckAndDelete(string filePath) + { + if (File.Exists(filePath)) + { + File.Delete(filePath); + } + } + + private void EmptyInstallationFolder() + { + var applicationPath = PathUp(Path.GetDirectoryName(Assembly.GetAssembly(typeof(InstallService)).Location ?? string.Empty) ?? string.Empty,1); + var allfiles = Directory.GetFiles(applicationPath, "*.*", SearchOption.AllDirectories); + + foreach (var file in allfiles) + { + if(file.Contains("BackupSystem") || file.Contains("UpdateService") || file.Contains(".sqlite")) continue; + CheckAndDelete(file); + } + } + static string PathUp(string path, int up) + { + if (up == 0) + return path; + for (int i = path.Length - 1; i >= 0; i--) + { + if (path[i] == Path.DirectorySeparatorChar) + { + up--; + if (up == 0) + return path.Substring(0, i); + } + } + return null; + } + } + + public class UpdateStartupContext + { + public int ProcessId { get; set; } + public string DownloadPath { get; set; } + public string StartupArgs { get; set; } } } \ No newline at end of file diff --git a/Ombi.Updater/Ombi.Updater.csproj b/Ombi.Updater/Ombi.Updater.csproj index 881b9badd..d01a42b60 100644 --- a/Ombi.Updater/Ombi.Updater.csproj +++ b/Ombi.Updater/Ombi.Updater.csproj @@ -13,7 +13,7 @@ true full false - bin\Debug\Updater\ + bin\Debug\UpdateService\ DEBUG; prompt 4 @@ -31,10 +31,6 @@ ..\packages\NLog.4.3.6\lib\net45\NLog.dll - - ..\packages\Polly-Signed.4.3.0\lib\net45\Polly.dll - True - @@ -46,7 +42,9 @@ + +
@@ -55,17 +53,13 @@ {bfd45569-90cf-47ca-b575-c7b0ff97f67b} Ombi.Common - - {DD7DC444-D3BF-4027-8AB9-EFC71F5EC581} - Ombi.Core - - - {1252336D-42A3-482A-804C-836E60173DFA} - Ombi.Helpers - + + (ROBOCOPY "$(ProjectDir)bin\$(ConfigurationName)\UpdateService" "$(SolutionDir)Ombi.UI\bin\$(ConfigurationName)\UpdateService" "*")^& IF %25ERRORLEVEL%25 GEQ 16 exit 1 +exit 0 + \ No newline at end of file diff --git a/Ombi.Updater/Program.cs b/Ombi.Updater/Program.cs index 358b7a332..b408f6656 100644 --- a/Ombi.Updater/Program.cs +++ b/Ombi.Updater/Program.cs @@ -1,4 +1,7 @@ using System; +using System.Linq; +using System.Windows.Forms; +using Ombi.Common.Processes; namespace Ombi.Updater { @@ -6,16 +9,32 @@ namespace Ombi.Updater { public static void Main (string[] args) { - Console.WriteLine ("Starting PlexRequests .Net updater"); - var s = new Updater(); - if (args.Length >= 2) - { - s.Start(args[0], args[1]); - } - else - { - s.Start(args[0], string.Empty); - } + var i = new InstallService(); + var context = ParseArgs(args); + i.Start(context); + //Console.WriteLine ("Starting Ombi updater"); + // var s = new Updater(); + // if (args.Length >= 2) + // { + // s.Start(args[0], args[1]); + // } + // else + // { + // s.Start(args[0], string.Empty); + // } } + + private static UpdateStartupContext ParseArgs(string[] args) + { + + var proc = new ProcessProvider(); + var ombiProc = proc.FindProcessByName("Ombi").FirstOrDefault().Id; + return new UpdateStartupContext + { + DownloadPath = args[0], + ProcessId = ombiProc, + StartupArgs = args.Length > 1 ? args[1] : string.Empty + }; + } } } diff --git a/Ombi.Updater/StartOmbi.cs b/Ombi.Updater/StartOmbi.cs new file mode 100644 index 000000000..f1f08a3eb --- /dev/null +++ b/Ombi.Updater/StartOmbi.cs @@ -0,0 +1,99 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2017 Jamie Rees +// File: StartOmbi.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + +using System; +using System.IO; +using NLog; +using Ombi.Common; +using Ombi.Common.Processes; +using IServiceProvider = Ombi.Common.IServiceProvider; + +namespace Ombi.Updater +{ + public interface IStartOmbi + { + void Start(AppType appType, string installationFolder, string args); + void Start(AppType app, string installationFolder); + + } + public class StartOmbi : IStartOmbi + { + private readonly IServiceProvider _serviceProvider; + private readonly IProcessProvider _processProvider; + private readonly Logger _logger = LogManager.GetCurrentClassLogger(); + public StartOmbi(IServiceProvider serviceProvider, IProcessProvider processProvider) + { + _serviceProvider = serviceProvider; + _processProvider = processProvider; + } + + public void Start(AppType app, string installationFolder) + { + Start(app, installationFolder, string.Empty); + } + + public void Start(AppType appType, string installationFolder, string args) + { + _logger.Info("Starting Ombi"); + if (appType == AppType.Service) + { + try + { + StartService(); + + } + catch (InvalidOperationException e) + { + _logger.Warn(e, "Couldn't start Ombi Service (Most likely due to permission issues). falling back to console."); + StartConsole(installationFolder, args); + } + } + else if (appType == AppType.Console) + { + StartConsole(installationFolder, args); + } + } + + private void StartService() + { + _logger.Info("Starting Ombi service"); + _serviceProvider.Start(ServiceProvider.OmbiServiceName); + } + + private void StartConsole(string installationFolder, string args) + { + Start(installationFolder, "Ombi.exe", args); + } + + private void Start(string installationFolder, string fileName, string args) + { + _logger.Info("Starting {0}", fileName); + var path = Path.Combine(installationFolder, fileName); + _processProvider.SpawnNewProcess(path); + } + } +} \ No newline at end of file diff --git a/Ombi.Updater/TerminateOmbi.cs b/Ombi.Updater/TerminateOmbi.cs index f72bc54d2..9f3fc162a 100644 --- a/Ombi.Updater/TerminateOmbi.cs +++ b/Ombi.Updater/TerminateOmbi.cs @@ -62,7 +62,7 @@ namespace Ombi.Updater { try { - _logger.Info("NzbDrone Service is installed and running"); + _logger.Info("Ombi Service is installed and running"); _serviceProvider.Stop(ServiceProvider.OmbiServiceName); } catch (Exception e) diff --git a/Ombi.Updater/UpdateEngine/BackupAndRestore.cs b/Ombi.Updater/UpdateEngine/BackupAndRestore.cs new file mode 100644 index 000000000..cad210605 --- /dev/null +++ b/Ombi.Updater/UpdateEngine/BackupAndRestore.cs @@ -0,0 +1,37 @@ +//using NLog; + +//namespace Ombi.Updater.UpdateEngine +//{ +// public interface IBackupAndRestore +// { +// void Backup(string source); +// void Restore(string target); +// } + +// public class BackupAndRestore : IBackupAndRestore +// { +// private readonly IDiskTransferService _diskTransferService; +// private readonly IAppFolderInfo _appFolderInfo; +// private readonly Logger _logger; + +// public BackupAndRestore(IDiskTransferService diskTransferService, IAppFolderInfo appFolderInfo, Logger logger) +// { +// _diskTransferService = diskTransferService; +// _appFolderInfo = appFolderInfo; +// _logger = logger; +// } + +// public void Backup(string source) +// { +// _logger.Info("Creating backup of existing installation"); +// _diskTransferService.MirrorFolder(source, _appFolderInfo.GetUpdateBackUpFolder()); +// } + +// public void Restore(string target) +// { +// _logger.Info("Attempting to rollback upgrade"); +// var count = _diskTransferService.MirrorFolder(_appFolderInfo.GetUpdateBackUpFolder(), target); +// _logger.Info("Rolled back {0} files", count); +// } +// } +//} \ No newline at end of file diff --git a/Ombi.Updater/Updater.cs b/Ombi.Updater/Updater.cs index 132fa21f1..ba0b0a780 100644 --- a/Ombi.Updater/Updater.cs +++ b/Ombi.Updater/Updater.cs @@ -184,8 +184,7 @@ namespace Ombi.Updater private DirectoryInfo CreateTempPath() { - try - { + try { var location = Path.GetDirectoryName(Assembly.GetAssembly(typeof(Updater)).Location ?? string.Empty); var path = Path.Combine(location, "UpdateTemp"); return Directory.CreateDirectory(path); diff --git a/Ombi.Windows/Class1.cs b/Ombi.Windows/Class1.cs new file mode 100644 index 000000000..05e2816fa --- /dev/null +++ b/Ombi.Windows/Class1.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Ombi.Windows +{ + public class Class1 + { + } +} diff --git a/Ombi.Windows/Ombi.Windows.csproj b/Ombi.Windows/Ombi.Windows.csproj new file mode 100644 index 000000000..d9cf62d7a --- /dev/null +++ b/Ombi.Windows/Ombi.Windows.csproj @@ -0,0 +1,53 @@ + + + + + Debug + AnyCPU + fa5f2172-e82f-4d73-9c50-bedc6a0a4037 + Library + Properties + Ombi.Windows + Ombi.Windows + v4.5.2 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Ombi.Windows/Properties/AssemblyInfo.cs b/Ombi.Windows/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..3fbe77ed4 --- /dev/null +++ b/Ombi.Windows/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Ombi.Windows")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Ombi.Windows")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("fa5f2172-e82f-4d73-9c50-bedc6a0a4037")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Ombi.sln b/Ombi.sln index 2eefc0648..86b3aa0ff 100644 --- a/Ombi.sln +++ b/Ombi.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26206.0 +VisualStudioVersion = 15.0.26228.4 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.UI", "Ombi.UI\Ombi.UI.csproj", "{68F5F5F3-B8BB-4911-875F-6F00AAE04EA6}" EndProject @@ -41,6 +41,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Core.Migration", "Ombi EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Common", "Ombi.Common\Ombi.Common.csproj", "{BFD45569-90CF-47CA-B575-C7B0FF97F67B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Mono", "Ombi.Mono\Ombi.Mono.csproj", "{96C89180-1FB5-48B7-9D35-6EB5F11C9D95}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Windows", "Ombi.Windows\Ombi.Windows.csproj", "{FA5F2172-E82F-4D73-9C50-BEDC6A0A4037}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Platform", "Platform", "{3186D191-D5C6-46B1-86E0-3F3B65A12096}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -103,10 +109,22 @@ Global {BFD45569-90CF-47CA-B575-C7B0FF97F67B}.Debug|Any CPU.Build.0 = Debug|Any CPU {BFD45569-90CF-47CA-B575-C7B0FF97F67B}.Release|Any CPU.ActiveCfg = Release|Any CPU {BFD45569-90CF-47CA-B575-C7B0FF97F67B}.Release|Any CPU.Build.0 = Release|Any CPU + {96C89180-1FB5-48B7-9D35-6EB5F11C9D95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {96C89180-1FB5-48B7-9D35-6EB5F11C9D95}.Debug|Any CPU.Build.0 = Debug|Any CPU + {96C89180-1FB5-48B7-9D35-6EB5F11C9D95}.Release|Any CPU.ActiveCfg = Release|Any CPU + {96C89180-1FB5-48B7-9D35-6EB5F11C9D95}.Release|Any CPU.Build.0 = Release|Any CPU + {FA5F2172-E82F-4D73-9C50-BEDC6A0A4037}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FA5F2172-E82F-4D73-9C50-BEDC6A0A4037}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FA5F2172-E82F-4D73-9C50-BEDC6A0A4037}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FA5F2172-E82F-4D73-9C50-BEDC6A0A4037}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {96C89180-1FB5-48B7-9D35-6EB5F11C9D95} = {3186D191-D5C6-46B1-86E0-3F3B65A12096} + {FA5F2172-E82F-4D73-9C50-BEDC6A0A4037} = {3186D191-D5C6-46B1-86E0-3F3B65A12096} + EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution RESX_PrefixTranslations = False EndGlobalSection