diff --git a/README.md b/README.md index b60089cbe..743ce46c1 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/ #### Supported Systems * Windows using .NET 4.6.1 or above [Download here](https://www.microsoft.com/net/framework/versions/net461). -* Linux and macOS using Mono 5.8 or above. [Download here](http://www.mono-project.com/download/). Earlier versions of mono may work, but some trackers may fail to negotiate SSL correctly, and others may cause Jackett to crash when used. +* Linux and macOS using Mono 5.8 or above. [Download here](http://www.mono-project.com/download/). ### Supported Public Trackers * 1337x @@ -403,6 +403,7 @@ All contributions are welcome just send a pull request. Jackett's framework all ## Building from source ### Windows +* Install the .NET Core [SDK](https://www.microsoft.com/net/download/windows) * Open the Jackett solution in Visual Studio 2017 (version 15.7 or above) * Right click on the Jackett solution and click 'Rebuild Solution' to restore nuget packages * Select Jackett.Console as startup project diff --git a/src/Jackett.Common/Indexers/BaseIndexer.cs b/src/Jackett.Common/Indexers/BaseIndexer.cs index c7d4f3cb9..195e0431f 100644 --- a/src/Jackett.Common/Indexers/BaseIndexer.cs +++ b/src/Jackett.Common/Indexers/BaseIndexer.cs @@ -13,6 +13,7 @@ using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; +using static Jackett.Common.Models.IndexerConfig.ConfigurationData; namespace Jackett.Common.Indexers { @@ -194,17 +195,31 @@ namespace Jackett.Common.Indexers LoadValuesFromJson(jsonConfig, false); - object passwordPropertyValue = null; + StringItem passwordPropertyValue = null; string passwordValue = ""; try { - passwordPropertyValue = configData.GetType().GetProperty("Password").GetValue(configData, null); - passwordValue = passwordPropertyValue.GetType().GetProperty("Value").GetValue(passwordPropertyValue, null).ToString(); + // try dynamic items first (e.g. all cardigann indexers) + passwordPropertyValue = (StringItem)configData.GetDynamicByName("password"); + + if (passwordPropertyValue == null) // if there's no dynamic password try the static property + { + passwordPropertyValue = (StringItem)configData.GetType().GetProperty("Password").GetValue(configData, null); + + // protection is based on the item.Name value (property name might be different, example: Abnormal), so check the Name again + if (!string.Equals(passwordPropertyValue.Name, "password", StringComparison.InvariantCultureIgnoreCase)) + { + logger.Debug($"Skipping non default password property (unencrpyted password) for [{ID}] while attempting migration"); + return false; + } + } + + passwordValue = passwordPropertyValue.Value; } catch (Exception) { - logger.Debug($"Unable to source password for [{ID}] while attempting migration, likely a public tracker"); + logger.Debug($"Unable to source password for [{ID}] while attempting migration, likely a tracker without a password setting"); return false; } @@ -230,7 +245,7 @@ namespace Jackett.Common.Indexers string unprotectedPassword = protectionService.LegacyUnProtect(passwordValue); //Password successfully unprotected using Windows/Mono DPAPI - passwordPropertyValue.GetType().GetProperty("Value").SetValue(passwordPropertyValue, unprotectedPassword); + passwordPropertyValue.Value = unprotectedPassword; SaveConfig(); IsConfigured = true; diff --git a/src/Jackett.Common/Indexers/MyAnonamouse.cs b/src/Jackett.Common/Indexers/MyAnonamouse.cs index 78d220b29..751d1ef8d 100644 --- a/src/Jackett.Common/Indexers/MyAnonamouse.cs +++ b/src/Jackett.Common/Indexers/MyAnonamouse.cs @@ -180,7 +180,7 @@ namespace Jackett.Common.Indexers } var response = await RequestStringWithCookiesAndRetry(urlSearch); - if (response.Status == System.Net.HttpStatusCode.Forbidden) + if (response.Status == System.Net.HttpStatusCode.Forbidden || CookieHeader.Contains("pass=deleted")) { // re-login await ApplyConfiguration(null); diff --git a/src/Jackett.Common/Models/IndexerConfig/ConfigurationData.cs b/src/Jackett.Common/Models/IndexerConfig/ConfigurationData.cs index 578b75862..f90319164 100644 --- a/src/Jackett.Common/Models/IndexerConfig/ConfigurationData.cs +++ b/src/Jackett.Common/Models/IndexerConfig/ConfigurationData.cs @@ -116,7 +116,7 @@ namespace Jackett.Common.Models.IndexerConfig case ItemType.HiddenData: case ItemType.DisplayInfo: var value = ((StringItem)item).Value; - if (string.Equals(item.Name, "password", StringComparison.InvariantCultureIgnoreCase)) + if (string.Equals(item.Name, "password", StringComparison.InvariantCultureIgnoreCase)) // if we chagne this logic we've to change the MigratedFromDPAPI() logic too, #2114 is realted { if (string.IsNullOrEmpty(value)) value = string.Empty; @@ -190,6 +190,11 @@ namespace Jackett.Common.Models.IndexerConfig } } + public Item GetDynamicByName(string Name) + { + return dynamics.Values.Where(i => string.Equals(i.Name, Name, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault(); + } + public class Item { public ItemType ItemType { get; set; } diff --git a/src/Jackett.Common/Services/TrayLockService.cs b/src/Jackett.Common/Services/TrayLockService.cs index a267a3f99..58c46f391 100644 --- a/src/Jackett.Common/Services/TrayLockService.cs +++ b/src/Jackett.Common/Services/TrayLockService.cs @@ -7,7 +7,7 @@ namespace Jackett.Common.Services public class TrayLockService : ITrayLockService { - private readonly string EVENT_HANDLE_NAME = "JACKETT.TRAY"; + private readonly string EVENT_HANDLE_NAME = @"Global\JACKETT.TRAY"; private EventWaitHandle GetEventHandle() { diff --git a/src/Jackett.Common/Services/UpdateService.cs b/src/Jackett.Common/Services/UpdateService.cs index a3c808d1d..2bde084e1 100644 --- a/src/Jackett.Common/Services/UpdateService.cs +++ b/src/Jackett.Common/Services/UpdateService.cs @@ -268,17 +268,29 @@ namespace Jackett.Common.Services return tempDir; } - private void StartUpdate(string updaterExePath, string installLocation, bool isWindows, bool NoRestart, bool trayWasRunning) + private void StartUpdate(string updaterExePath, string installLocation, bool isWindows, bool NoRestart, bool trayIsRunning) { + string appType = "Console"; + //DI once off Owin + IProcessService processService = new ProcessService(logger); + IServiceConfigService windowsService = new WindowsServiceConfigService(processService, logger); + + if (isWindows && windowsService.ServiceExists() && windowsService.ServiceRunning()) + { + appType = "WindowsService"; + } + var exe = Path.GetFileName(ExePath()); var args = string.Join(" ", Environment.GetCommandLineArgs().Skip(1).Select(a => a.Contains(" ") ? "\"" +a + "\"" : a )).Replace("\"", "\\\""); var startInfo = new ProcessStartInfo(); + startInfo.UseShellExecute = false; + startInfo.CreateNoWindow = true; // Note: add a leading space to the --Args argument to avoid parsing as arguments if (isWindows) { - startInfo.Arguments = $"--Path \"{installLocation}\" --Type \"{exe}\" --Args \" {args}\""; + startInfo.Arguments = $"--Path \"{installLocation}\" --Type \"{appType}\" --Args \" {args}\""; startInfo.FileName = Path.Combine(updaterExePath); } else @@ -287,13 +299,12 @@ namespace Jackett.Common.Services args = exe + " " + args; exe = "mono"; - startInfo.Arguments = $"{Path.Combine(updaterExePath)} --Path \"{installLocation}\" --Type \"{exe}\" --Args \" {args}\""; + startInfo.Arguments = $"{Path.Combine(updaterExePath)} --Path \"{installLocation}\" --Type \"{appType}\" --Args \" {args}\""; startInfo.FileName = "mono"; - startInfo.UseShellExecute = false; - startInfo.CreateNoWindow = true; } - try { + try + { var pid = Process.GetCurrentProcess().Id; startInfo.Arguments += $" --KillPids \"{pid}\""; } @@ -308,18 +319,25 @@ namespace Jackett.Common.Services startInfo.Arguments += " --NoRestart"; } - if (trayWasRunning) + if (trayIsRunning && appType == "Console") { startInfo.Arguments += " --StartTray"; } + if (isWindows) + { + lockService.Signal(); + logger.Info("Signal sent to lock service"); + Thread.Sleep(2000); + } + logger.Info($"Starting updater: {startInfo.FileName} {startInfo.Arguments}"); var procInfo = Process.Start(startInfo); logger.Info($"Updater started process id: {procInfo.Id}"); - if (NoRestart == false) - { + + if (!NoRestart) + { logger.Info("Exiting Jackett.."); - lockService.Signal(); //TODO: Remove once off Owin if (EnvironmentUtil.IsRunningLegacyOwin) { diff --git a/src/Jackett.Service/Service.cs b/src/Jackett.Service/Service.cs index ba95ec746..7fdd7fd22 100644 --- a/src/Jackett.Service/Service.cs +++ b/src/Jackett.Service/Service.cs @@ -77,10 +77,12 @@ namespace Jackett.Service private void ProcessExited(object sender, EventArgs e) { + logger.Info("Console process exited"); + if (!serviceStopInitiated) { logger.Info("Service stop not responsible for process exit"); - OnStop(); + Stop(); } } @@ -89,7 +91,7 @@ namespace Jackett.Service if (consoleProcess != null && !consoleProcess.HasExited) { consoleProcess.StandardInput.Close(); - System.Threading.Thread.Sleep(1000); + consoleProcess.WaitForExit(2000); if (consoleProcess != null && !consoleProcess.HasExited) { consoleProcess.Kill(); diff --git a/src/Jackett.Tray/Jackett.Tray.csproj b/src/Jackett.Tray/Jackett.Tray.csproj index f48380428..88c8c5d10 100644 --- a/src/Jackett.Tray/Jackett.Tray.csproj +++ b/src/Jackett.Tray/Jackett.Tray.csproj @@ -66,6 +66,7 @@ + Main.cs @@ -109,6 +110,11 @@ True + + + 2.2.1 + +