diff --git a/README.md b/README.md index d1f95f641..2bc04673a 100644 --- a/README.md +++ b/README.md @@ -610,7 +610,7 @@ All contributions are welcome just send a pull request. * Install the .NET Core [SDK](https://www.microsoft.com/net/download/windows) * Clone Jackett * Open Powershell and from the `src` directory, run `dotnet restore` -* Open the Jackett solution in Visual Studio 2017 (version 15.9 or above) +* Open the Jackett solution in Visual Studio 2019 (version 16.3 or above) * Right click on the Jackett solution and click 'Rebuild Solution' to restore nuget packages * Select Jackett.Server as startup project * In the drop down menu of the run button select "Jackett.Server" instead of "IIS Express" @@ -627,21 +627,21 @@ git clone https://github.com/Jackett/Jackett.git cd Jackett/src # dotnet core version -dotnet publish Jackett.Server -f netcoreapp2.2 --self-contained -r osx-x64 -c Debug # takes care of everything -./Jackett.Server/bin/Debug/netcoreapp2.2/osx-x64/jackett # run jackett +dotnet publish Jackett.Server -f netcoreapp3.0 --self-contained -r osx-x64 -c Debug # takes care of everything +./Jackett.Server/bin/Debug/netcoreapp3.0/osx-x64/jackett # run jackett ``` ### Linux ```bash -sudo apt install mono-complete nuget msbuild dotnet-sdk-2.2 # install build tools (debian/ubuntu) +sudo apt install mono-complete nuget msbuild dotnet-sdk-3.0 # install build tools (debian/ubuntu) git clone https://github.com/Jackett/Jackett.git cd Jackett/src # dotnet core version -dotnet publish Jackett.Server -f netcoreapp2.2 --self-contained -r linux-x64 -c Debug # takes care of everything -./Jackett.Server/bin/Debug/netcoreapp2.2/linux-x64/jackett # run jackett +dotnet publish Jackett.Server -f netcoreapp3.0 --self-contained -r linux-x64 -c Debug # takes care of everything +./Jackett.Server/bin/Debug/netcoreapp3.0/linux-x64/jackett # run jackett ``` ## Screenshots diff --git a/appveyor.yml b/appveyor.yml index 15c3265a7..b06ac0abe 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,15 +1,11 @@ -version: 0.11.{build} +version: 0.12.{build} skip_tags: true image: - Ubuntu - - Visual Studio 2017 + - Visual Studio 2019 environment: APPVEYOR_YML_DISABLE_PS_LINUX: true configuration: Release -install: - #Remove once .NET Core 2.2.5 is deployed to Appveyor - - sh: sudo apt-get update - - sh: sudo apt-get -y install dotnet-sdk-2.2 assembly_info: patch: true file: '**\AssemblyInfo.*' diff --git a/build.cake b/build.cake index 81c89d0da..cc7661901 100644 --- a/build.cake +++ b/build.cake @@ -16,7 +16,7 @@ var configuration = Argument("configuration", "Debug"); var workingDir = MakeAbsolute(Directory("./")); string artifactsDirName = "Artifacts"; string testResultsDirName = "TestResults"; -string netCoreFramework = "netcoreapp2.2"; +string netCoreFramework = "netcoreapp3.0"; string serverProjectPath = "./src/Jackett.Server/Jackett.Server.csproj"; string updaterProjectPath = "./src/Jackett.Updater/Jackett.Updater.csproj"; @@ -28,7 +28,7 @@ Task("Info") .Does(() => { Information(@"Jackett Cake build script starting..."); - Information(@"Requires InnoSetup and C:\cygwin to be present for packaging (Pre-installed on AppVeyor) on Windows"); + Information(@"Requires InnoSetup and C:\msys64 to be present for packaging (Pre-installed on AppVeyor) on Windows"); Information(@"Working directory is: " + workingDir); if (IsRunningOnWindows()) @@ -64,7 +64,7 @@ Task("Build-Full-Framework") var buildSettings = new MSBuildSettings() .SetConfiguration(configuration) - .UseToolVersion(MSBuildToolVersion.VS2017); + .UseToolVersion(MSBuildToolVersion.VS2019); MSBuild("./src/Jackett.sln", buildSettings); }); @@ -106,6 +106,8 @@ Task("Package-Windows-Full-Framework") InnoSetupSettings settings = new InnoSetupSettings(); settings.OutputDirectory = workingDir + "/" + artifactsDirName; + //Can remove below line once Cake is updated for InnoSetup 6 - https://github.com/cake-build/cake/pull/2565 + settings.ToolPath = @"C:\Program Files (x86)\Inno Setup 6\ISCC.exe"; settings.Defines = new Dictionary { { "MyFileForVersion", sourceFolder + "/Jackett.Common.dll" }, @@ -145,6 +147,7 @@ Task("Package-Mono-Full-Framework") DeleteFile(buildOutputPath + "/System.Runtime.InteropServices.RuntimeInformation.dll"); + InstallMsysTar(); Gzip("./BuildOutput/net461/linux-x64", $"./{artifactsDirName}", "Jackett", "Jackett.Binaries.Mono.tar.gz"); }); @@ -326,13 +329,13 @@ Task("Linux-Environment") }); -private void RunCygwinCommand(string utility, string utilityArguments) +private void RunMsysCommand(string utility, string utilityArguments) { - var cygwinDir = @"C:\cygwin\bin\"; - var utilityProcess = cygwinDir + utility + ".exe"; + var msysDir = @"C:\msys64\usr\bin\"; + var utilityProcess = msysDir + utility + ".exe"; - Information("CygWin Utility: " + utility); - Information("CygWin Directory: " + cygwinDir); + Information("MSYS2 Utility: " + utility); + Information("MSYS2 Directory: " + msysDir); Information("Utility Location: " + utilityProcess); Information("Utility Arguments: " + utilityArguments); @@ -343,7 +346,7 @@ private void RunCygwinCommand(string utility, string utilityArguments) utilityProcess, new ProcessSettings { Arguments = utilityArguments, - WorkingDirectory = cygwinDir, + WorkingDirectory = msysDir, RedirectStandardOutput = true }, out redirectedStandardOutput, @@ -364,11 +367,9 @@ private void RunCygwinCommand(string utility, string utilityArguments) Information(utility + " Exit code: {0}", exitCodeWithArgument); } -private string RelativeWinPathToCygPath(string relativePath) +private string RelativeWinPathToFullPath(string relativePath) { - var cygdriveBase = "/cygdrive/" + workingDir.ToString().Replace(":", "").Replace("\\", "/"); - var cygPath = cygdriveBase + relativePath.TrimStart('.'); - return cygPath; + return (workingDir + relativePath.TrimStart('.')); } private void RunLinuxCommand(string file, string arg) @@ -390,12 +391,12 @@ private void Gzip(string sourceFolder, string outputDirectory, string tarCdirect if (IsRunningOnWindows()) { - var cygSourcePath = RelativeWinPathToCygPath(sourceFolder); - var tarArguments = @"-cvf " + cygSourcePath + "/" + tarFileName + " -C " + cygSourcePath + $" {tarCdirectoryOption} --mode ='755'"; - var gzipArguments = @"-k " + cygSourcePath + "/" + tarFileName; + var fullSourcePath = RelativeWinPathToFullPath(sourceFolder); + var tarArguments = @"--force-local -cvf " + fullSourcePath + "/" + tarFileName + " -C " + fullSourcePath + $" {tarCdirectoryOption} --mode ='755'"; + var gzipArguments = @"-k " + fullSourcePath + "/" + tarFileName; - RunCygwinCommand("Tar", tarArguments); - RunCygwinCommand("Gzip", gzipArguments); + RunMsysCommand("tar", tarArguments); + RunMsysCommand("gzip", gzipArguments); MoveFile($"{sourceFolder}/{tarFileName}.gz", $"{outputDirectory}/{tarFileName}.gz"); } else @@ -421,16 +422,57 @@ private void Gzip(string sourceFolder, string outputDirectory, string tarCdirect } } -private void DotNetCorePublish(string projectPath, string framework, string runtime, string outputPath) +private void InstallMsysTar() { - var settings = new DotNetCorePublishSettings + //Gzip is included by default with MSYS2, but not tar. Use the package manager to install tar + + var startInfo = new System.Diagnostics.ProcessStartInfo() { - Framework = framework, - Runtime = runtime, - OutputDirectory = outputPath + Arguments = "-S --noconfirm tar", + FileName = @"C:\msys64\usr\bin\pacman.exe", + UseShellExecute = false }; - DotNetCorePublish(projectPath, settings); + var process = System.Diagnostics.Process.Start(startInfo); + process.WaitForExit(); + + if (FileExists(@"C:\msys64\usr\bin\tar.exe") && FileExists(@"C:\msys64\usr\bin\gzip.exe")) + { + Information("tar.exe and gzip.exe were found"); + } + else + { + throw new Exception("tar.exe and gzip.exe were NOT found"); + } +} + +private void DotNetCorePublish(string projectPath, string framework, string runtime, string outputPath) +{ + bool publishSingleFile = false; + + if (publishSingleFile && framework != "net461") + { + var settings = new DotNetCorePublishSettings + { + Framework = framework, + Runtime = runtime, + OutputDirectory = outputPath, + ArgumentCustomization = args=>args.Append("/p:PublishSingleFile=true") + }; + + DotNetCorePublish(projectPath, settings); + } + else + { + var settings = new DotNetCorePublishSettings + { + Framework = framework, + Runtime = runtime, + OutputDirectory = outputPath + }; + + DotNetCorePublish(projectPath, settings); + } } ////////////////////////////////////////////////////////////////////// diff --git a/src/Jackett.Common/Jackett.Common.csproj b/src/Jackett.Common/Jackett.Common.csproj index 494e84be2..31da76e75 100644 --- a/src/Jackett.Common/Jackett.Common.csproj +++ b/src/Jackett.Common/Jackett.Common.csproj @@ -7,23 +7,23 @@ - - + + - + - - + + - - - - + + + + diff --git a/src/Jackett.Server/Helper.cs b/src/Jackett.Server/Helper.cs index 7c4f817b8..6cc75bbca 100644 --- a/src/Jackett.Server/Helper.cs +++ b/src/Jackett.Server/Helper.cs @@ -8,15 +8,23 @@ using Microsoft.AspNetCore.Hosting; using NLog; using System.Linq; using System.Text; +#if !NET461 +using Microsoft.Extensions.Hosting; +#endif namespace Jackett.Server { public static class Helper { public static IContainer ApplicationContainer { get; set; } - public static IApplicationLifetime applicationLifetime; private static bool _automapperInitialised = false; +#if NET461 + public static IApplicationLifetime applicationLifetime; +#else + public static IHostApplicationLifetime applicationLifetime; +#endif + public static void Initialize() { if (_automapperInitialised == false) diff --git a/src/Jackett.Server/Jackett.Server.csproj b/src/Jackett.Server/Jackett.Server.csproj index 8244c9e78..aaadb1026 100644 --- a/src/Jackett.Server/Jackett.Server.csproj +++ b/src/Jackett.Server/Jackett.Server.csproj @@ -1,7 +1,7 @@  - netcoreapp2.2;net461 + netcoreapp3.0;net461 jackett.ico JackettConsole Exe @@ -13,25 +13,15 @@ jackett - - win-x86;osx-x64;linux-x64;linux-arm;linux-arm64 - - - - win7-x86;linux-x64 - - - - + + - + + - - - - - + + @@ -39,11 +29,18 @@ + + + + + + + - - - - + + + + diff --git a/src/Jackett.Server/Services/FilePermissionService.cs b/src/Jackett.Server/Services/FilePermissionService.cs index 3b5ee07a5..7cf9884fc 100644 --- a/src/Jackett.Server/Services/FilePermissionService.cs +++ b/src/Jackett.Server/Services/FilePermissionService.cs @@ -1,7 +1,7 @@ using Jackett.Common.Services.Interfaces; using NLog; using System; -#if NETCOREAPP2_2 +#if !NET461 using Mono.Unix; #endif @@ -18,7 +18,7 @@ namespace Jackett.Server.Services public void MakeFileExecutable(string path) { -#if NETCOREAPP2_2 +#if !NET461 //Calling the file permission service to limit usage to netcoreapp. The Mono.Posix.NETStandard library causes issues outside of .NET Core //https://github.com/xamarin/XamarinComponents/issues/282 diff --git a/src/Jackett.Server/Startup.cs b/src/Jackett.Server/Startup.cs index 52b6259e6..a85292a81 100644 --- a/src/Jackett.Server/Startup.cs +++ b/src/Jackett.Server/Startup.cs @@ -21,6 +21,9 @@ using Newtonsoft.Json.Serialization; using System; using System.IO; using System.Text; +#if !NET461 +using Microsoft.Extensions.Hosting; +#endif namespace Jackett.Server { @@ -49,6 +52,9 @@ namespace Jackett.Server options.Cookie.SameSite = SameSiteMode.None; }); + + +#if NET461 services.AddMvc(config => { var policy = new AuthorizationPolicyBuilder() @@ -59,8 +65,20 @@ namespace Jackett.Server .AddJsonOptions(options => { options.SerializerSettings.ContractResolver = new DefaultContractResolver(); //Web app uses Pascal Case JSON + }); +#else + services.AddControllers(config => + { + var policy = new AuthorizationPolicyBuilder() + .RequireAuthenticatedUser() + .Build(); + config.Filters.Add(new AuthorizeFilter(policy)); }) - .SetCompatibilityVersion(CompatibilityVersion.Version_2_1); + .AddNewtonsoftJson(options => + { + options.SerializerSettings.ContractResolver = new DefaultContractResolver(); //Web app uses Pascal Case JSON + }); +#endif RuntimeSettings runtimeSettings = new RuntimeSettings(); Configuration.GetSection("RuntimeSettings").Bind(runtimeSettings); @@ -96,6 +114,7 @@ namespace Jackett.Server } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. +#if NET461 public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime applicationLifetime) { applicationLifetime.ApplicationStopping.Register(OnShutdown); @@ -134,6 +153,53 @@ namespace Jackett.Server app.UseMvc(); } +#else + public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime applicationLifetime) + { + applicationLifetime.ApplicationStopping.Register(OnShutdown); + Helper.applicationLifetime = applicationLifetime; + app.UseResponseCompression(); + + app.UseDeveloperExceptionPage(); + + app.UseCustomExceptionHandler(); + + string serverBasePath = Helper.ServerService.BasePath() ?? string.Empty; + + if (!string.IsNullOrEmpty(serverBasePath)) + { + app.UsePathBase(serverBasePath); + } + + app.UseForwardedHeaders(new ForwardedHeadersOptions + { + // When adjusting these pareamters make sure it's well tested with various environments + // See https://github.com/Jackett/Jackett/issues/3517 + ForwardLimit = 10, + ForwardedHeaders = ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost + }); + + var rewriteOptions = new RewriteOptions() + .AddRewrite(@"^torznab\/([\w-]*)", "api/v2.0/indexers/$1/results/torznab", skipRemainingRules: true) //legacy torznab route + .AddRewrite(@"^potato\/([\w-]*)", "api/v2.0/indexers/$1/results/potato", skipRemainingRules: true) //legacy potato route + .Add(RedirectRules.RedirectToDashboard); + + app.UseRewriter(rewriteOptions); + + app.UseStaticFiles(); + + app.UseAuthentication(); + + app.UseRouting(); + + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + }); + } +#endif + + private void OnShutdown() { diff --git a/src/Jackett.Test/Jackett.Test.csproj b/src/Jackett.Test/Jackett.Test.csproj index e9a02742f..1c409aa23 100644 --- a/src/Jackett.Test/Jackett.Test.csproj +++ b/src/Jackett.Test/Jackett.Test.csproj @@ -21,15 +21,15 @@ - - + + - - - - + + + + - + diff --git a/src/Jackett.Test/WebUtilityHelpersTests.cs b/src/Jackett.Test/WebUtilityHelpersTests.cs index b1d37f49d..fbda16a74 100644 --- a/src/Jackett.Test/WebUtilityHelpersTests.cs +++ b/src/Jackett.Test/WebUtilityHelpersTests.cs @@ -30,7 +30,7 @@ namespace Jackett.Test }; //https://docs.microsoft.com/en-us/dotnet/api/system.text.codepagesencodingprovider?view=netcore-2.0 -#if NETCOREAPP2_0 +#if !NET461 if (Environment.OSVersion.Platform == PlatformID.Win32NT) { Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); diff --git a/src/Jackett.Tray/Jackett.Tray.csproj b/src/Jackett.Tray/Jackett.Tray.csproj index a3b0eedbd..daec5b515 100644 --- a/src/Jackett.Tray/Jackett.Tray.csproj +++ b/src/Jackett.Tray/Jackett.Tray.csproj @@ -110,7 +110,7 @@ - 2.5.0 + 2.6.0 diff --git a/src/Jackett.Updater/Jackett.Updater.csproj b/src/Jackett.Updater/Jackett.Updater.csproj index f115e19ec..0ef49e06c 100644 --- a/src/Jackett.Updater/Jackett.Updater.csproj +++ b/src/Jackett.Updater/Jackett.Updater.csproj @@ -1,7 +1,7 @@  - net461;netcoreapp2.2 + net461;netcoreapp3.0 jackett.ico JackettUpdater Exe