From 4df8fc02f1720cac683bc747b244360f0cf2dc2b Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 9 Feb 2025 17:51:35 +0200 Subject: [PATCH 01/59] Bump version to 1.31.2 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 15e63d064..a0efed9a7 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '1.31.1' + majorVersion: '1.31.2' minorVersion: $[counter('minorVersion', 1)] prowlarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(prowlarrVersion)' From 44bdff8b8fdb2fbdb07788ee884650b71f53e378 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 12 Feb 2025 15:50:29 +0200 Subject: [PATCH 02/59] Minor cleanup for AnimeTorrents --- .../Indexers/Definitions/AnimeTorrents.cs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/AnimeTorrents.cs b/src/NzbDrone.Core/Indexers/Definitions/AnimeTorrents.cs index 120fd690d..9ce2eb525 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/AnimeTorrents.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/AnimeTorrents.cs @@ -292,7 +292,7 @@ namespace NzbDrone.Core.Indexers.Definitions var qTitleLink = row.QuerySelector("td:nth-of-type(2) a:nth-of-type(1)"); var title = qTitleLink?.TextContent.Trim(); - // If we search an get no results, we still get a table just with no info. + // If we search and get no results, we still get a table just with no info. if (title.IsNullOrWhiteSpace()) { break; @@ -307,6 +307,8 @@ namespace NzbDrone.Core.Indexers.Definitions var connections = row.QuerySelector("td:nth-of-type(8)").TextContent.Trim().Split('/', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries); var seeders = ParseUtil.CoerceInt(connections[0]); + var leechers = ParseUtil.CoerceInt(connections[1]); + var grabs = ParseUtil.CoerceInt(connections[2]); var categoryLink = row.QuerySelector("td:nth-of-type(1) a")?.GetAttribute("href") ?? string.Empty; var categoryId = ParseUtil.GetArgumentFromQueryString(categoryLink, "cat"); @@ -328,17 +330,17 @@ namespace NzbDrone.Core.Indexers.Definitions PublishDate = publishedDate, Size = ParseUtil.GetBytes(row.QuerySelector("td:nth-of-type(6)").TextContent.Trim()), Seeders = seeders, - Peers = ParseUtil.CoerceInt(connections[1]) + seeders, - Grabs = ParseUtil.CoerceInt(connections[2]), + Peers = leechers + seeders, + Grabs = grabs, DownloadVolumeFactor = downloadVolumeFactor, UploadVolumeFactor = 1, Genres = row.QuerySelectorAll("td:nth-of-type(2) a.tortags").Select(t => t.TextContent.Trim()).ToList() }; - var uLFactorImg = row.QuerySelector("img[alt*=\"x Multiplier Torrent\"]"); - if (uLFactorImg != null) + var uploadFactor = row.QuerySelector("img[alt*=\"x Multiplier Torrent\"]")?.GetAttribute("alt"); + if (uploadFactor != null) { - release.UploadVolumeFactor = ParseUtil.CoerceDouble(uLFactorImg.GetAttribute("alt").Split('x')[0]); + release.UploadVolumeFactor = ParseUtil.CoerceDouble(uploadFactor.Split('x')[0]); } releaseInfos.Add(release); @@ -361,7 +363,7 @@ namespace NzbDrone.Core.Indexers.Definitions [FieldDefinition(4, Label = "Freeleech Only", Type = FieldType.Checkbox, HelpText = "Show freeleech torrents only")] public bool FreeleechOnly { get; set; } - [FieldDefinition(5, Label = "Downloadable Only", Type = FieldType.Checkbox, HelpText = "Search downloadable torrents only (enable this only if your account class is Newbie)")] + [FieldDefinition(5, Label = "Downloadable Only", Type = FieldType.Checkbox, HelpText = "Search downloadable torrents only (enable this only if your account class is Newbie)", Advanced = true)] public bool DownloadableOnly { get; set; } } } From 8672129d5a98cac9b591535aa0a63ac64df2766e Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 12 Feb 2025 15:51:48 +0200 Subject: [PATCH 03/59] Fixed: (AnimeTorrents) Switched to cookies login --- .../Indexers/Definitions/AnimeTorrents.cs | 52 +++++-------------- 1 file changed, 12 insertions(+), 40 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/AnimeTorrents.cs b/src/NzbDrone.Core/Indexers/Definitions/AnimeTorrents.cs index 9ce2eb525..14b64979b 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/AnimeTorrents.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/AnimeTorrents.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text.RegularExpressions; -using System.Threading.Tasks; using AngleSharp.Html.Parser; using NLog; using NzbDrone.Common.Extensions; @@ -44,46 +43,19 @@ namespace NzbDrone.Core.Indexers.Definitions return new AnimeTorrentsParser(Settings, Capabilities.Categories); } - protected override async Task DoLogin() - { - UpdateCookies(null, null); - - var loginUrl = Settings.BaseUrl + "login.php"; - - var loginPage = await ExecuteAuth(new HttpRequest(loginUrl)); - - var requestBuilder = new HttpRequestBuilder(loginUrl) - { - LogResponseContent = true, - AllowAutoRedirect = true - }; - - var authLoginRequest = requestBuilder - .Post() - .SetCookies(loginPage.GetCookies()) - .AddFormParameter("username", Settings.Username) - .AddFormParameter("password", Settings.Password) - .AddFormParameter("form", "login") - .AddFormParameter("rememberme[]", "1") - .SetHeader("Content-Type", "application/x-www-form-urlencoded") - .SetHeader("Referer", loginUrl) - .Build(); - - var response = await ExecuteAuth(authLoginRequest); - - if (response.Content == null || !response.Content.Contains("logout.php")) - { - throw new IndexerAuthException("AnimeTorrents authentication failed"); - } - - UpdateCookies(response.GetCookies(), DateTime.Now.AddDays(30)); - - _logger.Debug("AnimeTorrents authentication succeeded"); - } - protected override bool CheckIfLoginNeeded(HttpResponse httpResponse) { - return httpResponse.Content.Contains("Access Denied!") || httpResponse.Content.Contains("login.php"); + if (httpResponse.Content.Contains("Access Denied!") || httpResponse.Content.Contains("login.php")) + { + throw new IndexerAuthException("AnimeTorrents authentication with cookies failed."); + } + + return false; + } + + protected override IDictionary GetCookies() + { + return CookieUtil.CookieHeaderToDictionary(Settings.Cookie); } private IndexerCapabilities SetCapabilities() @@ -352,7 +324,7 @@ namespace NzbDrone.Core.Indexers.Definitions public Action, DateTime?> CookiesUpdater { get; set; } } - public class AnimeTorrentsSettings : UserPassTorrentBaseSettings + public class AnimeTorrentsSettings : CookieTorrentBaseSettings { public AnimeTorrentsSettings() { From d6e8d89be4daa73fb9d43bcd969622dc66d918e8 Mon Sep 17 00:00:00 2001 From: zodihax Date: Wed, 12 Feb 2025 18:27:09 +0100 Subject: [PATCH 04/59] Fixed: (NorBits) Update release category parsing (#2342) Co-authored-by: Bogdan --- .../Indexers/Definitions/NorBits.cs | 35 +++++-------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/NorBits.cs b/src/NzbDrone.Core/Indexers/Definitions/NorBits.cs index 4287f515f..990cf3d68 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/NorBits.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/NorBits.cs @@ -130,29 +130,13 @@ public class NorBits : TorrentIndexerBase }; caps.Categories.AddCategoryMapping("main_cat[]=1", NewznabStandardCategory.Movies, "Filmer"); - caps.Categories.AddCategoryMapping("main_cat[]=1&sub2_cat[]=49", NewznabStandardCategory.MoviesUHD, "Filmer - UHD-2160p"); - caps.Categories.AddCategoryMapping("main_cat[]=1&sub2_cat[]=19", NewznabStandardCategory.MoviesHD, "Filmer - HD-1080p/i"); - caps.Categories.AddCategoryMapping("main_cat[]=1&sub2_cat[]=20", NewznabStandardCategory.MoviesHD, "Filmer - HD-720p"); - caps.Categories.AddCategoryMapping("main_cat[]=1&sub2_cat[]=22", NewznabStandardCategory.MoviesSD, "Filmer - SD"); caps.Categories.AddCategoryMapping("main_cat[]=2", NewznabStandardCategory.TV, "TV"); - caps.Categories.AddCategoryMapping("main_cat[]=2&sub2_cat[]=49", NewznabStandardCategory.TVUHD, "TV - UHD-2160p"); - caps.Categories.AddCategoryMapping("main_cat[]=2&sub2_cat[]=19", NewznabStandardCategory.TVHD, "TV - HD-1080p/i"); - caps.Categories.AddCategoryMapping("main_cat[]=2&sub2_cat[]=20", NewznabStandardCategory.TVHD, "TV - HD-720p"); - caps.Categories.AddCategoryMapping("main_cat[]=2&sub2_cat[]=22", NewznabStandardCategory.TVSD, "TV - SD"); caps.Categories.AddCategoryMapping("main_cat[]=3", NewznabStandardCategory.PC, "Programmer"); caps.Categories.AddCategoryMapping("main_cat[]=4", NewznabStandardCategory.Console, "Spill"); caps.Categories.AddCategoryMapping("main_cat[]=5", NewznabStandardCategory.Audio, "Musikk"); - caps.Categories.AddCategoryMapping("main_cat[]=5&sub2_cat[]=42", NewznabStandardCategory.AudioMP3, "Musikk - 192"); - caps.Categories.AddCategoryMapping("main_cat[]=5&sub2_cat[]=43", NewznabStandardCategory.AudioMP3, "Musikk - 256"); - caps.Categories.AddCategoryMapping("main_cat[]=5&sub2_cat[]=44", NewznabStandardCategory.AudioMP3, "Musikk - 320"); - caps.Categories.AddCategoryMapping("main_cat[]=5&sub2_cat[]=45", NewznabStandardCategory.AudioMP3, "Musikk - VBR"); - caps.Categories.AddCategoryMapping("main_cat[]=5&sub2_cat[]=46", NewznabStandardCategory.AudioLossless, "Musikk - Lossless"); caps.Categories.AddCategoryMapping("main_cat[]=6", NewznabStandardCategory.Books, "Tidsskrift"); caps.Categories.AddCategoryMapping("main_cat[]=7", NewznabStandardCategory.AudioAudiobook, "Lydbøker"); caps.Categories.AddCategoryMapping("main_cat[]=8", NewznabStandardCategory.AudioVideo, "Musikkvideoer"); - caps.Categories.AddCategoryMapping("main_cat[]=8&sub2_cat[]=19", NewznabStandardCategory.AudioVideo, "Musikkvideoer - HD-1080p/i"); - caps.Categories.AddCategoryMapping("main_cat[]=8&sub2_cat[]=20", NewznabStandardCategory.AudioVideo, "Musikkvideoer - HD-720p"); - caps.Categories.AddCategoryMapping("main_cat[]=8&sub2_cat[]=22", NewznabStandardCategory.AudioVideo, "Musikkvideoer - SD"); caps.Categories.AddCategoryMapping("main_cat[]=40", NewznabStandardCategory.AudioOther, "Podcasts"); return caps; @@ -281,20 +265,17 @@ public class NorBitsParser : IParseIndexerResponse foreach (var row in rows) { - var link = _settings.BaseUrl + row.QuerySelector("td:nth-of-type(2) > a[href*=\"download.php?id=\"]")?.GetAttribute("href").TrimStart('/'); + var link = _settings.BaseUrl + row.QuerySelector("td:nth-of-type(2) > a[href*=\"download.php?id=\"]")?.GetAttribute("href")?.TrimStart('/'); var qDetails = row.QuerySelector("td:nth-of-type(2) > a[href*=\"details.php?id=\"]"); - var title = qDetails?.GetAttribute("title").Trim(); - var details = _settings.BaseUrl + qDetails?.GetAttribute("href").TrimStart('/'); + var title = qDetails?.GetAttribute("title")?.Trim(); + var details = _settings.BaseUrl + qDetails?.GetAttribute("href")?.TrimStart('/'); - var mainCategory = row.QuerySelector("td:nth-of-type(1) a[href*=\"main_cat[]\"]")?.GetAttribute("href")?.Split('?').Last(); - var secondCategory = row.QuerySelector("td:nth-of-type(1) a[href*=\"sub2_cat[]\"]")?.GetAttribute("href")?.Split('?').Last(); + var catQuery = row.QuerySelector("td:nth-of-type(1) a[href*=\"main_cat[]\"]")?.GetAttribute("href")?.Split('?').Last().Split('&', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); + var category = catQuery?.FirstOrDefault(x => x.StartsWith("main_cat[]=", StringComparison.OrdinalIgnoreCase)); - var categoryList = new[] { mainCategory, secondCategory }; - var cat = string.Join("&", categoryList.Where(c => !string.IsNullOrWhiteSpace(c))); - - var seeders = ParseUtil.CoerceInt(row.QuerySelector("td:nth-of-type(9)").TextContent); - var leechers = ParseUtil.CoerceInt(row.QuerySelector("td:nth-of-type(10)").TextContent); + var seeders = ParseUtil.CoerceInt(row.QuerySelector("td:nth-of-type(9)")?.TextContent); + var leechers = ParseUtil.CoerceInt(row.QuerySelector("td:nth-of-type(10)")?.TextContent); var release = new TorrentInfo { @@ -302,7 +283,7 @@ public class NorBitsParser : IParseIndexerResponse InfoUrl = details, DownloadUrl = link, Title = title, - Categories = _categories.MapTrackerCatToNewznab(cat), + Categories = _categories.MapTrackerCatToNewznab(category), Size = ParseUtil.GetBytes(row.QuerySelector("td:nth-of-type(7)")?.TextContent), Files = ParseUtil.CoerceInt(row.QuerySelector("td:nth-of-type(3) > a")?.TextContent.Trim()), Grabs = ParseUtil.CoerceInt(row.QuerySelector("td:nth-of-type(8)")?.FirstChild?.TextContent.Trim()), From 0f1d647cd7510bb48be01354aeea8edcf88b257d Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 16 Feb 2025 11:50:48 +0200 Subject: [PATCH 05/59] Fixed: (FileList) Download links when passkey contains spaces --- .../Indexers/Definitions/FileList/FileListParser.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/FileList/FileListParser.cs b/src/NzbDrone.Core/Indexers/Definitions/FileList/FileListParser.cs index a15751ab7..b45ddf19b 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/FileList/FileListParser.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/FileList/FileListParser.cs @@ -101,7 +101,7 @@ public class FileListParser : IParseIndexerResponse var url = new HttpUri(_settings.BaseUrl) .CombinePath("/download.php") .AddQueryParam("id", torrentId.ToString()) - .AddQueryParam("passkey", _settings.Passkey); + .AddQueryParam("passkey", _settings.Passkey.Trim()); return url.FullUri; } From 2d584f7eb64eeddb292b60a7cf1cfbf433debc99 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 18 Feb 2025 02:11:57 +0200 Subject: [PATCH 06/59] New: Support for exclusive indexer flag Co-authored-by: zakkarry --- .../IndexerTests/HDBitsTests/HDBitsFixture.cs | 8 ++--- .../Indexers/Definitions/BeyondHD.cs | 33 ++++++++++++------ .../Indexers/Definitions/HDBits/HDBits.cs | 7 +++- .../Indexers/Definitions/HDBits/HDBitsApi.cs | 3 ++ .../Indexers/Definitions/HDBits/HDBitsInfo.cs | 9 ----- .../Definitions/HDBits/HDBitsParser.cs | 34 ++++++++++++------- src/NzbDrone.Core/Indexers/IndexerFlag.cs | 1 + 7 files changed, 58 insertions(+), 37 deletions(-) delete mode 100644 src/NzbDrone.Core/Indexers/Definitions/HDBits/HDBitsInfo.cs diff --git a/src/NzbDrone.Core.Test/IndexerTests/HDBitsTests/HDBitsFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/HDBitsTests/HDBitsFixture.cs index 39d628d79..06326d162 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/HDBitsTests/HDBitsFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/HDBitsTests/HDBitsFixture.cs @@ -26,15 +26,15 @@ namespace NzbDrone.Core.Test.IndexerTests.HDBitsTests [SetUp] public void Setup() { - Subject.Definition = new IndexerDefinition() + Subject.Definition = new IndexerDefinition { Name = "HdBits", - Settings = new HDBitsSettings() { ApiKey = "fakekey" } + Settings = new HDBitsSettings { ApiKey = "fakekey" } }; _movieSearchCriteria = new MovieSearchCriteria { - Categories = new int[] { 2000, 2010 }, + Categories = new[] { 2000, 2010 }, ImdbId = "0076759" }; } @@ -52,7 +52,7 @@ namespace NzbDrone.Core.Test.IndexerTests.HDBitsTests var torrents = (await Subject.Fetch(_movieSearchCriteria)).Releases; torrents.Should().HaveCount(2); - torrents.First().Should().BeOfType(); + torrents.First().Should().BeOfType(); var first = torrents.First() as TorrentInfo; diff --git a/src/NzbDrone.Core/Indexers/Definitions/BeyondHD.cs b/src/NzbDrone.Core/Indexers/Definitions/BeyondHD.cs index f9194f00a..efa1a667d 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/BeyondHD.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/BeyondHD.cs @@ -55,7 +55,7 @@ namespace NzbDrone.Core.Indexers.Definitions return FilterReleasesByQuery(cleanReleases, searchCriteria).ToList(); } - private IndexerCapabilities SetCapabilities() + private static IndexerCapabilities SetCapabilities() { var caps = new IndexerCapabilities { @@ -69,7 +69,8 @@ namespace NzbDrone.Core.Indexers.Definitions }, Flags = new List { - IndexerFlag.Internal + IndexerFlag.Internal, + IndexerFlag.Exclusive, } }; @@ -275,13 +276,6 @@ namespace NzbDrone.Core.Indexers.Definitions var details = row.InfoUrl; var link = row.DownloadLink; - var flags = new HashSet(); - - if (row.Internal) - { - flags.Add(IndexerFlag.Internal); - } - var release = new TorrentInfo { Title = row.Name, @@ -291,7 +285,7 @@ namespace NzbDrone.Core.Indexers.Definitions Guid = details, Categories = _categories.MapTrackerCatDescToNewznab(row.Category), PublishDate = DateTime.Parse(row.CreatedAt, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal), - IndexerFlags = flags, + IndexerFlags = GetIndexerFlags(row), Size = row.Size, Grabs = row.Grabs, Seeders = row.Seeders, @@ -319,6 +313,23 @@ namespace NzbDrone.Core.Indexers.Definitions .ToArray(); } + private static HashSet GetIndexerFlags(BeyondHDTorrent item) + { + var flags = new HashSet(); + + if (item.Internal) + { + flags.Add(IndexerFlag.Internal); + } + + if (item.Exclusive) + { + flags.Add(IndexerFlag.Exclusive); + } + + return flags; + } + public Action, DateTime?> CookiesUpdater { get; set; } } @@ -478,6 +489,8 @@ namespace NzbDrone.Core.Indexers.Definitions public bool Limited { get; set; } + public bool Exclusive { get; set; } + public bool Internal { get; set; } } } diff --git a/src/NzbDrone.Core/Indexers/Definitions/HDBits/HDBits.cs b/src/NzbDrone.Core/Indexers/Definitions/HDBits/HDBits.cs index 84ea1be25..b4d924511 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/HDBits/HDBits.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/HDBits/HDBits.cs @@ -32,7 +32,7 @@ namespace NzbDrone.Core.Indexers.Definitions.HDBits return new HDBitsParser(Settings, Capabilities.Categories); } - private IndexerCapabilities SetCapabilities() + private static IndexerCapabilities SetCapabilities() { var caps = new IndexerCapabilities { @@ -43,6 +43,11 @@ namespace NzbDrone.Core.Indexers.Definitions.HDBits MovieSearchParams = new List { MovieSearchParam.Q, MovieSearchParam.ImdbId + }, + Flags = new List + { + IndexerFlag.Internal, + IndexerFlag.Exclusive, } }; diff --git a/src/NzbDrone.Core/Indexers/Definitions/HDBits/HDBitsApi.cs b/src/NzbDrone.Core/Indexers/Definitions/HDBits/HDBitsApi.cs index c66c6213e..5f8b947ae 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/HDBits/HDBitsApi.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/HDBits/HDBitsApi.cs @@ -85,6 +85,9 @@ namespace NzbDrone.Core.Indexers.Definitions.HDBits [JsonProperty(PropertyName = "type_origin")] public int TypeOrigin { get; set; } + [JsonProperty(PropertyName = "type_exclusive")] + public int TypeExclusive { get; set; } + [JsonProperty(PropertyName = "imdb")] public ImdbInfo ImdbInfo { get; set; } diff --git a/src/NzbDrone.Core/Indexers/Definitions/HDBits/HDBitsInfo.cs b/src/NzbDrone.Core/Indexers/Definitions/HDBits/HDBitsInfo.cs deleted file mode 100644 index 412295abf..000000000 --- a/src/NzbDrone.Core/Indexers/Definitions/HDBits/HDBitsInfo.cs +++ /dev/null @@ -1,9 +0,0 @@ -using NzbDrone.Core.Parser.Model; - -namespace NzbDrone.Core.Indexers.Definitions.HDBits -{ - public class HDBitsInfo : TorrentInfo - { - public bool? Internal { get; set; } - } -} diff --git a/src/NzbDrone.Core/Indexers/Definitions/HDBits/HDBitsParser.cs b/src/NzbDrone.Core/Indexers/Definitions/HDBits/HDBitsParser.cs index ff6692407..8b0b55319 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/HDBits/HDBitsParser.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/HDBits/HDBitsParser.cs @@ -62,16 +62,8 @@ namespace NzbDrone.Core.Indexers.Definitions.HDBits } var id = result.Id; - var internalRelease = result.TypeOrigin == 1; - var flags = new HashSet(); - - if (internalRelease) - { - flags.Add(IndexerFlag.Internal); - } - - releaseInfos.Add(new HDBitsInfo + releaseInfos.Add(new TorrentInfo { Guid = $"HDBits-{id}", Title = GetTitle(result), @@ -85,21 +77,18 @@ namespace NzbDrone.Core.Indexers.Definitions.HDBits Files = (int)result.NumFiles, Peers = result.Leechers + result.Seeders, PublishDate = result.Added.ToUniversalTime(), - Internal = internalRelease, Year = result.ImdbInfo?.Year ?? 0, ImdbId = result.ImdbInfo?.Id ?? 0, TvdbId = result.TvdbInfo?.Id ?? 0, DownloadVolumeFactor = GetDownloadVolumeFactor(result), UploadVolumeFactor = GetUploadVolumeFactor(result), - IndexerFlags = flags + IndexerFlags = GetIndexerFlags(result) }); } return releaseInfos.ToArray(); } - public Action, DateTime?> CookiesUpdater { get; set; } - private string GetTitle(TorrentQueryResponse item) { // Use release name for XXX content and full discs @@ -108,6 +97,23 @@ namespace NzbDrone.Core.Indexers.Definitions.HDBits : item.Name; } + private static HashSet GetIndexerFlags(TorrentQueryResponse item) + { + var flags = new HashSet(); + + if (item.TypeOrigin == 1) + { + flags.Add(IndexerFlag.Internal); + } + + if (item.TypeExclusive == 1) + { + flags.Add(IndexerFlag.Exclusive); + } + + return flags; + } + private double GetDownloadVolumeFactor(TorrentQueryResponse item) { if (item.FreeLeech == "yes") @@ -154,5 +160,7 @@ namespace NzbDrone.Core.Indexers.Definitions.HDBits return url.FullUri; } + + public Action, DateTime?> CookiesUpdater { get; set; } } } diff --git a/src/NzbDrone.Core/Indexers/IndexerFlag.cs b/src/NzbDrone.Core/Indexers/IndexerFlag.cs index 26a65e96c..cfa3d35de 100644 --- a/src/NzbDrone.Core/Indexers/IndexerFlag.cs +++ b/src/NzbDrone.Core/Indexers/IndexerFlag.cs @@ -63,6 +63,7 @@ namespace NzbDrone.Core.Indexers } public static IndexerFlag Internal => new ("internal", "Uploader is an internal release group"); + public static IndexerFlag Exclusive => new ("exclusive", "An exclusive release that must not be uploaded anywhere else"); public static IndexerFlag FreeLeech => new ("freeleech", "Download doesn't count toward ratio"); public static IndexerFlag NeutralLeech => new ("neutralleech", "Download and upload doesn't count toward ratio"); public static IndexerFlag HalfLeech => new ("halfleech", "Release counts 50% to ratio"); From d5b12cf51a7adf48d4ef5455014c61443a8a01ef Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 18 Feb 2025 04:00:24 +0200 Subject: [PATCH 07/59] Fixed release guid for SpeedApp --- src/NzbDrone.Core/Indexers/Definitions/SpeedApp/SpeedAppBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/SpeedApp/SpeedAppBase.cs b/src/NzbDrone.Core/Indexers/Definitions/SpeedApp/SpeedAppBase.cs index f0170d868..244a9c286 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/SpeedApp/SpeedAppBase.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/SpeedApp/SpeedAppBase.cs @@ -262,7 +262,7 @@ namespace NzbDrone.Core.Indexers.Definitions return jsonResponse.Resource.Select(torrent => new TorrentInfo { - Guid = torrent.Id.ToString(), + Guid = torrent.Url, Title = CleanTitle(torrent.Name), Description = torrent.ShortDescription, Size = torrent.Size, From 59b5d2fc786f5a0fca37d1a191772522f17debcd Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Wed, 29 Jan 2025 18:46:19 -0800 Subject: [PATCH 08/59] Fixed: Drop downs flickering in some cases (cherry picked from commit 3b024443c5447b7638a69a99809bf44b2419261f) --- .../src/Components/Form/EnhancedSelectInput.js | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/frontend/src/Components/Form/EnhancedSelectInput.js b/frontend/src/Components/Form/EnhancedSelectInput.js index 732e10f37..79b1c999c 100644 --- a/frontend/src/Components/Form/EnhancedSelectInput.js +++ b/frontend/src/Components/Form/EnhancedSelectInput.js @@ -20,6 +20,8 @@ import HintedSelectInputSelectedValue from './HintedSelectInputSelectedValue'; import TextInput from './TextInput'; import styles from './EnhancedSelectInput.css'; +const MINIMUM_DISTANCE_FROM_EDGE = 10; + function isArrowKey(keyCode) { return keyCode === keyCodes.UP_ARROW || keyCode === keyCodes.DOWN_ARROW; } @@ -137,18 +139,9 @@ class EnhancedSelectInput extends Component { // Listeners onComputeMaxHeight = (data) => { - const { - top, - bottom - } = data.offsets.reference; - const windowHeight = window.innerHeight; - if ((/^botton/).test(data.placement)) { - data.styles.maxHeight = windowHeight - bottom; - } else { - data.styles.maxHeight = top; - } + data.styles.maxHeight = windowHeight - MINIMUM_DISTANCE_FROM_EDGE; return data; }; @@ -460,6 +453,10 @@ class EnhancedSelectInput extends Component { order: 851, enabled: true, fn: this.onComputeMaxHeight + }, + preventOverflow: { + enabled: true, + boundariesElement: 'viewport' } }} > From 790feed5ab6b26ba25e50a6db81e0504e7823d17 Mon Sep 17 00:00:00 2001 From: Stevie Robinson Date: Wed, 19 Feb 2025 04:23:43 +0100 Subject: [PATCH 09/59] Fixed: Fallback to Instance Name for Discord notifications (cherry picked from commit b99e06acc0a3ecae2857d9225b35424c82c67a2b) --- .../Notifications/Discord/Discord.cs | 154 ++++++++---------- 1 file changed, 67 insertions(+), 87 deletions(-) diff --git a/src/NzbDrone.Core/Notifications/Discord/Discord.cs b/src/NzbDrone.Core/Notifications/Discord/Discord.cs index 9eb41e989..48b93f35d 100644 --- a/src/NzbDrone.Core/Notifications/Discord/Discord.cs +++ b/src/NzbDrone.Core/Notifications/Discord/Discord.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using FluentValidation.Results; using NzbDrone.Common.Extensions; +using NzbDrone.Core.Configuration; using NzbDrone.Core.Notifications.Discord.Payloads; using NzbDrone.Core.Validation; @@ -10,10 +11,12 @@ namespace NzbDrone.Core.Notifications.Discord public class Discord : NotificationBase { private readonly IDiscordProxy _proxy; + private readonly IConfigFileProvider _configFileProvider; - public Discord(IDiscordProxy proxy) + public Discord(IDiscordProxy proxy, IConfigFileProvider configFileProvider) { _proxy = proxy; + _configFileProvider = configFileProvider; } public override string Name => "Discord"; @@ -22,18 +25,18 @@ namespace NzbDrone.Core.Notifications.Discord public override void OnGrab(GrabMessage message) { var embed = new Embed - { - Author = new DiscordAuthor - { - Name = Settings.Author.IsNullOrWhiteSpace() ? Environment.MachineName : Settings.Author, - IconUrl = "https://raw.githubusercontent.com/Prowlarr/Prowlarr/develop/Logo/256.png" - }, - Title = RELEASE_GRABBED_TITLE, - Description = message.Message, - Timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"), - Color = message.Successful ? (int)DiscordColors.Success : (int)DiscordColors.Danger, - Fields = new List() - }; + { + Author = new DiscordAuthor + { + Name = Settings.Author.IsNullOrWhiteSpace() ? _configFileProvider.InstanceName : Settings.Author, + IconUrl = "https://raw.githubusercontent.com/Prowlarr/Prowlarr/develop/Logo/256.png" + }, + Title = RELEASE_GRABBED_TITLE, + Description = message.Message, + Timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"), + Color = message.Successful ? (int)DiscordColors.Success : (int)DiscordColors.Danger, + Fields = new List() + }; foreach (var field in Settings.GrabFields) { @@ -80,81 +83,72 @@ namespace NzbDrone.Core.Notifications.Discord public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck) { - var attachments = new List - { - new Embed - { - Author = new DiscordAuthor - { - Name = Settings.Author.IsNullOrWhiteSpace() ? Environment.MachineName : Settings.Author, - IconUrl = "https://raw.githubusercontent.com/Prowlarr/Prowlarr/develop/Logo/256.png" - }, - Title = healthCheck.Source.Name, - Description = healthCheck.Message, - Timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"), - Color = healthCheck.Type == HealthCheck.HealthCheckResult.Warning ? (int)DiscordColors.Warning : (int)DiscordColors.Danger - } - }; + var embed = new Embed + { + Author = new DiscordAuthor + { + Name = Settings.Author.IsNullOrWhiteSpace() ? _configFileProvider.InstanceName : Settings.Author, + IconUrl = "https://raw.githubusercontent.com/Prowlarr/Prowlarr/develop/Logo/256.png" + }, + Title = healthCheck.Source.Name, + Description = healthCheck.Message, + Timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"), + Color = healthCheck.Type == HealthCheck.HealthCheckResult.Warning ? (int)DiscordColors.Warning : (int)DiscordColors.Danger + }; - var payload = CreatePayload(null, attachments); + var payload = CreatePayload(null, new List { embed }); _proxy.SendPayload(payload, Settings); } public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck) { - var attachments = new List - { - new Embed - { - Author = new DiscordAuthor - { - Name = Settings.Author.IsNullOrWhiteSpace() ? Environment.MachineName : Settings.Author, - IconUrl = "https://raw.githubusercontent.com/Prowlarr/Prowlarr/develop/Logo/256.png" - }, - Title = "Health Issue Resolved: " + previousCheck.Source.Name, - Description = $"The following issue is now resolved: {previousCheck.Message}", - Timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"), - Color = (int)DiscordColors.Success - } - }; + var embed = new Embed + { + Author = new DiscordAuthor + { + Name = Settings.Author.IsNullOrWhiteSpace() ? _configFileProvider.InstanceName : Settings.Author, + IconUrl = "https://raw.githubusercontent.com/Prowlarr/Prowlarr/develop/Logo/256.png" + }, + Title = "Health Issue Resolved: " + previousCheck.Source.Name, + Description = $"The following issue is now resolved: {previousCheck.Message}", + Timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"), + Color = (int)DiscordColors.Success + }; - var payload = CreatePayload(null, attachments); + var payload = CreatePayload(null, new List { embed }); _proxy.SendPayload(payload, Settings); } public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage) { - var attachments = new List - { - new Embed - { - Author = new DiscordAuthor - { - Name = Settings.Author.IsNullOrWhiteSpace() ? Environment.MachineName : Settings.Author, - IconUrl = "https://raw.githubusercontent.com/Prowlarr/Prowlarr/develop/Logo/256.png" - }, - Title = APPLICATION_UPDATE_TITLE, - Timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"), - Color = (int)DiscordColors.Standard, - Fields = new List() - { - new DiscordField() - { - Name = "Previous Version", - Value = updateMessage.PreviousVersion.ToString() - }, - new DiscordField() - { - Name = "New Version", - Value = updateMessage.NewVersion.ToString() - } - }, - } - }; + var embed = new Embed + { + Author = new DiscordAuthor + { + Name = Settings.Author.IsNullOrWhiteSpace() ? _configFileProvider.InstanceName : Settings.Author, + IconUrl = "https://raw.githubusercontent.com/Prowlarr/Prowlarr/develop/Logo/256.png" + }, + Title = APPLICATION_UPDATE_TITLE, + Timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"), + Color = (int)DiscordColors.Standard, + Fields = new List + { + new () + { + Name = "Previous Version", + Value = updateMessage.PreviousVersion.ToString() + }, + new () + { + Name = "New Version", + Value = updateMessage.NewVersion.ToString() + } + }, + }; - var payload = CreatePayload(null, attachments); + var payload = CreatePayload(null, new List { embed }); _proxy.SendPayload(payload, Settings); } @@ -208,19 +202,5 @@ namespace NzbDrone.Core.Notifications.Discord return payload; } - - private static string BytesToString(long byteCount) - { - string[] suf = { "B", "KB", "MB", "GB", "TB", "PB", "EB" }; //Longs run out around EB - if (byteCount == 0) - { - return "0 " + suf[0]; - } - - var bytes = Math.Abs(byteCount); - var place = Convert.ToInt32(Math.Floor(Math.Log(bytes, 1024))); - var num = Math.Round(bytes / Math.Pow(1024, place), 1); - return string.Format("{0} {1}", (Math.Sign(byteCount) * num).ToString(), suf[place]); - } } } From 635e76526a38dd1c28d659c5a71f877e794ac700 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sun, 16 Feb 2025 19:15:27 -0800 Subject: [PATCH 10/59] Cleanse console log messages (cherry picked from commit 609e964794e17343f63e1ecff3fef323e3d284ff) --- .../Instrumentation/CleansingClefLogLayout.cs | 21 +++++++++++++ .../CleansingConsoleLogLayout.cs | 26 ++++++++++++++++ ...neFileTarget.cs => CleansingFileTarget.cs} | 2 +- .../Instrumentation/NzbDroneLogger.cs | 30 +++++++++++-------- .../Instrumentation/ReconfigureLogging.cs | 8 ++--- 5 files changed, 68 insertions(+), 19 deletions(-) create mode 100644 src/NzbDrone.Common/Instrumentation/CleansingClefLogLayout.cs create mode 100644 src/NzbDrone.Common/Instrumentation/CleansingConsoleLogLayout.cs rename src/NzbDrone.Common/Instrumentation/{NzbDroneFileTarget.cs => CleansingFileTarget.cs} (87%) diff --git a/src/NzbDrone.Common/Instrumentation/CleansingClefLogLayout.cs b/src/NzbDrone.Common/Instrumentation/CleansingClefLogLayout.cs new file mode 100644 index 000000000..f110b96ac --- /dev/null +++ b/src/NzbDrone.Common/Instrumentation/CleansingClefLogLayout.cs @@ -0,0 +1,21 @@ +using System.Text; +using NLog; +using NLog.Layouts.ClefJsonLayout; +using NzbDrone.Common.EnvironmentInfo; + +namespace NzbDrone.Common.Instrumentation; + +public class CleansingClefLogLayout : CompactJsonLayout +{ + protected override void RenderFormattedMessage(LogEventInfo logEvent, StringBuilder target) + { + base.RenderFormattedMessage(logEvent, target); + + if (RuntimeInfo.IsProduction) + { + var result = CleanseLogMessage.Cleanse(target.ToString()); + target.Clear(); + target.Append(result); + } + } +} diff --git a/src/NzbDrone.Common/Instrumentation/CleansingConsoleLogLayout.cs b/src/NzbDrone.Common/Instrumentation/CleansingConsoleLogLayout.cs new file mode 100644 index 000000000..f894a4df5 --- /dev/null +++ b/src/NzbDrone.Common/Instrumentation/CleansingConsoleLogLayout.cs @@ -0,0 +1,26 @@ +using System.Text; +using NLog; +using NLog.Layouts; +using NzbDrone.Common.EnvironmentInfo; + +namespace NzbDrone.Common.Instrumentation; + +public class CleansingConsoleLogLayout : SimpleLayout +{ + public CleansingConsoleLogLayout(string format) + : base(format) + { + } + + protected override void RenderFormattedMessage(LogEventInfo logEvent, StringBuilder target) + { + base.RenderFormattedMessage(logEvent, target); + + if (RuntimeInfo.IsProduction) + { + var result = CleanseLogMessage.Cleanse(target.ToString()); + target.Clear(); + target.Append(result); + } + } +} diff --git a/src/NzbDrone.Common/Instrumentation/NzbDroneFileTarget.cs b/src/NzbDrone.Common/Instrumentation/CleansingFileTarget.cs similarity index 87% rename from src/NzbDrone.Common/Instrumentation/NzbDroneFileTarget.cs rename to src/NzbDrone.Common/Instrumentation/CleansingFileTarget.cs index 84658cf74..f74d1fca4 100644 --- a/src/NzbDrone.Common/Instrumentation/NzbDroneFileTarget.cs +++ b/src/NzbDrone.Common/Instrumentation/CleansingFileTarget.cs @@ -4,7 +4,7 @@ using NLog.Targets; namespace NzbDrone.Common.Instrumentation { - public class NzbDroneFileTarget : FileTarget + public class CleansingFileTarget : FileTarget { protected override void RenderFormattedMessage(LogEventInfo logEvent, StringBuilder target) { diff --git a/src/NzbDrone.Common/Instrumentation/NzbDroneLogger.cs b/src/NzbDrone.Common/Instrumentation/NzbDroneLogger.cs index 80793e812..d9fdd5b25 100644 --- a/src/NzbDrone.Common/Instrumentation/NzbDroneLogger.cs +++ b/src/NzbDrone.Common/Instrumentation/NzbDroneLogger.cs @@ -3,7 +3,6 @@ using System.Diagnostics; using System.IO; using NLog; using NLog.Config; -using NLog.Layouts.ClefJsonLayout; using NLog.Targets; using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.Extensions; @@ -13,9 +12,11 @@ namespace NzbDrone.Common.Instrumentation { public static class NzbDroneLogger { - private const string FILE_LOG_LAYOUT = @"${date:format=yyyy-MM-dd HH\:mm\:ss.f}|${level}|${logger}|${message}${onexception:inner=${newline}${newline}[v${assembly-version}] ${exception:format=ToString}${newline}${exception:format=Data}${newline}}"; - public const string ConsoleLogLayout = "[${level}] ${logger}: ${message} ${onexception:inner=${newline}${newline}[v${assembly-version}] ${exception:format=ToString}${newline}${exception:format=Data}${newline}}"; - public static CompactJsonLayout ClefLogLayout = new CompactJsonLayout(); + private const string FileLogLayout = @"${date:format=yyyy-MM-dd HH\:mm\:ss.f}|${level}|${logger}|${message}${onexception:inner=${newline}${newline}[v${assembly-version}] ${exception:format=ToString}${newline}${exception:format=Data}${newline}}"; + private const string ConsoleFormat = "[${level}] ${logger}: ${message} ${onexception:inner=${newline}${newline}[v${assembly-version}] ${exception:format=ToString}${newline}${exception:format=Data}${newline}}"; + + private static readonly CleansingConsoleLogLayout CleansingConsoleLayout = new (ConsoleFormat); + private static readonly CleansingClefLogLayout ClefLogLayout = new (); private static bool _isConfigured; @@ -119,11 +120,7 @@ namespace NzbDrone.Common.Instrumentation ? formatEnumValue : ConsoleLogFormat.Standard; - coloredConsoleTarget.Layout = logFormat switch - { - ConsoleLogFormat.Clef => ClefLogLayout, - _ => ConsoleLogLayout - }; + ConfigureConsoleLayout(coloredConsoleTarget, logFormat); var loggingRule = new LoggingRule("*", level, coloredConsoleTarget); @@ -140,7 +137,7 @@ namespace NzbDrone.Common.Instrumentation private static void RegisterAppFile(IAppFolderInfo appFolderInfo, string name, string fileName, int maxArchiveFiles, LogLevel minLogLevel) { - var fileTarget = new NzbDroneFileTarget(); + var fileTarget = new CleansingFileTarget(); fileTarget.Name = name; fileTarget.FileName = Path.Combine(appFolderInfo.GetLogFolder(), fileName); @@ -153,7 +150,7 @@ namespace NzbDrone.Common.Instrumentation fileTarget.MaxArchiveFiles = maxArchiveFiles; fileTarget.EnableFileDelete = true; fileTarget.ArchiveNumbering = ArchiveNumberingMode.Rolling; - fileTarget.Layout = FILE_LOG_LAYOUT; + fileTarget.Layout = FileLogLayout; var loggingRule = new LoggingRule("*", minLogLevel, fileTarget); @@ -172,7 +169,7 @@ namespace NzbDrone.Common.Instrumentation fileTarget.ConcurrentWrites = false; fileTarget.ConcurrentWriteAttemptDelay = 50; fileTarget.ConcurrentWriteAttempts = 100; - fileTarget.Layout = FILE_LOG_LAYOUT; + fileTarget.Layout = FileLogLayout; var loggingRule = new LoggingRule("*", LogLevel.Trace, fileTarget); @@ -217,6 +214,15 @@ namespace NzbDrone.Common.Instrumentation { return GetLogger(obj.GetType()); } + + public static void ConfigureConsoleLayout(ColoredConsoleTarget target, ConsoleLogFormat format) + { + target.Layout = format switch + { + ConsoleLogFormat.Clef => NzbDroneLogger.ClefLogLayout, + _ => NzbDroneLogger.CleansingConsoleLayout + }; + } } public enum ConsoleLogFormat diff --git a/src/NzbDrone.Core/Instrumentation/ReconfigureLogging.cs b/src/NzbDrone.Core/Instrumentation/ReconfigureLogging.cs index 346b6acf1..ac0cd085b 100644 --- a/src/NzbDrone.Core/Instrumentation/ReconfigureLogging.cs +++ b/src/NzbDrone.Core/Instrumentation/ReconfigureLogging.cs @@ -95,7 +95,7 @@ namespace NzbDrone.Core.Instrumentation private void ReconfigureFile() { - foreach (var target in LogManager.Configuration.AllTargets.OfType()) + foreach (var target in LogManager.Configuration.AllTargets.OfType()) { target.MaxArchiveFiles = _configFileProvider.LogRotate; target.ArchiveAboveSize = _configFileProvider.LogSizeLimit.Megabytes(); @@ -120,11 +120,7 @@ namespace NzbDrone.Core.Instrumentation { var format = _configFileProvider.ConsoleLogFormat; - consoleTarget.Layout = format switch - { - ConsoleLogFormat.Clef => NzbDroneLogger.ClefLogLayout, - _ => NzbDroneLogger.ConsoleLogLayout - }; + NzbDroneLogger.ConfigureConsoleLayout(consoleTarget, format); } } From 328f3c0423511447eb0dac94ba602b009cd54fd0 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 22 Feb 2025 12:55:30 +0200 Subject: [PATCH 11/59] Bump version to 1.32.0 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index a0efed9a7..a7dad740e 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '1.31.2' + majorVersion: '1.32.0' minorVersion: $[counter('minorVersion', 1)] prowlarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(prowlarrVersion)' From b09d4927cc67593518c12ed0d45cff927f1b6c73 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 26 Feb 2025 03:59:22 +0200 Subject: [PATCH 12/59] Check instance name must contain application name with culture-insensitive --- src/NzbDrone.Core/Configuration/ConfigFileProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/Configuration/ConfigFileProvider.cs b/src/NzbDrone.Core/Configuration/ConfigFileProvider.cs index b9f4f23d2..f4715b203 100644 --- a/src/NzbDrone.Core/Configuration/ConfigFileProvider.cs +++ b/src/NzbDrone.Core/Configuration/ConfigFileProvider.cs @@ -274,7 +274,7 @@ namespace NzbDrone.Core.Configuration { var instanceName = _appOptions.InstanceName ?? GetValue("InstanceName", BuildInfo.AppName); - if (instanceName.ContainsIgnoreCase(BuildInfo.AppName)) + if (instanceName.Contains(BuildInfo.AppName, StringComparison.OrdinalIgnoreCase)) { return instanceName; } From 53bc97b3be93c5c74da341b56472a6813d2c12c5 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 1 Mar 2025 17:34:58 +0200 Subject: [PATCH 13/59] Fixed: (BeyondHd) Search daily episodes using year-month-day format --- .../Indexers/Definitions/BeyondHD.cs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/BeyondHD.cs b/src/NzbDrone.Core/Indexers/Definitions/BeyondHD.cs index efa1a667d..33a80f43a 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/BeyondHD.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/BeyondHD.cs @@ -92,7 +92,7 @@ namespace NzbDrone.Core.Indexers.Definitions _capabilities = capabilities; } - private IEnumerable GetPagedRequests(SearchCriteriaBase searchCriteria, string term, string imdbId = null, int tmdbId = 0) + private IEnumerable GetPagedRequests(SearchCriteriaBase searchCriteria, string searchTerm, string imdbId = null, int tmdbId = 0) { var body = new Dictionary { @@ -129,9 +129,9 @@ namespace NzbDrone.Core.Indexers.Definitions body.Add("tmdb_id", tmdbId); } - if (term.IsNotNullOrWhiteSpace()) + if (searchTerm.IsNotNullOrWhiteSpace()) { - body.Add("search", term); + body.Add("search", searchTerm.Trim()); } var cats = _capabilities.Categories.MapTorznabCapsToTrackers(searchCriteria.Categories); @@ -199,7 +199,16 @@ namespace NzbDrone.Core.Indexers.Definitions { var pageableRequests = new IndexerPageableRequestChain(); - pageableRequests.Add(GetPagedRequests(searchCriteria, searchCriteria.SanitizedTvSearchString, searchCriteria.FullImdbId)); + var searchTerm = searchCriteria.SanitizedTvSearchString; + + if (searchCriteria.Season is > 0 && + searchCriteria.Episode.IsNotNullOrWhiteSpace() && + DateTime.TryParseExact($"{searchCriteria.Season} {searchCriteria.Episode}", "yyyy MM/dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out var showDate)) + { + searchTerm = $"{searchCriteria.SanitizedSearchTerm} {showDate.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture)}"; + } + + pageableRequests.Add(GetPagedRequests(searchCriteria, searchTerm, searchCriteria.FullImdbId)); return pageableRequests; } From 46b6124b978e3ecb3a2cd948d4750f08cedc5390 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 2 Mar 2025 12:17:40 +0200 Subject: [PATCH 14/59] Bump version to 1.32.1 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index a7dad740e..7480d2763 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '1.32.0' + majorVersion: '1.32.1' minorVersion: $[counter('minorVersion', 1)] prowlarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(prowlarrVersion)' From f02a6f3e2cdb64763d3e03e5203169c842dbaece Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 3 Mar 2025 17:16:59 +0200 Subject: [PATCH 15/59] Update timezone offset for AvistaZ trackers --- src/NzbDrone.Core/Indexers/Definitions/AvistaZ.cs | 2 +- .../Indexers/Definitions/Avistaz/AvistazParserBase.cs | 2 +- src/NzbDrone.Core/Indexers/Definitions/ExoticaZ.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/AvistaZ.cs b/src/NzbDrone.Core/Indexers/Definitions/AvistaZ.cs index 7d9ba3b51..4e1899651 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/AvistaZ.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/AvistaZ.cs @@ -84,6 +84,6 @@ namespace NzbDrone.Core.Indexers.Definitions public class AvistaZParser : AvistazParserBase { - protected override string TimezoneOffset => "+02:00"; + protected override string TimezoneOffset => "+01:00"; } } diff --git a/src/NzbDrone.Core/Indexers/Definitions/Avistaz/AvistazParserBase.cs b/src/NzbDrone.Core/Indexers/Definitions/Avistaz/AvistazParserBase.cs index 56cc7a3fe..84e36cf7e 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Avistaz/AvistazParserBase.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Avistaz/AvistazParserBase.cs @@ -14,7 +14,7 @@ namespace NzbDrone.Core.Indexers.Definitions.Avistaz { public class AvistazParserBase : IParseIndexerResponse { - protected virtual string TimezoneOffset => "-04:00"; // Avistaz does not specify a timezone & returns server time + protected virtual string TimezoneOffset => "-05:00"; // Avistaz does not specify a timezone & returns server time private readonly HashSet _hdResolutions = new () { "1080p", "1080i", "720p" }; public Action, DateTime?> CookiesUpdater { get; set; } diff --git a/src/NzbDrone.Core/Indexers/Definitions/ExoticaZ.cs b/src/NzbDrone.Core/Indexers/Definitions/ExoticaZ.cs index 0933ea6a2..784cc56e4 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/ExoticaZ.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/ExoticaZ.cs @@ -54,7 +54,7 @@ namespace NzbDrone.Core.Indexers.Definitions { private readonly IndexerCapabilitiesCategories _categories; - protected override string TimezoneOffset => "+02:00"; + protected override string TimezoneOffset => "+01:00"; public ExoticaZParser(IndexerCapabilitiesCategories categories) { From 49268f3b8d0c57775db282445ff1096a0fc22096 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 4 Mar 2025 13:15:44 +0200 Subject: [PATCH 16/59] Fix timezone offset tests for AvistaZ trackers --- .../IndexerTests/AvistazTests/AvistazFixture.cs | 2 +- .../IndexerTests/AvistazTests/ExoticazFixture.cs | 2 +- .../IndexerTests/AvistazTests/PrivateHDFixture.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/NzbDrone.Core.Test/IndexerTests/AvistazTests/AvistazFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/AvistazTests/AvistazFixture.cs index dcabb4dbf..b8f7951d2 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/AvistazTests/AvistazFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/AvistazTests/AvistazFixture.cs @@ -51,7 +51,7 @@ namespace NzbDrone.Core.Test.IndexerTests.AvistazTests torrentInfo.InfoUrl.Should().Be("https://avistaz.to/torrent/187240-japan-sinks-people-of-hope-2021-s01e05-720p-nf-web-dl-ddp20-x264-seikel"); torrentInfo.CommentUrl.Should().BeNullOrEmpty(); torrentInfo.Indexer.Should().Be(Subject.Definition.Name); - torrentInfo.PublishDate.Should().Be(DateTime.Parse("2021-11-14 21:26:21")); + torrentInfo.PublishDate.Should().Be(DateTime.Parse("2021-11-14 22:26:21")); torrentInfo.Size.Should().Be(935127615); torrentInfo.InfoHash.Should().Be("a879261d4e6e792402f92401141a21de70d51bf2"); torrentInfo.MagnetUrl.Should().Be(null); diff --git a/src/NzbDrone.Core.Test/IndexerTests/AvistazTests/ExoticazFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/AvistazTests/ExoticazFixture.cs index fe4ada593..4c4f9f38e 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/AvistazTests/ExoticazFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/AvistazTests/ExoticazFixture.cs @@ -51,7 +51,7 @@ namespace NzbDrone.Core.Test.IndexerTests.AvistazTests torrentInfo.InfoUrl.Should().Be("https://exoticaz.to/torrent/64040-ssis-419-my-first-experience-is-yua-mikami-from-the-day-i-lost-my-virginity-i-was-devoted-to-sex"); torrentInfo.CommentUrl.Should().BeNullOrEmpty(); torrentInfo.Indexer.Should().Be(Subject.Definition.Name); - torrentInfo.PublishDate.Should().Be(DateTime.Parse("2022-06-11 09:04:50")); + torrentInfo.PublishDate.Should().Be(DateTime.Parse("2022-06-11 10:04:50")); torrentInfo.Size.Should().Be(7085405541); torrentInfo.InfoHash.Should().Be("asdjfiasdf54asd7f4a2sdf544asdf"); torrentInfo.MagnetUrl.Should().Be(null); diff --git a/src/NzbDrone.Core.Test/IndexerTests/AvistazTests/PrivateHDFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/AvistazTests/PrivateHDFixture.cs index f0531e9ec..e841659fd 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/AvistazTests/PrivateHDFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/AvistazTests/PrivateHDFixture.cs @@ -51,7 +51,7 @@ namespace NzbDrone.Core.Test.IndexerTests.AvistazTests torrentInfo.InfoUrl.Should().Be("https://privatehd.to/torrent/78506-godzilla-2014-2160p-uhd-bluray-remux-hdr-hevc-atmos-triton"); torrentInfo.CommentUrl.Should().BeNullOrEmpty(); torrentInfo.Indexer.Should().Be(Subject.Definition.Name); - torrentInfo.PublishDate.Should().Be(DateTime.Parse("2021-03-21 04:24:49")); + torrentInfo.PublishDate.Should().Be(DateTime.Parse("2021-03-21 05:24:49")); torrentInfo.Size.Should().Be(69914591044); torrentInfo.InfoHash.Should().Be("a879261d4e6e792402f92401141a21de70d51bf2"); torrentInfo.MagnetUrl.Should().Be(null); From 015db4a916865447674fdf356ba9c56cf5361b9c Mon Sep 17 00:00:00 2001 From: Servarr <32001786+ServarrAdmin@users.noreply.github.com> Date: Fri, 7 Mar 2025 03:38:29 -0500 Subject: [PATCH 17/59] Translations update from Servarr Weblate (#2351) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Multiple Translations updated by Weblate ignore-downstream Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fi/ Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ko/ Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_CN/ Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_Hans/ Translation: Servarr/Prowlarr Co-authored-by: Weblate Co-authored-by: Fixer Co-authored-by: Oskari Lavinto Co-authored-by: Weblate Co-authored-by: wangdj1314 Co-authored-by: 葛磊磊 --- src/NzbDrone.Core/Localization/Core/fi.json | 8 ++++---- src/NzbDrone.Core/Localization/Core/ko.json | 4 +++- src/NzbDrone.Core/Localization/Core/zh_CN.json | 3 ++- src/NzbDrone.Core/Localization/Core/zh_Hans.json | 3 ++- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index 27730aeee..2db696a8a 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -312,7 +312,7 @@ "FullSync": "Täysi synkronointi", "SyncLevelFull": "Täysi synkronointi: Pitää sovelluksen hakupalvelut täysin synkronoituna. Hakupalveluihin {appName}issa tehdyt muutokset synkronoidaan etäsovelluksen kanssa ja kaikki etäsovelluksessa tehdyt muutokset korvataan seuraavan synkronoinnin yhteydessä.", "EnableIndexer": "Ota hakupalvelu käyttöön", - "FilterPlaceHolder": "Suodata hakupalveluita", + "FilterPlaceHolder": "Suodata palveluita", "IndexerHealthCheckNoIndexers": "Yhtään hakupalvelua ei ole käytössä, eikä {appName} tämän vuoksi löydä tuloksia.", "IndexerObsoleteCheckMessage": "Hakupalvelut ovat poistuneet tai ne ovat muuttuneet: {0}. Poista tai lisää ne {appName}iin uudelleen.", "IndexerProxy": "Tiedonhaun välityspalvelin", @@ -507,7 +507,7 @@ "AddDownloadClientImplementation": "Lisätään latauspalvelua – {implementationName}", "AddIndexerImplementation": "Lisätään hakupalvelua – {implementationName}", "OnGrabHelpText": "Kun julkaisu kaapataan", - "ManageDownloadClients": "Hallitse latauspalveluita", + "ManageDownloadClients": "Hallitse palveluita", "NoDownloadClientsFound": "Latauspalveluita ei löytynyt", "CountDownloadClientsSelected": "{count} latauspalvelu(a) on valittu", "EditSelectedDownloadClients": "Muokkaa valittuja latauspalveluita", @@ -519,7 +519,7 @@ "ApplyChanges": "Toteuta muutokset", "EditSelectedIndexers": "Muokkaa valittuja sisältölähteitä", "NoHistoryFound": "Historiaa ei löytynyt", - "NoIndexersFound": "Hakupalveluita ei löytynyt", + "NoIndexersFound": "Palveluita ei löytynyt", "StopSelecting": "Lopeta valitseminen", "EditConnectionImplementation": "Muokataan ilmoituspalvelua – {implementationName}", "AddConnectionImplementation": "Lisätään ilmoituspavelua – {implementationName}", @@ -556,7 +556,7 @@ "Implementation": "Toteutus", "IndexerCategories": "Hakupalvelukategoriat", "IndexerStatus": "Hakupalvelun tila", - "ManageApplications": "Sovellusten hallinta", + "ManageApplications": "Hallitse sovelluksia", "NewznabUrl": "Newznab URL", "PackSeedTime": "Paketin jakoaika", "PackSeedTimeHelpText": "Aika, joka koostepaketin (kuten sarjan tuotantokauden tai esittäjän diskografian) sisältävää torrentia tulee jakaa. Käytä sovelluksen oletusta jättämällä tyhjäksi.", diff --git a/src/NzbDrone.Core/Localization/Core/ko.json b/src/NzbDrone.Core/Localization/Core/ko.json index bb90922eb..17cd81637 100644 --- a/src/NzbDrone.Core/Localization/Core/ko.json +++ b/src/NzbDrone.Core/Localization/Core/ko.json @@ -421,5 +421,7 @@ "UserAgentProvidedByTheAppThatCalledTheAPI": "API를 호출한 앱에서 제공하는 사용자 에이전트", "days": "일", "minutes": "분", - "Author": "저작자" + "Author": "저작자", + "Categories": "카테고리", + "SeedRatio": "종자 비율" } diff --git a/src/NzbDrone.Core/Localization/Core/zh_CN.json b/src/NzbDrone.Core/Localization/Core/zh_CN.json index 830cdbda6..41f815655 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_CN.json +++ b/src/NzbDrone.Core/Localization/Core/zh_CN.json @@ -753,5 +753,6 @@ "IndexerHDBitsSettingsUsernameHelpText": "网站用户名", "IndexerPassThePopcornSettingsFreeleechOnlyHelpText": "只搜索免费发布", "IndexerFileListSettingsFreeleechOnlyHelpText": "只搜索免费发布", - "IndexerFileListSettingsUsernameHelpText": "网站用户名" + "IndexerFileListSettingsUsernameHelpText": "网站用户名", + "IndexerBeyondHDSettingsRefundOnlyHelpText": "Search refund only" } diff --git a/src/NzbDrone.Core/Localization/Core/zh_Hans.json b/src/NzbDrone.Core/Localization/Core/zh_Hans.json index 1617e57fb..54e88a350 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_Hans.json +++ b/src/NzbDrone.Core/Localization/Core/zh_Hans.json @@ -2,5 +2,6 @@ "About": "关于", "Add": "添加", "Analytics": "分析", - "Username": "用户名" + "Username": "用户名", + "AcceptConfirmationModal": "中文" } From 32634540412a2efcd6092a042ff0a59319fc27cc Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 9 Mar 2025 11:50:31 +0200 Subject: [PATCH 18/59] Bump version to 1.32.2 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 7480d2763..5af617e05 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '1.32.1' + majorVersion: '1.32.2' minorVersion: $[counter('minorVersion', 1)] prowlarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(prowlarrVersion)' From 2c1b4647158ea964d90be1083c3130ce21b512b0 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 8 Mar 2025 22:32:52 +0200 Subject: [PATCH 19/59] New: Recommend against using uTorrent (cherry picked from commit 6d8c3f15b343a24fc31a212463af8ed2b5792508) --- src/NzbDrone.Core/Download/Clients/Aria2/Aria2.cs | 4 +++- .../Download/Clients/Blackhole/TorrentBlackhole.cs | 4 +++- .../Download/Clients/Blackhole/UsenetBlackhole.cs | 4 +++- src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs | 4 +++- .../Clients/DownloadStation/TorrentDownloadStation.cs | 4 +++- .../Clients/DownloadStation/UsenetDownloadStation.cs | 4 +++- src/NzbDrone.Core/Download/Clients/Flood/Flood.cs | 4 +++- .../Clients/FreeboxDownload/TorrentFreeboxDownload.cs | 4 +++- src/NzbDrone.Core/Download/Clients/Hadouken/Hadouken.cs | 4 +++- src/NzbDrone.Core/Download/Clients/NzbVortex/NzbVortex.cs | 4 +++- src/NzbDrone.Core/Download/Clients/Nzbget/Nzbget.cs | 6 +++--- src/NzbDrone.Core/Download/Clients/Pneumatic/Pneumatic.cs | 4 +++- .../Download/Clients/QBittorrent/QBittorrent.cs | 4 +++- src/NzbDrone.Core/Download/Clients/Sabnzbd/Sabnzbd.cs | 4 +++- .../Download/Clients/Transmission/Transmission.cs | 4 +++- .../Download/Clients/Transmission/TransmissionBase.cs | 4 +++- src/NzbDrone.Core/Download/Clients/Vuze/Vuze.cs | 4 +++- src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs | 4 +++- src/NzbDrone.Core/Download/Clients/uTorrent/UTorrent.cs | 8 +++++++- src/NzbDrone.Core/Download/DownloadClientBase.cs | 4 ++++ src/NzbDrone.Core/Download/TorrentClientBase.cs | 4 +++- src/NzbDrone.Core/Download/UsenetClientBase.cs | 4 +++- src/NzbDrone.Core/Localization/Core/en.json | 1 + 23 files changed, 72 insertions(+), 23 deletions(-) diff --git a/src/NzbDrone.Core/Download/Clients/Aria2/Aria2.cs b/src/NzbDrone.Core/Download/Clients/Aria2/Aria2.cs index ae076c14b..3085dbf63 100644 --- a/src/NzbDrone.Core/Download/Clients/Aria2/Aria2.cs +++ b/src/NzbDrone.Core/Download/Clients/Aria2/Aria2.cs @@ -7,6 +7,7 @@ using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; using NzbDrone.Core.Configuration; using NzbDrone.Core.Indexers; +using NzbDrone.Core.Localization; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Validation; @@ -25,8 +26,9 @@ namespace NzbDrone.Core.Download.Clients.Aria2 ISeedConfigProvider seedConfigProvider, IConfigService configService, IDiskProvider diskProvider, + ILocalizationService localizationService, Logger logger) - : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, logger) + : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, localizationService, logger) { _proxy = proxy; } diff --git a/src/NzbDrone.Core/Download/Clients/Blackhole/TorrentBlackhole.cs b/src/NzbDrone.Core/Download/Clients/Blackhole/TorrentBlackhole.cs index f8fd44e97..9e22a7460 100644 --- a/src/NzbDrone.Core/Download/Clients/Blackhole/TorrentBlackhole.cs +++ b/src/NzbDrone.Core/Download/Clients/Blackhole/TorrentBlackhole.cs @@ -8,6 +8,7 @@ using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; using NzbDrone.Core.Configuration; using NzbDrone.Core.Indexers; +using NzbDrone.Core.Localization; using NzbDrone.Core.Parser.Model; namespace NzbDrone.Core.Download.Clients.Blackhole @@ -20,8 +21,9 @@ namespace NzbDrone.Core.Download.Clients.Blackhole ISeedConfigProvider seedConfigProvider, IConfigService configService, IDiskProvider diskProvider, + ILocalizationService localizationService, Logger logger) - : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, logger) + : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, localizationService, logger) { } diff --git a/src/NzbDrone.Core/Download/Clients/Blackhole/UsenetBlackhole.cs b/src/NzbDrone.Core/Download/Clients/Blackhole/UsenetBlackhole.cs index 0f0364e61..0b64150ee 100644 --- a/src/NzbDrone.Core/Download/Clients/Blackhole/UsenetBlackhole.cs +++ b/src/NzbDrone.Core/Download/Clients/Blackhole/UsenetBlackhole.cs @@ -7,6 +7,7 @@ using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; using NzbDrone.Common.Http; using NzbDrone.Core.Configuration; +using NzbDrone.Core.Localization; using NzbDrone.Core.Parser.Model; namespace NzbDrone.Core.Download.Clients.Blackhole @@ -16,8 +17,9 @@ namespace NzbDrone.Core.Download.Clients.Blackhole public UsenetBlackhole(IHttpClient httpClient, IConfigService configService, IDiskProvider diskProvider, + ILocalizationService localizationService, Logger logger) - : base(httpClient, configService, diskProvider, logger) + : base(httpClient, configService, diskProvider, localizationService, logger) { } diff --git a/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs b/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs index ca63ba0e7..90bd6ba1f 100644 --- a/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs +++ b/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs @@ -9,6 +9,7 @@ using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; using NzbDrone.Core.Configuration; using NzbDrone.Core.Indexers; +using NzbDrone.Core.Localization; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Validation; @@ -23,8 +24,9 @@ namespace NzbDrone.Core.Download.Clients.Deluge ISeedConfigProvider seedConfigProvider, IConfigService configService, IDiskProvider diskProvider, + ILocalizationService localizationService, Logger logger) - : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, logger) + : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, localizationService, logger) { _proxy = proxy; } diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs index 482e86e30..97afe9480 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs @@ -10,6 +10,7 @@ using NzbDrone.Common.Extensions; using NzbDrone.Core.Configuration; using NzbDrone.Core.Download.Clients.DownloadStation.Proxies; using NzbDrone.Core.Indexers; +using NzbDrone.Core.Localization; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; @@ -33,8 +34,9 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation ISeedConfigProvider seedConfigProvider, IConfigService configService, IDiskProvider diskProvider, + ILocalizationService localizationService, Logger logger) - : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, logger) + : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, localizationService, logger) { _dsInfoProxy = dsInfoProxy; _dsTaskProxySelector = dsTaskProxySelector; diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/UsenetDownloadStation.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/UsenetDownloadStation.cs index 4661c6518..e78f5f5d2 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/UsenetDownloadStation.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/UsenetDownloadStation.cs @@ -9,6 +9,7 @@ using NzbDrone.Common.Extensions; using NzbDrone.Common.Http; using NzbDrone.Core.Configuration; using NzbDrone.Core.Download.Clients.DownloadStation.Proxies; +using NzbDrone.Core.Localization; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; @@ -31,8 +32,9 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation IHttpClient httpClient, IConfigService configService, IDiskProvider diskProvider, + ILocalizationService localizationService, Logger logger) - : base(httpClient, configService, diskProvider, logger) + : base(httpClient, configService, diskProvider, localizationService, logger) { _dsInfoProxy = dsInfoProxy; _dsTaskProxySelector = dsTaskProxySelector; diff --git a/src/NzbDrone.Core/Download/Clients/Flood/Flood.cs b/src/NzbDrone.Core/Download/Clients/Flood/Flood.cs index 845b4fa1c..5d39d7b5f 100644 --- a/src/NzbDrone.Core/Download/Clients/Flood/Flood.cs +++ b/src/NzbDrone.Core/Download/Clients/Flood/Flood.cs @@ -8,6 +8,7 @@ using NzbDrone.Common.Extensions; using NzbDrone.Core.Configuration; using NzbDrone.Core.Download.Clients.Flood.Models; using NzbDrone.Core.Indexers; +using NzbDrone.Core.Localization; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.ThingiProvider; @@ -22,8 +23,9 @@ namespace NzbDrone.Core.Download.Clients.Flood ISeedConfigProvider seedConfigProvider, IConfigService configService, IDiskProvider diskProvider, + ILocalizationService localizationService, Logger logger) - : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, logger) + : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, localizationService, logger) { _proxy = proxy; } diff --git a/src/NzbDrone.Core/Download/Clients/FreeboxDownload/TorrentFreeboxDownload.cs b/src/NzbDrone.Core/Download/Clients/FreeboxDownload/TorrentFreeboxDownload.cs index cec808592..00e7e06b4 100644 --- a/src/NzbDrone.Core/Download/Clients/FreeboxDownload/TorrentFreeboxDownload.cs +++ b/src/NzbDrone.Core/Download/Clients/FreeboxDownload/TorrentFreeboxDownload.cs @@ -6,6 +6,7 @@ using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; using NzbDrone.Core.Configuration; using NzbDrone.Core.Indexers; +using NzbDrone.Core.Localization; using NzbDrone.Core.Parser.Model; namespace NzbDrone.Core.Download.Clients.FreeboxDownload @@ -19,8 +20,9 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload ISeedConfigProvider seedConfigProvider, IConfigService configService, IDiskProvider diskProvider, + ILocalizationService localizationService, Logger logger) - : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, logger) + : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, localizationService, logger) { _proxy = proxy; } diff --git a/src/NzbDrone.Core/Download/Clients/Hadouken/Hadouken.cs b/src/NzbDrone.Core/Download/Clients/Hadouken/Hadouken.cs index b5aa1eb06..560c40eb3 100644 --- a/src/NzbDrone.Core/Download/Clients/Hadouken/Hadouken.cs +++ b/src/NzbDrone.Core/Download/Clients/Hadouken/Hadouken.cs @@ -6,6 +6,7 @@ using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; using NzbDrone.Core.Configuration; using NzbDrone.Core.Indexers; +using NzbDrone.Core.Localization; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Validation; @@ -20,8 +21,9 @@ namespace NzbDrone.Core.Download.Clients.Hadouken ISeedConfigProvider seedConfigProvider, IConfigService configService, IDiskProvider diskProvider, + ILocalizationService localizationService, Logger logger) - : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, logger) + : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, localizationService, logger) { _proxy = proxy; } diff --git a/src/NzbDrone.Core/Download/Clients/NzbVortex/NzbVortex.cs b/src/NzbDrone.Core/Download/Clients/NzbVortex/NzbVortex.cs index e1088780d..a87460d71 100644 --- a/src/NzbDrone.Core/Download/Clients/NzbVortex/NzbVortex.cs +++ b/src/NzbDrone.Core/Download/Clients/NzbVortex/NzbVortex.cs @@ -7,6 +7,7 @@ using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; using NzbDrone.Common.Http; using NzbDrone.Core.Configuration; +using NzbDrone.Core.Localization; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Validation; @@ -20,8 +21,9 @@ namespace NzbDrone.Core.Download.Clients.NzbVortex IHttpClient httpClient, IConfigService configService, IDiskProvider diskProvider, + ILocalizationService localizationService, Logger logger) - : base(httpClient, configService, diskProvider, logger) + : base(httpClient, configService, diskProvider, localizationService, logger) { _proxy = proxy; } diff --git a/src/NzbDrone.Core/Download/Clients/Nzbget/Nzbget.cs b/src/NzbDrone.Core/Download/Clients/Nzbget/Nzbget.cs index b286bf922..49ada68e6 100644 --- a/src/NzbDrone.Core/Download/Clients/Nzbget/Nzbget.cs +++ b/src/NzbDrone.Core/Download/Clients/Nzbget/Nzbget.cs @@ -10,6 +10,7 @@ using NzbDrone.Common.Extensions; using NzbDrone.Common.Http; using NzbDrone.Core.Configuration; using NzbDrone.Core.Exceptions; +using NzbDrone.Core.Localization; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Validation; @@ -18,15 +19,14 @@ namespace NzbDrone.Core.Download.Clients.Nzbget public class Nzbget : UsenetClientBase { private readonly INzbgetProxy _proxy; - private readonly string[] _successStatus = { "SUCCESS", "NONE" }; - private readonly string[] _deleteFailedStatus = { "HEALTH", "DUPE", "SCAN", "COPY", "BAD" }; public Nzbget(INzbgetProxy proxy, IHttpClient httpClient, IConfigService configService, IDiskProvider diskProvider, + ILocalizationService localizationService, Logger logger) - : base(httpClient, configService, diskProvider, logger) + : base(httpClient, configService, diskProvider, localizationService, logger) { _proxy = proxy; } diff --git a/src/NzbDrone.Core/Download/Clients/Pneumatic/Pneumatic.cs b/src/NzbDrone.Core/Download/Clients/Pneumatic/Pneumatic.cs index a0b1e85fd..99f80ab22 100644 --- a/src/NzbDrone.Core/Download/Clients/Pneumatic/Pneumatic.cs +++ b/src/NzbDrone.Core/Download/Clients/Pneumatic/Pneumatic.cs @@ -8,6 +8,7 @@ using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; using NzbDrone.Core.Configuration; using NzbDrone.Core.Indexers; +using NzbDrone.Core.Localization; using NzbDrone.Core.Parser; using NzbDrone.Core.Parser.Model; @@ -17,8 +18,9 @@ namespace NzbDrone.Core.Download.Clients.Pneumatic { public Pneumatic(IConfigService configService, IDiskProvider diskProvider, + ILocalizationService localizationService, Logger logger) - : base(configService, diskProvider, logger) + : base(configService, diskProvider, localizationService, logger) { } diff --git a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs index 6555ce6cc..3d1863784 100644 --- a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs +++ b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs @@ -8,6 +8,7 @@ using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; using NzbDrone.Core.Configuration; using NzbDrone.Core.Indexers; +using NzbDrone.Core.Localization; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Validation; @@ -30,8 +31,9 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent IConfigService configService, IDiskProvider diskProvider, ICacheManager cacheManager, + ILocalizationService localizationService, Logger logger) - : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, logger) + : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, localizationService, logger) { _proxySelector = proxySelector; diff --git a/src/NzbDrone.Core/Download/Clients/Sabnzbd/Sabnzbd.cs b/src/NzbDrone.Core/Download/Clients/Sabnzbd/Sabnzbd.cs index 584e392b2..246262527 100644 --- a/src/NzbDrone.Core/Download/Clients/Sabnzbd/Sabnzbd.cs +++ b/src/NzbDrone.Core/Download/Clients/Sabnzbd/Sabnzbd.cs @@ -9,6 +9,7 @@ using NzbDrone.Common.Extensions; using NzbDrone.Common.Http; using NzbDrone.Core.Configuration; using NzbDrone.Core.Exceptions; +using NzbDrone.Core.Localization; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Validation; @@ -22,8 +23,9 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd IHttpClient httpClient, IConfigService configService, IDiskProvider diskProvider, + ILocalizationService localizationService, Logger logger) - : base(httpClient, configService, diskProvider, logger) + : base(httpClient, configService, diskProvider, localizationService, logger) { _proxy = proxy; } diff --git a/src/NzbDrone.Core/Download/Clients/Transmission/Transmission.cs b/src/NzbDrone.Core/Download/Clients/Transmission/Transmission.cs index c62a1f6ff..ad14de894 100644 --- a/src/NzbDrone.Core/Download/Clients/Transmission/Transmission.cs +++ b/src/NzbDrone.Core/Download/Clients/Transmission/Transmission.cs @@ -5,6 +5,7 @@ using NLog; using NzbDrone.Common.Disk; using NzbDrone.Core.Configuration; using NzbDrone.Core.Indexers; +using NzbDrone.Core.Localization; namespace NzbDrone.Core.Download.Clients.Transmission { @@ -15,8 +16,9 @@ namespace NzbDrone.Core.Download.Clients.Transmission ISeedConfigProvider seedConfigProvider, IConfigService configService, IDiskProvider diskProvider, + ILocalizationService localizationService, Logger logger) - : base(proxy, torrentFileInfoReader, seedConfigProvider, configService, diskProvider, logger) + : base(proxy, torrentFileInfoReader, seedConfigProvider, configService, diskProvider, localizationService, logger) { } diff --git a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionBase.cs b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionBase.cs index f5cf1fed9..977e3bfee 100644 --- a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionBase.cs +++ b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionBase.cs @@ -6,6 +6,7 @@ using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; using NzbDrone.Core.Configuration; using NzbDrone.Core.Indexers; +using NzbDrone.Core.Localization; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Validation; @@ -20,8 +21,9 @@ namespace NzbDrone.Core.Download.Clients.Transmission ISeedConfigProvider seedConfigProvider, IConfigService configService, IDiskProvider diskProvider, + ILocalizationService localizationService, Logger logger) - : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, logger) + : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, localizationService, logger) { _proxy = proxy; } diff --git a/src/NzbDrone.Core/Download/Clients/Vuze/Vuze.cs b/src/NzbDrone.Core/Download/Clients/Vuze/Vuze.cs index 79f5df0e4..3b87962bb 100644 --- a/src/NzbDrone.Core/Download/Clients/Vuze/Vuze.cs +++ b/src/NzbDrone.Core/Download/Clients/Vuze/Vuze.cs @@ -4,6 +4,7 @@ using NzbDrone.Common.Disk; using NzbDrone.Core.Configuration; using NzbDrone.Core.Download.Clients.Transmission; using NzbDrone.Core.Indexers; +using NzbDrone.Core.Localization; namespace NzbDrone.Core.Download.Clients.Vuze { @@ -16,8 +17,9 @@ namespace NzbDrone.Core.Download.Clients.Vuze ISeedConfigProvider seedConfigProvider, IConfigService configService, IDiskProvider diskProvider, + ILocalizationService localizationService, Logger logger) - : base(proxy, torrentFileInfoReader, seedConfigProvider, configService, diskProvider, logger) + : base(proxy, torrentFileInfoReader, seedConfigProvider, configService, diskProvider, localizationService, logger) { } diff --git a/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs b/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs index 5218f9ebe..628ebdf52 100644 --- a/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs +++ b/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs @@ -10,6 +10,7 @@ using NzbDrone.Core.Configuration; using NzbDrone.Core.Download.Clients.rTorrent; using NzbDrone.Core.Exceptions; using NzbDrone.Core.Indexers; +using NzbDrone.Core.Localization; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; @@ -27,8 +28,9 @@ namespace NzbDrone.Core.Download.Clients.RTorrent IConfigService configService, IDiskProvider diskProvider, IRTorrentDirectoryValidator rTorrentDirectoryValidator, + ILocalizationService localizationService, Logger logger) - : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, logger) + : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, localizationService, logger) { _proxy = proxy; _rTorrentDirectoryValidator = rTorrentDirectoryValidator; diff --git a/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrent.cs b/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrent.cs index ef12042fb..98ad41eec 100644 --- a/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrent.cs +++ b/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrent.cs @@ -7,7 +7,9 @@ using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; using NzbDrone.Core.Configuration; using NzbDrone.Core.Indexers; +using NzbDrone.Core.Localization; using NzbDrone.Core.Parser.Model; +using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Download.Clients.UTorrent @@ -21,8 +23,9 @@ namespace NzbDrone.Core.Download.Clients.UTorrent ISeedConfigProvider seedConfigProvider, IConfigService configService, IDiskProvider diskProvider, + ILocalizationService localizationService, Logger logger) - : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, logger) + : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, localizationService, logger) { _proxy = proxy; } @@ -72,6 +75,9 @@ namespace NzbDrone.Core.Download.Clients.UTorrent } public override string Name => "uTorrent"; + + public override ProviderMessage Message => new (_localizationService.GetLocalizedString("DownloadClientUTorrentProviderMessage"), ProviderMessageType.Warning); + public override bool SupportsCategories => true; protected override void Test(List failures) diff --git a/src/NzbDrone.Core/Download/DownloadClientBase.cs b/src/NzbDrone.Core/Download/DownloadClientBase.cs index 7659c32a6..9a7da6fd6 100644 --- a/src/NzbDrone.Core/Download/DownloadClientBase.cs +++ b/src/NzbDrone.Core/Download/DownloadClientBase.cs @@ -8,6 +8,7 @@ using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; using NzbDrone.Core.Configuration; using NzbDrone.Core.Indexers; +using NzbDrone.Core.Localization; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; @@ -19,6 +20,7 @@ namespace NzbDrone.Core.Download { protected readonly IConfigService _configService; protected readonly IDiskProvider _diskProvider; + protected readonly ILocalizationService _localizationService; protected readonly Logger _logger; public abstract string Name { get; } @@ -40,10 +42,12 @@ namespace NzbDrone.Core.Download protected DownloadClientBase(IConfigService configService, IDiskProvider diskProvider, + ILocalizationService localizationService, Logger logger) { _configService = configService; _diskProvider = diskProvider; + _localizationService = localizationService; _logger = logger; } diff --git a/src/NzbDrone.Core/Download/TorrentClientBase.cs b/src/NzbDrone.Core/Download/TorrentClientBase.cs index 322cc206b..217e70a31 100644 --- a/src/NzbDrone.Core/Download/TorrentClientBase.cs +++ b/src/NzbDrone.Core/Download/TorrentClientBase.cs @@ -8,6 +8,7 @@ using NzbDrone.Common.Extensions; using NzbDrone.Core.Configuration; using NzbDrone.Core.Exceptions; using NzbDrone.Core.Indexers; +using NzbDrone.Core.Localization; using NzbDrone.Core.Parser; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.ThingiProvider; @@ -24,8 +25,9 @@ namespace NzbDrone.Core.Download ISeedConfigProvider seedConfigProvider, IConfigService configService, IDiskProvider diskProvider, + ILocalizationService localizationService, Logger logger) - : base(configService, diskProvider, logger) + : base(configService, diskProvider, localizationService, logger) { _torrentFileInfoReader = torrentFileInfoReader; _seedConfigProvider = seedConfigProvider; diff --git a/src/NzbDrone.Core/Download/UsenetClientBase.cs b/src/NzbDrone.Core/Download/UsenetClientBase.cs index ac62359aa..1e85ffbb9 100644 --- a/src/NzbDrone.Core/Download/UsenetClientBase.cs +++ b/src/NzbDrone.Core/Download/UsenetClientBase.cs @@ -5,6 +5,7 @@ using NzbDrone.Common.Disk; using NzbDrone.Common.Http; using NzbDrone.Core.Configuration; using NzbDrone.Core.Indexers; +using NzbDrone.Core.Localization; using NzbDrone.Core.Parser; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.ThingiProvider; @@ -19,8 +20,9 @@ namespace NzbDrone.Core.Download protected UsenetClientBase(IHttpClient httpClient, IConfigService configService, IDiskProvider diskProvider, + ILocalizationService localizationService, Logger logger) - : base(configService, diskProvider, logger) + : base(configService, diskProvider, localizationService, logger) { _httpClient = httpClient; } diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index 5e74f61d0..2565fdf01 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -241,6 +241,7 @@ "DownloadClientStatusSingleClientHealthCheckMessage": "Download clients unavailable due to failures: {downloadClientNames}", "DownloadClientTransmissionSettingsDirectoryHelpText": "Optional location to put downloads in, leave blank to use the default Transmission location", "DownloadClientTransmissionSettingsUrlBaseHelpText": "Adds a prefix to the {clientName} rpc url, eg {url}, defaults to '{defaultUrl}'", + "DownloadClientUTorrentProviderMessage": "uTorrent has a history of including cryptominers, malware and ads, we strongly encourage you to choose a different client.", "DownloadClients": "Download Clients", "DownloadClientsLoadError": "Unable to load download clients", "DownloadClientsSettingsSummary": "Download clients configuration for integration into {appName} UI search", From 10ea6cd753ae2bdb48cd47063d0f388cc61a72b8 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sun, 2 Mar 2025 12:32:44 -0800 Subject: [PATCH 20/59] Improve wrapping of text in sidebar (cherry picked from commit f58dfc5605738ebccdd6adc6f1ca2a7843c086b2) --- frontend/src/Components/Page/Sidebar/PageSidebarItem.css | 5 +---- .../src/Components/Page/Sidebar/PageSidebarItem.css.d.ts | 1 - frontend/src/Components/Page/Sidebar/PageSidebarItem.js | 4 +--- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/frontend/src/Components/Page/Sidebar/PageSidebarItem.css b/frontend/src/Components/Page/Sidebar/PageSidebarItem.css index 5e3e3b52c..409062f97 100644 --- a/frontend/src/Components/Page/Sidebar/PageSidebarItem.css +++ b/frontend/src/Components/Page/Sidebar/PageSidebarItem.css @@ -24,6 +24,7 @@ composes: link; padding: 10px 24px; + padding-left: 35px; } .isActiveLink { @@ -41,10 +42,6 @@ text-align: center; } -.noIcon { - margin-left: 25px; -} - .status { float: right; } diff --git a/frontend/src/Components/Page/Sidebar/PageSidebarItem.css.d.ts b/frontend/src/Components/Page/Sidebar/PageSidebarItem.css.d.ts index 77e23c767..5bf0eb815 100644 --- a/frontend/src/Components/Page/Sidebar/PageSidebarItem.css.d.ts +++ b/frontend/src/Components/Page/Sidebar/PageSidebarItem.css.d.ts @@ -8,7 +8,6 @@ interface CssExports { 'isActiveParentLink': string; 'item': string; 'link': string; - 'noIcon': string; 'status': string; } export const cssExports: CssExports; diff --git a/frontend/src/Components/Page/Sidebar/PageSidebarItem.js b/frontend/src/Components/Page/Sidebar/PageSidebarItem.js index 754071c79..8d0e4e790 100644 --- a/frontend/src/Components/Page/Sidebar/PageSidebarItem.js +++ b/frontend/src/Components/Page/Sidebar/PageSidebarItem.js @@ -63,9 +63,7 @@ class PageSidebarItem extends Component { } - - {typeof title === 'function' ? title() : title} - + {typeof title === 'function' ? title() : title} { !!StatusComponent && From a19b8ea997053e54c9e758b6d8ece06aeaffd9d5 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sun, 2 Mar 2025 12:35:04 -0800 Subject: [PATCH 21/59] New: Truncate button text Fixes #2352 (cherry picked from commit 093ee5b88db0470426f6132e66a5893e5cf89bab) --- frontend/src/Components/Page/Toolbar/PageToolbarButton.css | 3 +++ frontend/src/Components/Page/Toolbar/PageToolbarButton.js | 1 + 2 files changed, 4 insertions(+) diff --git a/frontend/src/Components/Page/Toolbar/PageToolbarButton.css b/frontend/src/Components/Page/Toolbar/PageToolbarButton.css index 0b6918296..e9a1b666d 100644 --- a/frontend/src/Components/Page/Toolbar/PageToolbarButton.css +++ b/frontend/src/Components/Page/Toolbar/PageToolbarButton.css @@ -22,11 +22,14 @@ display: flex; align-items: center; justify-content: center; + overflow: hidden; height: 24px; } .label { padding: 0 3px; + max-width: 100%; + max-height: 100%; color: var(--toolbarLabelColor); font-size: $extraSmallFontSize; line-height: calc($extraSmallFontSize + 1px); diff --git a/frontend/src/Components/Page/Toolbar/PageToolbarButton.js b/frontend/src/Components/Page/Toolbar/PageToolbarButton.js index c93603aa9..675bdfd02 100644 --- a/frontend/src/Components/Page/Toolbar/PageToolbarButton.js +++ b/frontend/src/Components/Page/Toolbar/PageToolbarButton.js @@ -23,6 +23,7 @@ function PageToolbarButton(props) { isDisabled && styles.isDisabled )} isDisabled={isDisabled || isSpinning} + title={label} {...otherProps} > Date: Sun, 16 Mar 2025 11:42:07 +0200 Subject: [PATCH 22/59] Bump version to 1.33.0 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 5af617e05..863747dc0 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '1.32.2' + majorVersion: '1.33.0' minorVersion: $[counter('minorVersion', 1)] prowlarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(prowlarrVersion)' From d20b2cc9c01b9d98f8a6b77fbb617e0e74901cc9 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 16 Mar 2025 12:04:49 +0200 Subject: [PATCH 23/59] Bump NLog and Polly --- src/NzbDrone.Common/Prowlarr.Common.csproj | 6 +++--- src/NzbDrone.Core/Prowlarr.Core.csproj | 4 ++-- src/NzbDrone.Host/Prowlarr.Host.csproj | 2 +- src/NzbDrone.Test.Common/Prowlarr.Test.Common.csproj | 2 +- src/NzbDrone.Update/Prowlarr.Update.csproj | 2 +- src/NzbDrone.Windows/Prowlarr.Windows.csproj | 2 +- src/Prowlarr.Api.V1/Prowlarr.Api.V1.csproj | 2 +- src/Prowlarr.Http/Prowlarr.Http.csproj | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/NzbDrone.Common/Prowlarr.Common.csproj b/src/NzbDrone.Common/Prowlarr.Common.csproj index 359fa8820..b26b024bc 100644 --- a/src/NzbDrone.Common/Prowlarr.Common.csproj +++ b/src/NzbDrone.Common/Prowlarr.Common.csproj @@ -9,9 +9,9 @@ - - - + + + diff --git a/src/NzbDrone.Core/Prowlarr.Core.csproj b/src/NzbDrone.Core/Prowlarr.Core.csproj index 5cfd16a41..4b8138cb4 100644 --- a/src/NzbDrone.Core/Prowlarr.Core.csproj +++ b/src/NzbDrone.Core/Prowlarr.Core.csproj @@ -12,7 +12,7 @@ - + @@ -20,7 +20,7 @@ - + diff --git a/src/NzbDrone.Host/Prowlarr.Host.csproj b/src/NzbDrone.Host/Prowlarr.Host.csproj index 07fed755c..8dd6d8e61 100644 --- a/src/NzbDrone.Host/Prowlarr.Host.csproj +++ b/src/NzbDrone.Host/Prowlarr.Host.csproj @@ -4,7 +4,7 @@ Library - + diff --git a/src/NzbDrone.Test.Common/Prowlarr.Test.Common.csproj b/src/NzbDrone.Test.Common/Prowlarr.Test.Common.csproj index d37b95690..b9ccacd9e 100644 --- a/src/NzbDrone.Test.Common/Prowlarr.Test.Common.csproj +++ b/src/NzbDrone.Test.Common/Prowlarr.Test.Common.csproj @@ -6,7 +6,7 @@ - + diff --git a/src/NzbDrone.Update/Prowlarr.Update.csproj b/src/NzbDrone.Update/Prowlarr.Update.csproj index 5570a6f1b..09b95e2f8 100644 --- a/src/NzbDrone.Update/Prowlarr.Update.csproj +++ b/src/NzbDrone.Update/Prowlarr.Update.csproj @@ -6,7 +6,7 @@ - + diff --git a/src/NzbDrone.Windows/Prowlarr.Windows.csproj b/src/NzbDrone.Windows/Prowlarr.Windows.csproj index f3baa19dc..4a9f864e5 100644 --- a/src/NzbDrone.Windows/Prowlarr.Windows.csproj +++ b/src/NzbDrone.Windows/Prowlarr.Windows.csproj @@ -4,7 +4,7 @@ true - + diff --git a/src/Prowlarr.Api.V1/Prowlarr.Api.V1.csproj b/src/Prowlarr.Api.V1/Prowlarr.Api.V1.csproj index aac0b246f..4371487f2 100644 --- a/src/Prowlarr.Api.V1/Prowlarr.Api.V1.csproj +++ b/src/Prowlarr.Api.V1/Prowlarr.Api.V1.csproj @@ -4,7 +4,7 @@ - + diff --git a/src/Prowlarr.Http/Prowlarr.Http.csproj b/src/Prowlarr.Http/Prowlarr.Http.csproj index 938b722a4..e326e5ed3 100644 --- a/src/Prowlarr.Http/Prowlarr.Http.csproj +++ b/src/Prowlarr.Http/Prowlarr.Http.csproj @@ -5,7 +5,7 @@ - + From b99e8d0d65217e5085db1b0e6a539d6ae6e54af9 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Tue, 11 Mar 2025 08:41:48 -0700 Subject: [PATCH 24/59] Improve logging when login fails due to CryptographicException (cherry picked from commit 1449941471cbb8885e9298317b9a30f2576d7941) --- .../AuthenticationController.cs | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/Prowlarr.Http/Authentication/AuthenticationController.cs b/src/Prowlarr.Http/Authentication/AuthenticationController.cs index 8bfec4318..05b058895 100644 --- a/src/Prowlarr.Http/Authentication/AuthenticationController.cs +++ b/src/Prowlarr.Http/Authentication/AuthenticationController.cs @@ -1,9 +1,14 @@ using System.Collections.Generic; +using System.IO; using System.Security.Claims; +using System.Security.Cryptography; using System.Threading.Tasks; +using System.Xml; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using NLog; +using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.Extensions; using NzbDrone.Core.Authentication; using NzbDrone.Core.Configuration; @@ -16,11 +21,15 @@ namespace Prowlarr.Http.Authentication { private readonly IAuthenticationService _authService; private readonly IConfigFileProvider _configFileProvider; + private readonly IAppFolderInfo _appFolderInfo; + private readonly Logger _logger; - public AuthenticationController(IAuthenticationService authService, IConfigFileProvider configFileProvider) + public AuthenticationController(IAuthenticationService authService, IConfigFileProvider configFileProvider, IAppFolderInfo appFolderInfo, Logger logger) { _authService = authService; _configFileProvider = configFileProvider; + _appFolderInfo = appFolderInfo; + _logger = logger; } [HttpPost("login")] @@ -45,7 +54,23 @@ namespace Prowlarr.Http.Authentication IsPersistent = resource.RememberMe == "on" }; - await HttpContext.SignInAsync(AuthenticationType.Forms.ToString(), new ClaimsPrincipal(new ClaimsIdentity(claims, "Cookies", "user", "identifier")), authProperties); + try + { + await HttpContext.SignInAsync(AuthenticationType.Forms.ToString(), new ClaimsPrincipal(new ClaimsIdentity(claims, "Cookies", "user", "identifier")), authProperties); + } + catch (CryptographicException e) + { + if (e.InnerException is XmlException) + { + _logger.Error(e, "Failed to authenticate user due to corrupt XML. Please remove all XML files from {0} and restart Prowlarr", Path.Combine(_appFolderInfo.AppDataFolder, "asp")); + } + else + { + _logger.Error(e, "Failed to authenticate user. {0}", e.Message); + } + + return Unauthorized(); + } if (returnUrl.IsNullOrWhiteSpace()) { From 5125f256fb8c20b902adafe16530c4792a580d87 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 20 Mar 2025 20:38:13 +0200 Subject: [PATCH 25/59] Fixed: Priority validation for indexers and download clients --- src/Prowlarr.Api.V1/DownloadClient/DownloadClientController.cs | 2 ++ src/Prowlarr.Api.V1/Indexers/IndexerController.cs | 1 + 2 files changed, 3 insertions(+) diff --git a/src/Prowlarr.Api.V1/DownloadClient/DownloadClientController.cs b/src/Prowlarr.Api.V1/DownloadClient/DownloadClientController.cs index dfaf24a9e..347c7e9c6 100644 --- a/src/Prowlarr.Api.V1/DownloadClient/DownloadClientController.cs +++ b/src/Prowlarr.Api.V1/DownloadClient/DownloadClientController.cs @@ -1,3 +1,4 @@ +using FluentValidation; using NzbDrone.Core.Download; using NzbDrone.SignalR; using Prowlarr.Http; @@ -13,6 +14,7 @@ namespace Prowlarr.Api.V1.DownloadClient public DownloadClientController(IBroadcastSignalRMessage signalRBroadcaster, IDownloadClientFactory downloadClientFactory) : base(signalRBroadcaster, downloadClientFactory, "downloadclient", ResourceMapper, BulkResourceMapper) { + SharedValidator.RuleFor(c => c.Priority).InclusiveBetween(1, 50); } } } diff --git a/src/Prowlarr.Api.V1/Indexers/IndexerController.cs b/src/Prowlarr.Api.V1/Indexers/IndexerController.cs index 6f360a574..07955299d 100644 --- a/src/Prowlarr.Api.V1/Indexers/IndexerController.cs +++ b/src/Prowlarr.Api.V1/Indexers/IndexerController.cs @@ -21,6 +21,7 @@ namespace Prowlarr.Api.V1.Indexers .ValidId() .SetValidator(appProfileExistsValidator); + SharedValidator.RuleFor(c => c.Priority).InclusiveBetween(1, 50); SharedValidator.RuleFor(c => c.DownloadClientId).SetValidator(downloadClientExistsValidator); } } From 27fbd7ef7e7ad8876a744a8bf147549549182a6e Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 22 Mar 2025 12:45:10 +0200 Subject: [PATCH 26/59] Fixed: (RuTracker.org) Improve subtitles removal --- src/NzbDrone.Core/Indexers/Definitions/RuTracker.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/RuTracker.cs b/src/NzbDrone.Core/Indexers/Definitions/RuTracker.cs index 79244b6b2..44f6bae38 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/RuTracker.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/RuTracker.cs @@ -30,7 +30,7 @@ namespace NzbDrone.Core.Indexers.Definitions "https://rutracker.net/", "https://rutracker.nl/" }; - public override string Description => "RuTracker.org is a Semi-Private Russian torrent site with a thriving file-sharing community"; + public override string Description => "RuTracker.org is a RUSSIAN Semi-Private site with a thriving file-sharing community"; public override string Language => "ru-RU"; public override Encoding Encoding => Encoding.GetEncoding("windows-1251"); public override IndexerPrivacy Privacy => IndexerPrivacy.SemiPrivate; @@ -144,6 +144,7 @@ namespace NzbDrone.Core.Indexers.Definitions SupportsRawSearch = true }; + // Note: When refreshing the categories use the tracker.php page and NOT the search.php page! caps.Categories.AddCategoryMapping(22, NewznabStandardCategory.Movies, "Наше кино"); caps.Categories.AddCategoryMapping(941, NewznabStandardCategory.Movies, "|- Кино СССР"); caps.Categories.AddCategoryMapping(1666, NewznabStandardCategory.Movies, "|- Детские отечественные фильмы"); @@ -1751,7 +1752,7 @@ namespace NzbDrone.Core.Indexers.Definitions title = Regex.Replace(title, @"(\([\p{IsCyrillic}\W]+)\s/\s(.+?)\)", string.Empty, RegexOptions.Compiled | RegexOptions.IgnoreCase); // Remove VO, MVO and DVO from titles - var vo = new Regex(@".VO\s\(.+?\)"); + var vo = new Regex(@"((?:\dx\s)?(?:[A-Z])?VO\s\(.+?\))"); title = vo.Replace(title, string.Empty); // Remove R5 and (R5) from release names @@ -1759,7 +1760,7 @@ namespace NzbDrone.Core.Indexers.Definitions title = r5.Replace(title, "$1"); // Remove Sub languages from release names - title = Regex.Replace(title, @"(\bSub\b.*$|\b[\+]*Sub[\+]*\b)", string.Empty); + title = Regex.Replace(title, @"(\bSub\b[^+]*\b|\b[\+]*Sub[\+]*\b)", string.Empty); } // language fix: all rutracker releases contains russian track From 73ee69563372dc57ed7eba8bb7c05f338319d1f3 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 22 Mar 2025 20:38:58 +0200 Subject: [PATCH 27/59] New: (BeyondHD) Parsing audio and subtitles languages --- src/NzbDrone.Core/Indexers/Definitions/BeyondHD.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/NzbDrone.Core/Indexers/Definitions/BeyondHD.cs b/src/NzbDrone.Core/Indexers/Definitions/BeyondHD.cs index 33a80f43a..3fc4a3328 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/BeyondHD.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/BeyondHD.cs @@ -304,6 +304,8 @@ namespace NzbDrone.Core.Indexers.Definitions UploadVolumeFactor = 1, MinimumRatio = 1, MinimumSeedTime = 172800, // 120 hours + Languages = row.Audios?.Split(",", StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List(), + Subs = row.Subtitles?.Split(",", StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List(), }; // BHD can return crazy values for tmdb @@ -470,9 +472,13 @@ namespace NzbDrone.Core.Indexers.Definitions [JsonPropertyName("times_completed")] public int Grabs { get; set; } + public int Seeders { get; set; } public int Leechers { get; set; } + public string Audios { get; set; } + public string Subtitles { get; set; } + [JsonPropertyName("created_at")] public string CreatedAt { get; set; } From 758dddd4ad8261a9c948303d4d5811676496e1e6 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 23 Mar 2025 09:45:33 +0200 Subject: [PATCH 28/59] Bump version to 1.33.1 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 863747dc0..b9f35e204 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '1.33.0' + majorVersion: '1.33.1' minorVersion: $[counter('minorVersion', 1)] prowlarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(prowlarrVersion)' From f4f1b38324e9351c8c96cf231333203579694b30 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 25 Mar 2025 12:23:12 +0200 Subject: [PATCH 29/59] New: On Grab notifications for CustomScript --- .../CustomScript/CustomScript.cs | 32 +++++++++++++++---- src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs | 1 + 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/NzbDrone.Core/Notifications/CustomScript/CustomScript.cs b/src/NzbDrone.Core/Notifications/CustomScript/CustomScript.cs index 7ca1dc8fc..04bac39f0 100755 --- a/src/NzbDrone.Core/Notifications/CustomScript/CustomScript.cs +++ b/src/NzbDrone.Core/Notifications/CustomScript/CustomScript.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Collections.Specialized; +using System.Linq; using FluentValidation.Results; using NLog; using NzbDrone.Common.Disk; @@ -38,7 +39,31 @@ namespace NzbDrone.Core.Notifications.CustomScript public override string Link => "https://wiki.servarr.com/prowlarr/settings#connections"; - public override ProviderMessage Message => new ProviderMessage("Testing will execute the script with the EventType set to Test, ensure your script handles this correctly", ProviderMessageType.Warning); + public override ProviderMessage Message => new ("Testing will execute the script with the EventType set to Test, ensure your script handles this correctly", ProviderMessageType.Warning); + + public override void OnGrab(GrabMessage message) + { + var environmentVariables = new StringDictionary(); + + environmentVariables.Add("Prowlarr_EventType", "Grab"); + environmentVariables.Add("Prowlarr_InstanceName", _configFileProvider.InstanceName); + environmentVariables.Add("Prowlarr_ApplicationUrl", _configService.ApplicationUrl); + environmentVariables.Add("Prowlarr_Release_Title", message.Release.Title); + environmentVariables.Add("Prowlarr_Release_Indexer", message.Release.Indexer ?? string.Empty); + environmentVariables.Add("Prowlarr_Release_Size", message.Release.Size.ToString()); + environmentVariables.Add("Prowlarr_Release_Genres", string.Join("|", message.Release.Genres)); + environmentVariables.Add("Prowlarr_Release_Categories", string.Join("|", message.Release.Categories.Select(f => f.Name))); + environmentVariables.Add("Prowlarr_Release_IndexerFlags", string.Join("|", message.Release.IndexerFlags.Select(f => f.Name))); + environmentVariables.Add("Prowlarr_Release_PublishDate", message.Release.PublishDate.ToUniversalTime().ToString("s") + "Z"); + environmentVariables.Add("Prowlarr_Download_Client", message.DownloadClientName ?? string.Empty); + environmentVariables.Add("Prowlarr_Download_Client_Type", message.DownloadClientType ?? string.Empty); + environmentVariables.Add("Prowlarr_Download_Id", message.DownloadId ?? string.Empty); + environmentVariables.Add("Prowlarr_Source", message.Source ?? string.Empty); + environmentVariables.Add("Prowlarr_Host", message.Host ?? string.Empty); + environmentVariables.Add("Prowlarr_Redirect", message.Redirect.ToString()); + + ExecuteScript(environmentVariables); + } public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck) { @@ -130,10 +155,5 @@ namespace NzbDrone.Core.Notifications.CustomScript return processOutput; } - - private bool ValidatePathParent(string possibleParent, string path) - { - return possibleParent.IsParentPath(path); - } } } diff --git a/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs b/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs index 7d8c83d50..6f0788607 100644 --- a/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs +++ b/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs @@ -9,6 +9,7 @@ namespace NzbDrone.Core.Parser.Model { public ReleaseInfo() { + Genres = new List(); IndexerFlags = new HashSet(); Categories = new List(); Languages = new List(); From 5cbacc01eb83531eaf0aa19b0a665b1b6d73eb0c Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 25 Mar 2025 12:50:17 +0200 Subject: [PATCH 30/59] Fixed: Publish dates timezone in history details for grabbed releases --- src/NzbDrone.Core/History/HistoryService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/History/HistoryService.cs b/src/NzbDrone.Core/History/HistoryService.cs index 144258272..e78e5d229 100644 --- a/src/NzbDrone.Core/History/HistoryService.cs +++ b/src/NzbDrone.Core/History/HistoryService.cs @@ -224,7 +224,7 @@ namespace NzbDrone.Core.History if (message.Release.PublishDate != DateTime.MinValue) { - history.Data.Add("PublishedDate", message.Release.PublishDate.ToString("s") + "Z"); + history.Data.Add("PublishedDate", message.Release.PublishDate.ToUniversalTime().ToString("s") + "Z"); } _historyRepository.Insert(history); From 5bc5f0e6b8218b6dd3da2ddb342e8a5e7370a52e Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 25 Mar 2025 12:57:39 +0200 Subject: [PATCH 31/59] New: Categories, genres, indexer flags and publish dates for webhook releases --- .../Notifications/Webhook/WebhookRelease.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookRelease.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookRelease.cs index 295d62986..ad98e5440 100644 --- a/src/NzbDrone.Core/Notifications/Webhook/WebhookRelease.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookRelease.cs @@ -1,3 +1,6 @@ +using System; +using System.Collections.Generic; +using System.Linq; using NzbDrone.Core.Parser.Model; namespace NzbDrone.Core.Notifications.Webhook @@ -13,10 +16,18 @@ namespace NzbDrone.Core.Notifications.Webhook ReleaseTitle = release.Title; Indexer = release.Indexer; Size = release.Size; + Categories = release.Categories.Select(f => f.Name).ToList(); + Genres = release.Genres.ToList(); + IndexerFlags = release.IndexerFlags.Select(f => f.Name).ToHashSet(); + PublishDate = release.PublishDate; } public string ReleaseTitle { get; set; } public string Indexer { get; set; } public long? Size { get; set; } + public List Categories { get; set; } + public List Genres { get; set; } + public HashSet IndexerFlags { get; set; } + public DateTime? PublishDate { get; set; } } } From 023eec0ec062a0e1fac3c45907fdcf1e2222125e Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 25 Mar 2025 13:04:07 +0200 Subject: [PATCH 32/59] Update timezone offset for PrivateHD and CinemaZ --- .../IndexerTests/AvistazTests/PrivateHDFixture.cs | 2 +- .../Indexers/Definitions/Avistaz/AvistazParserBase.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NzbDrone.Core.Test/IndexerTests/AvistazTests/PrivateHDFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/AvistazTests/PrivateHDFixture.cs index e841659fd..f0531e9ec 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/AvistazTests/PrivateHDFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/AvistazTests/PrivateHDFixture.cs @@ -51,7 +51,7 @@ namespace NzbDrone.Core.Test.IndexerTests.AvistazTests torrentInfo.InfoUrl.Should().Be("https://privatehd.to/torrent/78506-godzilla-2014-2160p-uhd-bluray-remux-hdr-hevc-atmos-triton"); torrentInfo.CommentUrl.Should().BeNullOrEmpty(); torrentInfo.Indexer.Should().Be(Subject.Definition.Name); - torrentInfo.PublishDate.Should().Be(DateTime.Parse("2021-03-21 05:24:49")); + torrentInfo.PublishDate.Should().Be(DateTime.Parse("2021-03-21 04:24:49")); torrentInfo.Size.Should().Be(69914591044); torrentInfo.InfoHash.Should().Be("a879261d4e6e792402f92401141a21de70d51bf2"); torrentInfo.MagnetUrl.Should().Be(null); diff --git a/src/NzbDrone.Core/Indexers/Definitions/Avistaz/AvistazParserBase.cs b/src/NzbDrone.Core/Indexers/Definitions/Avistaz/AvistazParserBase.cs index 84e36cf7e..56cc7a3fe 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Avistaz/AvistazParserBase.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Avistaz/AvistazParserBase.cs @@ -14,7 +14,7 @@ namespace NzbDrone.Core.Indexers.Definitions.Avistaz { public class AvistazParserBase : IParseIndexerResponse { - protected virtual string TimezoneOffset => "-05:00"; // Avistaz does not specify a timezone & returns server time + protected virtual string TimezoneOffset => "-04:00"; // Avistaz does not specify a timezone & returns server time private readonly HashSet _hdResolutions = new () { "1080p", "1080i", "720p" }; public Action, DateTime?> CookiesUpdater { get; set; } From 5c5a163151e6c3c69c9466df5792e6c072c3b457 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 28 Mar 2025 13:39:19 +0200 Subject: [PATCH 33/59] Fixed: (AnimeBytes) Allow season searching for ONA --- src/NzbDrone.Core/Indexers/Definitions/AnimeBytes.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/AnimeBytes.cs b/src/NzbDrone.Core/Indexers/Definitions/AnimeBytes.cs index cde688637..f45ff4173 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/AnimeBytes.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/AnimeBytes.cs @@ -232,7 +232,7 @@ namespace NzbDrone.Core.Indexers.Definitions if (queryCats.Any() && searchCriteria is TvSearchCriteria { Season: > 0 }) { // Avoid searching for specials if it's a non-zero season search - queryCats.RemoveAll(cat => cat is "anime[tv_special]" or "anime[ova]" or "anime[ona]" or "anime[dvd_special]" or "anime[bd_special]"); + queryCats.RemoveAll(cat => cat is "anime[tv_special]" or "anime[ova]" or "anime[dvd_special]" or "anime[bd_special]"); } if (queryCats.Any()) From e63ee13d236d2931fa9ded36cb0e3c2e7374a0e4 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 30 Mar 2025 10:30:03 +0300 Subject: [PATCH 34/59] Bump version to 1.33.2 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index b9f35e204..de880295f 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '1.33.1' + majorVersion: '1.33.2' minorVersion: $[counter('minorVersion', 1)] prowlarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(prowlarrVersion)' From 2b16d93095844ad6a867cfa69042f7398c9f442c Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 25 Mar 2025 11:04:28 +0000 Subject: [PATCH 35/59] Multiple Translations updated by Weblate ignore-downstream Co-authored-by: Alex Mills Co-authored-by: Lizandra Candido da Silva Co-authored-by: Oskari Lavinto Co-authored-by: Weblate Co-authored-by: Weblate Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/bg/ Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ca/ Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/cs/ Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/es/ Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fa/ Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fi/ Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ko/ Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/nb_NO/ Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt_BR/ Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/tr/ Translation: Servarr/Prowlarr --- src/NzbDrone.Core/Localization/Core/bg.json | 32 ++++++- src/NzbDrone.Core/Localization/Core/ca.json | 8 +- src/NzbDrone.Core/Localization/Core/cs.json | 7 +- src/NzbDrone.Core/Localization/Core/es.json | 3 +- src/NzbDrone.Core/Localization/Core/fa.json | 11 ++- src/NzbDrone.Core/Localization/Core/fi.json | 8 +- src/NzbDrone.Core/Localization/Core/ko.json | 85 ++++++++++++++++++- .../Localization/Core/nb_NO.json | 3 +- .../Localization/Core/pt_BR.json | 3 +- src/NzbDrone.Core/Localization/Core/tr.json | 3 +- 10 files changed, 150 insertions(+), 13 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/bg.json b/src/NzbDrone.Core/Localization/Core/bg.json index 35327a3a9..913275a68 100644 --- a/src/NzbDrone.Core/Localization/Core/bg.json +++ b/src/NzbDrone.Core/Localization/Core/bg.json @@ -387,5 +387,35 @@ "Label": "Етикет", "Categories": "Категории", "Album": "албум", - "Artist": "изпълнител" + "Artist": "изпълнител", + "AddConnection": "Добави връзка", + "AddConnectionImplementation": "Добави връзка - {implementationName}", + "AddDownloadClientImplementation": "Добави клиент за изтегляне - {implementationName}", + "AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Потвърдете новата парола", + "Default": "Подразбиране", + "Any": "Всеки", + "ApplicationUrlHelpText": "Външният URL адрес на това приложение, включително http(s)://, порт и основно URL", + "Database": "База данни", + "Destination": "Дестинация", + "DownloadClientAriaSettingsDirectoryHelpText": "Незадължително локация за изтеглянията, оставете празно, за да използвате локацията по подразбиране на Aria2", + "DownloadClientDelugeSettingsUrlBaseHelpText": "Добавя префикс към url адреса на deluge json, вижте {url}", + "Directory": "Директория", + "AddIndexerImplementation": "Добави индексатор - {implementationName}", + "AuthenticationRequiredHelpText": "Променете за кои заявки се изисква удостоверяване. Не променяйте, освен ако не разбирате рисковете.", + "AuthenticationRequiredPasswordHelpTextWarning": "Въведете нова парола", + "DownloadClientDownloadStationSettingsDirectoryHelpText": "Незадължителна споделена папка, в която да се поставят изтеглянията, оставете празно, за да използвате местоположението по подразбиране на Download Station", + "DownloadClientFloodSettingsAdditionalTags": "Допълнителни тагове", + "DownloadClientFloodSettingsAdditionalTagsHelpText": "Добавя свойствата на медията като тагове. Напътствията са примери.", + "DownloadClientFloodSettingsTagsHelpText": "Първоначални тагове на изтегляне. За да бъде разпознато едно изтегляне, то трябва да има всички начални тагове. По този начин се избягват конфликти с необвързани с приложение изтегляния.", + "ApplicationURL": "URL адрес на приложението", + "AuthenticationRequired": "Изисква се удостоверяване", + "ApplyChanges": "Прилагане на промените", + "ApiKeyValidationHealthCheckMessage": "Моля, актуализирайте API ключа си така, че да съдържа поне {length} знака. Можете да направите това чрез настройките или конфигурационния файл", + "AppUpdated": "{appName} Актуализиран", + "AppUpdatedVersion": "{appName} е актуализиранa до версия `{version}`, за да получите най-новите промени, ще трябва да презаредите {appName}", + "Donate": "Дарете", + "AddCustomFilter": "Добави персонализиран филтър", + "AuthenticationMethod": "Метод за удостоверяване", + "AuthenticationMethodHelpTextWarning": "Моля, изберете валиден метод за удостоверяване", + "BlackholeFolderHelpText": "Папка, в която {appName} ще съхранява файла {extension}" } diff --git a/src/NzbDrone.Core/Localization/Core/ca.json b/src/NzbDrone.Core/Localization/Core/ca.json index 342411047..3ff222098 100644 --- a/src/NzbDrone.Core/Localization/Core/ca.json +++ b/src/NzbDrone.Core/Localization/Core/ca.json @@ -501,5 +501,11 @@ "WouldYouLikeToRestoreBackup": "Voleu restaurar la còpia de seguretat '{name}'?", "InstallLatest": "Instal·la l'últim", "CurrentlyInstalled": "Instal·lat actualment", - "DownloadClientSettingsAddPaused": "Afegeix pausats" + "DownloadClientSettingsAddPaused": "Afegeix pausats", + "Install": "Instal·la", + "DownloadClientFloodSettingsAdditionalTags": "Etiquetes addicionals", + "DownloadClientFreeboxSettingsApiUrl": "URL de l'API", + "DownloadClientFreeboxSettingsAppId": "Identificador de l'aplicació", + "PreviouslyInstalled": "Instal·lat anteriorment", + "PasswordConfirmation": "Confirmeu la contrasenya" } diff --git a/src/NzbDrone.Core/Localization/Core/cs.json b/src/NzbDrone.Core/Localization/Core/cs.json index 89f8d9fd1..64f4be31d 100644 --- a/src/NzbDrone.Core/Localization/Core/cs.json +++ b/src/NzbDrone.Core/Localization/Core/cs.json @@ -633,5 +633,10 @@ "IndexerAvistazSettingsFreeleechOnlyHelpText": "Hledat pouze freeleech vydání", "InitialFailure": "Úvodní selhání", "IndexerTorrentSyndikatSettingsApiKeyHelpText": "Klíč API stránky", - "SearchTypes": "Hledat typy" + "SearchTypes": "Hledat typy", + "NotificationTriggersHelpText": "Vyber, které události mají vyvolat toto upozornění", + "IndexerSettingsBaseUrl": "Základní URL", + "DownloadClientUTorrentProviderMessage": "uTorrent má historii zahrnování kryptoměnových těžařů, malwaru a reklam, důrazně vám doporučujeme zvolit jiného klienta.", + "IndexerSettingsBaseUrlHelpText": "Vyberte, jakou základní URL bude {appName} používat pro požadavky na web", + "IndexerSettingsPackSeedTimeIndexerHelpText": "Doba, po kterou by měl být balíček (sezóna nebo diskografie) torrentu seedován před zastavením, prázdné pole znamená výchozí nastavení aplikace" } diff --git a/src/NzbDrone.Core/Localization/Core/es.json b/src/NzbDrone.Core/Localization/Core/es.json index 919dd5353..e7981a69e 100644 --- a/src/NzbDrone.Core/Localization/Core/es.json +++ b/src/NzbDrone.Core/Localization/Core/es.json @@ -806,5 +806,6 @@ "InstallMajorVersionUpdateMessageLink": "Por favor revisa [{domain}]({url}) para más información.", "FailedToFetchSettings": "Error al recuperar la configuración", "CurrentlyInstalled": "Actualmente instalado", - "PreviouslyInstalled": "Previamente instalado" + "PreviouslyInstalled": "Previamente instalado", + "DownloadClientUTorrentProviderMessage": "uTorrent tiene un amplio historial de incluir criptomineros, malware y publicidad, por lo que recomendamos encarecidamente que elijas un cliente diferente." } diff --git a/src/NzbDrone.Core/Localization/Core/fa.json b/src/NzbDrone.Core/Localization/Core/fa.json index 2839af8c0..c0f9f6513 100644 --- a/src/NzbDrone.Core/Localization/Core/fa.json +++ b/src/NzbDrone.Core/Localization/Core/fa.json @@ -1,4 +1,13 @@ { "ApiKey": "کلید API", - "NetCore": ".NET" + "NetCore": ".NET", + "Add": "افزودن", + "About": "درباره", + "Actions": "اقدامات", + "Docker": "Docker", + "AddConnection": "افزودن پیوند", + "AddConnectionImplementation": "افزودن پیوند - {implementationName}", + "AddDownloadClientImplementation": "افزودن کلاینت دانلود - {implementationName}", + "Torrents": "تورنت ها", + "Usenet": "Usenet" } diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index 2db696a8a..ab235f518 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -34,7 +34,7 @@ "Fixed": "Korjattu", "FocusSearchBox": "Kohdista hakukenttä", "ForMoreInformationOnTheIndividualDownloadClients": "Saat lisätietoja yksittäisistä latauspalveluista painamalla niiden ohessa olevia lisätietopainikkeita.", - "HideAdvanced": "Piilota lisäasetukset", + "HideAdvanced": "Laajenna asetukset", "History": "Historia", "MIA": "Puuttuu", "New": "Uutta", @@ -161,7 +161,7 @@ "SendAnonymousUsageData": "Lähetä nimettömiä käyttötietoja", "SetTags": "Tunnisteiden määritys", "SettingsEnableColorImpairedMode": "Heikentyneen värinäön tila", - "ShowAdvanced": "Näytä lisäasetukset", + "ShowAdvanced": "Supista asetukset", "ShowSearchHelpText": "Näytä hakupainike osoitettaessa.", "Shutdown": "Sammuta", "Size": "Koko", @@ -715,8 +715,8 @@ "UpdaterLogFiles": "Päivittäjän lokitiedostot", "WouldYouLikeToRestoreBackup": "Haluatko palauttaa varmuuskopion \"{name}\"?", "InstallLatest": "Asenna uusin", - "CurrentlyInstalled": "Nyt asennettu", - "PreviouslyInstalled": "Aiemmin asennettu", + "CurrentlyInstalled": "Käytössä oleva versio", + "PreviouslyInstalled": "Aiemmin käytössä ollut versio", "Mixed": "Sekoitettu", "IndexerSettingsAppsMinimumSeeders": "Jakajien vähimmäismäärä", "FailedToFetchSettings": "Asetusten nouto epäonnistui", diff --git a/src/NzbDrone.Core/Localization/Core/ko.json b/src/NzbDrone.Core/Localization/Core/ko.json index 17cd81637..5a30e0f08 100644 --- a/src/NzbDrone.Core/Localization/Core/ko.json +++ b/src/NzbDrone.Core/Localization/Core/ko.json @@ -423,5 +423,88 @@ "minutes": "분", "Author": "저작자", "Categories": "카테고리", - "SeedRatio": "종자 비율" + "SeedRatio": "종자 비율", + "AuthenticationRequiredHelpText": "필수 인증을 요청하는 변경 사항. 위험을 이해하지 못한다면 변경하지 마세요.", + "DownloadClientFloodSettingsAdditionalTagsHelpText": "미디어의 속성을 태그로 추가합니다. 힌트는 예시입니다.", + "DownloadClientRTorrentSettingsAddStoppedHelpText": "활성화하면 rTorrent에 정지된 상태에서 토런트와 마그넷이 추가됩니다. 마그넷 파일이 손상될 수 있습니다.", + "HealthMessagesInfoBox": "행 끝에 있는 위키 링크(책 아이콘)를 클릭하거나 [로그]({link})를 확인하면 이러한 상태 점검 메시지의 원인에 대한 상세 정보를 찾을 수 있습니다. 이러한 메시지를 해석하는 데 어려움이 있는 경우 아래 링크에서 지원팀에 문의할 수 있습니다.", + "DownloadClientSettingsDestinationHelpText": "다운로드 대상을 수동으로 지정하고 기본값을 사용하려면 비워두세요.", + "DownloadClientSettingsInitialStateHelpText": "{clientName}에 추가된 토런트의 초기 상태", + "IndexerSettingsAdditionalParameters": "매개 변수 추가", + "NoEventsFound": "이벤트가 없음", + "BlackholeFolderHelpText": "{appName}가 {extension} 파일을 저장할 폴더", + "DownloadClientSettingsUrlBaseHelpText": "{clientName} url에 {url}과 같은 접두사를 추가합니다.", + "DownloadClientQbittorrentSettingsContentLayout": "콘텐츠 레이아웃", + "Install": "설치", + "AuthenticationRequiredPasswordConfirmationHelpTextWarning": "새 비밀번호 확인", + "FailedToFetchSettings": "설정을 가져오는데 실패함", + "Default": "기본값", + "Episode": "에피소드", + "AuthenticationMethod": "인증 방법", + "IndexerSettingsSeedRatio": "시드 비율", + "Destination": "대상", + "DownloadClientFreeboxSettingsAppToken": "앱 토큰", + "Logout": "로그아웃", + "DownloadClientFreeboxSettingsApiUrl": "API 주소", + "IndexerHDBitsSettingsCodecs": "코덱", + "WhatsNew": "새로운 소식?", + "DownloadClientFreeboxSettingsPortHelpText": "Freebox 인터페이스에 액세스하는 데 사용되는 포트, 기본값은 '{port}'", + "DownloadClientPneumaticSettingsStrmFolderHelpText": "이 폴더의 .strm 파일은 드론으로 가져옵니다.", + "DownloadClientQbittorrentSettingsInitialStateHelpText": "qBittorrent에 추가된 토렌트의 초기 상태입니다. 강제 토렌트는 시드 제한을 따르지 않는다는 점에 유의하세요.", + "DownloadClientRTorrentSettingsDirectoryHelpText": "다운로드를 넣을 선택 위치, 기본 rTorrent 위치를 사용하려면 비워두세요.", + "DownloadClientSettingsUseSslHelpText": "{clientName}에 연결할 때 보안 연결을 사용", + "DownloadClientTransmissionSettingsUrlBaseHelpText": "{clientName} rpc URL에 접두사를 추가합니다(예: {url}, 기본값은 '{defaultUrl}')", + "InstallMajorVersionUpdateMessageLink": "상세 내용은 [{domain}]({url})을 확인하세요.", + "ApplicationUrlHelpText": "이 애플리케이션의 외부 URL - http(s)://, port 및 URL 기반 포함", + "Theme": "테마", + "ApplicationURL": "애플리케이션 URL", + "Directory": "디렉토리", + "DownloadClientDownloadStationSettingsDirectoryHelpText": "다운로드를 넣을 공유 폴더(선택 사항). 기본 다운로드 스테이션 위치를 사용하려면 비워두세요.", + "DownloadClientFloodSettingsAdditionalTags": "추가 태그", + "DownloadClientFloodSettingsUrlBaseHelpText": "{url}와 같은 Flood API에 접두사를 추가합니다", + "DownloadClientFreeboxSettingsApiUrlHelpText": "API 버전을 사용하여 Freebox API 기본 URL을 정의하세요, 예를 들어 '{url}', 기본값은 '{defaultApiUrl}')", + "DownloadClientFreeboxSettingsAppId": "앱 ID", + "DownloadClientNzbgetSettingsAddPausedHelpText": "이 옵션을 사용하려면 최소한 NzbGet 버전 16.0이 필요합니다", + "DownloadClientPneumaticSettingsNzbFolderHelpText": "이 폴더는 XBMC에서 접근할 수 있어야 합니다.", + "DownloadClientRTorrentSettingsAddStopped": "중지됨 추가", + "Category": "카테고리", + "DownloadClientTransmissionSettingsDirectoryHelpText": "다운로드를 넣을 위치 (선택 사항), 기본 전송 위치를 사용하려면 비워두세요", + "External": "외부", + "IndexerSettingsSeedRatioHelpText": "토렌드가 멈추기 전에 도달해야 하는 비율, 비어 있을 경우 다운로드 클라이언트의 기본값을 사용합니다. 비율은 최소 1.0이어야 하며 인덱서 규칙을 따라야 합니다", + "IndexerSettingsSeedTimeHelpText": "토렌드가 중지되기 전에 시드되어야 하는 시간, 비어 있을 경우 다운로드 클라이언트의 기본값을 사용합니다", + "InvalidUILanguage": "UI가 잘못된 언어로 설정되어 있습니다, 수정하고 설정을 저장하세요", + "AuthenticationRequired": "인증 필요", + "NotificationsTelegramSettingsIncludeAppNameHelpText": "다른 애플리케이션의 알림을 구분하기 위해 메시지 제목 앞에 {appName}를 접두사로 사용 (선택 사항)", + "PackageVersionInfo": "{packageVersion} by {packageAuthor}", + "Duration": "기간", + "Script": "스크립트", + "SelectDownloadClientModalTitle": "{modalTitle} - 다운로드 클라이언트 선택", + "TheLogLevelDefault": "로그 수준의 기본값은 '정보'이며 [일반 설정](/settings/general)에서 변경할 수 있습니다", + "UpdaterLogFiles": "업데이트 도구 로그 파일", + "CountDownloadClientsSelected": "{count}개의 다운로드 클라이언트를 선택함", + "DefaultNameCopiedProfile": "{name} - 복사", + "DownloadClientDelugeSettingsUrlBaseHelpText": "deluge json url에 접두사를 추가합니다. {url}을(를) 참조하세요", + "FailedToFetchUpdates": "업데이트를 가져오는데 실패함", + "ApplyChanges": "변경 사항 적용", + "Started": "시작됨", + "Database": "데이터베이스", + "PasswordConfirmation": "비밀번호 확인", + "TorrentBlackholeSaveMagnetFiles": "마그넷 파일 저장", + "TorrentBlackholeSaveMagnetFilesExtension": "마그넷 파일 확장자 저장", + "TorrentBlackholeSaveMagnetFilesExtensionHelpText": "마그넷 링크에 사용할 확장자, 기본값은 '.magnet'입니다", + "TorrentBlackholeSaveMagnetFilesHelpText": ".torrent 파일을 사용할 수 없는 경우 마그넷 링크를 저장합니다 (다운로드 클라이언트가 파일에 저장된 마그넷을 지원하는 경우에만 유용함)", + "AuthenticationMethodHelpTextWarning": "유효한 인증 방법을 선택해주세요", + "AuthenticationRequiredPasswordHelpTextWarning": "새로운 비밀번호를 입력하세요", + "AuthenticationRequiredUsernameHelpTextWarning": "새로운 사용자이름을 입력하세요", + "AuthenticationRequiredWarning": "인증 없이 원격 액세스를 방지하기 위해 {appName}은(는) 이제 인증을 활성화해야 합니다. 선택적으로 로컬 주소에서 인증을 비활성화할 수 있습니다.", + "CountIndexersSelected": "{count}개의 인덱서를 선택함", + "Label": "라벨", + "More": "더 보기", + "Donate": "기부하기", + "Menu": "메뉴", + "DownloadClientQbittorrentSettingsContentLayoutHelpText": "qBittorrent의 구성된 콘텐츠 레이아웃을 사용할지, 토런트의 원래 레이아웃을 사용할지, 항상 하위 폴더를 생성할지(qBittorrent 4.3.2+)", + "DownloadClientSettingsAddPaused": "일시 중지 추가", + "SecretToken": "비밀 토큰", + "NoDownloadClientsFound": "다운로드 클라이언트를 찾을 수 없음", + "PrioritySettings": "우선 순위: {0}" } diff --git a/src/NzbDrone.Core/Localization/Core/nb_NO.json b/src/NzbDrone.Core/Localization/Core/nb_NO.json index a01858498..12e1c4557 100644 --- a/src/NzbDrone.Core/Localization/Core/nb_NO.json +++ b/src/NzbDrone.Core/Localization/Core/nb_NO.json @@ -160,5 +160,6 @@ "AptUpdater": "Bruk apt til å installere oppdateringen", "Discord": "Discord", "AddCustomFilter": "Legg til eget filter", - "Clone": "Lukk" + "Clone": "Lukk", + "AddDownloadClientImplementation": "Ny Nedlastingsklient - {implementationName}" } diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index 5ba6e6764..43c1f2932 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -806,5 +806,6 @@ "InstallMajorVersionUpdateMessageLink": "Verifique [{domain}]({url}) para obter mais informações.", "FailedToFetchSettings": "Falha ao obter configurações", "CurrentlyInstalled": "Atualmente instalado", - "PreviouslyInstalled": "Instalado anteriormente" + "PreviouslyInstalled": "Instalado anteriormente", + "DownloadClientUTorrentProviderMessage": "O uTorrent tem um histórico de incluir criptomineradores, malware e anúncios, recomendamos que você escolha outro cliente de download." } diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index b9a2525f7..0d4af37ac 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -806,5 +806,6 @@ "IndexerGazelleGamesSettingsApiKeyHelpTextWarning": "Kullanıcı ve Torrent izinlerine sahip olmalısınız", "IndexerGazelleGamesSettingsSearchGroupNamesHelpText": "Grup adlarına göre sürüm ara", "IndexerHealthCheckNoIndexers": "Hiçbir indeksleyici etkinleştirilmedi, {appName} arama sonuçlarını döndürmeyecek", - "QueryType": "Sorgu Türü" + "QueryType": "Sorgu Türü", + "DownloadClientUTorrentProviderMessage": "uTorrent'in kripto para madenciliği, kötü amaçlı yazılım ve reklam içerme geçmişi vardır, bu nedenle farklı bir istemci seçmenizi önemle tavsiye ederiz." } From f6f2a3b00d0c3986f11078deb804e89480f812ff Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 2 Apr 2025 00:10:40 +0300 Subject: [PATCH 36/59] Bump linux agent to ubuntu-22.04 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index de880295f..1242e4eed 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -19,7 +19,7 @@ variables: nodeVersion: '20.X' innoVersion: '6.2.2' windowsImage: 'windows-2022' - linuxImage: 'ubuntu-20.04' + linuxImage: 'ubuntu-22.04' macImage: 'macOS-13' trigger: From 700862635823004f5abce0845931cfa3068b7a46 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 4 Apr 2025 21:33:47 +0300 Subject: [PATCH 37/59] Fixed: (PassThePopcorn) Parse volume factors for neutral leech releases --- .../Definitions/PassThePopcorn/PassThePopcornParser.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/PassThePopcorn/PassThePopcornParser.cs b/src/NzbDrone.Core/Indexers/Definitions/PassThePopcorn/PassThePopcornParser.cs index e08536162..7b6fe586e 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/PassThePopcorn/PassThePopcornParser.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/PassThePopcorn/PassThePopcornParser.cs @@ -59,7 +59,7 @@ namespace NzbDrone.Core.Indexers.Definitions.PassThePopcorn // skip non-freeleech results when freeleech only is set var downloadVolumeFactor = torrent.FreeleechType?.ToUpperInvariant() switch { - "FREELEECH" => 0, + "FREELEECH" or "NEUTRAL LEECH" => 0, "HALF LEECH" => 0.5, _ => 1 }; @@ -91,6 +91,12 @@ namespace NzbDrone.Core.Indexers.Definitions.PassThePopcorn categories.Add(NewznabStandardCategory.TV); } + var uploadVolumeFactor = torrent.FreeleechType?.ToUpperInvariant() switch + { + "NEUTRAL LEECH" => 0, + _ => 1 + }; + torrentInfos.Add(new TorrentInfo { Guid = $"PassThePopcorn-{id}", @@ -108,7 +114,7 @@ namespace NzbDrone.Core.Indexers.Definitions.PassThePopcorn Scene = torrent.Scene, IndexerFlags = flags, DownloadVolumeFactor = downloadVolumeFactor, - UploadVolumeFactor = 1, + UploadVolumeFactor = uploadVolumeFactor, MinimumRatio = 1, MinimumSeedTime = 345600, Genres = result.Tags ?? new List(), From 548dedad5c285a407c4bfe79c2f3e4d2f3496606 Mon Sep 17 00:00:00 2001 From: Weblate Date: Sun, 6 Apr 2025 09:22:41 +0000 Subject: [PATCH 38/59] Multiple Translations updated by Weblate ignore-downstream Co-authored-by: Ste Co-authored-by: Weblate Co-authored-by: Weblate Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ca/ Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/cs/ Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fr/ Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ru/ Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/uk/ Translation: Servarr/Prowlarr --- src/NzbDrone.Core/Localization/Core/ca.json | 7 ++++++- src/NzbDrone.Core/Localization/Core/cs.json | 3 ++- src/NzbDrone.Core/Localization/Core/fr.json | 3 ++- src/NzbDrone.Core/Localization/Core/ru.json | 3 ++- src/NzbDrone.Core/Localization/Core/uk.json | 10 +++++++++- 5 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/ca.json b/src/NzbDrone.Core/Localization/Core/ca.json index 3ff222098..76350e36a 100644 --- a/src/NzbDrone.Core/Localization/Core/ca.json +++ b/src/NzbDrone.Core/Localization/Core/ca.json @@ -507,5 +507,10 @@ "DownloadClientFreeboxSettingsApiUrl": "URL de l'API", "DownloadClientFreeboxSettingsAppId": "Identificador de l'aplicació", "PreviouslyInstalled": "Instal·lat anteriorment", - "PasswordConfirmation": "Confirmeu la contrasenya" + "PasswordConfirmation": "Confirmeu la contrasenya", + "IndexerHDBitsSettingsOriginsHelpText": "Si no s'especifica, s'utilitzen totes les opcions.", + "MinimumSeeders": "Seeders mínims", + "SeedRatio": "Ràtio de la llavor", + "ApplicationSettingsSyncRejectBlocklistedTorrentHashesHelpText": "Si un torrent està bloquejat per un hash, pot ser que no es rebutgi correctament durant el RSS/Search per a alguns indexadors, habilitant això permetrà que es rebutgi després que s'agafi el torrent, però abans que s'enviï al client.", + "SeedTime": "Temps de la llavor" } diff --git a/src/NzbDrone.Core/Localization/Core/cs.json b/src/NzbDrone.Core/Localization/Core/cs.json index 64f4be31d..21975a02e 100644 --- a/src/NzbDrone.Core/Localization/Core/cs.json +++ b/src/NzbDrone.Core/Localization/Core/cs.json @@ -638,5 +638,6 @@ "IndexerSettingsBaseUrl": "Základní URL", "DownloadClientUTorrentProviderMessage": "uTorrent má historii zahrnování kryptoměnových těžařů, malwaru a reklam, důrazně vám doporučujeme zvolit jiného klienta.", "IndexerSettingsBaseUrlHelpText": "Vyberte, jakou základní URL bude {appName} používat pro požadavky na web", - "IndexerSettingsPackSeedTimeIndexerHelpText": "Doba, po kterou by měl být balíček (sezóna nebo diskografie) torrentu seedován před zastavením, prázdné pole znamená výchozí nastavení aplikace" + "IndexerSettingsPackSeedTimeIndexerHelpText": "Doba, po kterou by měl být balíček (sezóna nebo diskografie) torrentu seedován před zastavením, prázdné pole znamená výchozí nastavení aplikace", + "PackSeedTimeHelpText": "Doba, po kterou by měl být balíček (sezóna nebo diskografie) torrentu seedován před zastavením, prázdné pole znamená výchozí nastavení aplikace" } diff --git a/src/NzbDrone.Core/Localization/Core/fr.json b/src/NzbDrone.Core/Localization/Core/fr.json index 34fb107a9..8768f9c50 100644 --- a/src/NzbDrone.Core/Localization/Core/fr.json +++ b/src/NzbDrone.Core/Localization/Core/fr.json @@ -806,5 +806,6 @@ "IndexerSettingsPreferMagnetUrl": "URL de préférence Magnet", "IndexerPassThePopcornSettingsGoldenPopcornOnly": "Popcorn doré uniquement", "IndexerPassThePopcornSettingsGoldenPopcornOnlyHelpText": "Rechercher uniquement les versions Golden Popcorn", - "IndexerAvistazSettingsUsernameHelpTextWarning": "Seuls les membres de rang et supérieur peuvent utiliser l'API sur cet indexeur." + "IndexerAvistazSettingsUsernameHelpTextWarning": "Seuls les membres de rang et supérieur peuvent utiliser l'API sur cet indexeur.", + "DownloadClientUTorrentProviderMessage": "uTorrent a un historique d'inclusion de cryptomineurs, de logiciels malveillants et de publicités. Nous vous recommandons fortement de choisir un autre client." } diff --git a/src/NzbDrone.Core/Localization/Core/ru.json b/src/NzbDrone.Core/Localization/Core/ru.json index d396b076e..f31829160 100644 --- a/src/NzbDrone.Core/Localization/Core/ru.json +++ b/src/NzbDrone.Core/Localization/Core/ru.json @@ -806,5 +806,6 @@ "InstallMajorVersionUpdateMessage": "Это обновление установит новую версию, которая может не поддерживаться вашей системой. Вы уверены, что хотите установить это обновление?", "FailedToFetchSettings": "Не удалось загрузить настройки", "CurrentlyInstalled": "Установлено", - "PreviouslyInstalled": "Ранее установленный" + "PreviouslyInstalled": "Ранее установленный", + "DownloadClientUTorrentProviderMessage": "Мы настоятельно советуем не использовать uTorrent, т.к. он известен как программа-шифровальщик и в целом вредоносное ПО." } diff --git a/src/NzbDrone.Core/Localization/Core/uk.json b/src/NzbDrone.Core/Localization/Core/uk.json index f6390540a..f42bd890b 100644 --- a/src/NzbDrone.Core/Localization/Core/uk.json +++ b/src/NzbDrone.Core/Localization/Core/uk.json @@ -441,5 +441,13 @@ "CurrentlyInstalled": "В даний час встановлено", "Season": "Причина", "Stats": "Статус", - "CountIndexersSelected": "{count} індексер(-и) обрано" + "CountIndexersSelected": "{count} індексер(-и) обрано", + "SeedRatio": "Коефіцієнт роздачі", + "ApplicationSettingsSyncRejectBlocklistedTorrentHashesHelpText": "Якщо торрент заблоковано хешем, він може не бути належним чином відхилений під час RSS/пошуку для деяких індексаторів. Увімкнення цього параметра дозволить відхилити його після захоплення торента, але до його відправки клієнту.", + "MinimumSeeders": "Мінімум сидерів (роздаючих)", + "SeedTime": "Час сидіння", + "Author": "Автор", + "OnHealthRestoredHelpText": "При відновленні стану", + "IndexerHDBitsSettingsOriginsHelpText": "Якщо не вказано, використовуються всі параметри.", + "days": "дні(в)" } From 7cb70716d040e1e5d00c060f05adb416805bae62 Mon Sep 17 00:00:00 2001 From: MrE12345 <78666580+MrE12345@users.noreply.github.com> Date: Sun, 6 Apr 2025 11:43:24 +0200 Subject: [PATCH 39/59] Fixed: (NorBits) Change encoding to UTF8 (#2367) --- src/NzbDrone.Core/Indexers/Definitions/NorBits.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/NorBits.cs b/src/NzbDrone.Core/Indexers/Definitions/NorBits.cs index 990cf3d68..e989a5c6a 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/NorBits.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/NorBits.cs @@ -27,7 +27,7 @@ public class NorBits : TorrentIndexerBase public override string[] IndexerUrls => new[] { "https://norbits.net/" }; public override string Description => "NorBits is a Norwegian Private site for MOVIES / TV / GENERAL"; public override string Language => "nb-NO"; - public override Encoding Encoding => Encoding.GetEncoding("iso-8859-1"); + public override Encoding Encoding => Encoding.UTF8; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); From 07711da4e090887eb6540d77d05bc3d3d9d2bc29 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 6 Apr 2025 15:44:25 +0300 Subject: [PATCH 40/59] Bump version to 1.33.3 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 1242e4eed..78b955e67 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '1.33.2' + majorVersion: '1.33.3' minorVersion: $[counter('minorVersion', 1)] prowlarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(prowlarrVersion)' From de099c6770ae96b12eadd48c1329b05d26568c77 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 7 Apr 2025 15:58:01 +0300 Subject: [PATCH 41/59] Log delete statements only once --- src/NzbDrone.Core/Datastore/BasicRepository.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/Datastore/BasicRepository.cs b/src/NzbDrone.Core/Datastore/BasicRepository.cs index dc76a5a31..796e277b7 100644 --- a/src/NzbDrone.Core/Datastore/BasicRepository.cs +++ b/src/NzbDrone.Core/Datastore/BasicRepository.cs @@ -254,7 +254,7 @@ namespace NzbDrone.Core.Datastore protected void Delete(SqlBuilder builder) { - var sql = builder.AddDeleteTemplate(typeof(TModel)).LogQuery(); + var sql = builder.AddDeleteTemplate(typeof(TModel)); using (var conn = _database.OpenConnection()) { From 8a9518c9c164f0c803b7f7bde6483bf12555f380 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Mon, 31 Mar 2025 19:26:14 -0700 Subject: [PATCH 42/59] Update WikiUrl type in API docs (cherry picked from commit 9bd619ccfe074abe396bbf043a36a5be18a7ba4b) --- src/Prowlarr.Api.V1/Health/HealthResource.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Prowlarr.Api.V1/Health/HealthResource.cs b/src/Prowlarr.Api.V1/Health/HealthResource.cs index 1e2c8ffa5..3f357285d 100644 --- a/src/Prowlarr.Api.V1/Health/HealthResource.cs +++ b/src/Prowlarr.Api.V1/Health/HealthResource.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using System.Linq; -using NzbDrone.Common.Http; using NzbDrone.Core.HealthCheck; using Prowlarr.Http.REST; @@ -11,7 +10,7 @@ namespace Prowlarr.Api.V1.Health public string Source { get; set; } public HealthCheckResult Type { get; set; } public string Message { get; set; } - public HttpUri WikiUrl { get; set; } + public string WikiUrl { get; set; } } public static class HealthResourceMapper @@ -29,7 +28,7 @@ namespace Prowlarr.Api.V1.Health Source = model.Source.Name, Type = model.Type, Message = model.Message, - WikiUrl = model.WikiUrl + WikiUrl = model.WikiUrl.FullUri }; } From 48301055eae8f7efd24dbfdcd1a2b20637f1a506 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Mon, 24 Mar 2025 20:07:15 -0700 Subject: [PATCH 43/59] Fixed: Set output encoding to UTF-8 when running external processes (cherry picked from commit f8e57b09856278a6d0c65f18704e96a33459687d) --- src/NzbDrone.Common/Processes/ProcessProvider.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/NzbDrone.Common/Processes/ProcessProvider.cs b/src/NzbDrone.Common/Processes/ProcessProvider.cs index 4947e7080..c68207a09 100644 --- a/src/NzbDrone.Common/Processes/ProcessProvider.cs +++ b/src/NzbDrone.Common/Processes/ProcessProvider.cs @@ -6,6 +6,7 @@ using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Linq; +using System.Text; using NLog; using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.Model; @@ -117,7 +118,9 @@ namespace NzbDrone.Common.Processes UseShellExecute = false, RedirectStandardError = true, RedirectStandardOutput = true, - RedirectStandardInput = true + RedirectStandardInput = true, + StandardOutputEncoding = Encoding.UTF8, + StandardErrorEncoding = Encoding.UTF8 }; if (environmentVariables != null) From fc9dfb0cf7e41a029a92a1f60e2ca109bb2bff3a Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 7 Apr 2025 15:54:06 +0300 Subject: [PATCH 44/59] Fixed: Disallow tags creation with empty label --- src/Prowlarr.Api.V1/Tags/TagController.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Prowlarr.Api.V1/Tags/TagController.cs b/src/Prowlarr.Api.V1/Tags/TagController.cs index ed3aeebb9..83e9825c9 100644 --- a/src/Prowlarr.Api.V1/Tags/TagController.cs +++ b/src/Prowlarr.Api.V1/Tags/TagController.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using FluentValidation; using Microsoft.AspNetCore.Mvc; using NzbDrone.Core.Datastore.Events; using NzbDrone.Core.Messaging.Events; @@ -20,6 +21,8 @@ namespace Prowlarr.Api.V1.Tags : base(signalRBroadcaster) { _tagService = tagService; + + SharedValidator.RuleFor(c => c.Label).NotEmpty(); } public override TagResource GetResourceById(int id) From 1339373e4344c0d6988f85fd1fb683eabfb0a58e Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 8 Apr 2025 11:42:21 +0300 Subject: [PATCH 45/59] Bump Selenium.WebDriver.ChromeDriver --- src/NzbDrone.Automation.Test/Prowlarr.Automation.Test.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NzbDrone.Automation.Test/Prowlarr.Automation.Test.csproj b/src/NzbDrone.Automation.Test/Prowlarr.Automation.Test.csproj index bb0b5fcc4..78c8b7d0f 100644 --- a/src/NzbDrone.Automation.Test/Prowlarr.Automation.Test.csproj +++ b/src/NzbDrone.Automation.Test/Prowlarr.Automation.Test.csproj @@ -4,7 +4,7 @@ - + From 6be4203b4134f4c47d08659110cf11e83c85c945 Mon Sep 17 00:00:00 2001 From: Servarr Date: Tue, 8 Apr 2025 10:37:59 +0000 Subject: [PATCH 46/59] Automated API Docs update --- src/Prowlarr.Api.V1/openapi.json | 45 ++------------------------------ 1 file changed, 2 insertions(+), 43 deletions(-) diff --git a/src/Prowlarr.Api.V1/openapi.json b/src/Prowlarr.Api.V1/openapi.json index c7fa206e8..35cb7d6a0 100644 --- a/src/Prowlarr.Api.V1/openapi.json +++ b/src/Prowlarr.Api.V1/openapi.json @@ -4739,7 +4739,8 @@ "nullable": true }, "wikiUrl": { - "$ref": "#/components/schemas/HttpUri" + "type": "string", + "nullable": true } }, "additionalProperties": false @@ -4991,48 +4992,6 @@ }, "additionalProperties": false }, - "HttpUri": { - "type": "object", - "properties": { - "fullUri": { - "type": "string", - "nullable": true, - "readOnly": true - }, - "scheme": { - "type": "string", - "nullable": true, - "readOnly": true - }, - "host": { - "type": "string", - "nullable": true, - "readOnly": true - }, - "port": { - "type": "integer", - "format": "int32", - "nullable": true, - "readOnly": true - }, - "path": { - "type": "string", - "nullable": true, - "readOnly": true - }, - "query": { - "type": "string", - "nullable": true, - "readOnly": true - }, - "fragment": { - "type": "string", - "nullable": true, - "readOnly": true - } - }, - "additionalProperties": false - }, "IActionResult": { "type": "object", "additionalProperties": false From c8370c9e00a545ab6b713dae486fd8e1721aaa28 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 9 Apr 2025 20:59:15 +0300 Subject: [PATCH 47/59] Bump version to 1.34.0 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 78b955e67..7871f712d 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '1.33.3' + majorVersion: '1.34.0' minorVersion: $[counter('minorVersion', 1)] prowlarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(prowlarrVersion)' From 6aefd46cd45544c7509c221b7395bb569fc2720a Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 12 Apr 2025 14:31:29 +0300 Subject: [PATCH 48/59] Fixed: (SecretCinema) Edition not being decoded --- src/NzbDrone.Core/Indexers/Definitions/SecretCinema.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/SecretCinema.cs b/src/NzbDrone.Core/Indexers/Definitions/SecretCinema.cs index ab63387e6..e8d8b1584 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/SecretCinema.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/SecretCinema.cs @@ -20,7 +20,7 @@ public class SecretCinema : GazelleBase { public override string Name => "Secret Cinema"; public override string[] IndexerUrls => new[] { "https://secret-cinema.pw/" }; - public override string Description => "A tracker for rare movies."; + public override string Description => "Secret Cinema is a Private ratioless site for rare MOVIES."; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); @@ -151,7 +151,7 @@ public class SecretCinemaParser : IParseIndexerResponse if (torrent.RemasterTitle.IsNotNullOrWhiteSpace()) { - release.Title += $" [{torrent.RemasterTitle.Trim()}]"; + release.Title += $" [{WebUtility.HtmlDecode(torrent.RemasterTitle).Trim()}]"; } // Replace media formats with standards From 71937fa44c71d51a7262edaf92ad7e76f85638c4 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 12 Apr 2025 14:33:30 +0300 Subject: [PATCH 49/59] Update timezone offset for FL --- .../IndexerTests/FileListTests/FileListFixture.cs | 2 +- .../Indexers/Definitions/FileList/FileListParser.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NzbDrone.Core.Test/IndexerTests/FileListTests/FileListFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/FileListTests/FileListFixture.cs index 3699a9d0c..b6f06d180 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/FileListTests/FileListFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/FileListTests/FileListFixture.cs @@ -55,7 +55,7 @@ namespace NzbDrone.Core.Test.IndexerTests.FileListTests torrentInfo.InfoUrl.Should().Be("https://filelist.io/details.php?id=665873"); torrentInfo.CommentUrl.Should().BeNullOrEmpty(); torrentInfo.Indexer.Should().Be(Subject.Definition.Name); - torrentInfo.PublishDate.Should().Be(DateTime.Parse("2020-01-25 20:20:19")); + torrentInfo.PublishDate.Should().Be(DateTime.Parse("2020-01-25 19:20:19")); torrentInfo.Size.Should().Be(8300512414); torrentInfo.InfoHash.Should().Be(null); torrentInfo.MagnetUrl.Should().Be(null); diff --git a/src/NzbDrone.Core/Indexers/Definitions/FileList/FileListParser.cs b/src/NzbDrone.Core/Indexers/Definitions/FileList/FileListParser.cs index b45ddf19b..6d91d930d 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/FileList/FileListParser.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/FileList/FileListParser.cs @@ -77,7 +77,7 @@ public class FileListParser : IParseIndexerResponse InfoUrl = GetInfoUrl(id), Seeders = row.Seeders, Peers = row.Leechers + row.Seeders, - PublishDate = DateTime.Parse(row.UploadDate + " +0200", CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal), + PublishDate = DateTime.Parse(row.UploadDate + " +0300", CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal), Description = row.SmallDescription, Genres = row.SmallDescription.Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries).ToList(), ImdbId = imdbId, From 3287d45661bdbb392777c53f5395a45c8cb28ef9 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 12 Apr 2025 14:42:25 +0300 Subject: [PATCH 50/59] Update timezone offset for AvistaZ trackers --- .../IndexerTests/AvistazTests/AvistazFixture.cs | 2 +- .../IndexerTests/AvistazTests/ExoticazFixture.cs | 2 +- src/NzbDrone.Core/Indexers/Definitions/AvistaZ.cs | 2 +- src/NzbDrone.Core/Indexers/Definitions/ExoticaZ.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NzbDrone.Core.Test/IndexerTests/AvistazTests/AvistazFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/AvistazTests/AvistazFixture.cs index b8f7951d2..dcabb4dbf 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/AvistazTests/AvistazFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/AvistazTests/AvistazFixture.cs @@ -51,7 +51,7 @@ namespace NzbDrone.Core.Test.IndexerTests.AvistazTests torrentInfo.InfoUrl.Should().Be("https://avistaz.to/torrent/187240-japan-sinks-people-of-hope-2021-s01e05-720p-nf-web-dl-ddp20-x264-seikel"); torrentInfo.CommentUrl.Should().BeNullOrEmpty(); torrentInfo.Indexer.Should().Be(Subject.Definition.Name); - torrentInfo.PublishDate.Should().Be(DateTime.Parse("2021-11-14 22:26:21")); + torrentInfo.PublishDate.Should().Be(DateTime.Parse("2021-11-14 21:26:21")); torrentInfo.Size.Should().Be(935127615); torrentInfo.InfoHash.Should().Be("a879261d4e6e792402f92401141a21de70d51bf2"); torrentInfo.MagnetUrl.Should().Be(null); diff --git a/src/NzbDrone.Core.Test/IndexerTests/AvistazTests/ExoticazFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/AvistazTests/ExoticazFixture.cs index 4c4f9f38e..fe4ada593 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/AvistazTests/ExoticazFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/AvistazTests/ExoticazFixture.cs @@ -51,7 +51,7 @@ namespace NzbDrone.Core.Test.IndexerTests.AvistazTests torrentInfo.InfoUrl.Should().Be("https://exoticaz.to/torrent/64040-ssis-419-my-first-experience-is-yua-mikami-from-the-day-i-lost-my-virginity-i-was-devoted-to-sex"); torrentInfo.CommentUrl.Should().BeNullOrEmpty(); torrentInfo.Indexer.Should().Be(Subject.Definition.Name); - torrentInfo.PublishDate.Should().Be(DateTime.Parse("2022-06-11 10:04:50")); + torrentInfo.PublishDate.Should().Be(DateTime.Parse("2022-06-11 09:04:50")); torrentInfo.Size.Should().Be(7085405541); torrentInfo.InfoHash.Should().Be("asdjfiasdf54asd7f4a2sdf544asdf"); torrentInfo.MagnetUrl.Should().Be(null); diff --git a/src/NzbDrone.Core/Indexers/Definitions/AvistaZ.cs b/src/NzbDrone.Core/Indexers/Definitions/AvistaZ.cs index 4e1899651..7d9ba3b51 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/AvistaZ.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/AvistaZ.cs @@ -84,6 +84,6 @@ namespace NzbDrone.Core.Indexers.Definitions public class AvistaZParser : AvistazParserBase { - protected override string TimezoneOffset => "+01:00"; + protected override string TimezoneOffset => "+02:00"; } } diff --git a/src/NzbDrone.Core/Indexers/Definitions/ExoticaZ.cs b/src/NzbDrone.Core/Indexers/Definitions/ExoticaZ.cs index 784cc56e4..0933ea6a2 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/ExoticaZ.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/ExoticaZ.cs @@ -54,7 +54,7 @@ namespace NzbDrone.Core.Indexers.Definitions { private readonly IndexerCapabilitiesCategories _categories; - protected override string TimezoneOffset => "+01:00"; + protected override string TimezoneOffset => "+02:00"; public ExoticaZParser(IndexerCapabilitiesCategories categories) { From 46f73c51bb4402094d31d8c71c0a964252e2bedf Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 12 Apr 2025 14:54:01 +0300 Subject: [PATCH 51/59] Bump IPAddressRange, Npgsql, System.Text.Json --- src/NzbDrone.Common/Prowlarr.Common.csproj | 14 +++++++------- src/NzbDrone.Core/Prowlarr.Core.csproj | 8 ++++---- src/NzbDrone.Host/Prowlarr.Host.csproj | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/NzbDrone.Common/Prowlarr.Common.csproj b/src/NzbDrone.Common/Prowlarr.Common.csproj index b26b024bc..106890399 100644 --- a/src/NzbDrone.Common/Prowlarr.Common.csproj +++ b/src/NzbDrone.Common/Prowlarr.Common.csproj @@ -5,21 +5,21 @@ - - - + + + - + - - + + - + diff --git a/src/NzbDrone.Core/Prowlarr.Core.csproj b/src/NzbDrone.Core/Prowlarr.Core.csproj index 4b8138cb4..d3f7656be 100644 --- a/src/NzbDrone.Core/Prowlarr.Core.csproj +++ b/src/NzbDrone.Core/Prowlarr.Core.csproj @@ -8,21 +8,21 @@ - + - + - + - + diff --git a/src/NzbDrone.Host/Prowlarr.Host.csproj b/src/NzbDrone.Host/Prowlarr.Host.csproj index 8dd6d8e61..f302e9cbe 100644 --- a/src/NzbDrone.Host/Prowlarr.Host.csproj +++ b/src/NzbDrone.Host/Prowlarr.Host.csproj @@ -5,8 +5,8 @@ - - + + From 4ba72ea7f3e00cd63e1265e1e35ffc25b7d8f3dc Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 12 Apr 2025 14:54:56 +0300 Subject: [PATCH 52/59] Bump Swashbuckle to 7.3.2 --- docs.sh | 2 +- src/NzbDrone.Host/Prowlarr.Host.csproj | 2 +- src/Prowlarr.Api.V1/Prowlarr.Api.V1.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs.sh b/docs.sh index ab084b61b..38b0e0fbc 100755 --- a/docs.sh +++ b/docs.sh @@ -38,7 +38,7 @@ dotnet clean $slnFile -c Release dotnet msbuild -restore $slnFile -p:Configuration=Debug -p:Platform=$platform -p:RuntimeIdentifiers=$RUNTIME -t:PublishAllRids dotnet new tool-manifest -dotnet tool install --version 6.6.2 Swashbuckle.AspNetCore.Cli +dotnet tool install --version 7.3.2 Swashbuckle.AspNetCore.Cli dotnet tool run swagger tofile --output ./src/Prowlarr.Api.V1/openapi.json "$outputFolder/$FRAMEWORK/$RUNTIME/$application" v1 & diff --git a/src/NzbDrone.Host/Prowlarr.Host.csproj b/src/NzbDrone.Host/Prowlarr.Host.csproj index f302e9cbe..12bd5168e 100644 --- a/src/NzbDrone.Host/Prowlarr.Host.csproj +++ b/src/NzbDrone.Host/Prowlarr.Host.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/Prowlarr.Api.V1/Prowlarr.Api.V1.csproj b/src/Prowlarr.Api.V1/Prowlarr.Api.V1.csproj index 4371487f2..15684b0fe 100644 --- a/src/Prowlarr.Api.V1/Prowlarr.Api.V1.csproj +++ b/src/Prowlarr.Api.V1/Prowlarr.Api.V1.csproj @@ -5,7 +5,7 @@ - + From 075fd24f96b7759b6459529a1c252f2e62aa5132 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 12 Apr 2025 16:17:13 +0300 Subject: [PATCH 53/59] Downgrade Microsoft.AspNetCore.WebUtilities --- src/NzbDrone.Core/Prowlarr.Core.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/Prowlarr.Core.csproj b/src/NzbDrone.Core/Prowlarr.Core.csproj index d3f7656be..3f70dd577 100644 --- a/src/NzbDrone.Core/Prowlarr.Core.csproj +++ b/src/NzbDrone.Core/Prowlarr.Core.csproj @@ -8,7 +8,7 @@ - + From 362f3fe22382220ec1478c8f2eef4c6a0e847d63 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 13 Apr 2025 09:48:04 +0300 Subject: [PATCH 54/59] Bump version to 1.34.1 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 7871f712d..1f79a65ec 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '1.34.0' + majorVersion: '1.34.1' minorVersion: $[counter('minorVersion', 1)] prowlarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(prowlarrVersion)' From 0322d70d6342af8437257986e5c2666564625e6c Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 20 Apr 2025 11:08:04 +0300 Subject: [PATCH 55/59] Fixed: Handle 307 and 308 redirects for indexer download requests --- src/NzbDrone.Core/Indexers/HttpIndexerBase.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs b/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs index fde23c691..4a8014c63 100644 --- a/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs +++ b/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs @@ -250,7 +250,11 @@ namespace NzbDrone.Core.Indexers { var response = await _httpClient.ExecuteProxiedAsync(request, Definition); - if (response.StatusCode is HttpStatusCode.MovedPermanently or HttpStatusCode.Found or HttpStatusCode.SeeOther) + if (response.StatusCode is HttpStatusCode.MovedPermanently + or HttpStatusCode.Found + or HttpStatusCode.SeeOther + or HttpStatusCode.TemporaryRedirect + or HttpStatusCode.PermanentRedirect) { var autoRedirectChain = new List { request.Url.ToString() }; From 356d07ef3405aab357f9216d5abe30f7819c854e Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 20 Apr 2025 22:30:15 +0300 Subject: [PATCH 56/59] Bump version to 1.35.0 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 1f79a65ec..dc667e803 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '1.34.1' + majorVersion: '1.35.0' minorVersion: $[counter('minorVersion', 1)] prowlarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(prowlarrVersion)' From 0b3a5c9bc41f5fa550bb487e9ac661496aa64b63 Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 8 Apr 2025 09:33:29 +0000 Subject: [PATCH 57/59] Multiple Translations updated by Weblate ignore-downstream Co-authored-by: Hugoren Martinako Co-authored-by: Oskari Lavinto Co-authored-by: Weblate Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ca/ Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fi/ Translation: Servarr/Prowlarr --- src/NzbDrone.Core/Localization/Core/ca.json | 232 +++++++++++++++++++- src/NzbDrone.Core/Localization/Core/fi.json | 4 +- 2 files changed, 232 insertions(+), 4 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/ca.json b/src/NzbDrone.Core/Localization/Core/ca.json index 76350e36a..83a720b51 100644 --- a/src/NzbDrone.Core/Localization/Core/ca.json +++ b/src/NzbDrone.Core/Localization/Core/ca.json @@ -484,7 +484,7 @@ "InfoUrl": "URL d'informació", "PublishedDate": "Data de publicació", "Redirected": "Redirecció", - "AllSearchResultsHiddenByFilter": "Tots els resultats estan ocults pel filtre aplicat", + "AllSearchResultsHiddenByFilter": "Tots els resultats estan ocults pel filtre aplicat.", "HealthMessagesInfoBox": "Podeu trobar més informació sobre la causa d'aquests missatges de comprovació de salut fent clic a l'enllaç wiki (icona del llibre) al final de la fila o consultant els vostres [registres]({link}). Si teniu problemes per a interpretar aquests missatges, podeu posar-vos en contacte amb el nostre suport als enllaços següents.", "AptUpdater": "Utilitzeu apt per a instal·lar l'actualització", "DockerUpdater": "actualitzeu el contenidor Docker per a rebre l'actualització", @@ -512,5 +512,233 @@ "MinimumSeeders": "Seeders mínims", "SeedRatio": "Ràtio de la llavor", "ApplicationSettingsSyncRejectBlocklistedTorrentHashesHelpText": "Si un torrent està bloquejat per un hash, pot ser que no es rebutgi correctament durant el RSS/Search per a alguns indexadors, habilitant això permetrà que es rebutgi després que s'agafi el torrent, però abans que s'enviï al client.", - "SeedTime": "Temps de la llavor" + "SeedTime": "Temps de la llavor", + "DefaultCategory": "Categoria predeterminada", + "IndexerVipExpiredHealthCheckMessage": "Els beneficis VIP de l'indexador han caducat: {indexerNames}", + "MassEditor": "Editor de masses", + "NoSearchResultsFound": "No s'han trobat resultats de cerca, proveu de realitzar una nova cerca a continuació.", + "NotSupported": "No suportat", + "OverrideAndAddToDownloadClient": "Sobreescriu i afegeix al client de baixada", + "PackSeedTime": "Temps de la llavor del paquet", + "SearchAllIndexers": "Cerca tots els indexadors", + "SearchIndexers": "Cerca indexadors", + "SeedTimeHelpText": "L'hora en què un torrent s'ha de sembrar abans d'aturar-se, buit és el predeterminat de l'aplicació", + "SettingsIndexerLogging": "Registre de l'indexador millorat", + "TotalIndexerSuccessfulGrabs": "Indexador total correcte", + "BookSearch": "Cerca de llibres", + "ClearHistoryMessageText": "Esteu segur que voleu netejar tot l'historial de {appName}?", + "IndexerGazelleGamesSettingsFreeleechOnlyHelpText": "Cerca només els llançaments de freeleech", + "ClearHistory": "Neteja l'historial", + "IndexerTorrentSyndikatSettingsApiKeyHelpText": "Clau de l'API del lloc", + "IndexerGazelleGamesSettingsApiKeyHelpText": "Clau API del lloc (trobada a Configuració => Accés)", + "IndexerBeyondHDSettingsRssKeyHelpText": "Clau RSS del lloc (trobada a Seguretat => Clau RSS)", + "ApplicationsLoadError": "No s'ha pogut carregar la llista d'aplicacions", + "BookSearchTypes": "Tipus de cerca de llibres", + "DownloadClientCategory": "Baixa la categoria del client", + "IndexerAuth": "Autor de l'indexador", + "IndexerBeyondHDSettingsLimitedOnly": "Només limitat", + "IndexerBeyondHDSettingsRefundOnly": "Només el reemborsament", + "IndexerBeyondHDSettingsRefundOnlyHelpText": "Cerca només el reemborsament", + "IndexerBeyondHDSettingsRewindOnlyHelpText": "Cerca només el rebobinat", + "IndexerBeyondHDSettingsSearchTypes": "Tipus de cerca", + "IndexerBeyondHDSettingsSearchTypesHelpText": "Seleccioneu els tipus de llançaments que us interessin. Si no hi ha cap seleccionat, s'utilitzen totes les opcions.", + "IndexerDownloadClientHelpText": "Especifiqueu quin client de baixada s'utilitza per a les captures fetes a {appName} des d'aquest indexador", + "IndexerGazelleGamesSettingsApiKeyHelpTextWarning": "Ha de tenir permisos d'usuari i torrents", + "IndexerGazelleGamesSettingsSearchGroupNames": "Cerca noms de grup", + "IndexerHDBitsSettingsFreeleechOnlyHelpText": "Mostra només els llançaments de freeleech", + "IndexerHDBitsSettingsUseFilenames": "Utilitza els noms de fitxer", + "IndexerHDBitsSettingsUseFilenamesHelpText": "Marqueu aquesta opció si voleu utilitzar noms de fitxer torrent com a títols de llançament", + "IndexerHDBitsSettingsUsernameHelpText": "Nom d'usuari del lloc", + "IndexerHealthCheckNoIndexers": "No hi ha indexadors activats, {appName} no retornarà els resultats de la cerca", + "IndexerHistoryLoadError": "Error en carregar l'historial de l'indexador", + "IndexerIPTorrentsSettingsCookieUserAgent": "Agent d'usuari de la galeta", + "IndexerIPTorrentsSettingsFreeleechOnlyHelpText": "Cerca només els llançaments de freeleech", + "IndexerInfo": "Informació de l'indexador", + "IndexerNebulanceSettingsApiKeyHelpText": "Clau API de la Configuració de l'usuari . Claus Api. La clau ha de tenir permisos de llista i baixada", + "IndexerNewznabSettingsVipExpirationHelpText": "Data d'entrada (yyyy-mm-dd) per a la caducitat VIP o en blanc, {appName} notificarà 1 setmana des de la caducitat de VIP", + "IndexerNoDefinitionCheckHealthCheckMessage": "Els indexadors no tenen definició i no funcionaran: {indexerNames}. Suprimiu i (o torneu a afegir) a {appName}.", + "IndexerObsoleteCheckMessage": "Els indexadors estan obsolets o s'han actualitzat: {0}. Suprimiu i (o torneu a afegir) a {appName}", + "IndexerPassThePopcornSettingsApiKeyHelpText": "Clau de l'API del lloc", + "IndexerRss": "Indexador RSS", + "IndexerSettingsGrabLimitHelpText": "El nombre màxim de captures especificat per la unitat respectiva que {appName} permetrà al lloc", + "IndexerSettingsPackSeedTimeIndexerHelpText": "L'hora en què un paquet (temporada o discografia) s'ha de sembrar el torrent abans d'aturar-se, buit és el valor predeterminat de l'aplicació", + "IndexerSettingsPreferMagnetUrl": "Prefereix l'URL de l'imant", + "IndexerSettingsPreferMagnetUrlHelpText": "Quan està activat, aquest indexador preferirà l'ús d'URLs magnet per a les captures amb enllaços de reserva a torrents", + "IndexerSettingsQueryLimitHelpText": "El nombre màxim de consultes especificat per la unitat respectiva que {appName} permetrà al lloc", + "InitialFailure": "Fallada inicial", + "NoIndexerCategories": "No s'ha trobat cap categoria per a aquest indexador", + "RepeatSearch": "Cerca repetida", + "SettingsLogRotateHelpText": "Nombre màxim de fitxers de registre a mantenir desats a la carpeta de registres", + "SyncProfile": "Perfil de sincronització", + "TotalUserAgentGrabs": "Total d'agents d'usuari", + "UnableToLoadAppProfiles": "No s'han pogut carregar els perfils de l'aplicació", + "VipExpiration": "Caducitat VIP", + "IndexerOrpheusSettingsApiKeyHelpText": "Clau API del lloc (trobada a Configuració => Accés)", + "IndexerRedactedSettingsApiKeyHelpText": "Clau API del lloc (trobada a Configuració => Accés)", + "ProwlarrSupportsAnyIndexer": "{appName} admet molts indexadors, a més de qualsevol indexador que utilitzi l'estàndard Newznab/Torznab utilitzant 'Generic Newznab' (per usenet) o 'Generic Torznab' (per torrents). Cerca i selecciona el teu indexador des de sota.", + "DownloadClientSettingsDefaultCategorySubFolderHelpText": "Categoria alternativa predeterminada si no hi ha cap categoria assignada per a un llançament. Afegir una categoria específica a {appName} evita conflictes amb baixades no relacionades amb {appName}. L'ús d'una categoria és opcional, però molt recomanable.", + "AppProfileSelectHelpText": "Els perfils d'aplicació s'utilitzen per controlar RSS, la cerca automàtica i la configuració de cerca interactiva en sincronitzar aplicacions", + "AudioSearch": "Cerca d'àudio", + "IndexerSettingsAppsMinimumSeeders": "Aplicacions de cercadors mínims", + "DeleteApplication": "Suprimeix l'aplicació", + "DownloadClientSettingsPriorityItemHelpText": "Prioritat a usar en capturar elements", + "DownloadClientSettingsDefaultCategoryHelpText": "Categoria alternativa predeterminada si no hi ha cap categoria assignada per a un llançament. Afegir una categoria específica a {appName} evita conflictes amb baixades no relacionades amb {appName}. L'ús d'una categoria és opcional, però molt recomanable.", + "EditCategory": "Edita la categoria", + "IndexerQuery": "Consulta de l'indexador", + "IndexerSettingsBaseUrl": "Url base", + "IndexerSettingsCookieHelpText": "Cookie del lloc", + "IndexerSettingsLimitsUnitHelpText": "La unitat de temps per comptar els límits per indexador", + "IndexerSettingsPackSeedTime": "Temps de la llavor del paquet", + "IndexerSite": "Lloc indexador", + "IndexerTagsHelpTextWarning": "Les etiquetes s'han d'utilitzar amb precaució, poden tenir efectes no desitjats. Un indexador amb una etiqueta només sincronitzarà amb aplicacions amb la mateixa etiqueta.", + "IndexerSettingsSummary": "Configura diversos paràmetres globals de l'indexador.", + "ManageApplications": "Gestiona les aplicacions", + "PackSeedTimeHelpText": "L'hora en què un paquet (temporada o discografia) s'ha de sembrar el torrent abans d'aturar-se, buit és el valor predeterminat de l'aplicació", + "PreferMagnetUrl": "Prefereix l'URL de l'imant", + "PreferMagnetUrlHelpText": "Quan està activat, aquest indexador preferirà l'ús d'URLs magnet per a les captures amb enllaços de reserva a torrents", + "ProwlarrDownloadClientsInAppOnlyAlert": "Els clients de baixada només són per a les cerques a l'aplicació {appName} i no sincronitzen amb les aplicacions. No hi ha plans per afegir aquesta funcionalitat.", + "IndexerBeyondHDSettingsRewindOnly": "Només rebobina", + "ProxyValidationUnableToConnect": "No s'ha pogut connectar al servidor intermediari: {exceptionMessage}. Comprova els detalls del registre que envolta aquest error", + "QueryOptions": "Opcions de la consulta", + "TestAllApps": "Prova totes les aplicacions", + "TotalHostQueries": "Total de consultes de l'amfitrió", + "AverageGrabs": "Mitjana d'herba", + "AverageQueries": "Mitjana de consultes", + "FilterPlaceHolder": "Cerca indexadors", + "IndexerBeyondHDSettingsLimitedOnlyHelpText": "Cerca només freeleech (Limited UL)", + "IndexerBeyondHDSettingsApiKeyHelpText": "Clau API del lloc (trobada a Seguretat => Clau API)", + "IndexerSettingsVipExpiration": "Caducitat VIP", + "IndexerVipExpiringHealthCheckMessage": "Els beneficis VIP de l'indexador expiraran aviat: {indexerNames}", + "LastFailure": "Darrera fallada", + "MovieSearch": "Cerca de pel·lícules", + "MovieSearchTypes": "Tipus de cerca de pel·lícules", + "MusicSearchTypes": "Tipus de cerca de música", + "QueryType": "Tipus de consulta", + "RssQueries": "Consultes RSS", + "SyncLevelFull": "Sincronització completa: mantindrà els indexadors d'aquesta aplicació completament sincronitzats. Els canvis fets als indexadors a {appName} se sincronitzen amb aquesta aplicació. Qualsevol canvi fet a indexadors remotament dins d'aquesta aplicació serà anul·lat per {appName} en la següent sincronització.", + "TotalHostGrabs": "Total d'amfitrions", + "TotalQueries": "Total de consultes", + "NoApplicationsFound": "No s'ha trobat cap aplicació", + "SyncProfiles": "Sincronitza els perfils", + "TorznabUrl": "Url Torznab", + "TvSearch": "Cerca de TV", + "DeleteIndexerProxy": "Suprimeix el servidor intermediari de l'indexador", + "DisabledUntil": "Desactivat fins", + "GrabTitle": "Captura el títol", + "SettingsIndexerLoggingHelpText": "Registra dades addicionals de l'indexador", + "SyncLevel": "Nivell de sincronització", + "AdvancedSettingsHiddenClickToShow": "Configuració avançada oculta, feu clic per mostrar", + "AdvancedSettingsShownClickToHide": "Configuració avançada mostrada, feu clic per amagar", + "AppsMinimumSeeders": "Aplicacions de cercadors mínims", + "AppsMinimumSeedersHelpText": "«Mínims filtradors requerits per les Aplicacions perquè l'indexador s'agafi", + "CountIndexersAvailable": "{count} indexador(s) disponible", + "HistoryCleanup": "Neteja de l'historial", + "HistoryDetails": "Detalls de l'historial", + "SettingsFilterSentryEventsHelpText": "Filtra els esdeveniments d'error d'usuari coneguts perquè s'enviïn com a Analytics", + "MappedCategories": "Categories assignades", + "AppSettingsSummary": "Aplicacions i paràmetres per configurar com {appName} interactua amb els vostres programes PVR", + "ConnectSettingsSummary": "Notificacions i scripts personalitzats", + "DeleteClientCategory": "Suprimeix la categoria del client de baixada", + "FullSync": "Sincronització completa", + "IndexerAlreadySetup": "Almenys una instància de l'indexador ja està configurada", + "RawSearchSupported": "S'admet la cerca RAW", + "RssFeed": "Canal RSS", + "SearchTypes": "Tipus de cerca", + "SeedRatioHelpText": "La relació a la qual ha d'arribar un torrent abans d'aturar-se, buida és la predeterminada de l'aplicació", + "SemiPrivate": "Semi-Privada", + "TotalIndexerQueries": "Total de consultes de l'indexador", + "TotalUserAgentQueries": "Total de consultes d'agents d'usuari", + "GoToApplication": "Ves a l'aplicació", + "Url": "Url", + "AreYouSureYouWantToDeleteIndexer": "Esteu segur que voleu suprimir '{name}' de {appName}?", + "AverageResponseTimesMs": "Temps mitjà de resposta de l'indexador (ms)", + "FoundCountReleases": "S'han trobat {itemCount} versions", + "AuthQueries": "Consultes d'Autorització", + "BasicSearch": "Cerca bàsica", + "IndexerName": "Nom de l'indexador", + "IndexerStatus": "Estat de l'indexador", + "IndexerTagsHelpText": "Utilitzeu etiquetes per especificar els intermediaris de l'indexador o a quines aplicacions se sincronitza l'indexador.", + "NewznabUrl": "Url Newznab", + "SearchCountIndexers": "Cerca {count} indexador", + "UnableToLoadDevelopmentSettings": "No s'han pogut carregar els paràmetres de desenvolupament", + "SettingsFilterSentryEvents": "Filtra els esdeveniments d'anàlisi", + "ApplicationTagsHelpText": "Sincronitza els indexadors d'aquesta aplicació que tenen una o més etiquetes coincidents. Si no es llisten etiquetes aquí, llavors no s'impedirà la sincronització d'indexadors a causa de les seves etiquetes.", + "ApplicationTagsHelpTextWarning": "Les etiquetes s'han d'utilitzar amb precaució, poden tenir efectes no desitjats. Una aplicació amb una etiqueta només sincronitzarà amb els indexadors que tinguin la mateixa etiqueta.", + "DeleteSelectedApplications": "Suprimeix les aplicacions seleccionades", + "DownloadClientsSettingsSummary": "Baixa la configuració dels clients per a la integració a la cerca de la interfície d'usuari {appName}", + "ElapsedTime": "Temps transcorregut", + "EnableIndexer": "Habilita l'indexador", + "EnableRssHelpText": "Habilita el canal RSS per a l'indexador", + "IncludeManualGrabsHelpText": "Inclou les notes manuals fetes a {appName}", + "IndexerFailureRate": "Taxa de fallada de l'indexador", + "ProwlarrSupportsAnyDownloadClient": "{appName} admet qualsevol dels clients de baixada que es llisten a continuació.", + "TotalGrabs": "Grabs totals", + "IndexerDetails": "Detalls de l'indexador", + "IndexerPriorityHelpText": "Prioritat de l'indexador des de l'1 (el més alt) fins al 50 (el més oest). Per defecte: 25.", + "IndexerProxy": "Servidor intermediari de l'indexador", + "UISettingsSummary": "Opcions de data, idioma i color defectuoses", + "IndexerCategories": "Categories de l'indexador", + "IndexerPassThePopcornSettingsFreeleechOnlyHelpText": "Cerca només els llançaments de freeleech", + "SearchCapabilities": "Capacitats de cerca", + "SearchType": "Tipus de cerca", + "SettingsLogSql": "Registre Sql", + "SyncLevelAddRemove": "Afegeix i elimina només: quan s'afegeixen o s'eliminen els indexadors de {appName}, s'actualitzarà aquesta aplicació remota.", + "IndexerProxies": "Propis de l'indexador", + "ApplicationSettingsSyncRejectBlocklistedTorrentHashes": "Sincronitza les fulles del torrent de la llista de blocs en bloc mentre s'agafa", + "CertificateValidationHelpText": "Canvia l'estricta validació de la certificació HTTPS", + "IndexerDisabled": "Indexador desactivat", + "IndexerFileListSettingsPasskeyHelpText": "Contrasenya del lloc (Aquesta és la cadena alfanumèrica a l'URL del seguidor que es mostra al client de baixada)", + "IndexerSettingsQueryLimit": "Límit de consulta", + "IndexerHDBitsSettingsPasskeyHelpText": "Contrasenya dels detalls de l'usuari", + "IndexerSettingsPasskey": "Clau de pas", + "ClickToChangeQueryOptions": "Feu clic per a canviar les opcions de consulta", + "EnabledRedirected": "Activat, redirigit", + "Parameters": "Paràmetres", + "QueryResults": "Resultats de la consulta", + "RedirectHelpText": "Redirigeix la sol·licitud de baixada entrant per a l'indexador i passa la captura directament en lloc de intermediaris a través de {appName}", + "UnableToLoadIndexerProxies": "No s'han pogut carregar els intermediaris de l'indexador", + "IndexerId": "ID de l'indexador", + "IndexerAlphaRatioSettingsExcludeScene": "Exclou l'escena", + "IndexerAlphaRatioSettingsExcludeSceneHelpText": "Exclou els llançaments d'escenes dels resultats", + "IndexerAlphaRatioSettingsFreeleechOnlyHelpText": "Cerca només els llançaments de freeleech", + "IndexerBeyondHDSettingsFreeleechOnlyHelpText": "Cerca només els llançaments de freeleech", + "IndexerFileListSettingsFreeleechOnlyHelpText": "Cerca només els llançaments de freeleech", + "IndexerFileListSettingsUsernameHelpText": "Nom d'usuari del lloc", + "IndexerGazelleGamesSettingsSearchGroupNamesHelpText": "Cerca publicacions per noms de grup", + "IndexerHDBitsSettingsOrigins": "Orígens", + "IndexerIPTorrentsSettingsCookieUserAgentHelpText": "Agent d'usuari associat a la cookie utilitzada des del navegador", + "IndexerNewznabSettingsApiKeyHelpText": "Clau de l'API del lloc", + "IndexerNzbIndexSettingsApiKeyHelpText": "Clau de l'API del lloc", + "IndexerSettingsAppsMinimumSeedersHelpText": "«Mínims filtradors requerits per les Aplicacions perquè l'indexador s'agafi", + "IndexerSettingsFreeleechOnly": "Només Freeleech", + "IndexerSettingsGrabLimit": "Límit de captura", + "IndexerSettingsLimitsUnit": "Unitats de límits", + "IndexerSettingsRssKey": "Clau RSS", + "SelectIndexers": "Selecciona els indexadors", + "SettingsSqlLoggingHelpText": "Registra totes les consultes SQL de {appName}", + "SyncAppIndexers": "Sincronitza els indexadors d'aplicacions", + "AppProfileInUse": "Perfil d'aplicació en ús", + "DeleteAppProfile": "Suprimeix el perfil de l'aplicació", + "TVSearchTypes": "Tipus de cerca de TV", + "IndexerMTeamTpSettingsFreeleechOnlyHelpText": "Cerca només els llançaments de freeleech", + "IndexerMTeamTpSettingsApiKeyHelpText": "Clau API del Lloc (trobada a Tauler de control de l'usuari => Seguretat => Laboratori)", + "MinimumSeedersHelpText": "Visors mínims requerits per l'aplicació perquè l'indexador s'agafi", + "NoIndexerHistory": "No s'ha trobat cap historial per a aquest indexador", + "SearchQueries": "Cerca consultes", + "SettingsConsoleLogLevel": "Nivell de registre de la consola", + "IndexerPassThePopcornSettingsGoldenPopcornOnly": "Només blat de moro daurat", + "IndexerPassThePopcornSettingsGoldenPopcornOnlyHelpText": "Cerca només els llançaments Golden Popcorn", + "Open": "Obre", + "ProwlarrDownloadClientsAlert": "Si voleu fer cerques directament dins de {appName}, heu d'afegir Clients de Baixades. En cas contrari, no cal afegir-les aquí. Per a les cerques des de les teves Apps, els clients de descàrrega configurats s'utilitzen en el seu lloc.", + "Website": "Lloc web", + "DownloadClientQbittorrentSettingsUseSslHelpText": "Utilitza una connexió segura. Vegeu Opcions -> Interfície web -> 'Utilitza HTTPS en comptes d'HTTP' a qBittorrent.", + "IndexerAvistazSettingsFreeleechOnlyHelpText": "Cerca només els llançaments de freeleech", + "IndexerAvistazSettingsPasswordHelpText": "Contrasenya del lloc", + "IndexerAvistazSettingsPidHelpText": "PID de la pàgina del meu compte o del meu perfil", + "IndexerAvistazSettingsUsernameHelpText": "Nom d'usuari del lloc", + "IndexerAvistazSettingsUsernameHelpTextWarning": "Només el rang de membre i superior pot utilitzar l'API en aquest indexador.", + "SelectedCountOfCountReleases": "S'han seleccionat {selectedCount} de les versions {itemCount}", + "SettingsLogRotate": "Rotació del registre", + "AreYouSureYouWantToDeleteCategory": "Esteu segur que voleu suprimir la categoria assignada?", + "Book": "Llibre" } diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index ab235f518..0236ce555 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -207,7 +207,7 @@ "StartTypingOrSelectAPathBelow": "Aloita kirjoitus tai valitse sijainti alta", "StartupDirectory": "Käynnistyskansio", "TableOptions": "Taulukkonäkymän asetukset", - "TableOptionsColumnsMessage": "Valitse näytettävät sarakkeet ja niiden järjestys", + "TableOptionsColumnsMessage": "Valitse näytettävät sarakkeet ja niiden järjestys.", "TagsHelpText": "Käytetään vähintään yhdellä täsmäävällä tunnisteella merkityille hakupalveluille.", "UnableToAddANewAppProfilePleaseTryAgain": "Virhe lisättäessä sovellusprofiilia. Yritä uudelleen.", "UnableToAddANewNotificationPleaseTryAgain": "Ilmoituspalvelun lisääminen epäonnistui. Yritä uudelleen.", @@ -805,6 +805,6 @@ "IndexerPassThePopcornSettingsGoldenPopcornOnly": "Vain \"Golden Popcorn\"", "IndexerPassThePopcornSettingsGoldenPopcornOnlyHelpText": "Etsi vain ns. kultaisella pocornilla merkittyjä julkaisuja.", "IndexerSettingsFreeleechOnly": "Vain \"Freeleech\"", - "IndexerSettingsCookieHelpText": "Jos sivusto vaatii kirjautumisevästeen, se on noudettava selaimen kautta.", + "IndexerSettingsCookieHelpText": "Jos sivusto vaatii kirjautumisevästeen, on se noudettava selaimen avulla.", "IndexerAvistazSettingsPasswordHelpText": "Sivuston salasana" } From 48a658571bdecda1d6a94b77876afb84346bdf5e Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 21 Apr 2025 14:36:35 +0300 Subject: [PATCH 58/59] Improve error messaging for not finding JSON selectors in Cardigann --- .../Indexers/Definitions/Cardigann/CardigannBase.cs | 13 +++++++------ .../Definitions/Cardigann/CardigannParser.cs | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannBase.cs b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannBase.cs index 6abdd710e..9e2c6e06b 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannBase.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannBase.cs @@ -8,6 +8,7 @@ using System.Text; using System.Text.RegularExpressions; using AngleSharp.Dom; using Microsoft.AspNetCore.WebUtilities; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; using NLog; using NzbDrone.Common.Extensions; @@ -214,19 +215,19 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann if (selector.Selector != null) { var selectorSelector = ApplyGoTemplateText(selector.Selector.TrimStart('.'), variables); - selectorSelector = JsonParseFieldSelector(parentObj, selectorSelector); + var fieldSelector = JsonParseFieldSelector(parentObj, selectorSelector); JToken selection = null; - if (selectorSelector != null) + if (fieldSelector != null) { - selection = parentObj.SelectToken(selectorSelector); + selection = parentObj.SelectToken(fieldSelector); } if (selection == null) { if (required) { - throw new Exception(string.Format("Selector \"{0}\" didn't match {1}", selectorSelector, parentObj.ToString())); + throw new Exception($"Selector \"{selectorSelector}\" didn't match {parentObj.ToString(Formatting.None)}"); } return null; @@ -234,7 +235,7 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann if (selection.Type is JTokenType.Array) { - // turn this json array into a comma delimited string + // turn this json array into a comma-delimited string var valueArray = selection.Value(); value = string.Join(",", valueArray); } @@ -259,7 +260,7 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann { if (required) { - throw new Exception($"None of the case selectors \"{string.Join(",", selector.Case)}\" matched {parentObj}"); + throw new Exception($"None of the case selectors \"{string.Join(",", selector.Case)}\" matched {parentObj.ToString(Formatting.None)}"); } return null; diff --git a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannParser.cs b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannParser.cs index 28be1c3e5..4b96e25ed 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannParser.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannParser.cs @@ -105,7 +105,7 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann } catch (Exception ex) { - _logger.Trace(ex, "Failed to parse JSON rows count."); + _logger.Debug(ex, "Failed to parse JSON rows count."); } } From c85f170d4174320ae6501dc1c74b74c6643182ef Mon Sep 17 00:00:00 2001 From: blu3 Date: Tue, 22 Apr 2025 14:15:28 +0300 Subject: [PATCH 59/59] Bump license year --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e8c60546a..6d196feee 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,6 @@ Thank you to [