From 6897ed0b3ff8734c2f206f52a8379c6853778870 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 28 May 2023 02:16:06 +0300 Subject: [PATCH 0001/1128] Fixed: (Anidex) Search with all categories selected --- src/NzbDrone.Core/Indexers/Definitions/Anidex.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/Anidex.cs b/src/NzbDrone.Core/Indexers/Definitions/Anidex.cs index cb5b934fc..c2065f119 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Anidex.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Anidex.cs @@ -161,7 +161,7 @@ namespace NzbDrone.Core.Indexers.Definitions var queryCats = _capabilities.Categories.MapTorznabCapsToTrackers(categories); - if (queryCats.Any()) + if (queryCats.Any() && _capabilities.Categories.GetTrackerCategories().Except(queryCats).Any()) { searchUrl += "&id=" + string.Join(",", queryCats); } From b02188acf433a22ec34a75ec4d27f157aaa37a2f Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 28 May 2023 14:55:20 +0300 Subject: [PATCH 0002/1128] Fixed: (HealthCheck) Check only enabled indexer proxies --- .../HealthCheck/Checks/IndexerProxyCheck.cs | 10 ++++++---- .../IndexerProxies/HttpIndexerProxyBase.cs | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/NzbDrone.Core/HealthCheck/Checks/IndexerProxyCheck.cs b/src/NzbDrone.Core/HealthCheck/Checks/IndexerProxyCheck.cs index a78061561..484f2bc19 100644 --- a/src/NzbDrone.Core/HealthCheck/Checks/IndexerProxyCheck.cs +++ b/src/NzbDrone.Core/HealthCheck/Checks/IndexerProxyCheck.cs @@ -22,16 +22,18 @@ namespace NzbDrone.Core.HealthCheck.Checks public override HealthCheck Check() { - var enabledProviders = _proxyFactory.GetAvailableProviders(); + var enabledProxies = _proxyFactory.GetAvailableProviders() + .Where(n => ((IndexerProxyDefinition)n.Definition).Enable) + .ToList(); - var badProxies = enabledProviders.Where(p => p.Test().IsValid == false).ToList(); + var badProxies = enabledProxies.Where(p => p.Test().IsValid == false).ToList(); - if (enabledProviders.Empty() || badProxies.Count == 0) + if (enabledProxies.Empty() || badProxies.Count == 0) { return new HealthCheck(GetType()); } - if (badProxies.Count == enabledProviders.Count) + if (badProxies.Count == enabledProxies.Count) { return new HealthCheck(GetType(), HealthCheckResult.Error, diff --git a/src/NzbDrone.Core/IndexerProxies/HttpIndexerProxyBase.cs b/src/NzbDrone.Core/IndexerProxies/HttpIndexerProxyBase.cs index 9974c1f7f..b82251d6e 100644 --- a/src/NzbDrone.Core/IndexerProxies/HttpIndexerProxyBase.cs +++ b/src/NzbDrone.Core/IndexerProxies/HttpIndexerProxyBase.cs @@ -31,8 +31,8 @@ namespace NzbDrone.Core.IndexerProxies var failures = new List(); var request = PreRequest(_cloudRequestBuilder.Create() - .Resource("/ping") - .Build()); + .Resource("/ping") + .Build()); try { From 5437aac346d73f74bb5968e2b63c0a9fec196b91 Mon Sep 17 00:00:00 2001 From: Matthew Strapp Date: Sat, 27 May 2023 18:34:48 -0500 Subject: [PATCH 0003/1128] Fixed: Use relative paths instead of absolute paths for webmanifest (cherry picked from commit 8e771f95ade919a8f1ed7b48675f032a6c508cb2) --- frontend/src/Content/Images/Icons/manifest.json | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/frontend/src/Content/Images/Icons/manifest.json b/frontend/src/Content/Images/Icons/manifest.json index d14732f60..f53279dd3 100644 --- a/frontend/src/Content/Images/Icons/manifest.json +++ b/frontend/src/Content/Images/Icons/manifest.json @@ -1,18 +1,19 @@ { - "name": "", + "name": "Prowlarr", "icons": [ { - "src": "/Content/Images/Icons/android-chrome-192x192.png", + "src": "android-chrome-192x192.png", "sizes": "192x192", "type": "image/png" }, { - "src": "/Content/Images/Icons/android-chrome-512x512.png", + "src": "android-chrome-512x512.png", "sizes": "512x512", "type": "image/png" } ], + "start_url": "../../../../", "theme_color": "#3a3f51", "background_color": "#3a3f51", "display": "standalone" -} \ No newline at end of file +} From ce430433e5f212a8883cfb4340e26ae7d4e6653a Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 28 May 2023 18:21:49 +0300 Subject: [PATCH 0004/1128] Bump version to 1.5.2 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 0bf0dc6d1..35128db74 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.5.1' + majorVersion: '1.5.2' minorVersion: $[counter('minorVersion', 1)] prowlarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(prowlarrVersion)' From ea0eb2efa7c3184bcdb4049e40de488b3dab6183 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 28 May 2023 02:53:49 +0300 Subject: [PATCH 0005/1128] Enforce rule IDE0005 on build (cherry picked from commit 6b1e4ef81938d264a2ddc8b626b0502f799aa640) --- src/Directory.Build.props | 7 +++++++ src/NzbDrone.Common/OAuth/OAuthRequest.cs | 2 +- src/NzbDrone.Core/Parser/RomanNumerals/RomanNumeral.cs | 6 +++--- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index cbabf416f..a26dd842a 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -30,6 +30,13 @@ false true + + + true + + $(NoWarn);CS1591 diff --git a/src/NzbDrone.Common/OAuth/OAuthRequest.cs b/src/NzbDrone.Common/OAuth/OAuthRequest.cs index cdf7d9e1f..ceb9b9117 100644 --- a/src/NzbDrone.Common/OAuth/OAuthRequest.cs +++ b/src/NzbDrone.Common/OAuth/OAuthRequest.cs @@ -29,7 +29,7 @@ namespace NzbDrone.Common.OAuth public virtual string Version { get; set; } public virtual string SessionHandle { get; set; } - /// + /// public virtual string RequestUrl { get; set; } #if !WINRT diff --git a/src/NzbDrone.Core/Parser/RomanNumerals/RomanNumeral.cs b/src/NzbDrone.Core/Parser/RomanNumerals/RomanNumeral.cs index bec6cb7dc..7837700ec 100644 --- a/src/NzbDrone.Core/Parser/RomanNumerals/RomanNumeral.cs +++ b/src/NzbDrone.Core/Parser/RomanNumerals/RomanNumeral.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Text; namespace NzbDrone.Core.Parser.RomanNumerals @@ -209,7 +209,7 @@ namespace NzbDrone.Core.Parser.RomanNumerals /// Returns the Roman numeral that was passed in as either an Arabic numeral /// or a Roman numeral. /// - /// A representing a Roman Numeral + /// A representing a Roman Numeral public string ToRomanNumeral() { return ToString(); @@ -349,7 +349,7 @@ namespace NzbDrone.Core.Parser.RomanNumerals /// during creation. /// /// - /// A that represents a Roman Numeral. + /// A that represents a Roman Numeral. /// public override string ToString() { From f54212a80973e9065b15cf8e36647a99c2be6d90 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 24 May 2023 02:55:10 +0300 Subject: [PATCH 0006/1128] Standardize variable declaration (cherry picked from commit 909f2ded6b75998fa8e1addd0dcf849279e7b120) --- .editorconfig | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.editorconfig b/.editorconfig index 9e14400f9..2fc5f556b 100644 --- a/.editorconfig +++ b/.editorconfig @@ -36,12 +36,18 @@ dotnet_naming_style.instance_field_style.capitalization = camel_case dotnet_naming_style.instance_field_style.required_prefix = _ # Prefer "var" everywhere -csharp_style_var_for_built_in_types = true:suggestion -csharp_style_var_when_type_is_apparent = true:suggestion -csharp_style_var_elsewhere = true:suggestion +csharp_style_var_for_built_in_types = true +csharp_style_var_when_type_is_apparent = true +csharp_style_var_elsewhere = true +# Prefer "out" variables to be declared inline +csharp_style_inlined_variable_declaration = true # Using directive is unnecessary. dotnet_diagnostic.IDE0005.severity = error +# Use var instead of explicit type +dotnet_diagnostic.IDE0007.severity = error +# Inline variable declaration +dotnet_diagnostic.IDE0018.severity = error # Stylecop Rules dotnet_diagnostic.SA0001.severity = none From 0509335387507638a810958f03e7215f43eac1d5 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 23 May 2023 13:48:37 +0300 Subject: [PATCH 0007/1128] Inline 'out' variable declarations (cherry picked from commit 281add47de1d3940990156c841362125dea9cc7d) --- src/NzbDrone.Common/Cache/Cached.cs | 10 +++------- src/NzbDrone.Common/Cache/CachedDictionary.cs | 13 ++++-------- .../Extensions/TryParseExtensions.cs | 12 +++-------- .../Applications/ApplicationFactory.cs | 3 +-- .../Configuration/ConfigFileProvider.cs | 3 +-- .../Configuration/ConfigService.cs | 7 ++----- .../DownloadStation/TorrentDownloadStation.cs | 6 ++---- .../DownloadStation/UsenetDownloadStation.cs | 6 ++---- .../NzbVortexLoginResultTypeConverter.cs | 3 +-- .../NzbVortexResultTypeConverter.cs | 3 +-- .../Download/Clients/Nzbget/Nzbget.cs | 3 +-- .../Download/Clients/Nzbget/NzbgetProxy.cs | 3 +-- .../SabnzbdPriorityTypeConverter.cs | 3 +-- .../Download/Clients/Sabnzbd/SabnzbdProxy.cs | 20 +++++-------------- .../Download/Clients/Vuze/Vuze.cs | 3 +-- .../Download/DownloadClientFactory.cs | 3 +-- .../HealthCheck/HealthCheckService.cs | 3 +-- .../BroadcastheNet/BroadcastheNet.cs | 5 ++--- .../Headphones/HeadphonesRssParser.cs | 16 +++++---------- .../Definitions/Newznab/NewznabRssParser.cs | 10 +++------- .../Definitions/Torznab/TorznabRssParser.cs | 11 +++------- src/NzbDrone.Core/Indexers/IndexerFactory.cs | 3 +-- .../Indexers/XElementExtensions.cs | 5 ++--- .../Messaging/Events/EventAggregator.cs | 3 +-- .../PushBullet/PushBulletProxy.cs | 3 +-- src/NzbDrone.Core/Parser/DateTimeRoutines.cs | 9 +++------ .../Parser/RomanNumerals/RomanNumeral.cs | 7 ++----- .../RomanNumerals/RomanNumeralParser.cs | 13 ++++-------- .../DiskProviderTests/DiskProviderFixture.cs | 3 +-- src/NzbDrone.Mono/Disk/DiskProvider.cs | 8 ++------ .../Disk/SymbolicLinkResolver.cs | 4 +--- src/NzbDrone.Test.Common/LoggingTest.cs | 3 +-- src/NzbDrone.Update/UpdateApp.cs | 3 +-- src/NzbDrone.Windows/Disk/DiskProvider.cs | 15 +++----------- .../ClientSchema/SchemaBuilder.cs | 3 +-- 35 files changed, 68 insertions(+), 160 deletions(-) diff --git a/src/NzbDrone.Common/Cache/Cached.cs b/src/NzbDrone.Common/Cache/Cached.cs index a530baa55..42463f682 100644 --- a/src/NzbDrone.Common/Cache/Cached.cs +++ b/src/NzbDrone.Common/Cache/Cached.cs @@ -47,8 +47,7 @@ namespace NzbDrone.Common.Cache public T Find(string key) { - CacheItem cacheItem; - if (!_store.TryGetValue(key, out cacheItem)) + if (!_store.TryGetValue(key, out var cacheItem)) { return default(T); } @@ -76,8 +75,7 @@ namespace NzbDrone.Common.Cache public void Remove(string key) { - CacheItem value; - _store.TryRemove(key, out value); + _store.TryRemove(key, out _); } public int Count => _store.Count; @@ -88,9 +86,7 @@ namespace NzbDrone.Common.Cache lifeTime = lifeTime ?? _defaultLifeTime; - CacheItem cacheItem; - - if (_store.TryGetValue(key, out cacheItem) && !cacheItem.IsExpired()) + if (_store.TryGetValue(key, out var cacheItem) && !cacheItem.IsExpired()) { if (_rollingExpiry && lifeTime.HasValue) { diff --git a/src/NzbDrone.Common/Cache/CachedDictionary.cs b/src/NzbDrone.Common/Cache/CachedDictionary.cs index 6332f5054..922b45835 100644 --- a/src/NzbDrone.Common/Cache/CachedDictionary.cs +++ b/src/NzbDrone.Common/Cache/CachedDictionary.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; @@ -86,9 +86,7 @@ namespace NzbDrone.Common.Cache { RefreshIfExpired(); - TValue result; - - if (!_items.TryGetValue(key, out result)) + if (!_items.TryGetValue(key, out var result)) { throw new KeyNotFoundException(string.Format("Item {0} not found in cache.", key)); } @@ -100,9 +98,7 @@ namespace NzbDrone.Common.Cache { RefreshIfExpired(); - TValue result; - - _items.TryGetValue(key, out result); + _items.TryGetValue(key, out var result); return result; } @@ -128,8 +124,7 @@ namespace NzbDrone.Common.Cache public void Remove(string key) { - TValue item; - _items.TryRemove(key, out item); + _items.TryRemove(key, out _); } } } diff --git a/src/NzbDrone.Common/Extensions/TryParseExtensions.cs b/src/NzbDrone.Common/Extensions/TryParseExtensions.cs index 1ed79c319..3b9f3db49 100644 --- a/src/NzbDrone.Common/Extensions/TryParseExtensions.cs +++ b/src/NzbDrone.Common/Extensions/TryParseExtensions.cs @@ -6,9 +6,7 @@ namespace NzbDrone.Common.Extensions { public static int? ParseInt32(this string source) { - int result; - - if (int.TryParse(source, out result)) + if (int.TryParse(source, out var result)) { return result; } @@ -18,9 +16,7 @@ namespace NzbDrone.Common.Extensions public static long? ParseInt64(this string source) { - long result; - - if (long.TryParse(source, out result)) + if (long.TryParse(source, out var result)) { return result; } @@ -30,9 +26,7 @@ namespace NzbDrone.Common.Extensions public static double? ParseDouble(this string source) { - double result; - - if (double.TryParse(source.Replace(',', '.'), NumberStyles.Number, CultureInfo.InvariantCulture, out result)) + if (double.TryParse(source.Replace(',', '.'), NumberStyles.Number, CultureInfo.InvariantCulture, out var result)) { return result; } diff --git a/src/NzbDrone.Core/Applications/ApplicationFactory.cs b/src/NzbDrone.Core/Applications/ApplicationFactory.cs index 1b8dc1e2e..31386ad50 100644 --- a/src/NzbDrone.Core/Applications/ApplicationFactory.cs +++ b/src/NzbDrone.Core/Applications/ApplicationFactory.cs @@ -48,8 +48,7 @@ namespace NzbDrone.Core.Applications foreach (var application in applications) { - ApplicationStatus blockedApplicationStatus; - if (blockedApplications.TryGetValue(application.Definition.Id, out blockedApplicationStatus)) + if (blockedApplications.TryGetValue(application.Definition.Id, out var blockedApplicationStatus)) { _logger.Debug("Temporarily ignoring application {0} till {1} due to recent failures.", application.Definition.Name, blockedApplicationStatus.DisabledTill.Value.ToLocalTime()); continue; diff --git a/src/NzbDrone.Core/Configuration/ConfigFileProvider.cs b/src/NzbDrone.Core/Configuration/ConfigFileProvider.cs index ddd4a98bc..127a5325b 100644 --- a/src/NzbDrone.Core/Configuration/ConfigFileProvider.cs +++ b/src/NzbDrone.Core/Configuration/ConfigFileProvider.cs @@ -121,8 +121,7 @@ namespace NzbDrone.Core.Configuration continue; } - object currentValue; - allWithDefaults.TryGetValue(configValue.Key, out currentValue); + allWithDefaults.TryGetValue(configValue.Key, out var currentValue); if (currentValue == null) { continue; diff --git a/src/NzbDrone.Core/Configuration/ConfigService.cs b/src/NzbDrone.Core/Configuration/ConfigService.cs index 8fb717ce6..77e43f378 100644 --- a/src/NzbDrone.Core/Configuration/ConfigService.cs +++ b/src/NzbDrone.Core/Configuration/ConfigService.cs @@ -53,8 +53,7 @@ namespace NzbDrone.Core.Configuration foreach (var configValue in configValues) { - object currentValue; - allWithDefaults.TryGetValue(configValue.Key, out currentValue); + allWithDefaults.TryGetValue(configValue.Key, out var currentValue); if (currentValue == null || configValue.Value == null) { continue; @@ -211,9 +210,7 @@ namespace NzbDrone.Core.Configuration EnsureCache(); - string dbValue; - - if (_cache.TryGetValue(key, out dbValue) && dbValue != null && !string.IsNullOrEmpty(dbValue)) + if (_cache.TryGetValue(key, out var dbValue) && dbValue != null && !string.IsNullOrEmpty(dbValue)) { return dbValue; } diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs index 42b5bb1f2..ebe52b722 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs @@ -130,9 +130,8 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation protected long GetRemainingSize(DownloadStationTask torrent) { var downloadedString = torrent.Additional.Transfer["size_downloaded"]; - long downloadedSize; - if (downloadedString.IsNullOrWhiteSpace() || !long.TryParse(downloadedString, out downloadedSize)) + if (downloadedString.IsNullOrWhiteSpace() || !long.TryParse(downloadedString, out var downloadedSize)) { _logger.Debug("Torrent {0} has invalid size_downloaded: {1}", torrent.Title, downloadedString); downloadedSize = 0; @@ -144,9 +143,8 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation protected TimeSpan? GetRemainingTime(DownloadStationTask torrent) { var speedString = torrent.Additional.Transfer["speed_download"]; - long downloadSpeed; - if (speedString.IsNullOrWhiteSpace() || !long.TryParse(speedString, out downloadSpeed)) + if (speedString.IsNullOrWhiteSpace() || !long.TryParse(speedString, out var downloadSpeed)) { _logger.Debug("Torrent {0} has invalid speed_download: {1}", torrent.Title, speedString); downloadSpeed = 0; diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/UsenetDownloadStation.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/UsenetDownloadStation.cs index 2cf42704b..1759cf600 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/UsenetDownloadStation.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/UsenetDownloadStation.cs @@ -211,9 +211,8 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation protected long GetRemainingSize(DownloadStationTask task) { var downloadedString = task.Additional.Transfer["size_downloaded"]; - long downloadedSize; - if (downloadedString.IsNullOrWhiteSpace() || !long.TryParse(downloadedString, out downloadedSize)) + if (downloadedString.IsNullOrWhiteSpace() || !long.TryParse(downloadedString, out var downloadedSize)) { _logger.Debug("Task {0} has invalid size_downloaded: {1}", task.Title, downloadedString); downloadedSize = 0; @@ -225,9 +224,8 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation protected long GetDownloadSpeed(DownloadStationTask task) { var speedString = task.Additional.Transfer["speed_download"]; - long downloadSpeed; - if (speedString.IsNullOrWhiteSpace() || !long.TryParse(speedString, out downloadSpeed)) + if (speedString.IsNullOrWhiteSpace() || !long.TryParse(speedString, out var downloadSpeed)) { _logger.Debug("Task {0} has invalid speed_download: {1}", task.Title, speedString); downloadSpeed = 0; diff --git a/src/NzbDrone.Core/Download/Clients/NzbVortex/JsonConverters/NzbVortexLoginResultTypeConverter.cs b/src/NzbDrone.Core/Download/Clients/NzbVortex/JsonConverters/NzbVortexLoginResultTypeConverter.cs index e74b8f973..7f0f27de7 100644 --- a/src/NzbDrone.Core/Download/Clients/NzbVortex/JsonConverters/NzbVortexLoginResultTypeConverter.cs +++ b/src/NzbDrone.Core/Download/Clients/NzbVortex/JsonConverters/NzbVortexLoginResultTypeConverter.cs @@ -15,8 +15,7 @@ namespace NzbDrone.Core.Download.Clients.NzbVortex.JsonConverters { var result = reader.Value.ToString().Replace("_", string.Empty); - NzbVortexLoginResultType output; - Enum.TryParse(result, true, out output); + Enum.TryParse(result, true, out NzbVortexLoginResultType output); return output; } diff --git a/src/NzbDrone.Core/Download/Clients/NzbVortex/JsonConverters/NzbVortexResultTypeConverter.cs b/src/NzbDrone.Core/Download/Clients/NzbVortex/JsonConverters/NzbVortexResultTypeConverter.cs index bd63788bc..aa515abdb 100644 --- a/src/NzbDrone.Core/Download/Clients/NzbVortex/JsonConverters/NzbVortexResultTypeConverter.cs +++ b/src/NzbDrone.Core/Download/Clients/NzbVortex/JsonConverters/NzbVortexResultTypeConverter.cs @@ -15,8 +15,7 @@ namespace NzbDrone.Core.Download.Clients.NzbVortex.JsonConverters { var result = reader.Value.ToString().Replace("_", string.Empty); - NzbVortexResultType output; - Enum.TryParse(result, true, out output); + Enum.TryParse(result, true, out NzbVortexResultType output); return output; } diff --git a/src/NzbDrone.Core/Download/Clients/Nzbget/Nzbget.cs b/src/NzbDrone.Core/Download/Clients/Nzbget/Nzbget.cs index 0aa160cda..958b9efde 100644 --- a/src/NzbDrone.Core/Download/Clients/Nzbget/Nzbget.cs +++ b/src/NzbDrone.Core/Download/Clients/Nzbget/Nzbget.cs @@ -169,8 +169,7 @@ namespace NzbDrone.Core.Download.Clients.Nzbget var config = _proxy.GetConfig(Settings); var keepHistory = config.GetValueOrDefault("KeepHistory", "7"); - int value; - if (!int.TryParse(keepHistory, NumberStyles.None, CultureInfo.InvariantCulture, out value) || value == 0) + if (!int.TryParse(keepHistory, NumberStyles.None, CultureInfo.InvariantCulture, out var value) || value == 0) { return new NzbDroneValidationFailure(string.Empty, "NzbGet setting KeepHistory should be greater than 0") { diff --git a/src/NzbDrone.Core/Download/Clients/Nzbget/NzbgetProxy.cs b/src/NzbDrone.Core/Download/Clients/Nzbget/NzbgetProxy.cs index 76cff3220..1d0b6d644 100644 --- a/src/NzbDrone.Core/Download/Clients/Nzbget/NzbgetProxy.cs +++ b/src/NzbDrone.Core/Download/Clients/Nzbget/NzbgetProxy.cs @@ -177,11 +177,10 @@ namespace NzbDrone.Core.Download.Clients.Nzbget var queue = GetQueue(settings); var history = GetHistory(settings); - int nzbId; NzbgetQueueItem queueItem; NzbgetHistoryItem historyItem; - if (id.Length < 10 && int.TryParse(id, out nzbId)) + if (id.Length < 10 && int.TryParse(id, out var nzbId)) { // Download wasn't grabbed by Prowlarr, so the id is the NzbId reported by nzbget. queueItem = queue.SingleOrDefault(h => h.NzbId == nzbId); diff --git a/src/NzbDrone.Core/Download/Clients/Sabnzbd/JsonConverters/SabnzbdPriorityTypeConverter.cs b/src/NzbDrone.Core/Download/Clients/Sabnzbd/JsonConverters/SabnzbdPriorityTypeConverter.cs index 246b5b558..f29317251 100644 --- a/src/NzbDrone.Core/Download/Clients/Sabnzbd/JsonConverters/SabnzbdPriorityTypeConverter.cs +++ b/src/NzbDrone.Core/Download/Clients/Sabnzbd/JsonConverters/SabnzbdPriorityTypeConverter.cs @@ -15,8 +15,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd.JsonConverters { var queuePriority = reader.Value.ToString(); - SabnzbdPriority output; - Enum.TryParse(queuePriority, out output); + Enum.TryParse(queuePriority, out SabnzbdPriority output); return output; } diff --git a/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdProxy.cs b/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdProxy.cs index de610ae9f..41fd428df 100644 --- a/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdProxy.cs +++ b/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdProxy.cs @@ -52,9 +52,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd request.AddFormUpload("name", filename, nzbData, "application/x-nzb"); - SabnzbdAddResponse response; - - if (!Json.TryDeserialize(ProcessRequest(request, settings), out response)) + if (!Json.TryDeserialize(ProcessRequest(request, settings), out var response)) { response = new SabnzbdAddResponse(); response.Status = true; @@ -71,9 +69,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd request.AddQueryParam("cat", category); request.AddQueryParam("priority", priority); - SabnzbdAddResponse response; - - if (!Json.TryDeserialize(ProcessRequest(request, settings), out response)) + if (!Json.TryDeserialize(ProcessRequest(request, settings), out var response)) { response = new SabnzbdAddResponse(); response.Status = true; @@ -96,9 +92,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd { var request = BuildRequest("version", settings); - SabnzbdVersionResponse response; - - if (!Json.TryDeserialize(ProcessRequest(request, settings), out response)) + if (!Json.TryDeserialize(ProcessRequest(request, settings), out var response)) { response = new SabnzbdVersionResponse(); } @@ -157,9 +151,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd var request = BuildRequest("retry", settings); request.AddQueryParam("value", id); - SabnzbdRetryResponse response; - - if (!Json.TryDeserialize(ProcessRequest(request, settings), out response)) + if (!Json.TryDeserialize(ProcessRequest(request, settings), out var response)) { response = new SabnzbdRetryResponse(); response.Status = true; @@ -230,9 +222,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd private void CheckForError(HttpResponse response) { - SabnzbdJsonError result; - - if (!Json.TryDeserialize(response.Content, out result)) + if (!Json.TryDeserialize(response.Content, out var result)) { //Handle plain text responses from SAB result = new SabnzbdJsonError(); diff --git a/src/NzbDrone.Core/Download/Clients/Vuze/Vuze.cs b/src/NzbDrone.Core/Download/Clients/Vuze/Vuze.cs index bd1f4c37b..66e4dedf1 100644 --- a/src/NzbDrone.Core/Download/Clients/Vuze/Vuze.cs +++ b/src/NzbDrone.Core/Download/Clients/Vuze/Vuze.cs @@ -46,8 +46,7 @@ namespace NzbDrone.Core.Download.Clients.Vuze _logger.Debug("Vuze protocol version information: {0}", versionString); - int version; - if (!int.TryParse(versionString, out version) || version < MINIMUM_SUPPORTED_PROTOCOL_VERSION) + if (!int.TryParse(versionString, out var version) || version < MINIMUM_SUPPORTED_PROTOCOL_VERSION) { { return new ValidationFailure(string.Empty, "Protocol version not supported, use Vuze 5.0.0.0 or higher with Vuze Web Remote plugin."); diff --git a/src/NzbDrone.Core/Download/DownloadClientFactory.cs b/src/NzbDrone.Core/Download/DownloadClientFactory.cs index f5cd9f005..d692d36ee 100644 --- a/src/NzbDrone.Core/Download/DownloadClientFactory.cs +++ b/src/NzbDrone.Core/Download/DownloadClientFactory.cs @@ -61,8 +61,7 @@ namespace NzbDrone.Core.Download foreach (var client in clients) { - DownloadClientStatus downloadClientStatus; - if (blockedIndexers.TryGetValue(client.Definition.Id, out downloadClientStatus)) + if (blockedIndexers.TryGetValue(client.Definition.Id, out var downloadClientStatus)) { _logger.Debug("Temporarily ignoring download client {0} till {1} due to recent failures.", client.Definition.Name, downloadClientStatus.DisabledTill.Value.ToLocalTime()); continue; diff --git a/src/NzbDrone.Core/HealthCheck/HealthCheckService.cs b/src/NzbDrone.Core/HealthCheck/HealthCheckService.cs index 11ae42719..78e60e314 100644 --- a/src/NzbDrone.Core/HealthCheck/HealthCheckService.cs +++ b/src/NzbDrone.Core/HealthCheck/HealthCheckService.cs @@ -160,8 +160,7 @@ namespace NzbDrone.Core.HealthCheck _isRunningHealthChecksAfterGracePeriod = false; } - IEventDrivenHealthCheck[] checks; - if (!_eventDrivenHealthChecks.TryGetValue(message.GetType(), out checks)) + if (!_eventDrivenHealthChecks.TryGetValue(message.GetType(), out var checks)) { return; } diff --git a/src/NzbDrone.Core/Indexers/Definitions/BroadcastheNet/BroadcastheNet.cs b/src/NzbDrone.Core/Indexers/Definitions/BroadcastheNet/BroadcastheNet.cs index 88449dbfa..596810d7f 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/BroadcastheNet/BroadcastheNet.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/BroadcastheNet/BroadcastheNet.cs @@ -36,10 +36,9 @@ namespace NzbDrone.Core.Indexers.BroadcastheNet var releaseInfo = _indexerStatusService.GetLastRssSyncReleaseInfo(Definition.Id); if (releaseInfo != null) { - int torrentID; - if (int.TryParse(releaseInfo.Guid.Replace("BTN-", string.Empty), out torrentID)) + if (int.TryParse(releaseInfo.Guid.Replace("BTN-", string.Empty), out var torrentId)) { - requestGenerator.LastRecentTorrentID = torrentID; + requestGenerator.LastRecentTorrentID = torrentId; } } diff --git a/src/NzbDrone.Core/Indexers/Definitions/Headphones/HeadphonesRssParser.cs b/src/NzbDrone.Core/Indexers/Definitions/Headphones/HeadphonesRssParser.cs index f17d0e260..8e0292f3c 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Headphones/HeadphonesRssParser.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Headphones/HeadphonesRssParser.cs @@ -150,10 +150,8 @@ namespace NzbDrone.Core.Indexers.Headphones protected override long GetSize(XElement item) { - long size; - var sizeString = TryGetNewznabAttribute(item, "size"); - if (!sizeString.IsNullOrWhiteSpace() && long.TryParse(sizeString, out size)) + if (!sizeString.IsNullOrWhiteSpace() && long.TryParse(sizeString, out var size)) { return size; } @@ -189,9 +187,8 @@ namespace NzbDrone.Core.Indexers.Headphones protected virtual int GetImdbId(XElement item) { var imdbIdString = TryGetNewznabAttribute(item, "imdb"); - int imdbId; - if (!imdbIdString.IsNullOrWhiteSpace() && int.TryParse(imdbIdString, out imdbId)) + if (!imdbIdString.IsNullOrWhiteSpace() && int.TryParse(imdbIdString, out var imdbId)) { return imdbId; } @@ -202,9 +199,8 @@ namespace NzbDrone.Core.Indexers.Headphones protected virtual int GetGrabs(XElement item) { var grabsString = TryGetNewznabAttribute(item, "grabs"); - int grabs; - if (!grabsString.IsNullOrWhiteSpace() && int.TryParse(grabsString, out grabs)) + if (!grabsString.IsNullOrWhiteSpace() && int.TryParse(grabsString, out var grabs)) { return grabs; } @@ -215,9 +211,8 @@ namespace NzbDrone.Core.Indexers.Headphones protected virtual int GetFiles(XElement item) { var filesString = TryGetNewznabAttribute(item, "files"); - int files; - if (!filesString.IsNullOrWhiteSpace() && int.TryParse(filesString, out files)) + if (!filesString.IsNullOrWhiteSpace() && int.TryParse(filesString, out var files)) { return files; } @@ -228,9 +223,8 @@ namespace NzbDrone.Core.Indexers.Headphones protected virtual int GetImdbYear(XElement item) { var imdbYearString = TryGetNewznabAttribute(item, "imdbyear"); - int imdbYear; - if (!imdbYearString.IsNullOrWhiteSpace() && int.TryParse(imdbYearString, out imdbYear)) + if (!imdbYearString.IsNullOrWhiteSpace() && int.TryParse(imdbYearString, out var imdbYear)) { return imdbYear; } diff --git a/src/NzbDrone.Core/Indexers/Definitions/Newznab/NewznabRssParser.cs b/src/NzbDrone.Core/Indexers/Definitions/Newznab/NewznabRssParser.cs index 063c6c951..87bea73ed 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Newznab/NewznabRssParser.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Newznab/NewznabRssParser.cs @@ -178,10 +178,8 @@ namespace NzbDrone.Core.Indexers.Newznab protected override long GetSize(XElement item) { - long size; - var sizeString = TryGetNewznabAttribute(item, "size"); - if (!sizeString.IsNullOrWhiteSpace() && long.TryParse(sizeString, out size)) + if (!sizeString.IsNullOrWhiteSpace() && long.TryParse(sizeString, out var size)) { return size; } @@ -241,9 +239,8 @@ namespace NzbDrone.Core.Indexers.Newznab foreach (var attr in attributes) { var idString = TryGetNewznabAttribute(item, attr); - int idInt; - if (!idString.IsNullOrWhiteSpace() && int.TryParse(idString, out idInt)) + if (!idString.IsNullOrWhiteSpace() && int.TryParse(idString, out var idInt)) { return idInt; } @@ -260,9 +257,8 @@ namespace NzbDrone.Core.Indexers.Newznab protected virtual int GetImdbYear(XElement item) { var imdbYearString = TryGetNewznabAttribute(item, "imdbyear"); - int imdbYear; - if (!imdbYearString.IsNullOrWhiteSpace() && int.TryParse(imdbYearString, out imdbYear)) + if (!imdbYearString.IsNullOrWhiteSpace() && int.TryParse(imdbYearString, out var imdbYear)) { return imdbYear; } diff --git a/src/NzbDrone.Core/Indexers/Definitions/Torznab/TorznabRssParser.cs b/src/NzbDrone.Core/Indexers/Definitions/Torznab/TorznabRssParser.cs index d0823f980..9bd544aad 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Torznab/TorznabRssParser.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Torznab/TorznabRssParser.cs @@ -149,10 +149,8 @@ namespace NzbDrone.Core.Indexers.Torznab protected override long GetSize(XElement item) { - long size; - var sizeString = TryGetTorznabAttribute(item, "size"); - if (!sizeString.IsNullOrWhiteSpace() && long.TryParse(sizeString, out size)) + if (!sizeString.IsNullOrWhiteSpace() && long.TryParse(sizeString, out var size)) { return size; } @@ -298,9 +296,7 @@ namespace NzbDrone.Core.Indexers.Torznab { var attr = TryGetTorznabAttribute(item, key, defaultValue.ToString()); - float result = 0; - - if (float.TryParse(attr, out result)) + if (float.TryParse(attr, out var result)) { return result; } @@ -330,9 +326,8 @@ namespace NzbDrone.Core.Indexers.Torznab foreach (var attr in attributes) { var idString = TryGetTorznabAttribute(item, attr); - int idInt; - if (!idString.IsNullOrWhiteSpace() && int.TryParse(idString, out idInt)) + if (!idString.IsNullOrWhiteSpace() && int.TryParse(idString, out var idInt)) { return idInt; } diff --git a/src/NzbDrone.Core/Indexers/IndexerFactory.cs b/src/NzbDrone.Core/Indexers/IndexerFactory.cs index 93eab492c..9bb810805 100644 --- a/src/NzbDrone.Core/Indexers/IndexerFactory.cs +++ b/src/NzbDrone.Core/Indexers/IndexerFactory.cs @@ -245,8 +245,7 @@ namespace NzbDrone.Core.Indexers foreach (var indexer in indexers) { - IndexerStatus blockedIndexerStatus; - if (blockedIndexers.TryGetValue(indexer.Definition.Id, out blockedIndexerStatus)) + if (blockedIndexers.TryGetValue(indexer.Definition.Id, out var blockedIndexerStatus)) { _logger.Debug("Temporarily ignoring indexer {0} till {1} due to recent failures.", indexer.Definition.Name, blockedIndexerStatus.DisabledTill.Value.ToLocalTime()); continue; diff --git a/src/NzbDrone.Core/Indexers/XElementExtensions.cs b/src/NzbDrone.Core/Indexers/XElementExtensions.cs index 1c4ca6634..f2fb9ef84 100644 --- a/src/NzbDrone.Core/Indexers/XElementExtensions.cs +++ b/src/NzbDrone.Core/Indexers/XElementExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Globalization; using System.Linq; @@ -37,8 +37,7 @@ namespace NzbDrone.Core.Indexers { try { - DateTime result; - if (!DateTime.TryParse(dateString, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AssumeUniversal, out result)) + if (!DateTime.TryParse(dateString, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AssumeUniversal, out var result)) { dateString = RemoveTimeZoneRegex.Replace(dateString, ""); result = DateTime.Parse(dateString, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AssumeUniversal); diff --git a/src/NzbDrone.Core/Messaging/Events/EventAggregator.cs b/src/NzbDrone.Core/Messaging/Events/EventAggregator.cs index 78bc5f15c..39d9dea25 100644 --- a/src/NzbDrone.Core/Messaging/Events/EventAggregator.cs +++ b/src/NzbDrone.Core/Messaging/Events/EventAggregator.cs @@ -75,8 +75,7 @@ namespace NzbDrone.Core.Messaging.Events EventSubscribers subscribers; lock (_eventSubscribers) { - object target; - if (!_eventSubscribers.TryGetValue(eventName, out target)) + if (!_eventSubscribers.TryGetValue(eventName, out var target)) { _eventSubscribers[eventName] = target = new EventSubscribers(_serviceFactory); } diff --git a/src/NzbDrone.Core/Notifications/PushBullet/PushBulletProxy.cs b/src/NzbDrone.Core/Notifications/PushBullet/PushBulletProxy.cs index da36b9970..fbe78dacf 100644 --- a/src/NzbDrone.Core/Notifications/PushBullet/PushBulletProxy.cs +++ b/src/NzbDrone.Core/Notifications/PushBullet/PushBulletProxy.cs @@ -152,14 +152,13 @@ namespace NzbDrone.Core.Notifications.PushBullet private HttpRequestBuilder BuildDeviceRequest(string deviceId) { var requestBuilder = new HttpRequestBuilder(PUSH_URL).Post(); - long integerId; if (deviceId.IsNullOrWhiteSpace()) { return requestBuilder; } - if (long.TryParse(deviceId, out integerId)) + if (long.TryParse(deviceId, out var integerId)) { requestBuilder.AddFormParameter("device_id", integerId); } diff --git a/src/NzbDrone.Core/Parser/DateTimeRoutines.cs b/src/NzbDrone.Core/Parser/DateTimeRoutines.cs index d0aea643a..c5280b6e6 100644 --- a/src/NzbDrone.Core/Parser/DateTimeRoutines.cs +++ b/src/NzbDrone.Core/Parser/DateTimeRoutines.cs @@ -111,9 +111,8 @@ namespace NzbDrone.Core.Parser { parsed_date_time = null; - ParsedDateTime parsed_date; ParsedDateTime parsed_time; - if (!TryParseDate(str, default_format, out parsed_date)) + if (!TryParseDate(str, default_format, out var parsed_date)) { if (!TryParseTime(str, default_format, out parsed_time, null)) { @@ -314,8 +313,7 @@ namespace NzbDrone.Core.Parser m = Regex.Match(str, @"(?<=^|[^\d])(?'year'\d{2}|\d{4})\s*(?'separator'[\-])\s*(?'month'\d{1,2})\s*\'separator'+\s*(?'day'\d{1,2})(?=$|[^\d])", RegexOptions.Compiled | RegexOptions.IgnoreCase); if (m.Success) { - DateTime date; - if (!ConvertToDate(int.Parse(m.Groups["year"].Value), int.Parse(m.Groups["month"].Value), int.Parse(m.Groups["day"].Value), out date)) + if (!ConvertToDate(int.Parse(m.Groups["year"].Value), int.Parse(m.Groups["month"].Value), int.Parse(m.Groups["day"].Value), out var date)) { return false; } @@ -417,8 +415,7 @@ namespace NzbDrone.Core.Parser year = DefaultDate.Year; } - DateTime date; - if (!ConvertToDate(year, month, int.Parse(m.Groups["day"].Value), out date)) + if (!ConvertToDate(year, month, int.Parse(m.Groups["day"].Value), out var date)) { return false; } diff --git a/src/NzbDrone.Core/Parser/RomanNumerals/RomanNumeral.cs b/src/NzbDrone.Core/Parser/RomanNumerals/RomanNumeral.cs index 7837700ec..ff3f03596 100644 --- a/src/NzbDrone.Core/Parser/RomanNumerals/RomanNumeral.cs +++ b/src/NzbDrone.Core/Parser/RomanNumerals/RomanNumeral.cs @@ -52,9 +52,7 @@ namespace NzbDrone.Core.Parser.RomanNumerals /// The roman numeral. public RomanNumeral(string romanNumeral) { - int value; - - if (TryParse(romanNumeral, out value)) + if (TryParse(romanNumeral, out var value)) { _value = value; } @@ -312,10 +310,9 @@ namespace NzbDrone.Core.Parser.RomanNumerals } else if (obj is string) { - int value; var numeral = obj as string; - if (TryParse(numeral, out value)) + if (TryParse(numeral, out var value)) { return _value.CompareTo(value); } diff --git a/src/NzbDrone.Core/Parser/RomanNumerals/RomanNumeralParser.cs b/src/NzbDrone.Core/Parser/RomanNumerals/RomanNumeralParser.cs index e8d6368d7..a898fc174 100644 --- a/src/NzbDrone.Core/Parser/RomanNumerals/RomanNumeralParser.cs +++ b/src/NzbDrone.Core/Parser/RomanNumerals/RomanNumeralParser.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; @@ -28,8 +28,7 @@ namespace NzbDrone.Core.Parser.RomanNumerals _simpleArabicNumeralMappings = new Dictionary(); foreach (int arabicNumeral in Enumerable.Range(1, DICTIONARY_PREPOPULATION_SIZE + 1)) { - string romanNumeralAsString, arabicNumeralAsString; - GenerateRomanNumerals(arabicNumeral, out romanNumeralAsString, out arabicNumeralAsString); + GenerateRomanNumerals(arabicNumeral, out var romanNumeralAsString, out var arabicNumeralAsString); ArabicRomanNumeral arm = new ArabicRomanNumeral(arabicNumeral, arabicNumeralAsString, romanNumeralAsString); _arabicRomanNumeralsMapping.Add(arm); @@ -51,9 +50,7 @@ namespace NzbDrone.Core.Parser.RomanNumerals HashSet additionalArabicRomanNumerals = new HashSet(); foreach (int arabicNumeral in Enumerable.Range(offset, length)) { - string romanNumeral; - string arabicNumeralAsString; - GenerateRomanNumerals(arabicNumeral, out romanNumeral, out arabicNumeralAsString); + GenerateRomanNumerals(arabicNumeral, out var romanNumeral, out var arabicNumeralAsString); ArabicRomanNumeral arm = new ArabicRomanNumeral(arabicNumeral, arabicNumeralAsString, romanNumeral); additionalArabicRomanNumerals.Add(arm); } @@ -129,9 +126,7 @@ namespace NzbDrone.Core.Parser.RomanNumerals Dictionary moreNumerals = new Dictionary(); foreach (int arabicNumeral in Enumerable.Range(offset, length)) { - string romanNumeral; - string arabicNumeralAsString; - GenerateRomanNumerals(arabicNumeral, out romanNumeral, out arabicNumeralAsString); + GenerateRomanNumerals(arabicNumeral, out var romanNumeral, out _); SimpleArabicNumeral san = new SimpleArabicNumeral(arabicNumeral); SimpleRomanNumeral srn = new SimpleRomanNumeral(romanNumeral); moreNumerals.Add(san, srn); diff --git a/src/NzbDrone.Mono.Test/DiskProviderTests/DiskProviderFixture.cs b/src/NzbDrone.Mono.Test/DiskProviderTests/DiskProviderFixture.cs index cb804ecf4..25a02fd43 100644 --- a/src/NzbDrone.Mono.Test/DiskProviderTests/DiskProviderFixture.cs +++ b/src/NzbDrone.Mono.Test/DiskProviderTests/DiskProviderFixture.cs @@ -57,8 +57,7 @@ namespace NzbDrone.Mono.Test.DiskProviderTests protected void SetWritePermissionsInternal(string path, bool writable, bool setgid) { // Remove Write permissions, we're still owner so we can clean it up, but we'll have to do that explicitly. - Stat stat; - Syscall.stat(path, out stat); + Syscall.stat(path, out var stat); FilePermissions mode = stat.st_mode; if (writable) diff --git a/src/NzbDrone.Mono/Disk/DiskProvider.cs b/src/NzbDrone.Mono/Disk/DiskProvider.cs index 26b1db082..0cbdf9cfa 100644 --- a/src/NzbDrone.Mono/Disk/DiskProvider.cs +++ b/src/NzbDrone.Mono/Disk/DiskProvider.cs @@ -474,9 +474,7 @@ namespace NzbDrone.Mono.Disk return UNCHANGED_ID; } - uint userId; - - if (uint.TryParse(user, out userId)) + if (uint.TryParse(user, out var userId)) { return userId; } @@ -498,9 +496,7 @@ namespace NzbDrone.Mono.Disk return UNCHANGED_ID; } - uint groupId; - - if (uint.TryParse(group, out groupId)) + if (uint.TryParse(group, out var groupId)) { return groupId; } diff --git a/src/NzbDrone.Mono/Disk/SymbolicLinkResolver.cs b/src/NzbDrone.Mono/Disk/SymbolicLinkResolver.cs index a837b59a6..103bdf430 100644 --- a/src/NzbDrone.Mono/Disk/SymbolicLinkResolver.cs +++ b/src/NzbDrone.Mono/Disk/SymbolicLinkResolver.cs @@ -83,9 +83,7 @@ namespace NzbDrone.Mono.Disk private bool TryFollowFirstSymbolicLink(ref string path) { - string[] dirs; - int lastIndex; - GetPathComponents(path, out dirs, out lastIndex); + GetPathComponents(path, out var dirs, out var lastIndex); if (lastIndex == 0) { diff --git a/src/NzbDrone.Test.Common/LoggingTest.cs b/src/NzbDrone.Test.Common/LoggingTest.cs index 396581f55..0085937ff 100644 --- a/src/NzbDrone.Test.Common/LoggingTest.cs +++ b/src/NzbDrone.Test.Common/LoggingTest.cs @@ -23,8 +23,7 @@ namespace NzbDrone.Test.Common { LogManager.Configuration = new LoggingConfiguration(); - var logOutput = TestLogOutput.Console; - Enum.TryParse(Environment.GetEnvironmentVariable("PROWLARR_TESTS_LOG_OUTPUT"), out logOutput); + Enum.TryParse(Environment.GetEnvironmentVariable("PROWLARR_TESTS_LOG_OUTPUT"), out var logOutput); RegisterSentryLogger(); diff --git a/src/NzbDrone.Update/UpdateApp.cs b/src/NzbDrone.Update/UpdateApp.cs index abbfd0f6d..ce4e92656 100644 --- a/src/NzbDrone.Update/UpdateApp.cs +++ b/src/NzbDrone.Update/UpdateApp.cs @@ -99,8 +99,7 @@ namespace NzbDrone.Update private int ParseProcessId(string arg) { - int id; - if (!int.TryParse(arg, out id) || id <= 0) + if (!int.TryParse(arg, out var id) || id <= 0) { throw new ArgumentOutOfRangeException("arg", "Invalid process ID"); } diff --git a/src/NzbDrone.Windows/Disk/DiskProvider.cs b/src/NzbDrone.Windows/Disk/DiskProvider.cs index f65dae3d0..ebdf026e1 100644 --- a/src/NzbDrone.Windows/Disk/DiskProvider.cs +++ b/src/NzbDrone.Windows/Disk/DiskProvider.cs @@ -92,8 +92,7 @@ namespace NzbDrone.Windows.Disk PropagationFlags.InheritOnly, controlType); - bool modified; - directorySecurity.ModifyAccessRule(AccessControlModification.Add, accessRule, out modified); + directorySecurity.ModifyAccessRule(AccessControlModification.Add, accessRule, out var modified); if (modified) { @@ -142,11 +141,7 @@ namespace NzbDrone.Windows.Disk folderName += '\\'; } - ulong free = 0; - ulong dummy1 = 0; - ulong dummy2 = 0; - - if (GetDiskFreeSpaceEx(folderName, out free, out dummy1, out dummy2)) + if (GetDiskFreeSpaceEx(folderName, out var free, out var dummy1, out var dummy2)) { return (long)free; } @@ -163,11 +158,7 @@ namespace NzbDrone.Windows.Disk folderName += '\\'; } - ulong total = 0; - ulong dummy1 = 0; - ulong dummy2 = 0; - - if (GetDiskFreeSpaceEx(folderName, out dummy1, out total, out dummy2)) + if (GetDiskFreeSpaceEx(folderName, out var dummy1, out var total, out var dummy2)) { return (long)total; } diff --git a/src/Prowlarr.Http/ClientSchema/SchemaBuilder.cs b/src/Prowlarr.Http/ClientSchema/SchemaBuilder.cs index 37c8b2afb..698a7ffc8 100644 --- a/src/Prowlarr.Http/ClientSchema/SchemaBuilder.cs +++ b/src/Prowlarr.Http/ClientSchema/SchemaBuilder.cs @@ -67,8 +67,7 @@ namespace Prowlarr.Http.ClientSchema { lock (_mappings) { - FieldMapping[] result; - if (!_mappings.TryGetValue(type, out result)) + if (!_mappings.TryGetValue(type, out var result)) { result = GetFieldMapping(type, "", v => v); From 360827708fae3d50f40c2aff99192415e90170bb Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 23 May 2023 13:52:39 +0300 Subject: [PATCH 0008/1128] Use 'var' instead of explicit type (cherry picked from commit 12374f7f0038e5b25548f5ab3f71122410832393) --- .../AutomationTest.cs | 2 +- .../PageModel/PageBase.cs | 2 +- .../CacheTests/CachedFixture.cs | 10 +++---- .../ConfigFileProviderTest.cs | 10 +++---- .../DirectoryLookupServiceFixture.cs | 6 ++--- .../Http/HttpClientFixture.cs | 4 +-- src/NzbDrone.Common/ArchiveService.cs | 14 +++++----- src/NzbDrone.Common/Disk/OsPath.cs | 6 ++--- .../Extensions/DateTimeExtensions.cs | 4 +-- .../Extensions/IEnumerableExtensions.cs | 4 +-- .../Extensions/LevenstheinExtensions.cs | 8 +++--- .../Extensions/StringExtensions.cs | 4 +-- src/NzbDrone.Common/HashUtil.cs | 6 ++--- .../Http/Dispatchers/ManagedHttpDispatcher.cs | 2 +- src/NzbDrone.Common/Http/HttpUri.cs | 2 +- .../Http/Proxy/HttpProxySettings.cs | 2 +- .../Instrumentation/CleansingJsonVisitor.cs | 4 +-- .../Instrumentation/NzbDroneLogger.cs | 2 +- .../Serializer/Newtonsoft.Json/JsonVisitor.cs | 6 ++--- .../UnderscoreStringEnumConverter.cs | 4 +-- .../System.Text.Json/STJVersionConverter.cs | 2 +- .../LimitedConcurrencyLevelTaskScheduler.cs | 2 +- src/NzbDrone.Console/ConsoleApp.cs | 2 +- .../Datastore/BasicRepositoryFixture.cs | 2 +- src/NzbDrone.Core.Test/FluentTest.cs | 4 +-- .../IndexerTests/PTPTests/PTPFixture.cs | 2 +- .../DatabaseTargetFixture.cs | 2 +- .../Configuration/ConfigFileProvider.cs | 2 +- .../Datastore/BasicRepository.cs | 2 +- .../Datastore/Converters/CommandConverter.cs | 2 +- .../Migration/Framework/SqliteSchemaDumper.cs | 4 +-- .../Download/Clients/Deluge/DelugeProxy.cs | 2 +- .../FreeboxDownloadEncoding.cs | 6 ++--- .../Download/Clients/Nzbget/Nzbget.cs | 2 +- .../Clients/QBittorrent/QBittorrent.cs | 2 +- .../SabnzbdStringArrayConverter.cs | 2 +- .../Download/Extensions/XmlExtensions.cs | 4 +-- src/NzbDrone.Core/Fluent.cs | 10 +++---- .../IndexerStats/IndexerStatisticsService.cs | 2 +- .../IndexerDefinitionUpdateService.cs | 2 +- .../BroadcastheNet/BroadcastheNetParser.cs | 2 +- src/NzbDrone.Core/Indexers/HttpIndexerBase.cs | 2 +- .../Messaging/Commands/CommandExecutor.cs | 6 ++--- .../Messaging/Commands/CommandQueueManager.cs | 2 +- src/NzbDrone.Core/Parser/DateTimeUtil.cs | 2 +- .../Parser/RomanNumerals/RomanNumeral.cs | 10 +++---- .../RomanNumerals/RomanNumeralParser.cs | 26 +++++++++---------- src/NzbDrone.Core/Parser/StringUtil.cs | 4 +-- .../DiskProviderTests/DiskProviderFixture.cs | 2 +- .../ReleaseFileVersionAdapter.cs | 2 +- .../ConcurrencyCounter.cs | 2 +- .../ExceptionVerification.cs | 6 ++--- .../StartNzbDroneService.cs | 6 ++--- .../UpdateEngine/InstallUpdateService.cs | 2 +- .../DiskProviderTests/FreeSpaceFixture.cs | 4 +-- .../Logs/LogFileControllerBase.cs | 2 +- .../Profiles/App/AppProfileSchemaModule.cs | 2 +- .../ClientSchema/SchemaBuilder.cs | 2 +- .../Extensions/RequestExtensions.cs | 8 +++--- .../ServiceInstall/ServiceHelper.cs | 2 +- .../ServiceUninstall/ServiceHelper.cs | 2 +- 61 files changed, 128 insertions(+), 128 deletions(-) diff --git a/src/NzbDrone.Automation.Test/AutomationTest.cs b/src/NzbDrone.Automation.Test/AutomationTest.cs index 4253095b9..ae1bcc5e1 100644 --- a/src/NzbDrone.Automation.Test/AutomationTest.cs +++ b/src/NzbDrone.Automation.Test/AutomationTest.cs @@ -67,7 +67,7 @@ namespace NzbDrone.Automation.Test { try { - Screenshot image = ((ITakesScreenshot)driver).GetScreenshot(); + var image = ((ITakesScreenshot)driver).GetScreenshot(); image.SaveAsFile($"./{name}_test_screenshot.png", ScreenshotImageFormat.Png); } catch (Exception ex) diff --git a/src/NzbDrone.Automation.Test/PageModel/PageBase.cs b/src/NzbDrone.Automation.Test/PageModel/PageBase.cs index 4c9a17581..a32084602 100644 --- a/src/NzbDrone.Automation.Test/PageModel/PageBase.cs +++ b/src/NzbDrone.Automation.Test/PageModel/PageBase.cs @@ -36,7 +36,7 @@ namespace NzbDrone.Automation.Test.PageModel { try { - IWebElement element = d.FindElement(By.ClassName("followingBalls")); + var element = d.FindElement(By.ClassName("followingBalls")); return !element.Displayed; } catch (NoSuchElementException) diff --git a/src/NzbDrone.Common.Test/CacheTests/CachedFixture.cs b/src/NzbDrone.Common.Test/CacheTests/CachedFixture.cs index 7c892047d..bdbd45aca 100644 --- a/src/NzbDrone.Common.Test/CacheTests/CachedFixture.cs +++ b/src/NzbDrone.Common.Test/CacheTests/CachedFixture.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Threading; using FluentAssertions; using NUnit.Framework; @@ -65,9 +65,9 @@ namespace NzbDrone.Common.Test.CacheTests [Test] public void should_store_null() { - int hitCount = 0; + var hitCount = 0; - for (int i = 0; i < 10; i++) + for (var i = 0; i < 10; i++) { _cachedString.Get("key", () => { @@ -83,10 +83,10 @@ namespace NzbDrone.Common.Test.CacheTests [Platform(Exclude = "MacOsX")] public void should_honor_ttl() { - int hitCount = 0; + var hitCount = 0; _cachedString = new Cached(); - for (int i = 0; i < 10; i++) + for (var i = 0; i < 10; i++) { _cachedString.Get("key", () => diff --git a/src/NzbDrone.Common.Test/ConfigFileProviderTest.cs b/src/NzbDrone.Common.Test/ConfigFileProviderTest.cs index 91564beb3..dd32e187d 100644 --- a/src/NzbDrone.Common.Test/ConfigFileProviderTest.cs +++ b/src/NzbDrone.Common.Test/ConfigFileProviderTest.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using FluentAssertions; using Moq; using NUnit.Framework; @@ -142,7 +142,7 @@ namespace NzbDrone.Common.Test [Test] public void SaveDictionary_should_save_proper_value() { - int port = 20555; + var port = 20555; var dic = Subject.GetConfigDictionary(); dic["Port"] = 20555; @@ -155,9 +155,9 @@ namespace NzbDrone.Common.Test [Test] public void SaveDictionary_should_only_save_specified_values() { - int port = 20555; - int origSslPort = 20551; - int sslPort = 20552; + var port = 20555; + var origSslPort = 20551; + var sslPort = 20552; var dic = Subject.GetConfigDictionary(); dic["Port"] = port; diff --git a/src/NzbDrone.Common.Test/DiskTests/DirectoryLookupServiceFixture.cs b/src/NzbDrone.Common.Test/DiskTests/DirectoryLookupServiceFixture.cs index 78aa99f7d..1dc4256ee 100644 --- a/src/NzbDrone.Common.Test/DiskTests/DirectoryLookupServiceFixture.cs +++ b/src/NzbDrone.Common.Test/DiskTests/DirectoryLookupServiceFixture.cs @@ -42,7 +42,7 @@ namespace NzbDrone.Common.Test.DiskTests [Test] public void should_not_contain_recycling_bin_for_root_of_drive() { - string root = @"C:\".AsOsAgnostic(); + var root = @"C:\".AsOsAgnostic(); SetupFolders(root); Mocker.GetMock() @@ -55,7 +55,7 @@ namespace NzbDrone.Common.Test.DiskTests [Test] public void should_not_contain_system_volume_information() { - string root = @"C:\".AsOsAgnostic(); + var root = @"C:\".AsOsAgnostic(); SetupFolders(root); Mocker.GetMock() @@ -68,7 +68,7 @@ namespace NzbDrone.Common.Test.DiskTests [Test] public void should_not_contain_recycling_bin_or_system_volume_information_for_root_of_drive() { - string root = @"C:\".AsOsAgnostic(); + var root = @"C:\".AsOsAgnostic(); SetupFolders(root); Mocker.GetMock() diff --git a/src/NzbDrone.Common.Test/Http/HttpClientFixture.cs b/src/NzbDrone.Common.Test/Http/HttpClientFixture.cs index 9b48e77ca..4181057d6 100644 --- a/src/NzbDrone.Common.Test/Http/HttpClientFixture.cs +++ b/src/NzbDrone.Common.Test/Http/HttpClientFixture.cs @@ -788,7 +788,7 @@ namespace NzbDrone.Common.Test.Http try { // the date is bad in the below - should be 13-Jul-2026 - string malformedCookie = @"__cfduid=d29e686a9d65800021c66faca0a29b4261436890790; expires=Mon, 13-Jul-26 16:19:50 GMT; path=/; HttpOnly"; + var malformedCookie = @"__cfduid=d29e686a9d65800021c66faca0a29b4261436890790; expires=Mon, 13-Jul-26 16:19:50 GMT; path=/; HttpOnly"; var requestSet = new HttpRequestBuilder($"https://{_httpBinHost}/response-headers") .AddQueryParam("Set-Cookie", malformedCookie) .Build(); @@ -822,7 +822,7 @@ namespace NzbDrone.Common.Test.Http { try { - string url = $"https://{_httpBinHost}/response-headers?Set-Cookie={Uri.EscapeDataString(malformedCookie)}"; + var url = $"https://{_httpBinHost}/response-headers?Set-Cookie={Uri.EscapeDataString(malformedCookie)}"; var requestSet = new HttpRequest(url); requestSet.AllowAutoRedirect = false; diff --git a/src/NzbDrone.Common/ArchiveService.cs b/src/NzbDrone.Common/ArchiveService.cs index 2dee4d822..4cd6f6835 100644 --- a/src/NzbDrone.Common/ArchiveService.cs +++ b/src/NzbDrone.Common/ArchiveService.cs @@ -74,17 +74,17 @@ namespace NzbDrone.Common continue; // Ignore directories } - string entryFileName = zipEntry.Name; + var entryFileName = zipEntry.Name; // to remove the folder from the entry:- entryFileName = Path.GetFileName(entryFileName); // Optionally match entrynames against a selection list here to skip as desired. // The unpacked length is available in the zipEntry.Size property. - byte[] buffer = new byte[4096]; // 4K is optimum - Stream zipStream = zipFile.GetInputStream(zipEntry); + var buffer = new byte[4096]; // 4K is optimum + var zipStream = zipFile.GetInputStream(zipEntry); // Manipulate the output filename here as desired. - string fullZipToPath = Path.Combine(destination, entryFileName); - string directoryName = Path.GetDirectoryName(fullZipToPath); + var fullZipToPath = Path.Combine(destination, entryFileName); + var directoryName = Path.GetDirectoryName(fullZipToPath); if (directoryName.Length > 0) { Directory.CreateDirectory(directoryName); @@ -93,7 +93,7 @@ namespace NzbDrone.Common // Unzip file in buffered chunks. This is just as fast as unpacking to a buffer the full size // of the file, but does not waste memory. // The "using" will close the stream even if an exception occurs. - using (FileStream streamWriter = File.Create(fullZipToPath)) + using (var streamWriter = File.Create(fullZipToPath)) { StreamUtils.Copy(zipStream, streamWriter, buffer); } @@ -106,7 +106,7 @@ namespace NzbDrone.Common Stream inStream = File.OpenRead(compressedFile); Stream gzipStream = new GZipInputStream(inStream); - TarArchive tarArchive = TarArchive.CreateInputTarArchive(gzipStream, null); + var tarArchive = TarArchive.CreateInputTarArchive(gzipStream, null); tarArchive.ExtractContents(destination); tarArchive.Close(); diff --git a/src/NzbDrone.Common/Disk/OsPath.cs b/src/NzbDrone.Common/Disk/OsPath.cs index 8d8dcf2f9..f6f01fccf 100644 --- a/src/NzbDrone.Common/Disk/OsPath.cs +++ b/src/NzbDrone.Common/Disk/OsPath.cs @@ -255,7 +255,7 @@ namespace NzbDrone.Common.Disk var stringComparison = (Kind == OsPathKind.Windows || other.Kind == OsPathKind.Windows) ? StringComparison.InvariantCultureIgnoreCase : StringComparison.InvariantCulture; - for (int i = 0; i < leftFragments.Length; i++) + for (var i = 0; i < leftFragments.Length; i++) { if (!string.Equals(leftFragments[i], rightFragments[i], stringComparison)) { @@ -372,12 +372,12 @@ namespace NzbDrone.Common.Disk var newFragments = new List(); - for (int j = i; j < rightFragments.Length; j++) + for (var j = i; j < rightFragments.Length; j++) { newFragments.Add(".."); } - for (int j = i; j < leftFragments.Length; j++) + for (var j = i; j < leftFragments.Length; j++) { newFragments.Add(leftFragments[j]); } diff --git a/src/NzbDrone.Common/Extensions/DateTimeExtensions.cs b/src/NzbDrone.Common/Extensions/DateTimeExtensions.cs index 57f8aac71..69e2e5e17 100644 --- a/src/NzbDrone.Common/Extensions/DateTimeExtensions.cs +++ b/src/NzbDrone.Common/Extensions/DateTimeExtensions.cs @@ -36,14 +36,14 @@ namespace NzbDrone.Common.Extensions public static bool IsValidDate(this string dateTime) { - DateTime.TryParse(dateTime, out DateTime result); + DateTime.TryParse(dateTime, out var result); return !result.Equals(default(DateTime)); } public static bool IsFutureDate(this string dateTime) { - DateTime.TryParse(dateTime, out DateTime result); + DateTime.TryParse(dateTime, out var result); return !result.Equals(default(DateTime)) && result.After(DateTime.Now); } diff --git a/src/NzbDrone.Common/Extensions/IEnumerableExtensions.cs b/src/NzbDrone.Common/Extensions/IEnumerableExtensions.cs index d18e58e51..9e5385593 100644 --- a/src/NzbDrone.Common/Extensions/IEnumerableExtensions.cs +++ b/src/NzbDrone.Common/Extensions/IEnumerableExtensions.cs @@ -126,9 +126,9 @@ namespace NzbDrone.Common.Extensions private static IEnumerable InternalDropLast(IEnumerable source, int n) { - Queue buffer = new Queue(n + 1); + var buffer = new Queue(n + 1); - foreach (T x in source) + foreach (var x in source) { buffer.Enqueue(x); diff --git a/src/NzbDrone.Common/Extensions/LevenstheinExtensions.cs b/src/NzbDrone.Common/Extensions/LevenstheinExtensions.cs index 825525457..eb20ce7b0 100644 --- a/src/NzbDrone.Common/Extensions/LevenstheinExtensions.cs +++ b/src/NzbDrone.Common/Extensions/LevenstheinExtensions.cs @@ -21,7 +21,7 @@ namespace NzbDrone.Common.Extensions return text.Length * costDelete; } - int[] matrix = new int[other.Length + 1]; + var matrix = new int[other.Length + 1]; for (var i = 1; i < matrix.Length; i++) { @@ -30,13 +30,13 @@ namespace NzbDrone.Common.Extensions for (var i = 0; i < text.Length; i++) { - int topLeft = matrix[0]; + var topLeft = matrix[0]; matrix[0] = matrix[0] + costDelete; for (var j = 0; j < other.Length; j++) { - int top = matrix[j]; - int left = matrix[j + 1]; + var top = matrix[j]; + var left = matrix[j + 1]; var sumIns = top + costInsert; var sumDel = left + costDelete; diff --git a/src/NzbDrone.Common/Extensions/StringExtensions.cs b/src/NzbDrone.Common/Extensions/StringExtensions.cs index 495bfc6ac..b36f81c40 100644 --- a/src/NzbDrone.Common/Extensions/StringExtensions.cs +++ b/src/NzbDrone.Common/Extensions/StringExtensions.cs @@ -198,13 +198,13 @@ namespace NzbDrone.Common.Extensions public static string CleanFileName(this string name) { - string result = name; + var result = name; string[] badCharacters = { "\\", "/", "<", ">", "?", "*", ":", "|", "\"" }; string[] goodCharacters = { "+", "+", "", "", "!", "-", "-", "", "" }; result = result.Replace(": ", " - "); - for (int i = 0; i < badCharacters.Length; i++) + for (var i = 0; i < badCharacters.Length; i++) { result = result.Replace(badCharacters[i], goodCharacters[i]); } diff --git a/src/NzbDrone.Common/HashUtil.cs b/src/NzbDrone.Common/HashUtil.cs index 3c9144023..372b875a0 100644 --- a/src/NzbDrone.Common/HashUtil.cs +++ b/src/NzbDrone.Common/HashUtil.cs @@ -8,9 +8,9 @@ namespace NzbDrone.Common { public static string CalculateCrc(string input) { - uint mCrc = 0xffffffff; - byte[] bytes = Encoding.UTF8.GetBytes(input); - foreach (byte myByte in bytes) + var mCrc = 0xffffffff; + var bytes = Encoding.UTF8.GetBytes(input); + foreach (var myByte in bytes) { mCrc ^= (uint)myByte << 24; for (var i = 0; i < 8; i++) diff --git a/src/NzbDrone.Common/Http/Dispatchers/ManagedHttpDispatcher.cs b/src/NzbDrone.Common/Http/Dispatchers/ManagedHttpDispatcher.cs index 098e47288..1530c85e9 100644 --- a/src/NzbDrone.Common/Http/Dispatchers/ManagedHttpDispatcher.cs +++ b/src/NzbDrone.Common/Http/Dispatchers/ManagedHttpDispatcher.cs @@ -127,7 +127,7 @@ namespace NzbDrone.Common.Http.Dispatchers headers.Add(responseMessage.Content.Headers.ToNameValueCollection()); - CookieContainer responseCookies = new CookieContainer(); + var responseCookies = new CookieContainer(); if (responseMessage.Headers.TryGetValues("Set-Cookie", out var cookieHeaders)) { diff --git a/src/NzbDrone.Common/Http/HttpUri.cs b/src/NzbDrone.Common/Http/HttpUri.cs index 45d2b98b5..2277ed60d 100644 --- a/src/NzbDrone.Common/Http/HttpUri.cs +++ b/src/NzbDrone.Common/Http/HttpUri.cs @@ -22,7 +22,7 @@ namespace NzbDrone.Common.Http public HttpUri(string scheme, string host, int? port, string path, string query, string fragment) { - StringBuilder builder = new StringBuilder(); + var builder = new StringBuilder(); if (scheme.IsNotNullOrWhiteSpace()) { diff --git a/src/NzbDrone.Common/Http/Proxy/HttpProxySettings.cs b/src/NzbDrone.Common/Http/Proxy/HttpProxySettings.cs index ef59c9c0f..022d8adee 100644 --- a/src/NzbDrone.Common/Http/Proxy/HttpProxySettings.cs +++ b/src/NzbDrone.Common/Http/Proxy/HttpProxySettings.cs @@ -31,7 +31,7 @@ namespace NzbDrone.Common.Http.Proxy if (!string.IsNullOrWhiteSpace(BypassFilter)) { var hostlist = BypassFilter.Split(','); - for (int i = 0; i < hostlist.Length; i++) + for (var i = 0; i < hostlist.Length; i++) { if (hostlist[i].StartsWith("*")) { diff --git a/src/NzbDrone.Common/Instrumentation/CleansingJsonVisitor.cs b/src/NzbDrone.Common/Instrumentation/CleansingJsonVisitor.cs index 1e32d399f..34df2dff3 100644 --- a/src/NzbDrone.Common/Instrumentation/CleansingJsonVisitor.cs +++ b/src/NzbDrone.Common/Instrumentation/CleansingJsonVisitor.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Linq; using NzbDrone.Common.Serializer; namespace NzbDrone.Common.Instrumentation @@ -16,7 +16,7 @@ namespace NzbDrone.Common.Instrumentation } } - foreach (JToken token in json) + foreach (var token in json) { Visit(token); } diff --git a/src/NzbDrone.Common/Instrumentation/NzbDroneLogger.cs b/src/NzbDrone.Common/Instrumentation/NzbDroneLogger.cs index 7d8cfaf83..2493e35cf 100644 --- a/src/NzbDrone.Common/Instrumentation/NzbDroneLogger.cs +++ b/src/NzbDrone.Common/Instrumentation/NzbDroneLogger.cs @@ -94,7 +94,7 @@ namespace NzbDrone.Common.Instrumentation private static void RegisterDebugger() { - DebuggerTarget target = new DebuggerTarget(); + var target = new DebuggerTarget(); target.Name = "debuggerLogger"; target.Layout = "[${level}] [${threadid}] ${logger}: ${message} ${onexception:inner=${newline}${newline}[v${assembly-version}] ${exception:format=ToString}${newline}${exception:format=Data}${newline}}"; diff --git a/src/NzbDrone.Common/Serializer/Newtonsoft.Json/JsonVisitor.cs b/src/NzbDrone.Common/Serializer/Newtonsoft.Json/JsonVisitor.cs index 0e69a0ae0..093de5b99 100644 --- a/src/NzbDrone.Common/Serializer/Newtonsoft.Json/JsonVisitor.cs +++ b/src/NzbDrone.Common/Serializer/Newtonsoft.Json/JsonVisitor.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Linq; namespace NzbDrone.Common.Serializer { @@ -60,7 +60,7 @@ namespace NzbDrone.Common.Serializer public virtual void Visit(JArray json) { - foreach (JToken token in json) + foreach (var token in json) { Visit(token); } @@ -72,7 +72,7 @@ namespace NzbDrone.Common.Serializer public virtual void Visit(JObject json) { - foreach (JProperty property in json.Properties()) + foreach (var property in json.Properties()) { Visit(property); } diff --git a/src/NzbDrone.Common/Serializer/Newtonsoft.Json/UnderscoreStringEnumConverter.cs b/src/NzbDrone.Common/Serializer/Newtonsoft.Json/UnderscoreStringEnumConverter.cs index 772f5640c..b202253b6 100644 --- a/src/NzbDrone.Common/Serializer/Newtonsoft.Json/UnderscoreStringEnumConverter.cs +++ b/src/NzbDrone.Common/Serializer/Newtonsoft.Json/UnderscoreStringEnumConverter.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Text; using Newtonsoft.Json; @@ -42,7 +42,7 @@ namespace NzbDrone.Common.Serializer var enumText = value.ToString(); var builder = new StringBuilder(enumText.Length + 4); builder.Append(char.ToLower(enumText[0])); - for (int i = 1; i < enumText.Length; i++) + for (var i = 1; i < enumText.Length; i++) { if (char.IsUpper(enumText[i])) { diff --git a/src/NzbDrone.Common/Serializer/System.Text.Json/STJVersionConverter.cs b/src/NzbDrone.Common/Serializer/System.Text.Json/STJVersionConverter.cs index 70ad492c3..6fd024f7d 100644 --- a/src/NzbDrone.Common/Serializer/System.Text.Json/STJVersionConverter.cs +++ b/src/NzbDrone.Common/Serializer/System.Text.Json/STJVersionConverter.cs @@ -18,7 +18,7 @@ namespace NzbDrone.Common.Serializer { try { - Version v = new Version(reader.GetString()); + var v = new Version(reader.GetString()); return v; } catch (Exception) diff --git a/src/NzbDrone.Common/TPL/LimitedConcurrencyLevelTaskScheduler.cs b/src/NzbDrone.Common/TPL/LimitedConcurrencyLevelTaskScheduler.cs index a6137486b..ba9d804d3 100644 --- a/src/NzbDrone.Common/TPL/LimitedConcurrencyLevelTaskScheduler.cs +++ b/src/NzbDrone.Common/TPL/LimitedConcurrencyLevelTaskScheduler.cs @@ -137,7 +137,7 @@ namespace NzbDrone.Common.TPL /// An enumerable of the tasks currently scheduled. protected sealed override IEnumerable GetScheduledTasks() { - bool lockTaken = false; + var lockTaken = false; try { Monitor.TryEnter(_tasks, ref lockTaken); diff --git a/src/NzbDrone.Console/ConsoleApp.cs b/src/NzbDrone.Console/ConsoleApp.cs index cff2fd254..8f284d003 100644 --- a/src/NzbDrone.Console/ConsoleApp.cs +++ b/src/NzbDrone.Console/ConsoleApp.cs @@ -110,7 +110,7 @@ namespace NzbDrone.Console } System.Console.WriteLine("Non-recoverable failure, waiting for user intervention..."); - for (int i = 0; i < 3600; i++) + for (var i = 0; i < 3600; i++) { System.Threading.Thread.Sleep(1000); if (!System.Console.IsInputRedirected && System.Console.KeyAvailable) diff --git a/src/NzbDrone.Core.Test/Datastore/BasicRepositoryFixture.cs b/src/NzbDrone.Core.Test/Datastore/BasicRepositoryFixture.cs index 9f0cf4b92..8070f9fda 100644 --- a/src/NzbDrone.Core.Test/Datastore/BasicRepositoryFixture.cs +++ b/src/NzbDrone.Core.Test/Datastore/BasicRepositoryFixture.cs @@ -197,7 +197,7 @@ namespace NzbDrone.Core.Test.Datastore Subject.SetFields(_basicList, x => x.Interval); - for (int i = 0; i < _basicList.Count; i++) + for (var i = 0; i < _basicList.Count; i++) { _basicList[i].LastExecution = executionBackup[i]; } diff --git a/src/NzbDrone.Core.Test/FluentTest.cs b/src/NzbDrone.Core.Test/FluentTest.cs index a17f142e3..1747c44f2 100644 --- a/src/NzbDrone.Core.Test/FluentTest.cs +++ b/src/NzbDrone.Core.Test/FluentTest.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Text; using FluentAssertions; @@ -57,7 +57,7 @@ namespace NzbDrone.Core.Test [Test] public void ToBestDateTime_DayOfWeek() { - for (int i = 2; i < 7; i++) + for (var i = 2; i < 7; i++) { var dateTime = DateTime.Today.AddDays(i); diff --git a/src/NzbDrone.Core.Test/IndexerTests/PTPTests/PTPFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/PTPTests/PTPFixture.cs index c27972e0f..307585d29 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/PTPTests/PTPFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/PTPTests/PTPFixture.cs @@ -33,7 +33,7 @@ namespace NzbDrone.Core.Test.IndexerTests.PTPTests { var authResponse = new PassThePopcornAuthResponse { Result = "Ok" }; - System.IO.StringWriter authStream = new System.IO.StringWriter(); + var authStream = new System.IO.StringWriter(); Json.Serialize(authResponse, authStream); var responseJson = ReadAllText(fileName); diff --git a/src/NzbDrone.Core.Test/InstrumentationTests/DatabaseTargetFixture.cs b/src/NzbDrone.Core.Test/InstrumentationTests/DatabaseTargetFixture.cs index 705ebf767..738f4c2bc 100644 --- a/src/NzbDrone.Core.Test/InstrumentationTests/DatabaseTargetFixture.cs +++ b/src/NzbDrone.Core.Test/InstrumentationTests/DatabaseTargetFixture.cs @@ -47,7 +47,7 @@ namespace NzbDrone.Core.Test.InstrumentationTests public void write_long_log() { var message = string.Empty; - for (int i = 0; i < 100; i++) + for (var i = 0; i < 100; i++) { message += Guid.NewGuid(); } diff --git a/src/NzbDrone.Core/Configuration/ConfigFileProvider.cs b/src/NzbDrone.Core/Configuration/ConfigFileProvider.cs index 127a5325b..c2731e084 100644 --- a/src/NzbDrone.Core/Configuration/ConfigFileProvider.cs +++ b/src/NzbDrone.Core/Configuration/ConfigFileProvider.cs @@ -144,7 +144,7 @@ namespace NzbDrone.Core.Configuration { const string defaultValue = "*"; - string bindAddress = GetValue("BindAddress", defaultValue); + var bindAddress = GetValue("BindAddress", defaultValue); if (string.IsNullOrWhiteSpace(bindAddress)) { return defaultValue; diff --git a/src/NzbDrone.Core/Datastore/BasicRepository.cs b/src/NzbDrone.Core/Datastore/BasicRepository.cs index 659a69e7f..8e1b92b77 100644 --- a/src/NzbDrone.Core/Datastore/BasicRepository.cs +++ b/src/NzbDrone.Core/Datastore/BasicRepository.cs @@ -196,7 +196,7 @@ namespace NzbDrone.Core.Datastore using (var conn = _database.OpenConnection()) { - using (IDbTransaction tran = conn.BeginTransaction(IsolationLevel.ReadCommitted)) + using (var tran = conn.BeginTransaction(IsolationLevel.ReadCommitted)) { foreach (var model in models) { diff --git a/src/NzbDrone.Core/Datastore/Converters/CommandConverter.cs b/src/NzbDrone.Core/Datastore/Converters/CommandConverter.cs index e2f77c6f0..790464f3f 100644 --- a/src/NzbDrone.Core/Datastore/Converters/CommandConverter.cs +++ b/src/NzbDrone.Core/Datastore/Converters/CommandConverter.cs @@ -18,7 +18,7 @@ namespace NzbDrone.Core.Datastore.Converters } string contract; - using (JsonDocument body = JsonDocument.Parse(stringValue)) + using (var body = JsonDocument.Parse(stringValue)) { contract = body.RootElement.GetProperty("name").GetString(); } diff --git a/src/NzbDrone.Core/Datastore/Migration/Framework/SqliteSchemaDumper.cs b/src/NzbDrone.Core/Datastore/Migration/Framework/SqliteSchemaDumper.cs index 4ae4e6e68..d0a661751 100644 --- a/src/NzbDrone.Core/Datastore/Migration/Framework/SqliteSchemaDumper.cs +++ b/src/NzbDrone.Core/Datastore/Migration/Framework/SqliteSchemaDumper.cs @@ -201,7 +201,7 @@ namespace NzbDrone.Core.Datastore.Migration.Framework public virtual IList ReadDbSchema() { - IList tables = ReadTables(); + var tables = ReadTables(); foreach (var table in tables) { table.Indexes = ReadIndexes(table.SchemaName, table.Name); @@ -264,7 +264,7 @@ namespace NzbDrone.Core.Datastore.Migration.Framework protected virtual IList ReadIndexes(string schemaName, string tableName) { var sqlCommand = string.Format(@"SELECT type, name, sql FROM sqlite_master WHERE tbl_name = '{0}' AND type = 'index' AND name NOT LIKE 'sqlite_auto%';", tableName); - DataTable table = Read(sqlCommand).Tables[0]; + var table = Read(sqlCommand).Tables[0]; IList indexes = new List(); diff --git a/src/NzbDrone.Core/Download/Clients/Deluge/DelugeProxy.cs b/src/NzbDrone.Core/Download/Clients/Deluge/DelugeProxy.cs index 6396052c3..77b3d1b3d 100644 --- a/src/NzbDrone.Core/Download/Clients/Deluge/DelugeProxy.cs +++ b/src/NzbDrone.Core/Download/Clients/Deluge/DelugeProxy.cs @@ -203,7 +203,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge private JsonRpcRequestBuilder BuildRequest(DelugeSettings settings) { - string url = HttpRequestBuilder.BuildBaseUrl(settings.UseSsl, settings.Host, settings.Port, settings.UrlBase); + var url = HttpRequestBuilder.BuildBaseUrl(settings.UseSsl, settings.Host, settings.Port, settings.UrlBase); var requestBuilder = new JsonRpcRequestBuilder(url); requestBuilder.LogResponseContent = true; diff --git a/src/NzbDrone.Core/Download/Clients/FreeboxDownload/FreeboxDownloadEncoding.cs b/src/NzbDrone.Core/Download/Clients/FreeboxDownload/FreeboxDownloadEncoding.cs index 0e12570aa..7c1ef310b 100644 --- a/src/NzbDrone.Core/Download/Clients/FreeboxDownload/FreeboxDownloadEncoding.cs +++ b/src/NzbDrone.Core/Download/Clients/FreeboxDownload/FreeboxDownloadEncoding.cs @@ -1,4 +1,4 @@ -namespace NzbDrone.Core.Download.Clients.FreeboxDownload +namespace NzbDrone.Core.Download.Clients.FreeboxDownload { public static class EncodingForBase64 { @@ -9,7 +9,7 @@ return null; } - byte[] textAsBytes = System.Text.Encoding.UTF8.GetBytes(text); + var textAsBytes = System.Text.Encoding.UTF8.GetBytes(text); return System.Convert.ToBase64String(textAsBytes); } @@ -20,7 +20,7 @@ return null; } - byte[] textAsBytes = System.Convert.FromBase64String(encodedText); + var textAsBytes = System.Convert.FromBase64String(encodedText); return System.Text.Encoding.UTF8.GetString(textAsBytes); } } diff --git a/src/NzbDrone.Core/Download/Clients/Nzbget/Nzbget.cs b/src/NzbDrone.Core/Download/Clients/Nzbget/Nzbget.cs index 958b9efde..b286bf922 100644 --- a/src/NzbDrone.Core/Download/Clients/Nzbget/Nzbget.cs +++ b/src/NzbDrone.Core/Download/Clients/Nzbget/Nzbget.cs @@ -70,7 +70,7 @@ namespace NzbDrone.Core.Download.Clients.Nzbget protected IEnumerable GetCategories(Dictionary config) { - for (int i = 1; i < 100; i++) + for (var i = 1; i < 100; i++) { var name = config.GetValueOrDefault("Category" + i + ".Name"); diff --git a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs index 95dd9e30b..edc9b2fd4 100644 --- a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs +++ b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs @@ -257,7 +257,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent return null; } - Dictionary labels = Proxy.GetLabels(Settings); + var labels = Proxy.GetLabels(Settings); foreach (var category in Categories) { diff --git a/src/NzbDrone.Core/Download/Clients/Sabnzbd/JsonConverters/SabnzbdStringArrayConverter.cs b/src/NzbDrone.Core/Download/Clients/Sabnzbd/JsonConverters/SabnzbdStringArrayConverter.cs index bca2353a1..b5ab193ce 100644 --- a/src/NzbDrone.Core/Download/Clients/Sabnzbd/JsonConverters/SabnzbdStringArrayConverter.cs +++ b/src/NzbDrone.Core/Download/Clients/Sabnzbd/JsonConverters/SabnzbdStringArrayConverter.cs @@ -14,7 +14,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd.JsonConverters var stringArray = (string[])value; writer.WriteStartArray(); - for (int i = 0; i < stringArray.Length; i++) + for (var i = 0; i < stringArray.Length; i++) { writer.WriteValue(stringArray[i]); } diff --git a/src/NzbDrone.Core/Download/Extensions/XmlExtensions.cs b/src/NzbDrone.Core/Download/Extensions/XmlExtensions.cs index bce66c8bc..b4571d6e8 100644 --- a/src/NzbDrone.Core/Download/Extensions/XmlExtensions.cs +++ b/src/NzbDrone.Core/Download/Extensions/XmlExtensions.cs @@ -32,13 +32,13 @@ namespace NzbDrone.Core.Download.Extensions public static long ElementAsLong(this XElement element, XName name) { var el = element.Element(name); - return long.TryParse(el?.Value, out long value) ? value : default; + return long.TryParse(el?.Value, out var value) ? value : default; } public static int ElementAsInt(this XElement element, XName name) { var el = element.Element(name); - return int.TryParse(el?.Value, out int value) ? value : default(int); + return int.TryParse(el?.Value, out var value) ? value : default(int); } public static int GetIntResponse(this XDocument document) diff --git a/src/NzbDrone.Core/Fluent.cs b/src/NzbDrone.Core/Fluent.cs index cc507b242..37a775e96 100644 --- a/src/NzbDrone.Core/Fluent.cs +++ b/src/NzbDrone.Core/Fluent.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -95,17 +95,17 @@ namespace NzbDrone.Core } var cs = s.ToCharArray(); - int length = 0; - int i = 0; + var length = 0; + var i = 0; while (i < cs.Length) { - int charSize = 1; + var charSize = 1; if (i < (cs.Length - 1) && char.IsSurrogate(cs[i])) { charSize = 2; } - int byteSize = Encoding.UTF8.GetByteCount(cs, i, charSize); + var byteSize = Encoding.UTF8.GetByteCount(cs, i, charSize); if ((byteSize + length) <= maxLength) { i = i + charSize; diff --git a/src/NzbDrone.Core/IndexerStats/IndexerStatisticsService.cs b/src/NzbDrone.Core/IndexerStats/IndexerStatisticsService.cs index e0a9bace7..e5274bee7 100644 --- a/src/NzbDrone.Core/IndexerStats/IndexerStatisticsService.cs +++ b/src/NzbDrone.Core/IndexerStats/IndexerStatisticsService.cs @@ -54,7 +54,7 @@ namespace NzbDrone.Core.IndexerStats var sortedEvents = indexer.OrderBy(v => v.Date) .ThenBy(v => v.Id) .ToArray(); - int temp = 0; + var temp = 0; var elapsedTimeEvents = sortedEvents.Where(h => int.TryParse(h.Data.GetValueOrDefault("elapsedTime"), out temp)) .Select(h => temp); diff --git a/src/NzbDrone.Core/IndexerVersions/IndexerDefinitionUpdateService.cs b/src/NzbDrone.Core/IndexerVersions/IndexerDefinitionUpdateService.cs index 7f0c82811..6b2c4dc91 100644 --- a/src/NzbDrone.Core/IndexerVersions/IndexerDefinitionUpdateService.cs +++ b/src/NzbDrone.Core/IndexerVersions/IndexerDefinitionUpdateService.cs @@ -293,7 +293,7 @@ namespace NzbDrone.Core.IndexerVersions _httpClient.DownloadFile($"https://indexers.prowlarr.com/{DEFINITION_BRANCH}/{DEFINITION_VERSION}/package.zip", saveFile); - using (ZipArchive archive = ZipFile.OpenRead(saveFile)) + using (var archive = ZipFile.OpenRead(saveFile)) { archive.ExtractToDirectory(definitionsFolder, true); } diff --git a/src/NzbDrone.Core/Indexers/Definitions/BroadcastheNet/BroadcastheNetParser.cs b/src/NzbDrone.Core/Indexers/Definitions/BroadcastheNet/BroadcastheNetParser.cs index 242c51a27..d06bef210 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/BroadcastheNet/BroadcastheNetParser.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/BroadcastheNet/BroadcastheNetParser.cs @@ -60,7 +60,7 @@ namespace NzbDrone.Core.Indexers.BroadcastheNet throw new IndexerException(indexerResponse, "Indexer API returned an internal server error"); } - JsonRpcResponse jsonResponse = new HttpResponse>(indexerHttpResponse).Resource; + var jsonResponse = new HttpResponse>(indexerHttpResponse).Resource; if (jsonResponse.Error != null || jsonResponse.Result == null) { diff --git a/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs b/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs index bb0615fb2..81c6f396a 100644 --- a/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs +++ b/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs @@ -276,7 +276,7 @@ namespace NzbDrone.Core.Indexers var pageableRequestChain = pageableRequestChainSelector(generator); - for (int i = 0; i < pageableRequestChain.Tiers; i++) + for (var i = 0; i < pageableRequestChain.Tiers; i++) { var pageableRequests = pageableRequestChain.GetTier(i); diff --git a/src/NzbDrone.Core/Messaging/Commands/CommandExecutor.cs b/src/NzbDrone.Core/Messaging/Commands/CommandExecutor.cs index 05b031a6a..45b3fd2e3 100644 --- a/src/NzbDrone.Core/Messaging/Commands/CommandExecutor.cs +++ b/src/NzbDrone.Core/Messaging/Commands/CommandExecutor.cs @@ -129,8 +129,8 @@ namespace NzbDrone.Core.Messaging.Commands _cancellationTokenSource = new CancellationTokenSource(); var envLimit = Environment.GetEnvironmentVariable("THREAD_LIMIT") ?? $"{THREAD_LIMIT}"; - int threadLimit = THREAD_LIMIT; - if (int.TryParse(envLimit, out int parsedLimit)) + var threadLimit = THREAD_LIMIT; + if (int.TryParse(envLimit, out var parsedLimit)) { threadLimit = parsedLimit; } @@ -140,7 +140,7 @@ namespace NzbDrone.Core.Messaging.Commands _logger.Info("Starting {} threads for tasks.", threadLimit); - for (int i = 0; i < threadLimit + 1; i++) + for (var i = 0; i < threadLimit + 1; i++) { var thread = new Thread(ExecuteCommands); thread.Start(); diff --git a/src/NzbDrone.Core/Messaging/Commands/CommandQueueManager.cs b/src/NzbDrone.Core/Messaging/Commands/CommandQueueManager.cs index 44edc9009..12ce4cb06 100644 --- a/src/NzbDrone.Core/Messaging/Commands/CommandQueueManager.cs +++ b/src/NzbDrone.Core/Messaging/Commands/CommandQueueManager.cs @@ -138,7 +138,7 @@ namespace NzbDrone.Core.Messaging.Commands public CommandModel Push(string commandName, DateTime? lastExecutionTime, DateTime? lastStartTime, CommandPriority priority = CommandPriority.Normal, CommandTrigger trigger = CommandTrigger.Unspecified) { - dynamic command = GetCommand(commandName); + var command = GetCommand(commandName); command.LastExecutionTime = lastExecutionTime; command.LastStartTime = lastStartTime; command.Trigger = trigger; diff --git a/src/NzbDrone.Core/Parser/DateTimeUtil.cs b/src/NzbDrone.Core/Parser/DateTimeUtil.cs index a69cbcd24..71f243c66 100644 --- a/src/NzbDrone.Core/Parser/DateTimeUtil.cs +++ b/src/NzbDrone.Core/Parser/DateTimeUtil.cs @@ -109,7 +109,7 @@ namespace NzbDrone.Core.Parser DateTimeRoutines.DateTimeFormat.USDate; if (DateTimeRoutines.TryParseDateOrTime( - str, dtFormat, out DateTimeRoutines.ParsedDateTime dt)) + str, dtFormat, out var dt)) { return dt.DateTime; } diff --git a/src/NzbDrone.Core/Parser/RomanNumerals/RomanNumeral.cs b/src/NzbDrone.Core/Parser/RomanNumerals/RomanNumeral.cs index ff3f03596..19795c643 100644 --- a/src/NzbDrone.Core/Parser/RomanNumerals/RomanNumeral.cs +++ b/src/NzbDrone.Core/Parser/RomanNumerals/RomanNumeral.cs @@ -95,9 +95,9 @@ namespace NzbDrone.Core.Parser.RomanNumerals } text = text.ToUpper(); - int len = 0; + var len = 0; - for (int i = 0; i < 3; i++) + for (var i = 0; i < 3; i++) { if (text.StartsWith(Thousands[i])) { @@ -113,7 +113,7 @@ namespace NzbDrone.Core.Parser.RomanNumerals len = 0; } - for (int i = 0; i < 9; i++) + for (var i = 0; i < 9; i++) { if (text.StartsWith(Hundreds[i])) { @@ -129,7 +129,7 @@ namespace NzbDrone.Core.Parser.RomanNumerals len = 0; } - for (int i = 0; i < 9; i++) + for (var i = 0; i < 9; i++) { if (text.StartsWith(Tens[i])) { @@ -145,7 +145,7 @@ namespace NzbDrone.Core.Parser.RomanNumerals len = 0; } - for (int i = 0; i < 9; i++) + for (var i = 0; i < 9; i++) { if (text.StartsWith(Units[i])) { diff --git a/src/NzbDrone.Core/Parser/RomanNumerals/RomanNumeralParser.cs b/src/NzbDrone.Core/Parser/RomanNumerals/RomanNumeralParser.cs index a898fc174..4ca73cf12 100644 --- a/src/NzbDrone.Core/Parser/RomanNumerals/RomanNumeralParser.cs +++ b/src/NzbDrone.Core/Parser/RomanNumerals/RomanNumeralParser.cs @@ -26,32 +26,32 @@ namespace NzbDrone.Core.Parser.RomanNumerals _arabicRomanNumeralsMapping = new HashSet(); _simpleArabicNumeralMappings = new Dictionary(); - foreach (int arabicNumeral in Enumerable.Range(1, DICTIONARY_PREPOPULATION_SIZE + 1)) + foreach (var arabicNumeral in Enumerable.Range(1, DICTIONARY_PREPOPULATION_SIZE + 1)) { GenerateRomanNumerals(arabicNumeral, out var romanNumeralAsString, out var arabicNumeralAsString); - ArabicRomanNumeral arm = new ArabicRomanNumeral(arabicNumeral, arabicNumeralAsString, romanNumeralAsString); + var arm = new ArabicRomanNumeral(arabicNumeral, arabicNumeralAsString, romanNumeralAsString); _arabicRomanNumeralsMapping.Add(arm); - SimpleArabicNumeral sam = new SimpleArabicNumeral(arabicNumeral); - SimpleRomanNumeral srm = new SimpleRomanNumeral(romanNumeralAsString); + var sam = new SimpleArabicNumeral(arabicNumeral); + var srm = new SimpleRomanNumeral(romanNumeralAsString); _simpleArabicNumeralMappings.Add(sam, srm); } } private static void GenerateRomanNumerals(int arabicNumeral, out string romanNumeral, out string arabicNumeralAsString) { - RomanNumeral romanNumeralObject = new RomanNumeral(arabicNumeral); + var romanNumeralObject = new RomanNumeral(arabicNumeral); romanNumeral = romanNumeralObject.ToRomanNumeral(); arabicNumeralAsString = Convert.ToString(arabicNumeral); } private static HashSet GenerateAdditionalMappings(int offset, int length) { - HashSet additionalArabicRomanNumerals = new HashSet(); - foreach (int arabicNumeral in Enumerable.Range(offset, length)) + var additionalArabicRomanNumerals = new HashSet(); + foreach (var arabicNumeral in Enumerable.Range(offset, length)) { GenerateRomanNumerals(arabicNumeral, out var romanNumeral, out var arabicNumeralAsString); - ArabicRomanNumeral arm = new ArabicRomanNumeral(arabicNumeral, arabicNumeralAsString, romanNumeral); + var arm = new ArabicRomanNumeral(arabicNumeral, arabicNumeralAsString, romanNumeral); additionalArabicRomanNumerals.Add(arm); } @@ -78,7 +78,7 @@ namespace NzbDrone.Core.Parser.RomanNumerals return new HashSet(_arabicRomanNumeralsMapping.Take(upToArabicNumber)); } - HashSet largerMapping = GenerateAdditionalMappings(DICTIONARY_PREPOPULATION_SIZE + 1, upToArabicNumber); + var largerMapping = GenerateAdditionalMappings(DICTIONARY_PREPOPULATION_SIZE + 1, upToArabicNumber); _arabicRomanNumeralsMapping = (HashSet)_arabicRomanNumeralsMapping.Union(largerMapping); } @@ -123,12 +123,12 @@ namespace NzbDrone.Core.Parser.RomanNumerals private static Dictionary GenerateAdditionalSimpleNumerals(int offset, int length) { - Dictionary moreNumerals = new Dictionary(); - foreach (int arabicNumeral in Enumerable.Range(offset, length)) + var moreNumerals = new Dictionary(); + foreach (var arabicNumeral in Enumerable.Range(offset, length)) { GenerateRomanNumerals(arabicNumeral, out var romanNumeral, out _); - SimpleArabicNumeral san = new SimpleArabicNumeral(arabicNumeral); - SimpleRomanNumeral srn = new SimpleRomanNumeral(romanNumeral); + var san = new SimpleArabicNumeral(arabicNumeral); + var srn = new SimpleRomanNumeral(romanNumeral); moreNumerals.Add(san, srn); } diff --git a/src/NzbDrone.Core/Parser/StringUtil.cs b/src/NzbDrone.Core/Parser/StringUtil.cs index cb30cff06..7fb5fab65 100644 --- a/src/NzbDrone.Core/Parser/StringUtil.cs +++ b/src/NzbDrone.Core/Parser/StringUtil.cs @@ -20,7 +20,7 @@ namespace NzbDrone.Core.Parser public static string CleanFileName(string name, bool replace = true) { - string result = name; + var result = name; string[] badCharacters = { "\\", "/", "<", ">", "?", "*", ":", "|", "\"" }; string[] goodCharacters = { "+", "+", "", "", "!", "-", "-", "", "" }; @@ -30,7 +30,7 @@ namespace NzbDrone.Core.Parser result = result.Replace(": ", " - "); } - for (int i = 0; i < badCharacters.Length; i++) + for (var i = 0; i < badCharacters.Length; i++) { result = result.Replace(badCharacters[i], replace ? goodCharacters[i] : string.Empty); } diff --git a/src/NzbDrone.Mono.Test/DiskProviderTests/DiskProviderFixture.cs b/src/NzbDrone.Mono.Test/DiskProviderTests/DiskProviderFixture.cs index 25a02fd43..a09a68a98 100644 --- a/src/NzbDrone.Mono.Test/DiskProviderTests/DiskProviderFixture.cs +++ b/src/NzbDrone.Mono.Test/DiskProviderTests/DiskProviderFixture.cs @@ -58,7 +58,7 @@ namespace NzbDrone.Mono.Test.DiskProviderTests { // Remove Write permissions, we're still owner so we can clean it up, but we'll have to do that explicitly. Syscall.stat(path, out var stat); - FilePermissions mode = stat.st_mode; + var mode = stat.st_mode; if (writable) { diff --git a/src/NzbDrone.Mono/EnvironmentInfo/VersionAdapters/ReleaseFileVersionAdapter.cs b/src/NzbDrone.Mono/EnvironmentInfo/VersionAdapters/ReleaseFileVersionAdapter.cs index 78dcceec6..9347176b2 100644 --- a/src/NzbDrone.Mono/EnvironmentInfo/VersionAdapters/ReleaseFileVersionAdapter.cs +++ b/src/NzbDrone.Mono/EnvironmentInfo/VersionAdapters/ReleaseFileVersionAdapter.cs @@ -28,7 +28,7 @@ namespace NzbDrone.Mono.EnvironmentInfo.VersionAdapters var fullName = ""; var version = ""; - bool success = false; + var success = false; foreach (var releaseFile in releaseFiles) { diff --git a/src/NzbDrone.Test.Common/ConcurrencyCounter.cs b/src/NzbDrone.Test.Common/ConcurrencyCounter.cs index f3c12023f..a6a07118b 100644 --- a/src/NzbDrone.Test.Common/ConcurrencyCounter.cs +++ b/src/NzbDrone.Test.Common/ConcurrencyCounter.cs @@ -27,7 +27,7 @@ namespace NzbDrone.Test.Common public int Start() { - int threadId = Environment.CurrentManagedThreadId; + var threadId = Environment.CurrentManagedThreadId; lock (_mutex) { _threads[threadId] = 1; diff --git a/src/NzbDrone.Test.Common/ExceptionVerification.cs b/src/NzbDrone.Test.Common/ExceptionVerification.cs index bcf417434..413769fd9 100644 --- a/src/NzbDrone.Test.Common/ExceptionVerification.cs +++ b/src/NzbDrone.Test.Common/ExceptionVerification.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Threading; @@ -44,10 +44,10 @@ namespace NzbDrone.Test.Common private static string GetLogsString(IEnumerable logs) { - string errors = ""; + var errors = ""; foreach (var log in logs) { - string exception = ""; + var exception = ""; if (log.Exception != null) { exception = string.Format("[{0}: {1}]", log.Exception.GetType(), log.Exception.Message); diff --git a/src/NzbDrone.Update.Test/StartNzbDroneService.cs b/src/NzbDrone.Update.Test/StartNzbDroneService.cs index ac59a5a1a..5d24080da 100644 --- a/src/NzbDrone.Update.Test/StartNzbDroneService.cs +++ b/src/NzbDrone.Update.Test/StartNzbDroneService.cs @@ -17,7 +17,7 @@ namespace NzbDrone.Update.Test [Test] public void should_start_service_if_app_type_was_serivce() { - string targetFolder = "c:\\Prowlarr\\".AsOsAgnostic(); + var targetFolder = "c:\\Prowlarr\\".AsOsAgnostic(); Subject.Start(AppType.Service, targetFolder); @@ -27,8 +27,8 @@ namespace NzbDrone.Update.Test [Test] public void should_start_console_if_app_type_was_service_but_start_failed_because_of_permissions() { - string targetFolder = "c:\\Prowlarr\\".AsOsAgnostic(); - string targetProcess = "c:\\Prowlarr\\Prowlarr.Console".AsOsAgnostic().ProcessNameToExe(); + var targetFolder = "c:\\Prowlarr\\".AsOsAgnostic(); + var targetProcess = "c:\\Prowlarr\\Prowlarr.Console".AsOsAgnostic().ProcessNameToExe(); Mocker.GetMock().Setup(c => c.Start(ServiceProvider.SERVICE_NAME)).Throws(new InvalidOperationException()); diff --git a/src/NzbDrone.Update/UpdateEngine/InstallUpdateService.cs b/src/NzbDrone.Update/UpdateEngine/InstallUpdateService.cs index 497f3a394..1b2f4d90d 100644 --- a/src/NzbDrone.Update/UpdateEngine/InstallUpdateService.cs +++ b/src/NzbDrone.Update/UpdateEngine/InstallUpdateService.cs @@ -152,7 +152,7 @@ namespace NzbDrone.Update.UpdateEngine _terminateNzbDrone.Terminate(processId); _logger.Info("Waiting for external auto-restart."); - for (int i = 0; i < 10; i++) + for (var i = 0; i < 10; i++) { System.Threading.Thread.Sleep(1000); diff --git a/src/NzbDrone.Windows.Test/DiskProviderTests/FreeSpaceFixture.cs b/src/NzbDrone.Windows.Test/DiskProviderTests/FreeSpaceFixture.cs index fdb0b0988..1cda90713 100644 --- a/src/NzbDrone.Windows.Test/DiskProviderTests/FreeSpaceFixture.cs +++ b/src/NzbDrone.Windows.Test/DiskProviderTests/FreeSpaceFixture.cs @@ -1,4 +1,4 @@ -using System.IO; +using System.IO; using FluentAssertions; using NUnit.Framework; using NzbDrone.Common.Test.DiskTests; @@ -19,7 +19,7 @@ namespace NzbDrone.Windows.Test.DiskProviderTests public void should_throw_if_drive_doesnt_exist() { // Find a drive that doesn't exist. - for (char driveletter = 'Z'; driveletter > 'D'; driveletter--) + for (var driveletter = 'Z'; driveletter > 'D'; driveletter--) { if (new DriveInfo(driveletter.ToString()).IsReady) { diff --git a/src/Prowlarr.Api.V1/Logs/LogFileControllerBase.cs b/src/Prowlarr.Api.V1/Logs/LogFileControllerBase.cs index a662a049c..b5414beb9 100644 --- a/src/Prowlarr.Api.V1/Logs/LogFileControllerBase.cs +++ b/src/Prowlarr.Api.V1/Logs/LogFileControllerBase.cs @@ -32,7 +32,7 @@ namespace Prowlarr.Api.V1.Logs var files = GetLogFiles().ToList(); - for (int i = 0; i < files.Count; i++) + for (var i = 0; i < files.Count; i++) { var file = files[i]; var filename = Path.GetFileName(file); diff --git a/src/Prowlarr.Api.V1/Profiles/App/AppProfileSchemaModule.cs b/src/Prowlarr.Api.V1/Profiles/App/AppProfileSchemaModule.cs index 9eafed370..9383d795f 100644 --- a/src/Prowlarr.Api.V1/Profiles/App/AppProfileSchemaModule.cs +++ b/src/Prowlarr.Api.V1/Profiles/App/AppProfileSchemaModule.cs @@ -17,7 +17,7 @@ namespace Prowlarr.Api.V1.Profiles.App [HttpGet] public AppProfileResource GetSchema() { - AppSyncProfile qualityProfile = _profileService.GetDefaultProfile(string.Empty); + var qualityProfile = _profileService.GetDefaultProfile(string.Empty); return qualityProfile.ToResource(); } diff --git a/src/Prowlarr.Http/ClientSchema/SchemaBuilder.cs b/src/Prowlarr.Http/ClientSchema/SchemaBuilder.cs index 698a7ffc8..3f36760af 100644 --- a/src/Prowlarr.Http/ClientSchema/SchemaBuilder.cs +++ b/src/Prowlarr.Http/ClientSchema/SchemaBuilder.cs @@ -72,7 +72,7 @@ namespace Prowlarr.Http.ClientSchema result = GetFieldMapping(type, "", v => v); // Renumber al the field Orders since nested settings will have dupe Orders. - for (int i = 0; i < result.Length; i++) + for (var i = 0; i < result.Length; i++) { result[i].Field.Order = i; } diff --git a/src/Prowlarr.Http/Extensions/RequestExtensions.cs b/src/Prowlarr.Http/Extensions/RequestExtensions.cs index 792c9a63b..bb7a0af5f 100644 --- a/src/Prowlarr.Http/Extensions/RequestExtensions.cs +++ b/src/Prowlarr.Http/Extensions/RequestExtensions.cs @@ -139,13 +139,13 @@ namespace Prowlarr.Http.Extensions public static string GetHostName(this HttpRequest request) { - string ip = request.GetRemoteIP(); + var ip = request.GetRemoteIP(); try { - IPAddress myIP = IPAddress.Parse(ip); - IPHostEntry getIPHost = Dns.GetHostEntry(myIP); - List compName = getIPHost.HostName.ToString().Split('.').ToList(); + var myIP = IPAddress.Parse(ip); + var getIPHost = Dns.GetHostEntry(myIP); + var compName = getIPHost.HostName.ToString().Split('.').ToList(); return compName.First(); } catch diff --git a/src/ServiceHelpers/ServiceInstall/ServiceHelper.cs b/src/ServiceHelpers/ServiceInstall/ServiceHelper.cs index 4c4901bc9..629d10b13 100644 --- a/src/ServiceHelpers/ServiceInstall/ServiceHelper.cs +++ b/src/ServiceHelpers/ServiceInstall/ServiceHelper.cs @@ -12,7 +12,7 @@ namespace ServiceInstall private static bool IsAnAdministrator() { - WindowsPrincipal principal = new WindowsPrincipal(WindowsIdentity.GetCurrent()); + var principal = new WindowsPrincipal(WindowsIdentity.GetCurrent()); return principal.IsInRole(WindowsBuiltInRole.Administrator); } diff --git a/src/ServiceHelpers/ServiceUninstall/ServiceHelper.cs b/src/ServiceHelpers/ServiceUninstall/ServiceHelper.cs index 01bb06d2b..28efd343f 100644 --- a/src/ServiceHelpers/ServiceUninstall/ServiceHelper.cs +++ b/src/ServiceHelpers/ServiceUninstall/ServiceHelper.cs @@ -12,7 +12,7 @@ namespace ServiceUninstall private static bool IsAnAdministrator() { - WindowsPrincipal principal = new WindowsPrincipal(WindowsIdentity.GetCurrent()); + var principal = new WindowsPrincipal(WindowsIdentity.GetCurrent()); return principal.IsInRole(WindowsBuiltInRole.Administrator); } From 7fe9942c2872cd2235157ac31729e4916ce46b19 Mon Sep 17 00:00:00 2001 From: SetekhZ Date: Sun, 28 May 2023 18:09:59 +0300 Subject: [PATCH 0009/1128] Fixed: (RuTracker) Use supported 200 categories per search request --- .../Indexers/Definitions/RuTracker.cs | 111 +++++++++--------- 1 file changed, 55 insertions(+), 56 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/RuTracker.cs b/src/NzbDrone.Core/Indexers/Definitions/RuTracker.cs index 2274a0f8a..5c25f3a47 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/RuTracker.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/RuTracker.cs @@ -1465,7 +1465,54 @@ namespace NzbDrone.Core.Indexers.Definitions _capabilities = capabilities; } - private IEnumerable GetPagedRequests(string term, int[] categories, int season = 0) + public IndexerPageableRequestChain GetSearchRequests(MovieSearchCriteria searchCriteria) + { + return GetPageableRequests(searchCriteria.SanitizedSearchTerm, searchCriteria.Categories); + } + + public IndexerPageableRequestChain GetSearchRequests(MusicSearchCriteria searchCriteria) + { + return GetPageableRequests(searchCriteria.SanitizedSearchTerm, searchCriteria.Categories); + } + + public IndexerPageableRequestChain GetSearchRequests(TvSearchCriteria searchCriteria) + { + return GetPageableRequests(searchCriteria.SanitizedSearchTerm, searchCriteria.Categories, searchCriteria.Season ?? 0); + } + + public IndexerPageableRequestChain GetSearchRequests(BookSearchCriteria searchCriteria) + { + return GetPageableRequests(searchCriteria.SanitizedSearchTerm, searchCriteria.Categories); + } + + public IndexerPageableRequestChain GetSearchRequests(BasicSearchCriteria searchCriteria) + { + return GetPageableRequests(searchCriteria.SanitizedSearchTerm, searchCriteria.Categories); + } + + private IndexerPageableRequestChain GetPageableRequests(string searchTerm, int[] categories, int season = 0) + { + var pageableRequests = new IndexerPageableRequestChain(); + + if (categories is { Length: > 0 }) + { + var trackerCategories = _capabilities.Categories.MapTorznabCapsToTrackers(categories).Distinct().ToList(); + + // RuTracker supports maximum 200 categories in one search + foreach (var trackerCategoriesChunk in trackerCategories.Chunk(200)) + { + pageableRequests.Add(GetPagedRequests(searchTerm, trackerCategoriesChunk, season)); + } + } + else + { + pageableRequests.Add(GetPagedRequests(searchTerm, null, season)); + } + + return pageableRequests; + } + + private IEnumerable GetPagedRequests(string term, string[] trackerCategories, int season = 0) { var parameters = new NameValueCollection(); @@ -1488,9 +1535,9 @@ namespace NzbDrone.Core.Indexers.Definitions parameters.Set("nm", searchString); } - if (categories != null && categories.Length > 0) + if (trackerCategories is { Length: > 0 }) { - parameters.Set("f", string.Join(",", _capabilities.Categories.MapTorznabCapsToTrackers(categories))); + parameters.Set("f", string.Join(",", trackerCategories)); } var searchUrl = $"{_settings.BaseUrl}forum/tracker.php"; @@ -1511,56 +1558,6 @@ namespace NzbDrone.Core.Indexers.Definitions yield return request; } - public IndexerPageableRequestChain GetSearchRequests(MovieSearchCriteria searchCriteria) - { - var pageableRequests = new IndexerPageableRequestChain(); - - pageableRequests.Add(GetPagedRequests(searchCriteria.SanitizedSearchTerm, searchCriteria.Categories)); - - return pageableRequests; - } - - public IndexerPageableRequestChain GetSearchRequests(MusicSearchCriteria searchCriteria) - { - var pageableRequests = new IndexerPageableRequestChain(); - - pageableRequests.Add(GetPagedRequests(searchCriteria.SanitizedSearchTerm, searchCriteria.Categories)); - - return pageableRequests; - } - - public IndexerPageableRequestChain GetSearchRequests(TvSearchCriteria searchCriteria) - { - var pageableRequests = new IndexerPageableRequestChain(); - - if (searchCriteria.Season == null) - { - searchCriteria.Season = 0; - } - - pageableRequests.Add(GetPagedRequests(searchCriteria.SanitizedSearchTerm, searchCriteria.Categories)); - - return pageableRequests; - } - - public IndexerPageableRequestChain GetSearchRequests(BookSearchCriteria searchCriteria) - { - var pageableRequests = new IndexerPageableRequestChain(); - - pageableRequests.Add(GetPagedRequests(searchCriteria.SanitizedSearchTerm, searchCriteria.Categories)); - - return pageableRequests; - } - - public IndexerPageableRequestChain GetSearchRequests(BasicSearchCriteria searchCriteria) - { - var pageableRequests = new IndexerPageableRequestChain(); - - pageableRequests.Add(GetPagedRequests(searchCriteria.SanitizedSearchTerm, searchCriteria.Categories)); - - return pageableRequests; - } - public Func> GetCookies { get; set; } public Action, DateTime?> CookiesUpdater { get; set; } } @@ -1580,7 +1577,7 @@ namespace NzbDrone.Core.Indexers.Definitions public IList ParseResponse(IndexerResponse indexerResponse) { - var torrentInfos = new List(); + var releaseInfos = new List(); var parser = new HtmlParser(); var doc = parser.ParseDocument(indexerResponse.Content); @@ -1591,11 +1588,13 @@ namespace NzbDrone.Core.Indexers.Definitions var release = ParseReleaseRow(row); if (release != null) { - torrentInfos.Add(release); + releaseInfos.Add(release); } } - return torrentInfos.ToArray(); + return releaseInfos + .OrderByDescending(o => o.PublishDate) + .ToArray(); } private TorrentInfo ParseReleaseRow(IElement row) From 65541017dd4d914c29106fa37e2a39d35ef57f9c Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 28 May 2023 20:50:15 +0300 Subject: [PATCH 0010/1128] Fixed: (RuTracker) Update categories --- .../Indexers/Definitions/RuTracker.cs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/RuTracker.cs b/src/NzbDrone.Core/Indexers/Definitions/RuTracker.cs index 5c25f3a47..8ee671f71 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/RuTracker.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/RuTracker.cs @@ -183,7 +183,6 @@ namespace NzbDrone.Core.Indexers.Definitions caps.Categories.AddCategoryMapping(2220, NewznabStandardCategory.MoviesDVD, "|- Индийское кино (DVD Video)"); caps.Categories.AddCategoryMapping(1670, NewznabStandardCategory.MoviesDVD, "|- Грайндхаус (DVD Video)"); caps.Categories.AddCategoryMapping(2198, NewznabStandardCategory.MoviesHD, "HD Video"); - caps.Categories.AddCategoryMapping(1457, NewznabStandardCategory.MoviesUHD, "|- UHD Video"); caps.Categories.AddCategoryMapping(2199, NewznabStandardCategory.MoviesHD, "|- Классика мирового кинематографа (HD Video)"); caps.Categories.AddCategoryMapping(313, NewznabStandardCategory.MoviesHD, "|- Зарубежное кино (HD Video)"); caps.Categories.AddCategoryMapping(312, NewznabStandardCategory.MoviesHD, "|- Наше кино (HD Video)"); @@ -192,6 +191,12 @@ namespace NzbDrone.Core.Indexers.Definitions caps.Categories.AddCategoryMapping(2339, NewznabStandardCategory.MoviesHD, "|- Арт-хаус и авторское кино (HD Video)"); caps.Categories.AddCategoryMapping(140, NewznabStandardCategory.MoviesHD, "|- Индийское кино (HD Video)"); caps.Categories.AddCategoryMapping(194, NewznabStandardCategory.MoviesHD, "|- Грайндхаус (HD Video)"); + caps.Categories.AddCategoryMapping(718, NewznabStandardCategory.MoviesUHD, "UHD Video"); + caps.Categories.AddCategoryMapping(775, NewznabStandardCategory.MoviesUHD, "|- Классика мирового кинематографа (UHD Video)"); + caps.Categories.AddCategoryMapping(1457, NewznabStandardCategory.MoviesUHD, "|- Зарубежное кино (UHD Video)"); + caps.Categories.AddCategoryMapping(1940, NewznabStandardCategory.MoviesUHD, "|- Наше кино (UHD Video)"); + caps.Categories.AddCategoryMapping(272, NewznabStandardCategory.MoviesUHD, "|- Азиатские фильмы (UHD Video)"); + caps.Categories.AddCategoryMapping(271, NewznabStandardCategory.MoviesUHD, "|- Арт-хаус и авторское кино (UHD Video)"); caps.Categories.AddCategoryMapping(352, NewznabStandardCategory.Movies3D, "3D/Стерео Кино, Видео, TV и Спорт"); caps.Categories.AddCategoryMapping(549, NewznabStandardCategory.Movies3D, "|- 3D Кинофильмы"); caps.Categories.AddCategoryMapping(1213, NewznabStandardCategory.Movies3D, "|- 3D Мультфильмы"); @@ -216,6 +221,7 @@ namespace NzbDrone.Core.Indexers.Definitions caps.Categories.AddCategoryMapping(815, NewznabStandardCategory.TVSD, "|- Мультсериалы (SD Video)"); caps.Categories.AddCategoryMapping(816, NewznabStandardCategory.TVHD, "|- Мультсериалы (DVD Video)"); caps.Categories.AddCategoryMapping(1460, NewznabStandardCategory.TVHD, "|- Мультсериалы (HD Video)"); + caps.Categories.AddCategoryMapping(498, NewznabStandardCategory.TVUHD, "|- Мультсериалы (UHD Video)"); caps.Categories.AddCategoryMapping(33, NewznabStandardCategory.TVAnime, "Аниме"); caps.Categories.AddCategoryMapping(1106, NewznabStandardCategory.TVAnime, "|- Онгоинги (HD Video)"); caps.Categories.AddCategoryMapping(1105, NewznabStandardCategory.TVAnime, "|- Аниме (HD Video)"); @@ -295,7 +301,6 @@ namespace NzbDrone.Core.Indexers.Definitions caps.Categories.AddCategoryMapping(1949, NewznabStandardCategory.TVHD, "|- Черное зеркало / Black Mirror (HD Video)"); caps.Categories.AddCategoryMapping(1498, NewznabStandardCategory.TVHD, "|- Для некондиционных раздач (HD Video)"); caps.Categories.AddCategoryMapping(911, NewznabStandardCategory.TVForeign, "Сериалы Латинской Америки, Турции и Индии"); - caps.Categories.AddCategoryMapping(1493, NewznabStandardCategory.TVForeign, "|- Актёры и актрисы латиноамериканских сериалов"); caps.Categories.AddCategoryMapping(325, NewznabStandardCategory.TVForeign, "|- Сериалы Аргентины"); caps.Categories.AddCategoryMapping(534, NewznabStandardCategory.TVForeign, "|- Сериалы Бразилии"); caps.Categories.AddCategoryMapping(594, NewznabStandardCategory.TVForeign, "|- Сериалы Венесуэлы"); @@ -303,11 +308,8 @@ namespace NzbDrone.Core.Indexers.Definitions caps.Categories.AddCategoryMapping(607, NewznabStandardCategory.TVForeign, "|- Сериалы Колумбии"); caps.Categories.AddCategoryMapping(1574, NewznabStandardCategory.TVForeign, "|- Сериалы Латинской Америки с озвучкой (раздачи папками)"); caps.Categories.AddCategoryMapping(1539, NewznabStandardCategory.TVForeign, "|- Сериалы Латинской Америки с субтитрами"); - caps.Categories.AddCategoryMapping(1940, NewznabStandardCategory.TVForeign, "|- Официальные краткие версии сериалов Латинской Америки"); caps.Categories.AddCategoryMapping(694, NewznabStandardCategory.TVForeign, "|- Сериалы Мексики"); - caps.Categories.AddCategoryMapping(775, NewznabStandardCategory.TVForeign, "|- Сериалы Перу, Сальвадора, Чили и других стран"); caps.Categories.AddCategoryMapping(781, NewznabStandardCategory.TVForeign, "|- Сериалы совместного производства"); - caps.Categories.AddCategoryMapping(718, NewznabStandardCategory.TVForeign, "|- Сериалы США (латиноамериканские)"); caps.Categories.AddCategoryMapping(704, NewznabStandardCategory.TVForeign, "|- Сериалы Турции"); caps.Categories.AddCategoryMapping(1537, NewznabStandardCategory.TVForeign, "|- Для некондиционных раздач"); caps.Categories.AddCategoryMapping(2100, NewznabStandardCategory.TVForeign, "Азиатские сериалы"); @@ -445,7 +447,7 @@ namespace NzbDrone.Core.Indexers.Definitions caps.Categories.AddCategoryMapping(1229, NewznabStandardCategory.TVSport, "|- Чемпионат Мира 2022 (финальный турнир)"); caps.Categories.AddCategoryMapping(1693, NewznabStandardCategory.TVSport, "|- Чемпионат Мира 2022 (отбор)"); caps.Categories.AddCategoryMapping(2532, NewznabStandardCategory.TVSport, "|- Чемпионат Европы 2020 [2021] (финальный турнир)"); - caps.Categories.AddCategoryMapping(136, NewznabStandardCategory.TVSport, "|- Чемпионат Европы 2020 [2021] (отбор)"); + caps.Categories.AddCategoryMapping(136, NewznabStandardCategory.TVSport, "|- Чемпионат Европы 2024 (отбор)"); caps.Categories.AddCategoryMapping(592, NewznabStandardCategory.TVSport, "|- Лига Наций"); caps.Categories.AddCategoryMapping(2533, NewznabStandardCategory.TVSport, "|- Чемпионат Мира 2018 (игры)"); caps.Categories.AddCategoryMapping(1952, NewznabStandardCategory.TVSport, "|- Чемпионат Мира 2018 (обзорные передачи, документалистика)"); @@ -491,8 +493,7 @@ namespace NzbDrone.Core.Indexers.Definitions caps.Categories.AddCategoryMapping(1527, NewznabStandardCategory.TVSport, "|- International Wrestling"); caps.Categories.AddCategoryMapping(2069, NewznabStandardCategory.TVSport, "|- Oldschool Wrestling"); caps.Categories.AddCategoryMapping(1323, NewznabStandardCategory.TVSport, "|- Documentary Wrestling"); - caps.Categories.AddCategoryMapping(1346, NewznabStandardCategory.TVSport, "Для дооформления раздач"); - caps.Categories.AddCategoryMapping(1411, NewznabStandardCategory.TVSport, "|- Сканирование, обработка сканов"); + caps.Categories.AddCategoryMapping(1411, NewznabStandardCategory.Books, "|- Сканирование, обработка сканов"); caps.Categories.AddCategoryMapping(21, NewznabStandardCategory.Books, "Книги и журналы (общий раздел)"); caps.Categories.AddCategoryMapping(2157, NewznabStandardCategory.Books, "|- Кино, театр, ТВ, мультипликация, цирк"); caps.Categories.AddCategoryMapping(765, NewznabStandardCategory.Books, "|- Рисунок, графический дизайн"); From fcfec1b8591ec7c9cfed7df804b3136ff0bb6da8 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 26 May 2023 18:32:35 +0300 Subject: [PATCH 0011/1128] Simplify ShouldHaveApiKey and HasErrors (cherry picked from commit 7343616a47cd538bba4c9128d2c1094561f9b3a5) --- .../Indexers/Definitions/Newznab/NewznabSettings.cs | 7 +------ .../Indexers/Definitions/Torznab/TorznabSettings.cs | 7 +------ .../Validation/NzbDroneValidationExtensions.cs | 12 +----------- 3 files changed, 3 insertions(+), 23 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/Newznab/NewznabSettings.cs b/src/NzbDrone.Core/Indexers/Definitions/Newznab/NewznabSettings.cs index 6551b2b30..5717d978b 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Newznab/NewznabSettings.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Newznab/NewznabSettings.cs @@ -23,12 +23,7 @@ namespace NzbDrone.Core.Indexers.Newznab private static bool ShouldHaveApiKey(NewznabSettings settings) { - if (settings.BaseUrl == null) - { - return false; - } - - return ApiKeyWhiteList.Any(c => settings.BaseUrl.ToLowerInvariant().Contains(c)); + return settings.BaseUrl != null && ApiKeyWhiteList.Any(c => settings.BaseUrl.ToLowerInvariant().Contains(c)); } private static readonly Regex AdditionalParametersRegex = new Regex(@"(&.+?\=.+?)+", RegexOptions.Compiled); diff --git a/src/NzbDrone.Core/Indexers/Definitions/Torznab/TorznabSettings.cs b/src/NzbDrone.Core/Indexers/Definitions/Torznab/TorznabSettings.cs index 4374c1256..31b4cac17 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Torznab/TorznabSettings.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Torznab/TorznabSettings.cs @@ -17,12 +17,7 @@ namespace NzbDrone.Core.Indexers.Torznab private static bool ShouldHaveApiKey(TorznabSettings settings) { - if (settings.BaseUrl == null) - { - return false; - } - - return ApiKeyWhiteList.Any(c => settings.BaseUrl.ToLowerInvariant().Contains(c)); + return settings.BaseUrl != null && ApiKeyWhiteList.Any(c => settings.BaseUrl.ToLowerInvariant().Contains(c)); } private static readonly Regex AdditionalParametersRegex = new Regex(@"(&.+?\=.+?)+", RegexOptions.Compiled); diff --git a/src/NzbDrone.Core/Validation/NzbDroneValidationExtensions.cs b/src/NzbDrone.Core/Validation/NzbDroneValidationExtensions.cs index f299c8ac3..46a247873 100644 --- a/src/NzbDrone.Core/Validation/NzbDroneValidationExtensions.cs +++ b/src/NzbDrone.Core/Validation/NzbDroneValidationExtensions.cs @@ -24,17 +24,7 @@ namespace NzbDrone.Core.Validation public static bool HasErrors(this List list) { - foreach (var item in list) - { - if (item is NzbDroneValidationFailure { IsWarning: true }) - { - continue; - } - - return true; - } - - return false; + return list.Any(item => item is not NzbDroneValidationFailure { IsWarning: true }); } } } From 5864a090e4e83c44bdae745eb1db07a28ec04b97 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 26 May 2023 18:35:31 +0300 Subject: [PATCH 0012/1128] Fixed: Enforce validation warnings (cherry picked from commit 48ee1158ad4213fd0690842e2672f52d08f7ad26) --- .../Store/Actions/Creators/createSaveProviderHandler.js | 4 ++-- src/Prowlarr.Api.V1/ProviderControllerBase.cs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/frontend/src/Store/Actions/Creators/createSaveProviderHandler.js b/frontend/src/Store/Actions/Creators/createSaveProviderHandler.js index 5761655d2..1cccf1666 100644 --- a/frontend/src/Store/Actions/Creators/createSaveProviderHandler.js +++ b/frontend/src/Store/Actions/Creators/createSaveProviderHandler.js @@ -32,9 +32,9 @@ function createSaveProviderHandler(section, url, options = {}) { const params = { ...queryParams }; // If the user is re-saving the same provider without changes - // force it to be saved. Only applies to editing existing providers. + // force it to be saved. - if (id && _.isEqual(saveData, lastSaveData)) { + if (_.isEqual(saveData, lastSaveData)) { params.forceSave = true; } diff --git a/src/Prowlarr.Api.V1/ProviderControllerBase.cs b/src/Prowlarr.Api.V1/ProviderControllerBase.cs index a5faf958d..52b931956 100644 --- a/src/Prowlarr.Api.V1/ProviderControllerBase.cs +++ b/src/Prowlarr.Api.V1/ProviderControllerBase.cs @@ -59,9 +59,9 @@ namespace Prowlarr.Api.V1 [RestPostById] [Produces("application/json")] - public ActionResult CreateProvider(TProviderResource providerResource) + public ActionResult CreateProvider([FromBody] TProviderResource providerResource, [FromQuery] bool forceSave = false) { - var providerDefinition = GetDefinition(providerResource, true, false, false); + var providerDefinition = GetDefinition(providerResource, true, !forceSave, false); if (providerDefinition.Enable) { @@ -77,7 +77,7 @@ namespace Prowlarr.Api.V1 [Produces("application/json")] public ActionResult UpdateProvider([FromBody] TProviderResource providerResource, [FromQuery] bool forceSave = false) { - var providerDefinition = GetDefinition(providerResource, true, false, false); + var providerDefinition = GetDefinition(providerResource, true, !forceSave, false); // Only test existing definitions if it is enabled and forceSave isn't set. if (providerDefinition.Enable && !forceSave) @@ -195,7 +195,7 @@ namespace Prowlarr.Api.V1 protected void VerifyValidationResult(ValidationResult validationResult, bool includeWarnings) { - var result = new NzbDroneValidationResult(validationResult.Errors); + var result = validationResult as NzbDroneValidationResult ?? new NzbDroneValidationResult(validationResult.Errors); if (includeWarnings && (!result.IsValid || result.HasWarnings)) { From 3ae1917d3b5f42411fdee1ff6c86113ab996d455 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 28 May 2023 14:37:25 +0300 Subject: [PATCH 0013/1128] Fixed: Revert seed criteria validation to warnings Closes #1692 --- .../Indexers/IndexerTorrentBaseSettings.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/IndexerTorrentBaseSettings.cs b/src/NzbDrone.Core/Indexers/IndexerTorrentBaseSettings.cs index d8001529d..bae3f889e 100644 --- a/src/NzbDrone.Core/Indexers/IndexerTorrentBaseSettings.cs +++ b/src/NzbDrone.Core/Indexers/IndexerTorrentBaseSettings.cs @@ -1,5 +1,6 @@ using FluentValidation; using NzbDrone.Core.Annotations; +using NzbDrone.Core.Validation; namespace NzbDrone.Core.Indexers { @@ -9,24 +10,25 @@ namespace NzbDrone.Core.Indexers { RuleFor(c => c.AppMinimumSeeders).GreaterThan(0) .When(c => c.AppMinimumSeeders.HasValue) - .WithMessage("Should be greater than zero"); + .AsWarning().WithMessage("Should be greater than zero"); RuleFor(c => c.SeedRatio).GreaterThan(0.0) .When(c => c.SeedRatio.HasValue) - .WithMessage("Should be greater than zero"); + .AsWarning().WithMessage("Should be greater than zero"); RuleFor(c => c.SeedTime).GreaterThan(0) .When(c => c.SeedTime.HasValue) - .WithMessage("Should be greater than zero"); + .AsWarning().WithMessage("Should be greater than zero"); RuleFor(c => c.PackSeedTime).GreaterThan(0) .When(c => c.PackSeedTime.HasValue) - .WithMessage("Should be greater than zero"); + .AsWarning().WithMessage("Should be greater than zero"); if (seedRatioMinimum != 0.0) { RuleFor(c => c.SeedRatio).GreaterThanOrEqualTo(seedRatioMinimum) .When(c => c.SeedRatio > 0.0) + .AsWarning() .WithMessage($"Under {seedRatioMinimum} leads to H&R"); } @@ -34,6 +36,7 @@ namespace NzbDrone.Core.Indexers { RuleFor(c => c.SeedTime).GreaterThanOrEqualTo(seedTimeMinimum) .When(c => c.SeedTime > 0) + .AsWarning() .WithMessage($"Under {seedTimeMinimum} leads to H&R"); } @@ -41,6 +44,7 @@ namespace NzbDrone.Core.Indexers { RuleFor(c => c.PackSeedTime).GreaterThanOrEqualTo(seasonPackSeedTimeMinimum) .When(c => c.PackSeedTime > 0) + .AsWarning() .WithMessage($"Under {seasonPackSeedTimeMinimum} leads to H&R"); } } @@ -48,8 +52,6 @@ namespace NzbDrone.Core.Indexers public class IndexerTorrentBaseSettings { - private static readonly IndexerTorrentSettingsValidator Validator = new (); - [FieldDefinition(1, Type = FieldType.Number, Label = "Apps Minimum Seeders", HelpText = "Minimum seeders required by the Applications for the indexer to grab, empty is Sync profile's default", Advanced = true)] public int? AppMinimumSeeders { get; set; } From 59b6e8af27d2c1f9d2ebb0b0f0d43aa7ec348406 Mon Sep 17 00:00:00 2001 From: Servarr Date: Sun, 28 May 2023 19:28:02 +0000 Subject: [PATCH 0014/1128] Automated API Docs update --- src/Prowlarr.Api.V1/openapi.json | 50 ++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/Prowlarr.Api.V1/openapi.json b/src/Prowlarr.Api.V1/openapi.json index 450efe0d4..f7034eec1 100644 --- a/src/Prowlarr.Api.V1/openapi.json +++ b/src/Prowlarr.Api.V1/openapi.json @@ -186,6 +186,16 @@ "tags": [ "Application" ], + "parameters": [ + { + "name": "forceSave", + "in": "query", + "schema": { + "type": "boolean", + "default": false + } + } + ], "requestBody": { "content": { "application/json": { @@ -1195,6 +1205,16 @@ "tags": [ "DownloadClient" ], + "parameters": [ + { + "name": "forceSave", + "in": "query", + "schema": { + "type": "boolean", + "default": false + } + } + ], "requestBody": { "content": { "application/json": { @@ -1921,6 +1941,16 @@ "tags": [ "Indexer" ], + "parameters": [ + { + "name": "forceSave", + "in": "query", + "schema": { + "type": "boolean", + "default": false + } + } + ], "requestBody": { "content": { "application/json": { @@ -2298,6 +2328,16 @@ "tags": [ "IndexerProxy" ], + "parameters": [ + { + "name": "forceSave", + "in": "query", + "schema": { + "type": "boolean", + "default": false + } + } + ], "requestBody": { "content": { "application/json": { @@ -3370,6 +3410,16 @@ "tags": [ "Notification" ], + "parameters": [ + { + "name": "forceSave", + "in": "query", + "schema": { + "type": "boolean", + "default": false + } + } + ], "requestBody": { "content": { "application/json": { From ef1ad59f595994244c0b3f5d92a82900d01fc3cb Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 28 May 2023 20:33:38 +0300 Subject: [PATCH 0015/1128] Fixed: (Cardigann) Respect the categories from search paths --- .../Cardigann/CardigannRequestGenerator.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannRequestGenerator.cs b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannRequestGenerator.cs index 9e03a6736..a9087d1ce 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannRequestGenerator.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannRequestGenerator.cs @@ -1044,8 +1044,6 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann mappedCategories = _defaultCategories; } - variables[".Categories"] = mappedCategories; - var keywordTokens = new List(); var keywordTokenKeys = new List { "Q", "Series", "Movie", "Year" }; foreach (var key in keywordTokenKeys) @@ -1069,20 +1067,26 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann var searchPaths = search.Paths; foreach (var searchPath in searchPaths) { + variables[".Categories"] = mappedCategories; + // skip path if categories don't match if (searchPath.Categories != null && mappedCategories.Count > 0) { - var invertMatch = searchPath.Categories[0] == "!"; var hasIntersect = mappedCategories.Intersect(searchPath.Categories).Any(); - if (invertMatch) + + if (searchPath.Categories[0] == "!") { hasIntersect = !hasIntersect; } if (!hasIntersect) { + variables[".Categories"] = mappedCategories.Except(searchPath.Categories).ToList(); + continue; } + + variables[".Categories"] = mappedCategories.Intersect(searchPath.Categories).ToList(); } // build search URL From 2d36adf8652410a26a5f92756c10c79e749a8a9c Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 29 May 2023 17:35:37 +0300 Subject: [PATCH 0016/1128] Fixed: (Cardigann): Use `MissingAttributeEqualsNoResults` for `Search.Rows.Attribute` --- .../Definitions/Cardigann/CardigannParser.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannParser.cs b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannParser.cs index 9af17a161..2513898b6 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannParser.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannParser.cs @@ -116,7 +116,18 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann foreach (var row in rowsArray) { - var selObj = search.Rows.Attribute != null ? row.SelectToken(search.Rows.Attribute).Value() : row; + var selObj = row; + + if (search.Rows.Attribute != null) + { + selObj = row.SelectToken(search.Rows.Attribute)?.Value(); + + if (selObj == null && search.Rows.MissingAttributeEqualsNoResults) + { + continue; + } + } + var mulRows = search.Rows.Multiple ? selObj.Values() : new List { selObj.Value() }; foreach (var mulRow in mulRows) From bf5855beb41d4ba611b9bd1213d78952c8184a4c Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 31 May 2023 06:52:36 +0300 Subject: [PATCH 0017/1128] Revert "Fixed: Don't log handled exceptions in API" This reverts commit 19ff73dad04c63c13cfb294065258721688914f0. --- src/NzbDrone.Host/Bootstrap.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/NzbDrone.Host/Bootstrap.cs b/src/NzbDrone.Host/Bootstrap.cs index f92ecb150..5f4a750e2 100644 --- a/src/NzbDrone.Host/Bootstrap.cs +++ b/src/NzbDrone.Host/Bootstrap.cs @@ -14,7 +14,6 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting.WindowsServices; -using Microsoft.Extensions.Logging; using NLog; using Npgsql; using NzbDrone.Common.Composition.Extensions; @@ -25,7 +24,6 @@ using NzbDrone.Common.Instrumentation; using NzbDrone.Common.Instrumentation.Extensions; using NzbDrone.Core.Configuration; using NzbDrone.Core.Datastore.Extensions; -using LogLevel = Microsoft.Extensions.Logging.LogLevel; using PostgresOptions = NzbDrone.Core.Datastore.PostgresOptions; namespace NzbDrone.Host @@ -143,10 +141,6 @@ namespace NzbDrone.Host return new HostBuilder() .UseContentRoot(Directory.GetCurrentDirectory()) .UseServiceProviderFactory(new DryIocServiceProviderFactory(new Container(rules => rules.WithNzbDroneRules()))) - .ConfigureLogging(logging => - { - logging.AddFilter("Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware", LogLevel.None); - }) .ConfigureContainer(c => { c.AutoAddServices(Bootstrap.ASSEMBLIES) From b59d89f3086a1588e60d8ff2e323d6d49156aeff Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 31 May 2023 06:53:06 +0300 Subject: [PATCH 0018/1128] Fixed: Don't log handled exceptions in API --- src/NzbDrone.Common/Instrumentation/NzbDroneLogger.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/NzbDrone.Common/Instrumentation/NzbDroneLogger.cs b/src/NzbDrone.Common/Instrumentation/NzbDroneLogger.cs index 2493e35cf..90b43b94e 100644 --- a/src/NzbDrone.Common/Instrumentation/NzbDroneLogger.cs +++ b/src/NzbDrone.Common/Instrumentation/NzbDroneLogger.cs @@ -108,9 +108,10 @@ namespace NzbDrone.Common.Instrumentation { LogManager.Setup().LoadConfiguration(c => { + c.ForLogger("System.*").WriteToNil(LogLevel.Warn); + c.ForLogger("Microsoft.*").WriteToNil(LogLevel.Warn); c.ForLogger("Microsoft.Hosting.Lifetime*").WriteToNil(LogLevel.Info); - c.ForLogger("System*").WriteToNil(LogLevel.Warn); - c.ForLogger("Microsoft*").WriteToNil(LogLevel.Warn); + c.ForLogger("Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware").WriteToNil(LogLevel.Fatal); }); } From d1e39f206acae4edc2ab4789df79597f3bfa0e9c Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 31 May 2023 17:30:29 +0300 Subject: [PATCH 0019/1128] New: (Rarbg) Obsolete due to tracker shutdown --- src/NzbDrone.Core.Test/IndexerTests/RarbgTests/RarbgFixture.cs | 1 + src/NzbDrone.Core/Indexers/Definitions/Rarbg/Rarbg.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/NzbDrone.Core.Test/IndexerTests/RarbgTests/RarbgFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/RarbgTests/RarbgFixture.cs index f077357a2..02a205b27 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/RarbgTests/RarbgFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/RarbgTests/RarbgFixture.cs @@ -17,6 +17,7 @@ using NzbDrone.Test.Common; namespace NzbDrone.Core.Test.IndexerTests.RarbgTests { + [Obsolete("Rarbg has shutdown 2023-05-31")] [TestFixture] public class RarbgFixture : CoreTest { diff --git a/src/NzbDrone.Core/Indexers/Definitions/Rarbg/Rarbg.cs b/src/NzbDrone.Core/Indexers/Definitions/Rarbg/Rarbg.cs index 33a80dccd..6437c9ba6 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Rarbg/Rarbg.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Rarbg/Rarbg.cs @@ -20,6 +20,7 @@ using NzbDrone.Core.Validation; namespace NzbDrone.Core.Indexers.Definitions.Rarbg { + [Obsolete("Rarbg has shutdown 2023-05-31")] public class Rarbg : TorrentIndexerBase { public override string Name => "Rarbg"; From d5e5697db8a29fa26628771a0b332d80abb4d0a1 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 31 May 2023 21:06:14 +0300 Subject: [PATCH 0020/1128] Remove Rarbg tracker from MagnetLinkBuilder --- src/NzbDrone.Core/Indexers/MagnetLinkBuilder.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/MagnetLinkBuilder.cs b/src/NzbDrone.Core/Indexers/MagnetLinkBuilder.cs index 3d26282c2..b56041150 100644 --- a/src/NzbDrone.Core/Indexers/MagnetLinkBuilder.cs +++ b/src/NzbDrone.Core/Indexers/MagnetLinkBuilder.cs @@ -8,10 +8,9 @@ namespace NzbDrone.Core.Indexers { public static class MagnetLinkBuilder { - private static readonly List _trackers = new List + private static readonly List Trackers = new () { "udp://tracker.opentrackr.org:1337/announce", - "udp://9.rarbg.com:2810/announce", "udp://tracker.openbittorrent.com:6969/announce", "http://tracker.openbittorrent.com:80/announce", "udp://opentracker.i2p.rocks:6969/announce", @@ -34,7 +33,7 @@ namespace NzbDrone.Core.Indexers public static string BuildPublicMagnetLink(string infoHash, string releaseTitle) { - return new MagnetLink(InfoHash.FromHex(infoHash), releaseTitle, _trackers).ToV1String(); + return new MagnetLink(InfoHash.FromHex(infoHash), releaseTitle, Trackers).ToV1String(); } public static string GetInfoHashFromMagnet(string magnet) From 868394d588a254f79ceb33d6ae42687ad71d88b0 Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 31 May 2023 17:36:46 +0000 Subject: [PATCH 0021/1128] Translations update from Servarr Weblate Co-authored-by: Cc95459 <954591059@qq.com> Co-authored-by: Havok Dan Co-authored-by: Jens Co-authored-by: Thijs Waalen Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/de/ Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/nl/ Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt_BR/ Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_CN/ Translation: Servarr/Prowlarr --- src/NzbDrone.Core/Localization/Core/de.json | 933 +++++++-------- src/NzbDrone.Core/Localization/Core/nl.json | 860 +++++++------- .../Localization/Core/pt_BR.json | 1028 ++++++++--------- .../Localization/Core/zh_CN.json | 1008 ++++++++-------- 4 files changed, 1917 insertions(+), 1912 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/de.json b/src/NzbDrone.Core/Localization/Core/de.json index c41b536e4..eddec7e18 100644 --- a/src/NzbDrone.Core/Localization/Core/de.json +++ b/src/NzbDrone.Core/Localization/Core/de.json @@ -1,468 +1,469 @@ { - "About": "Über", - "All": "Alle", - "Analytics": "Analytik", - "AppDataLocationHealthCheckMessage": "Ein Update ist nicht möglich, um das Löschen von AppData beim Update zu verhindern", - "Backup": "Backups", - "BackupNow": "Jetzt sichern", - "Clear": "Leeren", - "Connect": "Benachrichtigungen", - "Connections": "Verbindungen", - "CustomFilters": "Filter anpassen", - "Date": "Datum", - "Dates": "Termine", - "Delete": "Löschen", - "DownloadClientStatusCheckAllClientMessage": "Alle Download Clients sind aufgrund von Fehlern nicht verfügbar", - "DownloadClientStatusCheckSingleClientMessage": "Download Clients aufgrund von Fehlern nicht verfügbar: {0}", - "DownloadClients": "Downloader", - "Edit": "Bearbeiten", - "Events": "Events", - "Files": "Dateien", - "Filter": "Filter", - "Folder": "Ordner", - "General": "Allgemein", - "Health": "Zustandsüberwachung", - "HideAdvanced": "Erweiterte Ansicht", - "History": "Verlauf", - "Host": "Host", - "IndexerStatusCheckAllClientMessage": "Alle Indexer sind aufgrund von Fehlern nicht verfügbar", - "IndexerStatusCheckSingleClientMessage": "Indexer aufgrund von Fehlern nicht verfügbar: {0}", - "Indexers": "Indexer", - "LogFiles": "Protokolle", - "Logging": "Protokollierung", - "MoreInfo": "Mehr Infos", - "NoChange": "Keine Änderung", - "NoChanges": "Keine Änderungen", - "Options": "Optionen", - "Proxy": "Proxy", - "ProxyCheckBadRequestMessage": "Proxy konnte nicht getestet werden. StatusCode: {0}", - "ProxyCheckFailedToTestMessage": "Proxy konnte nicht getestet werden: {0}", - "ProxyCheckResolveIpMessage": "Fehler beim Auflösen der IP-Adresse für den konfigurierten Proxy-Host {0}", - "Queue": "Warteschlange", - "Refresh": "Aktualisieren", - "ReleaseBranchCheckOfficialBranchMessage": "Zweig {0} ist kein gültiger Prowlarr-Release-Zweig. Sie erhalten keine Updates", - "RestoreBackup": "Backup einspielen", - "SaveChanges": "Änderungen speichern", - "Scheduled": "Geplant", - "Search": "Suche", - "Security": "Sicherheit", - "SelectAll": "Alle wählen", - "SetTags": "Tags setzen", - "Settings": "Einstellungen", - "ShowAdvanced": "Einfache Ansicht", - "Sort": "Sortieren", - "Status": "Status", - "Style": "Stil", - "System": "System", - "Tags": "Tags", - "Tasks": "Aufgaben", - "UI": "Oberfläche", - "UnselectAll": "Keine wählen", - "UpdateCheckStartupNotWritableMessage": "Update kann nicht installiert werden, da der Startordner '{0}' vom Benutzer '{1}' nicht beschreibbar ist.", - "UpdateCheckStartupTranslocationMessage": "Update kann nicht installiert werden, da sich der Startordner '{0}' in einem App Translocation-Ordner befindet.", - "UpdateCheckUINotWritableMessage": "Update kann nicht installiert werden, da der Benutzeroberflächenordner '{0}' vom Benutzer '{1}' nicht beschreibbar ist.", - "Updates": "Updates", - "View": "Ansicht", - "Language": "Sprache", - "UISettingsSummary": "Optionen für Datum, Sprache und Farbbeinträchtigungen", - "TagsSettingsSummary": "Alle Tags und deren Benutzung anzeigen. Unbenutzte Tags können entfernt werden", - "Size": "Größe", - "ReleaseStatus": "Releasestatus", - "Protocol": "Protokoll", - "LastWriteTime": "Zuletzt beschrieben", - "Indexer": "Indexer", - "DownloadClientsSettingsSummary": "Download der Client-Konfigurationen für die Integration in die Prowlarr UI-Suche", - "Grabbed": "Erfasste", - "GeneralSettingsSummary": "Port, SSL, Benutzername/Passwort, Proxy, Analytik und Updates", - "Filename": "Dateiname", - "Failed": "Fehlgeschlagen", - "EventType": "Event Typ", - "DownloadClient": "Downloader", - "Details": "Details", - "ConnectSettingsSummary": "Benachrichtigungen und eigene Scripte", - "Added": "Hinzugefügt", - "Actions": "Aktionen", - "Warn": "Warnung", - "Type": "Typ", - "Title": "Titel", - "Time": "Zeit", - "TestAll": "Alle testen", - "Test": "Testen", - "TableOptionsColumnsMessage": "Wähle aus welche Spalten angezeigt werden und in welcher Reihenfolge", - "TableOptions": "Tabellen Optionen", - "Source": "Quelle", - "Shutdown": "Herunterfahren", - "Seeders": "Seeders", - "Save": "Speichern", - "Restart": "Neustarten", - "Reload": "Neuladen", - "Peers": "Peers", - "PageSize": "Einträge pro Seite", - "Ok": "OK", - "OAuthPopupMessage": "Dein Browser blockiert Pop-ups", - "Name": "Name", - "Message": "Nachricht", - "Level": "Stufe", - "KeyboardShortcuts": "Tastenkürzel", - "Info": "Info", - "HealthNoIssues": "Keine Probleme mit deiner Konfiguration", - "Error": "Fehler", - "ConnectionLostMessage": "Prowlarr hat die Verbindung zum Backend verloren und muss neugeladen werden.", - "ConnectionLostAutomaticMessage": "Prowlarr wird automatisch versuchen zu verbinden oder klicke unten auf neuladen.", - "ConnectionLost": "Verbindung unterbrochen", - "Component": "Komponente", - "Columns": "Spalten", - "Close": "Schließen", - "Cancel": "Abbrechen", - "Apply": "Anwenden", - "Age": "Alter", - "SystemTimeCheckMessage": "Die Systemzeit ist um einen Tag versetzt. Bis die Zeit korrigiert wurde, könnten die geplanten Aufgaben nicht korrekt ausgeführt werden", - "UnsavedChanges": "Ungespeicherte Änderungen", - "ShowSearchHelpText": "Suchbutton anzeigen beim draufzeigen", - "ShowSearch": "Suche anzeigen", - "SettingsTimeFormat": "Zeitformat", - "SettingsShowRelativeDatesHelpText": "Relatives (z.B.: Heute, gestern, etc) oder absolutes Datum anzeigen", - "SettingsShowRelativeDates": "Relatives Datum anzeigen", - "SettingsShortDateFormat": "Kurzes Datumsformat", - "SettingsLongDateFormat": "Langes Datumsformat", - "SettingsEnableColorImpairedMode": "Farbbeeinträchtigter Modus aktivieren", - "SettingsEnableColorImpairedModeHelpText": "Alternativer Stil, um farbbeeinträchtigten Benutzern eine bessere Unterscheidung farbcodierter Informationen zu ermöglichen", - "PendingChangesStayReview": "Auf der Seite bleiben", - "PendingChangesMessage": "Es gibt noch ungespeicherte Änderungen, bist du sicher, dass du die Seite verlassen möchtest?", - "PendingChangesDiscardChanges": "Änderungen verwerfen und schließen", - "UpdateAutomaticallyHelpText": "Updates automatisch herunteraden und installieren. Es kann weiterhin unter \"System -> Updates\" ein manuelles Update angestoßen werden", - "UrlBaseHelpText": "Für Reverse-Proxy-Unterstützung. Die Standardeinstellung leer", - "AppDataDirectory": "AppData Ordner", - "ApplyTags": "Tags setzen", - "Authentication": "Authentifizierung", - "Automatic": "Automatisch", - "BackupIntervalHelpText": "Intervall zum sichern der Datenbank und Einstellungen", - "BackupRetentionHelpText": "Automatische Backups, die älter als die Aufbewahrungsfrist sind, werden automatisch gelöscht", - "Backups": "Sicherungen", - "BindAddress": "Adresse binden", - "BindAddressHelpText": "Gültige IP Adresse oder \"*\" für alle Netzwerke", - "Branch": "Git-Branch", - "BypassProxyForLocalAddresses": "Proxy für lokale Adressen umgehen", - "CertificateValidation": "Zertifikat Validierung", - "CertificateValidationHelpText": "Ändere wie streng die Validierung der HTTPS-Zertifizierung ist", - "ChangeHasNotBeenSavedYet": "Änderung wurde noch nicht gespeichert", - "ClientPriority": "Priorität", - "CloneProfile": "Profil kopieren", - "DeleteBackup": "Backup löschen", - "DeleteDownloadClient": "Downloader löschen", - "DeleteTag": "Tag löschen", - "Docker": "Docker", - "DownloadClientSettings": "Downloader Einstellungen", - "Enable": "Aktivieren", - "EnableAutomaticSearch": "Automatisch suchen", - "EnableInteractiveSearch": "Interaktive Suche", - "EnableSSL": "SSL", - "EnableSslHelpText": " Erfordert einen Neustart als Administrator", - "Fixed": "Behoben", - "GeneralSettings": "Allgemeine Einstellungen", - "Hostname": "Hostname", - "IgnoredAddresses": "Ignorierte Adressen", - "IllRestartLater": "Später neustarten", - "IncludeHealthWarningsHelpText": "Zustandswarnung", - "IndexerFlags": "Indexer-Flags", - "Interval": "Intervall", - "LogLevel": "Log Level", - "Logs": "Protokolle", - "Mechanism": "Verfahren", - "MIA": "MIA", - "Mode": "Modus", - "NetCore": ".NET Core", - "New": "Neu", - "NoLeaveIt": "Nein, nicht ändern", - "NotificationTriggers": "Benachrichtigungs Auslöser", - "OnHealthIssueHelpText": "Zustandsproblem", - "OpenBrowserOnStart": "Browser beim Start öffnen", - "PackageVersion": "Paket Version", - "PageSizeHelpText": "Anzahl der Einträge pro Seite", - "Password": "Passwort", - "Port": "Port", - "PortNumber": "Port Nummer", - "ProxyBypassFilterHelpText": "Verwende ',' als Trennzeichen und '*.' als Platzhalter für Subdomains", - "ProxyType": "Proxy Typ", - "ProxyUsernameHelpText": "Nur wenn ein Benutzername und Passwort erforderlich ist, muss es eingegeben werden. Ansonsten leer lassen.", - "RefreshMovie": "Film aktualisieren", - "RemovedFromTaskQueue": "Aus der Aufgabenwarteschlage entfernt", - "RemoveFilter": "Filter entfernen", - "Reset": "Zurücksetzen", - "ResetAPIKey": "API-Schlüssel zurücksetzen", - "RestartNow": "Jetzt neustarten", - "RestartProwlarr": "Prowlarr Neustarten", - "Result": "Ergebnis", - "Retention": "Aufbewahrung ( Retention )", - "ScriptPath": "Script Pfad", - "SSLCertPassword": "SSL Zertifikat Passwort", - "SSLPort": "SSL Port", - "SSLCertPath": "Pfad zum SSL Zertifikat", - "StartupDirectory": "Start-Verzeichnis", - "SuggestTranslationChange": "Schlage eine Übersetzung vor", - "TagsHelpText": "Wird auf Filme mit mindestens einem passenden Tag angewandt", - "TestAllClients": "Alle testen", - "UpdateMechanismHelpText": "Benutze Prowlarr's Built-In Updater oder ein Script", - "UpdateScriptPathHelpText": "Pfad zu einem benutzerdefinierten Skript, das ein extrahiertes Update-Paket übernimmt und den Rest des Update-Prozesses abwickelt", - "Uptime": "Laufzeit", - "URLBase": "URL-Basis", - "Torrents": "Torrents", - "UISettings": "Benutzeroberflächen Einstellungen", - "UnableToLoadDownloadClients": "Downloader konnten nicht geladen werden", - "UnableToLoadNotifications": "Benachrichtigungen konnten nicht geladen werden", - "UnableToLoadTags": "Tags konnten nicht geladen werden", - "Usenet": "Usenet", - "UseProxy": "Proxy benutzen", - "Username": "Benutzername", - "Version": "Version", - "YesCancel": "Ja, abbrechen", - "AnalyticsEnabledHelpText": "Sende anonyme Nutzungs- und Fehlerinformationen an die Server von Prowlarr. Dazu gehören Informationen über Browser, welche Seiten der Prowlarr-Weboberfläche aufgerufen wurden, Fehlerberichte sowie Betriebssystem- und Laufzeitversion. Wir werden diese Informationen verwenden, um Funktionen und Fehlerbehebungen zu priorisieren.", - "RestartRequiredHelpTextWarning": "Erfordert einen Neustart", - "ApiKey": "API-Schlüssel", - "AreYouSureYouWantToResetYourAPIKey": "Bist du sicher, dass du den API-Schlüssel zurücksetzen willst?", - "PriorityHelpText": "Priorisiere mehrere Downloader. Rundlauf-Verfahren wird für Downloader mit der gleichen Priorität verwendet.", - "AuthenticationMethodHelpText": "Für den Zugriff auf Prowlarr sind Benutzername und Passwort erforderlich", - "ProxyPasswordHelpText": "Nur wenn ein Benutzername und Passwort erforderlich ist, muss es eingegeben werden. Ansonsten leer lassen.", - "SendAnonymousUsageData": "Anonyme Nutzungsdaten übertragen", - "DBMigration": "DB Migration", - "LaunchBrowserHelpText": " Öffne die Startseite von Prowlarr im Webbrowser nach dem Start.", - "ReadTheWikiForMoreInformation": "Lese das Wiki für mehr Informationen", - "BackupFolderHelpText": "Relative Pfade befinden sich unter Prowlarrs AppData Ordner", - "DeleteNotification": "Benachrichtigung löschen", - "ConnectSettings": "Eintellungen für Verbindungen", - "TagCannotBeDeletedWhileInUse": "Kann während der Benutzung nicht gelöscht werden", - "SSLCertPathHelpText": "Pfad zur PFX Datei", - "SSLCertPasswordHelpText": "Passwort für die PFX Datei", - "ShownClickToHide": "Angezeigt, zum verstecken klicken", - "RSSIsNotSupportedWithThisIndexer": "RSS wird von diesem Indexer nicht unterstützt", - "RemovingTag": "Tag entfernen", - "Manual": "Manuell", - "LogLevelTraceHelpTextWarning": "Trace logging sollte nur kurzzeitig aktiviert werden", - "HiddenClickToShow": "Versteckt, klicken zum anzeigen", - "ExistingTag": "Vorhandener Tag", - "EnableInteractiveSearchHelpText": "Wird bei der manuellen Suche benutzt", - "EnableAutomaticSearchHelpText": "Wird für automatische Suchen genutzt die vom Benutzer oder von Prowlarr gestartet werden", - "DeleteTagMessageText": "Tag '{0}' wirklich löschen?", - "DeleteNotificationMessageText": "Benachrichtigung '{0}' wirklich löschen?", - "DeleteDownloadClientMessageText": "Downloader '{0}' wirklich löschen?", - "DeleteBackupMessageText": "Backup '{0}' wirkich löschen?", - "CancelPendingTask": "Diese laufende Aufgabe wirklich abbrechen?", - "BranchUpdateMechanism": "Git-Branch für den externen Updateablauf", - "BranchUpdate": "Verwendeter Branch zur Aktualisierung von Prowlarr", - "BeforeUpdate": "Vor dem Update", - "AddingTag": "Tag hinzufügen", - "UnableToLoadUISettings": "Oberflächen Einstellungen konnten nicht geladen werden", - "UnableToLoadHistory": "Verlauf konnte nicht geladen werden", - "UnableToLoadGeneralSettings": "Allgemeine Einstellungen konnten nicht geladen werden", - "UnableToLoadBackups": "Backups konnten nicht geladen werden", - "UnableToAddANewNotificationPleaseTryAgain": "Die neue Benachrichtigung konnte nicht hinzugefügt werden, bitte erneut probieren.", - "UnableToAddANewIndexerPleaseTryAgain": "Der neue Indexer konnte nicht hinzugefügt werden, bitte erneut probieren.", - "UnableToAddANewDownloadClientPleaseTryAgain": "Der neue Downloader konnte nicht hinzugefügt werden, bitte erneut probieren.", - "TagIsNotUsedAndCanBeDeleted": "Tag wird nicht benutzt und kann gelöscht werden", - "StartTypingOrSelectAPathBelow": "Eingeben oder unten auswählen", - "Restore": "Wiederherstellen", - "ProwlarrSupportsAnyIndexer": "Prowlarr unterstützt alle Indexer, welcher den Newznab/Torznab Standard implementiert (verwende 'Generic Newznab' (für Usenet) oder 'Generic Torznab' (für Torrents)) und darüber hinaus viele weitere Indexer. Wählen Sie im Folgenden Ihren Indexer aus der Liste.", - "ProwlarrSupportsAnyDownloadClient": "Jeder Downloader der den Newznab-Standard verwendet oder unten aufgelistet ist wird untertützt.", - "NoUpdatesAreAvailable": "Es sind keine Updates verfügbar", - "NoTagsHaveBeenAddedYet": "Es wurden noch keine Tags erstellt", - "NoLogFiles": "Keine Log-Dateien", - "NoBackupsAreAvailable": "Es sind keine Backups vorhanden", - "MaintenanceRelease": "Wartung: Fehlerbehebung und andere Verbesserungen. Siehe Github Commit History für weitere Details", - "ForMoreInformationOnTheIndividualDownloadClients": "Für mehr Infomationen klicke auf die Info-Knöpfe.", - "FilterPlaceHolder": "Filme suchen", - "Exception": "Ausnahme", - "ErrorLoadingContents": "Fehler beim laden der Inhalte", - "ApplyTagsHelpTexts4": "Ersetzen: Nur eingegebene Tags übernehmen und vorhandene entfernen( keine Tags eingeben um alle zu entfernen )", - "ApplyTagsHelpTexts3": "Entfernen: Eingegebene Tags entfernen", - "ApplyTagsHelpTexts2": "Hinzufügen: Füge neu Tags zu den existierenden Tags hinzu", - "ApplyTagsHelpTexts1": "Wie werden Tags zu ausgewählten Indexern zugeteilt", - "UILanguageHelpTextWarning": "Webseite muss neu geladen werden", - "UILanguageHelpText": "Sprache für die gesamte Oberfläche", - "UILanguage": "Oberflächen Sprache ( UI Language )", - "Priority": "Priorität", - "InteractiveSearch": "Interaktive Suche", - "IndexerPriorityHelpText": "Indexer Priorität von 1 (höchste) bis 50 (niedrigste). Standard: 25.", - "IndexerPriority": "Priorität", - "EditIndexer": "Indexer bearbeiten", - "Disabled": "Deaktiviert", - "AutomaticSearch": "Automatische Suche", - "AddIndexer": "Indexer hinzufügen", - "SaveSettings": "Einstellungen speichern", - "OpenThisModal": "Dieses Modal öffnen", - "MovieIndexScrollTop": "Filmindex: Nach oben scrollen", - "MovieIndexScrollBottom": "Filmindex: Nach unten scrollen", - "FocusSearchBox": "Suchbox fokussieren", - "CloseCurrentModal": "Momentanes Modal schließen", - "AcceptConfirmationModal": "Bestätigung akzeptieren Modal", - "Yesterday": "Gestern", - "Tomorrow": "Morgen", - "Today": "Heute", - "IndexerLongTermStatusCheckSingleClientMessage": "Indexer wegen über 6 Stunden langen bestehenden Fehlern nicht verfügbar: {0}", - "IndexerLongTermStatusCheckAllClientMessage": "Alle Indexer sind wegen über 6 Stunden langen bestehender Fehler nicht verfügbar", - "SyncAppIndexers": "App Indexer syncen", - "UnableToLoadDevelopmentSettings": "Entwicklereinstellungen konnten nicht geladen werden", - "TestAllApps": "Alle Apps testen", - "SettingsSqlLoggingHelpText": "Log alle SQL Abfragen von Prowlarr", - "SettingsLogSql": "Log SQL", - "SettingsLogRotateHelpText": "Max. Anzahl der zu behaltenden Logdateien", - "SettingsLogRotate": "Logrotation", - "SettingsIndexerLoggingHelpText": "Erweiterte Indexerdaten loggen inklusive Antwort", - "SettingsIndexerLogging": "Verbesserte Indexer-Protokollierung", - "SettingsFilterSentryEventsHelpText": "Sende keine bekannten Benutzerfehler Ereignisse an Analystics", - "SettingsFilterSentryEvents": "Analystische Ergeinisse filtern", - "SettingsConsoleLogLevel": "Konsolen Log Level", - "SearchIndexers": "Indexer suchen", - "IndexersSelectedInterp": "{0} Indexer ausgewählt", - "IndexerRss": "Indexer RSS", - "IndexerQuery": "Indexer Anfrage", - "IndexerHealthCheckNoIndexers": "Keine Indexer aktiviert, Prowlarr wird keine Suchergebnisse zurückgeben", - "IndexerAuth": "Indexer Authentifizierung", - "EnableIndexer": "Indexer aktivieren", - "IndexerObsoleteCheckMessage": "Indexer sind nicht mehr verfügbar oder wurden aktualiiert: {0}. Bitte enfernen und (oder) neu zu Prowlarr hinzufügen", - "DevelopmentSettings": "Entwicklungseinstellungen", - "DeleteApplicationMessageText": "Wirklich die Applikation '{0}' löschen?", - "DeleteApplication": "Applikation löschen", - "ClearHistoryMessageText": "Wirklich den ganzen Prowlarr Verlauf löschen?", - "ClearHistory": "Verlauf leeren", - "ApplicationStatusCheckSingleClientMessage": "Applikationen wegen folgender Fehler nicht verfügbar: {0}", - "ApplicationStatusCheckAllClientMessage": "Wegen Fehlern sind keine Applikationen verfügbar", - "AllIndexersHiddenDueToFilter": "Alle Indexer sind durch den ausgewählten Filter ausgeblendet.", - "AddToDownloadClient": "Release zum Downloader hinzufügen", - "AddNewIndexer": "Neuen Indexer hinzufügen", - "AddedToDownloadClient": "Release zum Client hinzugefügt", - "EnableRssHelpText": "RSS-Feed für Indexer aktivieren", - "EnableRss": "RSS aktivieren", - "Wiki": "Wiki", - "RSS": "RSS", - "RedirectHelpText": "Eingehende Download-Anfragen für den Indexer umleiten, anstatt Proxying mit Prowlarr", - "Redirect": "Umleiten", - "Reddit": "Reddit", - "HomePage": "Startseite", - "FeatureRequests": "Funktionsanfragen", - "AppProfileSelectHelpText": "App-Profile werden verwendet, um die Einstellungen für RSS, automatische Suche und interaktive Suche bei der Anwendungssynchronisierung zu steuern", - "Discord": "Discord", - "PrioritySettings": "Priorität", - "NotificationTriggersHelpText": "Auslöser für diese Benachrichtigung auswählen", - "Add": "Hinzufügen", - "AddDownloadClient": "Zum Downloader hinzufügen", - "UnableToLoadAppProfiles": "App-Profile können nicht geladen werden", - "UnableToAddANewAppProfilePleaseTryAgain": "Es kann kein neues Anwendungsprofil hinzugefügt werden. Bitte versuchen Sie es erneut.", - "UnableToAddANewApplicationPleaseTryAgain": "Es kann keine neue Anwendung hinzugefügt werden. Bitte versuchen Sie es erneut.", - "SyncLevelFull": "Vollständige Synchronisierung: Hält die Indexer dieser App vollständig synchronisiert. Änderungen an Indexern in Prowlarr werden mit dieser App synchronisiert. Jede Änderung die and Indexern dieser App gemacht werden, wird von Prowlarr bei der nächsten Synchronisierung überschrieben.", - "SyncLevelAddRemove": "Nur hinzufügen und entfernen: Wenn Indexer zu Prowlarr hinzugefügt oder entfernt werden, wird diese Remote-App aktualisiert.", - "SyncLevel": "Sync-Level", - "Privacy": "Privatsphäre", - "Presets": "Voreinstellungen", - "FullSync": "Vollständige Synchronisierung", - "Encoding": "Codierung", - "Enabled": "Aktiviert", - "Donations": "Spenden", - "Description": "Beschreibung", - "DeleteAppProfile": "App-Profil löschen", - "Custom": "Benutzerdefiniert", - "CouldNotConnectSignalR": "Es konnte keine Verbindung zu SignalR hergestellt werden, die Benutzeroberfläche wird nicht aktualisiert", - "Category": "Kategorie", - "Apps": "Anwendungen", - "AppProfileInUse": "App-Profil im Einsatz", - "AppProfileDeleteConfirm": "Möchten Sie {0} wirklich löschen?", - "Applications": "Anwendungen", - "AddRemoveOnly": "Nur hinzufügen und entfernen", - "AddDownloadClientToProwlarr": "Durch das Hinzufügen eines Download-Clients kann Prowlarr während einer manuellen Suche Releases direkt über die Benutzeroberfläche senden.", - "Stats": "Statistiken", - "NoSearchResultsFound": "Keine Suchergebnisse gefunden. Versuchen Sie unten eine erneute Suche durchzuführen.", - "Query": "Abfrage", - "Torrent": "Torrent", - "NoLinks": "Keine Links", - "Grabs": "Erfasse", - "IndexerProxyStatusCheckAllClientMessage": "Alle Indexer sind aufgrund von Fehlern nicht verfügbar", - "IndexerProxyStatusCheckSingleClientMessage": "Listen aufgrund von Fehlern nicht verfügbar: {0}", - "UnableToAddANewIndexerProxyPleaseTryAgain": "Der neue Indexer konnte nicht hinzugefügt werden, bitte erneut probieren.", - "DeleteIndexerProxyMessageText": "Tag '{0}' wirklich löschen?", - "AudioSearch": "Audio Suche", - "AddIndexerProxy": "Indexer Proxy hinzufügen", - "AppSettingsSummary": "Anwendungen und Einstellungen um zu konfigurieren, wie Prowlarr mit deinen PVR Programmen interagiert", - "DeleteIndexerProxy": "Indexer Proxy löschen", - "Notification": "Benachrichtigungen", - "Filters": "Filter", - "Notifications": "Benachrichtigungen", - "HistoryCleanupDaysHelpText": "Auf 0 setzen um das automatische leeren des Papierkorbs zu deaktivieren", - "HistoryCleanupDaysHelpTextWarning": "Datien im Papierkorb die älter sind als der gewählte Wert, werden endgültig gelöscht", - "OnApplicationUpdate": "Bei Anwendungsaktualisierung", - "OnApplicationUpdateHelpText": "Bei Anwendungsaktualisierung", - "OnGrab": "Bei Erfassung", - "OnHealthIssue": "Bei Zustandsproblem", - "TestAllIndexers": "Alle testen", - "UserAgentProvidedByTheAppThatCalledTheAPI": "UserAgent von der App welcher die API aufgerufen hat", - "BookSearch": "Buch Suche", - "Id": "Id", - "IndexerProxies": "Indexer-Proxies", - "IndexerTagsHelpText": "Benutze Tags, um Indexer-Proxies zu spezifizieren, mit welchen Apps der Indexer synchronisiert oder um Indexer zu organisieren.", - "MovieSearch": "Film Suche", - "QueryOptions": "Abfrage-Optionen", - "Categories": "Kategorien", - "Database": "Datenbank", - "IndexerNoDefCheckMessage": "Indexer haben keine Definition und werden nicht funktionieren: {0}. Bitte entferne und (oder) füge diese neu zu Prowlarr hinzu", - "MassEditor": "Masseneditor", - "Private": "Privat", - "TvSearch": "TV Suche", - "Url": "Url", - "Auth": "Authentifizierung", - "HistoryCleanup": "Verlaufsbereinigung", - "IndexerAlreadySetup": "Mindestens eine Indexer Instanz ist bereits eingerichtet", - "IndexerInfo": "Indexer-Info", - "IndexerProxy": "Indexer-Proxy", - "IndexerSettingsSummary": "Konfiguration verschiedener globaler Indexer Einstellungen, einschließlich Proxies.", - "IndexerVipCheckExpiredClientMessage": "Die VIP Indexer Vorteile sind abgelaufen: {0}", - "IndexerVipCheckExpiringClientMessage": "Die Indexer VIP Vorteile verfallen bald: {0}", - "Proxies": "Proxies", - "Public": "Öffentlich", - "QueryResults": "Abfrageergebnisse", - "SearchType": "Suchtyp", - "SemiPrivate": "Halbprivat", - "UnableToLoadApplicationList": "Anwendungsliste kann nicht geladen werden", - "UnableToLoadIndexerProxies": "Indexer-Proxies können nicht geladen werden", - "Website": "Webseite", - "Application": "Anwendungen", - "GrabReleases": "Release erfassen", - "Link": "Links", - "MappedDrivesRunningAsService": "Zugeordnete Netzlaufwerke sind nicht verfügbar, wenn Prowlarr als Windows-Dienst ausgeführt wird. Bitte lesen Sie die FAQ für weitere Informationen", - "No": "Nein", - "SearchTypes": "Suchtyp", - "TVSearchTypes": "Suchtyp", - "UnableToLoadIndexers": "Indexer konnten nicht geladen werden", - "Yes": "Ja", - "InstanceName": "Instanzname", - "InstanceNameHelpText": "Instanzname im Browser-Tab und für Syslog-Anwendungsname", - "SyncProfiles": "Sync-Profile", - "ThemeHelpText": "Ändere das UI-Theme der Anwendung. Das 'Auto'-Theme verwendet dein Betriebssystem-Theme, um den hellen oder dunklen Modus einzustellen. Inspiriert von {0}", - "Duration": "Dauer", - "EditSyncProfile": "Synchronisationsprofil bearbeiten", - "ElapsedTime": "Vergangene Zeit", - "EnabledRedirected": "Aktiviert, Weitergeleitet", - "Ended": "Beendet", - "GrabTitle": "Titel holen", - "LastDuration": "Letzte Dauer", - "LastExecution": "Letzte Ausführung", - "MinimumSeeders": "Mindest-Seeder", - "MinimumSeedersHelpText": "Minimale Anzahl an Seedern die von der Anwendung benötigt werden um den Indexer zu holen", - "NextExecution": "Nächste Ausführung", - "Parameters": "Parameter", - "Queued": "In der Warteschlange", - "Started": "gestartet", - "SyncProfile": "Sync-Profile", - "IndexerSite": "Indexer-Seite", - "MovieSearchTypes": "Film-Suchtypen", - "MusicSearchTypes": "Musik-Suchtypen", - "NotSupported": "Nicht unterstützt", - "RawSearchSupported": "Raw-Suche unterstützt", - "SearchCapabilities": "Suchfähigkeiten", - "AddSyncProfile": "Synchronisationsprofil hinzufügen", - "BookSearchTypes": "Buch-Suchtypen", - "IndexerDetails": "Indexer-Details", - "IndexerName": "Indexer-Name", - "ApplicationLongTermStatusCheckAllClientMessage": "Alle Anwendungen sind nicht verfügbar, da es zu Störungen für mehr als 6 Stunden kam", - "ApplicationLongTermStatusCheckSingleClientMessage": "Anwendungen nicht verfügbar, da es zu Störungen für mehr als 6 Stunden kam: {0}", - "Remove": "Entfernen", - "Replace": "Ersetzen", - "TheLatestVersionIsAlreadyInstalled": "Die aktuellste Version ist bereits installiert" + "About": "Über", + "AcceptConfirmationModal": "Bestätigung akzeptieren Modal", + "Actions": "Aktionen", + "Add": "Hinzufügen", + "AddDownloadClient": "Zum Downloader hinzufügen", + "AddDownloadClientToProwlarr": "Durch das Hinzufügen eines Download-Clients kann Prowlarr während einer manuellen Suche Releases direkt über die Benutzeroberfläche senden.", + "AddIndexer": "Indexer hinzufügen", + "AddIndexerProxy": "Indexer Proxy hinzufügen", + "AddNewIndexer": "Neuen Indexer hinzufügen", + "AddRemoveOnly": "Nur hinzufügen und entfernen", + "AddSyncProfile": "Synchronisationsprofil hinzufügen", + "AddToDownloadClient": "Release zum Downloader hinzufügen", + "Added": "Hinzugefügt", + "AddedToDownloadClient": "Release zum Client hinzugefügt", + "AddingTag": "Tag hinzufügen", + "Age": "Alter", + "All": "Alle", + "AllIndexersHiddenDueToFilter": "Alle Indexer sind durch den ausgewählten Filter ausgeblendet.", + "Analytics": "Analytik", + "AnalyticsEnabledHelpText": "Sende anonyme Nutzungs- und Fehlerinformationen an die Server von Prowlarr. Dazu gehören Informationen über Browser, welche Seiten der Prowlarr-Weboberfläche aufgerufen wurden, Fehlerberichte sowie Betriebssystem- und Laufzeitversion. Wir werden diese Informationen verwenden, um Funktionen und Fehlerbehebungen zu priorisieren.", + "ApiKey": "API-Schlüssel", + "ApiKeyValidationHealthCheckMessage": "Bitte den API Schlüssel korrigieren, dieser muss mindestens {0} Zeichen lang sein. Die Änderung kann über die Einstellungen oder die Konfigurationsdatei erfolgen", + "AppDataDirectory": "AppData Ordner", + "AppDataLocationHealthCheckMessage": "Ein Update ist nicht möglich, um das Löschen von AppData beim Update zu verhindern", + "AppProfileDeleteConfirm": "Möchten Sie {0} wirklich löschen?", + "AppProfileInUse": "App-Profil im Einsatz", + "AppProfileSelectHelpText": "App-Profile werden verwendet, um die Einstellungen für RSS, automatische Suche und interaktive Suche bei der Anwendungssynchronisierung zu steuern", + "AppSettingsSummary": "Anwendungen und Einstellungen um zu konfigurieren, wie Prowlarr mit deinen PVR Programmen interagiert", + "Application": "Anwendungen", + "ApplicationLongTermStatusCheckAllClientMessage": "Alle Anwendungen sind nicht verfügbar, da es zu Störungen für mehr als 6 Stunden kam", + "ApplicationLongTermStatusCheckSingleClientMessage": "Anwendungen nicht verfügbar, da es zu Störungen für mehr als 6 Stunden kam: {0}", + "ApplicationStatusCheckAllClientMessage": "Wegen Fehlern sind keine Applikationen verfügbar", + "ApplicationStatusCheckSingleClientMessage": "Applikationen wegen folgender Fehler nicht verfügbar: {0}", + "Applications": "Anwendungen", + "Apply": "Anwenden", + "ApplyTags": "Tags setzen", + "ApplyTagsHelpTexts1": "Wie werden Tags zu ausgewählten Indexern zugeteilt", + "ApplyTagsHelpTexts2": "Hinzufügen: Füge neu Tags zu den existierenden Tags hinzu", + "ApplyTagsHelpTexts3": "Entfernen: Eingegebene Tags entfernen", + "ApplyTagsHelpTexts4": "Ersetzen: Nur eingegebene Tags übernehmen und vorhandene entfernen( keine Tags eingeben um alle zu entfernen )", + "Apps": "Anwendungen", + "AreYouSureYouWantToResetYourAPIKey": "Bist du sicher, dass du den API-Schlüssel zurücksetzen willst?", + "AudioSearch": "Audio Suche", + "Auth": "Authentifizierung", + "Authentication": "Authentifizierung", + "AuthenticationMethodHelpText": "Für den Zugriff auf Prowlarr sind Benutzername und Passwort erforderlich", + "Automatic": "Automatisch", + "AutomaticSearch": "Automatische Suche", + "Backup": "Backups", + "BackupFolderHelpText": "Relative Pfade befinden sich unter Prowlarrs AppData Ordner", + "BackupIntervalHelpText": "Intervall zum sichern der Datenbank und Einstellungen", + "BackupNow": "Jetzt sichern", + "BackupRetentionHelpText": "Automatische Backups, die älter als die Aufbewahrungsfrist sind, werden automatisch gelöscht", + "Backups": "Sicherungen", + "BeforeUpdate": "Vor dem Update", + "BindAddress": "Adresse binden", + "BindAddressHelpText": "Gültige IP Adresse oder \"*\" für alle Netzwerke", + "BookSearch": "Buch Suche", + "BookSearchTypes": "Buch-Suchtypen", + "Branch": "Git-Branch", + "BranchUpdate": "Verwendeter Branch zur Aktualisierung von Prowlarr", + "BranchUpdateMechanism": "Git-Branch für den externen Updateablauf", + "BypassProxyForLocalAddresses": "Proxy für lokale Adressen umgehen", + "Cancel": "Abbrechen", + "CancelPendingTask": "Diese laufende Aufgabe wirklich abbrechen?", + "Categories": "Kategorien", + "Category": "Kategorie", + "CertificateValidation": "Zertifikat Validierung", + "CertificateValidationHelpText": "Ändere wie streng die Validierung der HTTPS-Zertifizierung ist", + "ChangeHasNotBeenSavedYet": "Änderung wurde noch nicht gespeichert", + "Clear": "Leeren", + "ClearHistory": "Verlauf leeren", + "ClearHistoryMessageText": "Wirklich den ganzen Prowlarr Verlauf löschen?", + "ClientPriority": "Priorität", + "CloneProfile": "Profil kopieren", + "Close": "Schließen", + "CloseCurrentModal": "Momentanes Modal schließen", + "Columns": "Spalten", + "Component": "Komponente", + "Connect": "Benachrichtigungen", + "ConnectSettings": "Eintellungen für Verbindungen", + "ConnectSettingsSummary": "Benachrichtigungen und eigene Scripte", + "ConnectionLost": "Verbindung unterbrochen", + "ConnectionLostAutomaticMessage": "Prowlarr wird automatisch versuchen zu verbinden oder klicke unten auf neuladen.", + "ConnectionLostMessage": "Prowlarr hat die Verbindung zum Backend verloren und muss neugeladen werden.", + "Connections": "Verbindungen", + "CouldNotConnectSignalR": "Es konnte keine Verbindung zu SignalR hergestellt werden, die Benutzeroberfläche wird nicht aktualisiert", + "Custom": "Benutzerdefiniert", + "CustomFilters": "Filter anpassen", + "DBMigration": "DB Migration", + "Database": "Datenbank", + "Date": "Datum", + "Dates": "Termine", + "Delete": "Löschen", + "DeleteAppProfile": "App-Profil löschen", + "DeleteApplication": "Applikation löschen", + "DeleteApplicationMessageText": "Wirklich die Applikation '{0}' löschen?", + "DeleteBackup": "Backup löschen", + "DeleteBackupMessageText": "Backup '{0}' wirkich löschen?", + "DeleteDownloadClient": "Downloader löschen", + "DeleteDownloadClientMessageText": "Downloader '{0}' wirklich löschen?", + "DeleteIndexerProxy": "Indexer Proxy löschen", + "DeleteIndexerProxyMessageText": "Tag '{0}' wirklich löschen?", + "DeleteNotification": "Benachrichtigung löschen", + "DeleteNotificationMessageText": "Benachrichtigung '{0}' wirklich löschen?", + "DeleteTag": "Tag löschen", + "DeleteTagMessageText": "Tag '{0}' wirklich löschen?", + "Description": "Beschreibung", + "Details": "Details", + "DevelopmentSettings": "Entwicklungseinstellungen", + "Disabled": "Deaktiviert", + "Discord": "Discord", + "Docker": "Docker", + "Donations": "Spenden", + "DownloadClient": "Downloader", + "DownloadClientSettings": "Downloader Einstellungen", + "DownloadClientStatusCheckAllClientMessage": "Alle Download Clients sind aufgrund von Fehlern nicht verfügbar", + "DownloadClientStatusCheckSingleClientMessage": "Download Clients aufgrund von Fehlern nicht verfügbar: {0}", + "DownloadClients": "Downloader", + "DownloadClientsSettingsSummary": "Download der Client-Konfigurationen für die Integration in die Prowlarr UI-Suche", + "Duration": "Dauer", + "Edit": "Bearbeiten", + "EditIndexer": "Indexer bearbeiten", + "EditSyncProfile": "Synchronisationsprofil bearbeiten", + "ElapsedTime": "Vergangene Zeit", + "Enable": "Aktivieren", + "EnableAutomaticSearch": "Automatisch suchen", + "EnableAutomaticSearchHelpText": "Wird für automatische Suchen genutzt die vom Benutzer oder von Prowlarr gestartet werden", + "EnableIndexer": "Indexer aktivieren", + "EnableInteractiveSearch": "Interaktive Suche", + "EnableInteractiveSearchHelpText": "Wird bei der manuellen Suche benutzt", + "EnableRss": "RSS aktivieren", + "EnableRssHelpText": "RSS-Feed für Indexer aktivieren", + "EnableSSL": "SSL", + "EnableSslHelpText": " Erfordert einen Neustart als Administrator", + "Enabled": "Aktiviert", + "EnabledRedirected": "Aktiviert, Weitergeleitet", + "Encoding": "Codierung", + "Ended": "Beendet", + "Error": "Fehler", + "ErrorLoadingContents": "Fehler beim laden der Inhalte", + "EventType": "Event Typ", + "Events": "Events", + "Exception": "Ausnahme", + "ExistingTag": "Vorhandener Tag", + "Failed": "Fehlgeschlagen", + "FeatureRequests": "Funktionsanfragen", + "Filename": "Dateiname", + "Files": "Dateien", + "Filter": "Filter", + "FilterPlaceHolder": "Filme suchen", + "Filters": "Filter", + "Fixed": "Behoben", + "FocusSearchBox": "Suchbox fokussieren", + "Folder": "Ordner", + "ForMoreInformationOnTheIndividualDownloadClients": "Für mehr Infomationen klicke auf die Info-Knöpfe.", + "FullSync": "Vollständige Synchronisierung", + "General": "Allgemein", + "GeneralSettings": "Allgemeine Einstellungen", + "GeneralSettingsSummary": "Port, SSL, Benutzername/Passwort, Proxy, Analytik und Updates", + "GrabReleases": "Release erfassen", + "GrabTitle": "Titel holen", + "Grabbed": "Erfasste", + "Grabs": "Erfasse", + "Health": "Zustandsüberwachung", + "HealthNoIssues": "Keine Probleme mit deiner Konfiguration", + "HiddenClickToShow": "Versteckt, klicken zum anzeigen", + "HideAdvanced": "Erweiterte Ansicht", + "History": "Verlauf", + "HistoryCleanup": "Verlaufsbereinigung", + "HistoryCleanupDaysHelpText": "Auf 0 setzen um das automatische leeren des Papierkorbs zu deaktivieren", + "HistoryCleanupDaysHelpTextWarning": "Datien im Papierkorb die älter sind als der gewählte Wert, werden endgültig gelöscht", + "HomePage": "Startseite", + "Host": "Host", + "Hostname": "Hostname", + "Id": "Id", + "IgnoredAddresses": "Ignorierte Adressen", + "IllRestartLater": "Später neustarten", + "IncludeHealthWarningsHelpText": "Zustandswarnung", + "Indexer": "Indexer", + "IndexerAlreadySetup": "Mindestens eine Indexer Instanz ist bereits eingerichtet", + "IndexerAuth": "Indexer Authentifizierung", + "IndexerDetails": "Indexer-Details", + "IndexerFlags": "Indexer-Flags", + "IndexerHealthCheckNoIndexers": "Keine Indexer aktiviert, Prowlarr wird keine Suchergebnisse zurückgeben", + "IndexerInfo": "Indexer-Info", + "IndexerLongTermStatusCheckAllClientMessage": "Alle Indexer sind wegen über 6 Stunden langen bestehender Fehler nicht verfügbar", + "IndexerLongTermStatusCheckSingleClientMessage": "Indexer wegen über 6 Stunden langen bestehenden Fehlern nicht verfügbar: {0}", + "IndexerName": "Indexer-Name", + "IndexerNoDefCheckMessage": "Indexer haben keine Definition und werden nicht funktionieren: {0}. Bitte entferne und (oder) füge diese neu zu Prowlarr hinzu", + "IndexerObsoleteCheckMessage": "Indexer sind nicht mehr verfügbar oder wurden aktualiiert: {0}. Bitte enfernen und (oder) neu zu Prowlarr hinzufügen", + "IndexerPriority": "Priorität", + "IndexerPriorityHelpText": "Indexer Priorität von 1 (höchste) bis 50 (niedrigste). Standard: 25.", + "IndexerProxies": "Indexer-Proxies", + "IndexerProxy": "Indexer-Proxy", + "IndexerProxyStatusCheckAllClientMessage": "Alle Indexer sind aufgrund von Fehlern nicht verfügbar", + "IndexerProxyStatusCheckSingleClientMessage": "Listen aufgrund von Fehlern nicht verfügbar: {0}", + "IndexerQuery": "Indexer Anfrage", + "IndexerRss": "Indexer RSS", + "IndexerSettingsSummary": "Konfiguration verschiedener globaler Indexer Einstellungen, einschließlich Proxies.", + "IndexerSite": "Indexer-Seite", + "IndexerStatusCheckAllClientMessage": "Alle Indexer sind aufgrund von Fehlern nicht verfügbar", + "IndexerStatusCheckSingleClientMessage": "Indexer aufgrund von Fehlern nicht verfügbar: {0}", + "IndexerTagsHelpText": "Benutze Tags, um Indexer-Proxies zu spezifizieren, mit welchen Apps der Indexer synchronisiert oder um Indexer zu organisieren.", + "IndexerVipCheckExpiredClientMessage": "Die VIP Indexer Vorteile sind abgelaufen: {0}", + "IndexerVipCheckExpiringClientMessage": "Die Indexer VIP Vorteile verfallen bald: {0}", + "Indexers": "Indexer", + "IndexersSelectedInterp": "{0} Indexer ausgewählt", + "Info": "Info", + "InstanceName": "Instanzname", + "InstanceNameHelpText": "Instanzname im Browser-Tab und für Syslog-Anwendungsname", + "InteractiveSearch": "Interaktive Suche", + "Interval": "Intervall", + "KeyboardShortcuts": "Tastenkürzel", + "Language": "Sprache", + "LastDuration": "Letzte Dauer", + "LastExecution": "Letzte Ausführung", + "LastWriteTime": "Zuletzt beschrieben", + "LaunchBrowserHelpText": " Öffne die Startseite von Prowlarr im Webbrowser nach dem Start.", + "Level": "Stufe", + "Link": "Links", + "LogFiles": "Protokolle", + "LogLevel": "Log Level", + "LogLevelTraceHelpTextWarning": "Trace logging sollte nur kurzzeitig aktiviert werden", + "Logging": "Protokollierung", + "Logs": "Protokolle", + "MIA": "MIA", + "MaintenanceRelease": "Wartung: Fehlerbehebung und andere Verbesserungen. Siehe Github Commit History für weitere Details", + "Manual": "Manuell", + "MappedDrivesRunningAsService": "Zugeordnete Netzlaufwerke sind nicht verfügbar, wenn Prowlarr als Windows-Dienst ausgeführt wird. Bitte lesen Sie die FAQ für weitere Informationen", + "MassEditor": "Masseneditor", + "Mechanism": "Verfahren", + "Message": "Nachricht", + "MinimumSeeders": "Mindest-Seeder", + "MinimumSeedersHelpText": "Minimale Anzahl an Seedern die von der Anwendung benötigt werden um den Indexer zu holen", + "Mode": "Modus", + "MoreInfo": "Mehr Infos", + "MovieIndexScrollBottom": "Filmindex: Nach unten scrollen", + "MovieIndexScrollTop": "Filmindex: Nach oben scrollen", + "MovieSearch": "Film Suche", + "MovieSearchTypes": "Film-Suchtypen", + "MusicSearchTypes": "Musik-Suchtypen", + "Name": "Name", + "NetCore": ".NET Core", + "New": "Neu", + "NextExecution": "Nächste Ausführung", + "No": "Nein", + "NoBackupsAreAvailable": "Es sind keine Backups vorhanden", + "NoChange": "Keine Änderung", + "NoChanges": "Keine Änderungen", + "NoLeaveIt": "Nein, nicht ändern", + "NoLinks": "Keine Links", + "NoLogFiles": "Keine Log-Dateien", + "NoSearchResultsFound": "Keine Suchergebnisse gefunden. Versuchen Sie unten eine erneute Suche durchzuführen.", + "NoTagsHaveBeenAddedYet": "Es wurden noch keine Tags erstellt", + "NoUpdatesAreAvailable": "Es sind keine Updates verfügbar", + "NotSupported": "Nicht unterstützt", + "Notification": "Benachrichtigungen", + "NotificationTriggers": "Benachrichtigungs Auslöser", + "NotificationTriggersHelpText": "Auslöser für diese Benachrichtigung auswählen", + "Notifications": "Benachrichtigungen", + "OAuthPopupMessage": "Dein Browser blockiert Pop-ups", + "Ok": "OK", + "OnApplicationUpdate": "Bei Anwendungsaktualisierung", + "OnApplicationUpdateHelpText": "Bei Anwendungsaktualisierung", + "OnGrab": "Bei Erfassung", + "OnHealthIssue": "Bei Zustandsproblem", + "OnHealthIssueHelpText": "Zustandsproblem", + "OpenBrowserOnStart": "Browser beim Start öffnen", + "OpenThisModal": "Dieses Modal öffnen", + "Options": "Optionen", + "PackageVersion": "Paket Version", + "PageSize": "Einträge pro Seite", + "PageSizeHelpText": "Anzahl der Einträge pro Seite", + "Parameters": "Parameter", + "Password": "Passwort", + "Peers": "Peers", + "PendingChangesDiscardChanges": "Änderungen verwerfen und schließen", + "PendingChangesMessage": "Es gibt noch ungespeicherte Änderungen, bist du sicher, dass du die Seite verlassen möchtest?", + "PendingChangesStayReview": "Auf der Seite bleiben", + "Port": "Port", + "PortNumber": "Port Nummer", + "Presets": "Voreinstellungen", + "Priority": "Priorität", + "PriorityHelpText": "Priorisiere mehrere Downloader. Rundlauf-Verfahren wird für Downloader mit der gleichen Priorität verwendet.", + "PrioritySettings": "Priorität", + "Privacy": "Privatsphäre", + "Private": "Privat", + "Protocol": "Protokoll", + "ProwlarrSupportsAnyDownloadClient": "Jeder Downloader der den Newznab-Standard verwendet oder unten aufgelistet ist wird untertützt.", + "ProwlarrSupportsAnyIndexer": "Prowlarr unterstützt alle Indexer, welcher den Newznab/Torznab Standard implementiert (verwende 'Generic Newznab' (für Usenet) oder 'Generic Torznab' (für Torrents)) und darüber hinaus viele weitere Indexer. Wählen Sie im Folgenden Ihren Indexer aus der Liste.", + "Proxies": "Proxies", + "Proxy": "Proxy", + "ProxyBypassFilterHelpText": "Verwende ',' als Trennzeichen und '*.' als Platzhalter für Subdomains", + "ProxyCheckBadRequestMessage": "Proxy konnte nicht getestet werden. StatusCode: {0}", + "ProxyCheckFailedToTestMessage": "Proxy konnte nicht getestet werden: {0}", + "ProxyCheckResolveIpMessage": "Fehler beim Auflösen der IP-Adresse für den konfigurierten Proxy-Host {0}", + "ProxyPasswordHelpText": "Nur wenn ein Benutzername und Passwort erforderlich ist, muss es eingegeben werden. Ansonsten leer lassen.", + "ProxyType": "Proxy Typ", + "ProxyUsernameHelpText": "Nur wenn ein Benutzername und Passwort erforderlich ist, muss es eingegeben werden. Ansonsten leer lassen.", + "Public": "Öffentlich", + "Query": "Abfrage", + "QueryOptions": "Abfrage-Optionen", + "QueryResults": "Abfrageergebnisse", + "Queue": "Warteschlange", + "Queued": "In der Warteschlange", + "RSS": "RSS", + "RSSIsNotSupportedWithThisIndexer": "RSS wird von diesem Indexer nicht unterstützt", + "RawSearchSupported": "Raw-Suche unterstützt", + "ReadTheWikiForMoreInformation": "Lese das Wiki für mehr Informationen", + "Reddit": "Reddit", + "Redirect": "Umleiten", + "RedirectHelpText": "Eingehende Download-Anfragen für den Indexer umleiten, anstatt Proxying mit Prowlarr", + "Refresh": "Aktualisieren", + "RefreshMovie": "Film aktualisieren", + "ReleaseBranchCheckOfficialBranchMessage": "Zweig {0} ist kein gültiger Prowlarr-Release-Zweig. Sie erhalten keine Updates", + "ReleaseStatus": "Releasestatus", + "Reload": "Neuladen", + "Remove": "Entfernen", + "RemoveFilter": "Filter entfernen", + "RemovedFromTaskQueue": "Aus der Aufgabenwarteschlage entfernt", + "RemovingTag": "Tag entfernen", + "Replace": "Ersetzen", + "Reset": "Zurücksetzen", + "ResetAPIKey": "API-Schlüssel zurücksetzen", + "Restart": "Neustarten", + "RestartNow": "Jetzt neustarten", + "RestartProwlarr": "Prowlarr Neustarten", + "RestartRequiredHelpTextWarning": "Erfordert einen Neustart", + "Restore": "Wiederherstellen", + "RestoreBackup": "Backup einspielen", + "Result": "Ergebnis", + "Retention": "Aufbewahrung ( Retention )", + "SSLCertPassword": "SSL Zertifikat Passwort", + "SSLCertPasswordHelpText": "Passwort für die PFX Datei", + "SSLCertPath": "Pfad zum SSL Zertifikat", + "SSLCertPathHelpText": "Pfad zur PFX Datei", + "SSLPort": "SSL Port", + "Save": "Speichern", + "SaveChanges": "Änderungen speichern", + "SaveSettings": "Einstellungen speichern", + "Scheduled": "Geplant", + "ScriptPath": "Script Pfad", + "Search": "Suche", + "SearchCapabilities": "Suchfähigkeiten", + "SearchIndexers": "Indexer suchen", + "SearchType": "Suchtyp", + "SearchTypes": "Suchtyp", + "Security": "Sicherheit", + "Seeders": "Seeders", + "SelectAll": "Alle wählen", + "SemiPrivate": "Halbprivat", + "SendAnonymousUsageData": "Anonyme Nutzungsdaten übertragen", + "SetTags": "Tags setzen", + "Settings": "Einstellungen", + "SettingsConsoleLogLevel": "Konsolen Log Level", + "SettingsEnableColorImpairedMode": "Farbbeeinträchtigter Modus aktivieren", + "SettingsEnableColorImpairedModeHelpText": "Alternativer Stil, um farbbeeinträchtigten Benutzern eine bessere Unterscheidung farbcodierter Informationen zu ermöglichen", + "SettingsFilterSentryEvents": "Analystische Ergeinisse filtern", + "SettingsFilterSentryEventsHelpText": "Sende keine bekannten Benutzerfehler Ereignisse an Analystics", + "SettingsIndexerLogging": "Verbesserte Indexer-Protokollierung", + "SettingsIndexerLoggingHelpText": "Erweiterte Indexerdaten loggen inklusive Antwort", + "SettingsLogRotate": "Logrotation", + "SettingsLogRotateHelpText": "Max. Anzahl der zu behaltenden Logdateien", + "SettingsLogSql": "Log SQL", + "SettingsLongDateFormat": "Langes Datumsformat", + "SettingsShortDateFormat": "Kurzes Datumsformat", + "SettingsShowRelativeDates": "Relatives Datum anzeigen", + "SettingsShowRelativeDatesHelpText": "Relatives (z.B.: Heute, gestern, etc) oder absolutes Datum anzeigen", + "SettingsSqlLoggingHelpText": "Log alle SQL Abfragen von Prowlarr", + "SettingsTimeFormat": "Zeitformat", + "ShowAdvanced": "Einfache Ansicht", + "ShowSearch": "Suche anzeigen", + "ShowSearchHelpText": "Suchbutton anzeigen beim draufzeigen", + "ShownClickToHide": "Angezeigt, zum verstecken klicken", + "Shutdown": "Herunterfahren", + "Size": "Größe", + "Sort": "Sortieren", + "Source": "Quelle", + "StartTypingOrSelectAPathBelow": "Eingeben oder unten auswählen", + "Started": "gestartet", + "StartupDirectory": "Start-Verzeichnis", + "Stats": "Statistiken", + "Status": "Status", + "Style": "Stil", + "SuggestTranslationChange": "Schlage eine Übersetzung vor", + "SyncAppIndexers": "App Indexer syncen", + "SyncLevel": "Sync-Level", + "SyncLevelAddRemove": "Nur hinzufügen und entfernen: Wenn Indexer zu Prowlarr hinzugefügt oder entfernt werden, wird diese Remote-App aktualisiert.", + "SyncLevelFull": "Vollständige Synchronisierung: Hält die Indexer dieser App vollständig synchronisiert. Änderungen an Indexern in Prowlarr werden mit dieser App synchronisiert. Jede Änderung die and Indexern dieser App gemacht werden, wird von Prowlarr bei der nächsten Synchronisierung überschrieben.", + "SyncProfile": "Sync-Profile", + "SyncProfiles": "Sync-Profile", + "System": "System", + "SystemTimeCheckMessage": "Die Systemzeit ist um einen Tag versetzt. Bis die Zeit korrigiert wurde, könnten die geplanten Aufgaben nicht korrekt ausgeführt werden", + "TVSearchTypes": "Suchtyp", + "TableOptions": "Tabellen Optionen", + "TableOptionsColumnsMessage": "Wähle aus welche Spalten angezeigt werden und in welcher Reihenfolge", + "TagCannotBeDeletedWhileInUse": "Kann während der Benutzung nicht gelöscht werden", + "TagIsNotUsedAndCanBeDeleted": "Tag wird nicht benutzt und kann gelöscht werden", + "Tags": "Tags", + "TagsHelpText": "Wird auf Filme mit mindestens einem passenden Tag angewandt", + "TagsSettingsSummary": "Alle Tags und deren Benutzung anzeigen. Unbenutzte Tags können entfernt werden", + "Tasks": "Aufgaben", + "Test": "Testen", + "TestAll": "Alle testen", + "TestAllApps": "Alle Apps testen", + "TestAllClients": "Alle testen", + "TestAllIndexers": "Alle testen", + "TheLatestVersionIsAlreadyInstalled": "Die aktuellste Version ist bereits installiert", + "ThemeHelpText": "Ändere das UI-Theme der Anwendung. Das 'Auto'-Theme verwendet dein Betriebssystem-Theme, um den hellen oder dunklen Modus einzustellen. Inspiriert von {0}", + "Time": "Zeit", + "Title": "Titel", + "Today": "Heute", + "Tomorrow": "Morgen", + "Torrent": "Torrent", + "Torrents": "Torrents", + "TvSearch": "TV Suche", + "Type": "Typ", + "UI": "Oberfläche", + "UILanguage": "Oberflächen Sprache ( UI Language )", + "UILanguageHelpText": "Sprache für die gesamte Oberfläche", + "UILanguageHelpTextWarning": "Webseite muss neu geladen werden", + "UISettings": "Benutzeroberflächen Einstellungen", + "UISettingsSummary": "Optionen für Datum, Sprache und Farbbeinträchtigungen", + "URLBase": "URL-Basis", + "UnableToAddANewAppProfilePleaseTryAgain": "Es kann kein neues Anwendungsprofil hinzugefügt werden. Bitte versuchen Sie es erneut.", + "UnableToAddANewApplicationPleaseTryAgain": "Es kann keine neue Anwendung hinzugefügt werden. Bitte versuchen Sie es erneut.", + "UnableToAddANewDownloadClientPleaseTryAgain": "Der neue Downloader konnte nicht hinzugefügt werden, bitte erneut probieren.", + "UnableToAddANewIndexerPleaseTryAgain": "Der neue Indexer konnte nicht hinzugefügt werden, bitte erneut probieren.", + "UnableToAddANewIndexerProxyPleaseTryAgain": "Der neue Indexer konnte nicht hinzugefügt werden, bitte erneut probieren.", + "UnableToAddANewNotificationPleaseTryAgain": "Die neue Benachrichtigung konnte nicht hinzugefügt werden, bitte erneut probieren.", + "UnableToLoadAppProfiles": "App-Profile können nicht geladen werden", + "UnableToLoadApplicationList": "Anwendungsliste kann nicht geladen werden", + "UnableToLoadBackups": "Backups konnten nicht geladen werden", + "UnableToLoadDevelopmentSettings": "Entwicklereinstellungen konnten nicht geladen werden", + "UnableToLoadDownloadClients": "Downloader konnten nicht geladen werden", + "UnableToLoadGeneralSettings": "Allgemeine Einstellungen konnten nicht geladen werden", + "UnableToLoadHistory": "Verlauf konnte nicht geladen werden", + "UnableToLoadIndexerProxies": "Indexer-Proxies können nicht geladen werden", + "UnableToLoadIndexers": "Indexer konnten nicht geladen werden", + "UnableToLoadNotifications": "Benachrichtigungen konnten nicht geladen werden", + "UnableToLoadTags": "Tags konnten nicht geladen werden", + "UnableToLoadUISettings": "Oberflächen Einstellungen konnten nicht geladen werden", + "UnsavedChanges": "Ungespeicherte Änderungen", + "UnselectAll": "Keine wählen", + "UpdateAutomaticallyHelpText": "Updates automatisch herunteraden und installieren. Es kann weiterhin unter \"System -> Updates\" ein manuelles Update angestoßen werden", + "UpdateCheckStartupNotWritableMessage": "Update kann nicht installiert werden, da der Startordner '{0}' vom Benutzer '{1}' nicht beschreibbar ist.", + "UpdateCheckStartupTranslocationMessage": "Update kann nicht installiert werden, da sich der Startordner '{0}' in einem App Translocation-Ordner befindet.", + "UpdateCheckUINotWritableMessage": "Update kann nicht installiert werden, da der Benutzeroberflächenordner '{0}' vom Benutzer '{1}' nicht beschreibbar ist.", + "UpdateMechanismHelpText": "Benutze Prowlarr's Built-In Updater oder ein Script", + "UpdateScriptPathHelpText": "Pfad zu einem benutzerdefinierten Skript, das ein extrahiertes Update-Paket übernimmt und den Rest des Update-Prozesses abwickelt", + "Updates": "Updates", + "Uptime": "Laufzeit", + "Url": "Url", + "UrlBaseHelpText": "Für Reverse-Proxy-Unterstützung. Die Standardeinstellung leer", + "UseProxy": "Proxy benutzen", + "Usenet": "Usenet", + "UserAgentProvidedByTheAppThatCalledTheAPI": "UserAgent von der App welcher die API aufgerufen hat", + "Username": "Benutzername", + "Version": "Version", + "View": "Ansicht", + "Warn": "Warnung", + "Website": "Webseite", + "Wiki": "Wiki", + "Yes": "Ja", + "YesCancel": "Ja, abbrechen", + "Yesterday": "Gestern" } diff --git a/src/NzbDrone.Core/Localization/Core/nl.json b/src/NzbDrone.Core/Localization/Core/nl.json index 2f6033367..9bdf550f0 100644 --- a/src/NzbDrone.Core/Localization/Core/nl.json +++ b/src/NzbDrone.Core/Localization/Core/nl.json @@ -1,430 +1,434 @@ { - "Indexers": "Indexeerders", - "Host": "Host", - "History": "Geschiedenis", - "HideAdvanced": "Verberg Gevorderd", - "Health": "Gezondheid", - "General": "Algemeen", - "Folder": "Map", - "Filter": "Filter", - "Files": "Bestanden", - "Events": "Gebeurtenissen", - "Edit": "Bewerk", - "DownloadClientStatusCheckSingleClientMessage": "Downloaders onbeschikbaar wegens fouten: {0}", - "DownloadClientStatusCheckAllClientMessage": "Alle downloaders zijn onbeschikbaar wegens fouten", - "DownloadClients": "Downloaders", - "Delete": "Verwijderen", - "Dates": "Datum en tijd", - "Date": "Datum", - "CustomFilters": "Aangepaste Filters", - "Connections": "Connecties", - "Connect": "Meldingen", - "Clear": "Wissen", - "BackupNow": "Veiligheidskopie Maken", - "Analytics": "Statistieken", - "Backup": "Veiligheidskopie", - "AppDataLocationHealthCheckMessage": "Updaten zal niet mogelijk zijn om het verwijderen van AppData te voorkomen", - "All": "Alles", - "About": "Over", - "View": "Weergave", - "UnselectAll": "Alles Deselecteren", - "Tasks": "Taken", - "System": "Systeem", - "Style": "Stijl", - "Status": "Status", - "Sort": "Sorteer", - "Settings": "Instellingen", - "SelectAll": "Alles Selecteren", - "Security": "Beveiliging", - "Search": "Zoeken", - "Scheduled": "Gepland", - "SaveChanges": "Wijzigingen Opslaan", - "RestoreBackup": "Veiligheidskopie Herstellen", - "Refresh": "Vernieuw", - "Queue": "Wachtrij", - "Proxy": "Proxy", - "Options": "Opties", - "NoChanges": "Geen Wijzigingen", - "NoChange": "Geen Wijziging", - "MoreInfo": "Meer Info", - "Logging": "Logbeheer", - "LogFiles": "Logbestanden", - "Language": "Taal", - "ShowAdvanced": "Toon Geavanceerd", - "UpdateCheckUINotWritableMessage": "Kan de update niet installeren omdat de UI map '{0}' niet schrijfbaar is voor de gebruiker '{1}'.", - "UpdateCheckStartupTranslocationMessage": "Kan de update niet installeren omdat de map '{0}' zich in een 'App Translocation' map bevindt.", - "UpdateCheckStartupNotWritableMessage": "Kan de update niet installeren omdat de map '{0}' niet schrijfbaar is voor de gebruiker '{1}'.", - "IndexerStatusCheckSingleClientMessage": "Indexeerders onbeschikbaar wegens fouten: {0}", - "IndexerStatusCheckAllClientMessage": "Alle indexeerders zijn onbeschikbaar wegens fouten", - "Updates": "Updates", - "Tags": "Tags", - "SetTags": "Tags Toepassen", - "UI": "Gebruikersinterface", - "ReleaseBranchCheckOfficialBranchMessage": "Branch {0} is geen geldige Prowlarr release branch, u zult geen updates ontvangen", - "ProxyCheckResolveIpMessage": "Achterhalen van het IP-adres voor de geconfigureerde proxy host {0} is mislukt", - "ProxyCheckFailedToTestMessage": "Testen van proxy is mislukt: {0}", - "ProxyCheckBadRequestMessage": "Testen van proxy is mislukt. Statuscode: {0}", - "UISettingsSummary": "Datum, kleurenblindheid en taal instellingen", - "TagsSettingsSummary": "Bekijk alle tags en hun gebruik. Ongebruikte tags kunnen worden verwijderd", - "Size": "Grootte", - "ReleaseStatus": "Uitgave Status", - "Protocol": "Protocol", - "LastWriteTime": "Laatste Modificatietijd", - "Indexer": "Indexeerder", - "Grabbed": "Opgehaalde", - "GeneralSettingsSummary": "Poort, SSL, gebruikersnaam/wachtwoord, proxy, statistieken en updates", - "Filename": "Bestandsnaam", - "Failed": "Mislukt", - "EventType": "Gebeurtenis Type", - "DownloadClientsSettingsSummary": "Clientconfiguratie downloaden voor integratie in Prowlarr UI-zoekopdracht", - "DownloadClient": "Downloader", - "Details": "Details", - "ConnectSettingsSummary": "Meldingen en aangepaste scripts", - "Added": "Toegevoegd", - "Actions": "Acties", - "Seeders": "Seeders", - "Peers": "Peers", - "Warn": "Waarschuwing", - "Type": "Type", - "Title": "Titel", - "Time": "Tijd", - "TestAll": "Test Alle", - "Test": "Test", - "TableOptionsColumnsMessage": "Kies welke kolommen zichtbaar zijn en in welke volgorde", - "TableOptions": "Tabel Opties", - "SystemTimeCheckMessage": "De systeemtijd loopt verkeerd met meer dan 1 dag. Geplande taken worden mogelijk niet goed uitgevoerd tot dit is opgelost", - "Source": "Bron", - "Shutdown": "Afsluiten", - "Save": "Opslaan", - "Restart": "Herstart", - "Reload": "Herlaad", - "PageSize": "Pagina Grootte", - "Ok": "Ok", - "OAuthPopupMessage": "Pop-ups worden geblokkeerd door uw browser", - "Name": "Naam", - "Message": "Bericht", - "Level": "Niveau", - "KeyboardShortcuts": "Sneltoetsen", - "Info": "Info", - "HealthNoIssues": "Geen problemen gevonden met uw configuratie", - "Error": "Fout", - "ConnectionLostMessage": "Prowlarr heeft zijn verbinding met de backend verloren en zal moeten worden herladen om functionaliteit te herstellen.", - "ConnectionLostAutomaticMessage": "Prowlarr zal automatisch proberen te verbinden, of u kunt hieronder op herladen klikken.", - "ConnectionLost": "Verbinding Onderbroken", - "Component": "Onderdeel", - "Columns": "Kolommen", - "Close": "Sluit", - "Cancel": "Annuleer", - "Apply": "Toepassen", - "Age": "Leeftijd", - "UnsavedChanges": "Onopgeslagen Wijzigingen", - "ShowSearchHelpText": "Toon zoeken knop bij zweven", - "ShowSearch": "Toon Zoeken", - "SettingsTimeFormat": "Tijdsformaat", - "SettingsShowRelativeDatesHelpText": "Toon relatieve (Vandaag/Gisteren/enz.) of absolute datums", - "SettingsShowRelativeDates": "Toon Relatieve Datums", - "SettingsShortDateFormat": "Korte Datumnotatie", - "SettingsLongDateFormat": "Lange Datumnotatie", - "SettingsEnableColorImpairedModeHelpText": "Aangepaste stijl voor gebruikers die kleurenblind zijn om gemakkelijker kleurgecodeerde informatie te onderscheiden", - "SettingsEnableColorImpairedMode": "Activeer Kleurenblindheid-modus", - "PendingChangesStayReview": "Blijf en bekijk de wijzigingen", - "PendingChangesMessage": "U heeft onopgeslagen wijzigingen, bent u zeker dat u deze pagina wilt sluiten?", - "PendingChangesDiscardChanges": "Wijzigingen verwerpen en verdergaan", - "Interval": "Tussentijd", - "Fixed": "Opgelost", - "Automatic": "Automatisch", - "AuthenticationMethodHelpText": "Gebruikersnaam en wachtwoord nodig voor toegang tot Prowlarr", - "Authentication": "Authenticatie", - "AppDataDirectory": "AppData map", - "AnalyticsEnabledHelpText": "Stuur anonieme gebruiks- en foutinformatie naar de servers van Prowlarr. Dit omvat informatie over uw browser, welke Prowlarr WebUI pagina's u gebruikt, foutrapportage en OS en runtime versie. We zullen deze informatie gebruiken om prioriteiten te stellen voor functies en het verhelpen van fouten.", - "YesCancel": "Ja, Annuleren", - "DeleteTag": "Verwijder Tag", - "DeleteNotification": "Verwijder Notificatie", - "DeleteDownloadClient": "Verwijder Downloader", - "Enable": "Activeer", - "DownloadClientSettings": "Downloader Instellingen", - "Docker": "Docker", - "DBMigration": "DB Migratie", - "ConnectSettings": "Connecties Instellingen", - "CloneProfile": "Dupliceer Profiel", - "ClientPriority": "Client Prioriteit", - "ChangeHasNotBeenSavedYet": "Wijziging is nog niet opgeslagen", - "CertificateValidationHelpText": "Wijzig hoe strikt HTTPS certificaat validatie is", - "CertificateValidation": "Certificaat Validatie", - "BypassProxyForLocalAddresses": "Omzeil Proxy voor Lokale Adressen", - "Branch": "Branch", - "BindAddressHelpText": "Geldig IP-adres, localhost of '*' voor alle interfaces", - "DeleteBackup": "Verwijder Veiligheidskopie", - "BackupIntervalHelpText": "Tussentijd voor automatische back-up", - "Backups": "Veiligheidskopieën", - "BackupRetentionHelpText": "Automatische veiligheidskopieën ouder dan de retentie periode zullen worden opgeruimd", - "BackupFolderHelpText": "Relatieve paden zullen t.o.v. de Prowlarr AppData map bekeken worden", - "AreYouSureYouWantToResetYourAPIKey": "Bent u zeker dat u uw API-sleutel wilt resetten?", - "ApplyTags": "Tags Toepassen", - "ApiKey": "API-sleutel", - "IllRestartLater": "Ik zal later herstarten", - "IgnoredAddresses": "Genegeerde Adressen", - "Hostname": "Hostnaam", - "GeneralSettings": "Algemene Instellingen", - "EnableSSL": "Activeer SSL", - "EnableInteractiveSearch": "Activeer Interactief Zoeken", - "EnableAutomaticSearch": "Activeer Automatisch Zoeken", - "PortNumber": "Poort Nummer", - "Port": "Poort", - "Password": "Wachtwoord", - "PackageVersion": "Pakket Versie", - "OnHealthIssueHelpText": "Bij Gezondheidsprobleem", - "NoLeaveIt": "Nee, Ongemoeid Laten", - "New": "Nieuw", - "Mode": "Modus", - "Mechanism": "Mechanisme", - "Logs": "Logbestanden", - "LogLevel": "Log Niveau", - "BindAddress": "Aanhaak Adres", - "IndexerFlags": "Indexeerder Flags", - "EnableSslHelpText": " Vereist herstart als administrator om in werking te treden", - "PriorityHelpText": "Geef prioriteit aan meerdere downloaders. Round-Robin wordt gebruikt voor downloaders met dezelfde prioriteit.", - "SendAnonymousUsageData": "Zend Anonieme Gebruiksdata", - "UnableToLoadNotifications": "Notificaties kunnen niet worden geladen", - "UpdateAutomaticallyHelpText": "Download en installeer updates automatisch. Je zal nog steeds kunnen installeren vanuit Systeem: Updates", - "UrlBaseHelpText": "Voor reverse proxy ondersteuning, leeg is standaard", - "IncludeHealthWarningsHelpText": "Voeg Gezondheidswaarschuwingen Toe", - "LaunchBrowserHelpText": " Open een web browser en navigeer naar de Prowlarr startpagina bij het starten van de app.", - "MIA": "MIA", - "NotificationTriggers": "Melding Reactiestarters", - "OpenBrowserOnStart": "Open de browser bij het starten", - "PageSizeHelpText": "Aantal items om te tonen op iedere pagina", - "NetCore": ".NET", - "ProxyPasswordHelpText": "Je moet alleen een gebruikersnaam en wachtwoord ingeven als dit vereist is, laat ze anders leeg.", - "ProxyUsernameHelpText": "Je moet alleen een gebruikersnaam en wachtwoord ingeven als dit vereist is, laat ze anders leeg.", - "ReadTheWikiForMoreInformation": "Lees de Wiki voor meer informatie", - "RefreshMovie": "Film vernieuwen", - "ProxyType": "Proxy Type", - "ProxyBypassFilterHelpText": "Gebruik ',' als scheidingsteken en '*' als wildcard voor subdomeinen", - "RemovedFromTaskQueue": "Verwijderd uit taken wachtrij", - "RemoveFilter": "Verwijder filter", - "Reset": "Reset", - "RestartNow": "Herstart Nu", - "RestartProwlarr": "Herstart Prowlarr", - "RestartRequiredHelpTextWarning": "Herstarten vereist om in werking te treden", - "Result": "Resultaat", - "Retention": "Retentie", - "ScriptPath": "Script Pad", - "ResetAPIKey": "Reset API-sleutel", - "SSLCertPassword": "SSL Certificaat Wachtwoord", - "SSLCertPath": "SSL Certificaat Pad", - "SSLPort": "SSL Poort", - "StartupDirectory": "Opstart map", - "SuggestTranslationChange": "Stel vertaling voor", - "TagsHelpText": "Is van toepassing op films met minstens één overeenkomende tag", - "TestAllClients": "Test Alle Downloaders", - "Torrents": "Torrents", - "UISettings": "Gebruikersinterface Instellingen", - "UnableToLoadDownloadClients": "Downloaders kunnen niet worden geladen", - "UnableToLoadTags": "Tags kunnen niet worden geladen", - "UpdateMechanismHelpText": "Gebruik het ingebouwde updatemechanisme of een extern script", - "UpdateScriptPathHelpText": "Pad naar een aangepast script dat een uitgepakt updatepakket accepteert en de rest van het updateproces afhandelt", - "Uptime": "Bedrijfstijd", - "URLBase": "URL Basis", - "Usenet": "Usenet", - "UseProxy": "Gebruik Proxy", - "Username": "Gebruikersnaam", - "Version": "Versie", - "TagCannotBeDeletedWhileInUse": "Kan niet verwijderd worden terwijl in gebruik", - "SSLCertPathHelpText": "Pad naar pfx bestand", - "SSLCertPasswordHelpText": "Wachtwoord voor pfx bestand", - "ShownClickToHide": "Getoond, klik om te verbergen", - "RSSIsNotSupportedWithThisIndexer": "RSS wordt niet ondersteund door deze indexeerder", - "RemovingTag": "Tag verwijderen", - "Manual": "Manueel", - "LogLevelTraceHelpTextWarning": "Trace log niveau moet enkel tijdelijk worden gebruikt", - "HiddenClickToShow": "Verborgen, klik om te tonen", - "ExistingTag": "Bestaande tag", - "EnableInteractiveSearchHelpText": "Zal worden gebruikt wanneer interactief zoeken wordt gebruikt", - "EnableAutomaticSearchHelpText": "Zal worden gebruikt wanneer automatische zoekopdrachten worden uitgevoerd via de gebruikersinterface of door Prowlarr", - "DeleteTagMessageText": "Bent u zeker dat u de tag '{0}' wilt verwijderen?", - "DeleteNotificationMessageText": "Bent u zeker dat u de notificatie '{0}' wilt verwijderen?", - "DeleteDownloadClientMessageText": "Bent u zeker dat u de downloader '{0}' wilt verwijderen?", - "DeleteBackupMessageText": "Bent u zeker dat u de veiligheidskopie '{0}' wilt verwijderen?", - "CancelPendingTask": "Bent u zeker dat u deze taak in afwachting wilt annuleren?", - "BranchUpdateMechanism": "Gebruikte branch door extern update mechanisme", - "BranchUpdate": "Te gebruiken branch om Prowlarr bij te werken", - "BeforeUpdate": "Voor de update", - "AddingTag": "Tag toevoegen", - "UnableToLoadUISettings": "Kon gebruikersinterface instellingen niet inladen", - "UnableToLoadGeneralSettings": "Kon Algemene instellingen niet inladen", - "UnableToAddANewNotificationPleaseTryAgain": "Kon geen nieuwe notificatie toevoegen, gelieve opnieuw te proberen.", - "UnableToAddANewIndexerPleaseTryAgain": "Kon geen nieuwe indexeerder toevoegen, gelieve opnieuw te proberen.", - "UnableToAddANewDownloadClientPleaseTryAgain": "Kon geen nieuwe downloader toevoegen, gelieve opnieuw te proberen.", - "ProwlarrSupportsAnyIndexer": "Prowlarr ondersteunt veel indexeerders naast elke indexeerder die de Newznab/Torznab-standaard gebruikt met 'Generic Newznab' (voor usenet) of 'Generic Torznab' (voor torrents). Zoek en selecteer uw indexeerder hieronder.", - "ProwlarrSupportsAnyDownloadClient": "Prowlarr ondersteund elke downloader die gebruik maakt van de Newznab standaard, tevens ook de ander hieronder weergegeven downloaders.", - "NoTagsHaveBeenAddedYet": "Er zijn nog geen tags toegevoegd", - "ForMoreInformationOnTheIndividualDownloadClients": "Voor meer informatie over de individuele downloaders, klik op de info knoppen.", - "ApplyTagsHelpTexts4": "Vervangen: Vervang de tags met de ingevoerde tags (voer geen tags in om alle tags te wissen)", - "ApplyTagsHelpTexts3": "Verwijderen: Verwijder de ingevoerde tags", - "ApplyTagsHelpTexts2": "Toevoegen: Voeg de tags toe aan de lijst met bestaande tags", - "ApplyTagsHelpTexts1": "Hoe tags toe te passen op de geselecteerd films", - "UnableToLoadHistory": "Kon geschiedenis niet laden", - "UnableToLoadBackups": "Kon geen veiligheidskopieën laden", - "TagIsNotUsedAndCanBeDeleted": "Tag is niet in gebruik en kan verwijderd worden", - "StartTypingOrSelectAPathBelow": "Begin met typen of selecteer een pad hier beneden", - "Restore": "Herstellen", - "NoUpdatesAreAvailable": "Geen updates beschikbaar", - "NoLogFiles": "Geen logbestanden", - "NoBackupsAreAvailable": "Geen veiligheidskopieën beschikbaar", - "MaintenanceRelease": "Onderhoudsuitgave", - "FilterPlaceHolder": "Zoek indexeerder", - "Exception": "Uitzondering", - "ErrorLoadingContents": "Fout bij laden van inhoud", - "UILanguageHelpTextWarning": "Browser Herladen Vereist", - "UILanguageHelpText": "Taal die Prowlarr zal gebruiken voor de gebruikersinterface", - "UILanguage": "Gebruikersinterface Taal", - "Priority": "Prioriteit", - "InteractiveSearch": "Interactief Zoeken", - "IndexerPriorityHelpText": "Indexeerder Prioriteit van 1 (Hoogste) tot 50 (Laagste). Standaard: 25.", - "IndexerPriority": "Indexeerder Prioriteit", - "EditIndexer": "Bewerk Indexeerder", - "Disabled": "Uitgeschakeld", - "AutomaticSearch": "Automatisch Zoeken", - "AddIndexer": "Voeg Indexeerder Toe", - "FocusSearchBox": "Focus Zoekvak", - "CloseCurrentModal": "Sluit Huidig Bericht", - "AcceptConfirmationModal": "Accepteer Bevestigingsbericht", - "Yesterday": "Gisteren", - "Tomorrow": "Morgen", - "Today": "Vandaag", - "SaveSettings": "Instellingen Opslaan", - "MovieIndexScrollTop": "Film Index: Scroll omhoog", - "MovieIndexScrollBottom": "Film Index: Scroll naar onder", - "IndexerLongTermStatusCheckSingleClientMessage": "Indexeerders zijn niet beschikbaar vanwege storingen gedurende meer dan 6 uur: {0}", - "IndexerLongTermStatusCheckAllClientMessage": "Alle indexeerders zijn niet beschikbaar vanwege storingen gedurende meer dan 6 uur", - "ClearHistoryMessageText": "Weet je zeker dat je alle geschiedenis van Prowlarr wilt verwijderen?", - "ClearHistory": "Geschiedenis verwijderen", - "ApplicationStatusCheckSingleClientMessage": "Applicaties onbeschikbaar door fouten", - "ApplicationStatusCheckAllClientMessage": "Alle applicaties onbeschikbaar door fouten", - "AllIndexersHiddenDueToFilter": "Alle indexeerders zijn verborgen door actieve filter.", - "AddToDownloadClient": "Release toevoegen aan download client", - "AddNewIndexer": "Voeg nieuwe Indexeerder Toe", - "AddedToDownloadClient": "Release toegevoegd aan client", - "PrioritySettings": "Prioriteit", - "AddDownloadClient": "Download Client Toevoegen", - "Add": "Toevoegen", - "Applications": "Applicaties", - "AddRemoveOnly": "Alleen toevoegen en verwijderen", - "DeleteAppProfile": "App-profiel verwijderen", - "Discord": "Discord", - "Query": "Vraag", - "IndexerVipCheckExpiringClientMessage": "Indexeerder VIP-voordelen verlopen binnenkort: {0}", - "NoLinks": "Geen koppelingen", - "Privacy": "Privacy", - "RedirectHelpText": "Leid inkomend downloadverzoek voor indexeerder om en geef de grijper direct door in plaats van het verzoek via Prowlarr te proxyen", - "SettingsLogSql": "Log Sql", - "SettingsSqlLoggingHelpText": "Log alle SQL-query's van Prowlarr", - "Stats": "Statistieken", - "SyncLevel": "Synchronisatieniveau", - "Torrent": "Torrent", - "UnableToAddANewApplicationPleaseTryAgain": "Kan geen nieuwe toepassing toevoegen, probeer het opnieuw.", - "UnableToAddANewAppProfilePleaseTryAgain": "Kan geen nieuw applicatieprofiel toevoegen. Probeer het opnieuw.", - "UnableToAddANewIndexerProxyPleaseTryAgain": "Kan geen nieuwe Indexeerder-proxy toevoegen. Probeer het opnieuw.", - "UnableToLoadAppProfiles": "Kan app-profielen niet laden", - "UnableToLoadDevelopmentSettings": "Kan ontwikkelingsinstellingen niet laden", - "UnableToLoadIndexerProxies": "Kan Indexeerder-proxy's niet laden", - "SettingsFilterSentryEventsHelpText": "Filter bekende gebruikersfoutgebeurtenissen zodat ze niet als Analytiek worden verzonden", - "HomePage": "Startpagina", - "IndexerProxies": "Indexer-proxy's", - "IndexerObsoleteCheckMessage": "Indexeerders zijn verouderd of zijn bijgewerkt: {0}. Gelieve te verwijderen en (of) opnieuw toe te voegen aan Prowlarr", - "SettingsIndexerLogging": "Verbeterde logboekregistratie van Indexeerder", - "EnableRss": "RSS inschakelen", - "Reddit": "Reddit", - "Apps": "Applicaties", - "Auth": "Authenticatie", - "Custom": "Aangepast", - "DevelopmentSettings": "Ontwikkelingsinstellingen", - "Description": "Beschrijving", - "Donations": "Donaties", - "EnableRssHelpText": "Rss-feed voor Indexer inschakelen", - "IndexersSelectedInterp": "{0} Indexer(s) Geselecteerd", - "IndexerRss": "Indexeer RSS", - "IndexerAuth": "Indexer-authenticatie", - "FeatureRequests": "Functieverzoeken", - "IndexerSettingsSummary": "Configureer verschillende globale Indexer-instellingen, waaronder proxy's.", - "OpenThisModal": "Open deze modal", - "AppProfileDeleteConfirm": "Weet u zeker dat u {0} wilt verwijderen?", - "AppSettingsSummary": "Applicaties en instellingen om te configureren hoe Prowlarr met uw PVR-programma's omgaat", - "Category": "Categorie", - "IndexerTagsHelpText": "Gebruik tags om standaardclients op te geven, Indexeerder-proxy's op te geven of gewoon om uw indexeerders te ordenen.", - "IndexerVipCheckExpiredClientMessage": "Indexeerder VIP-voordelen zijn verlopen: {0}", - "NoSearchResultsFound": "Geen zoekresultaten gevonden, probeer hieronder een nieuwe zoekopdracht.", - "Notification": "Melding", - "Notifications": "Meldingen", - "Presets": "Voorinstellingen", - "Redirect": "Omleiden", - "RSS": "RSS", - "SearchIndexers": "Zoek indexeerders", - "SettingsConsoleLogLevel": "Console-logboekniveau", - "SettingsFilterSentryEvents": "Analytics-gebeurtenissen filteren", - "SettingsIndexerLoggingHelpText": "Log aanvullende Indexeerder-gegevens inclusief reactie", - "SettingsLogRotate": "Logboekrotatie", - "SettingsLogRotateHelpText": "Maximaal aantal logbestanden om te bewaren in de logboek-map", - "SyncAppIndexers": "App-indexeerders synchroniseren", - "SyncLevelAddRemove": "Alleen toevoegen en verwijderen: wanneer het wordt toegevoegd of verwijderd uit Prowlarr, wordt deze externe app bijgewerkt.", - "SyncLevelFull": "Volledige synchronisatie: houdt deze app volledig gesynchroniseerd. Wijzigingen in Prowlarr worden vervolgens gesynchroniseerd met deze app. Elke wijziging die op afstand wordt aangebracht, wordt bij de volgende synchronisatie overschreven door Prowlarr.", - "TestAllApps": "Alle apps testen", - "Wiki": "Wiki", - "Grabs": "Gegrepen", - "NotificationTriggersHelpText": "Selecteer welke gebeurtenissen deze melding moeten activeren", - "AddDownloadClientToProwlarr": "Door een downloadclient toe te voegen, kan Prowlarr releases rechtstreeks vanuit de gebruikersinterface verzenden tijdens een handmatige zoekopdracht.", - "AddIndexerProxy": "Indexeerproxy toevoegen", - "AppProfileInUse": "App-profiel in gebruik", - "AppProfileSelectHelpText": "App-profielen worden gebruikt om de instellingen voor RSS, Automatisch zoeken en Interactief zoeken bij applicatiesynchronisatie te beheren", - "CouldNotConnectSignalR": "Kan geen verbinding maken met SignalR, gebruikersinterface wordt niet bijgewerkt", - "DeleteApplication": "Applicatie verwijderen", - "DeleteApplicationMessageText": "Weet u zeker dat u de applicatie '{0}' wilt verwijderen?", - "DeleteIndexerProxy": "Indexeerproxy verwijderen", - "DeleteIndexerProxyMessageText": "Weet u zeker dat u de proxy '{0}' wilt verwijderen?", - "Enabled": "Ingeschakeld", - "EnableIndexer": "Indexer inschakelen", - "Encoding": "Coderen", - "FullSync": "Volledige synchronisatie", - "Id": "Id", - "IndexerHealthCheckNoIndexers": "Geen indexers ingeschakeld, Prowlarr geeft geen zoekresultaten terug", - "IndexerProxy": "Indexeerder-proxy", - "IndexerProxyStatusCheckAllClientMessage": "Alle proxy's zijn niet beschikbaar vanwege storingen", - "IndexerProxyStatusCheckSingleClientMessage": "Proxy's niet beschikbaar vanwege storingen: {0}", - "IndexerQuery": "Indexeer zoekopdracht", - "HistoryCleanupDaysHelpText": "Zet op 0 om automatisch opschonen uit te schakelen", - "HistoryCleanupDaysHelpTextWarning": "Bestanden in de prullenbak ouder dan het geselecteerde aantal dagen zullen automatisch opgeschoond worden", - "OnGrab": "Bij Ophalen", - "OnHealthIssue": "Bij Gezondheidsprobleem", - "Filters": "Filters", - "TestAllIndexers": "Test Alle Indexeerders", - "UserAgentProvidedByTheAppThatCalledTheAPI": "User-Agent geleverd door de app die de API heeft aangeroepen", - "Application": "Applicaties", - "Link": "Koppelingen", - "MappedDrivesRunningAsService": "Toegewezen netwerkstation is niet beschikbaar wanneer Prowlarr wordt uitgevoerd als een Windows Service. Bekijk de Veelgestelde Vragen voor meer informatie", - "No": "Nee", - "UnableToLoadIndexers": "Indexeerders kunnen niet worden geladen", - "GrabReleases": "Uitgave Ophalen", - "Yes": "Ja", - "OnApplicationUpdateHelpText": "Bij applicatie update", - "Database": "Databasis", - "OnApplicationUpdate": "Bij applicatie update", - "Duration": "Duur", - "Ended": "Beëindigd", - "NextExecution": "Volgende uitvoering", - "ApplicationLongTermStatusCheckAllClientMessage": "Alle indexeerders zijn niet beschikbaar vanwege storingen gedurende meer dan 6 uur", - "ApplicationLongTermStatusCheckSingleClientMessage": "Indexeerders zijn niet beschikbaar vanwege storingen gedurende meer dan 6 uur: {0}", - "LastDuration": "Laatste Looptijd", - "LastExecution": "Laatste Uitvoering", - "Queued": "Afwachtend", - "Categories": "Categorieën", - "AddSyncProfile": "Synchronisatieprofiel toevoegen", - "AudioSearch": "auditief zoeken", - "EditSyncProfile": "Synchronisatieprofiel toevoegen", - "Remove": "Verwijder", - "Replace": "Vervangen", - "TheLatestVersionIsAlreadyInstalled": "De nieuwste versie van Prowlarr is al geïnstalleerd", - "AddApplication": "Applicatie Toevoegen", - "Album": "Album", - "AddCustomFilter": "Aangepaste Filter Toevoegen" + "About": "Over", + "AcceptConfirmationModal": "Accepteer Bevestigingsbericht", + "Actions": "Acties", + "Add": "Toevoegen", + "AddApplication": "Applicatie Toevoegen", + "AddCustomFilter": "Aangepaste Filter Toevoegen", + "AddDownloadClient": "Download Client Toevoegen", + "AddDownloadClientToProwlarr": "Door een downloadclient toe te voegen, kan Prowlarr releases rechtstreeks vanuit de gebruikersinterface verzenden tijdens een handmatige zoekopdracht.", + "AddIndexer": "Voeg Indexeerder Toe", + "AddIndexerProxy": "Indexeerproxy toevoegen", + "AddNewIndexer": "Voeg nieuwe Indexeerder Toe", + "AddRemoveOnly": "Alleen toevoegen en verwijderen", + "AddSyncProfile": "Synchronisatieprofiel toevoegen", + "AddToDownloadClient": "Release toevoegen aan download client", + "Added": "Toegevoegd", + "AddedToDownloadClient": "Release toegevoegd aan client", + "AddingTag": "Tag toevoegen", + "Age": "Leeftijd", + "Album": "Album", + "All": "Alles", + "AllIndexersHiddenDueToFilter": "Alle indexeerders zijn verborgen door actieve filter.", + "Analytics": "Statistieken", + "AnalyticsEnabledHelpText": "Stuur anonieme gebruiks- en foutinformatie naar de servers van Prowlarr. Dit omvat informatie over uw browser, welke Prowlarr WebUI pagina's u gebruikt, foutrapportage en OS en runtime versie. We zullen deze informatie gebruiken om prioriteiten te stellen voor functies en het verhelpen van fouten.", + "ApiKey": "API-sleutel", + "ApiKeyValidationHealthCheckMessage": "Maak je API sleutel alsjeblieft minimaal {0} karakters lang. Dit kan gedaan worden via de instellingen of het configuratiebestand", + "AppDataDirectory": "AppData map", + "AppDataLocationHealthCheckMessage": "Updaten zal niet mogelijk zijn om het verwijderen van AppData te voorkomen", + "AppProfileDeleteConfirm": "Weet u zeker dat u {0} wilt verwijderen?", + "AppProfileInUse": "App-profiel in gebruik", + "AppProfileSelectHelpText": "App-profielen worden gebruikt om de instellingen voor RSS, Automatisch zoeken en Interactief zoeken bij applicatiesynchronisatie te beheren", + "AppSettingsSummary": "Applicaties en instellingen om te configureren hoe Prowlarr met uw PVR-programma's omgaat", + "Application": "Applicaties", + "ApplicationLongTermStatusCheckAllClientMessage": "Alle indexeerders zijn niet beschikbaar vanwege storingen gedurende meer dan 6 uur", + "ApplicationLongTermStatusCheckSingleClientMessage": "Indexeerders zijn niet beschikbaar vanwege storingen gedurende meer dan 6 uur: {0}", + "ApplicationStatusCheckAllClientMessage": "Alle applicaties onbeschikbaar door fouten", + "ApplicationStatusCheckSingleClientMessage": "Applicaties onbeschikbaar door fouten", + "Applications": "Applicaties", + "Apply": "Toepassen", + "ApplyTags": "Tags Toepassen", + "ApplyTagsHelpTexts1": "Hoe tags toe te passen op de geselecteerd films", + "ApplyTagsHelpTexts2": "Toevoegen: Voeg de tags toe aan de lijst met bestaande tags", + "ApplyTagsHelpTexts3": "Verwijderen: Verwijder de ingevoerde tags", + "ApplyTagsHelpTexts4": "Vervangen: Vervang de tags met de ingevoerde tags (voer geen tags in om alle tags te wissen)", + "Apps": "Applicaties", + "AreYouSureYouWantToResetYourAPIKey": "Bent u zeker dat u uw API-sleutel wilt resetten?", + "AudioSearch": "auditief zoeken", + "Auth": "Authenticatie", + "Authentication": "Authenticatie", + "AuthenticationMethodHelpText": "Gebruikersnaam en wachtwoord nodig voor toegang tot Prowlarr", + "Automatic": "Automatisch", + "AutomaticSearch": "Automatisch Zoeken", + "Backup": "Veiligheidskopie", + "BackupFolderHelpText": "Relatieve paden zullen t.o.v. de Prowlarr AppData map bekeken worden", + "BackupIntervalHelpText": "Tussentijd voor automatische back-up", + "BackupNow": "Veiligheidskopie Maken", + "BackupRetentionHelpText": "Automatische veiligheidskopieën ouder dan de retentie periode zullen worden opgeruimd", + "Backups": "Veiligheidskopieën", + "BeforeUpdate": "Voor de update", + "BindAddress": "Aanhaak Adres", + "BindAddressHelpText": "Geldig IP-adres, localhost of '*' voor alle interfaces", + "Branch": "Branch", + "BranchUpdate": "Te gebruiken branch om Prowlarr bij te werken", + "BranchUpdateMechanism": "Gebruikte branch door extern update mechanisme", + "BypassProxyForLocalAddresses": "Omzeil Proxy voor Lokale Adressen", + "Cancel": "Annuleer", + "CancelPendingTask": "Bent u zeker dat u deze taak in afwachting wilt annuleren?", + "Categories": "Categorieën", + "Category": "Categorie", + "CertificateValidation": "Certificaat Validatie", + "CertificateValidationHelpText": "Wijzig hoe strikt HTTPS certificaat validatie is", + "ChangeHasNotBeenSavedYet": "Wijziging is nog niet opgeslagen", + "Clear": "Wissen", + "ClearHistory": "Geschiedenis verwijderen", + "ClearHistoryMessageText": "Weet je zeker dat je alle geschiedenis van Prowlarr wilt verwijderen?", + "ClientPriority": "Client Prioriteit", + "CloneProfile": "Dupliceer Profiel", + "Close": "Sluit", + "CloseCurrentModal": "Sluit Huidig Bericht", + "Columns": "Kolommen", + "Component": "Onderdeel", + "Connect": "Meldingen", + "ConnectSettings": "Connecties Instellingen", + "ConnectSettingsSummary": "Meldingen en aangepaste scripts", + "ConnectionLost": "Verbinding Onderbroken", + "ConnectionLostAutomaticMessage": "Prowlarr zal automatisch proberen te verbinden, of u kunt hieronder op herladen klikken.", + "ConnectionLostMessage": "Prowlarr heeft zijn verbinding met de backend verloren en zal moeten worden herladen om functionaliteit te herstellen.", + "Connections": "Connecties", + "CouldNotConnectSignalR": "Kan geen verbinding maken met SignalR, gebruikersinterface wordt niet bijgewerkt", + "Custom": "Aangepast", + "CustomFilters": "Aangepaste Filters", + "DBMigration": "DB Migratie", + "Database": "Databasis", + "Date": "Datum", + "Dates": "Datum en tijd", + "Delete": "Verwijderen", + "DeleteAppProfile": "App-profiel verwijderen", + "DeleteApplication": "Applicatie verwijderen", + "DeleteApplicationMessageText": "Weet u zeker dat u de applicatie '{0}' wilt verwijderen?", + "DeleteBackup": "Verwijder Veiligheidskopie", + "DeleteBackupMessageText": "Bent u zeker dat u de veiligheidskopie '{0}' wilt verwijderen?", + "DeleteDownloadClient": "Verwijder Downloader", + "DeleteDownloadClientMessageText": "Bent u zeker dat u de downloader '{0}' wilt verwijderen?", + "DeleteIndexerProxy": "Indexeerproxy verwijderen", + "DeleteIndexerProxyMessageText": "Weet u zeker dat u de proxy '{0}' wilt verwijderen?", + "DeleteNotification": "Verwijder Notificatie", + "DeleteNotificationMessageText": "Bent u zeker dat u de notificatie '{0}' wilt verwijderen?", + "DeleteTag": "Verwijder Tag", + "DeleteTagMessageText": "Bent u zeker dat u de tag '{0}' wilt verwijderen?", + "Description": "Beschrijving", + "Details": "Details", + "DevelopmentSettings": "Ontwikkelingsinstellingen", + "Disabled": "Uitgeschakeld", + "Discord": "Discord", + "Docker": "Docker", + "Donations": "Donaties", + "DownloadClient": "Downloader", + "DownloadClientSettings": "Downloader Instellingen", + "DownloadClientStatusCheckAllClientMessage": "Alle downloaders zijn onbeschikbaar wegens fouten", + "DownloadClientStatusCheckSingleClientMessage": "Downloaders onbeschikbaar wegens fouten: {0}", + "DownloadClients": "Downloaders", + "DownloadClientsSettingsSummary": "Clientconfiguratie downloaden voor integratie in Prowlarr UI-zoekopdracht", + "Duration": "Duur", + "Edit": "Bewerk", + "EditIndexer": "Bewerk Indexeerder", + "EditSyncProfile": "Synchronisatieprofiel toevoegen", + "Enable": "Activeer", + "EnableAutomaticSearch": "Activeer Automatisch Zoeken", + "EnableAutomaticSearchHelpText": "Zal worden gebruikt wanneer automatische zoekopdrachten worden uitgevoerd via de gebruikersinterface of door Prowlarr", + "EnableIndexer": "Indexer inschakelen", + "EnableInteractiveSearch": "Activeer Interactief Zoeken", + "EnableInteractiveSearchHelpText": "Zal worden gebruikt wanneer interactief zoeken wordt gebruikt", + "EnableRss": "RSS inschakelen", + "EnableRssHelpText": "Rss-feed voor Indexer inschakelen", + "EnableSSL": "Activeer SSL", + "EnableSslHelpText": " Vereist herstart als administrator om in werking te treden", + "Enabled": "Ingeschakeld", + "Encoding": "Coderen", + "Ended": "Beëindigd", + "Error": "Fout", + "ErrorLoadingContents": "Fout bij laden van inhoud", + "EventType": "Gebeurtenis Type", + "Events": "Gebeurtenissen", + "Exception": "Uitzondering", + "ExistingTag": "Bestaande tag", + "Failed": "Mislukt", + "FeatureRequests": "Functieverzoeken", + "Filename": "Bestandsnaam", + "Files": "Bestanden", + "Filter": "Filter", + "FilterPlaceHolder": "Zoek indexeerder", + "Filters": "Filters", + "Fixed": "Opgelost", + "FocusSearchBox": "Focus Zoekvak", + "Folder": "Map", + "ForMoreInformationOnTheIndividualDownloadClients": "Voor meer informatie over de individuele downloaders, klik op de info knoppen.", + "FullSync": "Volledige synchronisatie", + "General": "Algemeen", + "GeneralSettings": "Algemene Instellingen", + "GeneralSettingsSummary": "Poort, SSL, gebruikersnaam/wachtwoord, proxy, statistieken en updates", + "GrabReleases": "Uitgave Ophalen", + "Grabbed": "Opgehaalde", + "Grabs": "Gegrepen", + "Health": "Gezondheid", + "HealthNoIssues": "Geen problemen gevonden met uw configuratie", + "HiddenClickToShow": "Verborgen, klik om te tonen", + "HideAdvanced": "Verberg Gevorderd", + "History": "Geschiedenis", + "HistoryCleanupDaysHelpText": "Zet op 0 om automatisch opschonen uit te schakelen", + "HistoryCleanupDaysHelpTextWarning": "Bestanden in de prullenbak ouder dan het geselecteerde aantal dagen zullen automatisch opgeschoond worden", + "HomePage": "Startpagina", + "Host": "Host", + "Hostname": "Hostnaam", + "Id": "Id", + "IgnoredAddresses": "Genegeerde Adressen", + "IllRestartLater": "Ik zal later herstarten", + "IncludeHealthWarningsHelpText": "Voeg Gezondheidswaarschuwingen Toe", + "Indexer": "Indexeerder", + "IndexerAuth": "Indexer-authenticatie", + "IndexerFlags": "Indexeerder Flags", + "IndexerHealthCheckNoIndexers": "Geen indexers ingeschakeld, Prowlarr geeft geen zoekresultaten terug", + "IndexerLongTermStatusCheckAllClientMessage": "Alle indexeerders zijn niet beschikbaar vanwege storingen gedurende meer dan 6 uur", + "IndexerLongTermStatusCheckSingleClientMessage": "Indexeerders zijn niet beschikbaar vanwege storingen gedurende meer dan 6 uur: {0}", + "IndexerObsoleteCheckMessage": "Indexeerders zijn verouderd of zijn bijgewerkt: {0}. Gelieve te verwijderen en (of) opnieuw toe te voegen aan Prowlarr", + "IndexerPriority": "Indexeerder Prioriteit", + "IndexerPriorityHelpText": "Indexeerder Prioriteit van 1 (Hoogste) tot 50 (Laagste). Standaard: 25.", + "IndexerProxies": "Indexer-proxy's", + "IndexerProxy": "Indexeerder-proxy", + "IndexerProxyStatusCheckAllClientMessage": "Alle proxy's zijn niet beschikbaar vanwege storingen", + "IndexerProxyStatusCheckSingleClientMessage": "Proxy's niet beschikbaar vanwege storingen: {0}", + "IndexerQuery": "Indexeer zoekopdracht", + "IndexerRss": "Indexeer RSS", + "IndexerSettingsSummary": "Configureer verschillende globale Indexer-instellingen, waaronder proxy's.", + "IndexerStatusCheckAllClientMessage": "Alle indexeerders zijn onbeschikbaar wegens fouten", + "IndexerStatusCheckSingleClientMessage": "Indexeerders onbeschikbaar wegens fouten: {0}", + "IndexerTagsHelpText": "Gebruik tags om standaardclients op te geven, Indexeerder-proxy's op te geven of gewoon om uw indexeerders te ordenen.", + "IndexerVipCheckExpiredClientMessage": "Indexeerder VIP-voordelen zijn verlopen: {0}", + "IndexerVipCheckExpiringClientMessage": "Indexeerder VIP-voordelen verlopen binnenkort: {0}", + "Indexers": "Indexeerders", + "IndexersSelectedInterp": "{0} Indexer(s) Geselecteerd", + "Info": "Info", + "InstanceName": "Naam van de instantie", + "InteractiveSearch": "Interactief Zoeken", + "Interval": "Tussentijd", + "KeyboardShortcuts": "Sneltoetsen", + "Language": "Taal", + "LastDuration": "Laatste Looptijd", + "LastExecution": "Laatste Uitvoering", + "LastWriteTime": "Laatste Modificatietijd", + "LaunchBrowserHelpText": " Open een web browser en navigeer naar de Prowlarr startpagina bij het starten van de app.", + "Level": "Niveau", + "Link": "Koppelingen", + "LogFiles": "Logbestanden", + "LogLevel": "Log Niveau", + "LogLevelTraceHelpTextWarning": "Trace log niveau moet enkel tijdelijk worden gebruikt", + "Logging": "Logbeheer", + "Logs": "Logbestanden", + "MIA": "MIA", + "MaintenanceRelease": "Onderhoudsuitgave", + "Manual": "Manueel", + "MappedDrivesRunningAsService": "Toegewezen netwerkstation is niet beschikbaar wanneer Prowlarr wordt uitgevoerd als een Windows Service. Bekijk de Veelgestelde Vragen voor meer informatie", + "Mechanism": "Mechanisme", + "Message": "Bericht", + "Mode": "Modus", + "MoreInfo": "Meer Info", + "MovieIndexScrollBottom": "Film Index: Scroll naar onder", + "MovieIndexScrollTop": "Film Index: Scroll omhoog", + "Name": "Naam", + "NetCore": ".NET", + "New": "Nieuw", + "NextExecution": "Volgende uitvoering", + "No": "Nee", + "NoBackupsAreAvailable": "Geen veiligheidskopieën beschikbaar", + "NoChange": "Geen Wijziging", + "NoChanges": "Geen Wijzigingen", + "NoLeaveIt": "Nee, Ongemoeid Laten", + "NoLinks": "Geen koppelingen", + "NoLogFiles": "Geen logbestanden", + "NoSearchResultsFound": "Geen zoekresultaten gevonden, probeer hieronder een nieuwe zoekopdracht.", + "NoTagsHaveBeenAddedYet": "Er zijn nog geen tags toegevoegd", + "NoUpdatesAreAvailable": "Geen updates beschikbaar", + "Notification": "Melding", + "NotificationTriggers": "Melding Reactiestarters", + "NotificationTriggersHelpText": "Selecteer welke gebeurtenissen deze melding moeten activeren", + "Notifications": "Meldingen", + "OAuthPopupMessage": "Pop-ups worden geblokkeerd door uw browser", + "Ok": "Ok", + "OnApplicationUpdate": "Bij applicatie update", + "OnApplicationUpdateHelpText": "Bij applicatie update", + "OnGrab": "Bij Ophalen", + "OnHealthIssue": "Bij Gezondheidsprobleem", + "OnHealthIssueHelpText": "Bij Gezondheidsprobleem", + "OnHealthRestored": "Bij opgelost gezondheidsprobleem", + "OnHealthRestoredHelpText": "Bij opgelost gezondheidsprobleem", + "OpenBrowserOnStart": "Open de browser bij het starten", + "OpenThisModal": "Open deze modal", + "Options": "Opties", + "PackageVersion": "Pakket Versie", + "PageSize": "Pagina Grootte", + "PageSizeHelpText": "Aantal items om te tonen op iedere pagina", + "Password": "Wachtwoord", + "Peers": "Peers", + "PendingChangesDiscardChanges": "Wijzigingen verwerpen en verdergaan", + "PendingChangesMessage": "U heeft onopgeslagen wijzigingen, bent u zeker dat u deze pagina wilt sluiten?", + "PendingChangesStayReview": "Blijf en bekijk de wijzigingen", + "Port": "Poort", + "PortNumber": "Poort Nummer", + "Presets": "Voorinstellingen", + "Priority": "Prioriteit", + "PriorityHelpText": "Geef prioriteit aan meerdere downloaders. Round-Robin wordt gebruikt voor downloaders met dezelfde prioriteit.", + "PrioritySettings": "Prioriteit", + "Privacy": "Privacy", + "Protocol": "Protocol", + "ProwlarrSupportsAnyDownloadClient": "Prowlarr ondersteund elke downloader die gebruik maakt van de Newznab standaard, tevens ook de ander hieronder weergegeven downloaders.", + "ProwlarrSupportsAnyIndexer": "Prowlarr ondersteunt veel indexeerders naast elke indexeerder die de Newznab/Torznab-standaard gebruikt met 'Generic Newznab' (voor usenet) of 'Generic Torznab' (voor torrents). Zoek en selecteer uw indexeerder hieronder.", + "Proxy": "Proxy", + "ProxyBypassFilterHelpText": "Gebruik ',' als scheidingsteken en '*' als wildcard voor subdomeinen", + "ProxyCheckBadRequestMessage": "Testen van proxy is mislukt. Statuscode: {0}", + "ProxyCheckFailedToTestMessage": "Testen van proxy is mislukt: {0}", + "ProxyCheckResolveIpMessage": "Achterhalen van het IP-adres voor de geconfigureerde proxy host {0} is mislukt", + "ProxyPasswordHelpText": "Je moet alleen een gebruikersnaam en wachtwoord ingeven als dit vereist is, laat ze anders leeg.", + "ProxyType": "Proxy Type", + "ProxyUsernameHelpText": "Je moet alleen een gebruikersnaam en wachtwoord ingeven als dit vereist is, laat ze anders leeg.", + "Query": "Vraag", + "Queue": "Wachtrij", + "Queued": "Afwachtend", + "RSS": "RSS", + "RSSIsNotSupportedWithThisIndexer": "RSS wordt niet ondersteund door deze indexeerder", + "ReadTheWikiForMoreInformation": "Lees de Wiki voor meer informatie", + "Reddit": "Reddit", + "Redirect": "Omleiden", + "RedirectHelpText": "Leid inkomend downloadverzoek voor indexeerder om en geef de grijper direct door in plaats van het verzoek via Prowlarr te proxyen", + "Refresh": "Vernieuw", + "RefreshMovie": "Film vernieuwen", + "ReleaseBranchCheckOfficialBranchMessage": "Branch {0} is geen geldige Prowlarr release branch, u zult geen updates ontvangen", + "ReleaseStatus": "Uitgave Status", + "Reload": "Herlaad", + "Remove": "Verwijder", + "RemoveFilter": "Verwijder filter", + "RemovedFromTaskQueue": "Verwijderd uit taken wachtrij", + "RemovingTag": "Tag verwijderen", + "Replace": "Vervangen", + "Reset": "Reset", + "ResetAPIKey": "Reset API-sleutel", + "Restart": "Herstart", + "RestartNow": "Herstart Nu", + "RestartProwlarr": "Herstart Prowlarr", + "RestartRequiredHelpTextWarning": "Herstarten vereist om in werking te treden", + "Restore": "Herstellen", + "RestoreBackup": "Veiligheidskopie Herstellen", + "Result": "Resultaat", + "Retention": "Retentie", + "SSLCertPassword": "SSL Certificaat Wachtwoord", + "SSLCertPasswordHelpText": "Wachtwoord voor pfx bestand", + "SSLCertPath": "SSL Certificaat Pad", + "SSLCertPathHelpText": "Pad naar pfx bestand", + "SSLPort": "SSL Poort", + "Save": "Opslaan", + "SaveChanges": "Wijzigingen Opslaan", + "SaveSettings": "Instellingen Opslaan", + "Scheduled": "Gepland", + "ScriptPath": "Script Pad", + "Search": "Zoeken", + "SearchIndexers": "Zoek indexeerders", + "Security": "Beveiliging", + "Seeders": "Seeders", + "SelectAll": "Alles Selecteren", + "SendAnonymousUsageData": "Zend Anonieme Gebruiksdata", + "SetTags": "Tags Toepassen", + "Settings": "Instellingen", + "SettingsConsoleLogLevel": "Console-logboekniveau", + "SettingsEnableColorImpairedMode": "Activeer Kleurenblindheid-modus", + "SettingsEnableColorImpairedModeHelpText": "Aangepaste stijl voor gebruikers die kleurenblind zijn om gemakkelijker kleurgecodeerde informatie te onderscheiden", + "SettingsFilterSentryEvents": "Analytics-gebeurtenissen filteren", + "SettingsFilterSentryEventsHelpText": "Filter bekende gebruikersfoutgebeurtenissen zodat ze niet als Analytiek worden verzonden", + "SettingsIndexerLogging": "Verbeterde logboekregistratie van Indexeerder", + "SettingsIndexerLoggingHelpText": "Log aanvullende Indexeerder-gegevens inclusief reactie", + "SettingsLogRotate": "Logboekrotatie", + "SettingsLogRotateHelpText": "Maximaal aantal logbestanden om te bewaren in de logboek-map", + "SettingsLogSql": "Log Sql", + "SettingsLongDateFormat": "Lange Datumnotatie", + "SettingsShortDateFormat": "Korte Datumnotatie", + "SettingsShowRelativeDates": "Toon Relatieve Datums", + "SettingsShowRelativeDatesHelpText": "Toon relatieve (Vandaag/Gisteren/enz.) of absolute datums", + "SettingsSqlLoggingHelpText": "Log alle SQL-query's van Prowlarr", + "SettingsTimeFormat": "Tijdsformaat", + "ShowAdvanced": "Toon Geavanceerd", + "ShowSearch": "Toon Zoeken", + "ShowSearchHelpText": "Toon zoeken knop bij zweven", + "ShownClickToHide": "Getoond, klik om te verbergen", + "Shutdown": "Afsluiten", + "Size": "Grootte", + "Sort": "Sorteer", + "Source": "Bron", + "StartTypingOrSelectAPathBelow": "Begin met typen of selecteer een pad hier beneden", + "StartupDirectory": "Opstart map", + "Stats": "Statistieken", + "Status": "Status", + "Style": "Stijl", + "SuggestTranslationChange": "Stel vertaling voor", + "SyncAppIndexers": "App-indexeerders synchroniseren", + "SyncLevel": "Synchronisatieniveau", + "SyncLevelAddRemove": "Alleen toevoegen en verwijderen: wanneer het wordt toegevoegd of verwijderd uit Prowlarr, wordt deze externe app bijgewerkt.", + "SyncLevelFull": "Volledige synchronisatie: houdt deze app volledig gesynchroniseerd. Wijzigingen in Prowlarr worden vervolgens gesynchroniseerd met deze app. Elke wijziging die op afstand wordt aangebracht, wordt bij de volgende synchronisatie overschreven door Prowlarr.", + "System": "Systeem", + "SystemTimeCheckMessage": "De systeemtijd loopt verkeerd met meer dan 1 dag. Geplande taken worden mogelijk niet goed uitgevoerd tot dit is opgelost", + "TableOptions": "Tabel Opties", + "TableOptionsColumnsMessage": "Kies welke kolommen zichtbaar zijn en in welke volgorde", + "TagCannotBeDeletedWhileInUse": "Kan niet verwijderd worden terwijl in gebruik", + "TagIsNotUsedAndCanBeDeleted": "Tag is niet in gebruik en kan verwijderd worden", + "Tags": "Tags", + "TagsHelpText": "Is van toepassing op films met minstens één overeenkomende tag", + "TagsSettingsSummary": "Bekijk alle tags en hun gebruik. Ongebruikte tags kunnen worden verwijderd", + "Tasks": "Taken", + "Test": "Test", + "TestAll": "Test Alle", + "TestAllApps": "Alle apps testen", + "TestAllClients": "Test Alle Downloaders", + "TestAllIndexers": "Test Alle Indexeerders", + "TheLatestVersionIsAlreadyInstalled": "De nieuwste versie van Prowlarr is al geïnstalleerd", + "Time": "Tijd", + "Title": "Titel", + "Today": "Vandaag", + "Tomorrow": "Morgen", + "Torrent": "Torrent", + "Torrents": "Torrents", + "Type": "Type", + "UI": "Gebruikersinterface", + "UILanguage": "Gebruikersinterface Taal", + "UILanguageHelpText": "Taal die Prowlarr zal gebruiken voor de gebruikersinterface", + "UILanguageHelpTextWarning": "Browser Herladen Vereist", + "UISettings": "Gebruikersinterface Instellingen", + "UISettingsSummary": "Datum, kleurenblindheid en taal instellingen", + "URLBase": "URL Basis", + "UnableToAddANewAppProfilePleaseTryAgain": "Kan geen nieuw applicatieprofiel toevoegen. Probeer het opnieuw.", + "UnableToAddANewApplicationPleaseTryAgain": "Kan geen nieuwe toepassing toevoegen, probeer het opnieuw.", + "UnableToAddANewDownloadClientPleaseTryAgain": "Kon geen nieuwe downloader toevoegen, gelieve opnieuw te proberen.", + "UnableToAddANewIndexerPleaseTryAgain": "Kon geen nieuwe indexeerder toevoegen, gelieve opnieuw te proberen.", + "UnableToAddANewIndexerProxyPleaseTryAgain": "Kan geen nieuwe Indexeerder-proxy toevoegen. Probeer het opnieuw.", + "UnableToAddANewNotificationPleaseTryAgain": "Kon geen nieuwe notificatie toevoegen, gelieve opnieuw te proberen.", + "UnableToLoadAppProfiles": "Kan app-profielen niet laden", + "UnableToLoadBackups": "Kon geen veiligheidskopieën laden", + "UnableToLoadDevelopmentSettings": "Kan ontwikkelingsinstellingen niet laden", + "UnableToLoadDownloadClients": "Downloaders kunnen niet worden geladen", + "UnableToLoadGeneralSettings": "Kon Algemene instellingen niet inladen", + "UnableToLoadHistory": "Kon geschiedenis niet laden", + "UnableToLoadIndexerProxies": "Kan Indexeerder-proxy's niet laden", + "UnableToLoadIndexers": "Indexeerders kunnen niet worden geladen", + "UnableToLoadNotifications": "Notificaties kunnen niet worden geladen", + "UnableToLoadTags": "Tags kunnen niet worden geladen", + "UnableToLoadUISettings": "Kon gebruikersinterface instellingen niet inladen", + "UnsavedChanges": "Onopgeslagen Wijzigingen", + "UnselectAll": "Alles Deselecteren", + "UpdateAutomaticallyHelpText": "Download en installeer updates automatisch. Je zal nog steeds kunnen installeren vanuit Systeem: Updates", + "UpdateCheckStartupNotWritableMessage": "Kan de update niet installeren omdat de map '{0}' niet schrijfbaar is voor de gebruiker '{1}'.", + "UpdateCheckStartupTranslocationMessage": "Kan de update niet installeren omdat de map '{0}' zich in een 'App Translocation' map bevindt.", + "UpdateCheckUINotWritableMessage": "Kan de update niet installeren omdat de UI map '{0}' niet schrijfbaar is voor de gebruiker '{1}'.", + "UpdateMechanismHelpText": "Gebruik het ingebouwde updatemechanisme of een extern script", + "UpdateScriptPathHelpText": "Pad naar een aangepast script dat een uitgepakt updatepakket accepteert en de rest van het updateproces afhandelt", + "Updates": "Updates", + "Uptime": "Bedrijfstijd", + "UrlBaseHelpText": "Voor reverse proxy ondersteuning, leeg is standaard", + "UseProxy": "Gebruik Proxy", + "Usenet": "Usenet", + "UserAgentProvidedByTheAppThatCalledTheAPI": "User-Agent geleverd door de app die de API heeft aangeroepen", + "Username": "Gebruikersnaam", + "Version": "Versie", + "View": "Weergave", + "Warn": "Waarschuwing", + "Wiki": "Wiki", + "Yes": "Ja", + "YesCancel": "Ja, Annuleren", + "Yesterday": "Gisteren" } diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index e47ad811b..983f90a64 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -1,516 +1,516 @@ { - "CustomFilters": "Filtros Personalizados", - "About": "Sobre", - "AcceptConfirmationModal": "Aceitar o pop-up de confirmação", - "AllIndexersHiddenDueToFilter": "Todos os indexadores estão ocultos devido ao filtro aplicado.", - "AnalyticsEnabledHelpText": "Envie informações anônimas de uso e erro para os servidores do Prowlarr. Isso inclui informações sobre seu navegador, quais páginas da interface Web do Prowlarr você usa, relatórios de erros, e a versão do sistema operacional e do tempo de execução. Usaremos essas informações para priorizar recursos e correções de bugs.", - "AreYouSureYouWantToResetYourAPIKey": "Tem certeza de que deseja redefinir sua chave da API?", - "BackupRetentionHelpText": "Backups automáticos anteriores ao período de retenção serão limpos automaticamente", - "BranchUpdateMechanism": "Ramificação usada pelo mecanismo de atualização externo", - "CertificateValidationHelpText": "Alterar o quão estrita é a validação da certificação HTTPS", - "ClientPriority": "Prioridade do cliente", - "ConnectionLostAutomaticMessage": "O Prowlarr tentará se conectar automaticamente, ou você pode clicar em Recarregar abaixo.", - "ConnectSettingsSummary": "Notificações e scripts personalizados", - "IndexerObsoleteCheckMessage": "Os seguintes indexadores são obsoletos ou foram atualizados: {0}. Remova-os e/ou adicione-os novamente ao Prowlarr", - "DownloadClientsSettingsSummary": "Configuração de clientes de download para integração com a pesquisa da interface do usuário do Prowlarr", - "EnableInteractiveSearchHelpText": "Será usado com a pesquisa interativa", - "ForMoreInformationOnTheIndividualDownloadClients": "Para saber mais sobre cada cliente de download, clique nos botões de informações.", - "IndexerFlags": "Sinalizadores do indexador", - "IndexerHealthCheckNoIndexers": "Não há indexadores habilitados, o Prowlarr não retornará resultados para a pesquisa", - "IndexerPriorityHelpText": "Prioridade do Indexador de 1 (Mais Alta) a 50 (Mais Baixa). Padrão: 25.", - "IndexersSelectedInterp": "{0} indexador(es) selecionado(s)", - "LastWriteTime": "Hora da última gravação", - "LaunchBrowserHelpText": " Abrir o navegador Web e navegar até a página inicial do Prowlarr ao iniciar o aplicativo.", - "NoTagsHaveBeenAddedYet": "Você ainda não adicionou tags", - "NotificationTriggers": "Acionadores da notificação", - "NoUpdatesAreAvailable": "Não há atualizações disponíveis", - "PageSize": "Tamanho da página", - "PendingChangesDiscardChanges": "Descartar alterações e sair", - "PriorityHelpText": "Priorizar vários clientes de download. Usamos um rodízio para clientes com a mesma prioridade.", - "ProwlarrSupportsAnyIndexer": "Prowlarr suporte muitos indexadores em adição a qualquer indexador que use o padrão Newznab/Torznab usando 'Newznab Genérico' (para usenet) ou 'Torznab Genérico' (para torrents). Busque & Selecione seu indexador dos abaixo.", - "ProxyUsernameHelpText": "Você só precisa inserir um nome de usuário e uma senha se solicitado. Caso contrário, deixe em branco.", - "ReleaseBranchCheckOfficialBranchMessage": "A ramificação {0} não é de uma versão válida para o Prowlarr, você não receberá atualizações", - "ResetAPIKey": "Redefinir chave da API", - "RestartProwlarr": "Reiniciar o Prowlarr", - "RSSIsNotSupportedWithThisIndexer": "O RSS não é compatível com este indexador", - "SendAnonymousUsageData": "Enviar dados de uso anônimos", - "SettingsEnableColorImpairedModeHelpText": "Estilo alterado para permitir que usuários com daltonismo distingam melhor as informações codificadas por cores", - "SettingsLogRotateHelpText": "Quantidade máxima de arquivos de log a manter na pasta", - "ShownClickToHide": "Mostrar configurações avançadas, clique para ocultar", - "SSLCertPasswordHelpText": "Senha para arquivo pfx", - "StartupDirectory": "Diretório de inicialização", - "SuggestTranslationChange": "Sugerir alteração para a tradução", - "SystemTimeCheckMessage": "A hora do sistema está desligada por mais de 1 dia. Tarefas agendadas podem não ser executadas corretamente até que o horário seja corrigido", - "TagsHelpText": "Aplica-se a indexadores com pelo menos uma tag correspondente", - "UILanguageHelpText": "Idioma que o Prowlarr usará para a interface", - "UnableToAddANewIndexerPleaseTryAgain": "Não foi possível adicionar um novo indexador, tente novamente.", - "UnableToLoadGeneralSettings": "Não foi possível carregar as configurações gerais", - "UpdateAutomaticallyHelpText": "Baixar e instalar atualizações automaticamente. Você ainda poderá instalar a partir de Sistema: Atualizações", - "UpdateCheckStartupTranslocationMessage": "Não é possível instalar a atualização porque a pasta de inicialização '{0}' está em uma pasta de translocação de aplicativo.", - "UrlBaseHelpText": "Para suporte de proxy reverso, o padrão é vazio", - "Actions": "Ações", - "Added": "Adicionado", - "AddedToDownloadClient": "Lançamento adicionado ao cliente", - "AddIndexer": "Adicionar indexador", - "AddingTag": "Adicionando etiqueta", - "AddNewIndexer": "Adicionar novo indexador", - "AddToDownloadClient": "Adicionar lançamento ao cliente de download", - "Age": "Tempo de vida", - "All": "Todos", - "Analytics": "Análises", - "ApiKey": "Chave da API", - "AppDataDirectory": "Diretório AppData", - "AppDataLocationHealthCheckMessage": "A atualização não será possível para evitar a exclusão de AppData na atualização", - "ApplicationStatusCheckAllClientMessage": "Não há aplicativos disponíveis devido a falhas", - "ApplicationStatusCheckSingleClientMessage": "Aplicativos indisponíveis devido a falhas: {0}", - "Apply": "Aplicar", - "ApplyTags": "Aplicar tags", - "ApplyTagsHelpTexts1": "Como aplicar tags aos indexadores selecionados", - "ApplyTagsHelpTexts2": "Adicionar: inserir as tags à lista de tags existente", - "ApplyTagsHelpTexts3": "Remover: excluir as tags inseridas", - "ApplyTagsHelpTexts4": "Substituir: sobrepor as tags existentes pelas inseridas (deixe em branco para limpar todas as tags)", - "Authentication": "Autenticação", - "AuthenticationMethodHelpText": "Requer nome de usuário e senha para acessar o Prowlarr", - "Automatic": "Automático", - "Backup": "Backup", - "BackupFolderHelpText": "Os caminhos relativos estarão no diretório AppData do Prowlarr", - "BackupIntervalHelpText": "Intervalo entre backups automáticos", - "BackupNow": "Disparar Backup", - "Backups": "Backups", - "BeforeUpdate": "Antes da atualização", - "BindAddress": "Endereço de vínculo", - "BindAddressHelpText": "Endereço IP válido, localhost ou '*' para todas as interfaces", - "Branch": "Ramificação", - "BranchUpdate": "Ramificação para atualização do Prowlarr", - "BypassProxyForLocalAddresses": "Ignorar proxy para endereços locais", - "Cancel": "Cancelar", - "CancelPendingTask": "Tem certeza de que deseja cancelar esta tarefa pendente?", - "CertificateValidation": "Validação de certificado", - "ChangeHasNotBeenSavedYet": "A alteração ainda não foi salva", - "Clear": "Limpar", - "ClearHistory": "Limpar histórico", - "ClearHistoryMessageText": "Tem certeza de que deseja limpar o histórico do Prowlarr?", - "Close": "Fechar", - "CloseCurrentModal": "Fechar modal atual", - "Columns": "Colunas", - "Component": "Componente", - "Connect": "Notificações", - "ConnectionLost": "Conexão perdida", - "ConnectionLostMessage": "O Prowlarr perdeu sua conexão com o backend e precisará ser recarregado para restaurar a funcionalidade.", - "Connections": "Conexões", - "ConnectSettings": "Configurações de conexão", - "Date": "Data", - "Dates": "Datas", - "DBMigration": "Migração de banco de dados", - "Delete": "Excluir", - "DeleteApplication": "Excluir aplicativo", - "DeleteApplicationMessageText": "Tem certeza de que deseja excluir o aplicativo \"{0}\"?", - "DeleteBackup": "Excluir backup", - "DeleteBackupMessageText": "Tem certeza que deseja excluir o backup \"{0}\"?", - "DeleteNotification": "Excluir notificação", - "DeleteNotificationMessageText": "Tem certeza de que deseja excluir a notificação \"{0}\"?", - "DeleteTag": "Excluir tag", - "DeleteTagMessageText": "Tem certeza de que deseja excluir a tag \"{0}\"?", - "Details": "Detalhes", - "DevelopmentSettings": "Configurações de desenvolvimento", - "Disabled": "Desabilitado", - "Docker": "Docker", - "DownloadClient": "Cliente de download", - "DownloadClients": "Clientes de download", - "DownloadClientSettings": "Configurações do cliente de download", - "DownloadClientStatusCheckAllClientMessage": "Todos os clientes de download estão indisponíveis devido a falhas", - "DownloadClientStatusCheckSingleClientMessage": "Clientes de download indisponíveis devido a falhas: {0}", - "EditIndexer": "Editar indexador", - "Enable": "Habilitar", - "EnableAutomaticSearch": "Habilitar pesquisa automática", - "EnableAutomaticSearchHelpText": "Será usado ao realizar pesquisas automáticas pela interface ou pelo Prowlarr", - "EnableIndexer": "Habilitar indexador", - "EnableInteractiveSearch": "Habilitar pesquisa interativa", - "EnableSSL": "Habilitar SSL", - "EnableSslHelpText": " Requer a reinicialização com a execução como administrador para fazer efeito", - "Error": "Erro", - "ErrorLoadingContents": "Erro ao carregar conteúdo", - "Events": "Eventos", - "EventType": "Tipo de evento", - "Exception": "Exceção", - "ExistingTag": "Tag existente", - "Filename": "Nome do arquivo", - "Files": "Arquivos", - "Filter": "Filtrar", - "FilterPlaceHolder": "Pesquisar indexadores", - "Fixed": "Corrigido", - "FocusSearchBox": "Selecionar caixa de pesquisa", - "Folder": "Pasta", - "General": "Geral", - "GeneralSettings": "Configurações gerais", - "GeneralSettingsSummary": "Porta, SSL, nome de usuário/senha, proxy, análises e atualizações", - "Grabbed": "Obtido", - "Health": "Integridade", - "HealthNoIssues": "Nenhum problema com sua configuração", - "HiddenClickToShow": "Oculto, clique para mostrar", - "HideAdvanced": "Ocultar avançado", - "History": "Histórico", - "Host": "Host", - "Hostname": "Nome do host", - "IgnoredAddresses": "Endereços ignorados", - "IllRestartLater": "Reiniciarei mais tarde", - "IncludeHealthWarningsHelpText": "Incluir avisos de integridade", - "Indexer": "Indexador", - "IndexerAuth": "Autenticação do indexador", - "IndexerLongTermStatusCheckAllClientMessage": "Todos os indexadores estão indisponíveis devido a falhas por mais de 6 horas", - "IndexerLongTermStatusCheckSingleClientMessage": "Indexadores indisponíveis devido a falhas por mais de 6 horas: {0}", - "IndexerPriority": "Prioridade do indexador", - "IndexerQuery": "Consulta do indexador", - "IndexerRss": "RSS do indexador", - "Indexers": "Indexadores", - "IndexerStatusCheckAllClientMessage": "Todos os indexadores estão indisponíveis devido a falhas", - "IndexerStatusCheckSingleClientMessage": "Indexadores indisponíveis devido a falhas: {0}", - "Info": "Informações", - "Interval": "Intervalo", - "KeyboardShortcuts": "Atalhos de teclado", - "Language": "Idioma", - "Level": "Nível", - "LogFiles": "Arquivos de log", - "Logging": "Registro em log", - "LogLevel": "Nível do log", - "LogLevelTraceHelpTextWarning": "O registro de rastreamento deve ser ativado apenas temporariamente", - "Logs": "Registros", - "MaintenanceRelease": "Versão de manutenção: correções de bugs e outras melhorias. Veja Github Commit History para mais detalhes", - "Manual": "Manual", - "Mechanism": "Mecanismo", - "Message": "Mensagem", - "MIA": "Desaparecidos", - "Mode": "Modo", - "MoreInfo": "Mais informações", - "MovieIndexScrollBottom": "Índice do filme: rolar pra baixo", - "MovieIndexScrollTop": "Índice do filme: rolar para cima", - "Name": "Nome", - "NetCore": ".NET", - "New": "Novo", - "NoBackupsAreAvailable": "Não há backups disponíveis", - "NoChange": "Sem alteração", - "NoChanges": "Sem alterações", - "NoLeaveIt": "Não, deixe assim", - "NoLogFiles": "Sem arquivos de log", - "OAuthPopupMessage": "Os pop-ups estão bloqueados em seu navegador", - "Ok": "Ok", - "OnHealthIssueHelpText": "Ao ter problema de integridade", - "OpenBrowserOnStart": "Abrir navegador ao iniciar", - "OpenThisModal": "Abrir este modal", - "Options": "Opções", - "PackageVersion": "Versão do pacote", - "PageSizeHelpText": "Quantidade de itens a exibir em cada página", - "Password": "Senha", - "Peers": "Pares", - "PendingChangesMessage": "Há alterações não salvas. Tem certeza que deseja sair desta página?", - "PendingChangesStayReview": "Ficar e revisar alterações", - "Port": "Porta", - "PortNumber": "Número da porta", - "Priority": "Prioridade", - "Protocol": "Protocolo", - "ProwlarrSupportsAnyDownloadClient": "O Prowlarr é compatível com todos os clientes de download listados abaixo.", - "Proxy": "Proxy", - "ProxyBypassFilterHelpText": "Usar \",\" como separador e \"*.\" como curinga para subdomínios", - "ProxyCheckBadRequestMessage": "Falha ao testar o proxy. Código de status: {0}", - "ProxyCheckFailedToTestMessage": "Falha ao testar o proxy: {0}", - "ProxyCheckResolveIpMessage": "Falha ao resolver o endereço IP do host de proxy configurado {0}", - "ProxyPasswordHelpText": "Você só precisa inserir um nome de usuário e uma senha se solicitado. Caso contrário, deixe em branco.", - "ProxyType": "Tipo de proxy", - "Queue": "Fila", - "ReadTheWikiForMoreInformation": "Leia a Wiki para saber mais", - "Refresh": "Atualizar", - "RefreshMovie": "Atualizar filme", - "ReleaseStatus": "Status da versão", - "Reload": "Recarregar", - "RemovedFromTaskQueue": "Removido da fila de tarefas", - "RemoveFilter": "Remover filtro", - "RemovingTag": "Removendo tag", - "Reset": "Redefinir", - "Restart": "Reiniciar", - "RestartNow": "Reiniciar agora", - "RestartRequiredHelpTextWarning": "Requer reinicialização para ter efeito", - "Restore": "Restaurar", - "RestoreBackup": "Restaurar backup", - "Result": "Resultado", - "Retention": "Retenção", - "Save": "Salvar", - "SaveChanges": "Salvar alterações", - "SaveSettings": "Salvar configurações", - "Scheduled": "Agendado", - "ScriptPath": "Caminho do script", - "Search": "Pesquisar", - "SearchIndexers": "Pesquisar indexadores", - "Security": "Segurança", - "Seeders": "Semeadores", - "SelectAll": "Selecionar tudo", - "SetTags": "Definir tags", - "Settings": "Configurações", - "SettingsConsoleLogLevel": "Nível de log do console", - "SettingsEnableColorImpairedMode": "Habilitar modo para daltonismo", - "SettingsFilterSentryEvents": "Filtrar eventos de análises", - "SettingsFilterSentryEventsHelpText": "Filtrar eventos de erro de usuário conhecidos para que não sejam enviados para análise", - "SettingsIndexerLogging": "Registro em log avançado do indexador", - "SettingsIndexerLoggingHelpText": "Registrar dados adicionar do indexador, incluindo resposta", - "SettingsLogRotate": "Rotação de logs", - "SettingsLogSql": "Registrar SQL", - "SettingsLongDateFormat": "Formato longo da data", - "SettingsShortDateFormat": "Formato curto da data", - "SettingsShowRelativeDates": "Mostrar datas relativas", - "SettingsShowRelativeDatesHelpText": "Mostrar datas absolutas ou relativas (Hoje, Ontem, etc.)", - "SettingsSqlLoggingHelpText": "Registrar todas as consultas de SQL do Prowlarr", - "SettingsTimeFormat": "Formato de hora", - "ShowAdvanced": "Mostrar opções avançadas", - "ShowSearch": "Mostrar pesquisa", - "ShowSearchHelpText": "Mostrar botão de pesquisa ao passar o mouse", - "Shutdown": "Desligar", - "Size": "Tamanho", - "Sort": "Classificar", - "Source": "Fonte", - "SSLCertPassword": "Senha do certificado SSL", - "SSLCertPath": "Caminho do certificado SSL", - "SSLCertPathHelpText": "Caminho para o arquivo pfx", - "SSLPort": "Porta SSL", - "StartTypingOrSelectAPathBelow": "Comece a digitar ou selecione um caminho abaixo", - "Status": "Status", - "Style": "Estilo", - "SyncAppIndexers": "Sincronizar indexadores do aplicativo", - "System": "Sistema", - "TableOptions": "Opções da tabela", - "TableOptionsColumnsMessage": "Escolha quais colunas são visíveis e em que ordem aparecem", - "TagCannotBeDeletedWhileInUse": "Não pode ser excluído durante o uso", - "TagIsNotUsedAndCanBeDeleted": "A tag não está em uso e pode ser excluída", - "Tags": "Tags", - "TagsSettingsSummary": "Veja todas as tags e como são usadas. Tags não utilizadas podem ser removidas", - "Tasks": "Tarefas", - "Test": "Testar", - "TestAll": "Testar tudo", - "TestAllApps": "Testar todos os aplicativos", - "TestAllClients": "Testar todos os clientes", - "Time": "Tempo", - "Title": "Título", - "Today": "Hoje", - "Tomorrow": "Amanhã", - "Type": "Tipo", - "UI": "Interface", - "UILanguage": "Idioma da interface", - "UILanguageHelpTextWarning": "É necessário recarregar o navegador", - "UISettings": "Configurações da interface", - "UISettingsSummary": "Opções de daltonismo, data e idioma", - "UnableToAddANewNotificationPleaseTryAgain": "Não foi possível adicionar uma nova notificação, tente novamente.", - "UnableToLoadBackups": "Não foi possível carregar os backups", - "UnableToLoadDevelopmentSettings": "Não foi possível carregar as configurações de desenvolvimento", - "UnableToLoadHistory": "Não foi possível carregar o histórico", - "UnableToLoadNotifications": "Não foi possível carregar as notificações", - "UnableToLoadTags": "Não foi possível carregar as tags", - "UnableToLoadUISettings": "Não foi possível carregar as configurações da interface", - "UnsavedChanges": "Alterações não salvas", - "UnselectAll": "Desmarcar tudo", - "UpdateCheckStartupNotWritableMessage": "Não é possível instalar a atualização porque a pasta de inicialização '{0}' não pode ser gravada pelo usuário '{1}'.", - "UpdateCheckUINotWritableMessage": "Não é possível instalar a atualização porque a pasta de IU '{0}' não pode ser gravada pelo usuário '{1}'.", - "UpdateMechanismHelpText": "Usar o atualizador integrado do Prowlarr ou um script", - "Updates": "Atualizações", - "UpdateScriptPathHelpText": "Caminho para um script personalizado que usa um pacote de atualização extraído e lida com o restante do processo de atualização", - "Uptime": "Tempo de atividade", - "URLBase": "URL base", - "Usenet": "Usenet", - "UseProxy": "Usar proxy", - "Username": "Nome de usuário", - "Version": "Versão", - "View": "Exibir", - "Warn": "Avisar", - "YesCancel": "Sim, Cancelar", - "Yesterday": "Ontem", - "EnableRssHelpText": "Habilitar feed RSS para o indexador", - "EnableRss": "Habilitar RSS", - "Wiki": "Wiki", - "RSS": "RSS", - "RedirectHelpText": "Redirecionar a solicitação de download de entrada para o indexador e passar diretamente para a obtenção, em vez de por proxy usando o Prowlarr", - "Redirect": "Redirecionar", - "Reddit": "Reddit", - "InteractiveSearch": "Pesquisa interativa", - "HomePage": "Página inicial", - "FeatureRequests": "Solicitações de recursos", - "Discord": "Discord", - "AutomaticSearch": "Pesquisa automática", - "AppProfileSelectHelpText": "Os perfis de aplicativos são usados para controlar as configurações de RSS, Pesquisa automática e Pesquisa interativa ao sincronizar o aplicativo", - "UnableToLoadDownloadClients": "Não foi possível carregar os clientes de download", - "UnableToLoadAppProfiles": "Não foi possível carregar os perfis de aplicativos", - "UnableToAddANewDownloadClientPleaseTryAgain": "Não foi possível adicionar um novo cliente de download, tente novamente.", - "UnableToAddANewAppProfilePleaseTryAgain": "Não foi possível adicionar um novo perfil de aplicativo, tente novamente.", - "UnableToAddANewApplicationPleaseTryAgain": "Não foi possível adicionar um novo aplicativo, tente novamente.", - "Torrents": "Torrents", - "Torrent": "Torrent", - "Stats": "Estatísticas", - "Query": "Consulta", - "Privacy": "Privacidade", - "Presets": "Predefinições", - "NotificationTriggersHelpText": "Selecionar quais eventos devem acionar esta notificação", - "Id": "ID", - "Grabs": "Obtenções", - "Failed": "Falhou", - "Encoding": "Codificação", - "Enabled": "Habilitado", - "Donations": "Doações", - "Description": "Descrição", - "DeleteDownloadClientMessageText": "Tem certeza que deseja excluir o cliente de download \"{0}\"?", - "DeleteDownloadClient": "Excluir cliente de download", - "DeleteAppProfile": "Excluir perfil do aplicativo", - "Custom": "Personalizado", - "CloneProfile": "Clonar perfil", - "Category": "Categoria", - "Auth": "Autenticação", - "Apps": "Aplicativos", - "AppProfileInUse": "Perfil de aplicativo em uso", - "AppProfileDeleteConfirm": "Tem certeza que deseja excluir {0}?", - "Applications": "Aplicativos", - "AddDownloadClient": "Adicionar cliente de download", - "CouldNotConnectSignalR": "Não é possível conectar ao SignalR, a interface não atualizará", - "PrioritySettings": "Prioridade", - "SyncLevelFull": "Full Sync: manterá totalmente os indexadores deste aplicativo em sincronia. As alterações feitas em indexadores em Prowlarr são então sincronizadas com este aplicativo. Qualquer alteração feita para indexadores remotamente dentro deste aplicativo será substituída por Prowlarr na próxima sincronização.", - "SyncLevelAddRemove": "Adicione e remova somente: quando os indexadores são adicionados ou removidos do Prowlarr, ele atualizará este aplicativo remoto.", - "SyncLevel": "Nível de sincronização", - "FullSync": "Sincronização completa", - "Edit": "Editar", - "AddRemoveOnly": "Adicionar e remover apenas", - "AddDownloadClientToProwlarr": "Adicionar um cliente de download possibilita que o Prowlarr envie lançamentos diretamente da interface ao executar uma pesquisa manual.", - "Add": "Adicionar", - "NoSearchResultsFound": "Nenhum resultado encontrado, tente fazer uma nova busca abaixo.", - "AppSettingsSummary": "Aplicativos e configurações para configurar como Prowlarr interage com seus programas PVR", - "DeleteIndexerProxy": "Apagar Proxy do Indexador", - "DeleteIndexerProxyMessageText": "Tem certeza que deseja apagar o proxy '{0}'?", - "AddIndexerProxy": "Adicionar Proxy ao Indexador", - "IndexerProxies": "Proxies do Indexador", - "IndexerSettingsSummary": "Defina várias configurações globais do Indexador, incluindo Proxies.", - "IndexerProxyStatusCheckAllClientMessage": "Todos os proxies estão indisponíveis devido a falhas", - "IndexerProxyStatusCheckSingleClientMessage": "Proxies indisponíveis devido a falhas: {0}", - "IndexerTagsHelpText": "Usar etiquetas para especificar os proxies do indexador ou com quais aplicativos o indexador está sincronizado. Aplicativos sem 1 ou mais etiquetas de indexador correspondentes não serão sincronizados.", - "Notifications": "Notificações", - "UnableToAddANewIndexerProxyPleaseTryAgain": "Não foi possível adicionar um novo proxy indexador, tente novamente.", - "UnableToLoadIndexerProxies": "Não foi possível carregar proxies do indexador", - "IndexerVipCheckExpiredClientMessage": "Benefícios VIP do Indexador expiraram: {0}", - "IndexerProxy": "Proxy do Indexador", - "IndexerVipCheckExpiringClientMessage": "Os benefícios VIPS do Indexador expirarão em breve: {0}", - "NoLinks": "Sem Links", - "Notification": "Notificação", - "BookSearch": "Pesquisar Livro", - "AudioSearch": "Pesquisar Áudio", - "MovieSearch": "Pesquisar Filme", - "QueryOptions": "Opções de Consulta", - "SearchType": "Tipo de Pesquisa", - "TvSearch": "Pesquisar Séries", - "HistoryCleanupDaysHelpTextWarning": "Os arquivos na lixeira mais antigos do que o número de dias selecionado serão limpos automaticamente", - "Filters": "Filtros", - "HistoryCleanupDaysHelpText": "Defina como 0 para desabilitar a limpeza automática", - "OnApplicationUpdate": "Ao atualizar o aplicativo", - "OnApplicationUpdateHelpText": "Ao atualizar o aplicativo", - "OnGrab": "Ao Obter Lançamento", - "OnHealthIssue": "Ao ter problema de integridade", - "TestAllIndexers": "Testar todos os indexadores", - "UserAgentProvidedByTheAppThatCalledTheAPI": "User-Agent fornecido pelo aplicativo que chamou a API", - "Categories": "Categorias", - "IndexerAlreadySetup": "Pelo menos uma instância do indexador já está configurada", - "IndexerInfo": "Info do Indexador", - "MassEditor": "Editor em Massa", - "Database": "Banco de dados", - "HistoryCleanup": "Histórico de Limpeza", - "IndexerNoDefCheckMessage": "Os indexadores não têm definição e não funcionarão: {0}. Por favor, remova e (ou) adicione novamente ao Prowlarr", - "Private": "Privado", - "Proxies": "Proxies", - "Public": "Público", - "QueryResults": "Resultados da Consulta", - "SemiPrivate": "Semi-Privado", - "UnableToLoadApplicationList": "Não é possível carregar a lista de aplicativos", - "Url": "Url", - "Website": "Website", - "IndexerDetails": "Detalhes do Indexador", - "IndexerName": "Nome do Indexador", - "IndexerSite": "Site do Indexador", - "MovieSearchTypes": "Tipos de Pesquisa de Filmes", - "MusicSearchTypes": "Tipos de Pesquisa de Músicas", - "NotSupported": "Não Suportado", - "RawSearchSupported": "Pesquisa Bruta Suportada", - "SearchCapabilities": "Recursos de Pesquisa", - "TVSearchTypes": "Tipos de Pesquisa de Seriados", - "BookSearchTypes": "Tipos de Pesquisa de Livros", - "SearchTypes": "Tipos de pesquisa", - "UnableToLoadIndexers": "Não foi possível carregar os indexadores", - "Yes": "Sim", - "Application": "Aplicação", - "GrabReleases": "Capturar lançamento(s)", - "Link": "Link", - "MappedDrivesRunningAsService": "As unidades de rede mapeadas não estão disponíveis quando executadas como um serviço do Windows. Consulte as Perguntas frequentes para saber mais", - "No": "Não", - "EditSyncProfile": "Editar Perfil de Sincronização", - "SyncProfile": "Perfil de Sincronização", - "SyncProfiles": "Perfis de Sincronização", - "AddSyncProfile": "Adicionar Perfil de Sincronização", - "MinimumSeeders": "Mínimo de Seeders", - "MinimumSeedersHelpText": "Semeadores mínimos exigidos pelo aplicativo para o indexador baixar", - "ThemeHelpText": "Alterar o tema da interface do usuário do aplicativo, o tema 'Auto' usará o tema do sistema operacional para definir o modo Claro ou Escuro. Inspirado por {0}", - "InstanceName": "Nome da instância", - "InstanceNameHelpText": "Nome da instância na guia e para o nome do aplicativo do Syslog", - "Duration": "Duração", - "ElapsedTime": "Tempo Decorrido", - "EnabledRedirected": "Habilitado, Redirecionado", - "Ended": "Terminado", - "LastExecution": "Última Execução", - "Parameters": "Parâmetros", - "Queued": "Enfileirado", - "GrabTitle": "Obter Título", - "LastDuration": "Última duração", - "NextExecution": "Próxima Execução", - "Started": "Iniciado", - "ApplicationLongTermStatusCheckAllClientMessage": "Todos os aplicativos estão indisponíveis devido a falhas por mais de 6 horas", - "ApplicationLongTermStatusCheckSingleClientMessage": "Aplicativos indisponíveis devido a falhas por mais de 6 horas: {0}", - "AreYouSureYouWantToDeleteCategory": "Tem certeza de que deseja excluir a categoria mapeada?", - "DeleteClientCategory": "Excluir Categoria de Cliente de Download", - "DownloadClientCategory": "Categoria de Download do Cliente", - "MappedCategories": "Categorias Mapeadas", - "AuthenticationRequired": "Autenticação Requerida", - "AuthenticationRequiredHelpText": "Altera para quais solicitações a autenticação é necessária. Não mude a menos que você entenda os riscos.", - "AuthenticationRequiredWarning": "Para impedir o acesso remoto sem autenticação, o Prowlarr agora exige que a autenticação seja habilitada. Configure seu método de autenticação e credenciais. Você pode, opcionalmente, desabilitar a autenticação de endereços locais. Consulte o FAQ para obter informações adicionais.", - "Remove": "Remover", - "Replace": "Substituir", - "TheLatestVersionIsAlreadyInstalled": "A versão mais recente do Prowlarr já está instalada", - "AddApplication": "Adicionar Aplicativo", - "AddCustomFilter": "Adicionar Filtro Personalizado", - "OnGrabHelpText": "Ao obter lançamento", - "IncludeManualGrabsHelpText": "Incluir Capturas Manuais feitas no Prowlarr", - "RssFeed": "Alimentador RSS", - "VipExpiration": "Expiração VIP", - "DisabledUntil": "Desabilitar Até", - "IndexerDisabled": "Indexador Desabilitado", - "InitialFailure": "Falha Inicial", - "LastFailure": "Última Falha", - "TotalUserAgentQueries": "Total de consultas do agente do usuário", - "Track": "Faixa", - "Album": "Álbum", - "AverageResponseTimesMs": "Tempos Médios de Resposta (Ms)", - "Episode": "Episódio", - "IndexerFailureRate": "Taxa de falha do indexador", - "More": "Mais", - "RepeatSearch": "Repetir pesquisa", - "TotalIndexerSuccessfulGrabs": "Total de capturas bem-sucedidas do indexador", - "TotalUserAgentGrabs": "Total de capturas do agente de usuário", - "Year": "Ano", - "Book": "Livro", - "Artist": "Artista", - "Author": "Autor", - "Genre": "Gênero", - "HistoryDetails": "Detalhes do histórico", - "Label": "Rótulo", - "Publisher": "Editora", - "Season": "Temporada", - "Theme": "Tema", - "TotalHostGrabs": "Total de capturas do host", - "TotalHostQueries": "Total de consultas do host", - "TotalIndexerQueries": "Total de consultas do indexador", - "SelectIndexer": "Selecionar Indexador", - "StopSelecting": "Parar Seleção", - "UpdateAvailable": "Nova atualização está disponível", - "ApplicationURL": "URL do aplicativo", - "ApplicationUrlHelpText": "A URL externa deste aplicativo, incluindo http(s)://, porta e base da URL", - "OnHealthRestored": "Com a Saúde Restaurada", - "OnHealthRestoredHelpText": "Com a Saúde Restaurada", - "ApiKeyValidationHealthCheckMessage": "Atualize sua chave de API para ter pelo menos {0} caracteres. Você pode fazer isso através das configurações ou do arquivo de configuração" + "About": "Sobre", + "AcceptConfirmationModal": "Aceitar o pop-up de confirmação", + "Actions": "Ações", + "Add": "Adicionar", + "AddApplication": "Adicionar Aplicativo", + "AddCustomFilter": "Adicionar Filtro Personalizado", + "AddDownloadClient": "Adicionar cliente de download", + "AddDownloadClientToProwlarr": "Adicionar um cliente de download possibilita que o Prowlarr envie lançamentos diretamente da interface ao executar uma pesquisa manual.", + "AddIndexer": "Adicionar indexador", + "AddIndexerProxy": "Adicionar Proxy ao Indexador", + "AddNewIndexer": "Adicionar novo indexador", + "AddRemoveOnly": "Adicionar e remover apenas", + "AddSyncProfile": "Adicionar Perfil de Sincronização", + "AddToDownloadClient": "Adicionar lançamento ao cliente de download", + "Added": "Adicionado", + "AddedToDownloadClient": "Lançamento adicionado ao cliente", + "AddingTag": "Adicionando etiqueta", + "Age": "Tempo de vida", + "Album": "Álbum", + "All": "Todos", + "AllIndexersHiddenDueToFilter": "Todos os indexadores estão ocultos devido ao filtro aplicado.", + "Analytics": "Análises", + "AnalyticsEnabledHelpText": "Envie informações anônimas de uso e erro para os servidores do Prowlarr. Isso inclui informações sobre seu navegador, quais páginas da interface Web do Prowlarr você usa, relatórios de erros, e a versão do sistema operacional e do tempo de execução. Usaremos essas informações para priorizar recursos e correções de bugs.", + "ApiKey": "Chave da API", + "ApiKeyValidationHealthCheckMessage": "Atualize sua chave de API para ter pelo menos {0} caracteres. Você pode fazer isso através das configurações ou do arquivo de configuração", + "AppDataDirectory": "Diretório AppData", + "AppDataLocationHealthCheckMessage": "A atualização não será possível para evitar a exclusão de AppData na atualização", + "AppProfileDeleteConfirm": "Tem certeza que deseja excluir {0}?", + "AppProfileInUse": "Perfil de aplicativo em uso", + "AppProfileSelectHelpText": "Os perfis de aplicativos são usados para controlar as configurações de RSS, Pesquisa automática e Pesquisa interativa ao sincronizar o aplicativo", + "AppSettingsSummary": "Aplicativos e configurações para configurar como Prowlarr interage com seus programas PVR", + "Application": "Aplicação", + "ApplicationLongTermStatusCheckAllClientMessage": "Todos os aplicativos estão indisponíveis devido a falhas por mais de 6 horas", + "ApplicationLongTermStatusCheckSingleClientMessage": "Aplicativos indisponíveis devido a falhas por mais de 6 horas: {0}", + "ApplicationStatusCheckAllClientMessage": "Não há aplicativos disponíveis devido a falhas", + "ApplicationStatusCheckSingleClientMessage": "Aplicativos indisponíveis devido a falhas: {0}", + "ApplicationURL": "URL do aplicativo", + "ApplicationUrlHelpText": "A URL externa deste aplicativo, incluindo http(s)://, porta e base da URL", + "Applications": "Aplicativos", + "Apply": "Aplicar", + "ApplyTags": "Aplicar tags", + "ApplyTagsHelpTexts1": "Como aplicar tags aos indexadores selecionados", + "ApplyTagsHelpTexts2": "Adicionar: inserir as tags à lista de tags existente", + "ApplyTagsHelpTexts3": "Remover: excluir as tags inseridas", + "ApplyTagsHelpTexts4": "Substituir: sobrepor as tags existentes pelas inseridas (deixe em branco para limpar todas as tags)", + "Apps": "Aplicativos", + "AreYouSureYouWantToDeleteCategory": "Tem certeza de que deseja excluir a categoria mapeada?", + "AreYouSureYouWantToResetYourAPIKey": "Tem certeza de que deseja redefinir sua chave da API?", + "Artist": "Artista", + "AudioSearch": "Pesquisar Áudio", + "Auth": "Autenticação", + "Authentication": "Autenticação", + "AuthenticationMethodHelpText": "Requer nome de usuário e senha para acessar o Prowlarr", + "AuthenticationRequired": "Autenticação Requerida", + "AuthenticationRequiredHelpText": "Altera para quais solicitações a autenticação é necessária. Não mude a menos que você entenda os riscos.", + "AuthenticationRequiredWarning": "Para impedir o acesso remoto sem autenticação, o Prowlarr agora exige que a autenticação seja habilitada. Configure seu método de autenticação e credenciais. Você pode, opcionalmente, desabilitar a autenticação de endereços locais. Consulte o FAQ para obter informações adicionais.", + "Author": "Autor", + "Automatic": "Automático", + "AutomaticSearch": "Pesquisa automática", + "AverageResponseTimesMs": "Tempos Médios de Resposta (Ms)", + "Backup": "Backup", + "BackupFolderHelpText": "Os caminhos relativos estarão no diretório AppData do Prowlarr", + "BackupIntervalHelpText": "Intervalo entre backups automáticos", + "BackupNow": "Disparar Backup", + "BackupRetentionHelpText": "Backups automáticos anteriores ao período de retenção serão limpos automaticamente", + "Backups": "Backups", + "BeforeUpdate": "Antes da atualização", + "BindAddress": "Endereço de vínculo", + "BindAddressHelpText": "Endereço IP válido, localhost ou '*' para todas as interfaces", + "Book": "Livro", + "BookSearch": "Pesquisar Livro", + "BookSearchTypes": "Tipos de Pesquisa de Livros", + "Branch": "Ramificação", + "BranchUpdate": "Ramificação para atualização do Prowlarr", + "BranchUpdateMechanism": "Ramificação usada pelo mecanismo de atualização externo", + "BypassProxyForLocalAddresses": "Ignorar proxy para endereços locais", + "Cancel": "Cancelar", + "CancelPendingTask": "Tem certeza de que deseja cancelar esta tarefa pendente?", + "Categories": "Categorias", + "Category": "Categoria", + "CertificateValidation": "Validação de certificado", + "CertificateValidationHelpText": "Alterar o quão estrita é a validação da certificação HTTPS", + "ChangeHasNotBeenSavedYet": "A alteração ainda não foi salva", + "Clear": "Limpar", + "ClearHistory": "Limpar histórico", + "ClearHistoryMessageText": "Tem certeza de que deseja limpar o histórico do Prowlarr?", + "ClientPriority": "Prioridade do cliente", + "CloneProfile": "Clonar perfil", + "Close": "Fechar", + "CloseCurrentModal": "Fechar modal atual", + "Columns": "Colunas", + "Component": "Componente", + "Connect": "Notificações", + "ConnectSettings": "Configurações de conexão", + "ConnectSettingsSummary": "Notificações e scripts personalizados", + "ConnectionLost": "Conexão perdida", + "ConnectionLostAutomaticMessage": "O Prowlarr tentará se conectar automaticamente, ou você pode clicar em Recarregar abaixo.", + "ConnectionLostMessage": "O Prowlarr perdeu sua conexão com o backend e precisará ser recarregado para restaurar a funcionalidade.", + "Connections": "Conexões", + "CouldNotConnectSignalR": "Não é possível conectar ao SignalR, a interface não atualizará", + "Custom": "Personalizado", + "CustomFilters": "Filtros Personalizados", + "DBMigration": "Migração de banco de dados", + "Database": "Banco de dados", + "Date": "Data", + "Dates": "Datas", + "Delete": "Excluir", + "DeleteAppProfile": "Excluir perfil do aplicativo", + "DeleteApplication": "Excluir aplicativo", + "DeleteApplicationMessageText": "Tem certeza de que deseja excluir o aplicativo \"{0}\"?", + "DeleteBackup": "Excluir backup", + "DeleteBackupMessageText": "Tem certeza que deseja excluir o backup \"{0}\"?", + "DeleteClientCategory": "Excluir Categoria de Cliente de Download", + "DeleteDownloadClient": "Excluir cliente de download", + "DeleteDownloadClientMessageText": "Tem certeza que deseja excluir o cliente de download \"{0}\"?", + "DeleteIndexerProxy": "Apagar Proxy do Indexador", + "DeleteIndexerProxyMessageText": "Tem certeza que deseja apagar o proxy '{0}'?", + "DeleteNotification": "Excluir notificação", + "DeleteNotificationMessageText": "Tem certeza de que deseja excluir a notificação \"{0}\"?", + "DeleteTag": "Excluir tag", + "DeleteTagMessageText": "Tem certeza de que deseja excluir a tag \"{0}\"?", + "Description": "Descrição", + "Details": "Detalhes", + "DevelopmentSettings": "Configurações de desenvolvimento", + "Disabled": "Desabilitado", + "DisabledUntil": "Desabilitar Até", + "Discord": "Discord", + "Docker": "Docker", + "Donations": "Doações", + "DownloadClient": "Cliente de download", + "DownloadClientCategory": "Categoria de Download do Cliente", + "DownloadClientSettings": "Configurações do cliente de download", + "DownloadClientStatusCheckAllClientMessage": "Todos os clientes de download estão indisponíveis devido a falhas", + "DownloadClientStatusCheckSingleClientMessage": "Clientes de download indisponíveis devido a falhas: {0}", + "DownloadClients": "Clientes de download", + "DownloadClientsSettingsSummary": "Configuração de clientes de download para integração com a pesquisa da interface do usuário do Prowlarr", + "Duration": "Duração", + "Edit": "Editar", + "EditIndexer": "Editar indexador", + "EditSyncProfile": "Editar Perfil de Sincronização", + "ElapsedTime": "Tempo Decorrido", + "Enable": "Habilitar", + "EnableAutomaticSearch": "Ativar pesquisa automática", + "EnableAutomaticSearchHelpText": "Será usado ao realizar pesquisas automáticas pela interface ou pelo Prowlarr", + "EnableIndexer": "Habilitar indexador", + "EnableInteractiveSearch": "Ativar pesquisa interativa", + "EnableInteractiveSearchHelpText": "Será usado com a pesquisa interativa", + "EnableRss": "Habilitar RSS", + "EnableRssHelpText": "Habilitar feed RSS para o indexador", + "EnableSSL": "Habilitar SSL", + "EnableSslHelpText": " Requer a reinicialização com a execução como administrador para fazer efeito", + "Enabled": "Habilitado", + "EnabledRedirected": "Habilitado, Redirecionado", + "Encoding": "Codificação", + "Ended": "Terminou", + "Episode": "Episódio", + "Error": "Erro", + "ErrorLoadingContents": "Erro ao carregar conteúdo", + "EventType": "Tipo de evento", + "Events": "Eventos", + "Exception": "Exceção", + "ExistingTag": "Tag existente", + "Failed": "Falhou", + "FeatureRequests": "Solicitações de recursos", + "Filename": "Nome do arquivo", + "Files": "Arquivos", + "Filter": "Filtrar", + "FilterPlaceHolder": "Pesquisar indexadores", + "Filters": "Filtros", + "Fixed": "Corrigido", + "FocusSearchBox": "Selecionar caixa de pesquisa", + "Folder": "Pasta", + "ForMoreInformationOnTheIndividualDownloadClients": "Para saber mais sobre cada cliente de download, clique nos botões de informações.", + "FullSync": "Sincronização completa", + "General": "Geral", + "GeneralSettings": "Configurações gerais", + "GeneralSettingsSummary": "Porta, SSL, nome de usuário/senha, proxy, análises e atualizações", + "Genre": "Gênero", + "GrabReleases": "Capturar lançamento(s)", + "GrabTitle": "Obter Título", + "Grabbed": "Obtido", + "Grabs": "Obtenções", + "Health": "Integridade", + "HealthNoIssues": "Nenhum problema com sua configuração", + "HiddenClickToShow": "Oculto, clique para mostrar", + "HideAdvanced": "Ocultar Avançado", + "History": "Histórico", + "HistoryCleanup": "Histórico de Limpeza", + "HistoryCleanupDaysHelpText": "Defina como 0 para desabilitar a limpeza automática", + "HistoryCleanupDaysHelpTextWarning": "Os arquivos na lixeira mais antigos do que o número de dias selecionado serão limpos automaticamente", + "HistoryDetails": "Detalhes do histórico", + "HomePage": "Página inicial", + "Host": "Host", + "Hostname": "Nome do host", + "Id": "ID", + "IgnoredAddresses": "Endereços ignorados", + "IllRestartLater": "Reiniciarei mais tarde", + "IncludeHealthWarningsHelpText": "Incluir avisos de integridade", + "IncludeManualGrabsHelpText": "Incluir Capturas Manuais feitas no Prowlarr", + "Indexer": "Indexador", + "IndexerAlreadySetup": "Pelo menos uma instância do indexador já está configurada", + "IndexerAuth": "Autenticação do indexador", + "IndexerDetails": "Detalhes do Indexador", + "IndexerDisabled": "Indexador Desabilitado", + "IndexerFailureRate": "Taxa de falha do indexador", + "IndexerFlags": "Sinalizadores do indexador", + "IndexerHealthCheckNoIndexers": "Não há indexadores habilitados, o Prowlarr não retornará resultados para a pesquisa", + "IndexerInfo": "Info do Indexador", + "IndexerLongTermStatusCheckAllClientMessage": "Todos os indexadores estão indisponíveis devido a falhas por mais de 6 horas", + "IndexerLongTermStatusCheckSingleClientMessage": "Indexadores indisponíveis devido a falhas por mais de 6 horas: {0}", + "IndexerName": "Nome do Indexador", + "IndexerNoDefCheckMessage": "Os indexadores não têm definição e não funcionarão: {0}. Por favor, remova e (ou) adicione novamente ao Prowlarr", + "IndexerObsoleteCheckMessage": "Os seguintes indexadores são obsoletos ou foram atualizados: {0}. Remova-os e/ou adicione-os novamente ao Prowlarr", + "IndexerPriority": "Prioridade do indexador", + "IndexerPriorityHelpText": "Prioridade do Indexador de 1 (Mais Alta) a 50 (Mais Baixa). Padrão: 25.", + "IndexerProxies": "Proxies do Indexador", + "IndexerProxy": "Proxy do Indexador", + "IndexerProxyStatusCheckAllClientMessage": "Todos os proxies estão indisponíveis devido a falhas", + "IndexerProxyStatusCheckSingleClientMessage": "Proxies indisponíveis devido a falhas: {0}", + "IndexerQuery": "Consulta do indexador", + "IndexerRss": "RSS do indexador", + "IndexerSettingsSummary": "Defina várias configurações globais do Indexador, incluindo Proxies.", + "IndexerSite": "Site do Indexador", + "IndexerStatusCheckAllClientMessage": "Todos os indexadores estão indisponíveis devido a falhas", + "IndexerStatusCheckSingleClientMessage": "Indexadores indisponíveis devido a falhas: {0}", + "IndexerTagsHelpText": "Usar etiquetas para especificar os proxies do indexador ou com quais aplicativos o indexador está sincronizado. Aplicativos sem 1 ou mais etiquetas de indexador correspondentes não serão sincronizados.", + "IndexerVipCheckExpiredClientMessage": "Benefícios VIP do Indexador expiraram: {0}", + "IndexerVipCheckExpiringClientMessage": "Os benefícios VIPS do Indexador expirarão em breve: {0}", + "Indexers": "Indexadores", + "IndexersSelectedInterp": "{0} indexador(es) selecionado(s)", + "Info": "Informações", + "InitialFailure": "Falha Inicial", + "InstanceName": "Nome da instância", + "InstanceNameHelpText": "Nome da instância na guia e para o nome do aplicativo do Syslog", + "InteractiveSearch": "Pesquisa interativa", + "Interval": "Intervalo", + "KeyboardShortcuts": "Atalhos de teclado", + "Label": "Rótulo", + "Language": "Idioma", + "LastDuration": "Última duração", + "LastExecution": "Última Execução", + "LastFailure": "Última Falha", + "LastWriteTime": "Hora da última gravação", + "LaunchBrowserHelpText": " Abrir o navegador Web e navegar até a página inicial do Prowlarr ao iniciar o aplicativo.", + "Level": "Nível", + "Link": "Link", + "LogFiles": "Arquivos de log", + "LogLevel": "Nível do log", + "LogLevelTraceHelpTextWarning": "O registro de rastreamento deve ser ativado apenas temporariamente", + "Logging": "Registro em log", + "Logs": "Registros", + "MIA": "Desaparecidos", + "MaintenanceRelease": "Versão de manutenção: correções de bugs e outras melhorias. Veja Github Commit History para mais detalhes", + "Manual": "Manual", + "MappedCategories": "Categorias Mapeadas", + "MappedDrivesRunningAsService": "As unidades de rede mapeadas não estão disponíveis quando executadas como um serviço do Windows. Consulte as Perguntas frequentes para saber mais", + "MassEditor": "Editor em Massa", + "Mechanism": "Mecanismo", + "Message": "Mensagem", + "MinimumSeeders": "Mínimo de Seeders", + "MinimumSeedersHelpText": "Semeadores mínimos exigidos pelo aplicativo para o indexador baixar", + "Mode": "Modo", + "More": "Mais", + "MoreInfo": "Mais informações", + "MovieIndexScrollBottom": "Índice do filme: rolar pra baixo", + "MovieIndexScrollTop": "Índice do filme: rolar para cima", + "MovieSearch": "Pesquisar Filme", + "MovieSearchTypes": "Tipos de Pesquisa de Filmes", + "MusicSearchTypes": "Tipos de Pesquisa de Músicas", + "Name": "Nome", + "NetCore": ".NET", + "New": "Novo", + "NextExecution": "Próxima Execução", + "No": "Não", + "NoBackupsAreAvailable": "Não há backups disponíveis", + "NoChange": "Sem alteração", + "NoChanges": "Sem alterações", + "NoLeaveIt": "Não, deixe assim", + "NoLinks": "Sem Links", + "NoLogFiles": "Sem arquivos de log", + "NoSearchResultsFound": "Nenhum resultado encontrado, tente fazer uma nova busca abaixo.", + "NoTagsHaveBeenAddedYet": "Você ainda não adicionou tags", + "NoUpdatesAreAvailable": "Não há atualizações disponíveis", + "NotSupported": "Não Suportado", + "Notification": "Notificação", + "NotificationTriggers": "Acionadores da notificação", + "NotificationTriggersHelpText": "Selecionar quais eventos devem acionar esta notificação", + "Notifications": "Notificações", + "OAuthPopupMessage": "Os pop-ups estão bloqueados em seu navegador", + "Ok": "Ok", + "OnApplicationUpdate": "Ao atualizar o aplicativo", + "OnApplicationUpdateHelpText": "Ao atualizar o aplicativo", + "OnGrab": "Ao Obter Lançamento", + "OnGrabHelpText": "Ao obter lançamento", + "OnHealthIssue": "Ao ter problema de integridade", + "OnHealthIssueHelpText": "Ao ter problema de integridade", + "OnHealthRestored": "Com a Saúde Restaurada", + "OnHealthRestoredHelpText": "Com a Saúde Restaurada", + "OpenBrowserOnStart": "Abrir navegador ao iniciar", + "OpenThisModal": "Abrir este modal", + "Options": "Opções", + "PackageVersion": "Versão do pacote", + "PageSize": "Tamanho da página", + "PageSizeHelpText": "Quantidade de itens a exibir em cada página", + "Parameters": "Parâmetros", + "Password": "Senha", + "Peers": "Pares", + "PendingChangesDiscardChanges": "Descartar alterações e sair", + "PendingChangesMessage": "Há alterações não salvas. Tem certeza que deseja sair desta página?", + "PendingChangesStayReview": "Ficar e revisar alterações", + "Port": "Porta", + "PortNumber": "Número da porta", + "Presets": "Predefinições", + "Priority": "Prioridade", + "PriorityHelpText": "Priorizar vários clientes de download. Usamos um rodízio para clientes com a mesma prioridade.", + "PrioritySettings": "Prioridade", + "Privacy": "Privacidade", + "Private": "Privado", + "Protocol": "Protocolo", + "ProwlarrSupportsAnyDownloadClient": "O Prowlarr é compatível com todos os clientes de download listados abaixo.", + "ProwlarrSupportsAnyIndexer": "Prowlarr suporte muitos indexadores em adição a qualquer indexador que use o padrão Newznab/Torznab usando 'Newznab Genérico' (para usenet) ou 'Torznab Genérico' (para torrents). Busque & Selecione seu indexador dos abaixo.", + "Proxies": "Proxies", + "Proxy": "Proxy", + "ProxyBypassFilterHelpText": "Usar \",\" como separador e \"*.\" como curinga para subdomínios", + "ProxyCheckBadRequestMessage": "Falha ao testar o proxy. Código de status: {0}", + "ProxyCheckFailedToTestMessage": "Falha ao testar o proxy: {0}", + "ProxyCheckResolveIpMessage": "Falha ao resolver o endereço IP do host de proxy configurado {0}", + "ProxyPasswordHelpText": "Você só precisa inserir um nome de usuário e uma senha se solicitado. Caso contrário, deixe em branco.", + "ProxyType": "Tipo de proxy", + "ProxyUsernameHelpText": "Você só precisa inserir um nome de usuário e uma senha se solicitado. Caso contrário, deixe em branco.", + "Public": "Público", + "Publisher": "Editora", + "Query": "Consulta", + "QueryOptions": "Opções de Consulta", + "QueryResults": "Resultados da Consulta", + "Queue": "Fila", + "Queued": "Enfileirado", + "RSS": "RSS", + "RSSIsNotSupportedWithThisIndexer": "O RSS não é compatível com este indexador", + "RawSearchSupported": "Pesquisa Bruta Suportada", + "ReadTheWikiForMoreInformation": "Leia a Wiki para saber mais", + "Reddit": "Reddit", + "Redirect": "Redirecionar", + "RedirectHelpText": "Redirecionar a solicitação de download de entrada para o indexador e passar diretamente para a obtenção, em vez de por proxy usando o Prowlarr", + "Refresh": "Atualizar", + "RefreshMovie": "Atualizar filme", + "ReleaseBranchCheckOfficialBranchMessage": "A ramificação {0} não é de uma versão válida para o Prowlarr, você não receberá atualizações", + "ReleaseStatus": "Status da versão", + "Reload": "Recarregar", + "Remove": "Remover", + "RemoveFilter": "Remover filtro", + "RemovedFromTaskQueue": "Removido da fila de tarefas", + "RemovingTag": "Removendo tag", + "RepeatSearch": "Repetir pesquisa", + "Replace": "Substituir", + "Reset": "Redefinir", + "ResetAPIKey": "Redefinir chave da API", + "Restart": "Reiniciar", + "RestartNow": "Reiniciar agora", + "RestartProwlarr": "Reiniciar o Prowlarr", + "RestartRequiredHelpTextWarning": "Requer reinicialização para ter efeito", + "Restore": "Restaurar", + "RestoreBackup": "Restaurar backup", + "Result": "Resultado", + "Retention": "Retenção", + "RssFeed": "Alimentador RSS", + "SSLCertPassword": "Senha do certificado SSL", + "SSLCertPasswordHelpText": "Senha para arquivo pfx", + "SSLCertPath": "Caminho do certificado SSL", + "SSLCertPathHelpText": "Caminho para o arquivo pfx", + "SSLPort": "Porta SSL", + "Save": "Salvar", + "SaveChanges": "Salvar alterações", + "SaveSettings": "Salvar configurações", + "Scheduled": "Agendado", + "ScriptPath": "Caminho do script", + "Search": "Pesquisar", + "SearchCapabilities": "Recursos de Pesquisa", + "SearchIndexers": "Pesquisar indexadores", + "SearchType": "Tipo de Pesquisa", + "SearchTypes": "Tipos de pesquisa", + "Season": "Temporada", + "Security": "Segurança", + "Seeders": "Semeadores", + "SelectAll": "Selecionar tudo", + "SelectIndexer": "Selecionar Indexador", + "SemiPrivate": "Semi-Privado", + "SendAnonymousUsageData": "Enviar dados de uso anônimos", + "SetTags": "Definir tags", + "Settings": "Configurações", + "SettingsConsoleLogLevel": "Nível de log do console", + "SettingsEnableColorImpairedMode": "Habilitar modo para daltonismo", + "SettingsEnableColorImpairedModeHelpText": "Estilo alterado para permitir que usuários com daltonismo distingam melhor as informações codificadas por cores", + "SettingsFilterSentryEvents": "Filtrar eventos de análises", + "SettingsFilterSentryEventsHelpText": "Filtrar eventos de erro de usuário conhecidos para que não sejam enviados para análise", + "SettingsIndexerLogging": "Registro em log avançado do indexador", + "SettingsIndexerLoggingHelpText": "Registrar dados adicionar do indexador, incluindo resposta", + "SettingsLogRotate": "Rotação de logs", + "SettingsLogRotateHelpText": "Quantidade máxima de arquivos de log a manter na pasta", + "SettingsLogSql": "Registrar SQL", + "SettingsLongDateFormat": "Formato longo da data", + "SettingsShortDateFormat": "Formato curto da data", + "SettingsShowRelativeDates": "Mostrar datas relativas", + "SettingsShowRelativeDatesHelpText": "Mostrar datas absolutas ou relativas (Hoje, Ontem, etc.)", + "SettingsSqlLoggingHelpText": "Registrar todas as consultas de SQL do Prowlarr", + "SettingsTimeFormat": "Formato de hora", + "ShowAdvanced": "Mostrar Avançado", + "ShowSearch": "Mostrar pesquisa", + "ShowSearchHelpText": "Mostrar botão de pesquisa ao passar o mouse", + "ShownClickToHide": "Mostrar configurações avançadas, clique para ocultar", + "Shutdown": "Desligar", + "Size": "Tamanho", + "Sort": "Classificar", + "Source": "Fonte", + "StartTypingOrSelectAPathBelow": "Comece a digitar ou selecione um caminho abaixo", + "Started": "Iniciado", + "StartupDirectory": "Diretório de inicialização", + "Stats": "Estatísticas", + "Status": "Status", + "StopSelecting": "Parar Seleção", + "Style": "Estilo", + "SuggestTranslationChange": "Sugerir alteração para a tradução", + "SyncAppIndexers": "Sincronizar indexadores do aplicativo", + "SyncLevel": "Nível de sincronização", + "SyncLevelAddRemove": "Adicione e remova somente: quando os indexadores são adicionados ou removidos do Prowlarr, ele atualizará este aplicativo remoto.", + "SyncLevelFull": "Full Sync: manterá totalmente os indexadores deste aplicativo em sincronia. As alterações feitas em indexadores em Prowlarr são então sincronizadas com este aplicativo. Qualquer alteração feita para indexadores remotamente dentro deste aplicativo será substituída por Prowlarr na próxima sincronização.", + "SyncProfile": "Perfil de Sincronização", + "SyncProfiles": "Perfis de Sincronização", + "System": "Sistema", + "SystemTimeCheckMessage": "A hora do sistema está desligada por mais de 1 dia. Tarefas agendadas podem não ser executadas corretamente até que o horário seja corrigido", + "TVSearchTypes": "Tipos de Pesquisa de Seriados", + "TableOptions": "Opções da tabela", + "TableOptionsColumnsMessage": "Escolha quais colunas são visíveis e em que ordem aparecem", + "TagCannotBeDeletedWhileInUse": "Não pode ser excluído durante o uso", + "TagIsNotUsedAndCanBeDeleted": "A tag não está em uso e pode ser excluída", + "Tags": "Tags", + "TagsHelpText": "Aplica-se a indexadores com pelo menos uma tag correspondente", + "TagsSettingsSummary": "Veja todas as tags e como são usadas. Tags não utilizadas podem ser removidas", + "Tasks": "Tarefas", + "Test": "Testar", + "TestAll": "Testar tudo", + "TestAllApps": "Testar todos os aplicativos", + "TestAllClients": "Testar todos os clientes", + "TestAllIndexers": "Testar todos os indexadores", + "TheLatestVersionIsAlreadyInstalled": "A versão mais recente do Prowlarr já está instalada", + "Theme": "Tema", + "ThemeHelpText": "Alterar o tema da interface do usuário do aplicativo, o tema 'Auto' usará o tema do sistema operacional para definir o modo Claro ou Escuro. Inspirado por {0}", + "Time": "Tempo", + "Title": "Título", + "Today": "Hoje", + "Tomorrow": "Amanhã", + "Torrent": "Torrent", + "Torrents": "Torrents", + "TotalHostGrabs": "Total de capturas do host", + "TotalHostQueries": "Total de consultas do host", + "TotalIndexerQueries": "Total de consultas do indexador", + "TotalIndexerSuccessfulGrabs": "Total de capturas bem-sucedidas do indexador", + "TotalUserAgentGrabs": "Total de capturas do agente de usuário", + "TotalUserAgentQueries": "Total de consultas do agente do usuário", + "Track": "Faixa", + "TvSearch": "Pesquisar Séries", + "Type": "Tipo", + "UI": "Interface", + "UILanguage": "Idioma da interface", + "UILanguageHelpText": "Idioma que o Prowlarr usará para a interface", + "UILanguageHelpTextWarning": "É necessário recarregar o navegador", + "UISettings": "Configurações da interface", + "UISettingsSummary": "Opções de daltonismo, data e idioma", + "URLBase": "URL base", + "UnableToAddANewAppProfilePleaseTryAgain": "Não foi possível adicionar um novo perfil de aplicativo, tente novamente.", + "UnableToAddANewApplicationPleaseTryAgain": "Não foi possível adicionar um novo aplicativo, tente novamente.", + "UnableToAddANewDownloadClientPleaseTryAgain": "Não foi possível adicionar um novo cliente de download, tente novamente.", + "UnableToAddANewIndexerPleaseTryAgain": "Não foi possível adicionar um novo indexador, tente novamente.", + "UnableToAddANewIndexerProxyPleaseTryAgain": "Não foi possível adicionar um novo proxy indexador, tente novamente.", + "UnableToAddANewNotificationPleaseTryAgain": "Não foi possível adicionar uma nova notificação, tente novamente.", + "UnableToLoadAppProfiles": "Não foi possível carregar os perfis de aplicativos", + "UnableToLoadApplicationList": "Não é possível carregar a lista de aplicativos", + "UnableToLoadBackups": "Não foi possível carregar os backups", + "UnableToLoadDevelopmentSettings": "Não foi possível carregar as configurações de desenvolvimento", + "UnableToLoadDownloadClients": "Não foi possível carregar os clientes de download", + "UnableToLoadGeneralSettings": "Não foi possível carregar as configurações gerais", + "UnableToLoadHistory": "Não foi possível carregar o histórico", + "UnableToLoadIndexerProxies": "Não foi possível carregar proxies do indexador", + "UnableToLoadIndexers": "Não foi possível carregar os indexadores", + "UnableToLoadNotifications": "Não foi possível carregar as notificações", + "UnableToLoadTags": "Não foi possível carregar as tags", + "UnableToLoadUISettings": "Não foi possível carregar as configurações da interface", + "UnsavedChanges": "Alterações não salvas", + "UnselectAll": "Desmarcar tudo", + "UpdateAutomaticallyHelpText": "Baixar e instalar atualizações automaticamente. Você ainda poderá instalar a partir de Sistema: Atualizações", + "UpdateAvailable": "Nova atualização está disponível", + "UpdateCheckStartupNotWritableMessage": "Não é possível instalar a atualização porque a pasta de inicialização '{0}' não pode ser gravada pelo usuário '{1}'.", + "UpdateCheckStartupTranslocationMessage": "Não é possível instalar a atualização porque a pasta de inicialização '{0}' está em uma pasta de translocação de aplicativo.", + "UpdateCheckUINotWritableMessage": "Não é possível instalar a atualização porque a pasta de IU '{0}' não pode ser gravada pelo usuário '{1}'.", + "UpdateMechanismHelpText": "Usar o atualizador integrado do Prowlarr ou um script", + "UpdateScriptPathHelpText": "Caminho para um script personalizado que usa um pacote de atualização extraído e lida com o restante do processo de atualização", + "Updates": "Atualizações", + "Uptime": "Tempo de atividade", + "Url": "Url", + "UrlBaseHelpText": "Para suporte de proxy reverso, o padrão é vazio", + "UseProxy": "Usar proxy", + "Usenet": "Usenet", + "UserAgentProvidedByTheAppThatCalledTheAPI": "User-Agent fornecido pelo aplicativo que chamou a API", + "Username": "Nome de usuário", + "Version": "Versão", + "View": "Exibir", + "VipExpiration": "Expiração VIP", + "Warn": "Avisar", + "Website": "Website", + "Wiki": "Wiki", + "Year": "Ano", + "Yes": "Sim", + "YesCancel": "Sim, Cancelar", + "Yesterday": "Ontem" } diff --git a/src/NzbDrone.Core/Localization/Core/zh_CN.json b/src/NzbDrone.Core/Localization/Core/zh_CN.json index b15d62008..d0e871a14 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_CN.json +++ b/src/NzbDrone.Core/Localization/Core/zh_CN.json @@ -1,506 +1,506 @@ { - "ApplyTagsHelpTexts1": "如何应用标签到已选择索引器", - "ApplyTags": "应用标签", - "Apply": "应用", - "ApplicationStatusCheckSingleClientMessage": "由于故障应用程序不可用", - "ApplicationStatusCheckAllClientMessage": "由于故障所用应用程序都不可用", - "AppDataDirectory": "AppData目录", - "ApiKey": "API 密钥", - "AnalyticsEnabledHelpText": "将匿名使用情况和错误信息发送到Prowlarr的服务器。这包括有关您的浏览器的信息、您使用的Prowlarr WebUI页面、错误报告以及操作系统和运行时版本。我们将使用此信息来确定功能和错误修复的优先级。", - "Analytics": "分析", - "AllIndexersHiddenDueToFilter": "由于应用了筛选器,所有索引器都被隐藏。", - "All": "全部", - "Age": "年龄", - "AddToDownloadClient": "添加发布到下载客户端", - "AddNewIndexer": "添加新的索引器", - "AddingTag": "添加标签", - "AddIndexer": "添加索引器", - "AddedToDownloadClient": "发布已添加档案到客户端", - "Added": "已添加", - "Actions": "操作", - "About": "关于", - "MoreInfo": "更多信息", - "Mode": "模式", - "MIA": "MIA", - "Message": "信息", - "Mechanism": "机制", - "Manual": "手动", - "MaintenanceRelease": "维护版本:修复错误及其他改进,参见Github提交 查看更多详情", - "Logs": "日志", - "LogLevelTraceHelpTextWarning": "追踪日志只应该暂时启用", - "LogLevel": "日志等级", - "Logging": "日志记录中", - "LogFiles": "日志文件", - "Level": "等级", - "LaunchBrowserHelpText": " 启动浏览器时导航到Prowlarr 主页。", - "LastWriteTime": "最后写入时间", - "Language": "语言", - "KeyboardShortcuts": "键盘快捷键", - "Interval": "间隔", - "InteractiveSearch": "手动搜索", - "Info": "信息", - "IndexerStatusCheckSingleClientMessage": "搜刮器因错误不可用:{0}", - "IndexerStatusCheckAllClientMessage": "所有搜刮器都因错误不可用", - "IndexersSelectedInterp": "已选择 {0} 个搜刮器", - "Indexers": "搜刮器", - "IndexerRss": "搜刮器RSS", - "IndexerQuery": "搜刮器查询", - "IndexerPriorityHelpText": "索引器优先级从1(最高)到50(最低),默认25。", - "IndexerPriority": "搜刮器优先级", - "IndexerObsoleteCheckMessage": "搜刮器已过弃用或已更新:{0}。请将其删除和(或)重新添加到 Prowlarr", - "IndexerLongTermStatusCheckSingleClientMessage": "由于故障6小时,下列搜刮器都已不可用:{0}", - "IndexerLongTermStatusCheckAllClientMessage": "由于故障超过6小时,所有搜刮器均不可用", - "IndexerHealthCheckNoIndexers": "未启用任何搜刮器,Prowlarr将不会返回搜索结果", - "IndexerFlags": "搜刮器标记", - "IndexerAuth": "搜刮器认证", - "Indexer": "搜刮器", - "IncludeHealthWarningsHelpText": "包含健康度警告", - "IllRestartLater": "稍后重启", - "IgnoredAddresses": "已忽略地址", - "Id": "Id", - "Hostname": "主机名", - "Host": "主机", - "HomePage": "主页", - "History": "历史记录", - "HideAdvanced": "隐藏高级设置", - "HiddenClickToShow": "已隐藏,点击显示", - "HealthNoIssues": "您的设置没有问题", - "Health": "健康度", - "Grabs": "抓取", - "Grabbed": "已抓取", - "GeneralSettingsSummary": "端口、SSL、用户名/密码、代理、分析、更新", - "GeneralSettings": "通用设置", - "General": "通用", - "FullSync": "完全同步", - "ForMoreInformationOnTheIndividualDownloadClients": "有关个别下载客户端的详细信息,请单击info按钮。", - "Folder": "文件夹", - "FocusSearchBox": "聚焦搜索框", - "Fixed": "已修复", - "FilterPlaceHolder": "搜刮器搜索", - "Filter": "过滤", - "Files": "文件", - "Filename": "文件名", - "FeatureRequests": "功能建议", - "Failed": "失败", - "ExistingTag": "已有标签", - "Exception": "例外", - "EventType": "事件类型", - "Events": "事件", - "ErrorLoadingContents": "读取内容错误", - "Error": "错误", - "Encoding": "编码", - "EnableSslHelpText": " 重启生效", - "EnableSSL": "启用SSL", - "EnableRssHelpText": "为搜刮器启用 RSS订阅", - "EnableRss": "启用RSS", - "EnableInteractiveSearchHelpText": "当手动搜索启用时使用", - "EnableInteractiveSearch": "启用手动搜索", - "EnableIndexer": "启用搜刮器", - "Enabled": "已启用", - "EnableAutomaticSearchHelpText": "当自动搜索通过UI或Prowlarr执行时将被使用", - "EnableAutomaticSearch": "启用自动搜索", - "Enable": "启用", - "EditIndexer": "编辑搜刮器", - "Edit": "编辑", - "DownloadClientStatusCheckSingleClientMessage": "所有下载客户端都不可用: {0}", - "DownloadClientStatusCheckAllClientMessage": "所有下载客户端都不可用", - "DownloadClientsSettingsSummary": "下载客户端配置以集成到 Prowlarr UI 搜索中", - "DownloadClientSettings": "下载客户端设置", - "DownloadClients": "下载客户端", - "DownloadClient": "下载客户端", - "Donations": "捐赠", - "Docker": "Docker", - "Discord": "冲突", - "Disabled": "禁用", - "DevelopmentSettings": "开发设置", - "Details": "详情", - "Description": "描述", - "DeleteTagMessageText": "您确定要删除标签 '{0}' 吗?", - "DeleteTag": "删除标签", - "DeleteNotificationMessageText": "您确定要删除推送 '{0}' 吗?", - "DeleteNotification": "删除消息推送", - "DeleteDownloadClientMessageText": "您确定要删除下载客户端 '{0}' 吗?", - "DeleteDownloadClient": "删除下载客户端", - "DeleteBackupMessageText": "您确定要删除备份 '{0}' 吗?", - "DeleteBackup": "删除备份", - "DeleteAppProfile": "删除应用配置文件", - "DeleteApplicationMessageText": "您确定要删除应用程序“{0}”吗?", - "DeleteApplication": "删除应用程序", - "Delete": "删除", - "DBMigration": "数据库迁移版本", - "Dates": "日期", - "Date": "日期", - "CustomFilters": "自定义过滤", - "Custom": "自定义", - "CouldNotConnectSignalR": "无法连接至SignalR,不会升级UI", - "ConnectSettingsSummary": "通知和自定义脚本", - "ConnectSettings": "连接设置", - "Connections": "连接", - "ConnectionLostMessage": "Prowlarr 已与服务端断开链接,请尝试刷新来恢复使用。", - "ConnectionLostAutomaticMessage": "Prowlarr 将会自动重连,您也可以点击下方的重新加载。", - "ConnectionLost": "连接丢失", - "Connect": "通知", - "Component": "组件", - "Columns": "列", - "CloseCurrentModal": "关闭当前模组", - "Close": "关闭", - "CloneProfile": "复制配置", - "ClientPriority": "客户端优先级", - "ClearHistoryMessageText": "您确定要清除Prowlarr所有的历史记录吗?", - "ClearHistory": "清楚历史", - "Clear": "清除", - "ChangeHasNotBeenSavedYet": "修改暂未保存", - "CertificateValidationHelpText": "改变HTTPS证书验证的严格程度", - "CertificateValidation": "验证证书", - "Category": "类别", - "CancelPendingTask": "您确定要取消这个挂起的任务吗?", - "Cancel": "取消", - "BypassProxyForLocalAddresses": "对局域网地址不使用代理", - "BranchUpdateMechanism": "外部更新机制使用的分支", - "BranchUpdate": "更新Prowlarr的分支", - "Branch": "分支", - "BindAddressHelpText": "有效的 IPv4 地址、localhost、或以'*'代表所有接口", - "BindAddress": "绑定地址", - "BeforeUpdate": "更新前", - "Backups": "备份", - "BackupRetentionHelpText": "早于保留周期的自动备份将被自动清除", - "BackupNow": "马上备份", - "BackupFolderHelpText": "相对路径将在 Prowlarr 的 AppData 目录下", - "Backup": "备份", - "AutomaticSearch": "自动搜索", - "Automatic": "自动化", - "AuthenticationMethodHelpText": "需要账号和密码以登录Prowlarr", - "Authentication": "认证", - "Auth": "认证", - "AreYouSureYouWantToResetYourAPIKey": "你确认希望重置API密钥吗?", - "Apps": "应用程序", - "AppProfileSelectHelpText": "应用程序配置用于控制应用程序同步设置 RSS、自动搜索和交互式搜索设置", - "AppProfileInUse": "正在使用的应用程序配置文件", - "AppProfileDeleteConfirm": "您确认您想删除吗?", - "ApplyTagsHelpTexts4": "替换:用输入的标签替换标签(不输入标签将清除所有标签)", - "ApplyTagsHelpTexts3": "删除:移除输入的标签", - "ApplyTagsHelpTexts2": "添加:将标签添加到现有标签列表", - "Applications": "程序", - "AppDataLocationHealthCheckMessage": "更新将无法阻止在更新时删除 AppData", - "AddRemoveOnly": "仅添加和删除", - "AddDownloadClientToProwlarr": "添加下载客户端允许 Prowlarr 在进行手动搜索时从 UI直接发送结果.", - "AddDownloadClient": "添加下载客户端", - "Add": "添加", - "SettingsEnableColorImpairedModeHelpText": "改变样式,以允许有颜色障碍的用户更好地区分颜色编码信息", - "SettingsEnableColorImpairedMode": "启用色障模式", - "ProxyUsernameHelpText": "如果需要,您只需要输入用户名和密码。否则就让它们为空。", - "ProxyType": "代理类型", - "ProxyPasswordHelpText": "如果需要,您只需要输入用户名和密码,否则就让它们为空。", - "ProxyCheckResolveIpMessage": "无法解析已设置的代理服务器主机{0}的IP地址", - "ProxyCheckFailedToTestMessage": "测试代理失败: {0}", - "ProxyCheckBadRequestMessage": "测试代理失败,状态码: {0}", - "ProxyBypassFilterHelpText": "使用“ , ”作为分隔符,和“ *. ”作为二级域名的通配符", - "Proxy": "代理", - "ProwlarrSupportsAnyIndexer": "Prowlarr支持多种搜刮器,包括任何使用Newznab/Torznab标准的搜刮器(“通用Newznab”对应Usenet,“Generic Torznab”对应Torrents)。从以下搜索并选择你的搜刮器。", - "ProwlarrSupportsAnyDownloadClient": "Prowlarr 支持以下列出的下载客户端。", - "Protocol": "协议", - "Privacy": "隐私", - "PrioritySettings": "优先级", - "PriorityHelpText": "优先考虑多个下载客户端,循环查询用于具有相同优先级的客户端。", - "Priority": "优先级", - "Presets": "预设", - "PortNumber": "端口号", - "Port": "端口", - "PendingChangesStayReview": "留下检查更改", - "PendingChangesMessage": "您有未保存的修改,确定要退出本页么?", - "PendingChangesDiscardChanges": "舍弃修改并退出", - "Peers": "用户", - "Password": "密码", - "PageSizeHelpText": "每页显示的项目数", - "PageSize": "页面大小", - "PackageVersion": "Package版本", - "Options": "选项", - "OpenThisModal": "打开该模组", - "OpenBrowserOnStart": "打开浏览器时启动", - "OnHealthIssueHelpText": "健康度异常", - "Ok": "完成", - "OAuthPopupMessage": "您的浏览器已禁止弹出页面", - "NoUpdatesAreAvailable": "无可用更新", - "NotificationTriggersHelpText": "选择触发此通知的事件", - "NotificationTriggers": "通知触发器", - "NoTagsHaveBeenAddedYet": "未添加标签", - "NoLogFiles": "没有日志文件", - "NoLeaveIt": "不,就这样", - "NoChanges": "无修改", - "NoChange": "无修改", - "NoBackupsAreAvailable": "无备份可用", - "New": "新的", - "NetCore": ".NET", - "Name": "名称", - "MovieIndexScrollTop": "影片索引:滚动到顶部", - "MovieIndexScrollBottom": "影片索引:滚动到底部", - "BackupIntervalHelpText": "自动备份时间间隔", - "IndexerProxyStatusCheckAllClientMessage": "所有搜刮器都因错误不可用", - "SettingsShowRelativeDates": "显示相对日期", - "SettingsShowRelativeDatesHelpText": "显示相对日期(今天昨天等)或绝对日期", - "Source": "源", - "SSLCertPasswordHelpText": "pfx文件密码", - "TagCannotBeDeletedWhileInUse": "使用中无法删除", - "TagIsNotUsedAndCanBeDeleted": "标签未被使用,可删除", - "UILanguageHelpTextWarning": "浏览器需重新加载", - "UISettings": "UI设置", - "UnableToAddANewApplicationPleaseTryAgain": "无法添加新通知,请稍后重试。", - "UnableToAddANewAppProfilePleaseTryAgain": "无法添加新影片质量配置,请稍后重试。", - "UnableToAddANewDownloadClientPleaseTryAgain": "无法添加下载客户端,请稍后重试。", - "UnableToAddANewIndexerProxyPleaseTryAgain": "无法添加搜刮器,请稍后重试。", - "UnableToAddANewNotificationPleaseTryAgain": "无法添加新通知,请稍后重试。", - "UnableToLoadBackups": "无法加载备份", - "UnableToLoadDownloadClients": "无法加载下载客户端", - "UnableToLoadGeneralSettings": "无法加载通用设置", - "UnableToLoadUISettings": "无法加载UI设置", - "UnsavedChanges": "未保存更改", - "UnselectAll": "全不选", - "UpdateAutomaticallyHelpText": "自动下载并安装更新。你还可以在“系统:更新”中安装", - "UpdateCheckStartupNotWritableMessage": "无法安装更新,因为用户“{1}”对于启动文件夹“{0}”没有写入权限。", - "UpdateCheckStartupTranslocationMessage": "无法安装更新,因为启动文件夹“{0}”在一个应用程序迁移文件夹。Cannot install update because startup folder '{0}' is in an App Translocation folder.", - "Usenet": "Usenet", - "UseProxy": "使用代理", - "Username": "用户名", - "Version": "版本", - "View": "视图", - "Warn": "警告", - "Wiki": "Wiki", - "Yesterday": "昨天", - "Torrent": "Torrents", - "Torrents": "种子", - "Type": "类型", - "UnableToLoadNotifications": "无法加载通知连接", - "RefreshMovie": "刷新影片", - "Reload": "重新加载", - "Restore": "恢复", - "NoLinks": "无链接", - "Queue": "队列", - "ReadTheWikiForMoreInformation": "查阅Wiki获得更多信息", - "Reddit": "Reddit", - "ReleaseBranchCheckOfficialBranchMessage": "分支 {0} 不是合法的Prowlarr发布分支,您不会收到任何更新", - "RemovedFromTaskQueue": "从任务队列中移除", - "RemoveFilter": "移除过滤条件", - "RemovingTag": "移除标签", - "RestartRequiredHelpTextWarning": "需要重新启动才能生效", - "RestoreBackup": "恢复备份", - "Result": "结果", - "Retention": "保留", - "RSS": "RSS", - "RSSIsNotSupportedWithThisIndexer": "该搜刮器不支持RSS", - "Save": "保存", - "SaveChanges": "保存更改", - "SaveSettings": "保存设置", - "Scheduled": "计划中", - "ScriptPath": "脚本路径", - "SearchIndexers": "搜刮器搜索", - "Security": "安全", - "Seeders": "种子", - "SelectAll": "选择全部", - "SendAnonymousUsageData": "发送匿名使用数据", - "Settings": "设置", - "SettingsLongDateFormat": "长时间格式", - "SettingsShortDateFormat": "短日期格式", - "SettingsTimeFormat": "时间格式", - "ShowAdvanced": "显示高级设置", - "ShownClickToHide": "显示高级设置,点击隐藏", - "ShowSearch": "显示搜索按钮", - "ShowSearchHelpText": "在选项中显示搜索框", - "Shutdown": "关机", - "Size": "文件大小", - "Sort": "排序", - "SSLCertPath": "SSL证书路径", - "SSLCertPathHelpText": "pfx文件路径", - "SSLPort": "SSL端口", - "StartTypingOrSelectAPathBelow": "输入路径或者从下面选择", - "StartupDirectory": "启动目录", - "Status": "状态", - "Style": "类型", - "SuggestTranslationChange": "建议翻译改变 Suggest translation change", - "SystemTimeCheckMessage": "系统时间相差超过1天。在纠正时间之前,计划的任务可能无法正确运行", - "TableOptions": "表格选项", - "TableOptionsColumnsMessage": "选择显示哪些列并排序", - "Tags": "标签", - "TagsHelpText": "适用于至少有一个匹配标签的索引器", - "TagsSettingsSummary": "显示全部标签和标签使用情况,可删除未使用的标签", - "Tasks": "任务", - "Test": "测试", - "TestAll": "测试全部", - "TestAllClients": "测试全部客户端", - "Time": "时间", - "Title": "标题", - "Today": "今天", - "Tomorrow": "明天", - "UI": "UI界面", - "UILanguage": "UI界面语言", - "UILanguageHelpText": "Prowlarr使用的UI界面语言", - "UpdateCheckUINotWritableMessage": "无法安装升级,因为用户“{1}”不可写入界面文件夹“{0}”。", - "UpdateMechanismHelpText": "使用 Prowlarr 内置的更新器或者脚本", - "Updates": "更新", - "UpdateScriptPathHelpText": "自定义脚本的路径,该脚本处理获取的更新包并处理更新过程的其余部分", - "Uptime": "运行时间", - "URLBase": "基本URL", - "UrlBaseHelpText": "对于反向代理支持,默认为空", - "ReleaseStatus": "发布状态", - "SetTags": "设定标签", - "Search": "搜索", - "SSLCertPassword": "SSL证书密码", - "UnableToAddANewIndexerPleaseTryAgain": "无法添加搜刮器,请稍后重试。", - "AcceptConfirmationModal": "接受确认模组Accept Confirmation Modal", - "DeleteIndexerProxyMessageText": "您确定要删除列表 '{0}'?", - "IndexerProxyStatusCheckSingleClientMessage": "搜刮器因错误不可用:{0}", - "Refresh": "刷新", - "UnableToLoadHistory": "无法加载历史记录", - "UnableToLoadTags": "无法加载标签", - "YesCancel": "是,取消", - "System": "系统", - "Reset": "重置", - "ResetAPIKey": "重置API Key", - "Restart": "重启", - "RestartNow": "马上重启", - "UnableToLoadIndexerProxies": "无法加载索引器代理", - "UnableToLoadDevelopmentSettings": "无法加载开发设置", - "UnableToLoadAppProfiles": "无法加载应用配置", - "UISettingsSummary": "日期,语言及色盲选项", - "TestAllApps": "测试全部应用", - "SyncLevel": "同步级别", - "SettingsIndexerLogging": "增强型搜刮器日志", - "SettingsFilterSentryEvents": "筛选分析事件", - "SettingsConsoleLogLevel": "控制台日志级别", - "RestartProwlarr": "重启Prowlarr", - "Redirect": "重定向", - "Query": "查询字段", - "Notifications": "通知", - "Notification": "通知", - "NoSearchResultsFound": "无搜索结果,请在下面尝试新的搜索。", - "IndexerVipCheckExpiringClientMessage": "索引器VIP特权即将过期:{0}", - "IndexerVipCheckExpiredClientMessage": "索引器VIP特权已过期:{0}", - "IndexerProxy": "搜刮器代理", - "IndexerProxies": "搜刮器代理", - "DeleteIndexerProxy": "删除搜刮器代理", - "AddIndexerProxy": "添加搜刮器代理", - "AppSettingsSummary": "配置Prowlarr与PVR程序交互方式的应用和设置", - "SyncLevelFull": "完全同步:将保持此应用的索引器完全同步。当在Prowlarr中所做的更改将同步到与此关联的应用程序。任何关联应用上的更改都将在下次同步时被Prowlarr覆盖。", - "SyncLevelAddRemove": "仅添加和删除:当索引器从 Prowlarr 添加或删除时,它将更新与此关联的应用程序。", - "SyncAppIndexers": "同步应用索引", - "Stats": "统计数据", - "SettingsSqlLoggingHelpText": "记录来自Prowlarr的所有SQL查询", - "SettingsLogSql": "事务日志", - "SettingsLogRotateHelpText": "保存在日志文件夹中的最大日志文件数", - "SettingsLogRotate": "日志轮替", - "SettingsIndexerLoggingHelpText": "记录额外的搜刮器数据,包括响应", - "SettingsFilterSentryEventsHelpText": "过滤已知的用户错误事件,不让其作为分析报告发送", - "RedirectHelpText": "重定向搜刮器的传入下载请求并直接传递抓取,而不是通过Prowlarr代理请求搜刮器", - "IndexerTagsHelpText": "使用标签指定索引器代理, 索引器同步到哪些应用程序,或者只是为了组织索引器。未指定索引器的应用程序将不会同步。", - "IndexerSettingsSummary": "配置全局索引器设置,包括代理。", - "HistoryCleanupDaysHelpTextWarning": "回收站中的文件在超出选择的天数后会被自动清理", - "UserAgentProvidedByTheAppThatCalledTheAPI": "由调用API的应用程序提供的User-Agent", - "Filters": "过滤器", - "HistoryCleanupDaysHelpText": "设置为0关闭自动清理", - "OnGrab": "运行中", - "OnHealthIssue": "健康度异常", - "TestAllIndexers": "测试全部搜刮器", - "AudioSearch": "音频搜索", - "BookSearch": "图书搜索", - "Categories": "分类", - "Database": "数据库", - "HistoryCleanup": "清理历史记录", - "IndexerAlreadySetup": "至少已经设置了一个索引器", - "IndexerInfo": "索引器信息", - "IndexerNoDefCheckMessage": "索引器没有定义,将无法工作: {0}. 请删除或重新添加到Prowlarr", - "MovieSearch": "搜索电影", - "OnApplicationUpdate": "程序更新时", - "OnApplicationUpdateHelpText": "在程序更新时", - "Private": "私有", - "Public": "公开", - "QueryOptions": "查询选项", - "QueryResults": "查询结果", - "MassEditor": "批量编辑器", - "Proxies": "代理", - "SearchType": "搜索类型", - "TvSearch": "搜索剧集", - "UnableToLoadApplicationList": "123", - "BookSearchTypes": "搜索图书类型", - "IndexerDetails": "‎索引器‎‎详细信息‎", - "IndexerName": "‎索引‎‎名字‎", - "IndexerSite": "‎索引‎‎网站‎", - "MovieSearchTypes": "‎影片‎‎搜索‎‎类型‎", - "MusicSearchTypes": "‎音乐‎‎搜索‎‎类型‎", - "NotSupported": "‎不支持‎", - "RawSearchSupported": "‎支持原始‎‎搜索‎", - "SearchCapabilities": "‎搜索‎‎能力‎", - "SemiPrivate": "‎半私有‎", - "TVSearchTypes": "‎电视‎‎搜索‎‎类型‎", - "Url": "Url", - "Website": "‎网站‎", - "GrabReleases": "抓取版本", - "Link": "链接", - "MappedDrivesRunningAsService": "映射的网络驱动器在作为Windows服务运行时不可用。请参阅常见问题解答了解更多信息", - "No": "否", - "Yes": "是", - "Application": "程序", - "SearchTypes": "搜索类型", - "UnableToLoadIndexers": "无法加载搜刮器", - "AddSyncProfile": "添加同步配置文件", - "SyncProfiles": "同步配置文件", - "EditSyncProfile": "编辑同步配置文件", - "SyncProfile": "同步配置文件", - "MinimumSeeders": "最少播种量", - "MinimumSeedersHelpText": "用于索引器抓取的应用程序所需的最小播种量", - "InstanceName": "中文", - "InstanceNameHelpText": "选项卡及日志应用名称", - "ThemeHelpText": "更改应用程序UI主题,“自动”主题将使用您的操作系统主题设置明亮模式或黑暗模式。受到{0}的影响", - "Duration": "时长", - "ElapsedTime": "运行时间", - "EnabledRedirected": "启用, 修改", - "Ended": "已完结", - "GrabTitle": "抓取标题", - "LastExecution": "上一次执行", - "NextExecution": "接下来执行", - "Parameters": "参数", - "Queued": "队列中", - "Started": "已开始", - "LastDuration": "上一次用时", - "ApplicationLongTermStatusCheckAllClientMessage": "由于故障超过6小时,所有程序都不可用", - "ApplicationLongTermStatusCheckSingleClientMessage": "由于故障超过6小时而无法使用的程序:{0}", - "AuthenticationRequired": "需要认证", - "AreYouSureYouWantToDeleteCategory": "您确定要删除映射类别吗?", - "DeleteClientCategory": "删除下载客户端类别", - "DownloadClientCategory": "下载客户端类别", - "MappedCategories": "映射类别", - "AuthenticationRequiredHelpText": "更改需要身份验证的请求。除非您了解风险,否则请勿更改。", - "AuthenticationRequiredWarning": "为了防止远程访问而无需身份验证,Prowlarr现在需要启用身份验证。请配置您的身份验证方法和凭据。您可以选择从本地地址禁用身份验证。有关其他信息,请参阅FAQ。", - "Replace": "替换", - "TheLatestVersionIsAlreadyInstalled": "已安装最新版的Prowlarr", - "Remove": "移除", - "OnGrabHelpText": "运行中", - "AddApplication": "添加应用程序", - "AddCustomFilter": "添加自定义过滤", - "IncludeManualGrabsHelpText": "安装手动抓取Prowlarr", - "RssFeed": "RSS订阅", - "VipExpiration": "VIP过期", - "DisabledUntil": "禁用Until", - "IndexerDisabled": "索引器已被禁用", - "InitialFailure": "初始化失败", - "LastFailure": "最后一次失败", - "Episode": "集", - "IndexerFailureRate": "Indexer失败率", - "Author": "作者", - "AverageResponseTimesMs": "平均响应时间(毫秒)", - "Book": "图书", - "Genre": "类型", - "HistoryDetails": "历史详情", - "ApplicationURL": "应用程序 URL", - "ApplicationUrlHelpText": "此应用程序的外部URL,包括http(s)://,端口和基本URL", - "Theme": "主题", - "Year": "年", - "RepeatSearch": "再次搜索", - "ApiKeyValidationHealthCheckMessage": "请更新您的API key,保证长度至少为20个字符。您可以通过设置或配置文件执行此操作", - "Artist": "艺术家", - "Season": "季", - "SelectIndexer": "选择索引器", - "StopSelecting": "停止选择", - "UpdateAvailable": "有新的更新可用", - "Label": "标签", - "More": "更多的", - "Publisher": "发布者" + "About": "关于", + "AcceptConfirmationModal": "接受确认模组Accept Confirmation Modal", + "Actions": "操作", + "Add": "添加", + "AddApplication": "添加应用程序", + "AddCustomFilter": "添加自定义过滤", + "AddDownloadClient": "添加下载客户端", + "AddDownloadClientToProwlarr": "添加下载客户端允许 Prowlarr 在进行手动搜索时从 UI直接发送结果.", + "AddIndexer": "添加索引器", + "AddIndexerProxy": "添加搜刮器代理", + "AddNewIndexer": "添加新的索引器", + "AddRemoveOnly": "仅添加和删除", + "AddSyncProfile": "添加同步配置文件", + "AddToDownloadClient": "添加发布到下载客户端", + "Added": "已添加", + "AddedToDownloadClient": "发布已添加档案到客户端", + "AddingTag": "添加标签", + "Age": "年龄", + "All": "全部", + "AllIndexersHiddenDueToFilter": "由于应用了筛选器,所有索引器都被隐藏。", + "Analytics": "分析", + "AnalyticsEnabledHelpText": "将匿名使用情况和错误信息发送到Prowlarr的服务器。这包括有关您的浏览器的信息、您使用的Prowlarr WebUI页面、错误报告以及操作系统和运行时版本。我们将使用此信息来确定功能和错误修复的优先级。", + "ApiKey": "API 密钥", + "ApiKeyValidationHealthCheckMessage": "", + "AppDataDirectory": "AppData目录", + "AppDataLocationHealthCheckMessage": "更新将无法阻止在更新时删除 AppData", + "AppProfileDeleteConfirm": "您确认您想删除吗?", + "AppProfileInUse": "正在使用的应用程序配置文件", + "AppProfileSelectHelpText": "应用程序配置用于控制应用程序同步设置 RSS、自动搜索和交互式搜索设置", + "AppSettingsSummary": "配置Prowlarr与PVR程序交互方式的应用和设置", + "Application": "程序", + "ApplicationLongTermStatusCheckAllClientMessage": "由于故障超过6小时,所有程序都不可用", + "ApplicationLongTermStatusCheckSingleClientMessage": "由于故障超过6小时而无法使用的程序:{0}", + "ApplicationStatusCheckAllClientMessage": "由于故障所用应用程序都不可用", + "ApplicationStatusCheckSingleClientMessage": "由于故障应用程序不可用", + "ApplicationURL": "应用程序 URL", + "ApplicationUrlHelpText": "此应用程序的外部URL,包括http(s)://,端口和基本URL", + "Applications": "程序", + "Apply": "应用", + "ApplyTags": "应用标签", + "ApplyTagsHelpTexts1": "如何应用标签到已选择索引器", + "ApplyTagsHelpTexts2": "添加:将标签添加到现有标签列表", + "ApplyTagsHelpTexts3": "删除:移除输入的标签", + "ApplyTagsHelpTexts4": "替换:用输入的标签替换标签(不输入标签将清除所有标签)", + "Apps": "应用程序", + "AreYouSureYouWantToDeleteCategory": "您确定要删除映射类别吗?", + "AreYouSureYouWantToResetYourAPIKey": "你确认希望重置API密钥吗?", + "Artist": "艺术家", + "AudioSearch": "音频搜索", + "Auth": "认证", + "Authentication": "认证", + "AuthenticationMethodHelpText": "需要账号和密码以登录Prowlarr", + "AuthenticationRequired": "需要认证", + "AuthenticationRequiredHelpText": "更改需要身份验证的请求。除非您了解风险,否则请勿更改。", + "AuthenticationRequiredWarning": "为了防止远程访问而无需身份验证,Prowlarr现在需要启用身份验证。请配置您的身份验证方法和凭据。您可以选择从本地地址禁用身份验证。有关其他信息,请参阅FAQ。", + "Author": "作者", + "Automatic": "自动化", + "AutomaticSearch": "自动搜索", + "AverageResponseTimesMs": "平均响应时间(毫秒)", + "Backup": "备份", + "BackupFolderHelpText": "相对路径将在 Prowlarr 的 AppData 目录下", + "BackupIntervalHelpText": "自动备份时间间隔", + "BackupNow": "马上备份", + "BackupRetentionHelpText": "早于保留周期的自动备份将被自动清除", + "Backups": "备份", + "BeforeUpdate": "更新前", + "BindAddress": "绑定地址", + "BindAddressHelpText": "有效的 IPv4 地址、localhost、或以'*'代表所有接口", + "Book": "图书", + "BookSearch": "图书搜索", + "BookSearchTypes": "搜索图书类型", + "Branch": "分支", + "BranchUpdate": "更新Prowlarr的分支", + "BranchUpdateMechanism": "外部更新机制使用的分支", + "BypassProxyForLocalAddresses": "对局域网地址不使用代理", + "Cancel": "取消", + "CancelPendingTask": "您确定要取消这个挂起的任务吗?", + "Categories": "分类", + "Category": "类别", + "CertificateValidation": "验证证书", + "CertificateValidationHelpText": "改变HTTPS证书验证的严格程度", + "ChangeHasNotBeenSavedYet": "修改暂未保存", + "Clear": "清除", + "ClearHistory": "清楚历史", + "ClearHistoryMessageText": "您确定要清除Prowlarr所有的历史记录吗?", + "ClientPriority": "客户端优先级", + "CloneProfile": "复制配置", + "Close": "关闭", + "CloseCurrentModal": "关闭当前模组", + "Columns": "列", + "Component": "组件", + "Connect": "通知", + "ConnectSettings": "连接设置", + "ConnectSettingsSummary": "通知和自定义脚本", + "ConnectionLost": "连接丢失", + "ConnectionLostAutomaticMessage": "Prowlarr 将会自动重连,您也可以点击下方的重新加载。", + "ConnectionLostMessage": "Prowlarr 已与服务端断开链接,请尝试刷新来恢复使用。", + "Connections": "连接", + "CouldNotConnectSignalR": "无法连接至SignalR,不会升级UI", + "Custom": "自定义", + "CustomFilters": "自定义过滤", + "DBMigration": "数据库迁移版本", + "Database": "数据库", + "Date": "日期", + "Dates": "日期", + "Delete": "删除", + "DeleteAppProfile": "删除应用配置文件", + "DeleteApplication": "删除应用程序", + "DeleteApplicationMessageText": "您确定要删除应用程序“{0}”吗?", + "DeleteBackup": "删除备份", + "DeleteBackupMessageText": "您确定要删除备份 '{0}' 吗?", + "DeleteClientCategory": "删除下载客户端类别", + "DeleteDownloadClient": "删除下载客户端", + "DeleteDownloadClientMessageText": "您确定要删除下载客户端 '{0}' 吗?", + "DeleteIndexerProxy": "删除搜刮器代理", + "DeleteIndexerProxyMessageText": "您确定要删除列表 '{0}'?", + "DeleteNotification": "删除消息推送", + "DeleteNotificationMessageText": "您确定要删除推送 '{0}' 吗?", + "DeleteTag": "删除标签", + "DeleteTagMessageText": "您确定要删除标签 '{0}' 吗?", + "Description": "描述", + "Details": "详情", + "DevelopmentSettings": "开发设置", + "Disabled": "禁用", + "DisabledUntil": "禁用Until", + "Discord": "冲突", + "Docker": "Docker", + "Donations": "捐赠", + "DownloadClient": "下载客户端", + "DownloadClientCategory": "下载客户端类别", + "DownloadClientSettings": "下载客户端设置", + "DownloadClientStatusCheckAllClientMessage": "所有下载客户端都不可用", + "DownloadClientStatusCheckSingleClientMessage": "所有下载客户端都不可用: {0}", + "DownloadClients": "下载客户端", + "DownloadClientsSettingsSummary": "下载客户端配置以集成到 Prowlarr UI 搜索中", + "Duration": "时长", + "Edit": "编辑", + "EditIndexer": "编辑搜刮器", + "EditSyncProfile": "编辑同步配置文件", + "ElapsedTime": "运行时间", + "Enable": "启用", + "EnableAutomaticSearch": "启用自动搜索", + "EnableAutomaticSearchHelpText": "当自动搜索通过UI或Prowlarr执行时将被使用", + "EnableIndexer": "启用搜刮器", + "EnableInteractiveSearch": "启用手动搜索", + "EnableInteractiveSearchHelpText": "当手动搜索启用时使用", + "EnableRss": "启用RSS", + "EnableRssHelpText": "为搜刮器启用 RSS订阅", + "EnableSSL": "启用SSL", + "EnableSslHelpText": " 重启生效", + "Enabled": "已启用", + "EnabledRedirected": "启用, 修改", + "Encoding": "编码", + "Ended": "已完结", + "Episode": "集", + "Error": "错误", + "ErrorLoadingContents": "读取内容错误", + "EventType": "事件类型", + "Events": "事件", + "Exception": "例外", + "ExistingTag": "已有标签", + "Failed": "失败", + "FeatureRequests": "功能建议", + "Filename": "文件名", + "Files": "文件", + "Filter": "过滤", + "FilterPlaceHolder": "搜刮器搜索", + "Filters": "过滤器", + "Fixed": "已修复", + "FocusSearchBox": "聚焦搜索框", + "Folder": "文件夹", + "ForMoreInformationOnTheIndividualDownloadClients": "有关个别下载客户端的详细信息,请单击info按钮。", + "FullSync": "完全同步", + "General": "通用", + "GeneralSettings": "通用设置", + "GeneralSettingsSummary": "端口、SSL、用户名/密码、代理、分析、更新", + "Genre": "类型", + "GrabReleases": "抓取版本", + "GrabTitle": "抓取标题", + "Grabbed": "已抓取", + "Grabs": "抓取", + "Health": "健康度", + "HealthNoIssues": "您的设置没有问题", + "HiddenClickToShow": "已隐藏,点击显示", + "HideAdvanced": "隐藏高级设置", + "History": "历史记录", + "HistoryCleanup": "清理历史记录", + "HistoryCleanupDaysHelpText": "设置为0关闭自动清理", + "HistoryCleanupDaysHelpTextWarning": "回收站中的文件在超出选择的天数后会被自动清理", + "HistoryDetails": "历史详情", + "HomePage": "主页", + "Host": "主机", + "Hostname": "主机名", + "Id": "Id", + "IgnoredAddresses": "已忽略地址", + "IllRestartLater": "稍后重启", + "IncludeHealthWarningsHelpText": "包含健康度警告", + "IncludeManualGrabsHelpText": "安装手动抓取Prowlarr", + "Indexer": "搜刮器", + "IndexerAlreadySetup": "至少已经设置了一个索引器", + "IndexerAuth": "搜刮器认证", + "IndexerDetails": "‎索引器‎‎详细信息‎", + "IndexerDisabled": "索引器已被禁用", + "IndexerFailureRate": "Indexer失败率", + "IndexerFlags": "搜刮器标记", + "IndexerHealthCheckNoIndexers": "未启用任何搜刮器,Prowlarr将不会返回搜索结果", + "IndexerInfo": "索引器信息", + "IndexerLongTermStatusCheckAllClientMessage": "由于故障超过6小时,所有搜刮器均不可用", + "IndexerLongTermStatusCheckSingleClientMessage": "由于故障6小时,下列搜刮器都已不可用:{0}", + "IndexerName": "‎索引‎‎名字‎", + "IndexerNoDefCheckMessage": "索引器没有定义,将无法工作: {0}. 请删除或重新添加到Prowlarr", + "IndexerObsoleteCheckMessage": "搜刮器已过弃用或已更新:{0}。请将其删除和(或)重新添加到 Prowlarr", + "IndexerPriority": "搜刮器优先级", + "IndexerPriorityHelpText": "索引器优先级从1(最高)到50(最低),默认25。", + "IndexerProxies": "搜刮器代理", + "IndexerProxy": "搜刮器代理", + "IndexerProxyStatusCheckAllClientMessage": "所有搜刮器都因错误不可用", + "IndexerProxyStatusCheckSingleClientMessage": "搜刮器因错误不可用:{0}", + "IndexerQuery": "搜刮器查询", + "IndexerRss": "搜刮器RSS", + "IndexerSettingsSummary": "配置全局索引器设置,包括代理。", + "IndexerSite": "‎索引‎‎网站‎", + "IndexerStatusCheckAllClientMessage": "所有搜刮器都因错误不可用", + "IndexerStatusCheckSingleClientMessage": "搜刮器因错误不可用:{0}", + "IndexerTagsHelpText": "使用标签指定索引器代理, 索引器同步到哪些应用程序,或者只是为了组织索引器。未指定索引器的应用程序将不会同步。", + "IndexerVipCheckExpiredClientMessage": "索引器VIP特权已过期:{0}", + "IndexerVipCheckExpiringClientMessage": "索引器VIP特权即将过期:{0}", + "Indexers": "搜刮器", + "IndexersSelectedInterp": "已选择 {0} 个搜刮器", + "Info": "信息", + "InitialFailure": "初始化失败", + "InstanceName": "中文", + "InstanceNameHelpText": "选项卡及日志应用名称", + "InteractiveSearch": "手动搜索", + "Interval": "间隔", + "KeyboardShortcuts": "键盘快捷键", + "Label": "标签", + "Language": "语言", + "LastDuration": "上一次用时", + "LastExecution": "上一次执行", + "LastFailure": "最后一次失败", + "LastWriteTime": "最后写入时间", + "LaunchBrowserHelpText": " 启动浏览器时导航到Prowlarr 主页。", + "Level": "等级", + "Link": "链接", + "LogFiles": "日志文件", + "LogLevel": "日志等级", + "LogLevelTraceHelpTextWarning": "追踪日志只应该暂时启用", + "Logging": "日志记录中", + "Logs": "日志", + "MIA": "MIA", + "MaintenanceRelease": "维护版本:修复错误及其他改进,参见Github提交 查看更多详情", + "Manual": "手动", + "MappedCategories": "映射类别", + "MappedDrivesRunningAsService": "映射的网络驱动器在作为Windows服务运行时不可用。请参阅常见问题解答了解更多信息", + "MassEditor": "批量编辑器", + "Mechanism": "机制", + "Message": "信息", + "MinimumSeeders": "最少播种量", + "MinimumSeedersHelpText": "用于索引器抓取的应用程序所需的最小播种量", + "Mode": "模式", + "More": "更多的", + "MoreInfo": "更多信息", + "MovieIndexScrollBottom": "影片索引:滚动到底部", + "MovieIndexScrollTop": "影片索引:滚动到顶部", + "MovieSearch": "搜索电影", + "MovieSearchTypes": "‎影片‎‎搜索‎‎类型‎", + "MusicSearchTypes": "‎音乐‎‎搜索‎‎类型‎", + "Name": "名称", + "NetCore": ".NET", + "New": "新的", + "NextExecution": "接下来执行", + "No": "否", + "NoBackupsAreAvailable": "无备份可用", + "NoChange": "无修改", + "NoChanges": "无修改", + "NoLeaveIt": "不,就这样", + "NoLinks": "无链接", + "NoLogFiles": "没有日志文件", + "NoSearchResultsFound": "无搜索结果,请在下面尝试新的搜索。", + "NoTagsHaveBeenAddedYet": "未添加标签", + "NoUpdatesAreAvailable": "无可用更新", + "NotSupported": "‎不支持‎", + "Notification": "通知", + "NotificationTriggers": "通知触发器", + "NotificationTriggersHelpText": "选择触发此通知的事件", + "Notifications": "通知", + "OAuthPopupMessage": "您的浏览器已禁止弹出页面", + "Ok": "完成", + "OnApplicationUpdate": "程序更新时", + "OnApplicationUpdateHelpText": "在程序更新时", + "OnGrab": "运行中", + "OnGrabHelpText": "运行中", + "OnHealthIssue": "健康度异常", + "OnHealthIssueHelpText": "健康度异常", + "OpenBrowserOnStart": "打开浏览器时启动", + "OpenThisModal": "打开该模组", + "Options": "选项", + "PackageVersion": "Package版本", + "PageSize": "页面大小", + "PageSizeHelpText": "每页显示的项目数", + "Parameters": "参数", + "Password": "密码", + "Peers": "用户", + "PendingChangesDiscardChanges": "舍弃修改并退出", + "PendingChangesMessage": "您有未保存的修改,确定要退出本页么?", + "PendingChangesStayReview": "留下检查更改", + "Port": "端口", + "PortNumber": "端口号", + "Presets": "预设", + "Priority": "优先级", + "PriorityHelpText": "优先考虑多个下载客户端,循环查询用于具有相同优先级的客户端。", + "PrioritySettings": "优先级", + "Privacy": "隐私", + "Private": "私有", + "Protocol": "协议", + "ProwlarrSupportsAnyDownloadClient": "Prowlarr 支持以下列出的下载客户端。", + "ProwlarrSupportsAnyIndexer": "Prowlarr支持多种搜刮器,包括任何使用Newznab/Torznab标准的搜刮器(“通用Newznab”对应Usenet,“Generic Torznab”对应Torrents)。从以下搜索并选择你的搜刮器。", + "Proxies": "代理", + "Proxy": "代理", + "ProxyBypassFilterHelpText": "使用“ , ”作为分隔符,和“ *. ”作为二级域名的通配符", + "ProxyCheckBadRequestMessage": "测试代理失败,状态码: {0}", + "ProxyCheckFailedToTestMessage": "测试代理失败: {0}", + "ProxyCheckResolveIpMessage": "无法解析已设置的代理服务器主机{0}的IP地址", + "ProxyPasswordHelpText": "如果需要,您只需要输入用户名和密码,否则就让它们为空。", + "ProxyType": "代理类型", + "ProxyUsernameHelpText": "如果需要,您只需要输入用户名和密码。否则就让它们为空。", + "Public": "公开", + "Publisher": "发布者", + "Query": "查询字段", + "QueryOptions": "查询选项", + "QueryResults": "查询结果", + "Queue": "队列", + "Queued": "队列中", + "RSS": "RSS", + "RSSIsNotSupportedWithThisIndexer": "该搜刮器不支持RSS", + "RawSearchSupported": "‎支持原始‎‎搜索‎", + "ReadTheWikiForMoreInformation": "查阅Wiki获得更多信息", + "Reddit": "Reddit", + "Redirect": "重定向", + "RedirectHelpText": "重定向搜刮器的传入下载请求并直接传递抓取,而不是通过Prowlarr代理请求搜刮器", + "Refresh": "刷新", + "RefreshMovie": "刷新影片", + "ReleaseBranchCheckOfficialBranchMessage": "分支 {0} 不是合法的Prowlarr发布分支,您不会收到任何更新", + "ReleaseStatus": "发布状态", + "Reload": "重新加载", + "Remove": "移除", + "RemoveFilter": "移除过滤条件", + "RemovedFromTaskQueue": "从任务队列中移除", + "RemovingTag": "移除标签", + "RepeatSearch": "再次搜索", + "Replace": "替换", + "Reset": "重置", + "ResetAPIKey": "重置API Key", + "Restart": "重启", + "RestartNow": "马上重启", + "RestartProwlarr": "重启Prowlarr", + "RestartRequiredHelpTextWarning": "需要重新启动才能生效", + "Restore": "恢复", + "RestoreBackup": "恢复备份", + "Result": "结果", + "Retention": "保留", + "RssFeed": "RSS订阅", + "SSLCertPassword": "SSL证书密码", + "SSLCertPasswordHelpText": "pfx文件密码", + "SSLCertPath": "SSL证书路径", + "SSLCertPathHelpText": "pfx文件路径", + "SSLPort": "SSL端口", + "Save": "保存", + "SaveChanges": "保存更改", + "SaveSettings": "保存设置", + "Scheduled": "计划中", + "ScriptPath": "脚本路径", + "Search": "搜索", + "SearchCapabilities": "‎搜索‎‎能力‎", + "SearchIndexers": "搜刮器搜索", + "SearchType": "搜索类型", + "SearchTypes": "搜索类型", + "Season": "季", + "Security": "安全", + "Seeders": "种子", + "SelectAll": "选择全部", + "SelectIndexer": "选择索引器", + "SemiPrivate": "‎半私有‎", + "SendAnonymousUsageData": "发送匿名使用数据", + "SetTags": "设定标签", + "Settings": "设置", + "SettingsConsoleLogLevel": "控制台日志级别", + "SettingsEnableColorImpairedMode": "启用色障模式", + "SettingsEnableColorImpairedModeHelpText": "改变样式,以允许有颜色障碍的用户更好地区分颜色编码信息", + "SettingsFilterSentryEvents": "筛选分析事件", + "SettingsFilterSentryEventsHelpText": "过滤已知的用户错误事件,不让其作为分析报告发送", + "SettingsIndexerLogging": "增强型搜刮器日志", + "SettingsIndexerLoggingHelpText": "记录额外的搜刮器数据,包括响应", + "SettingsLogRotate": "日志轮替", + "SettingsLogRotateHelpText": "保存在日志文件夹中的最大日志文件数", + "SettingsLogSql": "事务日志", + "SettingsLongDateFormat": "长时间格式", + "SettingsShortDateFormat": "短日期格式", + "SettingsShowRelativeDates": "显示相对日期", + "SettingsShowRelativeDatesHelpText": "显示相对日期(今天昨天等)或绝对日期", + "SettingsSqlLoggingHelpText": "记录来自Prowlarr的所有SQL查询", + "SettingsTimeFormat": "时间格式", + "ShowAdvanced": "显示高级设置", + "ShowSearch": "显示搜索按钮", + "ShowSearchHelpText": "在选项中显示搜索框", + "ShownClickToHide": "显示高级设置,点击隐藏", + "Shutdown": "关机", + "Size": "文件大小", + "Sort": "排序", + "Source": "源", + "StartTypingOrSelectAPathBelow": "输入路径或者从下面选择", + "Started": "已开始", + "StartupDirectory": "启动目录", + "Stats": "统计数据", + "Status": "状态", + "StopSelecting": "停止选择", + "Style": "类型", + "SuggestTranslationChange": "建议翻译改变 Suggest translation change", + "SyncAppIndexers": "同步应用索引", + "SyncLevel": "同步级别", + "SyncLevelAddRemove": "仅添加和删除:当索引器从 Prowlarr 添加或删除时,它将更新与此关联的应用程序。", + "SyncLevelFull": "完全同步:将保持此应用的索引器完全同步。当在Prowlarr中所做的更改将同步到与此关联的应用程序。任何关联应用上的更改都将在下次同步时被Prowlarr覆盖。", + "SyncProfile": "同步配置文件", + "SyncProfiles": "同步配置文件", + "System": "系统", + "SystemTimeCheckMessage": "系统时间相差超过1天。在纠正时间之前,计划的任务可能无法正确运行", + "TVSearchTypes": "‎电视‎‎搜索‎‎类型‎", + "TableOptions": "表格选项", + "TableOptionsColumnsMessage": "选择显示哪些列并排序", + "TagCannotBeDeletedWhileInUse": "使用中无法删除", + "TagIsNotUsedAndCanBeDeleted": "标签未被使用,可删除", + "Tags": "标签", + "TagsHelpText": "适用于至少有一个匹配标签的索引器", + "TagsSettingsSummary": "显示全部标签和标签使用情况,可删除未使用的标签", + "Tasks": "任务", + "Test": "测试", + "TestAll": "测试全部", + "TestAllApps": "测试全部应用", + "TestAllClients": "测试全部客户端", + "TestAllIndexers": "测试全部搜刮器", + "TheLatestVersionIsAlreadyInstalled": "已安装最新版的Prowlarr", + "Theme": "主题", + "ThemeHelpText": "更改应用程序UI主题,“自动”主题将使用您的操作系统主题设置明亮模式或黑暗模式。受到{0}的影响", + "Time": "时间", + "Title": "标题", + "Today": "今天", + "Tomorrow": "明天", + "Torrent": "Torrents", + "Torrents": "种子", + "TvSearch": "搜索剧集", + "Type": "类型", + "UI": "UI界面", + "UILanguage": "UI界面语言", + "UILanguageHelpText": "Prowlarr使用的UI界面语言", + "UILanguageHelpTextWarning": "浏览器需重新加载", + "UISettings": "UI设置", + "UISettingsSummary": "日期,语言及色盲选项", + "URLBase": "基本URL", + "UnableToAddANewAppProfilePleaseTryAgain": "无法添加新影片质量配置,请稍后重试。", + "UnableToAddANewApplicationPleaseTryAgain": "无法添加新通知,请稍后重试。", + "UnableToAddANewDownloadClientPleaseTryAgain": "无法添加下载客户端,请稍后重试。", + "UnableToAddANewIndexerPleaseTryAgain": "无法添加搜刮器,请稍后重试。", + "UnableToAddANewIndexerProxyPleaseTryAgain": "无法添加搜刮器,请稍后重试。", + "UnableToAddANewNotificationPleaseTryAgain": "无法添加新通知,请稍后重试。", + "UnableToLoadAppProfiles": "无法加载应用配置", + "UnableToLoadApplicationList": "123", + "UnableToLoadBackups": "无法加载备份", + "UnableToLoadDevelopmentSettings": "无法加载开发设置", + "UnableToLoadDownloadClients": "无法加载下载客户端", + "UnableToLoadGeneralSettings": "无法加载通用设置", + "UnableToLoadHistory": "无法加载历史记录", + "UnableToLoadIndexerProxies": "无法加载索引器代理", + "UnableToLoadIndexers": "无法加载搜刮器", + "UnableToLoadNotifications": "无法加载通知连接", + "UnableToLoadTags": "无法加载标签", + "UnableToLoadUISettings": "无法加载UI设置", + "UnsavedChanges": "未保存更改", + "UnselectAll": "全不选", + "UpdateAutomaticallyHelpText": "自动下载并安装更新。你还可以在“系统:更新”中安装", + "UpdateAvailable": "有新的更新可用", + "UpdateCheckStartupNotWritableMessage": "无法安装更新,因为用户“{1}”对于启动文件夹“{0}”没有写入权限。", + "UpdateCheckStartupTranslocationMessage": "无法安装更新,因为启动文件夹“{0}”在一个应用程序迁移文件夹。Cannot install update because startup folder '{0}' is in an App Translocation folder.", + "UpdateCheckUINotWritableMessage": "无法安装升级,因为用户“{1}”不可写入界面文件夹“{0}”。", + "UpdateMechanismHelpText": "使用 Prowlarr 内置的更新器或者脚本", + "UpdateScriptPathHelpText": "自定义脚本的路径,该脚本处理获取的更新包并处理更新过程的其余部分", + "Updates": "更新", + "Uptime": "运行时间", + "Url": "Url", + "UrlBaseHelpText": "对于反向代理支持,默认为空", + "UseProxy": "使用代理", + "Usenet": "Usenet", + "UserAgentProvidedByTheAppThatCalledTheAPI": "由调用API的应用程序提供的User-Agent", + "Username": "用户名", + "Version": "版本", + "View": "视图", + "VipExpiration": "VIP过期", + "Warn": "警告", + "Website": "‎网站‎", + "Wiki": "Wiki", + "Year": "年", + "Yes": "是", + "YesCancel": "是,取消", + "Yesterday": "昨天" } From 78aab807034b21253b1a63455dd768f0c31cee42 Mon Sep 17 00:00:00 2001 From: Qstick Date: Wed, 31 May 2023 19:33:28 -0500 Subject: [PATCH 0022/1128] New: Additional custom filter predicates for strings --- .../src/Helpers/Props/filterBuilderTypes.js | 18 +++++++++++++++++- .../src/Helpers/Props/filterTypePredicates.js | 16 ++++++++++++++++ frontend/src/Helpers/Props/filterTypes.js | 10 +++++++++- 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/frontend/src/Helpers/Props/filterBuilderTypes.js b/frontend/src/Helpers/Props/filterBuilderTypes.js index 776ba2afc..c0806fabc 100644 --- a/frontend/src/Helpers/Props/filterBuilderTypes.js +++ b/frontend/src/Helpers/Props/filterBuilderTypes.js @@ -1,14 +1,18 @@ import * as filterTypes from './filterTypes'; export const ARRAY = 'array'; +export const CONTAINS = 'contains'; export const DATE = 'date'; +export const EQUAL = 'equal'; export const EXACT = 'exact'; export const NUMBER = 'number'; export const STRING = 'string'; export const all = [ ARRAY, + CONTAINS, DATE, + EQUAL, EXACT, NUMBER, STRING @@ -20,6 +24,10 @@ export const possibleFilterTypes = { { key: filterTypes.NOT_CONTAINS, value: 'does not contain' } ], + [CONTAINS]: [ + { key: filterTypes.CONTAINS, value: 'contains' } + ], + [DATE]: [ { key: filterTypes.LESS_THAN, value: 'is before' }, { key: filterTypes.GREATER_THAN, value: 'is after' }, @@ -29,6 +37,10 @@ export const possibleFilterTypes = { { key: filterTypes.NOT_IN_NEXT, value: 'not in the next' } ], + [EQUAL]: [ + { key: filterTypes.EQUAL, value: 'is' } + ], + [EXACT]: [ { key: filterTypes.EQUAL, value: 'is' }, { key: filterTypes.NOT_EQUAL, value: 'is not' } @@ -47,6 +59,10 @@ export const possibleFilterTypes = { { key: filterTypes.CONTAINS, value: 'contains' }, { key: filterTypes.NOT_CONTAINS, value: 'does not contain' }, { key: filterTypes.EQUAL, value: 'equal' }, - { key: filterTypes.NOT_EQUAL, value: 'not equal' } + { key: filterTypes.NOT_EQUAL, value: 'not equal' }, + { key: filterTypes.STARTS_WITH, value: 'starts with' }, + { key: filterTypes.NOT_STARTS_WITH, value: 'does not start with' }, + { key: filterTypes.ENDS_WITH, value: 'ends with' }, + { key: filterTypes.NOT_ENDS_WITH, value: 'does not end with' } ] }; diff --git a/frontend/src/Helpers/Props/filterTypePredicates.js b/frontend/src/Helpers/Props/filterTypePredicates.js index a3ea11956..d07059c02 100644 --- a/frontend/src/Helpers/Props/filterTypePredicates.js +++ b/frontend/src/Helpers/Props/filterTypePredicates.js @@ -39,6 +39,22 @@ const filterTypePredicates = { [filterTypes.NOT_EQUAL]: function(itemValue, filterValue) { return itemValue !== filterValue; + }, + + [filterTypes.STARTS_WITH]: function(itemValue, filterValue) { + return itemValue.toLowerCase().startsWith(filterValue.toLowerCase()); + }, + + [filterTypes.NOT_STARTS_WITH]: function(itemValue, filterValue) { + return !itemValue.toLowerCase().startsWith(filterValue.toLowerCase()); + }, + + [filterTypes.ENDS_WITH]: function(itemValue, filterValue) { + return itemValue.toLowerCase().endsWith(filterValue.toLowerCase()); + }, + + [filterTypes.NOT_ENDS_WITH]: function(itemValue, filterValue) { + return !itemValue.toLowerCase().endsWith(filterValue.toLowerCase()); } }; diff --git a/frontend/src/Helpers/Props/filterTypes.js b/frontend/src/Helpers/Props/filterTypes.js index 993e8df57..239a4e7e9 100644 --- a/frontend/src/Helpers/Props/filterTypes.js +++ b/frontend/src/Helpers/Props/filterTypes.js @@ -10,6 +10,10 @@ export const LESS_THAN = 'lessThan'; export const LESS_THAN_OR_EQUAL = 'lessThanOrEqual'; export const NOT_CONTAINS = 'notContains'; export const NOT_EQUAL = 'notEqual'; +export const STARTS_WITH = 'startsWith'; +export const NOT_STARTS_WITH = 'notStartsWith'; +export const ENDS_WITH = 'endsWith'; +export const NOT_ENDS_WITH = 'notEndsWith'; export const all = [ CONTAINS, @@ -23,5 +27,9 @@ export const all = [ IN_LAST, NOT_IN_LAST, IN_NEXT, - NOT_IN_NEXT + NOT_IN_NEXT, + STARTS_WITH, + NOT_STARTS_WITH, + ENDS_WITH, + NOT_ENDS_WITH ]; From 9fd3eb4d6bfa59e88a394c27e689b329f48e639b Mon Sep 17 00:00:00 2001 From: Qstick Date: Wed, 31 May 2023 19:41:55 -0500 Subject: [PATCH 0023/1128] Extract useSelectState from SelectContext Co-Authored-By: Mark McDowall --- frontend/src/App/SelectContext.tsx | 150 ++++-------------- frontend/src/Helpers/Hooks/useSelectState.tsx | 113 +++++++++++++ .../Select/IndexerIndexSelectAllButton.tsx | 6 +- .../Select/IndexerIndexSelectAllMenuItem.tsx | 6 +- .../Index/Select/IndexerIndexSelectFooter.tsx | 4 +- .../Select/IndexerIndexSelectModeButton.tsx | 4 +- .../Select/IndexerIndexSelectModeMenuItem.tsx | 4 +- .../Indexer/Index/Table/IndexerIndexRow.tsx | 4 +- .../Index/Table/IndexerIndexTableHeader.tsx | 4 +- 9 files changed, 162 insertions(+), 133 deletions(-) create mode 100644 frontend/src/Helpers/Hooks/useSelectState.tsx diff --git a/frontend/src/App/SelectContext.tsx b/frontend/src/App/SelectContext.tsx index 6980129c1..66be388ce 100644 --- a/frontend/src/App/SelectContext.tsx +++ b/frontend/src/App/SelectContext.tsx @@ -1,58 +1,28 @@ import { cloneDeep } from 'lodash'; -import React, { useEffect } from 'react'; -import areAllSelected from 'Utilities/Table/areAllSelected'; -import selectAll from 'Utilities/Table/selectAll'; -import toggleSelected from 'Utilities/Table/toggleSelected'; +import React, { useCallback, useEffect } from 'react'; +import useSelectState, { SelectState } from 'Helpers/Hooks/useSelectState'; import ModelBase from './ModelBase'; -export enum SelectActionType { - Reset, - SelectAll, - UnselectAll, - ToggleSelected, - RemoveItem, - UpdateItems, -} - -type SelectedState = Record; - -interface SelectState { - selectedState: SelectedState; - lastToggled: number | null; - allSelected: boolean; - allUnselected: boolean; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - items: any[]; -} - -type SelectAction = - | { type: SelectActionType.Reset } - | { type: SelectActionType.SelectAll } - | { type: SelectActionType.UnselectAll } +export type SelectContextAction = + | { type: 'reset' } + | { type: 'selectAll' } + | { type: 'unselectAll' } | { - type: SelectActionType.ToggleSelected; + type: 'toggleSelected'; id: number; isSelected: boolean; shiftKey: boolean; } | { - type: SelectActionType.RemoveItem; + type: 'removeItem'; id: number; } | { - type: SelectActionType.UpdateItems; + type: 'updateItems'; items: ModelBase[]; }; -type Dispatch = (action: SelectAction) => void; - -const initialState = { - selectedState: {}, - lastToggled: null, - allSelected: false, - allUnselected: true, - items: [], -}; +export type SelectDispatch = (action: SelectContextAction) => void; interface SelectProviderOptions { // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -60,90 +30,40 @@ interface SelectProviderOptions { items: Array; } -function getSelectedState(items: ModelBase[], existingState: SelectedState) { - return items.reduce((acc: SelectedState, item) => { - const id = item.id; - - acc[id] = existingState[id] ?? false; - - return acc; - }, {}); -} - -// TODO: Can this be reused? - -const SelectContext = React.createContext<[SelectState, Dispatch] | undefined>( - cloneDeep(undefined) -); - -function selectReducer(state: SelectState, action: SelectAction): SelectState { - const { items, selectedState } = state; - - switch (action.type) { - case SelectActionType.Reset: { - return cloneDeep(initialState); - } - case SelectActionType.SelectAll: { - return { - items, - ...selectAll(selectedState, true), - }; - } - case SelectActionType.UnselectAll: { - return { - items, - ...selectAll(selectedState, false), - }; - } - case SelectActionType.ToggleSelected: { - const result = { - items, - ...toggleSelected( - state, - items, - action.id, - action.isSelected, - action.shiftKey - ), - }; - - return result; - } - case SelectActionType.UpdateItems: { - const nextSelectedState = getSelectedState(action.items, selectedState); - - return { - ...state, - ...areAllSelected(nextSelectedState), - selectedState: nextSelectedState, - items: action.items, - }; - } - default: { - throw new Error(`Unhandled action type: ${action.type}`); - } - } -} +const SelectContext = React.createContext< + [SelectState, SelectDispatch] | undefined +>(cloneDeep(undefined)); export function SelectProvider( props: SelectProviderOptions ) { const { items } = props; - const selectedState = getSelectedState(items, {}); + const [state, dispatch] = useSelectState(); - const [state, dispatch] = React.useReducer(selectReducer, { - selectedState, - lastToggled: null, - allSelected: false, - allUnselected: true, - items, - }); + const dispatchWrapper = useCallback( + (action: SelectContextAction) => { + switch (action.type) { + case 'reset': + case 'removeItem': + dispatch(action); + break; - const value: [SelectState, Dispatch] = [state, dispatch]; + default: + dispatch({ + ...action, + items, + }); + break; + } + }, + [items, dispatch] + ); + + const value: [SelectState, SelectDispatch] = [state, dispatchWrapper]; useEffect(() => { - dispatch({ type: SelectActionType.UpdateItems, items }); - }, [items]); + dispatch({ type: 'updateItems', items }); + }, [items, dispatch]); return ( diff --git a/frontend/src/Helpers/Hooks/useSelectState.tsx b/frontend/src/Helpers/Hooks/useSelectState.tsx new file mode 100644 index 000000000..8fb96e42a --- /dev/null +++ b/frontend/src/Helpers/Hooks/useSelectState.tsx @@ -0,0 +1,113 @@ +import { cloneDeep } from 'lodash'; +import { useReducer } from 'react'; +import ModelBase from 'App/ModelBase'; +import areAllSelected from 'Utilities/Table/areAllSelected'; +import selectAll from 'Utilities/Table/selectAll'; +import toggleSelected from 'Utilities/Table/toggleSelected'; + +export type SelectedState = Record; + +export interface SelectState { + selectedState: SelectedState; + lastToggled: number | null; + allSelected: boolean; + allUnselected: boolean; +} + +export type SelectAction = + | { type: 'reset' } + | { type: 'selectAll'; items: ModelBase[] } + | { type: 'unselectAll'; items: ModelBase[] } + | { + type: 'toggleSelected'; + id: number; + isSelected: boolean; + shiftKey: boolean; + items: ModelBase[]; + } + | { + type: 'removeItem'; + id: number; + } + | { + type: 'updateItems'; + items: ModelBase[]; + }; + +export type Dispatch = (action: SelectAction) => void; + +const initialState = { + selectedState: {}, + lastToggled: null, + allSelected: false, + allUnselected: true, + items: [], +}; + +function getSelectedState(items: ModelBase[], existingState: SelectedState) { + return items.reduce((acc: SelectedState, item) => { + const id = item.id; + + acc[id] = existingState[id] ?? false; + + return acc; + }, {}); +} + +function selectReducer(state: SelectState, action: SelectAction): SelectState { + const { selectedState } = state; + + switch (action.type) { + case 'reset': { + return cloneDeep(initialState); + } + case 'selectAll': { + return { + ...selectAll(selectedState, true), + }; + } + case 'unselectAll': { + return { + ...selectAll(selectedState, false), + }; + } + case 'toggleSelected': { + const result = { + ...toggleSelected( + state, + action.items, + action.id, + action.isSelected, + action.shiftKey + ), + }; + + return result; + } + case 'updateItems': { + const nextSelectedState = getSelectedState(action.items, selectedState); + + return { + ...state, + ...areAllSelected(nextSelectedState), + selectedState: nextSelectedState, + }; + } + default: { + throw new Error(`Unhandled action type: ${action.type}`); + } + } +} + +export default function useSelectState(): [SelectState, Dispatch] { + const selectedState = getSelectedState([], {}); + + const [state, dispatch] = useReducer(selectReducer, { + selectedState, + lastToggled: null, + allSelected: false, + allUnselected: true, + }); + + return [state, dispatch]; +} diff --git a/frontend/src/Indexer/Index/Select/IndexerIndexSelectAllButton.tsx b/frontend/src/Indexer/Index/Select/IndexerIndexSelectAllButton.tsx index 746317dd1..bd7682018 100644 --- a/frontend/src/Indexer/Index/Select/IndexerIndexSelectAllButton.tsx +++ b/frontend/src/Indexer/Index/Select/IndexerIndexSelectAllButton.tsx @@ -1,5 +1,5 @@ import React, { useCallback } from 'react'; -import { SelectActionType, useSelect } from 'App/SelectContext'; +import { useSelect } from 'App/SelectContext'; import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton'; import { icons } from 'Helpers/Props'; import translate from 'Utilities/String/translate'; @@ -25,9 +25,7 @@ function IndexerIndexSelectAllButton(props: IndexerIndexSelectAllButtonProps) { const onPress = useCallback(() => { selectDispatch({ - type: allSelected - ? SelectActionType.UnselectAll - : SelectActionType.SelectAll, + type: allSelected ? 'unselectAll' : 'selectAll', }); }, [allSelected, selectDispatch]); diff --git a/frontend/src/Indexer/Index/Select/IndexerIndexSelectAllMenuItem.tsx b/frontend/src/Indexer/Index/Select/IndexerIndexSelectAllMenuItem.tsx index c5dc6981d..f9a52ed30 100644 --- a/frontend/src/Indexer/Index/Select/IndexerIndexSelectAllMenuItem.tsx +++ b/frontend/src/Indexer/Index/Select/IndexerIndexSelectAllMenuItem.tsx @@ -1,5 +1,5 @@ import React, { useCallback } from 'react'; -import { SelectActionType, useSelect } from 'App/SelectContext'; +import { useSelect } from 'App/SelectContext'; import PageToolbarOverflowMenuItem from 'Components/Page/Toolbar/PageToolbarOverflowMenuItem'; import { icons } from 'Helpers/Props'; import translate from 'Utilities/String/translate'; @@ -26,9 +26,7 @@ function IndexerIndexSelectAllMenuItem( const onPressWrapper = useCallback(() => { selectDispatch({ - type: allSelected - ? SelectActionType.UnselectAll - : SelectActionType.SelectAll, + type: allSelected ? 'unselectAll' : 'selectAll', }); }, [allSelected, selectDispatch]); diff --git a/frontend/src/Indexer/Index/Select/IndexerIndexSelectFooter.tsx b/frontend/src/Indexer/Index/Select/IndexerIndexSelectFooter.tsx index 5d9317859..37828f8f4 100644 --- a/frontend/src/Indexer/Index/Select/IndexerIndexSelectFooter.tsx +++ b/frontend/src/Indexer/Index/Select/IndexerIndexSelectFooter.tsx @@ -1,7 +1,7 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { createSelector } from 'reselect'; -import { SelectActionType, useSelect } from 'App/SelectContext'; +import { useSelect } from 'App/SelectContext'; import SpinnerButton from 'Components/Link/SpinnerButton'; import PageContentFooter from 'Components/Page/PageContentFooter'; import { kinds } from 'Helpers/Props'; @@ -111,7 +111,7 @@ function IndexerIndexSelectFooter() { useEffect(() => { if (!isDeleting && !deleteError) { - selectDispatch({ type: SelectActionType.UnselectAll }); + selectDispatch({ type: 'unselectAll' }); } }, [isDeleting, deleteError, selectDispatch]); diff --git a/frontend/src/Indexer/Index/Select/IndexerIndexSelectModeButton.tsx b/frontend/src/Indexer/Index/Select/IndexerIndexSelectModeButton.tsx index f95a5fa91..31fa1d041 100644 --- a/frontend/src/Indexer/Index/Select/IndexerIndexSelectModeButton.tsx +++ b/frontend/src/Indexer/Index/Select/IndexerIndexSelectModeButton.tsx @@ -1,6 +1,6 @@ import { IconDefinition } from '@fortawesome/fontawesome-common-types'; import React, { useCallback } from 'react'; -import { SelectActionType, useSelect } from 'App/SelectContext'; +import { useSelect } from 'App/SelectContext'; import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton'; interface IndexerIndexSelectModeButtonProps { @@ -20,7 +20,7 @@ function IndexerIndexSelectModeButton( const onPressWrapper = useCallback(() => { if (isSelectMode) { selectDispatch({ - type: SelectActionType.Reset, + type: 'reset', }); } diff --git a/frontend/src/Indexer/Index/Select/IndexerIndexSelectModeMenuItem.tsx b/frontend/src/Indexer/Index/Select/IndexerIndexSelectModeMenuItem.tsx index f7d63950f..8f1c0623f 100644 --- a/frontend/src/Indexer/Index/Select/IndexerIndexSelectModeMenuItem.tsx +++ b/frontend/src/Indexer/Index/Select/IndexerIndexSelectModeMenuItem.tsx @@ -1,6 +1,6 @@ import { IconDefinition } from '@fortawesome/fontawesome-common-types'; import React, { useCallback } from 'react'; -import { SelectActionType, useSelect } from 'App/SelectContext'; +import { useSelect } from 'App/SelectContext'; import PageToolbarOverflowMenuItem from 'Components/Page/Toolbar/PageToolbarOverflowMenuItem'; interface IndexerIndexSelectModeMenuItemProps { @@ -19,7 +19,7 @@ function IndexerIndexSelectModeMenuItem( const onPressWrapper = useCallback(() => { if (isSelectMode) { selectDispatch({ - type: SelectActionType.Reset, + type: 'reset', }); } diff --git a/frontend/src/Indexer/Index/Table/IndexerIndexRow.tsx b/frontend/src/Indexer/Index/Table/IndexerIndexRow.tsx index 7bda8a287..fbb5a88ca 100644 --- a/frontend/src/Indexer/Index/Table/IndexerIndexRow.tsx +++ b/frontend/src/Indexer/Index/Table/IndexerIndexRow.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useState } from 'react'; import { useSelector } from 'react-redux'; -import { SelectActionType, useSelect } from 'App/SelectContext'; +import { useSelect } from 'App/SelectContext'; import Label from 'Components/Label'; import IconButton from 'Components/Link/IconButton'; import RelativeDateCellConnector from 'Components/Table/Cells/RelativeDateCellConnector'; @@ -90,7 +90,7 @@ function IndexerIndexRow(props: IndexerIndexRowProps) { const onSelectedChange = useCallback( ({ id, value, shiftKey }) => { selectDispatch({ - type: SelectActionType.ToggleSelected, + type: 'toggleSelected', id, isSelected: value, shiftKey, diff --git a/frontend/src/Indexer/Index/Table/IndexerIndexTableHeader.tsx b/frontend/src/Indexer/Index/Table/IndexerIndexTableHeader.tsx index aa231533c..10fa849cd 100644 --- a/frontend/src/Indexer/Index/Table/IndexerIndexTableHeader.tsx +++ b/frontend/src/Indexer/Index/Table/IndexerIndexTableHeader.tsx @@ -1,7 +1,7 @@ import classNames from 'classnames'; import React, { useCallback } from 'react'; import { useDispatch } from 'react-redux'; -import { SelectActionType, useSelect } from 'App/SelectContext'; +import { useSelect } from 'App/SelectContext'; import IconButton from 'Components/Link/IconButton'; import Column from 'Components/Table/Column'; import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper'; @@ -47,7 +47,7 @@ function IndexerIndexTableHeader(props: IndexerIndexTableHeaderProps) { const onSelectAllChange = useCallback( ({ value }) => { selectDispatch({ - type: value ? SelectActionType.SelectAll : SelectActionType.UnselectAll, + type: value ? 'selectAll' : 'unselectAll', }); }, [selectDispatch] From e40ccc49adbd7fa16cc835fb08a4f058f6c37b82 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 1 Jun 2023 22:22:37 +0300 Subject: [PATCH 0024/1128] Fixed: (Apps) Prevent null reference exception on sync failure --- .../Applications/LazyLibrarian/LazyLibrarian.cs | 8 ++++++++ src/NzbDrone.Core/Applications/Lidarr/Lidarr.cs | 8 ++++++++ src/NzbDrone.Core/Applications/Mylar/Mylar.cs | 8 ++++++++ src/NzbDrone.Core/Applications/Radarr/Radarr.cs | 8 ++++++++ src/NzbDrone.Core/Applications/Readarr/Readarr.cs | 8 ++++++++ src/NzbDrone.Core/Applications/Sonarr/Sonarr.cs | 8 ++++++++ src/NzbDrone.Core/Applications/Whisparr/Whisparr.cs | 8 ++++++++ 7 files changed, 56 insertions(+) diff --git a/src/NzbDrone.Core/Applications/LazyLibrarian/LazyLibrarian.cs b/src/NzbDrone.Core/Applications/LazyLibrarian/LazyLibrarian.cs index e965d12b4..56401c46d 100644 --- a/src/NzbDrone.Core/Applications/LazyLibrarian/LazyLibrarian.cs +++ b/src/NzbDrone.Core/Applications/LazyLibrarian/LazyLibrarian.cs @@ -78,6 +78,14 @@ namespace NzbDrone.Core.Applications.LazyLibrarian var lazyLibrarianIndexer = BuildLazyLibrarianIndexer(indexer, indexer.Protocol); var remoteIndexer = _lazyLibrarianV1Proxy.AddIndexer(lazyLibrarianIndexer, Settings); + + if (remoteIndexer == null) + { + _logger.Debug("Failed to add {0} [{1}]", indexer.Name, indexer.Id); + + return; + } + _appIndexerMapService.Insert(new AppIndexerMap { AppId = Definition.Id, IndexerId = indexer.Id, RemoteIndexerName = $"{remoteIndexer.Type},{remoteIndexer.Name}" }); } diff --git a/src/NzbDrone.Core/Applications/Lidarr/Lidarr.cs b/src/NzbDrone.Core/Applications/Lidarr/Lidarr.cs index 7856d0e00..f33cb700a 100644 --- a/src/NzbDrone.Core/Applications/Lidarr/Lidarr.cs +++ b/src/NzbDrone.Core/Applications/Lidarr/Lidarr.cs @@ -95,6 +95,14 @@ namespace NzbDrone.Core.Applications.Lidarr var lidarrIndexer = BuildLidarrIndexer(indexer, indexer.Protocol); var remoteIndexer = _lidarrV1Proxy.AddIndexer(lidarrIndexer, Settings); + + if (remoteIndexer == null) + { + _logger.Debug("Failed to add {0} [{1}]", indexer.Name, indexer.Id); + + return; + } + _appIndexerMapService.Insert(new AppIndexerMap { AppId = Definition.Id, IndexerId = indexer.Id, RemoteIndexerId = remoteIndexer.Id }); } diff --git a/src/NzbDrone.Core/Applications/Mylar/Mylar.cs b/src/NzbDrone.Core/Applications/Mylar/Mylar.cs index 052a96ff1..247c752dd 100644 --- a/src/NzbDrone.Core/Applications/Mylar/Mylar.cs +++ b/src/NzbDrone.Core/Applications/Mylar/Mylar.cs @@ -78,6 +78,14 @@ namespace NzbDrone.Core.Applications.Mylar var mylarIndexer = BuildMylarIndexer(indexer, indexer.Protocol); var remoteIndexer = _mylarV3Proxy.AddIndexer(mylarIndexer, Settings); + + if (remoteIndexer == null) + { + _logger.Debug("Failed to add {0} [{1}]", indexer.Name, indexer.Id); + + return; + } + _appIndexerMapService.Insert(new AppIndexerMap { AppId = Definition.Id, IndexerId = indexer.Id, RemoteIndexerName = $"{remoteIndexer.Type},{remoteIndexer.Name}" }); } diff --git a/src/NzbDrone.Core/Applications/Radarr/Radarr.cs b/src/NzbDrone.Core/Applications/Radarr/Radarr.cs index ab4b7cdce..8b10a6db1 100644 --- a/src/NzbDrone.Core/Applications/Radarr/Radarr.cs +++ b/src/NzbDrone.Core/Applications/Radarr/Radarr.cs @@ -95,6 +95,14 @@ namespace NzbDrone.Core.Applications.Radarr var radarrIndexer = BuildRadarrIndexer(indexer, indexer.Protocol); var remoteIndexer = _radarrV3Proxy.AddIndexer(radarrIndexer, Settings); + + if (remoteIndexer == null) + { + _logger.Debug("Failed to add {0} [{1}]", indexer.Name, indexer.Id); + + return; + } + _appIndexerMapService.Insert(new AppIndexerMap { AppId = Definition.Id, IndexerId = indexer.Id, RemoteIndexerId = remoteIndexer.Id }); } diff --git a/src/NzbDrone.Core/Applications/Readarr/Readarr.cs b/src/NzbDrone.Core/Applications/Readarr/Readarr.cs index 5349324f8..81655bf03 100644 --- a/src/NzbDrone.Core/Applications/Readarr/Readarr.cs +++ b/src/NzbDrone.Core/Applications/Readarr/Readarr.cs @@ -96,6 +96,14 @@ namespace NzbDrone.Core.Applications.Readarr var readarrIndexer = BuildReadarrIndexer(indexer, indexer.Protocol); var remoteIndexer = _readarrV1Proxy.AddIndexer(readarrIndexer, Settings); + + if (remoteIndexer == null) + { + _logger.Debug("Failed to add {0} [{1}]", indexer.Name, indexer.Id); + + return; + } + _appIndexerMapService.Insert(new AppIndexerMap { AppId = Definition.Id, IndexerId = indexer.Id, RemoteIndexerId = remoteIndexer.Id }); } diff --git a/src/NzbDrone.Core/Applications/Sonarr/Sonarr.cs b/src/NzbDrone.Core/Applications/Sonarr/Sonarr.cs index c372f7a53..3b27b419d 100644 --- a/src/NzbDrone.Core/Applications/Sonarr/Sonarr.cs +++ b/src/NzbDrone.Core/Applications/Sonarr/Sonarr.cs @@ -96,6 +96,14 @@ namespace NzbDrone.Core.Applications.Sonarr var sonarrIndexer = BuildSonarrIndexer(indexer, indexer.Protocol); var remoteIndexer = _sonarrV3Proxy.AddIndexer(sonarrIndexer, Settings); + + if (remoteIndexer == null) + { + _logger.Debug("Failed to add {0} [{1}]", indexer.Name, indexer.Id); + + return; + } + _appIndexerMapService.Insert(new AppIndexerMap { AppId = Definition.Id, IndexerId = indexer.Id, RemoteIndexerId = remoteIndexer.Id }); } diff --git a/src/NzbDrone.Core/Applications/Whisparr/Whisparr.cs b/src/NzbDrone.Core/Applications/Whisparr/Whisparr.cs index 6d16318ed..cab60d72a 100644 --- a/src/NzbDrone.Core/Applications/Whisparr/Whisparr.cs +++ b/src/NzbDrone.Core/Applications/Whisparr/Whisparr.cs @@ -96,6 +96,14 @@ namespace NzbDrone.Core.Applications.Whisparr var whisparrIndexer = BuildWhisparrIndexer(indexer, indexer.Protocol); var remoteIndexer = _whisparrV3Proxy.AddIndexer(whisparrIndexer, Settings); + + if (remoteIndexer == null) + { + _logger.Debug("Failed to add {0} [{1}]", indexer.Name, indexer.Id); + + return; + } + _appIndexerMapService.Insert(new AppIndexerMap { AppId = Definition.Id, IndexerId = indexer.Id, RemoteIndexerId = remoteIndexer.Id }); } From 9539e4d48199eaf4d1f32720c822cd435ed1a91b Mon Sep 17 00:00:00 2001 From: Qstick Date: Fri, 2 Jun 2023 00:20:18 -0500 Subject: [PATCH 0025/1128] More mono cleanup --- src/NzbDrone.Common/Processes/ProcessProvider.cs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/NzbDrone.Common/Processes/ProcessProvider.cs b/src/NzbDrone.Common/Processes/ProcessProvider.cs index ab7d7abb4..5db0565e0 100644 --- a/src/NzbDrone.Common/Processes/ProcessProvider.cs +++ b/src/NzbDrone.Common/Processes/ProcessProvider.cs @@ -330,16 +330,7 @@ namespace NzbDrone.Common.Processes private List GetProcessesByName(string name) { - //TODO: move this to an OS specific class - var monoProcesses = Process.GetProcessesByName("mono") - .Union(Process.GetProcessesByName("mono-sgen")) - .Where(process => - process.Modules.Cast() - .Any(module => - module.ModuleName.ToLower() == name.ToLower() + ".exe")); - - var processes = Process.GetProcessesByName(name) - .Union(monoProcesses).ToList(); + var processes = Process.GetProcessesByName(name).ToList(); _logger.Debug("Found {0} processes with the name: {1}", processes.Count, name); From f14ccebf3a2a43f04f8bf6396d5bdaaf5af675da Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 2 Jun 2023 15:16:56 +0300 Subject: [PATCH 0026/1128] Update magnet trackers --- .../Indexers/MagnetLinkBuilder.cs | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/MagnetLinkBuilder.cs b/src/NzbDrone.Core/Indexers/MagnetLinkBuilder.cs index b56041150..33b516d96 100644 --- a/src/NzbDrone.Core/Indexers/MagnetLinkBuilder.cs +++ b/src/NzbDrone.Core/Indexers/MagnetLinkBuilder.cs @@ -11,24 +11,25 @@ namespace NzbDrone.Core.Indexers private static readonly List Trackers = new () { "udp://tracker.opentrackr.org:1337/announce", + "udp://opentracker.i2p.rocks:6969/announce", "udp://tracker.openbittorrent.com:6969/announce", "http://tracker.openbittorrent.com:80/announce", - "udp://opentracker.i2p.rocks:6969/announce", - "https://opentracker.i2p.rocks:443/announce", - "udp://www.peckservers.com:9000/announce", - "udp://tracker.torrent.eu.org:451/announce", - "udp://tracker.tiny-vps.com:6969/announce", - "udp://tracker.moeking.me:6969/announce", - "udp://tracker.dler.org:6969/announce", - "udp://tracker.altrosky.nl:6969/announce", - "udp://p4p.arenabg.com:1337/announce", - "udp://open.stealth.si:80/announce", "udp://open.demonii.com:1337/announce", - "udp://ipv4.tracker.harry.lu:80/announce", - "udp://explodie.org:6969/announce", + "udp://open.stealth.si:80/announce", "udp://exodus.desync.com:6969/announce", - "udp://bt1.archive.org:6969/announce", - "https://tracker.lilithraws.org:443/announce" + "udp://tracker.torrent.eu.org:451/announce", + "udp://tracker.moeking.me:6969/announce", + "udp://tracker.bitsearch.to:1337/announce", + "udp://p4p.arenabg.com:1337/announce", + "udp://movies.zsw.ca:6969/announce", + "udp://explodie.org:6969/announce", + "https://tracker.tamersunion.org:443/announce", + "https://tr.burnabyhighstar.com:443/announce", + "udp://uploads.gamecoast.net:6969/announce", + "udp://tracker1.bt.moack.co.kr:80/announce", + "udp://tracker.tiny-vps.com:6969/announce", + "udp://tracker.theoks.net:6969/announce", + "udp://tracker.joybomb.tw:6969/announce" }; public static string BuildPublicMagnetLink(string infoHash, string releaseTitle) From 73f23d56dc7f50a0add7faaad19390a25a2ab959 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 2 Jun 2023 18:24:14 +0300 Subject: [PATCH 0027/1128] Use HelpText for non-URL values --- src/NzbDrone.Core/Indexers/Definitions/PornoLab.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/PornoLab.cs b/src/NzbDrone.Core/Indexers/Definitions/PornoLab.cs index 9787007e8..ea9188fe3 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/PornoLab.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/PornoLab.cs @@ -410,7 +410,7 @@ namespace NzbDrone.Core.Indexers.Definitions StripRussianLetters = false; } - [FieldDefinition(4, Label = "Strip Russian Letters", HelpLink = "Strip Cyrillic letters from release names", Type = FieldType.Checkbox)] + [FieldDefinition(4, Label = "Strip Russian Letters", HelpText = "Strip Cyrillic letters from release names", Type = FieldType.Checkbox)] public bool StripRussianLetters { get; set; } } } From ea635e685b80d372856c056e48fb5faf7c4f6565 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 3 Jun 2023 04:33:04 +0300 Subject: [PATCH 0028/1128] Fix duplicate indexers with same name in add modal --- frontend/src/Indexer/Add/AddIndexerModalContent.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/Indexer/Add/AddIndexerModalContent.js b/frontend/src/Indexer/Add/AddIndexerModalContent.js index f334af39e..e5db3a937 100644 --- a/frontend/src/Indexer/Add/AddIndexerModalContent.js +++ b/frontend/src/Indexer/Add/AddIndexerModalContent.js @@ -226,7 +226,7 @@ class AddIndexerModalContent extends Component { { filteredIndexers.map((indexer) => ( Date: Sun, 4 Jun 2023 15:43:52 -0500 Subject: [PATCH 0029/1128] Bump version to 1.6.0 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 35128db74..5e6790a2e 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.5.2' + majorVersion: '1.6.0' minorVersion: $[counter('minorVersion', 1)] prowlarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(prowlarrVersion)' From 87fdf17926e5b4f1552542d8b14b19a420c15c43 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 4 Jun 2023 00:37:17 +0300 Subject: [PATCH 0030/1128] Add HelpTextWarning support in FieldDefinition --- .../Components/Form/ProviderFieldFormGroup.js | 3 ++ .../Annotations/FieldDefinitionAttribute.cs | 1 + .../ClientSchemaTests/SchemaBuilderFixture.cs | 36 ++++++++++++++++--- src/Prowlarr.Http/ClientSchema/Field.cs | 1 + .../ClientSchema/SchemaBuilder.cs | 1 + 5 files changed, 38 insertions(+), 4 deletions(-) diff --git a/frontend/src/Components/Form/ProviderFieldFormGroup.js b/frontend/src/Components/Form/ProviderFieldFormGroup.js index 2b32e0e38..878e3a7ce 100644 --- a/frontend/src/Components/Form/ProviderFieldFormGroup.js +++ b/frontend/src/Components/Form/ProviderFieldFormGroup.js @@ -67,6 +67,7 @@ function ProviderFieldFormGroup(props) { name, label, helpText, + helpTextWarning, helpLink, placeholder, value, @@ -100,6 +101,7 @@ function ProviderFieldFormGroup(props) { name={name} label={label} helpText={helpText} + helpTextWarning={helpTextWarning} helpLink={helpLink} placeholder={placeholder} value={value} @@ -126,6 +128,7 @@ ProviderFieldFormGroup.propTypes = { name: PropTypes.string.isRequired, label: PropTypes.string, helpText: PropTypes.string, + helpTextWarning: PropTypes.string, helpLink: PropTypes.string, placeholder: PropTypes.string, value: PropTypes.any, diff --git a/src/NzbDrone.Core/Annotations/FieldDefinitionAttribute.cs b/src/NzbDrone.Core/Annotations/FieldDefinitionAttribute.cs index bb56e1a02..d35409c0b 100644 --- a/src/NzbDrone.Core/Annotations/FieldDefinitionAttribute.cs +++ b/src/NzbDrone.Core/Annotations/FieldDefinitionAttribute.cs @@ -15,6 +15,7 @@ namespace NzbDrone.Core.Annotations public string Label { get; set; } public string Unit { get; set; } public string HelpText { get; set; } + public string HelpTextWarning { get; set; } public string HelpLink { get; set; } public FieldType Type { get; set; } public bool Advanced { get; set; } diff --git a/src/Prowlarr.Api.V1.Test/ClientSchemaTests/SchemaBuilderFixture.cs b/src/Prowlarr.Api.V1.Test/ClientSchemaTests/SchemaBuilderFixture.cs index 049deb3df..16b54921f 100644 --- a/src/Prowlarr.Api.V1.Test/ClientSchemaTests/SchemaBuilderFixture.cs +++ b/src/Prowlarr.Api.V1.Test/ClientSchemaTests/SchemaBuilderFixture.cs @@ -27,19 +27,47 @@ namespace NzbDrone.Api.Test.ClientSchemaTests var schema = SchemaBuilder.ToSchema(model); - schema.Should().Contain(c => c.Order == 1 && c.Name == "lastName" && c.Label == "Last Name" && c.HelpText == "Your Last Name" && (string)c.Value == "Poop"); - schema.Should().Contain(c => c.Order == 0 && c.Name == "firstName" && c.Label == "First Name" && c.HelpText == "Your First Name" && (string)c.Value == "Bob"); + schema.Should().Contain(c => c.Order == 1 && c.Name == "lastName" && c.Label == "Last Name" && c.HelpText == "Your Last Name" && c.HelpTextWarning == "Mandatory Last Name" && (string)c.Value == "Poop"); + schema.Should().Contain(c => c.Order == 0 && c.Name == "firstName" && c.Label == "First Name" && c.HelpText == "Your First Name" && c.HelpTextWarning == "Mandatory First Name" && (string)c.Value == "Bob"); + } + + [Test] + public void schema_should_have_nested_fields() + { + var model = new NestedTestModel + { + Name = + { + FirstName = "Bob", + LastName = "Poop" + } + }; + + var schema = SchemaBuilder.ToSchema(model); + + schema.Should().Contain(c => c.Order == 0 && c.Name == "name.firstName" && c.Label == "First Name" && c.HelpText == "Your First Name" && c.HelpTextWarning == "Mandatory First Name" && (string)c.Value == "Bob"); + schema.Should().Contain(c => c.Order == 1 && c.Name == "name.lastName" && c.Label == "Last Name" && c.HelpText == "Your Last Name" && c.HelpTextWarning == "Mandatory Last Name" && (string)c.Value == "Poop"); + schema.Should().Contain(c => c.Order == 2 && c.Name == "quote" && c.Label == "Quote" && c.HelpText == "Your Favorite Quote"); } } public class TestModel { - [FieldDefinition(0, Label = "First Name", HelpText = "Your First Name")] + [FieldDefinition(0, Label = "First Name", HelpText = "Your First Name", HelpTextWarning = "Mandatory First Name")] public string FirstName { get; set; } - [FieldDefinition(1, Label = "Last Name", HelpText = "Your Last Name")] + [FieldDefinition(1, Label = "Last Name", HelpText = "Your Last Name", HelpTextWarning = "Mandatory Last Name")] public string LastName { get; set; } public string Other { get; set; } } + + public class NestedTestModel + { + [FieldDefinition(0)] + public TestModel Name { get; set; } = new TestModel(); + + [FieldDefinition(1, Label = "Quote", HelpText = "Your Favorite Quote")] + public string Quote { get; set; } + } } diff --git a/src/Prowlarr.Http/ClientSchema/Field.cs b/src/Prowlarr.Http/ClientSchema/Field.cs index 1e6f58ff4..0ef510ca6 100644 --- a/src/Prowlarr.Http/ClientSchema/Field.cs +++ b/src/Prowlarr.Http/ClientSchema/Field.cs @@ -10,6 +10,7 @@ namespace Prowlarr.Http.ClientSchema public string Label { get; set; } public string Unit { get; set; } public string HelpText { get; set; } + public string HelpTextWarning { get; set; } public string HelpLink { get; set; } public object Value { get; set; } public string Type { get; set; } diff --git a/src/Prowlarr.Http/ClientSchema/SchemaBuilder.cs b/src/Prowlarr.Http/ClientSchema/SchemaBuilder.cs index 3f36760af..424ea27bc 100644 --- a/src/Prowlarr.Http/ClientSchema/SchemaBuilder.cs +++ b/src/Prowlarr.Http/ClientSchema/SchemaBuilder.cs @@ -99,6 +99,7 @@ namespace Prowlarr.Http.ClientSchema Label = fieldAttribute.Label, Unit = fieldAttribute.Unit, HelpText = fieldAttribute.HelpText, + HelpTextWarning = fieldAttribute.HelpTextWarning, HelpLink = fieldAttribute.HelpLink, Order = fieldAttribute.Order, Advanced = fieldAttribute.Advanced, From b0c2b9119bf67ec2b750fd473f49c0cfaf92ee37 Mon Sep 17 00:00:00 2001 From: Servarr Date: Sun, 4 Jun 2023 21:02:02 +0000 Subject: [PATCH 0031/1128] Automated API Docs update --- src/Prowlarr.Api.V1/openapi.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Prowlarr.Api.V1/openapi.json b/src/Prowlarr.Api.V1/openapi.json index f7034eec1..3123f761c 100644 --- a/src/Prowlarr.Api.V1/openapi.json +++ b/src/Prowlarr.Api.V1/openapi.json @@ -5099,6 +5099,10 @@ "type": "string", "nullable": true }, + "helpTextWarning": { + "type": "string", + "nullable": true + }, "helpLink": { "type": "string", "nullable": true From 8c0bc9ab4e51b1501ee7ae731992ace0fa23715d Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 5 Jun 2023 02:22:05 +0300 Subject: [PATCH 0032/1128] Filter enabled indexer proxies in Active --- .../IndexerProxies/IndexerProxyFactory.cs | 6 ++++++ src/NzbDrone.Core/Indexers/IndexerHttpClient.cs | 13 ++----------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/NzbDrone.Core/IndexerProxies/IndexerProxyFactory.cs b/src/NzbDrone.Core/IndexerProxies/IndexerProxyFactory.cs index e62c58dab..a103d676d 100644 --- a/src/NzbDrone.Core/IndexerProxies/IndexerProxyFactory.cs +++ b/src/NzbDrone.Core/IndexerProxies/IndexerProxyFactory.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using NLog; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.ThingiProvider; @@ -16,5 +17,10 @@ namespace NzbDrone.Core.IndexerProxies : base(providerRepository, providers, container, eventAggregator, logger) { } + + protected override List Active() + { + return All().Where(c => c.Enable && c.Settings.Validate().IsValid).ToList(); + } } } diff --git a/src/NzbDrone.Core/Indexers/IndexerHttpClient.cs b/src/NzbDrone.Core/Indexers/IndexerHttpClient.cs index 1d351ad92..bca05fc51 100644 --- a/src/NzbDrone.Core/Indexers/IndexerHttpClient.cs +++ b/src/NzbDrone.Core/Indexers/IndexerHttpClient.cs @@ -52,23 +52,14 @@ namespace NzbDrone.Core.Indexers private IIndexerProxy GetProxy(ProviderDefinition definition) { - //Skip DB call if no tags on the indexers + // Skip DB call if no tags on the indexers if (definition.Tags.Count == 0 && definition.Id > 0) { return null; } var proxies = _indexerProxyFactory.GetAvailableProviders(); - IIndexerProxy selectedProxy = null; - - foreach (var proxy in proxies) - { - if (definition.Tags.Intersect(proxy.Definition.Tags).Any()) - { - selectedProxy = proxy; - break; - } - } + var selectedProxy = proxies.FirstOrDefault(proxy => definition.Tags.Intersect(proxy.Definition.Tags).Any()); if (selectedProxy == null && definition.Id == 0) { From 76a2f515333fca50a3aca2d3751972b3430da528 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 5 Jun 2023 02:22:49 +0300 Subject: [PATCH 0033/1128] Fixed: (HDTorrents) Add login error message --- src/NzbDrone.Core/Indexers/Definitions/HDTorrents.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/NzbDrone.Core/Indexers/Definitions/HDTorrents.cs b/src/NzbDrone.Core/Indexers/Definitions/HDTorrents.cs index ba3f1859d..398f5af58 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/HDTorrents.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/HDTorrents.cs @@ -8,8 +8,10 @@ using System.Text.RegularExpressions; using System.Threading.Tasks; using AngleSharp.Html.Parser; using NLog; +using NzbDrone.Common.Extensions; using NzbDrone.Common.Http; using NzbDrone.Core.Configuration; +using NzbDrone.Core.Indexers.Exceptions; using NzbDrone.Core.Indexers.Settings; using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.Messaging.Events; @@ -70,6 +72,16 @@ namespace NzbDrone.Core.Indexers.Definitions var response = await ExecuteAuth(authLoginRequest); + if (response.Content != null && !response.Content.ContainsIgnoreCase("If your browser doesn't have javascript enabled")) + { + var parser = new HtmlParser(); + var dom = parser.ParseDocument(response.Content); + + var errorMessage = dom.QuerySelector("div > font[color=\"#FF0000\"]")?.TextContent.Trim(); + + throw new IndexerAuthException(errorMessage ?? "Couldn't login"); + } + UpdateCookies(response.GetCookies(), DateTime.Now.AddDays(30)); _logger.Debug("Authentication succeeded"); From 1f1a345d25c10a4da020552a71c3e5bc5c794d09 Mon Sep 17 00:00:00 2001 From: Weblate Date: Sun, 4 Jun 2023 20:43:56 +0000 Subject: [PATCH 0034/1128] Translations update from Servarr Weblate Co-authored-by: MoowGlax Co-authored-by: Thodoris Kalatzis Co-authored-by: Weblate Co-authored-by: emacsdias Co-authored-by: reloxx Co-authored-by: splifter Co-authored-by: victor22265 <843427709@qq.com> Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/de/ Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/el/ Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fr/ Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt/ Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_CN/ Translation: Servarr/Prowlarr --- src/NzbDrone.Core/Localization/Core/de.json | 937 +++++++-------- src/NzbDrone.Core/Localization/Core/el.json | 3 +- src/NzbDrone.Core/Localization/Core/fr.json | 6 +- src/NzbDrone.Core/Localization/Core/pt.json | 5 +- .../Localization/Core/zh_CN.json | 1009 +++++++++-------- 5 files changed, 983 insertions(+), 977 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/de.json b/src/NzbDrone.Core/Localization/Core/de.json index eddec7e18..325bdfd75 100644 --- a/src/NzbDrone.Core/Localization/Core/de.json +++ b/src/NzbDrone.Core/Localization/Core/de.json @@ -1,469 +1,472 @@ { - "About": "Über", - "AcceptConfirmationModal": "Bestätigung akzeptieren Modal", - "Actions": "Aktionen", - "Add": "Hinzufügen", - "AddDownloadClient": "Zum Downloader hinzufügen", - "AddDownloadClientToProwlarr": "Durch das Hinzufügen eines Download-Clients kann Prowlarr während einer manuellen Suche Releases direkt über die Benutzeroberfläche senden.", - "AddIndexer": "Indexer hinzufügen", - "AddIndexerProxy": "Indexer Proxy hinzufügen", - "AddNewIndexer": "Neuen Indexer hinzufügen", - "AddRemoveOnly": "Nur hinzufügen und entfernen", - "AddSyncProfile": "Synchronisationsprofil hinzufügen", - "AddToDownloadClient": "Release zum Downloader hinzufügen", - "Added": "Hinzugefügt", - "AddedToDownloadClient": "Release zum Client hinzugefügt", - "AddingTag": "Tag hinzufügen", - "Age": "Alter", - "All": "Alle", - "AllIndexersHiddenDueToFilter": "Alle Indexer sind durch den ausgewählten Filter ausgeblendet.", - "Analytics": "Analytik", - "AnalyticsEnabledHelpText": "Sende anonyme Nutzungs- und Fehlerinformationen an die Server von Prowlarr. Dazu gehören Informationen über Browser, welche Seiten der Prowlarr-Weboberfläche aufgerufen wurden, Fehlerberichte sowie Betriebssystem- und Laufzeitversion. Wir werden diese Informationen verwenden, um Funktionen und Fehlerbehebungen zu priorisieren.", - "ApiKey": "API-Schlüssel", - "ApiKeyValidationHealthCheckMessage": "Bitte den API Schlüssel korrigieren, dieser muss mindestens {0} Zeichen lang sein. Die Änderung kann über die Einstellungen oder die Konfigurationsdatei erfolgen", - "AppDataDirectory": "AppData Ordner", - "AppDataLocationHealthCheckMessage": "Ein Update ist nicht möglich, um das Löschen von AppData beim Update zu verhindern", - "AppProfileDeleteConfirm": "Möchten Sie {0} wirklich löschen?", - "AppProfileInUse": "App-Profil im Einsatz", - "AppProfileSelectHelpText": "App-Profile werden verwendet, um die Einstellungen für RSS, automatische Suche und interaktive Suche bei der Anwendungssynchronisierung zu steuern", - "AppSettingsSummary": "Anwendungen und Einstellungen um zu konfigurieren, wie Prowlarr mit deinen PVR Programmen interagiert", - "Application": "Anwendungen", - "ApplicationLongTermStatusCheckAllClientMessage": "Alle Anwendungen sind nicht verfügbar, da es zu Störungen für mehr als 6 Stunden kam", - "ApplicationLongTermStatusCheckSingleClientMessage": "Anwendungen nicht verfügbar, da es zu Störungen für mehr als 6 Stunden kam: {0}", - "ApplicationStatusCheckAllClientMessage": "Wegen Fehlern sind keine Applikationen verfügbar", - "ApplicationStatusCheckSingleClientMessage": "Applikationen wegen folgender Fehler nicht verfügbar: {0}", - "Applications": "Anwendungen", - "Apply": "Anwenden", - "ApplyTags": "Tags setzen", - "ApplyTagsHelpTexts1": "Wie werden Tags zu ausgewählten Indexern zugeteilt", - "ApplyTagsHelpTexts2": "Hinzufügen: Füge neu Tags zu den existierenden Tags hinzu", - "ApplyTagsHelpTexts3": "Entfernen: Eingegebene Tags entfernen", - "ApplyTagsHelpTexts4": "Ersetzen: Nur eingegebene Tags übernehmen und vorhandene entfernen( keine Tags eingeben um alle zu entfernen )", - "Apps": "Anwendungen", - "AreYouSureYouWantToResetYourAPIKey": "Bist du sicher, dass du den API-Schlüssel zurücksetzen willst?", - "AudioSearch": "Audio Suche", - "Auth": "Authentifizierung", - "Authentication": "Authentifizierung", - "AuthenticationMethodHelpText": "Für den Zugriff auf Prowlarr sind Benutzername und Passwort erforderlich", - "Automatic": "Automatisch", - "AutomaticSearch": "Automatische Suche", - "Backup": "Backups", - "BackupFolderHelpText": "Relative Pfade befinden sich unter Prowlarrs AppData Ordner", - "BackupIntervalHelpText": "Intervall zum sichern der Datenbank und Einstellungen", - "BackupNow": "Jetzt sichern", - "BackupRetentionHelpText": "Automatische Backups, die älter als die Aufbewahrungsfrist sind, werden automatisch gelöscht", - "Backups": "Sicherungen", - "BeforeUpdate": "Vor dem Update", - "BindAddress": "Adresse binden", - "BindAddressHelpText": "Gültige IP Adresse oder \"*\" für alle Netzwerke", - "BookSearch": "Buch Suche", - "BookSearchTypes": "Buch-Suchtypen", - "Branch": "Git-Branch", - "BranchUpdate": "Verwendeter Branch zur Aktualisierung von Prowlarr", - "BranchUpdateMechanism": "Git-Branch für den externen Updateablauf", - "BypassProxyForLocalAddresses": "Proxy für lokale Adressen umgehen", - "Cancel": "Abbrechen", - "CancelPendingTask": "Diese laufende Aufgabe wirklich abbrechen?", - "Categories": "Kategorien", - "Category": "Kategorie", - "CertificateValidation": "Zertifikat Validierung", - "CertificateValidationHelpText": "Ändere wie streng die Validierung der HTTPS-Zertifizierung ist", - "ChangeHasNotBeenSavedYet": "Änderung wurde noch nicht gespeichert", - "Clear": "Leeren", - "ClearHistory": "Verlauf leeren", - "ClearHistoryMessageText": "Wirklich den ganzen Prowlarr Verlauf löschen?", - "ClientPriority": "Priorität", - "CloneProfile": "Profil kopieren", - "Close": "Schließen", - "CloseCurrentModal": "Momentanes Modal schließen", - "Columns": "Spalten", - "Component": "Komponente", - "Connect": "Benachrichtigungen", - "ConnectSettings": "Eintellungen für Verbindungen", - "ConnectSettingsSummary": "Benachrichtigungen und eigene Scripte", - "ConnectionLost": "Verbindung unterbrochen", - "ConnectionLostAutomaticMessage": "Prowlarr wird automatisch versuchen zu verbinden oder klicke unten auf neuladen.", - "ConnectionLostMessage": "Prowlarr hat die Verbindung zum Backend verloren und muss neugeladen werden.", - "Connections": "Verbindungen", - "CouldNotConnectSignalR": "Es konnte keine Verbindung zu SignalR hergestellt werden, die Benutzeroberfläche wird nicht aktualisiert", - "Custom": "Benutzerdefiniert", - "CustomFilters": "Filter anpassen", - "DBMigration": "DB Migration", - "Database": "Datenbank", - "Date": "Datum", - "Dates": "Termine", - "Delete": "Löschen", - "DeleteAppProfile": "App-Profil löschen", - "DeleteApplication": "Applikation löschen", - "DeleteApplicationMessageText": "Wirklich die Applikation '{0}' löschen?", - "DeleteBackup": "Backup löschen", - "DeleteBackupMessageText": "Backup '{0}' wirkich löschen?", - "DeleteDownloadClient": "Downloader löschen", - "DeleteDownloadClientMessageText": "Downloader '{0}' wirklich löschen?", - "DeleteIndexerProxy": "Indexer Proxy löschen", - "DeleteIndexerProxyMessageText": "Tag '{0}' wirklich löschen?", - "DeleteNotification": "Benachrichtigung löschen", - "DeleteNotificationMessageText": "Benachrichtigung '{0}' wirklich löschen?", - "DeleteTag": "Tag löschen", - "DeleteTagMessageText": "Tag '{0}' wirklich löschen?", - "Description": "Beschreibung", - "Details": "Details", - "DevelopmentSettings": "Entwicklungseinstellungen", - "Disabled": "Deaktiviert", - "Discord": "Discord", - "Docker": "Docker", - "Donations": "Spenden", - "DownloadClient": "Downloader", - "DownloadClientSettings": "Downloader Einstellungen", - "DownloadClientStatusCheckAllClientMessage": "Alle Download Clients sind aufgrund von Fehlern nicht verfügbar", - "DownloadClientStatusCheckSingleClientMessage": "Download Clients aufgrund von Fehlern nicht verfügbar: {0}", - "DownloadClients": "Downloader", - "DownloadClientsSettingsSummary": "Download der Client-Konfigurationen für die Integration in die Prowlarr UI-Suche", - "Duration": "Dauer", - "Edit": "Bearbeiten", - "EditIndexer": "Indexer bearbeiten", - "EditSyncProfile": "Synchronisationsprofil bearbeiten", - "ElapsedTime": "Vergangene Zeit", - "Enable": "Aktivieren", - "EnableAutomaticSearch": "Automatisch suchen", - "EnableAutomaticSearchHelpText": "Wird für automatische Suchen genutzt die vom Benutzer oder von Prowlarr gestartet werden", - "EnableIndexer": "Indexer aktivieren", - "EnableInteractiveSearch": "Interaktive Suche", - "EnableInteractiveSearchHelpText": "Wird bei der manuellen Suche benutzt", - "EnableRss": "RSS aktivieren", - "EnableRssHelpText": "RSS-Feed für Indexer aktivieren", - "EnableSSL": "SSL", - "EnableSslHelpText": " Erfordert einen Neustart als Administrator", - "Enabled": "Aktiviert", - "EnabledRedirected": "Aktiviert, Weitergeleitet", - "Encoding": "Codierung", - "Ended": "Beendet", - "Error": "Fehler", - "ErrorLoadingContents": "Fehler beim laden der Inhalte", - "EventType": "Event Typ", - "Events": "Events", - "Exception": "Ausnahme", - "ExistingTag": "Vorhandener Tag", - "Failed": "Fehlgeschlagen", - "FeatureRequests": "Funktionsanfragen", - "Filename": "Dateiname", - "Files": "Dateien", - "Filter": "Filter", - "FilterPlaceHolder": "Filme suchen", - "Filters": "Filter", - "Fixed": "Behoben", - "FocusSearchBox": "Suchbox fokussieren", - "Folder": "Ordner", - "ForMoreInformationOnTheIndividualDownloadClients": "Für mehr Infomationen klicke auf die Info-Knöpfe.", - "FullSync": "Vollständige Synchronisierung", - "General": "Allgemein", - "GeneralSettings": "Allgemeine Einstellungen", - "GeneralSettingsSummary": "Port, SSL, Benutzername/Passwort, Proxy, Analytik und Updates", - "GrabReleases": "Release erfassen", - "GrabTitle": "Titel holen", - "Grabbed": "Erfasste", - "Grabs": "Erfasse", - "Health": "Zustandsüberwachung", - "HealthNoIssues": "Keine Probleme mit deiner Konfiguration", - "HiddenClickToShow": "Versteckt, klicken zum anzeigen", - "HideAdvanced": "Erweiterte Ansicht", - "History": "Verlauf", - "HistoryCleanup": "Verlaufsbereinigung", - "HistoryCleanupDaysHelpText": "Auf 0 setzen um das automatische leeren des Papierkorbs zu deaktivieren", - "HistoryCleanupDaysHelpTextWarning": "Datien im Papierkorb die älter sind als der gewählte Wert, werden endgültig gelöscht", - "HomePage": "Startseite", - "Host": "Host", - "Hostname": "Hostname", - "Id": "Id", - "IgnoredAddresses": "Ignorierte Adressen", - "IllRestartLater": "Später neustarten", - "IncludeHealthWarningsHelpText": "Zustandswarnung", - "Indexer": "Indexer", - "IndexerAlreadySetup": "Mindestens eine Indexer Instanz ist bereits eingerichtet", - "IndexerAuth": "Indexer Authentifizierung", - "IndexerDetails": "Indexer-Details", - "IndexerFlags": "Indexer-Flags", - "IndexerHealthCheckNoIndexers": "Keine Indexer aktiviert, Prowlarr wird keine Suchergebnisse zurückgeben", - "IndexerInfo": "Indexer-Info", - "IndexerLongTermStatusCheckAllClientMessage": "Alle Indexer sind wegen über 6 Stunden langen bestehender Fehler nicht verfügbar", - "IndexerLongTermStatusCheckSingleClientMessage": "Indexer wegen über 6 Stunden langen bestehenden Fehlern nicht verfügbar: {0}", - "IndexerName": "Indexer-Name", - "IndexerNoDefCheckMessage": "Indexer haben keine Definition und werden nicht funktionieren: {0}. Bitte entferne und (oder) füge diese neu zu Prowlarr hinzu", - "IndexerObsoleteCheckMessage": "Indexer sind nicht mehr verfügbar oder wurden aktualiiert: {0}. Bitte enfernen und (oder) neu zu Prowlarr hinzufügen", - "IndexerPriority": "Priorität", - "IndexerPriorityHelpText": "Indexer Priorität von 1 (höchste) bis 50 (niedrigste). Standard: 25.", - "IndexerProxies": "Indexer-Proxies", - "IndexerProxy": "Indexer-Proxy", - "IndexerProxyStatusCheckAllClientMessage": "Alle Indexer sind aufgrund von Fehlern nicht verfügbar", - "IndexerProxyStatusCheckSingleClientMessage": "Listen aufgrund von Fehlern nicht verfügbar: {0}", - "IndexerQuery": "Indexer Anfrage", - "IndexerRss": "Indexer RSS", - "IndexerSettingsSummary": "Konfiguration verschiedener globaler Indexer Einstellungen, einschließlich Proxies.", - "IndexerSite": "Indexer-Seite", - "IndexerStatusCheckAllClientMessage": "Alle Indexer sind aufgrund von Fehlern nicht verfügbar", - "IndexerStatusCheckSingleClientMessage": "Indexer aufgrund von Fehlern nicht verfügbar: {0}", - "IndexerTagsHelpText": "Benutze Tags, um Indexer-Proxies zu spezifizieren, mit welchen Apps der Indexer synchronisiert oder um Indexer zu organisieren.", - "IndexerVipCheckExpiredClientMessage": "Die VIP Indexer Vorteile sind abgelaufen: {0}", - "IndexerVipCheckExpiringClientMessage": "Die Indexer VIP Vorteile verfallen bald: {0}", - "Indexers": "Indexer", - "IndexersSelectedInterp": "{0} Indexer ausgewählt", - "Info": "Info", - "InstanceName": "Instanzname", - "InstanceNameHelpText": "Instanzname im Browser-Tab und für Syslog-Anwendungsname", - "InteractiveSearch": "Interaktive Suche", - "Interval": "Intervall", - "KeyboardShortcuts": "Tastenkürzel", - "Language": "Sprache", - "LastDuration": "Letzte Dauer", - "LastExecution": "Letzte Ausführung", - "LastWriteTime": "Zuletzt beschrieben", - "LaunchBrowserHelpText": " Öffne die Startseite von Prowlarr im Webbrowser nach dem Start.", - "Level": "Stufe", - "Link": "Links", - "LogFiles": "Protokolle", - "LogLevel": "Log Level", - "LogLevelTraceHelpTextWarning": "Trace logging sollte nur kurzzeitig aktiviert werden", - "Logging": "Protokollierung", - "Logs": "Protokolle", - "MIA": "MIA", - "MaintenanceRelease": "Wartung: Fehlerbehebung und andere Verbesserungen. Siehe Github Commit History für weitere Details", - "Manual": "Manuell", - "MappedDrivesRunningAsService": "Zugeordnete Netzlaufwerke sind nicht verfügbar, wenn Prowlarr als Windows-Dienst ausgeführt wird. Bitte lesen Sie die FAQ für weitere Informationen", - "MassEditor": "Masseneditor", - "Mechanism": "Verfahren", - "Message": "Nachricht", - "MinimumSeeders": "Mindest-Seeder", - "MinimumSeedersHelpText": "Minimale Anzahl an Seedern die von der Anwendung benötigt werden um den Indexer zu holen", - "Mode": "Modus", - "MoreInfo": "Mehr Infos", - "MovieIndexScrollBottom": "Filmindex: Nach unten scrollen", - "MovieIndexScrollTop": "Filmindex: Nach oben scrollen", - "MovieSearch": "Film Suche", - "MovieSearchTypes": "Film-Suchtypen", - "MusicSearchTypes": "Musik-Suchtypen", - "Name": "Name", - "NetCore": ".NET Core", - "New": "Neu", - "NextExecution": "Nächste Ausführung", - "No": "Nein", - "NoBackupsAreAvailable": "Es sind keine Backups vorhanden", - "NoChange": "Keine Änderung", - "NoChanges": "Keine Änderungen", - "NoLeaveIt": "Nein, nicht ändern", - "NoLinks": "Keine Links", - "NoLogFiles": "Keine Log-Dateien", - "NoSearchResultsFound": "Keine Suchergebnisse gefunden. Versuchen Sie unten eine erneute Suche durchzuführen.", - "NoTagsHaveBeenAddedYet": "Es wurden noch keine Tags erstellt", - "NoUpdatesAreAvailable": "Es sind keine Updates verfügbar", - "NotSupported": "Nicht unterstützt", - "Notification": "Benachrichtigungen", - "NotificationTriggers": "Benachrichtigungs Auslöser", - "NotificationTriggersHelpText": "Auslöser für diese Benachrichtigung auswählen", - "Notifications": "Benachrichtigungen", - "OAuthPopupMessage": "Dein Browser blockiert Pop-ups", - "Ok": "OK", - "OnApplicationUpdate": "Bei Anwendungsaktualisierung", - "OnApplicationUpdateHelpText": "Bei Anwendungsaktualisierung", - "OnGrab": "Bei Erfassung", - "OnHealthIssue": "Bei Zustandsproblem", - "OnHealthIssueHelpText": "Zustandsproblem", - "OpenBrowserOnStart": "Browser beim Start öffnen", - "OpenThisModal": "Dieses Modal öffnen", - "Options": "Optionen", - "PackageVersion": "Paket Version", - "PageSize": "Einträge pro Seite", - "PageSizeHelpText": "Anzahl der Einträge pro Seite", - "Parameters": "Parameter", - "Password": "Passwort", - "Peers": "Peers", - "PendingChangesDiscardChanges": "Änderungen verwerfen und schließen", - "PendingChangesMessage": "Es gibt noch ungespeicherte Änderungen, bist du sicher, dass du die Seite verlassen möchtest?", - "PendingChangesStayReview": "Auf der Seite bleiben", - "Port": "Port", - "PortNumber": "Port Nummer", - "Presets": "Voreinstellungen", - "Priority": "Priorität", - "PriorityHelpText": "Priorisiere mehrere Downloader. Rundlauf-Verfahren wird für Downloader mit der gleichen Priorität verwendet.", - "PrioritySettings": "Priorität", - "Privacy": "Privatsphäre", - "Private": "Privat", - "Protocol": "Protokoll", - "ProwlarrSupportsAnyDownloadClient": "Jeder Downloader der den Newznab-Standard verwendet oder unten aufgelistet ist wird untertützt.", - "ProwlarrSupportsAnyIndexer": "Prowlarr unterstützt alle Indexer, welcher den Newznab/Torznab Standard implementiert (verwende 'Generic Newznab' (für Usenet) oder 'Generic Torznab' (für Torrents)) und darüber hinaus viele weitere Indexer. Wählen Sie im Folgenden Ihren Indexer aus der Liste.", - "Proxies": "Proxies", - "Proxy": "Proxy", - "ProxyBypassFilterHelpText": "Verwende ',' als Trennzeichen und '*.' als Platzhalter für Subdomains", - "ProxyCheckBadRequestMessage": "Proxy konnte nicht getestet werden. StatusCode: {0}", - "ProxyCheckFailedToTestMessage": "Proxy konnte nicht getestet werden: {0}", - "ProxyCheckResolveIpMessage": "Fehler beim Auflösen der IP-Adresse für den konfigurierten Proxy-Host {0}", - "ProxyPasswordHelpText": "Nur wenn ein Benutzername und Passwort erforderlich ist, muss es eingegeben werden. Ansonsten leer lassen.", - "ProxyType": "Proxy Typ", - "ProxyUsernameHelpText": "Nur wenn ein Benutzername und Passwort erforderlich ist, muss es eingegeben werden. Ansonsten leer lassen.", - "Public": "Öffentlich", - "Query": "Abfrage", - "QueryOptions": "Abfrage-Optionen", - "QueryResults": "Abfrageergebnisse", - "Queue": "Warteschlange", - "Queued": "In der Warteschlange", - "RSS": "RSS", - "RSSIsNotSupportedWithThisIndexer": "RSS wird von diesem Indexer nicht unterstützt", - "RawSearchSupported": "Raw-Suche unterstützt", - "ReadTheWikiForMoreInformation": "Lese das Wiki für mehr Informationen", - "Reddit": "Reddit", - "Redirect": "Umleiten", - "RedirectHelpText": "Eingehende Download-Anfragen für den Indexer umleiten, anstatt Proxying mit Prowlarr", - "Refresh": "Aktualisieren", - "RefreshMovie": "Film aktualisieren", - "ReleaseBranchCheckOfficialBranchMessage": "Zweig {0} ist kein gültiger Prowlarr-Release-Zweig. Sie erhalten keine Updates", - "ReleaseStatus": "Releasestatus", - "Reload": "Neuladen", - "Remove": "Entfernen", - "RemoveFilter": "Filter entfernen", - "RemovedFromTaskQueue": "Aus der Aufgabenwarteschlage entfernt", - "RemovingTag": "Tag entfernen", - "Replace": "Ersetzen", - "Reset": "Zurücksetzen", - "ResetAPIKey": "API-Schlüssel zurücksetzen", - "Restart": "Neustarten", - "RestartNow": "Jetzt neustarten", - "RestartProwlarr": "Prowlarr Neustarten", - "RestartRequiredHelpTextWarning": "Erfordert einen Neustart", - "Restore": "Wiederherstellen", - "RestoreBackup": "Backup einspielen", - "Result": "Ergebnis", - "Retention": "Aufbewahrung ( Retention )", - "SSLCertPassword": "SSL Zertifikat Passwort", - "SSLCertPasswordHelpText": "Passwort für die PFX Datei", - "SSLCertPath": "Pfad zum SSL Zertifikat", - "SSLCertPathHelpText": "Pfad zur PFX Datei", - "SSLPort": "SSL Port", - "Save": "Speichern", - "SaveChanges": "Änderungen speichern", - "SaveSettings": "Einstellungen speichern", - "Scheduled": "Geplant", - "ScriptPath": "Script Pfad", - "Search": "Suche", - "SearchCapabilities": "Suchfähigkeiten", - "SearchIndexers": "Indexer suchen", - "SearchType": "Suchtyp", - "SearchTypes": "Suchtyp", - "Security": "Sicherheit", - "Seeders": "Seeders", - "SelectAll": "Alle wählen", - "SemiPrivate": "Halbprivat", - "SendAnonymousUsageData": "Anonyme Nutzungsdaten übertragen", - "SetTags": "Tags setzen", - "Settings": "Einstellungen", - "SettingsConsoleLogLevel": "Konsolen Log Level", - "SettingsEnableColorImpairedMode": "Farbbeeinträchtigter Modus aktivieren", - "SettingsEnableColorImpairedModeHelpText": "Alternativer Stil, um farbbeeinträchtigten Benutzern eine bessere Unterscheidung farbcodierter Informationen zu ermöglichen", - "SettingsFilterSentryEvents": "Analystische Ergeinisse filtern", - "SettingsFilterSentryEventsHelpText": "Sende keine bekannten Benutzerfehler Ereignisse an Analystics", - "SettingsIndexerLogging": "Verbesserte Indexer-Protokollierung", - "SettingsIndexerLoggingHelpText": "Erweiterte Indexerdaten loggen inklusive Antwort", - "SettingsLogRotate": "Logrotation", - "SettingsLogRotateHelpText": "Max. Anzahl der zu behaltenden Logdateien", - "SettingsLogSql": "Log SQL", - "SettingsLongDateFormat": "Langes Datumsformat", - "SettingsShortDateFormat": "Kurzes Datumsformat", - "SettingsShowRelativeDates": "Relatives Datum anzeigen", - "SettingsShowRelativeDatesHelpText": "Relatives (z.B.: Heute, gestern, etc) oder absolutes Datum anzeigen", - "SettingsSqlLoggingHelpText": "Log alle SQL Abfragen von Prowlarr", - "SettingsTimeFormat": "Zeitformat", - "ShowAdvanced": "Einfache Ansicht", - "ShowSearch": "Suche anzeigen", - "ShowSearchHelpText": "Suchbutton anzeigen beim draufzeigen", - "ShownClickToHide": "Angezeigt, zum verstecken klicken", - "Shutdown": "Herunterfahren", - "Size": "Größe", - "Sort": "Sortieren", - "Source": "Quelle", - "StartTypingOrSelectAPathBelow": "Eingeben oder unten auswählen", - "Started": "gestartet", - "StartupDirectory": "Start-Verzeichnis", - "Stats": "Statistiken", - "Status": "Status", - "Style": "Stil", - "SuggestTranslationChange": "Schlage eine Übersetzung vor", - "SyncAppIndexers": "App Indexer syncen", - "SyncLevel": "Sync-Level", - "SyncLevelAddRemove": "Nur hinzufügen und entfernen: Wenn Indexer zu Prowlarr hinzugefügt oder entfernt werden, wird diese Remote-App aktualisiert.", - "SyncLevelFull": "Vollständige Synchronisierung: Hält die Indexer dieser App vollständig synchronisiert. Änderungen an Indexern in Prowlarr werden mit dieser App synchronisiert. Jede Änderung die and Indexern dieser App gemacht werden, wird von Prowlarr bei der nächsten Synchronisierung überschrieben.", - "SyncProfile": "Sync-Profile", - "SyncProfiles": "Sync-Profile", - "System": "System", - "SystemTimeCheckMessage": "Die Systemzeit ist um einen Tag versetzt. Bis die Zeit korrigiert wurde, könnten die geplanten Aufgaben nicht korrekt ausgeführt werden", - "TVSearchTypes": "Suchtyp", - "TableOptions": "Tabellen Optionen", - "TableOptionsColumnsMessage": "Wähle aus welche Spalten angezeigt werden und in welcher Reihenfolge", - "TagCannotBeDeletedWhileInUse": "Kann während der Benutzung nicht gelöscht werden", - "TagIsNotUsedAndCanBeDeleted": "Tag wird nicht benutzt und kann gelöscht werden", - "Tags": "Tags", - "TagsHelpText": "Wird auf Filme mit mindestens einem passenden Tag angewandt", - "TagsSettingsSummary": "Alle Tags und deren Benutzung anzeigen. Unbenutzte Tags können entfernt werden", - "Tasks": "Aufgaben", - "Test": "Testen", - "TestAll": "Alle testen", - "TestAllApps": "Alle Apps testen", - "TestAllClients": "Alle testen", - "TestAllIndexers": "Alle testen", - "TheLatestVersionIsAlreadyInstalled": "Die aktuellste Version ist bereits installiert", - "ThemeHelpText": "Ändere das UI-Theme der Anwendung. Das 'Auto'-Theme verwendet dein Betriebssystem-Theme, um den hellen oder dunklen Modus einzustellen. Inspiriert von {0}", - "Time": "Zeit", - "Title": "Titel", - "Today": "Heute", - "Tomorrow": "Morgen", - "Torrent": "Torrent", - "Torrents": "Torrents", - "TvSearch": "TV Suche", - "Type": "Typ", - "UI": "Oberfläche", - "UILanguage": "Oberflächen Sprache ( UI Language )", - "UILanguageHelpText": "Sprache für die gesamte Oberfläche", - "UILanguageHelpTextWarning": "Webseite muss neu geladen werden", - "UISettings": "Benutzeroberflächen Einstellungen", - "UISettingsSummary": "Optionen für Datum, Sprache und Farbbeinträchtigungen", - "URLBase": "URL-Basis", - "UnableToAddANewAppProfilePleaseTryAgain": "Es kann kein neues Anwendungsprofil hinzugefügt werden. Bitte versuchen Sie es erneut.", - "UnableToAddANewApplicationPleaseTryAgain": "Es kann keine neue Anwendung hinzugefügt werden. Bitte versuchen Sie es erneut.", - "UnableToAddANewDownloadClientPleaseTryAgain": "Der neue Downloader konnte nicht hinzugefügt werden, bitte erneut probieren.", - "UnableToAddANewIndexerPleaseTryAgain": "Der neue Indexer konnte nicht hinzugefügt werden, bitte erneut probieren.", - "UnableToAddANewIndexerProxyPleaseTryAgain": "Der neue Indexer konnte nicht hinzugefügt werden, bitte erneut probieren.", - "UnableToAddANewNotificationPleaseTryAgain": "Die neue Benachrichtigung konnte nicht hinzugefügt werden, bitte erneut probieren.", - "UnableToLoadAppProfiles": "App-Profile können nicht geladen werden", - "UnableToLoadApplicationList": "Anwendungsliste kann nicht geladen werden", - "UnableToLoadBackups": "Backups konnten nicht geladen werden", - "UnableToLoadDevelopmentSettings": "Entwicklereinstellungen konnten nicht geladen werden", - "UnableToLoadDownloadClients": "Downloader konnten nicht geladen werden", - "UnableToLoadGeneralSettings": "Allgemeine Einstellungen konnten nicht geladen werden", - "UnableToLoadHistory": "Verlauf konnte nicht geladen werden", - "UnableToLoadIndexerProxies": "Indexer-Proxies können nicht geladen werden", - "UnableToLoadIndexers": "Indexer konnten nicht geladen werden", - "UnableToLoadNotifications": "Benachrichtigungen konnten nicht geladen werden", - "UnableToLoadTags": "Tags konnten nicht geladen werden", - "UnableToLoadUISettings": "Oberflächen Einstellungen konnten nicht geladen werden", - "UnsavedChanges": "Ungespeicherte Änderungen", - "UnselectAll": "Keine wählen", - "UpdateAutomaticallyHelpText": "Updates automatisch herunteraden und installieren. Es kann weiterhin unter \"System -> Updates\" ein manuelles Update angestoßen werden", - "UpdateCheckStartupNotWritableMessage": "Update kann nicht installiert werden, da der Startordner '{0}' vom Benutzer '{1}' nicht beschreibbar ist.", - "UpdateCheckStartupTranslocationMessage": "Update kann nicht installiert werden, da sich der Startordner '{0}' in einem App Translocation-Ordner befindet.", - "UpdateCheckUINotWritableMessage": "Update kann nicht installiert werden, da der Benutzeroberflächenordner '{0}' vom Benutzer '{1}' nicht beschreibbar ist.", - "UpdateMechanismHelpText": "Benutze Prowlarr's Built-In Updater oder ein Script", - "UpdateScriptPathHelpText": "Pfad zu einem benutzerdefinierten Skript, das ein extrahiertes Update-Paket übernimmt und den Rest des Update-Prozesses abwickelt", - "Updates": "Updates", - "Uptime": "Laufzeit", - "Url": "Url", - "UrlBaseHelpText": "Für Reverse-Proxy-Unterstützung. Die Standardeinstellung leer", - "UseProxy": "Proxy benutzen", - "Usenet": "Usenet", - "UserAgentProvidedByTheAppThatCalledTheAPI": "UserAgent von der App welcher die API aufgerufen hat", - "Username": "Benutzername", - "Version": "Version", - "View": "Ansicht", - "Warn": "Warnung", - "Website": "Webseite", - "Wiki": "Wiki", - "Yes": "Ja", - "YesCancel": "Ja, abbrechen", - "Yesterday": "Gestern" + "About": "Über", + "AcceptConfirmationModal": "Bestätigung akzeptieren Modal", + "Actions": "Aktionen", + "Add": "Hinzufügen", + "AddDownloadClient": "Zum Downloader hinzufügen", + "AddDownloadClientToProwlarr": "Durch das Hinzufügen eines Download-Clients kann Prowlarr während einer manuellen Suche Releases direkt über die Benutzeroberfläche senden.", + "AddIndexer": "Indexer hinzufügen", + "AddIndexerProxy": "Indexer Proxy hinzufügen", + "AddNewIndexer": "Neuen Indexer hinzufügen", + "AddRemoveOnly": "Nur hinzufügen und entfernen", + "AddSyncProfile": "Synchronisationsprofil hinzufügen", + "AddToDownloadClient": "Release zum Downloader hinzufügen", + "Added": "Hinzugefügt", + "AddedToDownloadClient": "Release zum Client hinzugefügt", + "AddingTag": "Tag hinzufügen", + "Age": "Alter", + "All": "Alle", + "AllIndexersHiddenDueToFilter": "Alle Indexer sind durch den ausgewählten Filter ausgeblendet.", + "Analytics": "Analytik", + "AnalyticsEnabledHelpText": "Sende anonyme Nutzungs- und Fehlerinformationen an die Server von Prowlarr. Dazu gehören Informationen über Browser, welche Seiten der Prowlarr-Weboberfläche aufgerufen wurden, Fehlerberichte sowie Betriebssystem- und Laufzeitversion. Wir werden diese Informationen verwenden, um Funktionen und Fehlerbehebungen zu priorisieren.", + "ApiKey": "API-Schlüssel", + "ApiKeyValidationHealthCheckMessage": "Bitte den API Schlüssel korrigieren, dieser muss mindestens {0} Zeichen lang sein. Die Änderung kann über die Einstellungen oder die Konfigurationsdatei erfolgen", + "AppDataDirectory": "AppData Ordner", + "AppDataLocationHealthCheckMessage": "Ein Update ist nicht möglich, um das Löschen von AppData beim Update zu verhindern", + "AppProfileDeleteConfirm": "Möchten Sie {0} wirklich löschen?", + "AppProfileInUse": "App-Profil im Einsatz", + "AppProfileSelectHelpText": "App-Profile werden verwendet, um die Einstellungen für RSS, automatische Suche und interaktive Suche bei der Anwendungssynchronisierung zu steuern", + "AppSettingsSummary": "Anwendungen und Einstellungen um zu konfigurieren, wie Prowlarr mit deinen PVR Programmen interagiert", + "Application": "Anwendungen", + "ApplicationLongTermStatusCheckAllClientMessage": "Alle Anwendungen sind nicht verfügbar, da es zu Störungen für mehr als 6 Stunden kam", + "ApplicationLongTermStatusCheckSingleClientMessage": "Anwendungen nicht verfügbar, da es zu Störungen für mehr als 6 Stunden kam: {0}", + "ApplicationStatusCheckAllClientMessage": "Wegen Fehlern sind keine Applikationen verfügbar", + "ApplicationStatusCheckSingleClientMessage": "Applikationen wegen folgender Fehler nicht verfügbar: {0}", + "Applications": "Anwendungen", + "Apply": "Anwenden", + "ApplyTags": "Tags setzen", + "ApplyTagsHelpTexts1": "Wie werden Tags zu ausgewählten Indexern zugeteilt", + "ApplyTagsHelpTexts2": "Hinzufügen: Füge neu Tags zu den existierenden Tags hinzu", + "ApplyTagsHelpTexts3": "Entfernen: Eingegebene Tags entfernen", + "ApplyTagsHelpTexts4": "Ersetzen: Nur eingegebene Tags übernehmen und vorhandene entfernen( keine Tags eingeben um alle zu entfernen )", + "Apps": "Anwendungen", + "AreYouSureYouWantToResetYourAPIKey": "Bist du sicher, dass du den API-Schlüssel zurücksetzen willst?", + "AudioSearch": "Audio Suche", + "Auth": "Authentifizierung", + "Authentication": "Authentifizierung", + "AuthenticationMethodHelpText": "Für den Zugriff auf Prowlarr sind Benutzername und Passwort erforderlich", + "Automatic": "Automatisch", + "AutomaticSearch": "Automatische Suche", + "Backup": "Backups", + "BackupFolderHelpText": "Relative Pfade befinden sich unter Prowlarrs AppData Ordner", + "BackupIntervalHelpText": "Intervall zum sichern der Datenbank und Einstellungen", + "BackupNow": "Jetzt sichern", + "BackupRetentionHelpText": "Automatische Backups, die älter als die Aufbewahrungsfrist sind, werden automatisch gelöscht", + "Backups": "Sicherungen", + "BeforeUpdate": "Vor dem Update", + "BindAddress": "Adresse binden", + "BindAddressHelpText": "Gültige IP Adresse oder \"*\" für alle Netzwerke", + "BookSearch": "Buch Suche", + "BookSearchTypes": "Buch-Suchtypen", + "Branch": "Git-Branch", + "BranchUpdate": "Verwendeter Branch zur Aktualisierung von Prowlarr", + "BranchUpdateMechanism": "Git-Branch für den externen Updateablauf", + "BypassProxyForLocalAddresses": "Proxy für lokale Adressen umgehen", + "Cancel": "Abbrechen", + "CancelPendingTask": "Diese laufende Aufgabe wirklich abbrechen?", + "Categories": "Kategorien", + "Category": "Kategorie", + "CertificateValidation": "Zertifikat Validierung", + "CertificateValidationHelpText": "Ändere wie streng die Validierung der HTTPS-Zertifizierung ist", + "ChangeHasNotBeenSavedYet": "Änderung wurde noch nicht gespeichert", + "Clear": "Leeren", + "ClearHistory": "Verlauf leeren", + "ClearHistoryMessageText": "Wirklich den ganzen Prowlarr Verlauf löschen?", + "ClientPriority": "Priorität", + "CloneProfile": "Profil kopieren", + "Close": "Schließen", + "CloseCurrentModal": "Momentanes Modal schließen", + "Columns": "Spalten", + "Component": "Komponente", + "Connect": "Benachrichtigungen", + "ConnectSettings": "Eintellungen für Verbindungen", + "ConnectSettingsSummary": "Benachrichtigungen und eigene Scripte", + "ConnectionLost": "Verbindung unterbrochen", + "ConnectionLostAutomaticMessage": "Prowlarr wird automatisch versuchen zu verbinden oder klicke unten auf neuladen.", + "ConnectionLostMessage": "Prowlarr hat die Verbindung zum Backend verloren und muss neugeladen werden.", + "Connections": "Verbindungen", + "CouldNotConnectSignalR": "Es konnte keine Verbindung zu SignalR hergestellt werden, die Benutzeroberfläche wird nicht aktualisiert", + "Custom": "Benutzerdefiniert", + "CustomFilters": "Eigene Filter", + "DBMigration": "DB Migration", + "Database": "Datenbank", + "Date": "Datum", + "Dates": "Termine", + "Delete": "Löschen", + "DeleteAppProfile": "App-Profil löschen", + "DeleteApplication": "Applikation löschen", + "DeleteApplicationMessageText": "Wirklich die Applikation '{0}' löschen?", + "DeleteBackup": "Backup löschen", + "DeleteBackupMessageText": "Backup '{0}' wirkich löschen?", + "DeleteDownloadClient": "Downloader löschen", + "DeleteDownloadClientMessageText": "Downloader '{0}' wirklich löschen?", + "DeleteIndexerProxy": "Indexer Proxy löschen", + "DeleteIndexerProxyMessageText": "Tag '{0}' wirklich löschen?", + "DeleteNotification": "Benachrichtigung löschen", + "DeleteNotificationMessageText": "Benachrichtigung '{0}' wirklich löschen?", + "DeleteTag": "Tag löschen", + "DeleteTagMessageText": "Tag '{0}' wirklich löschen?", + "Description": "Beschreibung", + "Details": "Details", + "DevelopmentSettings": "Entwicklungseinstellungen", + "Disabled": "Deaktiviert", + "Discord": "Discord", + "Docker": "Docker", + "Donations": "Spenden", + "DownloadClient": "Downloader", + "DownloadClientSettings": "Downloader Einstellungen", + "DownloadClientStatusCheckAllClientMessage": "Alle Download Clients sind aufgrund von Fehlern nicht verfügbar", + "DownloadClientStatusCheckSingleClientMessage": "Download Clients aufgrund von Fehlern nicht verfügbar: {0}", + "DownloadClients": "Downloader", + "DownloadClientsSettingsSummary": "Download der Client-Konfigurationen für die Integration in die Prowlarr UI-Suche", + "Duration": "Dauer", + "Edit": "Bearbeiten", + "EditIndexer": "Indexer bearbeiten", + "EditSyncProfile": "Synchronisationsprofil bearbeiten", + "ElapsedTime": "Vergangene Zeit", + "Enable": "Aktivieren", + "EnableAutomaticSearch": "Automatische Suche einschalten", + "EnableAutomaticSearchHelpText": "Wird für automatische Suchen genutzt die vom Benutzer oder von Prowlarr gestartet werden", + "EnableIndexer": "Indexer aktivieren", + "EnableInteractiveSearch": "Interaktive Suche einschalten", + "EnableInteractiveSearchHelpText": "Wird bei der manuellen Suche benutzt", + "EnableRss": "RSS aktivieren", + "EnableRssHelpText": "RSS-Feed für Indexer aktivieren", + "EnableSSL": "SSL", + "EnableSslHelpText": " Erfordert einen Neustart als Administrator", + "Enabled": "Aktiviert", + "EnabledRedirected": "Aktiviert, Weitergeleitet", + "Encoding": "Codierung", + "Ended": "Beendet", + "Error": "Fehler", + "ErrorLoadingContents": "Fehler beim laden der Inhalte", + "EventType": "Event Typ", + "Events": "Events", + "Exception": "Ausnahme", + "ExistingTag": "Vorhandener Tag", + "Failed": "Fehlgeschlagen", + "FeatureRequests": "Funktionsanfragen", + "Filename": "Dateiname", + "Files": "Dateien", + "Filter": "Filter", + "FilterPlaceHolder": "Filme suchen", + "Filters": "Filter", + "Fixed": "Behoben", + "FocusSearchBox": "Suchbox fokussieren", + "Folder": "Ordner", + "ForMoreInformationOnTheIndividualDownloadClients": "Für mehr Infomationen klicke auf die Info-Knöpfe.", + "FullSync": "Vollständige Synchronisierung", + "General": "Allgemein", + "GeneralSettings": "Allgemeine Einstellungen", + "GeneralSettingsSummary": "Port, SSL, Benutzername/Passwort, Proxy, Analytik und Updates", + "GrabReleases": "Release erfassen", + "GrabTitle": "Titel holen", + "Grabbed": "Erfasste", + "Grabs": "Erfasse", + "Health": "Zustandsüberwachung", + "HealthNoIssues": "Keine Probleme mit deiner Konfiguration", + "HiddenClickToShow": "Versteckt, klicken zum anzeigen", + "HideAdvanced": "Erweiterte Ansicht", + "History": "Verlauf", + "HistoryCleanup": "Verlaufsbereinigung", + "HistoryCleanupDaysHelpText": "Auf 0 setzen um das automatische leeren des Papierkorbs zu deaktivieren", + "HistoryCleanupDaysHelpTextWarning": "Datien im Papierkorb die älter sind als der gewählte Wert, werden endgültig gelöscht", + "HomePage": "Startseite", + "Host": "Host", + "Hostname": "Hostname", + "Id": "Id", + "IgnoredAddresses": "Ignorierte Adressen", + "IllRestartLater": "Später neustarten", + "IncludeHealthWarningsHelpText": "Zustandswarnung", + "Indexer": "Indexer", + "IndexerAlreadySetup": "Mindestens eine Indexer Instanz ist bereits eingerichtet", + "IndexerAuth": "Indexer Authentifizierung", + "IndexerDetails": "Indexer-Details", + "IndexerFlags": "Indexer-Flags", + "IndexerHealthCheckNoIndexers": "Keine Indexer aktiviert, Prowlarr wird keine Suchergebnisse zurückgeben", + "IndexerInfo": "Indexer-Info", + "IndexerLongTermStatusCheckAllClientMessage": "Alle Indexer sind wegen über 6 Stunden langen bestehender Fehler nicht verfügbar", + "IndexerLongTermStatusCheckSingleClientMessage": "Indexer wegen über 6 Stunden langen bestehenden Fehlern nicht verfügbar: {0}", + "IndexerName": "Indexer-Name", + "IndexerNoDefCheckMessage": "Indexer haben keine Definition und werden nicht funktionieren: {0}. Bitte entferne und (oder) füge diese neu zu Prowlarr hinzu", + "IndexerObsoleteCheckMessage": "Indexer sind nicht mehr verfügbar oder wurden aktualiiert: {0}. Bitte enfernen und (oder) neu zu Prowlarr hinzufügen", + "IndexerPriority": "Priorität", + "IndexerPriorityHelpText": "Indexer Priorität von 1 (höchste) bis 50 (niedrigste). Standard: 25.", + "IndexerProxies": "Indexer-Proxies", + "IndexerProxy": "Indexer-Proxy", + "IndexerProxyStatusCheckAllClientMessage": "Alle Indexer sind aufgrund von Fehlern nicht verfügbar", + "IndexerProxyStatusCheckSingleClientMessage": "Listen aufgrund von Fehlern nicht verfügbar: {0}", + "IndexerQuery": "Indexer Anfrage", + "IndexerRss": "Indexer RSS", + "IndexerSettingsSummary": "Konfiguration verschiedener globaler Indexer Einstellungen, einschließlich Proxies.", + "IndexerSite": "Indexer-Seite", + "IndexerStatusCheckAllClientMessage": "Alle Indexer sind aufgrund von Fehlern nicht verfügbar", + "IndexerStatusCheckSingleClientMessage": "Indexer aufgrund von Fehlern nicht verfügbar: {0}", + "IndexerTagsHelpText": "Benutze Tags, um Indexer-Proxies zu spezifizieren, mit welchen Apps der Indexer synchronisiert oder um Indexer zu organisieren.", + "IndexerVipCheckExpiredClientMessage": "Die VIP Indexer Vorteile sind abgelaufen: {0}", + "IndexerVipCheckExpiringClientMessage": "Die Indexer VIP Vorteile verfallen bald: {0}", + "Indexers": "Indexer", + "IndexersSelectedInterp": "{0} Indexer ausgewählt", + "Info": "Info", + "InstanceName": "Instanzname", + "InstanceNameHelpText": "Instanzname im Browser-Tab und für Syslog-Anwendungsname", + "InteractiveSearch": "Interaktive Suche", + "Interval": "Intervall", + "KeyboardShortcuts": "Tastenkürzel", + "Language": "Sprache", + "LastDuration": "Letzte Dauer", + "LastExecution": "Letzte Ausführung", + "LastWriteTime": "Zuletzt beschrieben", + "LaunchBrowserHelpText": " Öffne die Startseite von Prowlarr im Webbrowser nach dem Start.", + "Level": "Stufe", + "Link": "Links", + "LogFiles": "Protokolle", + "LogLevel": "Log Level", + "LogLevelTraceHelpTextWarning": "Trace logging sollte nur kurzzeitig aktiviert werden", + "Logging": "Protokollierung", + "Logs": "Protokolle", + "MIA": "MIA", + "MaintenanceRelease": "Wartung: Fehlerbehebung und andere Verbesserungen. Siehe Github Commit History für weitere Details", + "Manual": "Manuell", + "MappedDrivesRunningAsService": "Zugeordnete Netzlaufwerke sind nicht verfügbar, wenn Prowlarr als Windows-Dienst ausgeführt wird. Bitte lesen Sie die FAQ für weitere Informationen", + "MassEditor": "Masseneditor", + "Mechanism": "Verfahren", + "Message": "Nachricht", + "MinimumSeeders": "Mindest-Seeder", + "MinimumSeedersHelpText": "Minimale Anzahl an Seedern die von der Anwendung benötigt werden um den Indexer zu holen", + "Mode": "Modus", + "MoreInfo": "Mehr Infos", + "MovieIndexScrollBottom": "Filmindex: Nach unten scrollen", + "MovieIndexScrollTop": "Filmindex: Nach oben scrollen", + "MovieSearch": "Film Suche", + "MovieSearchTypes": "Film-Suchtypen", + "MusicSearchTypes": "Musik-Suchtypen", + "Name": "Name", + "NetCore": ".NET Core", + "New": "Neu", + "NextExecution": "Nächste Ausführung", + "No": "Nein", + "NoBackupsAreAvailable": "Es sind keine Backups vorhanden", + "NoChange": "Keine Änderung", + "NoChanges": "Keine Änderungen", + "NoLeaveIt": "Nein, nicht ändern", + "NoLinks": "Keine Links", + "NoLogFiles": "Keine Log-Dateien", + "NoSearchResultsFound": "Keine Suchergebnisse gefunden. Versuchen Sie unten eine erneute Suche durchzuführen.", + "NoTagsHaveBeenAddedYet": "Es wurden noch keine Tags erstellt", + "NoUpdatesAreAvailable": "Es sind keine Updates verfügbar", + "NotSupported": "Nicht unterstützt", + "Notification": "Benachrichtigungen", + "NotificationTriggers": "Benachrichtigungs Auslöser", + "NotificationTriggersHelpText": "Auslöser für diese Benachrichtigung auswählen", + "Notifications": "Benachrichtigungen", + "OAuthPopupMessage": "Dein Browser blockiert Pop-ups", + "Ok": "OK", + "OnApplicationUpdate": "Bei Anwendungsaktualisierung", + "OnApplicationUpdateHelpText": "Bei Anwendungsaktualisierung", + "OnGrab": "Bei Erfassung", + "OnHealthIssue": "Bei Zustandsproblem", + "OnHealthIssueHelpText": "Zustandsproblem", + "OpenBrowserOnStart": "Browser beim Start öffnen", + "OpenThisModal": "Dieses Modal öffnen", + "Options": "Optionen", + "PackageVersion": "Paket Version", + "PageSize": "Einträge pro Seite", + "PageSizeHelpText": "Anzahl der Einträge pro Seite", + "Parameters": "Parameter", + "Password": "Passwort", + "Peers": "Peers", + "PendingChangesDiscardChanges": "Änderungen verwerfen und schließen", + "PendingChangesMessage": "Es gibt noch ungespeicherte Änderungen, bist du sicher, dass du die Seite verlassen möchtest?", + "PendingChangesStayReview": "Auf der Seite bleiben", + "Port": "Port", + "PortNumber": "Port Nummer", + "Presets": "Voreinstellungen", + "Priority": "Priorität", + "PriorityHelpText": "Priorisiere mehrere Downloader. Rundlauf-Verfahren wird für Downloader mit der gleichen Priorität verwendet.", + "PrioritySettings": "Priorität", + "Privacy": "Privatsphäre", + "Private": "Privat", + "Protocol": "Protokoll", + "ProwlarrSupportsAnyDownloadClient": "Jeder Downloader der den Newznab-Standard verwendet oder unten aufgelistet ist wird untertützt.", + "ProwlarrSupportsAnyIndexer": "Prowlarr unterstützt alle Indexer, welcher den Newznab/Torznab Standard implementiert (verwende 'Generic Newznab' (für Usenet) oder 'Generic Torznab' (für Torrents)) und darüber hinaus viele weitere Indexer. Wählen Sie im Folgenden Ihren Indexer aus der Liste.", + "Proxies": "Proxies", + "Proxy": "Proxy", + "ProxyBypassFilterHelpText": "Verwende ',' als Trennzeichen und '*.' als Platzhalter für Subdomains", + "ProxyCheckBadRequestMessage": "Proxy konnte nicht getestet werden. StatusCode: {0}", + "ProxyCheckFailedToTestMessage": "Proxy konnte nicht getestet werden: {0}", + "ProxyCheckResolveIpMessage": "Fehler beim Auflösen der IP-Adresse für den konfigurierten Proxy-Host {0}", + "ProxyPasswordHelpText": "Nur wenn ein Benutzername und Passwort erforderlich ist, muss es eingegeben werden. Ansonsten leer lassen.", + "ProxyType": "Proxy Typ", + "ProxyUsernameHelpText": "Nur wenn ein Benutzername und Passwort erforderlich ist, muss es eingegeben werden. Ansonsten leer lassen.", + "Public": "Öffentlich", + "Query": "Abfrage", + "QueryOptions": "Abfrage-Optionen", + "QueryResults": "Abfrageergebnisse", + "Queue": "Warteschlange", + "Queued": "In der Warteschlange", + "RSS": "RSS", + "RSSIsNotSupportedWithThisIndexer": "RSS wird von diesem Indexer nicht unterstützt", + "RawSearchSupported": "Raw-Suche unterstützt", + "ReadTheWikiForMoreInformation": "Lese das Wiki für mehr Informationen", + "Reddit": "Reddit", + "Redirect": "Umleiten", + "RedirectHelpText": "Eingehende Download-Anfragen für den Indexer umleiten, anstatt Proxying mit Prowlarr", + "Refresh": "Aktualisieren", + "RefreshMovie": "Film aktualisieren", + "ReleaseBranchCheckOfficialBranchMessage": "Zweig {0} ist kein gültiger Prowlarr-Release-Zweig. Sie erhalten keine Updates", + "ReleaseStatus": "Releasestatus", + "Reload": "Neuladen", + "Remove": "Entfernen", + "RemoveFilter": "Filter entfernen", + "RemovedFromTaskQueue": "Aus der Aufgabenwarteschlage entfernt", + "RemovingTag": "Tag entfernen", + "Replace": "Ersetzen", + "Reset": "Zurücksetzen", + "ResetAPIKey": "API-Schlüssel zurücksetzen", + "Restart": "Neustarten", + "RestartNow": "Jetzt neustarten", + "RestartProwlarr": "Prowlarr Neustarten", + "RestartRequiredHelpTextWarning": "Erfordert einen Neustart", + "Restore": "Wiederherstellen", + "RestoreBackup": "Backup einspielen", + "Result": "Ergebnis", + "Retention": "Aufbewahrung ( Retention )", + "SSLCertPassword": "SSL Zertifikat Passwort", + "SSLCertPasswordHelpText": "Passwort für die PFX Datei", + "SSLCertPath": "Pfad zum SSL Zertifikat", + "SSLCertPathHelpText": "Pfad zur PFX Datei", + "SSLPort": "SSL Port", + "Save": "Speichern", + "SaveChanges": "Änderungen speichern", + "SaveSettings": "Einstellungen speichern", + "Scheduled": "Geplant", + "ScriptPath": "Script Pfad", + "Search": "Suche", + "SearchCapabilities": "Suchfähigkeiten", + "SearchIndexers": "Indexer suchen", + "SearchType": "Suchtyp", + "SearchTypes": "Suchtyp", + "Security": "Sicherheit", + "Seeders": "Seeders", + "SelectAll": "Alle wählen", + "SemiPrivate": "Halbprivat", + "SendAnonymousUsageData": "Anonyme Nutzungsdaten übertragen", + "SetTags": "Tags setzen", + "Settings": "Einstellungen", + "SettingsConsoleLogLevel": "Konsolen Log Level", + "SettingsEnableColorImpairedMode": "Farbbeeinträchtigter Modus aktivieren", + "SettingsEnableColorImpairedModeHelpText": "Alternativer Stil, um farbbeeinträchtigten Benutzern eine bessere Unterscheidung farbcodierter Informationen zu ermöglichen", + "SettingsFilterSentryEvents": "Analystische Ergeinisse filtern", + "SettingsFilterSentryEventsHelpText": "Sende keine bekannten Benutzerfehler Ereignisse an Analystics", + "SettingsIndexerLogging": "Verbesserte Indexer-Protokollierung", + "SettingsIndexerLoggingHelpText": "Erweiterte Indexerdaten loggen inklusive Antwort", + "SettingsLogRotate": "Logrotation", + "SettingsLogRotateHelpText": "Max. Anzahl der zu behaltenden Logdateien", + "SettingsLogSql": "Log SQL", + "SettingsLongDateFormat": "Langes Datumsformat", + "SettingsShortDateFormat": "Kurzes Datumsformat", + "SettingsShowRelativeDates": "Relatives Datum anzeigen", + "SettingsShowRelativeDatesHelpText": "Relatives (z.B.: Heute, gestern, etc) oder absolutes Datum anzeigen", + "SettingsSqlLoggingHelpText": "Log alle SQL Abfragen von Prowlarr", + "SettingsTimeFormat": "Zeitformat", + "ShowAdvanced": "Einfache Ansicht", + "ShowSearch": "Suche anzeigen", + "ShowSearchHelpText": "Suchbutton anzeigen beim draufzeigen", + "ShownClickToHide": "Angezeigt, zum verstecken klicken", + "Shutdown": "Herunterfahren", + "Size": "Größe", + "Sort": "Sortieren", + "Source": "Quelle", + "StartTypingOrSelectAPathBelow": "Eingeben oder unten auswählen", + "Started": "gestartet", + "StartupDirectory": "Start-Verzeichnis", + "Stats": "Statistiken", + "Status": "Status", + "Style": "Stil", + "SuggestTranslationChange": "Schlage eine Übersetzung vor", + "SyncAppIndexers": "App Indexer syncen", + "SyncLevel": "Sync-Level", + "SyncLevelAddRemove": "Nur hinzufügen und entfernen: Wenn Indexer zu Prowlarr hinzugefügt oder entfernt werden, wird diese Remote-App aktualisiert.", + "SyncLevelFull": "Vollständige Synchronisierung: Hält die Indexer dieser App vollständig synchronisiert. Änderungen an Indexern in Prowlarr werden mit dieser App synchronisiert. Jede Änderung die and Indexern dieser App gemacht werden, wird von Prowlarr bei der nächsten Synchronisierung überschrieben.", + "SyncProfile": "Sync-Profile", + "SyncProfiles": "Sync-Profile", + "System": "System", + "SystemTimeCheckMessage": "Die Systemzeit ist um einen Tag versetzt. Bis die Zeit korrigiert wurde, könnten die geplanten Aufgaben nicht korrekt ausgeführt werden", + "TVSearchTypes": "Suchtyp", + "TableOptions": "Tabellen Optionen", + "TableOptionsColumnsMessage": "Wähle aus welche Spalten angezeigt werden und in welcher Reihenfolge", + "TagCannotBeDeletedWhileInUse": "Kann während der Benutzung nicht gelöscht werden", + "TagIsNotUsedAndCanBeDeleted": "Tag wird nicht benutzt und kann gelöscht werden", + "Tags": "Tags", + "TagsHelpText": "Wird auf Filme mit mindestens einem passenden Tag angewandt", + "TagsSettingsSummary": "Alle Tags und deren Benutzung anzeigen. Unbenutzte Tags können entfernt werden", + "Tasks": "Aufgaben", + "Test": "Testen", + "TestAll": "Alle testen", + "TestAllApps": "Alle Apps testen", + "TestAllClients": "Alle testen", + "TestAllIndexers": "Alle testen", + "TheLatestVersionIsAlreadyInstalled": "Die aktuellste Version ist bereits installiert", + "ThemeHelpText": "Ändere das UI-Theme der Anwendung. Das 'Auto'-Theme verwendet dein Betriebssystem-Theme, um den hellen oder dunklen Modus einzustellen. Inspiriert von {0}", + "Time": "Zeit", + "Title": "Titel", + "Today": "Heute", + "Tomorrow": "Morgen", + "Torrent": "Torrent", + "Torrents": "Torrents", + "TvSearch": "TV Suche", + "Type": "Typ", + "UI": "Oberfläche", + "UILanguage": "Oberflächen Sprache ( UI Language )", + "UILanguageHelpText": "Sprache für die gesamte Oberfläche", + "UILanguageHelpTextWarning": "Webseite muss neu geladen werden", + "UISettings": "Benutzeroberflächen Einstellungen", + "UISettingsSummary": "Optionen für Datum, Sprache und Farbbeinträchtigungen", + "URLBase": "URL-Basis", + "UnableToAddANewAppProfilePleaseTryAgain": "Es kann kein neues Anwendungsprofil hinzugefügt werden. Bitte versuchen Sie es erneut.", + "UnableToAddANewApplicationPleaseTryAgain": "Es kann keine neue Anwendung hinzugefügt werden. Bitte versuchen Sie es erneut.", + "UnableToAddANewDownloadClientPleaseTryAgain": "Der neue Downloader konnte nicht hinzugefügt werden, bitte erneut probieren.", + "UnableToAddANewIndexerPleaseTryAgain": "Der neue Indexer konnte nicht hinzugefügt werden, bitte erneut probieren.", + "UnableToAddANewIndexerProxyPleaseTryAgain": "Der neue Indexer konnte nicht hinzugefügt werden, bitte erneut probieren.", + "UnableToAddANewNotificationPleaseTryAgain": "Die neue Benachrichtigung konnte nicht hinzugefügt werden, bitte erneut probieren.", + "UnableToLoadAppProfiles": "App-Profile können nicht geladen werden", + "UnableToLoadApplicationList": "Anwendungsliste kann nicht geladen werden", + "UnableToLoadBackups": "Backups konnten nicht geladen werden", + "UnableToLoadDevelopmentSettings": "Entwicklereinstellungen konnten nicht geladen werden", + "UnableToLoadDownloadClients": "Downloader konnten nicht geladen werden", + "UnableToLoadGeneralSettings": "Allgemeine Einstellungen konnten nicht geladen werden", + "UnableToLoadHistory": "Verlauf konnte nicht geladen werden", + "UnableToLoadIndexerProxies": "Indexer-Proxies können nicht geladen werden", + "UnableToLoadIndexers": "Indexer konnten nicht geladen werden", + "UnableToLoadNotifications": "Benachrichtigungen konnten nicht geladen werden", + "UnableToLoadTags": "Tags konnten nicht geladen werden", + "UnableToLoadUISettings": "Oberflächen Einstellungen konnten nicht geladen werden", + "UnsavedChanges": "Ungespeicherte Änderungen", + "UnselectAll": "Keine wählen", + "UpdateAutomaticallyHelpText": "Updates automatisch herunteraden und installieren. Es kann weiterhin unter \"System -> Updates\" ein manuelles Update angestoßen werden", + "UpdateCheckStartupNotWritableMessage": "Update kann nicht installiert werden, da der Startordner '{0}' vom Benutzer '{1}' nicht beschreibbar ist.", + "UpdateCheckStartupTranslocationMessage": "Update kann nicht installiert werden, da sich der Startordner '{0}' in einem App Translocation-Ordner befindet.", + "UpdateCheckUINotWritableMessage": "Update kann nicht installiert werden, da der Benutzeroberflächenordner '{0}' vom Benutzer '{1}' nicht beschreibbar ist.", + "UpdateMechanismHelpText": "Benutze Prowlarr's Built-In Updater oder ein Script", + "UpdateScriptPathHelpText": "Pfad zu einem benutzerdefinierten Skript, das ein extrahiertes Update-Paket übernimmt und den Rest des Update-Prozesses abwickelt", + "Updates": "Updates", + "Uptime": "Laufzeit", + "Url": "Url", + "UrlBaseHelpText": "Für Reverse-Proxy-Unterstützung. Die Standardeinstellung leer", + "UseProxy": "Proxy benutzen", + "Usenet": "Usenet", + "UserAgentProvidedByTheAppThatCalledTheAPI": "UserAgent von der App welcher die API aufgerufen hat", + "Username": "Benutzername", + "Version": "Version", + "View": "Ansicht", + "Warn": "Warnung", + "Website": "Webseite", + "Wiki": "Wiki", + "Yes": "Ja", + "YesCancel": "Ja, abbrechen", + "Yesterday": "Gestern", + "OnHealthRestoredHelpText": "Bei Wiederherstellung des Zustands", + "OnHealthRestored": "Bei Wiederherstellung des Zustands", + "StopSelecting": "Auswahl stoppen" } diff --git a/src/NzbDrone.Core/Localization/Core/el.json b/src/NzbDrone.Core/Localization/Core/el.json index 918d92c8f..10248de44 100644 --- a/src/NzbDrone.Core/Localization/Core/el.json +++ b/src/NzbDrone.Core/Localization/Core/el.json @@ -471,5 +471,6 @@ "SyncLevelFull": "Πλήρης συγχρονισμός: Θα διατηρήσει πλήρως συγχρονισμένα τα ευρετήρια αυτής της εφαρμογής. Στη συνέχεια, οι αλλαγές που γίνονται στους indexers στο Prowlarr συγχρονίζονται με αυτήν την εφαρμογή. Οποιαδήποτε αλλαγή γίνει σε ευρετήρια απομακρυσμένα σε αυτήν την εφαρμογή θα παρακαμφθεί από τον Prowlarr στον επόμενο συγχρονισμό.", "Remove": "Αφαιρώ", "Replace": "Αντικαθιστώ", - "TheLatestVersionIsAlreadyInstalled": "Η τελευταία έκδοση του Prowlarr είναι ήδη εγκατεστημένη" + "TheLatestVersionIsAlreadyInstalled": "Η τελευταία έκδοση του Prowlarr είναι ήδη εγκατεστημένη", + "ApiKeyValidationHealthCheckMessage": "Παρακαλούμε ενημερώστε το κλείδι API ώστε να έχει τουλάχιστον {0} χαρακτήρες. Μπορείτε να το κάνετε αυτό μέσα από τις ρυθμίσεις ή το αρχείο ρυθμίσεων" } diff --git a/src/NzbDrone.Core/Localization/Core/fr.json b/src/NzbDrone.Core/Localization/Core/fr.json index de073e90e..0b6735ad7 100644 --- a/src/NzbDrone.Core/Localization/Core/fr.json +++ b/src/NzbDrone.Core/Localization/Core/fr.json @@ -22,7 +22,7 @@ "Clear": "Effacer", "BackupNow": "Sauvegarder maintenant", "Backup": "Sauvegarde", - "AppDataLocationHealthCheckMessage": "Mettre à jour ne sera pas possible afin d'éviter de supprimer le dossier AppData lors de la mise à jour", + "AppDataLocationHealthCheckMessage": "La mise à jour ne sera pas possible pour empêcher la suppression de AppData lors de la mise à jour", "Analytics": "Analytique", "All": "Tout", "About": "À propos", @@ -80,7 +80,7 @@ "EventType": "Type d'événement", "Details": "Détails", "ConnectSettingsSummary": "Notifications et scripts personnalisés", - "Added": "Ajoutée", + "Added": "Ajouter", "Actions": "Actions", "Info": "Info", "Error": "Erreur", @@ -506,5 +506,5 @@ "Track": "Piste", "Year": "Année", "ApplicationURL": "URL de l'application", - "ApiKeyValidationHealthCheckMessage": "Merci de mettre à jour votre clé API afin qu'elle fasse plus de 20 caractères. Rendez vous dans les paramètres ou dans le fichier de configuration" + "ApiKeyValidationHealthCheckMessage": "Veuillez mettre à jour votre clé API pour qu'elle contienne au moins {0} caractères. Vous pouvez le faire via les paramètres ou le fichier de configuration" } diff --git a/src/NzbDrone.Core/Localization/Core/pt.json b/src/NzbDrone.Core/Localization/Core/pt.json index e8f7c5f4a..227a88d26 100644 --- a/src/NzbDrone.Core/Localization/Core/pt.json +++ b/src/NzbDrone.Core/Localization/Core/pt.json @@ -1,6 +1,6 @@ { "Peers": "Elementos", - "AppDataLocationHealthCheckMessage": "Não será possível atualizar para evitar a exclusão da pasta AppData durante a atualização", + "AppDataLocationHealthCheckMessage": "Não foi possivél actualizar para prevenir apagar a AppData durante a actualização", "Warn": "Avisar", "View": "Ver", "Updates": "Atualizações", @@ -420,5 +420,6 @@ "TheLatestVersionIsAlreadyInstalled": "A versão mais recente do Prowlarr já está instalada", "AddSyncProfile": "Adicionar Perfil de Sincronização", "AddApplication": "Adicionar Aplicação", - "AddCustomFilter": "Adicionar Filtro customizado" + "AddCustomFilter": "Adicionar Filtro customizado", + "ApiKeyValidationHealthCheckMessage": "Por favor, actualize a sua API Key para ter no minimo {0} caracteres. Pode fazer através das definições ou do ficheiro de configuração" } diff --git a/src/NzbDrone.Core/Localization/Core/zh_CN.json b/src/NzbDrone.Core/Localization/Core/zh_CN.json index d0e871a14..0e225242f 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_CN.json +++ b/src/NzbDrone.Core/Localization/Core/zh_CN.json @@ -1,506 +1,507 @@ { - "About": "关于", - "AcceptConfirmationModal": "接受确认模组Accept Confirmation Modal", - "Actions": "操作", - "Add": "添加", - "AddApplication": "添加应用程序", - "AddCustomFilter": "添加自定义过滤", - "AddDownloadClient": "添加下载客户端", - "AddDownloadClientToProwlarr": "添加下载客户端允许 Prowlarr 在进行手动搜索时从 UI直接发送结果.", - "AddIndexer": "添加索引器", - "AddIndexerProxy": "添加搜刮器代理", - "AddNewIndexer": "添加新的索引器", - "AddRemoveOnly": "仅添加和删除", - "AddSyncProfile": "添加同步配置文件", - "AddToDownloadClient": "添加发布到下载客户端", - "Added": "已添加", - "AddedToDownloadClient": "发布已添加档案到客户端", - "AddingTag": "添加标签", - "Age": "年龄", - "All": "全部", - "AllIndexersHiddenDueToFilter": "由于应用了筛选器,所有索引器都被隐藏。", - "Analytics": "分析", - "AnalyticsEnabledHelpText": "将匿名使用情况和错误信息发送到Prowlarr的服务器。这包括有关您的浏览器的信息、您使用的Prowlarr WebUI页面、错误报告以及操作系统和运行时版本。我们将使用此信息来确定功能和错误修复的优先级。", - "ApiKey": "API 密钥", - "ApiKeyValidationHealthCheckMessage": "", - "AppDataDirectory": "AppData目录", - "AppDataLocationHealthCheckMessage": "更新将无法阻止在更新时删除 AppData", - "AppProfileDeleteConfirm": "您确认您想删除吗?", - "AppProfileInUse": "正在使用的应用程序配置文件", - "AppProfileSelectHelpText": "应用程序配置用于控制应用程序同步设置 RSS、自动搜索和交互式搜索设置", - "AppSettingsSummary": "配置Prowlarr与PVR程序交互方式的应用和设置", - "Application": "程序", - "ApplicationLongTermStatusCheckAllClientMessage": "由于故障超过6小时,所有程序都不可用", - "ApplicationLongTermStatusCheckSingleClientMessage": "由于故障超过6小时而无法使用的程序:{0}", - "ApplicationStatusCheckAllClientMessage": "由于故障所用应用程序都不可用", - "ApplicationStatusCheckSingleClientMessage": "由于故障应用程序不可用", - "ApplicationURL": "应用程序 URL", - "ApplicationUrlHelpText": "此应用程序的外部URL,包括http(s)://,端口和基本URL", - "Applications": "程序", - "Apply": "应用", - "ApplyTags": "应用标签", - "ApplyTagsHelpTexts1": "如何应用标签到已选择索引器", - "ApplyTagsHelpTexts2": "添加:将标签添加到现有标签列表", - "ApplyTagsHelpTexts3": "删除:移除输入的标签", - "ApplyTagsHelpTexts4": "替换:用输入的标签替换标签(不输入标签将清除所有标签)", - "Apps": "应用程序", - "AreYouSureYouWantToDeleteCategory": "您确定要删除映射类别吗?", - "AreYouSureYouWantToResetYourAPIKey": "你确认希望重置API密钥吗?", - "Artist": "艺术家", - "AudioSearch": "音频搜索", - "Auth": "认证", - "Authentication": "认证", - "AuthenticationMethodHelpText": "需要账号和密码以登录Prowlarr", - "AuthenticationRequired": "需要认证", - "AuthenticationRequiredHelpText": "更改需要身份验证的请求。除非您了解风险,否则请勿更改。", - "AuthenticationRequiredWarning": "为了防止远程访问而无需身份验证,Prowlarr现在需要启用身份验证。请配置您的身份验证方法和凭据。您可以选择从本地地址禁用身份验证。有关其他信息,请参阅FAQ。", - "Author": "作者", - "Automatic": "自动化", - "AutomaticSearch": "自动搜索", - "AverageResponseTimesMs": "平均响应时间(毫秒)", - "Backup": "备份", - "BackupFolderHelpText": "相对路径将在 Prowlarr 的 AppData 目录下", - "BackupIntervalHelpText": "自动备份时间间隔", - "BackupNow": "马上备份", - "BackupRetentionHelpText": "早于保留周期的自动备份将被自动清除", - "Backups": "备份", - "BeforeUpdate": "更新前", - "BindAddress": "绑定地址", - "BindAddressHelpText": "有效的 IPv4 地址、localhost、或以'*'代表所有接口", - "Book": "图书", - "BookSearch": "图书搜索", - "BookSearchTypes": "搜索图书类型", - "Branch": "分支", - "BranchUpdate": "更新Prowlarr的分支", - "BranchUpdateMechanism": "外部更新机制使用的分支", - "BypassProxyForLocalAddresses": "对局域网地址不使用代理", - "Cancel": "取消", - "CancelPendingTask": "您确定要取消这个挂起的任务吗?", - "Categories": "分类", - "Category": "类别", - "CertificateValidation": "验证证书", - "CertificateValidationHelpText": "改变HTTPS证书验证的严格程度", - "ChangeHasNotBeenSavedYet": "修改暂未保存", - "Clear": "清除", - "ClearHistory": "清楚历史", - "ClearHistoryMessageText": "您确定要清除Prowlarr所有的历史记录吗?", - "ClientPriority": "客户端优先级", - "CloneProfile": "复制配置", - "Close": "关闭", - "CloseCurrentModal": "关闭当前模组", - "Columns": "列", - "Component": "组件", - "Connect": "通知", - "ConnectSettings": "连接设置", - "ConnectSettingsSummary": "通知和自定义脚本", - "ConnectionLost": "连接丢失", - "ConnectionLostAutomaticMessage": "Prowlarr 将会自动重连,您也可以点击下方的重新加载。", - "ConnectionLostMessage": "Prowlarr 已与服务端断开链接,请尝试刷新来恢复使用。", - "Connections": "连接", - "CouldNotConnectSignalR": "无法连接至SignalR,不会升级UI", - "Custom": "自定义", - "CustomFilters": "自定义过滤", - "DBMigration": "数据库迁移版本", - "Database": "数据库", - "Date": "日期", - "Dates": "日期", - "Delete": "删除", - "DeleteAppProfile": "删除应用配置文件", - "DeleteApplication": "删除应用程序", - "DeleteApplicationMessageText": "您确定要删除应用程序“{0}”吗?", - "DeleteBackup": "删除备份", - "DeleteBackupMessageText": "您确定要删除备份 '{0}' 吗?", - "DeleteClientCategory": "删除下载客户端类别", - "DeleteDownloadClient": "删除下载客户端", - "DeleteDownloadClientMessageText": "您确定要删除下载客户端 '{0}' 吗?", - "DeleteIndexerProxy": "删除搜刮器代理", - "DeleteIndexerProxyMessageText": "您确定要删除列表 '{0}'?", - "DeleteNotification": "删除消息推送", - "DeleteNotificationMessageText": "您确定要删除推送 '{0}' 吗?", - "DeleteTag": "删除标签", - "DeleteTagMessageText": "您确定要删除标签 '{0}' 吗?", - "Description": "描述", - "Details": "详情", - "DevelopmentSettings": "开发设置", - "Disabled": "禁用", - "DisabledUntil": "禁用Until", - "Discord": "冲突", - "Docker": "Docker", - "Donations": "捐赠", - "DownloadClient": "下载客户端", - "DownloadClientCategory": "下载客户端类别", - "DownloadClientSettings": "下载客户端设置", - "DownloadClientStatusCheckAllClientMessage": "所有下载客户端都不可用", - "DownloadClientStatusCheckSingleClientMessage": "所有下载客户端都不可用: {0}", - "DownloadClients": "下载客户端", - "DownloadClientsSettingsSummary": "下载客户端配置以集成到 Prowlarr UI 搜索中", - "Duration": "时长", - "Edit": "编辑", - "EditIndexer": "编辑搜刮器", - "EditSyncProfile": "编辑同步配置文件", - "ElapsedTime": "运行时间", - "Enable": "启用", - "EnableAutomaticSearch": "启用自动搜索", - "EnableAutomaticSearchHelpText": "当自动搜索通过UI或Prowlarr执行时将被使用", - "EnableIndexer": "启用搜刮器", - "EnableInteractiveSearch": "启用手动搜索", - "EnableInteractiveSearchHelpText": "当手动搜索启用时使用", - "EnableRss": "启用RSS", - "EnableRssHelpText": "为搜刮器启用 RSS订阅", - "EnableSSL": "启用SSL", - "EnableSslHelpText": " 重启生效", - "Enabled": "已启用", - "EnabledRedirected": "启用, 修改", - "Encoding": "编码", - "Ended": "已完结", - "Episode": "集", - "Error": "错误", - "ErrorLoadingContents": "读取内容错误", - "EventType": "事件类型", - "Events": "事件", - "Exception": "例外", - "ExistingTag": "已有标签", - "Failed": "失败", - "FeatureRequests": "功能建议", - "Filename": "文件名", - "Files": "文件", - "Filter": "过滤", - "FilterPlaceHolder": "搜刮器搜索", - "Filters": "过滤器", - "Fixed": "已修复", - "FocusSearchBox": "聚焦搜索框", - "Folder": "文件夹", - "ForMoreInformationOnTheIndividualDownloadClients": "有关个别下载客户端的详细信息,请单击info按钮。", - "FullSync": "完全同步", - "General": "通用", - "GeneralSettings": "通用设置", - "GeneralSettingsSummary": "端口、SSL、用户名/密码、代理、分析、更新", - "Genre": "类型", - "GrabReleases": "抓取版本", - "GrabTitle": "抓取标题", - "Grabbed": "已抓取", - "Grabs": "抓取", - "Health": "健康度", - "HealthNoIssues": "您的设置没有问题", - "HiddenClickToShow": "已隐藏,点击显示", - "HideAdvanced": "隐藏高级设置", - "History": "历史记录", - "HistoryCleanup": "清理历史记录", - "HistoryCleanupDaysHelpText": "设置为0关闭自动清理", - "HistoryCleanupDaysHelpTextWarning": "回收站中的文件在超出选择的天数后会被自动清理", - "HistoryDetails": "历史详情", - "HomePage": "主页", - "Host": "主机", - "Hostname": "主机名", - "Id": "Id", - "IgnoredAddresses": "已忽略地址", - "IllRestartLater": "稍后重启", - "IncludeHealthWarningsHelpText": "包含健康度警告", - "IncludeManualGrabsHelpText": "安装手动抓取Prowlarr", - "Indexer": "搜刮器", - "IndexerAlreadySetup": "至少已经设置了一个索引器", - "IndexerAuth": "搜刮器认证", - "IndexerDetails": "‎索引器‎‎详细信息‎", - "IndexerDisabled": "索引器已被禁用", - "IndexerFailureRate": "Indexer失败率", - "IndexerFlags": "搜刮器标记", - "IndexerHealthCheckNoIndexers": "未启用任何搜刮器,Prowlarr将不会返回搜索结果", - "IndexerInfo": "索引器信息", - "IndexerLongTermStatusCheckAllClientMessage": "由于故障超过6小时,所有搜刮器均不可用", - "IndexerLongTermStatusCheckSingleClientMessage": "由于故障6小时,下列搜刮器都已不可用:{0}", - "IndexerName": "‎索引‎‎名字‎", - "IndexerNoDefCheckMessage": "索引器没有定义,将无法工作: {0}. 请删除或重新添加到Prowlarr", - "IndexerObsoleteCheckMessage": "搜刮器已过弃用或已更新:{0}。请将其删除和(或)重新添加到 Prowlarr", - "IndexerPriority": "搜刮器优先级", - "IndexerPriorityHelpText": "索引器优先级从1(最高)到50(最低),默认25。", - "IndexerProxies": "搜刮器代理", - "IndexerProxy": "搜刮器代理", - "IndexerProxyStatusCheckAllClientMessage": "所有搜刮器都因错误不可用", - "IndexerProxyStatusCheckSingleClientMessage": "搜刮器因错误不可用:{0}", - "IndexerQuery": "搜刮器查询", - "IndexerRss": "搜刮器RSS", - "IndexerSettingsSummary": "配置全局索引器设置,包括代理。", - "IndexerSite": "‎索引‎‎网站‎", - "IndexerStatusCheckAllClientMessage": "所有搜刮器都因错误不可用", - "IndexerStatusCheckSingleClientMessage": "搜刮器因错误不可用:{0}", - "IndexerTagsHelpText": "使用标签指定索引器代理, 索引器同步到哪些应用程序,或者只是为了组织索引器。未指定索引器的应用程序将不会同步。", - "IndexerVipCheckExpiredClientMessage": "索引器VIP特权已过期:{0}", - "IndexerVipCheckExpiringClientMessage": "索引器VIP特权即将过期:{0}", - "Indexers": "搜刮器", - "IndexersSelectedInterp": "已选择 {0} 个搜刮器", - "Info": "信息", - "InitialFailure": "初始化失败", - "InstanceName": "中文", - "InstanceNameHelpText": "选项卡及日志应用名称", - "InteractiveSearch": "手动搜索", - "Interval": "间隔", - "KeyboardShortcuts": "键盘快捷键", - "Label": "标签", - "Language": "语言", - "LastDuration": "上一次用时", - "LastExecution": "上一次执行", - "LastFailure": "最后一次失败", - "LastWriteTime": "最后写入时间", - "LaunchBrowserHelpText": " 启动浏览器时导航到Prowlarr 主页。", - "Level": "等级", - "Link": "链接", - "LogFiles": "日志文件", - "LogLevel": "日志等级", - "LogLevelTraceHelpTextWarning": "追踪日志只应该暂时启用", - "Logging": "日志记录中", - "Logs": "日志", - "MIA": "MIA", - "MaintenanceRelease": "维护版本:修复错误及其他改进,参见Github提交 查看更多详情", - "Manual": "手动", - "MappedCategories": "映射类别", - "MappedDrivesRunningAsService": "映射的网络驱动器在作为Windows服务运行时不可用。请参阅常见问题解答了解更多信息", - "MassEditor": "批量编辑器", - "Mechanism": "机制", - "Message": "信息", - "MinimumSeeders": "最少播种量", - "MinimumSeedersHelpText": "用于索引器抓取的应用程序所需的最小播种量", - "Mode": "模式", - "More": "更多的", - "MoreInfo": "更多信息", - "MovieIndexScrollBottom": "影片索引:滚动到底部", - "MovieIndexScrollTop": "影片索引:滚动到顶部", - "MovieSearch": "搜索电影", - "MovieSearchTypes": "‎影片‎‎搜索‎‎类型‎", - "MusicSearchTypes": "‎音乐‎‎搜索‎‎类型‎", - "Name": "名称", - "NetCore": ".NET", - "New": "新的", - "NextExecution": "接下来执行", - "No": "否", - "NoBackupsAreAvailable": "无备份可用", - "NoChange": "无修改", - "NoChanges": "无修改", - "NoLeaveIt": "不,就这样", - "NoLinks": "无链接", - "NoLogFiles": "没有日志文件", - "NoSearchResultsFound": "无搜索结果,请在下面尝试新的搜索。", - "NoTagsHaveBeenAddedYet": "未添加标签", - "NoUpdatesAreAvailable": "无可用更新", - "NotSupported": "‎不支持‎", - "Notification": "通知", - "NotificationTriggers": "通知触发器", - "NotificationTriggersHelpText": "选择触发此通知的事件", - "Notifications": "通知", - "OAuthPopupMessage": "您的浏览器已禁止弹出页面", - "Ok": "完成", - "OnApplicationUpdate": "程序更新时", - "OnApplicationUpdateHelpText": "在程序更新时", - "OnGrab": "运行中", - "OnGrabHelpText": "运行中", - "OnHealthIssue": "健康度异常", - "OnHealthIssueHelpText": "健康度异常", - "OpenBrowserOnStart": "打开浏览器时启动", - "OpenThisModal": "打开该模组", - "Options": "选项", - "PackageVersion": "Package版本", - "PageSize": "页面大小", - "PageSizeHelpText": "每页显示的项目数", - "Parameters": "参数", - "Password": "密码", - "Peers": "用户", - "PendingChangesDiscardChanges": "舍弃修改并退出", - "PendingChangesMessage": "您有未保存的修改,确定要退出本页么?", - "PendingChangesStayReview": "留下检查更改", - "Port": "端口", - "PortNumber": "端口号", - "Presets": "预设", - "Priority": "优先级", - "PriorityHelpText": "优先考虑多个下载客户端,循环查询用于具有相同优先级的客户端。", - "PrioritySettings": "优先级", - "Privacy": "隐私", - "Private": "私有", - "Protocol": "协议", - "ProwlarrSupportsAnyDownloadClient": "Prowlarr 支持以下列出的下载客户端。", - "ProwlarrSupportsAnyIndexer": "Prowlarr支持多种搜刮器,包括任何使用Newznab/Torznab标准的搜刮器(“通用Newznab”对应Usenet,“Generic Torznab”对应Torrents)。从以下搜索并选择你的搜刮器。", - "Proxies": "代理", - "Proxy": "代理", - "ProxyBypassFilterHelpText": "使用“ , ”作为分隔符,和“ *. ”作为二级域名的通配符", - "ProxyCheckBadRequestMessage": "测试代理失败,状态码: {0}", - "ProxyCheckFailedToTestMessage": "测试代理失败: {0}", - "ProxyCheckResolveIpMessage": "无法解析已设置的代理服务器主机{0}的IP地址", - "ProxyPasswordHelpText": "如果需要,您只需要输入用户名和密码,否则就让它们为空。", - "ProxyType": "代理类型", - "ProxyUsernameHelpText": "如果需要,您只需要输入用户名和密码。否则就让它们为空。", - "Public": "公开", - "Publisher": "发布者", - "Query": "查询字段", - "QueryOptions": "查询选项", - "QueryResults": "查询结果", - "Queue": "队列", - "Queued": "队列中", - "RSS": "RSS", - "RSSIsNotSupportedWithThisIndexer": "该搜刮器不支持RSS", - "RawSearchSupported": "‎支持原始‎‎搜索‎", - "ReadTheWikiForMoreInformation": "查阅Wiki获得更多信息", - "Reddit": "Reddit", - "Redirect": "重定向", - "RedirectHelpText": "重定向搜刮器的传入下载请求并直接传递抓取,而不是通过Prowlarr代理请求搜刮器", - "Refresh": "刷新", - "RefreshMovie": "刷新影片", - "ReleaseBranchCheckOfficialBranchMessage": "分支 {0} 不是合法的Prowlarr发布分支,您不会收到任何更新", - "ReleaseStatus": "发布状态", - "Reload": "重新加载", - "Remove": "移除", - "RemoveFilter": "移除过滤条件", - "RemovedFromTaskQueue": "从任务队列中移除", - "RemovingTag": "移除标签", - "RepeatSearch": "再次搜索", - "Replace": "替换", - "Reset": "重置", - "ResetAPIKey": "重置API Key", - "Restart": "重启", - "RestartNow": "马上重启", - "RestartProwlarr": "重启Prowlarr", - "RestartRequiredHelpTextWarning": "需要重新启动才能生效", - "Restore": "恢复", - "RestoreBackup": "恢复备份", - "Result": "结果", - "Retention": "保留", - "RssFeed": "RSS订阅", - "SSLCertPassword": "SSL证书密码", - "SSLCertPasswordHelpText": "pfx文件密码", - "SSLCertPath": "SSL证书路径", - "SSLCertPathHelpText": "pfx文件路径", - "SSLPort": "SSL端口", - "Save": "保存", - "SaveChanges": "保存更改", - "SaveSettings": "保存设置", - "Scheduled": "计划中", - "ScriptPath": "脚本路径", - "Search": "搜索", - "SearchCapabilities": "‎搜索‎‎能力‎", - "SearchIndexers": "搜刮器搜索", - "SearchType": "搜索类型", - "SearchTypes": "搜索类型", - "Season": "季", - "Security": "安全", - "Seeders": "种子", - "SelectAll": "选择全部", - "SelectIndexer": "选择索引器", - "SemiPrivate": "‎半私有‎", - "SendAnonymousUsageData": "发送匿名使用数据", - "SetTags": "设定标签", - "Settings": "设置", - "SettingsConsoleLogLevel": "控制台日志级别", - "SettingsEnableColorImpairedMode": "启用色障模式", - "SettingsEnableColorImpairedModeHelpText": "改变样式,以允许有颜色障碍的用户更好地区分颜色编码信息", - "SettingsFilterSentryEvents": "筛选分析事件", - "SettingsFilterSentryEventsHelpText": "过滤已知的用户错误事件,不让其作为分析报告发送", - "SettingsIndexerLogging": "增强型搜刮器日志", - "SettingsIndexerLoggingHelpText": "记录额外的搜刮器数据,包括响应", - "SettingsLogRotate": "日志轮替", - "SettingsLogRotateHelpText": "保存在日志文件夹中的最大日志文件数", - "SettingsLogSql": "事务日志", - "SettingsLongDateFormat": "长时间格式", - "SettingsShortDateFormat": "短日期格式", - "SettingsShowRelativeDates": "显示相对日期", - "SettingsShowRelativeDatesHelpText": "显示相对日期(今天昨天等)或绝对日期", - "SettingsSqlLoggingHelpText": "记录来自Prowlarr的所有SQL查询", - "SettingsTimeFormat": "时间格式", - "ShowAdvanced": "显示高级设置", - "ShowSearch": "显示搜索按钮", - "ShowSearchHelpText": "在选项中显示搜索框", - "ShownClickToHide": "显示高级设置,点击隐藏", - "Shutdown": "关机", - "Size": "文件大小", - "Sort": "排序", - "Source": "源", - "StartTypingOrSelectAPathBelow": "输入路径或者从下面选择", - "Started": "已开始", - "StartupDirectory": "启动目录", - "Stats": "统计数据", - "Status": "状态", - "StopSelecting": "停止选择", - "Style": "类型", - "SuggestTranslationChange": "建议翻译改变 Suggest translation change", - "SyncAppIndexers": "同步应用索引", - "SyncLevel": "同步级别", - "SyncLevelAddRemove": "仅添加和删除:当索引器从 Prowlarr 添加或删除时,它将更新与此关联的应用程序。", - "SyncLevelFull": "完全同步:将保持此应用的索引器完全同步。当在Prowlarr中所做的更改将同步到与此关联的应用程序。任何关联应用上的更改都将在下次同步时被Prowlarr覆盖。", - "SyncProfile": "同步配置文件", - "SyncProfiles": "同步配置文件", - "System": "系统", - "SystemTimeCheckMessage": "系统时间相差超过1天。在纠正时间之前,计划的任务可能无法正确运行", - "TVSearchTypes": "‎电视‎‎搜索‎‎类型‎", - "TableOptions": "表格选项", - "TableOptionsColumnsMessage": "选择显示哪些列并排序", - "TagCannotBeDeletedWhileInUse": "使用中无法删除", - "TagIsNotUsedAndCanBeDeleted": "标签未被使用,可删除", - "Tags": "标签", - "TagsHelpText": "适用于至少有一个匹配标签的索引器", - "TagsSettingsSummary": "显示全部标签和标签使用情况,可删除未使用的标签", - "Tasks": "任务", - "Test": "测试", - "TestAll": "测试全部", - "TestAllApps": "测试全部应用", - "TestAllClients": "测试全部客户端", - "TestAllIndexers": "测试全部搜刮器", - "TheLatestVersionIsAlreadyInstalled": "已安装最新版的Prowlarr", - "Theme": "主题", - "ThemeHelpText": "更改应用程序UI主题,“自动”主题将使用您的操作系统主题设置明亮模式或黑暗模式。受到{0}的影响", - "Time": "时间", - "Title": "标题", - "Today": "今天", - "Tomorrow": "明天", - "Torrent": "Torrents", - "Torrents": "种子", - "TvSearch": "搜索剧集", - "Type": "类型", - "UI": "UI界面", - "UILanguage": "UI界面语言", - "UILanguageHelpText": "Prowlarr使用的UI界面语言", - "UILanguageHelpTextWarning": "浏览器需重新加载", - "UISettings": "UI设置", - "UISettingsSummary": "日期,语言及色盲选项", - "URLBase": "基本URL", - "UnableToAddANewAppProfilePleaseTryAgain": "无法添加新影片质量配置,请稍后重试。", - "UnableToAddANewApplicationPleaseTryAgain": "无法添加新通知,请稍后重试。", - "UnableToAddANewDownloadClientPleaseTryAgain": "无法添加下载客户端,请稍后重试。", - "UnableToAddANewIndexerPleaseTryAgain": "无法添加搜刮器,请稍后重试。", - "UnableToAddANewIndexerProxyPleaseTryAgain": "无法添加搜刮器,请稍后重试。", - "UnableToAddANewNotificationPleaseTryAgain": "无法添加新通知,请稍后重试。", - "UnableToLoadAppProfiles": "无法加载应用配置", - "UnableToLoadApplicationList": "123", - "UnableToLoadBackups": "无法加载备份", - "UnableToLoadDevelopmentSettings": "无法加载开发设置", - "UnableToLoadDownloadClients": "无法加载下载客户端", - "UnableToLoadGeneralSettings": "无法加载通用设置", - "UnableToLoadHistory": "无法加载历史记录", - "UnableToLoadIndexerProxies": "无法加载索引器代理", - "UnableToLoadIndexers": "无法加载搜刮器", - "UnableToLoadNotifications": "无法加载通知连接", - "UnableToLoadTags": "无法加载标签", - "UnableToLoadUISettings": "无法加载UI设置", - "UnsavedChanges": "未保存更改", - "UnselectAll": "全不选", - "UpdateAutomaticallyHelpText": "自动下载并安装更新。你还可以在“系统:更新”中安装", - "UpdateAvailable": "有新的更新可用", - "UpdateCheckStartupNotWritableMessage": "无法安装更新,因为用户“{1}”对于启动文件夹“{0}”没有写入权限。", - "UpdateCheckStartupTranslocationMessage": "无法安装更新,因为启动文件夹“{0}”在一个应用程序迁移文件夹。Cannot install update because startup folder '{0}' is in an App Translocation folder.", - "UpdateCheckUINotWritableMessage": "无法安装升级,因为用户“{1}”不可写入界面文件夹“{0}”。", - "UpdateMechanismHelpText": "使用 Prowlarr 内置的更新器或者脚本", - "UpdateScriptPathHelpText": "自定义脚本的路径,该脚本处理获取的更新包并处理更新过程的其余部分", - "Updates": "更新", - "Uptime": "运行时间", - "Url": "Url", - "UrlBaseHelpText": "对于反向代理支持,默认为空", - "UseProxy": "使用代理", - "Usenet": "Usenet", - "UserAgentProvidedByTheAppThatCalledTheAPI": "由调用API的应用程序提供的User-Agent", - "Username": "用户名", - "Version": "版本", - "View": "视图", - "VipExpiration": "VIP过期", - "Warn": "警告", - "Website": "‎网站‎", - "Wiki": "Wiki", - "Year": "年", - "Yes": "是", - "YesCancel": "是,取消", - "Yesterday": "昨天" + "About": "关于", + "AcceptConfirmationModal": "接受确认模组Accept Confirmation Modal", + "Actions": "操作", + "Add": "添加", + "AddApplication": "添加应用程序", + "AddCustomFilter": "添加自定义过滤", + "AddDownloadClient": "添加下载客户端", + "AddDownloadClientToProwlarr": "添加下载客户端允许 Prowlarr 在进行手动搜索时从 UI直接发送结果.", + "AddIndexer": "添加索引器", + "AddIndexerProxy": "添加搜刮器代理", + "AddNewIndexer": "添加新的索引器", + "AddRemoveOnly": "仅添加和删除", + "AddSyncProfile": "添加同步配置文件", + "AddToDownloadClient": "添加发布到下载客户端", + "Added": "已添加", + "AddedToDownloadClient": "发布已添加档案到客户端", + "AddingTag": "添加标签", + "Age": "年龄", + "All": "全部", + "AllIndexersHiddenDueToFilter": "由于应用了筛选器,所有索引器都被隐藏。", + "Analytics": "分析", + "AnalyticsEnabledHelpText": "将匿名使用情况和错误信息发送到Prowlarr的服务器。这包括有关您的浏览器的信息、您使用的Prowlarr WebUI页面、错误报告以及操作系统和运行时版本。我们将使用此信息来确定功能和错误修复的优先级。", + "ApiKey": "API 密钥", + "ApiKeyValidationHealthCheckMessage": "", + "AppDataDirectory": "AppData目录", + "AppDataLocationHealthCheckMessage": "更新将无法阻止在更新时删除 AppData", + "AppProfileDeleteConfirm": "您确认您想删除吗?", + "AppProfileInUse": "正在使用的应用程序配置文件", + "AppProfileSelectHelpText": "应用程序配置用于控制应用程序同步设置 RSS、自动搜索和交互式搜索设置", + "AppSettingsSummary": "配置Prowlarr与PVR程序交互方式的应用和设置", + "Application": "程序", + "ApplicationLongTermStatusCheckAllClientMessage": "由于故障超过6小时,所有程序都不可用", + "ApplicationLongTermStatusCheckSingleClientMessage": "由于故障超过6小时而无法使用的程序:{0}", + "ApplicationStatusCheckAllClientMessage": "由于故障所用应用程序都不可用", + "ApplicationStatusCheckSingleClientMessage": "由于故障应用程序不可用", + "ApplicationURL": "应用程序 URL", + "ApplicationUrlHelpText": "此应用程序的外部URL,包括http(s)://,端口和基本URL", + "Applications": "程序", + "Apply": "应用", + "ApplyTags": "应用标签", + "ApplyTagsHelpTexts1": "如何应用标签到已选择索引器", + "ApplyTagsHelpTexts2": "添加:将标签添加到现有标签列表", + "ApplyTagsHelpTexts3": "删除:移除输入的标签", + "ApplyTagsHelpTexts4": "替换:用输入的标签替换标签(不输入标签将清除所有标签)", + "Apps": "应用程序", + "AreYouSureYouWantToDeleteCategory": "您确定要删除映射类别吗?", + "AreYouSureYouWantToResetYourAPIKey": "你确认希望重置API密钥吗?", + "Artist": "艺术家", + "AudioSearch": "音频搜索", + "Auth": "认证", + "Authentication": "认证", + "AuthenticationMethodHelpText": "需要账号和密码以登录Prowlarr", + "AuthenticationRequired": "需要认证", + "AuthenticationRequiredHelpText": "更改需要身份验证的请求。除非您了解风险,否则请勿更改。", + "AuthenticationRequiredWarning": "为了防止远程访问而无需身份验证,Prowlarr现在需要启用身份验证。请配置您的身份验证方法和凭据。您可以选择从本地地址禁用身份验证。有关其他信息,请参阅FAQ。", + "Author": "作者", + "Automatic": "自动化", + "AutomaticSearch": "自动搜索", + "AverageResponseTimesMs": "平均响应时间(毫秒)", + "Backup": "备份", + "BackupFolderHelpText": "相对路径将在 Prowlarr 的 AppData 目录下", + "BackupIntervalHelpText": "自动备份时间间隔", + "BackupNow": "马上备份", + "BackupRetentionHelpText": "早于保留周期的自动备份将被自动清除", + "Backups": "备份", + "BeforeUpdate": "更新前", + "BindAddress": "绑定地址", + "BindAddressHelpText": "有效的 IPv4 地址、localhost、或以'*'代表所有接口", + "Book": "图书", + "BookSearch": "图书搜索", + "BookSearchTypes": "搜索图书类型", + "Branch": "分支", + "BranchUpdate": "更新Prowlarr的分支", + "BranchUpdateMechanism": "外部更新机制使用的分支", + "BypassProxyForLocalAddresses": "对局域网地址不使用代理", + "Cancel": "取消", + "CancelPendingTask": "您确定要取消这个挂起的任务吗?", + "Categories": "分类", + "Category": "类别", + "CertificateValidation": "验证证书", + "CertificateValidationHelpText": "改变HTTPS证书验证的严格程度", + "ChangeHasNotBeenSavedYet": "修改暂未保存", + "Clear": "清除", + "ClearHistory": "清楚历史", + "ClearHistoryMessageText": "您确定要清除Prowlarr所有的历史记录吗?", + "ClientPriority": "客户端优先级", + "CloneProfile": "复制配置", + "Close": "关闭", + "CloseCurrentModal": "关闭当前模组", + "Columns": "列", + "Component": "组件", + "Connect": "通知", + "ConnectSettings": "连接设置", + "ConnectSettingsSummary": "通知和自定义脚本", + "ConnectionLost": "连接丢失", + "ConnectionLostAutomaticMessage": "Prowlarr 将会自动重连,您也可以点击下方的重新加载。", + "ConnectionLostMessage": "Prowlarr 已与服务端断开链接,请尝试刷新来恢复使用。", + "Connections": "连接", + "CouldNotConnectSignalR": "无法连接至SignalR,不会升级UI", + "Custom": "自定义", + "CustomFilters": "自定义过滤", + "DBMigration": "数据库迁移版本", + "Database": "数据库", + "Date": "日期", + "Dates": "日期", + "Delete": "删除", + "DeleteAppProfile": "删除应用配置文件", + "DeleteApplication": "删除应用程序", + "DeleteApplicationMessageText": "您确定要删除应用程序“{0}”吗?", + "DeleteBackup": "删除备份", + "DeleteBackupMessageText": "您确定要删除备份 '{0}' 吗?", + "DeleteClientCategory": "删除下载客户端类别", + "DeleteDownloadClient": "删除下载客户端", + "DeleteDownloadClientMessageText": "您确定要删除下载客户端 '{0}' 吗?", + "DeleteIndexerProxy": "删除搜刮器代理", + "DeleteIndexerProxyMessageText": "您确定要删除列表 '{0}'?", + "DeleteNotification": "删除消息推送", + "DeleteNotificationMessageText": "您确定要删除推送 '{0}' 吗?", + "DeleteTag": "删除标签", + "DeleteTagMessageText": "您确定要删除标签 '{0}' 吗?", + "Description": "描述", + "Details": "详情", + "DevelopmentSettings": "开发设置", + "Disabled": "禁用", + "DisabledUntil": "禁用Until", + "Discord": "冲突", + "Docker": "Docker", + "Donations": "捐赠", + "DownloadClient": "下载客户端", + "DownloadClientCategory": "下载客户端类别", + "DownloadClientSettings": "下载客户端设置", + "DownloadClientStatusCheckAllClientMessage": "所有下载客户端都不可用", + "DownloadClientStatusCheckSingleClientMessage": "所有下载客户端都不可用: {0}", + "DownloadClients": "下载客户端", + "DownloadClientsSettingsSummary": "下载客户端配置以集成到 Prowlarr UI 搜索中", + "Duration": "时长", + "Edit": "编辑", + "EditIndexer": "编辑搜刮器", + "EditSyncProfile": "编辑同步配置文件", + "ElapsedTime": "运行时间", + "Enable": "启用", + "EnableAutomaticSearch": "启用自动搜索", + "EnableAutomaticSearchHelpText": "当自动搜索通过UI或Prowlarr执行时将被使用", + "EnableIndexer": "启用搜刮器", + "EnableInteractiveSearch": "启用手动搜索", + "EnableInteractiveSearchHelpText": "当手动搜索启用时使用", + "EnableRss": "启用RSS", + "EnableRssHelpText": "为搜刮器启用 RSS订阅", + "EnableSSL": "启用SSL", + "EnableSslHelpText": " 重启生效", + "Enabled": "已启用", + "EnabledRedirected": "启用, 修改", + "Encoding": "编码", + "Ended": "已完结", + "Episode": "集", + "Error": "错误", + "ErrorLoadingContents": "读取内容错误", + "EventType": "事件类型", + "Events": "事件", + "Exception": "例外", + "ExistingTag": "已有标签", + "Failed": "失败", + "FeatureRequests": "功能建议", + "Filename": "文件名", + "Files": "文件", + "Filter": "过滤", + "FilterPlaceHolder": "搜刮器搜索", + "Filters": "过滤器", + "Fixed": "已修复", + "FocusSearchBox": "聚焦搜索框", + "Folder": "文件夹", + "ForMoreInformationOnTheIndividualDownloadClients": "有关个别下载客户端的详细信息,请单击info按钮。", + "FullSync": "完全同步", + "General": "通用", + "GeneralSettings": "通用设置", + "GeneralSettingsSummary": "端口、SSL、用户名/密码、代理、分析、更新", + "Genre": "类型", + "GrabReleases": "抓取版本", + "GrabTitle": "抓取标题", + "Grabbed": "已抓取", + "Grabs": "抓取", + "Health": "健康度", + "HealthNoIssues": "您的设置没有问题", + "HiddenClickToShow": "已隐藏,点击显示", + "HideAdvanced": "隐藏高级设置", + "History": "历史记录", + "HistoryCleanup": "清理历史记录", + "HistoryCleanupDaysHelpText": "设置为0关闭自动清理", + "HistoryCleanupDaysHelpTextWarning": "回收站中的文件在超出选择的天数后会被自动清理", + "HistoryDetails": "历史详情", + "HomePage": "主页", + "Host": "主机", + "Hostname": "主机名", + "Id": "Id", + "IgnoredAddresses": "已忽略地址", + "IllRestartLater": "稍后重启", + "IncludeHealthWarningsHelpText": "包含健康度警告", + "IncludeManualGrabsHelpText": "安装手动抓取Prowlarr", + "Indexer": "搜刮器", + "IndexerAlreadySetup": "至少已经设置了一个索引器", + "IndexerAuth": "搜刮器认证", + "IndexerDetails": "‎索引器‎‎详细信息‎", + "IndexerDisabled": "索引器已被禁用", + "IndexerFailureRate": "Indexer失败率", + "IndexerFlags": "搜刮器标记", + "IndexerHealthCheckNoIndexers": "未启用任何搜刮器,Prowlarr将不会返回搜索结果", + "IndexerInfo": "索引器信息", + "IndexerLongTermStatusCheckAllClientMessage": "由于故障超过6小时,所有搜刮器均不可用", + "IndexerLongTermStatusCheckSingleClientMessage": "由于故障6小时,下列搜刮器都已不可用:{0}", + "IndexerName": "‎索引‎‎名字‎", + "IndexerNoDefCheckMessage": "索引器没有定义,将无法工作: {0}. 请删除或重新添加到Prowlarr", + "IndexerObsoleteCheckMessage": "搜刮器已过弃用或已更新:{0}。请将其删除和(或)重新添加到 Prowlarr", + "IndexerPriority": "搜刮器优先级", + "IndexerPriorityHelpText": "索引器优先级从1(最高)到50(最低),默认25。", + "IndexerProxies": "搜刮器代理", + "IndexerProxy": "搜刮器代理", + "IndexerProxyStatusCheckAllClientMessage": "所有搜刮器都因错误不可用", + "IndexerProxyStatusCheckSingleClientMessage": "搜刮器因错误不可用:{0}", + "IndexerQuery": "搜刮器查询", + "IndexerRss": "搜刮器RSS", + "IndexerSettingsSummary": "配置全局索引器设置,包括代理。", + "IndexerSite": "‎索引‎‎网站‎", + "IndexerStatusCheckAllClientMessage": "所有搜刮器都因错误不可用", + "IndexerStatusCheckSingleClientMessage": "搜刮器因错误不可用:{0}", + "IndexerTagsHelpText": "使用标签指定索引器代理, 索引器同步到哪些应用程序,或者只是为了组织索引器。未指定索引器的应用程序将不会同步。", + "IndexerVipCheckExpiredClientMessage": "索引器VIP特权已过期:{0}", + "IndexerVipCheckExpiringClientMessage": "索引器VIP特权即将过期:{0}", + "Indexers": "搜刮器", + "IndexersSelectedInterp": "已选择 {0} 个搜刮器", + "Info": "信息", + "InitialFailure": "初始化失败", + "InstanceName": "中文", + "InstanceNameHelpText": "选项卡及日志应用名称", + "InteractiveSearch": "手动搜索", + "Interval": "间隔", + "KeyboardShortcuts": "键盘快捷键", + "Label": "标签", + "Language": "语言", + "LastDuration": "上一次用时", + "LastExecution": "上一次执行", + "LastFailure": "最后一次失败", + "LastWriteTime": "最后写入时间", + "LaunchBrowserHelpText": " 启动浏览器时导航到Prowlarr 主页。", + "Level": "等级", + "Link": "链接", + "LogFiles": "日志文件", + "LogLevel": "日志等级", + "LogLevelTraceHelpTextWarning": "追踪日志只应该暂时启用", + "Logging": "日志记录中", + "Logs": "日志", + "MIA": "MIA", + "MaintenanceRelease": "维护版本:修复错误及其他改进,参见Github提交 查看更多详情", + "Manual": "手动", + "MappedCategories": "映射类别", + "MappedDrivesRunningAsService": "映射的网络驱动器在作为Windows服务运行时不可用。请参阅常见问题解答了解更多信息", + "MassEditor": "批量编辑器", + "Mechanism": "机制", + "Message": "信息", + "MinimumSeeders": "最少播种量", + "MinimumSeedersHelpText": "用于索引器抓取的应用程序所需的最小播种量", + "Mode": "模式", + "More": "更多的", + "MoreInfo": "更多信息", + "MovieIndexScrollBottom": "影片索引:滚动到底部", + "MovieIndexScrollTop": "影片索引:滚动到顶部", + "MovieSearch": "搜索电影", + "MovieSearchTypes": "‎影片‎‎搜索‎‎类型‎", + "MusicSearchTypes": "‎音乐‎‎搜索‎‎类型‎", + "Name": "名称", + "NetCore": ".NET", + "New": "新的", + "NextExecution": "接下来执行", + "No": "否", + "NoBackupsAreAvailable": "无备份可用", + "NoChange": "无修改", + "NoChanges": "无修改", + "NoLeaveIt": "不,就这样", + "NoLinks": "无链接", + "NoLogFiles": "没有日志文件", + "NoSearchResultsFound": "无搜索结果,请在下面尝试新的搜索。", + "NoTagsHaveBeenAddedYet": "未添加标签", + "NoUpdatesAreAvailable": "无可用更新", + "NotSupported": "‎不支持‎", + "Notification": "通知", + "NotificationTriggers": "通知触发器", + "NotificationTriggersHelpText": "选择触发此通知的事件", + "Notifications": "通知", + "OAuthPopupMessage": "您的浏览器已禁止弹出页面", + "Ok": "完成", + "OnApplicationUpdate": "程序更新时", + "OnApplicationUpdateHelpText": "在程序更新时", + "OnGrab": "运行中", + "OnGrabHelpText": "运行中", + "OnHealthIssue": "健康度异常", + "OnHealthIssueHelpText": "健康度异常", + "OpenBrowserOnStart": "打开浏览器时启动", + "OpenThisModal": "打开该模组", + "Options": "选项", + "PackageVersion": "Package版本", + "PageSize": "页面大小", + "PageSizeHelpText": "每页显示的项目数", + "Parameters": "参数", + "Password": "密码", + "Peers": "用户", + "PendingChangesDiscardChanges": "舍弃修改并退出", + "PendingChangesMessage": "您有未保存的修改,确定要退出本页么?", + "PendingChangesStayReview": "留下检查更改", + "Port": "端口", + "PortNumber": "端口号", + "Presets": "预设", + "Priority": "优先级", + "PriorityHelpText": "优先考虑多个下载客户端,循环查询用于具有相同优先级的客户端。", + "PrioritySettings": "优先级", + "Privacy": "隐私", + "Private": "私有", + "Protocol": "协议", + "ProwlarrSupportsAnyDownloadClient": "Prowlarr 支持以下列出的下载客户端。", + "ProwlarrSupportsAnyIndexer": "Prowlarr支持多种搜刮器,包括任何使用Newznab/Torznab标准的搜刮器(“通用Newznab”对应Usenet,“Generic Torznab”对应Torrents)。从以下搜索并选择你的搜刮器。", + "Proxies": "代理", + "Proxy": "代理", + "ProxyBypassFilterHelpText": "使用“ , ”作为分隔符,和“ *. ”作为二级域名的通配符", + "ProxyCheckBadRequestMessage": "测试代理失败,状态码: {0}", + "ProxyCheckFailedToTestMessage": "测试代理失败: {0}", + "ProxyCheckResolveIpMessage": "无法解析已设置的代理服务器主机{0}的IP地址", + "ProxyPasswordHelpText": "如果需要,您只需要输入用户名和密码,否则就让它们为空。", + "ProxyType": "代理类型", + "ProxyUsernameHelpText": "如果需要,您只需要输入用户名和密码。否则就让它们为空。", + "Public": "公开", + "Publisher": "发布者", + "Query": "查询字段", + "QueryOptions": "查询选项", + "QueryResults": "查询结果", + "Queue": "队列", + "Queued": "队列中", + "RSS": "RSS", + "RSSIsNotSupportedWithThisIndexer": "该搜刮器不支持RSS", + "RawSearchSupported": "‎支持原始‎‎搜索‎", + "ReadTheWikiForMoreInformation": "查阅Wiki获得更多信息", + "Reddit": "Reddit", + "Redirect": "重定向", + "RedirectHelpText": "重定向搜刮器的传入下载请求并直接传递抓取,而不是通过Prowlarr代理请求搜刮器", + "Refresh": "刷新", + "RefreshMovie": "刷新影片", + "ReleaseBranchCheckOfficialBranchMessage": "分支 {0} 不是合法的Prowlarr发布分支,您不会收到任何更新", + "ReleaseStatus": "发布状态", + "Reload": "重新加载", + "Remove": "移除", + "RemoveFilter": "移除过滤条件", + "RemovedFromTaskQueue": "从任务队列中移除", + "RemovingTag": "移除标签", + "RepeatSearch": "再次搜索", + "Replace": "替换", + "Reset": "重置", + "ResetAPIKey": "重置API Key", + "Restart": "重启", + "RestartNow": "马上重启", + "RestartProwlarr": "重启Prowlarr", + "RestartRequiredHelpTextWarning": "需要重新启动才能生效", + "Restore": "恢复", + "RestoreBackup": "恢复备份", + "Result": "结果", + "Retention": "保留", + "RssFeed": "RSS订阅", + "SSLCertPassword": "SSL证书密码", + "SSLCertPasswordHelpText": "pfx文件密码", + "SSLCertPath": "SSL证书路径", + "SSLCertPathHelpText": "pfx文件路径", + "SSLPort": "SSL端口", + "Save": "保存", + "SaveChanges": "保存更改", + "SaveSettings": "保存设置", + "Scheduled": "计划中", + "ScriptPath": "脚本路径", + "Search": "搜索", + "SearchCapabilities": "‎搜索‎‎能力‎", + "SearchIndexers": "搜刮器搜索", + "SearchType": "搜索类型", + "SearchTypes": "搜索类型", + "Season": "季", + "Security": "安全", + "Seeders": "种子", + "SelectAll": "选择全部", + "SelectIndexer": "选择索引器", + "SemiPrivate": "‎半私有‎", + "SendAnonymousUsageData": "发送匿名使用数据", + "SetTags": "设定标签", + "Settings": "设置", + "SettingsConsoleLogLevel": "控制台日志级别", + "SettingsEnableColorImpairedMode": "启用色障模式", + "SettingsEnableColorImpairedModeHelpText": "改变样式,以允许有颜色障碍的用户更好地区分颜色编码信息", + "SettingsFilterSentryEvents": "筛选分析事件", + "SettingsFilterSentryEventsHelpText": "过滤已知的用户错误事件,不让其作为分析报告发送", + "SettingsIndexerLogging": "增强型搜刮器日志", + "SettingsIndexerLoggingHelpText": "记录额外的搜刮器数据,包括响应", + "SettingsLogRotate": "日志轮替", + "SettingsLogRotateHelpText": "保存在日志文件夹中的最大日志文件数", + "SettingsLogSql": "事务日志", + "SettingsLongDateFormat": "长时间格式", + "SettingsShortDateFormat": "短日期格式", + "SettingsShowRelativeDates": "显示相对日期", + "SettingsShowRelativeDatesHelpText": "显示相对日期(今天昨天等)或绝对日期", + "SettingsSqlLoggingHelpText": "记录来自Prowlarr的所有SQL查询", + "SettingsTimeFormat": "时间格式", + "ShowAdvanced": "显示高级设置", + "ShowSearch": "显示搜索按钮", + "ShowSearchHelpText": "在选项中显示搜索框", + "ShownClickToHide": "显示高级设置,点击隐藏", + "Shutdown": "关机", + "Size": "文件大小", + "Sort": "排序", + "Source": "源", + "StartTypingOrSelectAPathBelow": "输入路径或者从下面选择", + "Started": "已开始", + "StartupDirectory": "启动目录", + "Stats": "统计数据", + "Status": "状态", + "StopSelecting": "停止选择", + "Style": "类型", + "SuggestTranslationChange": "建议翻译改变 Suggest translation change", + "SyncAppIndexers": "同步应用索引", + "SyncLevel": "同步级别", + "SyncLevelAddRemove": "仅添加和删除:当索引器从 Prowlarr 添加或删除时,它将更新与此关联的应用程序。", + "SyncLevelFull": "完全同步:将保持此应用的索引器完全同步。当在Prowlarr中所做的更改将同步到与此关联的应用程序。任何关联应用上的更改都将在下次同步时被Prowlarr覆盖。", + "SyncProfile": "同步配置文件", + "SyncProfiles": "同步配置文件", + "System": "系统", + "SystemTimeCheckMessage": "系统时间相差超过1天。在纠正时间之前,计划的任务可能无法正确运行", + "TVSearchTypes": "‎电视‎‎搜索‎‎类型‎", + "TableOptions": "表格选项", + "TableOptionsColumnsMessage": "选择显示哪些列并排序", + "TagCannotBeDeletedWhileInUse": "使用中无法删除", + "TagIsNotUsedAndCanBeDeleted": "标签未被使用,可删除", + "Tags": "标签", + "TagsHelpText": "适用于至少有一个匹配标签的索引器", + "TagsSettingsSummary": "显示全部标签和标签使用情况,可删除未使用的标签", + "Tasks": "任务", + "Test": "测试", + "TestAll": "测试全部", + "TestAllApps": "测试全部应用", + "TestAllClients": "测试全部客户端", + "TestAllIndexers": "测试全部搜刮器", + "TheLatestVersionIsAlreadyInstalled": "已安装最新版的Prowlarr", + "Theme": "主题", + "ThemeHelpText": "更改应用程序UI主题,“自动”主题将使用您的操作系统主题设置明亮模式或黑暗模式。受到{0}的影响", + "Time": "时间", + "Title": "标题", + "Today": "今天", + "Tomorrow": "明天", + "Torrent": "Torrents", + "Torrents": "种子", + "TvSearch": "搜索剧集", + "Type": "类型", + "UI": "UI界面", + "UILanguage": "UI界面语言", + "UILanguageHelpText": "Prowlarr使用的UI界面语言", + "UILanguageHelpTextWarning": "浏览器需重新加载", + "UISettings": "UI设置", + "UISettingsSummary": "日期,语言及色盲选项", + "URLBase": "基本URL", + "UnableToAddANewAppProfilePleaseTryAgain": "无法添加新影片质量配置,请稍后重试。", + "UnableToAddANewApplicationPleaseTryAgain": "无法添加新通知,请稍后重试。", + "UnableToAddANewDownloadClientPleaseTryAgain": "无法添加下载客户端,请稍后重试。", + "UnableToAddANewIndexerPleaseTryAgain": "无法添加搜刮器,请稍后重试。", + "UnableToAddANewIndexerProxyPleaseTryAgain": "无法添加搜刮器,请稍后重试。", + "UnableToAddANewNotificationPleaseTryAgain": "无法添加新通知,请稍后重试。", + "UnableToLoadAppProfiles": "无法加载应用配置", + "UnableToLoadApplicationList": "123", + "UnableToLoadBackups": "无法加载备份", + "UnableToLoadDevelopmentSettings": "无法加载开发设置", + "UnableToLoadDownloadClients": "无法加载下载客户端", + "UnableToLoadGeneralSettings": "无法加载通用设置", + "UnableToLoadHistory": "无法加载历史记录", + "UnableToLoadIndexerProxies": "无法加载索引器代理", + "UnableToLoadIndexers": "无法加载搜刮器", + "UnableToLoadNotifications": "无法加载通知连接", + "UnableToLoadTags": "无法加载标签", + "UnableToLoadUISettings": "无法加载UI设置", + "UnsavedChanges": "未保存更改", + "UnselectAll": "全不选", + "UpdateAutomaticallyHelpText": "自动下载并安装更新。你还可以在“系统:更新”中安装", + "UpdateAvailable": "有新的更新可用", + "UpdateCheckStartupNotWritableMessage": "无法安装更新,因为用户“{1}”对于启动文件夹“{0}”没有写入权限。", + "UpdateCheckStartupTranslocationMessage": "无法安装更新,因为启动文件夹“{0}”在一个应用程序迁移文件夹。Cannot install update because startup folder '{0}' is in an App Translocation folder.", + "UpdateCheckUINotWritableMessage": "无法安装升级,因为用户“{1}”不可写入界面文件夹“{0}”。", + "UpdateMechanismHelpText": "使用 Prowlarr 内置的更新器或者脚本", + "UpdateScriptPathHelpText": "自定义脚本的路径,该脚本处理获取的更新包并处理更新过程的其余部分", + "Updates": "更新", + "Uptime": "运行时间", + "Url": "Url", + "UrlBaseHelpText": "对于反向代理支持,默认为空", + "UseProxy": "使用代理", + "Usenet": "Usenet", + "UserAgentProvidedByTheAppThatCalledTheAPI": "由调用API的应用程序提供的User-Agent", + "Username": "用户名", + "Version": "版本", + "View": "视图", + "VipExpiration": "VIP过期", + "Warn": "警告", + "Website": "‎网站‎", + "Wiki": "Wiki", + "Year": "年", + "Yes": "是", + "YesCancel": "是,取消", + "Yesterday": "昨天", + "Album": "" } From d5daf6791c8b26ee0e1bb15dfe85a727347abed7 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 2 Jun 2023 15:13:01 +0300 Subject: [PATCH 0035/1128] New: Support for seed configuration in DownloadService --- .../Download/Clients/Aria2/Aria2.cs | 6 +- .../Clients/Blackhole/TorrentBlackhole.cs | 6 +- .../Download/Clients/Deluge/Deluge.cs | 6 +- .../DownloadStation/TorrentDownloadStation.cs | 6 +- .../Download/Clients/Flood/Flood.cs | 6 +- .../FreeboxDownload/TorrentFreeboxDownload.cs | 6 +- .../Download/Clients/Hadouken/Hadouken.cs | 6 +- .../Clients/QBittorrent/QBittorrent.cs | 6 +- .../Clients/Transmission/TransmissionBase.cs | 6 +- .../Download/Clients/rTorrent/RTorrent.cs | 6 +- .../Download/Clients/uTorrent/UTorrent.cs | 6 +- src/NzbDrone.Core/Download/DownloadService.cs | 6 +- .../Download/TorrentClientBase.cs | 10 +- .../Indexers/SeedConfigProvider.cs | 91 +++++++++++++++++++ src/NzbDrone.Core/Parser/Model/TorrentInfo.cs | 3 + 15 files changed, 137 insertions(+), 39 deletions(-) create mode 100644 src/NzbDrone.Core/Indexers/SeedConfigProvider.cs diff --git a/src/NzbDrone.Core/Download/Clients/Aria2/Aria2.cs b/src/NzbDrone.Core/Download/Clients/Aria2/Aria2.cs index 902985371..cdf869695 100644 --- a/src/NzbDrone.Core/Download/Clients/Aria2/Aria2.cs +++ b/src/NzbDrone.Core/Download/Clients/Aria2/Aria2.cs @@ -31,7 +31,7 @@ namespace NzbDrone.Core.Download.Clients.Aria2 _proxy = proxy; } - protected override string AddFromMagnetLink(ReleaseInfo release, string hash, string magnetLink) + protected override string AddFromMagnetLink(TorrentInfo release, string hash, string magnetLink) { var gid = _proxy.AddUri(Settings, magnetLink); @@ -50,7 +50,7 @@ namespace NzbDrone.Core.Download.Clients.Aria2 return hash; } - protected override string AddFromTorrentFile(ReleaseInfo release, string hash, string filename, byte[] fileContent) + protected override string AddFromTorrentFile(TorrentInfo release, string hash, string filename, byte[] fileContent) { var gid = _proxy.AddTorrent(Settings, fileContent); @@ -120,7 +120,7 @@ namespace NzbDrone.Core.Download.Clients.Aria2 return null; } - protected override string AddFromTorrentLink(ReleaseInfo release, string hash, string torrentLink) + protected override string AddFromTorrentLink(TorrentInfo release, string hash, string torrentLink) { var gid = _proxy.AddUri(Settings, torrentLink); diff --git a/src/NzbDrone.Core/Download/Clients/Blackhole/TorrentBlackhole.cs b/src/NzbDrone.Core/Download/Clients/Blackhole/TorrentBlackhole.cs index 5f6dd7a9d..5505233e5 100644 --- a/src/NzbDrone.Core/Download/Clients/Blackhole/TorrentBlackhole.cs +++ b/src/NzbDrone.Core/Download/Clients/Blackhole/TorrentBlackhole.cs @@ -25,12 +25,12 @@ namespace NzbDrone.Core.Download.Clients.Blackhole { } - protected override string AddFromTorrentLink(ReleaseInfo release, string hash, string torrentLink) + protected override string AddFromTorrentLink(TorrentInfo release, string hash, string torrentLink) { throw new NotImplementedException("Blackhole does not support redirected indexers."); } - protected override string AddFromMagnetLink(ReleaseInfo release, string hash, string magnetLink) + protected override string AddFromMagnetLink(TorrentInfo release, string hash, string magnetLink) { if (!Settings.SaveMagnetFiles) { @@ -54,7 +54,7 @@ namespace NzbDrone.Core.Download.Clients.Blackhole return null; } - protected override string AddFromTorrentFile(ReleaseInfo release, string hash, string filename, byte[] fileContent) + protected override string AddFromTorrentFile(TorrentInfo release, string hash, string filename, byte[] fileContent) { var title = release.Title; diff --git a/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs b/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs index 9ea829e6a..caa83fbdc 100644 --- a/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs +++ b/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs @@ -29,7 +29,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge _proxy = proxy; } - protected override string AddFromMagnetLink(ReleaseInfo release, string hash, string magnetLink) + protected override string AddFromMagnetLink(TorrentInfo release, string hash, string magnetLink) { var actualHash = _proxy.AddTorrentFromMagnet(magnetLink, Settings); @@ -53,7 +53,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge return actualHash.ToUpper(); } - protected override string AddFromTorrentFile(ReleaseInfo release, string hash, string filename, byte[] fileContent) + protected override string AddFromTorrentFile(TorrentInfo release, string hash, string filename, byte[] fileContent) { var actualHash = _proxy.AddTorrentFromFile(filename, fileContent, Settings); @@ -211,7 +211,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge return null; } - protected override string AddFromTorrentLink(ReleaseInfo release, string hash, string torrentLink) + protected override string AddFromTorrentLink(TorrentInfo release, string hash, string torrentLink) { throw new NotImplementedException(); } diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs index ebe52b722..b2d89a0c7 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs @@ -53,7 +53,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation return _dsTaskProxy.GetTasks(Settings).Where(v => v.Type.ToLower() == DownloadStationTaskType.BT.ToString().ToLower()); } - protected override string AddFromMagnetLink(ReleaseInfo release, string hash, string magnetLink) + protected override string AddFromMagnetLink(TorrentInfo release, string hash, string magnetLink) { var hashedSerialNumber = _serialNumberProvider.GetSerialNumber(Settings); @@ -72,7 +72,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation throw new DownloadClientException("Failed to add magnet task to Download Station"); } - protected override string AddFromTorrentFile(ReleaseInfo release, string hash, string filename, byte[] fileContent) + protected override string AddFromTorrentFile(TorrentInfo release, string hash, string filename, byte[] fileContent) { var hashedSerialNumber = _serialNumberProvider.GetSerialNumber(Settings); @@ -315,7 +315,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation return null; } - protected override string AddFromTorrentLink(ReleaseInfo release, string hash, string torrentLink) + protected override string AddFromTorrentLink(TorrentInfo release, string hash, string torrentLink) { throw new NotImplementedException(); } diff --git a/src/NzbDrone.Core/Download/Clients/Flood/Flood.cs b/src/NzbDrone.Core/Download/Clients/Flood/Flood.cs index f292eaf53..5506edeac 100644 --- a/src/NzbDrone.Core/Download/Clients/Flood/Flood.cs +++ b/src/NzbDrone.Core/Download/Clients/Flood/Flood.cs @@ -63,14 +63,14 @@ namespace NzbDrone.Core.Download.Clients.Flood public override bool SupportsCategories => true; public override ProviderMessage Message => new ProviderMessage("Prowlarr is unable to remove torrents that have finished seeding when using Flood", ProviderMessageType.Warning); - protected override string AddFromTorrentFile(ReleaseInfo release, string hash, string filename, byte[] fileContent) + protected override string AddFromTorrentFile(TorrentInfo release, string hash, string filename, byte[] fileContent) { _proxy.AddTorrentByFile(Convert.ToBase64String(fileContent), HandleTags(release, Settings, GetCategoryForRelease(release)), Settings); return hash; } - protected override string AddFromMagnetLink(ReleaseInfo release, string hash, string magnetLink) + protected override string AddFromMagnetLink(TorrentInfo release, string hash, string magnetLink) { _proxy.AddTorrentByUrl(magnetLink, HandleTags(release, Settings, GetCategoryForRelease(release)), Settings); @@ -93,7 +93,7 @@ namespace NzbDrone.Core.Download.Clients.Flood } } - protected override string AddFromTorrentLink(ReleaseInfo release, string hash, string torrentLink) + protected override string AddFromTorrentLink(TorrentInfo release, string hash, string torrentLink) { throw new NotImplementedException(); } diff --git a/src/NzbDrone.Core/Download/Clients/FreeboxDownload/TorrentFreeboxDownload.cs b/src/NzbDrone.Core/Download/Clients/FreeboxDownload/TorrentFreeboxDownload.cs index a7f3ace5e..13c992443 100644 --- a/src/NzbDrone.Core/Download/Clients/FreeboxDownload/TorrentFreeboxDownload.cs +++ b/src/NzbDrone.Core/Download/Clients/FreeboxDownload/TorrentFreeboxDownload.cs @@ -36,7 +36,7 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload return _proxy.GetTasks(Settings).Where(v => v.Type.ToLower() == FreeboxDownloadTaskType.Bt.ToString().ToLower()); } - protected override string AddFromMagnetLink(ReleaseInfo release, string hash, string magnetLink) + protected override string AddFromMagnetLink(TorrentInfo release, string hash, string magnetLink) { return _proxy.AddTaskFromUrl(magnetLink, GetDownloadDirectory(release).EncodeBase64(), @@ -45,7 +45,7 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload Settings); } - protected override string AddFromTorrentFile(ReleaseInfo release, string hash, string filename, byte[] fileContent) + protected override string AddFromTorrentFile(TorrentInfo release, string hash, string filename, byte[] fileContent) { return _proxy.AddTaskFromFile(filename, fileContent, @@ -55,7 +55,7 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload Settings); } - protected override string AddFromTorrentLink(ReleaseInfo release, string hash, string torrentLink) + protected override string AddFromTorrentLink(TorrentInfo release, string hash, string torrentLink) { return _proxy.AddTaskFromUrl(torrentLink, GetDownloadDirectory(release).EncodeBase64(), diff --git a/src/NzbDrone.Core/Download/Clients/Hadouken/Hadouken.cs b/src/NzbDrone.Core/Download/Clients/Hadouken/Hadouken.cs index a5ca2e4fc..f3aa2c93b 100644 --- a/src/NzbDrone.Core/Download/Clients/Hadouken/Hadouken.cs +++ b/src/NzbDrone.Core/Download/Clients/Hadouken/Hadouken.cs @@ -40,14 +40,14 @@ namespace NzbDrone.Core.Download.Clients.Hadouken failures.AddIfNotNull(TestGetTorrents()); } - protected override string AddFromMagnetLink(ReleaseInfo release, string hash, string magnetLink) + protected override string AddFromMagnetLink(TorrentInfo release, string hash, string magnetLink) { _proxy.AddTorrentUri(Settings, magnetLink, GetCategoryForRelease(release) ?? Settings.Category); return hash.ToUpper(); } - protected override string AddFromTorrentFile(ReleaseInfo release, string hash, string filename, byte[] fileContent) + protected override string AddFromTorrentFile(TorrentInfo release, string hash, string filename, byte[] fileContent) { return _proxy.AddTorrentFile(Settings, fileContent, GetCategoryForRelease(release) ?? Settings.Category).ToUpper(); } @@ -97,7 +97,7 @@ namespace NzbDrone.Core.Download.Clients.Hadouken return null; } - protected override string AddFromTorrentLink(ReleaseInfo release, string hash, string torrentLink) + protected override string AddFromTorrentLink(TorrentInfo release, string hash, string torrentLink) { throw new NotImplementedException(); } diff --git a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs index edc9b2fd4..1cca3d3ba 100644 --- a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs +++ b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs @@ -41,7 +41,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent private IQBittorrentProxy Proxy => _proxySelector.GetProxy(Settings); private Version ProxyApiVersion => _proxySelector.GetApiVersion(Settings); - protected override string AddFromMagnetLink(ReleaseInfo release, string hash, string magnetLink) + protected override string AddFromMagnetLink(TorrentInfo release, string hash, string magnetLink) { if (!Proxy.GetConfig(Settings).DhtEnabled && !magnetLink.Contains("&tr=")) { @@ -95,7 +95,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent return hash; } - protected override string AddFromTorrentFile(ReleaseInfo release, string hash, string filename, byte[] fileContent) + protected override string AddFromTorrentFile(TorrentInfo release, string hash, string filename, byte[] fileContent) { //var setShareLimits = release.SeedConfiguration != null && (release.SeedConfiguration.Ratio.HasValue || release.SeedConfiguration.SeedTime.HasValue); //var addHasSetShareLimits = setShareLimits && ProxyApiVersion >= new Version(2, 8, 1); @@ -450,7 +450,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent torrent.SeedingTime = torrentProperties.SeedingTime; } - protected override string AddFromTorrentLink(ReleaseInfo release, string hash, string torrentLink) + protected override string AddFromTorrentLink(TorrentInfo release, string hash, string torrentLink) { throw new NotImplementedException(); } diff --git a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionBase.cs b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionBase.cs index a4e4d90ae..51af63ee9 100644 --- a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionBase.cs +++ b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionBase.cs @@ -66,7 +66,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission return false; } - protected override string AddFromMagnetLink(ReleaseInfo release, string hash, string magnetLink) + protected override string AddFromMagnetLink(TorrentInfo release, string hash, string magnetLink) { _proxy.AddTorrentFromUrl(magnetLink, GetDownloadDirectory(), Settings); @@ -79,7 +79,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission return hash; } - protected override string AddFromTorrentFile(ReleaseInfo release, string hash, string filename, byte[] fileContent) + protected override string AddFromTorrentFile(TorrentInfo release, string hash, string filename, byte[] fileContent) { _proxy.AddTorrentFromData(fileContent, GetDownloadDirectory(), Settings); @@ -92,7 +92,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission return hash; } - protected override string AddFromTorrentLink(ReleaseInfo release, string hash, string torrentLink) + protected override string AddFromTorrentLink(TorrentInfo release, string hash, string torrentLink) { throw new NotImplementedException(); } diff --git a/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs b/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs index 9f7505cfd..e4ae67767 100644 --- a/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs +++ b/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs @@ -34,7 +34,7 @@ namespace NzbDrone.Core.Download.Clients.RTorrent _rTorrentDirectoryValidator = rTorrentDirectoryValidator; } - protected override string AddFromMagnetLink(ReleaseInfo release, string hash, string magnetLink) + protected override string AddFromMagnetLink(TorrentInfo release, string hash, string magnetLink) { var priority = (RTorrentPriority)Settings.Priority; @@ -54,7 +54,7 @@ namespace NzbDrone.Core.Download.Clients.RTorrent return hash; } - protected override string AddFromTorrentFile(ReleaseInfo release, string hash, string filename, byte[] fileContent) + protected override string AddFromTorrentFile(TorrentInfo release, string hash, string filename, byte[] fileContent) { var priority = (RTorrentPriority)Settings.Priority; @@ -157,7 +157,7 @@ namespace NzbDrone.Core.Download.Clients.RTorrent return false; } - protected override string AddFromTorrentLink(ReleaseInfo release, string hash, string torrentLink) + protected override string AddFromTorrentLink(TorrentInfo release, string hash, string torrentLink) { throw new NotImplementedException(); } diff --git a/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrent.cs b/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrent.cs index 7d8da7b1c..6ab0635c5 100644 --- a/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrent.cs +++ b/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrent.cs @@ -32,7 +32,7 @@ namespace NzbDrone.Core.Download.Clients.UTorrent _torrentCache = cacheManager.GetCache(GetType(), "differentialTorrents"); } - protected override string AddFromMagnetLink(ReleaseInfo release, string hash, string magnetLink) + protected override string AddFromMagnetLink(TorrentInfo release, string hash, string magnetLink) { _proxy.AddTorrentFromUrl(magnetLink, Settings); @@ -53,7 +53,7 @@ namespace NzbDrone.Core.Download.Clients.UTorrent return hash; } - protected override string AddFromTorrentFile(ReleaseInfo release, string hash, string filename, byte[] fileContent) + protected override string AddFromTorrentFile(TorrentInfo release, string hash, string filename, byte[] fileContent) { _proxy.AddTorrentFromFile(filename, fileContent, Settings); @@ -148,7 +148,7 @@ namespace NzbDrone.Core.Download.Clients.UTorrent return null; } - protected override string AddFromTorrentLink(ReleaseInfo release, string hash, string torrentLink) + protected override string AddFromTorrentLink(TorrentInfo release, string hash, string torrentLink) { throw new NotImplementedException(); } diff --git a/src/NzbDrone.Core/Download/DownloadService.cs b/src/NzbDrone.Core/Download/DownloadService.cs index 49085b6e4..e4d10f1eb 100644 --- a/src/NzbDrone.Core/Download/DownloadService.cs +++ b/src/NzbDrone.Core/Download/DownloadService.cs @@ -29,6 +29,7 @@ namespace NzbDrone.Core.Download private readonly IIndexerStatusService _indexerStatusService; private readonly IRateLimitService _rateLimitService; private readonly IEventAggregator _eventAggregator; + private readonly ISeedConfigProvider _seedConfigProvider; private readonly Logger _logger; public DownloadService(IProvideDownloadClient downloadClientProvider, @@ -37,6 +38,7 @@ namespace NzbDrone.Core.Download IIndexerStatusService indexerStatusService, IRateLimitService rateLimitService, IEventAggregator eventAggregator, + ISeedConfigProvider seedConfigProvider, Logger logger) { _downloadClientProvider = downloadClientProvider; @@ -45,6 +47,7 @@ namespace NzbDrone.Core.Download _indexerStatusService = indexerStatusService; _rateLimitService = rateLimitService; _eventAggregator = eventAggregator; + _seedConfigProvider = seedConfigProvider; _logger = logger; } @@ -59,7 +62,8 @@ namespace NzbDrone.Core.Download } // Get the seed configuration for this release. - // remoteMovie.SeedConfiguration = _seedConfigProvider.GetSeedConfiguration(remoteMovie); + ((TorrentInfo)release).SeedConfiguration = _seedConfigProvider.GetSeedConfiguration(release); + var indexer = _indexerFactory.GetInstance(_indexerFactory.Get(release.IndexerId)); var grabEvent = new IndexerDownloadEvent(release, true, source, host, release.Title, release.DownloadUrl) diff --git a/src/NzbDrone.Core/Download/TorrentClientBase.cs b/src/NzbDrone.Core/Download/TorrentClientBase.cs index 9a5787e0a..2bcc4382e 100644 --- a/src/NzbDrone.Core/Download/TorrentClientBase.cs +++ b/src/NzbDrone.Core/Download/TorrentClientBase.cs @@ -36,9 +36,9 @@ namespace NzbDrone.Core.Download public virtual bool PreferTorrentFile => false; - protected abstract string AddFromMagnetLink(ReleaseInfo release, string hash, string magnetLink); - protected abstract string AddFromTorrentFile(ReleaseInfo release, string hash, string filename, byte[] fileContent); - protected abstract string AddFromTorrentLink(ReleaseInfo release, string hash, string torrentLink); + protected abstract string AddFromMagnetLink(TorrentInfo release, string hash, string magnetLink); + protected abstract string AddFromTorrentFile(TorrentInfo release, string hash, string filename, byte[] fileContent); + protected abstract string AddFromTorrentLink(TorrentInfo release, string hash, string torrentLink); public override async Task Download(ReleaseInfo release, bool redirect, IIndexer indexer) { @@ -142,7 +142,7 @@ namespace NzbDrone.Core.Download var filename = string.Format("{0}.torrent", StringUtil.CleanFileName(release.Title)); var hash = _torrentFileInfoReader.GetHashFromTorrentFile(torrentFile); - var actualHash = AddFromTorrentFile(release, hash, filename, torrentFile); + var actualHash = AddFromTorrentFile((TorrentInfo)release, hash, filename, torrentFile); if (actualHash.IsNotNullOrWhiteSpace() && hash != actualHash) { @@ -173,7 +173,7 @@ namespace NzbDrone.Core.Download if (hash != null) { - actualHash = AddFromMagnetLink(release, hash, magnetUrl); + actualHash = AddFromMagnetLink((TorrentInfo)release, hash, magnetUrl); } if (actualHash.IsNotNullOrWhiteSpace() && hash != actualHash) diff --git a/src/NzbDrone.Core/Indexers/SeedConfigProvider.cs b/src/NzbDrone.Core/Indexers/SeedConfigProvider.cs new file mode 100644 index 000000000..88d8e8e9a --- /dev/null +++ b/src/NzbDrone.Core/Indexers/SeedConfigProvider.cs @@ -0,0 +1,91 @@ +using System; +using NzbDrone.Common.Cache; +using NzbDrone.Core.Datastore; +using NzbDrone.Core.Download.Clients; +using NzbDrone.Core.Messaging.Events; +using NzbDrone.Core.Parser.Model; +using NzbDrone.Core.ThingiProvider.Events; + +namespace NzbDrone.Core.Indexers +{ + public interface ISeedConfigProvider + { + TorrentSeedConfiguration GetSeedConfiguration(ReleaseInfo release); + TorrentSeedConfiguration GetSeedConfiguration(int indexerId); + } + + public class SeedConfigProvider : ISeedConfigProvider, IHandle> + { + private readonly IIndexerFactory _indexerFactory; + private readonly ICached _cache; + + public SeedConfigProvider(IIndexerFactory indexerFactory, ICacheManager cacheManager) + { + _indexerFactory = indexerFactory; + _cache = cacheManager.GetRollingCache(GetType(), "criteriaByIndexer", TimeSpan.FromHours(1)); + } + + public TorrentSeedConfiguration GetSeedConfiguration(ReleaseInfo release) + { + if (release.DownloadProtocol != DownloadProtocol.Torrent) + { + return null; + } + + if (release.IndexerId == 0) + { + return null; + } + + return GetSeedConfiguration(release.IndexerId); + } + + public TorrentSeedConfiguration GetSeedConfiguration(int indexerId) + { + if (indexerId == 0) + { + return null; + } + + var seedCriteria = _cache.Get(indexerId.ToString(), () => FetchSeedCriteria(indexerId)); + + if (seedCriteria == null) + { + return null; + } + + var seedConfig = new TorrentSeedConfiguration + { + Ratio = seedCriteria.SeedRatio + }; + + var seedTime = seedCriteria.SeedTime; + if (seedTime.HasValue) + { + seedConfig.SeedTime = TimeSpan.FromMinutes(seedTime.Value); + } + + return seedConfig; + } + + private IndexerTorrentBaseSettings FetchSeedCriteria(int indexerId) + { + try + { + var indexer = _indexerFactory.Get(indexerId); + var torrentIndexerSettings = indexer.Settings as ITorrentIndexerSettings; + + return torrentIndexerSettings?.TorrentBaseSettings; + } + catch (ModelNotFoundException) + { + return null; + } + } + + public void Handle(ProviderUpdatedEvent message) + { + _cache.Clear(); + } + } +} diff --git a/src/NzbDrone.Core/Parser/Model/TorrentInfo.cs b/src/NzbDrone.Core/Parser/Model/TorrentInfo.cs index a5ae1d26e..b8081f73b 100644 --- a/src/NzbDrone.Core/Parser/Model/TorrentInfo.cs +++ b/src/NzbDrone.Core/Parser/Model/TorrentInfo.cs @@ -1,4 +1,5 @@ using System.Text; +using NzbDrone.Core.Download.Clients; namespace NzbDrone.Core.Parser.Model { @@ -13,6 +14,8 @@ namespace NzbDrone.Core.Parser.Model public double? DownloadVolumeFactor { get; set; } public double? UploadVolumeFactor { get; set; } + public TorrentSeedConfiguration SeedConfiguration { get; set; } + public static int? GetSeeders(ReleaseInfo release) { var torrentInfo = release as TorrentInfo; From ed1fb58242eb80c802b6448c652f1a3feefa6c7a Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 2 Jun 2023 15:13:32 +0300 Subject: [PATCH 0036/1128] Align QBittorrent with upstream --- .../Clients/QBittorrent/QBittorrent.cs | 75 +++++++------ .../Clients/QBittorrent/QBittorrentLabel.cs | 2 +- .../QBittorrent/QBittorrentPriority.cs | 2 +- .../QBittorrent/QBittorrentProxySelector.cs | 7 +- .../Clients/QBittorrent/QBittorrentProxyV1.cs | 34 ++++-- .../Clients/QBittorrent/QBittorrentProxyV2.cs | 104 +++++++++++------- .../QBittorrent/QBittorrentSettings.cs | 6 + 7 files changed, 140 insertions(+), 90 deletions(-) diff --git a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs index 1cca3d3ba..a2513ae06 100644 --- a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs +++ b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs @@ -48,26 +48,34 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent throw new NotSupportedException("Magnet Links without trackers not supported if DHT is disabled"); } - //var setShareLimits = release.SeedConfiguration != null && (release.SeedConfiguration.Ratio.HasValue || release.SeedConfiguration.SeedTime.HasValue); - //var addHasSetShareLimits = setShareLimits && ProxyApiVersion >= new Version(2, 8, 1); - var itemToTop = Settings.Priority == (int)QBittorrentPriority.First; + var setShareLimits = release.SeedConfiguration != null && (release.SeedConfiguration.Ratio.HasValue || release.SeedConfiguration.SeedTime.HasValue); + var addHasSetShareLimits = setShareLimits && ProxyApiVersion >= new Version(2, 8, 1); + var moveToTop = Settings.Priority == (int)QBittorrentPriority.First; var forceStart = (QBittorrentState)Settings.InitialState == QBittorrentState.ForceStart; var category = GetCategoryForRelease(release) ?? Settings.Category; - Proxy.AddTorrentFromUrl(magnetLink, null, Settings, category); + Proxy.AddTorrentFromUrl(magnetLink, addHasSetShareLimits && setShareLimits ? release.SeedConfiguration : null, Settings, category); - if (itemToTop || forceStart) + if ((!addHasSetShareLimits && setShareLimits) || moveToTop || forceStart) { if (!WaitForTorrent(hash)) { return hash; } - //if (!addHasSetShareLimits && setShareLimits) - //{ - // Proxy.SetTorrentSeedingConfiguration(hash.ToLower(), release.SeedConfiguration, Settings); - //} - if (itemToTop) + if (!addHasSetShareLimits && setShareLimits) + { + try + { + Proxy.SetTorrentSeedingConfiguration(hash.ToLower(), release.SeedConfiguration, Settings); + } + catch (Exception ex) + { + _logger.Warn(ex, "Failed to set the torrent seed criteria for {0}.", hash); + } + } + + if (moveToTop) { try { @@ -97,26 +105,34 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent protected override string AddFromTorrentFile(TorrentInfo release, string hash, string filename, byte[] fileContent) { - //var setShareLimits = release.SeedConfiguration != null && (release.SeedConfiguration.Ratio.HasValue || release.SeedConfiguration.SeedTime.HasValue); - //var addHasSetShareLimits = setShareLimits && ProxyApiVersion >= new Version(2, 8, 1); - var itemToTop = Settings.Priority == (int)QBittorrentPriority.First; + var setShareLimits = release.SeedConfiguration != null && (release.SeedConfiguration.Ratio.HasValue || release.SeedConfiguration.SeedTime.HasValue); + var addHasSetShareLimits = setShareLimits && ProxyApiVersion >= new Version(2, 8, 1); + var moveToTop = Settings.Priority == (int)QBittorrentPriority.First; var forceStart = (QBittorrentState)Settings.InitialState == QBittorrentState.ForceStart; var category = GetCategoryForRelease(release) ?? Settings.Category; - Proxy.AddTorrentFromFile(filename, fileContent, null, Settings, category); + Proxy.AddTorrentFromFile(filename, fileContent, addHasSetShareLimits ? release.SeedConfiguration : null, Settings, category); - if (itemToTop || forceStart) + if ((!addHasSetShareLimits && setShareLimits) || moveToTop || forceStart) { if (!WaitForTorrent(hash)) { return hash; } - //if (!addHasSetShareLimits && setShareLimits) - //{ - // Proxy.SetTorrentSeedingConfiguration(hash.ToLower(), release.SeedConfiguration, Settings); - //} - if (itemToTop) + if (!addHasSetShareLimits && setShareLimits) + { + try + { + Proxy.SetTorrentSeedingConfiguration(hash.ToLower(), release.SeedConfiguration, Settings); + } + catch (Exception ex) + { + _logger.Warn(ex, "Failed to set the torrent seed criteria for {0}.", hash); + } + } + + if (moveToTop) { try { @@ -146,14 +162,16 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent protected bool WaitForTorrent(string hash) { - var count = 5; + var count = 10; while (count != 0) { try { - Proxy.GetTorrentProperties(hash.ToLower(), Settings); - return true; + if (Proxy.IsTorrentLoaded(hash.ToLower(), Settings)) + { + return true; + } } catch { @@ -235,9 +253,9 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent _logger.Error(ex, "Unable to test qBittorrent"); return new NzbDroneValidationFailure("Host", "Unable to connect to qBittorrent") - { - DetailedDescription = ex.Message - }; + { + DetailedDescription = ex.Message + }; } return null; @@ -297,11 +315,6 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent { var recentPriorityDefault = Settings.Priority == (int)QBittorrentPriority.Last; - if (recentPriorityDefault) - { - return null; - } - try { var config = Proxy.GetConfig(Settings); diff --git a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentLabel.cs b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentLabel.cs index 224a079e9..8980502fe 100644 --- a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentLabel.cs +++ b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentLabel.cs @@ -1,4 +1,4 @@ -namespace NzbDrone.Core.Download.Clients.QBittorrent +namespace NzbDrone.Core.Download.Clients.QBittorrent { public class QBittorrentLabel { diff --git a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentPriority.cs b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentPriority.cs index 7374fc312..5455fd8f6 100644 --- a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentPriority.cs +++ b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentPriority.cs @@ -1,4 +1,4 @@ -namespace NzbDrone.Core.Download.Clients.QBittorrent +namespace NzbDrone.Core.Download.Clients.QBittorrent { public enum QBittorrentPriority { diff --git a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentProxySelector.cs b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentProxySelector.cs index 2460b3239..14bee89fc 100644 --- a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentProxySelector.cs +++ b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentProxySelector.cs @@ -1,11 +1,8 @@ using System; using System.Collections.Generic; - using NLog; using NzbDrone.Common.Cache; -using NzbDrone.Common.Http; - namespace NzbDrone.Core.Download.Clients.QBittorrent { public interface IQBittorrentProxy @@ -15,6 +12,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent string GetVersion(QBittorrentSettings settings); QBittorrentPreferences GetConfig(QBittorrentSettings settings); List GetTorrents(QBittorrentSettings settings); + bool IsTorrentLoaded(string hash, QBittorrentSettings settings); QBittorrentTorrentProperties GetTorrentProperties(string hash, QBittorrentSettings settings); List GetTorrentFiles(string hash, QBittorrentSettings settings); @@ -40,7 +38,6 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent public class QBittorrentProxySelector : IQBittorrentProxySelector { - private readonly IHttpClient _httpClient; private readonly ICached> _proxyCache; private readonly Logger _logger; @@ -49,11 +46,9 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent public QBittorrentProxySelector(QBittorrentProxyV1 proxyV1, QBittorrentProxyV2 proxyV2, - IHttpClient httpClient, ICacheManager cacheManager, Logger logger) { - _httpClient = httpClient; _proxyCache = cacheManager.GetCache>(GetType()); _logger = logger; diff --git a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentProxyV1.cs b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentProxyV1.cs index 8bf6c1878..cdf161c7f 100644 --- a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentProxyV1.cs +++ b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentProxyV1.cs @@ -97,6 +97,23 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent return response; } + public bool IsTorrentLoaded(string hash, QBittorrentSettings settings) + { + var request = BuildRequest(settings).Resource($"/query/propertiesGeneral/{hash}"); + request.LogHttpError = false; + + try + { + ProcessRequest(request, settings); + + return true; + } + catch + { + return false; + } + } + public QBittorrentTorrentProperties GetTorrentProperties(string hash, QBittorrentSettings settings) { var request = BuildRequest(settings).Resource($"/query/propertiesGeneral/{hash}"); @@ -295,15 +312,14 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent var request = requestBuilder.Build(); request.LogResponseContent = true; + request.SuppressHttpErrorStatusCodes = new[] { HttpStatusCode.Forbidden }; HttpResponse response; try { response = _httpClient.Execute(request); - } - catch (HttpException ex) - { - if (ex.Response.StatusCode == HttpStatusCode.Forbidden) + + if (response.StatusCode == HttpStatusCode.Forbidden) { _logger.Debug("Authentication required, logging in."); @@ -313,10 +329,10 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent response = _httpClient.Execute(request); } - else - { - throw new DownloadClientException("Failed to connect to qBittorrent, check your settings.", ex); - } + } + catch (HttpException ex) + { + throw new DownloadClientException("Failed to connect to qBittorrent, check your settings.", ex); } catch (WebException ex) { @@ -367,9 +383,9 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent throw new DownloadClientUnavailableException("Failed to connect to qBittorrent, please check your settings.", ex); } - // returns "Fails." on bad login if (response.Content != "Ok.") { + // returns "Fails." on bad login _logger.Debug("qbitTorrent authentication failed."); throw new DownloadClientAuthenticationException("Failed to authenticate with qBittorrent."); } diff --git a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentProxyV2.cs b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentProxyV2.cs index 12a29c401..5e967d095 100644 --- a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentProxyV2.cs +++ b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentProxyV2.cs @@ -106,6 +106,24 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent return response; } + public bool IsTorrentLoaded(string hash, QBittorrentSettings settings) + { + var request = BuildRequest(settings).Resource("/api/v2/torrents/properties") + .AddQueryParam("hash", hash); + request.LogHttpError = false; + + try + { + ProcessRequest(request, settings); + + return true; + } + catch + { + return false; + } + } + public QBittorrentTorrentProperties GetTorrentProperties(string hash, QBittorrentSettings settings) { var request = BuildRequest(settings).Resource("/api/v2/torrents/properties") @@ -129,24 +147,12 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent var request = BuildRequest(settings).Resource("/api/v2/torrents/add") .Post() .AddFormParameter("urls", torrentUrl); - if (category.IsNotNullOrWhiteSpace()) - { - request.AddFormParameter("category", category); - } - // Note: ForceStart is handled by separate api call - if ((QBittorrentState)settings.InitialState == QBittorrentState.Start) - { - request.AddFormParameter("paused", false); - } - else if ((QBittorrentState)settings.InitialState == QBittorrentState.Pause) - { - request.AddFormParameter("paused", true); - } + AddTorrentDownloadFormParameters(request, settings, category); if (seedConfiguration != null) { - AddTorrentSeedingFormParameters(request, seedConfiguration, settings); + AddTorrentSeedingFormParameters(request, seedConfiguration); } var result = ProcessRequest(request, settings); @@ -164,24 +170,11 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent .Post() .AddFormUpload("torrents", fileName, fileContent); - if (category.IsNotNullOrWhiteSpace()) - { - request.AddFormParameter("category", category); - } - - // Note: ForceStart is handled by separate api call - if ((QBittorrentState)settings.InitialState == QBittorrentState.Start) - { - request.AddFormParameter("paused", false); - } - else if ((QBittorrentState)settings.InitialState == QBittorrentState.Pause) - { - request.AddFormParameter("paused", true); - } + AddTorrentDownloadFormParameters(request, settings, category); if (seedConfiguration != null) { - AddTorrentSeedingFormParameters(request, seedConfiguration, settings); + AddTorrentSeedingFormParameters(request, seedConfiguration); } var result = ProcessRequest(request, settings); @@ -230,29 +223,57 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent return Json.Deserialize>(ProcessRequest(request, settings)); } - private void AddTorrentSeedingFormParameters(HttpRequestBuilder request, TorrentSeedConfiguration seedConfiguration, QBittorrentSettings settings) + private void AddTorrentSeedingFormParameters(HttpRequestBuilder request, TorrentSeedConfiguration seedConfiguration, bool always = false) { var ratioLimit = seedConfiguration.Ratio.HasValue ? seedConfiguration.Ratio : -2; var seedingTimeLimit = seedConfiguration.SeedTime.HasValue ? (long)seedConfiguration.SeedTime.Value.TotalMinutes : -2; - if (ratioLimit != -2) + if (ratioLimit != -2 || always) { request.AddFormParameter("ratioLimit", ratioLimit); } - if (seedingTimeLimit != -2) + if (seedingTimeLimit != -2 || always) { request.AddFormParameter("seedingTimeLimit", seedingTimeLimit); } } + private void AddTorrentDownloadFormParameters(HttpRequestBuilder request, QBittorrentSettings settings, string category) + { + if (category.IsNotNullOrWhiteSpace()) + { + request.AddFormParameter("category", category); + } + + // Note: ForceStart is handled by separate api call + if ((QBittorrentState)settings.InitialState == QBittorrentState.Start) + { + request.AddFormParameter("paused", false); + } + else if ((QBittorrentState)settings.InitialState == QBittorrentState.Pause) + { + request.AddFormParameter("paused", true); + } + + if (settings.SequentialOrder) + { + request.AddFormParameter("sequentialDownload", true); + } + + if (settings.FirstAndLast) + { + request.AddFormParameter("firstLastPiecePrio", true); + } + } + public void SetTorrentSeedingConfiguration(string hash, TorrentSeedConfiguration seedConfiguration, QBittorrentSettings settings) { var request = BuildRequest(settings).Resource("/api/v2/torrents/setShareLimits") .Post() .AddFormParameter("hashes", hash); - AddTorrentSeedingFormParameters(request, seedConfiguration, settings); + AddTorrentSeedingFormParameters(request, seedConfiguration, true); try { @@ -341,15 +362,14 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent var request = requestBuilder.Build(); request.LogResponseContent = true; + request.SuppressHttpErrorStatusCodes = new[] { HttpStatusCode.Forbidden }; HttpResponse response; try { response = _httpClient.Execute(request); - } - catch (HttpException ex) - { - if (ex.Response.StatusCode == HttpStatusCode.Forbidden) + + if (response.StatusCode == HttpStatusCode.Forbidden) { _logger.Debug("Authentication required, logging in."); @@ -359,10 +379,10 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent response = _httpClient.Execute(request); } - else - { - throw new DownloadClientException("Failed to connect to qBittorrent, check your settings.", ex); - } + } + catch (HttpException ex) + { + throw new DownloadClientException("Failed to connect to qBittorrent, check your settings.", ex); } catch (WebException ex) { @@ -418,9 +438,9 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent throw new DownloadClientUnavailableException("Failed to connect to qBittorrent, please check your settings.", ex); } - // returns "Fails." on bad login if (response.Content != "Ok.") { + // returns "Fails." on bad login _logger.Debug("qbitTorrent authentication failed."); throw new DownloadClientAuthenticationException("Failed to authenticate with qBittorrent."); } diff --git a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentSettings.cs b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentSettings.cs index d0c46c0c5..4427472ae 100644 --- a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentSettings.cs +++ b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentSettings.cs @@ -56,6 +56,12 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent [FieldDefinition(8, Label = "Initial State", Type = FieldType.Select, SelectOptions = typeof(QBittorrentState), HelpText = "Initial state for torrents added to qBittorrent")] public int InitialState { get; set; } + [FieldDefinition(9, Label = "Sequential Order", Type = FieldType.Checkbox, HelpText = "Download in sequential order (qBittorrent 4.1.0+)")] + public bool SequentialOrder { get; set; } + + [FieldDefinition(10, Label = "First and Last First", Type = FieldType.Checkbox, HelpText = "Download first and last pieces first (qBittorrent 4.1.0+)")] + public bool FirstAndLast { get; set; } + public NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); From da75519524948d5a43e54389ef285c5a60863331 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 5 Jun 2023 17:22:30 +0300 Subject: [PATCH 0037/1128] Fixed: (Deluge) Set seed limits in client --- src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs | 12 ++++++++---- .../Download/Clients/Deluge/DelugeException.cs | 2 +- .../Download/Clients/Deluge/DelugeProxy.cs | 4 ++-- .../Download/Clients/Deluge/DelugeTorrentStatus.cs | 4 ++-- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs b/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs index caa83fbdc..8f862525b 100644 --- a/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs +++ b/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs @@ -38,8 +38,10 @@ namespace NzbDrone.Core.Download.Clients.Deluge throw new DownloadClientException("Deluge failed to add magnet " + magnetLink); } - // _proxy.SetTorrentSeedingConfiguration(actualHash, remoteMovie.SeedConfiguration, Settings); + _proxy.SetTorrentSeedingConfiguration(actualHash, release.SeedConfiguration, Settings); + var category = GetCategoryForRelease(release) ?? Settings.Category; + if (category.IsNotNullOrWhiteSpace()) { _proxy.SetTorrentLabel(actualHash, category, Settings); @@ -62,8 +64,10 @@ namespace NzbDrone.Core.Download.Clients.Deluge throw new DownloadClientException("Deluge failed to add torrent " + filename); } - // _proxy.SetTorrentSeedingConfiguration(actualHash, release.SeedConfiguration, Settings); + _proxy.SetTorrentSeedingConfiguration(actualHash, release.SeedConfiguration, Settings); + var category = GetCategoryForRelease(release) ?? Settings.Category; + if (category.IsNotNullOrWhiteSpace()) { _proxy.SetTorrentLabel(actualHash, category, Settings); @@ -117,12 +121,12 @@ namespace NzbDrone.Core.Download.Clients.Deluge case WebExceptionStatus.ConnectionClosed: return new NzbDroneValidationFailure("UseSsl", "Verify SSL settings") { - DetailedDescription = "Please verify your SSL configuration on both Deluge and NzbDrone." + DetailedDescription = "Please verify your SSL configuration on both Deluge and Prowlarr." }; case WebExceptionStatus.SecureChannelFailure: return new NzbDroneValidationFailure("UseSsl", "Unable to connect through SSL") { - DetailedDescription = "Drone is unable to connect to Deluge using SSL. This problem could be computer related. Please try to configure both drone and Deluge to not use SSL." + DetailedDescription = "Prowlarr is unable to connect to Deluge using SSL. This problem could be computer related. Please try to configure both Prowlarr and Deluge to not use SSL." }; default: return new NzbDroneValidationFailure(string.Empty, "Unknown exception: " + ex.Message); diff --git a/src/NzbDrone.Core/Download/Clients/Deluge/DelugeException.cs b/src/NzbDrone.Core/Download/Clients/Deluge/DelugeException.cs index 45df09c8c..fb6ca2a8a 100644 --- a/src/NzbDrone.Core/Download/Clients/Deluge/DelugeException.cs +++ b/src/NzbDrone.Core/Download/Clients/Deluge/DelugeException.cs @@ -1,4 +1,4 @@ -namespace NzbDrone.Core.Download.Clients.Deluge +namespace NzbDrone.Core.Download.Clients.Deluge { public class DelugeException : DownloadClientException { diff --git a/src/NzbDrone.Core/Download/Clients/Deluge/DelugeProxy.cs b/src/NzbDrone.Core/Download/Clients/Deluge/DelugeProxy.cs index 77b3d1b3d..7639ad7df 100644 --- a/src/NzbDrone.Core/Download/Clients/Deluge/DelugeProxy.cs +++ b/src/NzbDrone.Core/Download/Clients/Deluge/DelugeProxy.cs @@ -82,7 +82,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge var filter = new Dictionary(); // TODO: get_torrents_status returns the files as well, which starts to cause deluge timeouts when you get enough season packs. - //var response = ProcessRequest>(settings, "core.get_torrents_status", filter, new String[0]); + // var response = ProcessRequest>(settings, "core.get_torrents_status", filter, new String[0]); var response = ProcessRequest(settings, "web.update_ui", RequiredProperties, filter); return GetTorrents(response); @@ -93,7 +93,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge var filter = new Dictionary(); filter.Add("label", label); - //var response = ProcessRequest>(settings, "core.get_torrents_status", filter, new String[0]); + // var response = ProcessRequest>(settings, "core.get_torrents_status", filter, new String[0]); var response = ProcessRequest(settings, "web.update_ui", RequiredProperties, filter); return GetTorrents(response); diff --git a/src/NzbDrone.Core/Download/Clients/Deluge/DelugeTorrentStatus.cs b/src/NzbDrone.Core/Download/Clients/Deluge/DelugeTorrentStatus.cs index e9f5a6a70..52114f241 100644 --- a/src/NzbDrone.Core/Download/Clients/Deluge/DelugeTorrentStatus.cs +++ b/src/NzbDrone.Core/Download/Clients/Deluge/DelugeTorrentStatus.cs @@ -1,6 +1,6 @@ -namespace NzbDrone.Core.Download.Clients.Deluge +namespace NzbDrone.Core.Download.Clients.Deluge { - internal class DelugeTorrentStatus + public class DelugeTorrentStatus { public const string Paused = "Paused"; public const string Queued = "Queued"; From 65adf30f5983cb52a42475db202fcb84f1cd6e9a Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 5 Jun 2023 17:36:20 +0300 Subject: [PATCH 0038/1128] Fixed: (UTorrent) Set seed limits in client --- .../Download/Clients/uTorrent/UTorrent.cs | 19 ++++++++----------- .../Clients/uTorrent/UTorrentTorrent.cs | 2 +- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrent.cs b/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrent.cs index 6ab0635c5..2f4206ffb 100644 --- a/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrent.cs +++ b/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrent.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Net; using FluentValidation.Results; using NLog; -using NzbDrone.Common.Cache; using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; using NzbDrone.Common.Http; @@ -16,10 +15,8 @@ namespace NzbDrone.Core.Download.Clients.UTorrent public class UTorrent : TorrentClientBase { private readonly IUTorrentProxy _proxy; - private readonly ICached _torrentCache; public UTorrent(IUTorrentProxy proxy, - ICacheManager cacheManager, ITorrentFileInfoReader torrentFileInfoReader, IHttpClient httpClient, IConfigService configService, @@ -28,17 +25,16 @@ namespace NzbDrone.Core.Download.Clients.UTorrent : base(torrentFileInfoReader, httpClient, configService, diskProvider, logger) { _proxy = proxy; - - _torrentCache = cacheManager.GetCache(GetType(), "differentialTorrents"); } protected override string AddFromMagnetLink(TorrentInfo release, string hash, string magnetLink) { _proxy.AddTorrentFromUrl(magnetLink, Settings); + _proxy.SetTorrentSeedingConfiguration(hash, release.SeedConfiguration, Settings); - //_proxy.SetTorrentSeedingConfiguration(hash, release.SeedConfiguration, Settings); var category = GetCategoryForRelease(release) ?? Settings.Category; - if (GetCategoryForRelease(release).IsNotNullOrWhiteSpace()) + + if (category.IsNotNullOrWhiteSpace()) { _proxy.SetTorrentLabel(hash, category, Settings); } @@ -56,9 +52,10 @@ namespace NzbDrone.Core.Download.Clients.UTorrent protected override string AddFromTorrentFile(TorrentInfo release, string hash, string filename, byte[] fileContent) { _proxy.AddTorrentFromFile(filename, fileContent, Settings); + _proxy.SetTorrentSeedingConfiguration(hash, release.SeedConfiguration, Settings); - //_proxy.SetTorrentSeedingConfiguration(hash, release.SeedConfiguration, Settings); var category = GetCategoryForRelease(release) ?? Settings.Category; + if (category.IsNotNullOrWhiteSpace()) { _proxy.SetTorrentLabel(hash, category, Settings); @@ -125,9 +122,9 @@ namespace NzbDrone.Core.Download.Clients.UTorrent _logger.Error(ex, "Failed to test uTorrent"); return new NzbDroneValidationFailure("Host", "Unable to connect to uTorrent") - { - DetailedDescription = ex.Message - }; + { + DetailedDescription = ex.Message + }; } return null; diff --git a/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrentTorrent.cs b/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrentTorrent.cs index 027b138e0..35fec74de 100644 --- a/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrentTorrent.cs +++ b/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrentTorrent.cs @@ -39,7 +39,7 @@ namespace NzbDrone.Core.Download.Clients.UTorrent public object Unknown28 { get; set; } } - internal class UTorrentTorrentJsonConverter : JsonConverter + public class UTorrentTorrentJsonConverter : JsonConverter { public override bool CanConvert(Type objectType) { From 0f31af6b89bfd12aa0b9743ef504b9c0f73cec98 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 6 Jun 2023 01:17:27 +0300 Subject: [PATCH 0039/1128] Fixed: (Cardigann) Allow empty inputs for login.method `get` --- .../Definitions/Cardigann/CardigannRequestGenerator.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannRequestGenerator.cs b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannRequestGenerator.cs index a9087d1ce..0076a02f7 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannRequestGenerator.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannRequestGenerator.cs @@ -501,10 +501,14 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann else if (login.Method == "get") { var queryCollection = new NameValueCollection(); - foreach (var input in login.Inputs) + + if (login.Inputs != null && login.Inputs.Any()) { - var value = ApplyGoTemplateText(input.Value); - queryCollection.Add(input.Key, value); + foreach (var input in login.Inputs) + { + var value = ApplyGoTemplateText(input.Value); + queryCollection.Add(input.Key, value); + } } var loginUrl = ResolvePath(login.Path + "?" + queryCollection.GetQueryString()).ToString(); From 88e793d76dc5d2631c61bb3a529c31e0caa6a0e1 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 6 Jun 2023 05:59:17 +0300 Subject: [PATCH 0040/1128] Fixed: (Cardigann) Allow empty inputs for login.method `form`/`post` --- .../Cardigann/CardigannRequestGenerator.cs | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannRequestGenerator.cs b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannRequestGenerator.cs index 0076a02f7..814799752 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannRequestGenerator.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannRequestGenerator.cs @@ -203,10 +203,13 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann { var pairs = new Dictionary(); - foreach (var input in login.Inputs) + if (login.Inputs != null && login.Inputs.Any()) { - var value = ApplyGoTemplateText(input.Value); - pairs.Add(input.Key, value); + foreach (var input in login.Inputs) + { + var value = ApplyGoTemplateText(input.Value); + pairs.Add(input.Key, value); + } } var loginUrl = ResolvePath(login.Path).ToString(); @@ -302,22 +305,25 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann pairs[name] = value; } - foreach (var input in login.Inputs) + if (login.Inputs != null && login.Inputs.Any()) { - var value = ApplyGoTemplateText(input.Value); - var inputKey = input.Key; - if (login.Selectors) + foreach (var input in login.Inputs) { - var inputElement = landingResultDocument.QuerySelector(input.Key); - if (inputElement == null) + var value = ApplyGoTemplateText(input.Value); + var inputKey = input.Key; + if (login.Selectors) { - throw new CardigannConfigException(_definition, string.Format("Login failed: No input found using selector {0}", input.Key)); + var inputElement = landingResultDocument.QuerySelector(input.Key); + if (inputElement == null) + { + throw new CardigannConfigException(_definition, string.Format("Login failed: No input found using selector {0}", input.Key)); + } + + inputKey = inputElement.GetAttribute("name"); } - inputKey = inputElement.GetAttribute("name"); + pairs[inputKey] = value; } - - pairs[inputKey] = value; } // selector inputs From 98db8f8bf8eb9fd469c7716604d3084b8abd6378 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 6 Jun 2023 19:56:35 +0300 Subject: [PATCH 0041/1128] Add default definitions for download clients --- src/NzbDrone.Core/Download/DownloadClientBase.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/Download/DownloadClientBase.cs b/src/NzbDrone.Core/Download/DownloadClientBase.cs index 7659c32a6..89fce8f3c 100644 --- a/src/NzbDrone.Core/Download/DownloadClientBase.cs +++ b/src/NzbDrone.Core/Download/DownloadClientBase.cs @@ -27,7 +27,20 @@ namespace NzbDrone.Core.Download public virtual ProviderMessage Message => null; - public IEnumerable DefaultDefinitions => new List(); + public IEnumerable DefaultDefinitions + { + get + { + var config = (IProviderConfig)new TSettings(); + + yield return new DownloadClientDefinition + { + Name = GetType().Name, + Implementation = GetType().Name, + Settings = config + }; + } + } public ProviderDefinition Definition { get; set; } From 7c5409383e4f68c6a6fc8f6f25090b052f3607a9 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 6 Jun 2023 20:10:01 +0300 Subject: [PATCH 0042/1128] Fixed: (NzbIndex) Use UsenetIndexerBase --- src/NzbDrone.Core/Indexers/Definitions/NzbIndex.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/NzbIndex.cs b/src/NzbDrone.Core/Indexers/Definitions/NzbIndex.cs index 3cc9b2360..45df8e91a 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/NzbIndex.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/NzbIndex.cs @@ -10,6 +10,7 @@ using NzbDrone.Common.Extensions; using NzbDrone.Common.Http; using NzbDrone.Core.Annotations; using NzbDrone.Core.Configuration; +using NzbDrone.Core.Download; using NzbDrone.Core.Indexers.Exceptions; using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.Messaging.Events; @@ -19,7 +20,7 @@ using NzbDrone.Core.Validation; namespace NzbDrone.Core.Indexers.Definitions { - public class NzbIndex : TorrentIndexerBase + public class NzbIndex : UsenetIndexerBase { public override string Name => "NZBIndex"; public override string[] IndexerUrls => new[] { "https://nzbindex.com/" }; @@ -29,8 +30,8 @@ namespace NzbDrone.Core.Indexers.Definitions public override bool SupportsPagination => true; public override IndexerCapabilities Capabilities => SetCapabilities(); - public NzbIndex(IIndexerHttpClient httpClient, IEventAggregator eventAggregator, IIndexerStatusService indexerStatusService, IConfigService configService, Logger logger) - : base(httpClient, eventAggregator, indexerStatusService, configService, logger) + public NzbIndex(IIndexerHttpClient httpClient, IEventAggregator eventAggregator, IIndexerStatusService indexerStatusService, IConfigService configService, IValidateNzbs nzbValidationService, Logger logger) + : base(httpClient, eventAggregator, indexerStatusService, configService, nzbValidationService, logger) { } From f7d7cca98298052c78b561de5dce38f2d3a61c7f Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 6 Jun 2023 21:52:44 +0300 Subject: [PATCH 0043/1128] Add extension only for known protocols in ReleaseResource --- src/Prowlarr.Api.V1/Search/ReleaseResource.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Prowlarr.Api.V1/Search/ReleaseResource.cs b/src/Prowlarr.Api.V1/Search/ReleaseResource.cs index e589d40cf..04d899483 100644 --- a/src/Prowlarr.Api.V1/Search/ReleaseResource.cs +++ b/src/Prowlarr.Api.V1/Search/ReleaseResource.cs @@ -43,14 +43,14 @@ namespace Prowlarr.Api.V1.Search { get { - var extension = "torrent"; - - if (Protocol == DownloadProtocol.Usenet) + var extension = Protocol switch { - extension = "nzb"; - } + DownloadProtocol.Torrent => ".torrent", + DownloadProtocol.Usenet => ".nzb", + _ => string.Empty + }; - return $"{Title}.{extension}"; + return $"{Title}{extension}"; } } } From f5b57db75371aec6d46536748b8f799cbd6b4064 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 6 Jun 2023 23:00:12 +0300 Subject: [PATCH 0044/1128] Check if release still exists in cache when grabbing release --- src/Prowlarr.Api.V1/Search/SearchController.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Prowlarr.Api.V1/Search/SearchController.cs b/src/Prowlarr.Api.V1/Search/SearchController.cs index bf380eacc..8ffd81a71 100644 --- a/src/Prowlarr.Api.V1/Search/SearchController.cs +++ b/src/Prowlarr.Api.V1/Search/SearchController.cs @@ -57,6 +57,13 @@ namespace Prowlarr.Api.V1.Search var releaseInfo = _remoteReleaseCache.Find(GetCacheKey(release)); + if (releaseInfo == null) + { + _logger.Debug("Couldn't find requested release in cache, cache timeout probably expired."); + + throw new NzbDroneClientException(HttpStatusCode.NotFound, "Couldn't find requested release in cache, try searching again"); + } + var indexerDef = _indexerFactory.Get(release.IndexerId); var source = Request.GetSource(); var host = Request.GetHostName(); From d05128ca3376c26dbb3d9ec884efba5339786dd2 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 6 Jun 2023 23:12:52 +0300 Subject: [PATCH 0045/1128] Map seed configuration on release only when it's not null Fixes #1720 --- src/NzbDrone.Core/Download/DownloadService.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/Download/DownloadService.cs b/src/NzbDrone.Core/Download/DownloadService.cs index e4d10f1eb..0f28b3511 100644 --- a/src/NzbDrone.Core/Download/DownloadService.cs +++ b/src/NzbDrone.Core/Download/DownloadService.cs @@ -62,7 +62,12 @@ namespace NzbDrone.Core.Download } // Get the seed configuration for this release. - ((TorrentInfo)release).SeedConfiguration = _seedConfigProvider.GetSeedConfiguration(release); + var seedConfiguration = _seedConfigProvider.GetSeedConfiguration(release); + + if (seedConfiguration != null) + { + ((TorrentInfo)release).SeedConfiguration = _seedConfigProvider.GetSeedConfiguration(release); + } var indexer = _indexerFactory.GetInstance(_indexerFactory.Get(release.IndexerId)); From 596d3297da31db849182886fc193f34b24a4dcdd Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 7 Jun 2023 01:32:03 +0300 Subject: [PATCH 0046/1128] Move seed configuration logic to TorrentClientBase --- .../Download/Clients/Aria2/Aria2.cs | 6 ++-- .../Clients/Blackhole/TorrentBlackhole.cs | 6 ++-- .../Download/Clients/Deluge/Deluge.cs | 6 ++-- .../DownloadStation/TorrentDownloadStation.cs | 6 ++-- .../Download/Clients/Flood/Flood.cs | 6 ++-- .../FreeboxDownload/TorrentFreeboxDownload.cs | 6 ++-- .../Download/Clients/Hadouken/Hadouken.cs | 6 ++-- .../Clients/QBittorrent/QBittorrent.cs | 6 ++-- .../Clients/Transmission/Transmission.cs | 6 ++-- .../Clients/Transmission/TransmissionBase.cs | 6 ++-- .../Download/Clients/Vuze/Vuze.cs | 6 ++-- .../Download/Clients/rTorrent/RTorrent.cs | 6 ++-- .../Download/Clients/uTorrent/UTorrent.cs | 6 ++-- src/NzbDrone.Core/Download/DownloadService.cs | 11 ------- .../Download/TorrentClientBase.cs | 31 +++++++++++-------- 15 files changed, 57 insertions(+), 63 deletions(-) diff --git a/src/NzbDrone.Core/Download/Clients/Aria2/Aria2.cs b/src/NzbDrone.Core/Download/Clients/Aria2/Aria2.cs index cdf869695..ae076c14b 100644 --- a/src/NzbDrone.Core/Download/Clients/Aria2/Aria2.cs +++ b/src/NzbDrone.Core/Download/Clients/Aria2/Aria2.cs @@ -5,8 +5,8 @@ using FluentValidation.Results; using NLog; using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; -using NzbDrone.Common.Http; using NzbDrone.Core.Configuration; +using NzbDrone.Core.Indexers; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Validation; @@ -22,11 +22,11 @@ namespace NzbDrone.Core.Download.Clients.Aria2 public Aria2(IAria2Proxy proxy, ITorrentFileInfoReader torrentFileInfoReader, - IHttpClient httpClient, + ISeedConfigProvider seedConfigProvider, IConfigService configService, IDiskProvider diskProvider, Logger logger) - : base(torrentFileInfoReader, httpClient, configService, diskProvider, logger) + : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, logger) { _proxy = proxy; } diff --git a/src/NzbDrone.Core/Download/Clients/Blackhole/TorrentBlackhole.cs b/src/NzbDrone.Core/Download/Clients/Blackhole/TorrentBlackhole.cs index 5505233e5..f8fd44e97 100644 --- a/src/NzbDrone.Core/Download/Clients/Blackhole/TorrentBlackhole.cs +++ b/src/NzbDrone.Core/Download/Clients/Blackhole/TorrentBlackhole.cs @@ -6,8 +6,8 @@ using FluentValidation.Results; using NLog; using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; -using NzbDrone.Common.Http; using NzbDrone.Core.Configuration; +using NzbDrone.Core.Indexers; using NzbDrone.Core.Parser.Model; namespace NzbDrone.Core.Download.Clients.Blackhole @@ -17,11 +17,11 @@ namespace NzbDrone.Core.Download.Clients.Blackhole public override bool PreferTorrentFile => true; public TorrentBlackhole(ITorrentFileInfoReader torrentFileInfoReader, - IHttpClient httpClient, + ISeedConfigProvider seedConfigProvider, IConfigService configService, IDiskProvider diskProvider, Logger logger) - : base(torrentFileInfoReader, httpClient, configService, diskProvider, logger) + : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, logger) { } diff --git a/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs b/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs index 8f862525b..ca63ba0e7 100644 --- a/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs +++ b/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs @@ -7,8 +7,8 @@ using FluentValidation.Results; using NLog; using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; -using NzbDrone.Common.Http; using NzbDrone.Core.Configuration; +using NzbDrone.Core.Indexers; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Validation; @@ -20,11 +20,11 @@ namespace NzbDrone.Core.Download.Clients.Deluge public Deluge(IDelugeProxy proxy, ITorrentFileInfoReader torrentFileInfoReader, - IHttpClient httpClient, + ISeedConfigProvider seedConfigProvider, IConfigService configService, IDiskProvider diskProvider, Logger logger) - : base(torrentFileInfoReader, httpClient, configService, diskProvider, logger) + : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, logger) { _proxy = proxy; } diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs index b2d89a0c7..09db5a136 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs @@ -7,9 +7,9 @@ using FluentValidation.Results; using NLog; using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; -using NzbDrone.Common.Http; using NzbDrone.Core.Configuration; using NzbDrone.Core.Download.Clients.DownloadStation.Proxies; +using NzbDrone.Core.Indexers; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; @@ -30,11 +30,11 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation IDownloadStationInfoProxy dsInfoProxy, IDownloadStationTaskProxy dsTaskProxy, ITorrentFileInfoReader torrentFileInfoReader, - IHttpClient httpClient, + ISeedConfigProvider seedConfigProvider, IConfigService configService, IDiskProvider diskProvider, Logger logger) - : base(torrentFileInfoReader, httpClient, configService, diskProvider, logger) + : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, logger) { _dsInfoProxy = dsInfoProxy; _dsTaskProxy = dsTaskProxy; diff --git a/src/NzbDrone.Core/Download/Clients/Flood/Flood.cs b/src/NzbDrone.Core/Download/Clients/Flood/Flood.cs index 5506edeac..73c6de8a2 100644 --- a/src/NzbDrone.Core/Download/Clients/Flood/Flood.cs +++ b/src/NzbDrone.Core/Download/Clients/Flood/Flood.cs @@ -4,9 +4,9 @@ using System.Linq; using FluentValidation.Results; using NLog; using NzbDrone.Common.Disk; -using NzbDrone.Common.Http; using NzbDrone.Core.Configuration; using NzbDrone.Core.Download.Clients.Flood.Models; +using NzbDrone.Core.Indexers; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.ThingiProvider; @@ -18,11 +18,11 @@ namespace NzbDrone.Core.Download.Clients.Flood public Flood(IFloodProxy proxy, ITorrentFileInfoReader torrentFileInfoReader, - IHttpClient httpClient, + ISeedConfigProvider seedConfigProvider, IConfigService configService, IDiskProvider diskProvider, Logger logger) - : base(torrentFileInfoReader, httpClient, configService, diskProvider, logger) + : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, logger) { _proxy = proxy; } diff --git a/src/NzbDrone.Core/Download/Clients/FreeboxDownload/TorrentFreeboxDownload.cs b/src/NzbDrone.Core/Download/Clients/FreeboxDownload/TorrentFreeboxDownload.cs index 13c992443..8f23e93b6 100644 --- a/src/NzbDrone.Core/Download/Clients/FreeboxDownload/TorrentFreeboxDownload.cs +++ b/src/NzbDrone.Core/Download/Clients/FreeboxDownload/TorrentFreeboxDownload.cs @@ -5,9 +5,9 @@ using FluentValidation.Results; using NLog; using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; -using NzbDrone.Common.Http; using NzbDrone.Core.Configuration; using NzbDrone.Core.Download.Clients.FreeboxDownload.Responses; +using NzbDrone.Core.Indexers; using NzbDrone.Core.Parser.Model; namespace NzbDrone.Core.Download.Clients.FreeboxDownload @@ -18,11 +18,11 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload public TorrentFreeboxDownload(IFreeboxDownloadProxy proxy, ITorrentFileInfoReader torrentFileInfoReader, - IHttpClient httpClient, + ISeedConfigProvider seedConfigProvider, IConfigService configService, IDiskProvider diskProvider, Logger logger) - : base(torrentFileInfoReader, httpClient, configService, diskProvider, logger) + : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, logger) { _proxy = proxy; } diff --git a/src/NzbDrone.Core/Download/Clients/Hadouken/Hadouken.cs b/src/NzbDrone.Core/Download/Clients/Hadouken/Hadouken.cs index f3aa2c93b..b5aa1eb06 100644 --- a/src/NzbDrone.Core/Download/Clients/Hadouken/Hadouken.cs +++ b/src/NzbDrone.Core/Download/Clients/Hadouken/Hadouken.cs @@ -4,8 +4,8 @@ using FluentValidation.Results; using NLog; using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; -using NzbDrone.Common.Http; using NzbDrone.Core.Configuration; +using NzbDrone.Core.Indexers; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Validation; @@ -17,11 +17,11 @@ namespace NzbDrone.Core.Download.Clients.Hadouken public Hadouken(IHadoukenProxy proxy, ITorrentFileInfoReader torrentFileInfoReader, - IHttpClient httpClient, + ISeedConfigProvider seedConfigProvider, IConfigService configService, IDiskProvider diskProvider, Logger logger) - : base(torrentFileInfoReader, httpClient, configService, diskProvider, logger) + : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, logger) { _proxy = proxy; } diff --git a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs index a2513ae06..6555ce6cc 100644 --- a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs +++ b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs @@ -6,8 +6,8 @@ using NLog; using NzbDrone.Common.Cache; using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; -using NzbDrone.Common.Http; using NzbDrone.Core.Configuration; +using NzbDrone.Core.Indexers; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Validation; @@ -26,12 +26,12 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent public QBittorrent(IQBittorrentProxySelector proxySelector, ITorrentFileInfoReader torrentFileInfoReader, - IHttpClient httpClient, + ISeedConfigProvider seedConfigProvider, IConfigService configService, IDiskProvider diskProvider, ICacheManager cacheManager, Logger logger) - : base(torrentFileInfoReader, httpClient, configService, diskProvider, logger) + : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, logger) { _proxySelector = proxySelector; diff --git a/src/NzbDrone.Core/Download/Clients/Transmission/Transmission.cs b/src/NzbDrone.Core/Download/Clients/Transmission/Transmission.cs index fac544a20..a2bd2bf91 100644 --- a/src/NzbDrone.Core/Download/Clients/Transmission/Transmission.cs +++ b/src/NzbDrone.Core/Download/Clients/Transmission/Transmission.cs @@ -3,8 +3,8 @@ using System.Text.RegularExpressions; using FluentValidation.Results; using NLog; using NzbDrone.Common.Disk; -using NzbDrone.Common.Http; using NzbDrone.Core.Configuration; +using NzbDrone.Core.Indexers; namespace NzbDrone.Core.Download.Clients.Transmission { @@ -12,11 +12,11 @@ namespace NzbDrone.Core.Download.Clients.Transmission { public Transmission(ITransmissionProxy proxy, ITorrentFileInfoReader torrentFileInfoReader, - IHttpClient httpClient, + ISeedConfigProvider seedConfigProvider, IConfigService configService, IDiskProvider diskProvider, Logger logger) - : base(proxy, torrentFileInfoReader, httpClient, configService, diskProvider, logger) + : base(proxy, torrentFileInfoReader, seedConfigProvider, configService, diskProvider, logger) { } diff --git a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionBase.cs b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionBase.cs index 51af63ee9..5ed105d77 100644 --- a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionBase.cs +++ b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionBase.cs @@ -4,8 +4,8 @@ using FluentValidation.Results; using NLog; using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; -using NzbDrone.Common.Http; using NzbDrone.Core.Configuration; +using NzbDrone.Core.Indexers; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Validation; @@ -17,11 +17,11 @@ namespace NzbDrone.Core.Download.Clients.Transmission public TransmissionBase(ITransmissionProxy proxy, ITorrentFileInfoReader torrentFileInfoReader, - IHttpClient httpClient, + ISeedConfigProvider seedConfigProvider, IConfigService configService, IDiskProvider diskProvider, Logger logger) - : base(torrentFileInfoReader, httpClient, configService, diskProvider, logger) + : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, logger) { _proxy = proxy; } diff --git a/src/NzbDrone.Core/Download/Clients/Vuze/Vuze.cs b/src/NzbDrone.Core/Download/Clients/Vuze/Vuze.cs index 66e4dedf1..107b299cb 100644 --- a/src/NzbDrone.Core/Download/Clients/Vuze/Vuze.cs +++ b/src/NzbDrone.Core/Download/Clients/Vuze/Vuze.cs @@ -1,9 +1,9 @@ using FluentValidation.Results; using NLog; using NzbDrone.Common.Disk; -using NzbDrone.Common.Http; using NzbDrone.Core.Configuration; using NzbDrone.Core.Download.Clients.Transmission; +using NzbDrone.Core.Indexers; namespace NzbDrone.Core.Download.Clients.Vuze { @@ -13,11 +13,11 @@ namespace NzbDrone.Core.Download.Clients.Vuze public Vuze(ITransmissionProxy proxy, ITorrentFileInfoReader torrentFileInfoReader, - IHttpClient httpClient, + ISeedConfigProvider seedConfigProvider, IConfigService configService, IDiskProvider diskProvider, Logger logger) - : base(proxy, torrentFileInfoReader, httpClient, configService, diskProvider, logger) + : base(proxy, torrentFileInfoReader, seedConfigProvider, configService, diskProvider, logger) { } diff --git a/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs b/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs index e4ae67767..5218f9ebe 100644 --- a/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs +++ b/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs @@ -6,10 +6,10 @@ using FluentValidation.Results; using NLog; using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; -using NzbDrone.Common.Http; using NzbDrone.Core.Configuration; using NzbDrone.Core.Download.Clients.rTorrent; using NzbDrone.Core.Exceptions; +using NzbDrone.Core.Indexers; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; @@ -23,12 +23,12 @@ namespace NzbDrone.Core.Download.Clients.RTorrent public RTorrent(IRTorrentProxy proxy, ITorrentFileInfoReader torrentFileInfoReader, - IHttpClient httpClient, + ISeedConfigProvider seedConfigProvider, IConfigService configService, IDiskProvider diskProvider, IRTorrentDirectoryValidator rTorrentDirectoryValidator, Logger logger) - : base(torrentFileInfoReader, httpClient, configService, diskProvider, logger) + : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, 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 2f4206ffb..ef12042fb 100644 --- a/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrent.cs +++ b/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrent.cs @@ -5,8 +5,8 @@ using FluentValidation.Results; using NLog; using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; -using NzbDrone.Common.Http; using NzbDrone.Core.Configuration; +using NzbDrone.Core.Indexers; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Validation; @@ -18,11 +18,11 @@ namespace NzbDrone.Core.Download.Clients.UTorrent public UTorrent(IUTorrentProxy proxy, ITorrentFileInfoReader torrentFileInfoReader, - IHttpClient httpClient, + ISeedConfigProvider seedConfigProvider, IConfigService configService, IDiskProvider diskProvider, Logger logger) - : base(torrentFileInfoReader, httpClient, configService, diskProvider, logger) + : base(torrentFileInfoReader, seedConfigProvider, configService, diskProvider, logger) { _proxy = proxy; } diff --git a/src/NzbDrone.Core/Download/DownloadService.cs b/src/NzbDrone.Core/Download/DownloadService.cs index 0f28b3511..d0a15115e 100644 --- a/src/NzbDrone.Core/Download/DownloadService.cs +++ b/src/NzbDrone.Core/Download/DownloadService.cs @@ -29,7 +29,6 @@ namespace NzbDrone.Core.Download private readonly IIndexerStatusService _indexerStatusService; private readonly IRateLimitService _rateLimitService; private readonly IEventAggregator _eventAggregator; - private readonly ISeedConfigProvider _seedConfigProvider; private readonly Logger _logger; public DownloadService(IProvideDownloadClient downloadClientProvider, @@ -38,7 +37,6 @@ namespace NzbDrone.Core.Download IIndexerStatusService indexerStatusService, IRateLimitService rateLimitService, IEventAggregator eventAggregator, - ISeedConfigProvider seedConfigProvider, Logger logger) { _downloadClientProvider = downloadClientProvider; @@ -47,7 +45,6 @@ namespace NzbDrone.Core.Download _indexerStatusService = indexerStatusService; _rateLimitService = rateLimitService; _eventAggregator = eventAggregator; - _seedConfigProvider = seedConfigProvider; _logger = logger; } @@ -61,14 +58,6 @@ namespace NzbDrone.Core.Download throw new DownloadClientUnavailableException($"{release.DownloadProtocol} Download client isn't configured yet"); } - // Get the seed configuration for this release. - var seedConfiguration = _seedConfigProvider.GetSeedConfiguration(release); - - if (seedConfiguration != null) - { - ((TorrentInfo)release).SeedConfiguration = _seedConfigProvider.GetSeedConfiguration(release); - } - var indexer = _indexerFactory.GetInstance(_indexerFactory.Get(release.IndexerId)); var grabEvent = new IndexerDownloadEvent(release, true, source, host, release.Title, release.DownloadUrl) diff --git a/src/NzbDrone.Core/Download/TorrentClientBase.cs b/src/NzbDrone.Core/Download/TorrentClientBase.cs index 2bcc4382e..d9d7f7133 100644 --- a/src/NzbDrone.Core/Download/TorrentClientBase.cs +++ b/src/NzbDrone.Core/Download/TorrentClientBase.cs @@ -5,7 +5,6 @@ using MonoTorrent; using NLog; using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; -using NzbDrone.Common.Http; using NzbDrone.Core.Configuration; using NzbDrone.Core.Exceptions; using NzbDrone.Core.Indexers; @@ -18,18 +17,18 @@ namespace NzbDrone.Core.Download public abstract class TorrentClientBase : DownloadClientBase where TSettings : IProviderConfig, new() { - protected readonly IHttpClient _httpClient; - protected readonly ITorrentFileInfoReader _torrentFileInfoReader; + private readonly ITorrentFileInfoReader _torrentFileInfoReader; + private readonly ISeedConfigProvider _seedConfigProvider; protected TorrentClientBase(ITorrentFileInfoReader torrentFileInfoReader, - IHttpClient httpClient, + ISeedConfigProvider seedConfigProvider, IConfigService configService, IDiskProvider diskProvider, Logger logger) : base(configService, diskProvider, logger) { - _httpClient = httpClient; _torrentFileInfoReader = torrentFileInfoReader; + _seedConfigProvider = seedConfigProvider; } public override DownloadProtocol Protocol => DownloadProtocol.Torrent; @@ -44,6 +43,12 @@ namespace NzbDrone.Core.Download { var torrentInfo = release as TorrentInfo; + if (torrentInfo != null) + { + // Get the seed configuration for this release. + torrentInfo.SeedConfiguration = _seedConfigProvider.GetSeedConfiguration(release); + } + string magnetUrl = null; string torrentUrl = null; @@ -67,7 +72,7 @@ namespace NzbDrone.Core.Download { try { - return await DownloadFromWebUrl(release, indexer, torrentUrl); + return await DownloadFromWebUrl(torrentInfo, indexer, torrentUrl); } catch (Exception ex) { @@ -84,7 +89,7 @@ namespace NzbDrone.Core.Download { try { - return DownloadFromMagnetUrl(release, magnetUrl); + return DownloadFromMagnetUrl(torrentInfo, magnetUrl); } catch (NotSupportedException ex) { @@ -98,7 +103,7 @@ namespace NzbDrone.Core.Download { try { - return DownloadFromMagnetUrl(release, magnetUrl); + return DownloadFromMagnetUrl(torrentInfo, magnetUrl); } catch (NotSupportedException ex) { @@ -113,14 +118,14 @@ namespace NzbDrone.Core.Download if (torrentUrl.IsNotNullOrWhiteSpace()) { - return await DownloadFromWebUrl(release, indexer, torrentUrl); + return await DownloadFromWebUrl(torrentInfo, indexer, torrentUrl); } } return null; } - private async Task DownloadFromWebUrl(ReleaseInfo release, IIndexer indexer, string torrentUrl) + private async Task DownloadFromWebUrl(TorrentInfo release, IIndexer indexer, string torrentUrl) { byte[] torrentFile = null; @@ -142,7 +147,7 @@ namespace NzbDrone.Core.Download var filename = string.Format("{0}.torrent", StringUtil.CleanFileName(release.Title)); var hash = _torrentFileInfoReader.GetHashFromTorrentFile(torrentFile); - var actualHash = AddFromTorrentFile((TorrentInfo)release, hash, filename, torrentFile); + var actualHash = AddFromTorrentFile(release, hash, filename, torrentFile); if (actualHash.IsNotNullOrWhiteSpace() && hash != actualHash) { @@ -155,7 +160,7 @@ namespace NzbDrone.Core.Download return actualHash; } - private string DownloadFromMagnetUrl(ReleaseInfo release, string magnetUrl) + private string DownloadFromMagnetUrl(TorrentInfo release, string magnetUrl) { string hash = null; string actualHash = null; @@ -173,7 +178,7 @@ namespace NzbDrone.Core.Download if (hash != null) { - actualHash = AddFromMagnetLink((TorrentInfo)release, hash, magnetUrl); + actualHash = AddFromMagnetLink(release, hash, magnetUrl); } if (actualHash.IsNotNullOrWhiteSpace() && hash != actualHash) From 455b76c45c233debc92a9cdc66cefa729f23f87f Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 20 May 2023 01:36:25 +0300 Subject: [PATCH 0047/1128] New: Add TorrentRssIndexer Co-authored-by: ilike2burnthing <59480337+ilike2burnthing@users.noreply.github.com> --- .../TorrentRss/TorrentRssIndexer.cs | 92 ++++++ .../TorrentRssIndexerParserSettings.cs | 12 + .../TorrentRssIndexerRequestGenerator.cs | 63 ++++ .../TorrentRss/TorrentRssIndexerSettings.cs | 51 +++ .../TorrentRss/TorrentRssParserFactory.cs | 65 ++++ .../TorrentRss/TorrentRssSettingsDetector.cs | 305 ++++++++++++++++++ src/NzbDrone.Core/Indexers/IndexerFactory.cs | 5 +- src/NzbDrone.Core/Indexers/RssParser.cs | 40 +-- .../Indexers/TorrentRssParser.cs | 78 ++++- 9 files changed, 682 insertions(+), 29 deletions(-) create mode 100644 src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexer.cs create mode 100644 src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexerParserSettings.cs create mode 100644 src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexerRequestGenerator.cs create mode 100644 src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexerSettings.cs create mode 100644 src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssParserFactory.cs create mode 100644 src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssSettingsDetector.cs diff --git a/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexer.cs b/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexer.cs new file mode 100644 index 000000000..a9ccb4f32 --- /dev/null +++ b/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexer.cs @@ -0,0 +1,92 @@ +using System.Collections.Generic; +using NLog; +using NzbDrone.Core.Configuration; +using NzbDrone.Core.Messaging.Events; +using NzbDrone.Core.ThingiProvider; + +namespace NzbDrone.Core.Indexers.Definitions.TorrentRss +{ + public class TorrentRssIndexer : TorrentIndexerBase + { + private readonly ITorrentRssParserFactory _torrentRssParserFactory; + + public override string Name => "Torrent RSS Feed"; + public override string[] IndexerUrls => new[] { "" }; + public override string Description => "Generic RSS Feed containing torrents"; + public override DownloadProtocol Protocol => DownloadProtocol.Torrent; + public override IndexerPrivacy Privacy => IndexerPrivacy.Public; + public override int PageSize => 0; + public override IndexerCapabilities Capabilities => SetCapabilities(); + + public TorrentRssIndexer(IIndexerHttpClient httpClient, IEventAggregator eventAggregator, IIndexerStatusService indexerStatusService, IConfigService configService, Logger logger, ITorrentRssParserFactory torrentRssParserFactory) + : base(httpClient, eventAggregator, indexerStatusService, configService, logger) + { + _torrentRssParserFactory = torrentRssParserFactory; + } + + public override IIndexerRequestGenerator GetRequestGenerator() + { + return new TorrentRssIndexerRequestGenerator { Settings = Settings }; + } + + public override IParseIndexerResponse GetParser() + { + return _torrentRssParserFactory.GetParser(Settings); + } + + public override IEnumerable DefaultDefinitions + { + get + { + yield return GetDefinition("showRSS", "showRSS is a service that allows you to keep track of your favorite TV shows", GetSettings("https://showrss.info/other/all.rss", allowZeroSize: true, defaultReleaseSize: 512)); + yield return GetDefinition("Torrent RSS Feed", "Generic RSS Feed containing torrents", GetSettings("")); + } + } + + private IndexerDefinition GetDefinition(string name, string description, TorrentRssIndexerSettings settings) + { + return new IndexerDefinition + { + Enable = true, + Name = name, + Description = description, + Implementation = GetType().Name, + Settings = settings, + Protocol = DownloadProtocol.Torrent, + SupportsRss = SupportsRss, + SupportsSearch = SupportsSearch, + SupportsRedirect = SupportsRedirect, + SupportsPagination = SupportsPagination, + Capabilities = Capabilities + }; + } + + private TorrentRssIndexerSettings GetSettings(string url, bool? allowZeroSize = null, double? defaultReleaseSize = null) + { + var settings = new TorrentRssIndexerSettings + { + BaseUrl = url, + AllowZeroSize = allowZeroSize.GetValueOrDefault(false) + }; + + if (defaultReleaseSize.HasValue) + { + settings.DefaultReleaseSize = defaultReleaseSize; + } + + return settings; + } + + private IndexerCapabilities SetCapabilities() + { + var caps = new IndexerCapabilities + { + SearchParams = new List(), + }; + + caps.Categories.AddCategoryMapping(1, NewznabStandardCategory.Other); + + return caps; + } + } +} diff --git a/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexerParserSettings.cs b/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexerParserSettings.cs new file mode 100644 index 000000000..f72a359a0 --- /dev/null +++ b/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexerParserSettings.cs @@ -0,0 +1,12 @@ +namespace NzbDrone.Core.Indexers.Definitions.TorrentRss +{ + public class TorrentRssIndexerParserSettings + { + public bool UseEZTVFormat { get; set; } + public bool ParseSeedersInDescription { get; set; } + public bool UseEnclosureUrl { get; set; } + public bool UseEnclosureLength { get; set; } + public bool ParseSizeInDescription { get; set; } + public string SizeElementName { get; set; } + } +} diff --git a/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexerRequestGenerator.cs b/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexerRequestGenerator.cs new file mode 100644 index 000000000..715e1ecf1 --- /dev/null +++ b/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexerRequestGenerator.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using NzbDrone.Common.Extensions; +using NzbDrone.Common.Http; +using NzbDrone.Core.IndexerSearch.Definitions; + +namespace NzbDrone.Core.Indexers.Definitions.TorrentRss +{ + public class TorrentRssIndexerRequestGenerator : IIndexerRequestGenerator + { + public TorrentRssIndexerSettings Settings { get; set; } + + public virtual IndexerPageableRequestChain GetSearchRequests(MovieSearchCriteria searchCriteria) + { + return new IndexerPageableRequestChain(); + } + + public virtual IndexerPageableRequestChain GetSearchRequests(MusicSearchCriteria searchCriteria) + { + return new IndexerPageableRequestChain(); + } + + public virtual IndexerPageableRequestChain GetSearchRequests(TvSearchCriteria searchCriteria) + { + return new IndexerPageableRequestChain(); + } + + public virtual IndexerPageableRequestChain GetSearchRequests(BookSearchCriteria searchCriteria) + { + return new IndexerPageableRequestChain(); + } + + public virtual IndexerPageableRequestChain GetSearchRequests(BasicSearchCriteria searchCriteria) + { + var pageableRequests = new IndexerPageableRequestChain(); + + if (searchCriteria.IsRssSearch) + { + pageableRequests.Add(GetRssRequests()); + } + + return pageableRequests; + } + + private IEnumerable GetRssRequests() + { + var request = new IndexerRequest(Settings.BaseUrl.Trim().TrimEnd('/'), HttpAccept.Rss); + + if (Settings.Cookie.IsNotNullOrWhiteSpace()) + { + foreach (var cookie in HttpHeader.ParseCookies(Settings.Cookie)) + { + request.HttpRequest.Cookies[cookie.Key] = cookie.Value; + } + } + + yield return request; + } + + public Func> GetCookies { get; set; } + public Action, DateTime?> CookiesUpdater { get; set; } + } +} diff --git a/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexerSettings.cs b/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexerSettings.cs new file mode 100644 index 000000000..a0525135b --- /dev/null +++ b/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexerSettings.cs @@ -0,0 +1,51 @@ +using FluentValidation; +using NzbDrone.Core.Annotations; +using NzbDrone.Core.Validation; + +namespace NzbDrone.Core.Indexers.Definitions.TorrentRss +{ + public class TorrentRssIndexerSettingsValidator : AbstractValidator + { + public TorrentRssIndexerSettingsValidator() + { + RuleFor(c => c.BaseUrl).ValidRootUrl(); + + RuleFor(c => c.BaseSettings).SetValidator(new IndexerCommonSettingsValidator()); + RuleFor(c => c.TorrentBaseSettings).SetValidator(new IndexerTorrentSettingsValidator()); + } + } + + public class TorrentRssIndexerSettings : ITorrentIndexerSettings + { + private static readonly TorrentRssIndexerSettingsValidator Validator = new (); + + public TorrentRssIndexerSettings() + { + BaseUrl = string.Empty; + AllowZeroSize = false; + } + + [FieldDefinition(0, Label = "Full RSS Feed URL", HelpTextWarning = "To sync to your apps you will need to include the 8000(Other) in the Sync Categories", HelpLink = "https://wiki.servarr.com/en/prowlarr/faq#can-i-add-any-generic-torrent-rss-feed")] + public string BaseUrl { get; set; } + + [FieldDefinition(1, Label = "Cookie", HelpText = "If your site requires a login cookie to access the RSS, you'll have to retrieve it via a browser.")] + public string Cookie { get; set; } + + [FieldDefinition(2, Type = FieldType.Checkbox, Label = "Allow Zero Size", HelpText="Enabling this will allow you to use feeds that don't specify release size, but be careful, size related checks will not be performed.")] + public bool AllowZeroSize { get; set; } + + [FieldDefinition(3, Type = FieldType.Number, Label = "Default Release Size", HelpText="Add a default size for feeds with missing sizes.", Unit = "MB", Advanced = true)] + public double? DefaultReleaseSize { get; set; } + + [FieldDefinition(20)] + public IndexerBaseSettings BaseSettings { get; set; } = new (); + + [FieldDefinition(21)] + public IndexerTorrentBaseSettings TorrentBaseSettings { get; set; } = new (); + + public NzbDroneValidationResult Validate() + { + return new NzbDroneValidationResult(Validator.Validate(this)); + } + } +} diff --git a/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssParserFactory.cs b/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssParserFactory.cs new file mode 100644 index 000000000..fd11862b1 --- /dev/null +++ b/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssParserFactory.cs @@ -0,0 +1,65 @@ +using System; +using NLog; +using NzbDrone.Common.Cache; +using NzbDrone.Common.Serializer; +using NzbDrone.Core.Indexers.Exceptions; + +namespace NzbDrone.Core.Indexers.Definitions.TorrentRss +{ + public interface ITorrentRssParserFactory + { + TorrentRssParser GetParser(TorrentRssIndexerSettings settings); + } + + public class TorrentRssParserFactory : ITorrentRssParserFactory + { + protected readonly Logger _logger; + + private readonly ICached _settingsCache; + + private readonly ITorrentRssSettingsDetector _torrentRssSettingsDetector; + + public TorrentRssParserFactory(ICacheManager cacheManager, ITorrentRssSettingsDetector torrentRssSettingsDetector, Logger logger) + { + _settingsCache = cacheManager.GetCache(GetType()); + _torrentRssSettingsDetector = torrentRssSettingsDetector; + _logger = logger; + } + + public TorrentRssParser GetParser(TorrentRssIndexerSettings indexerSettings) + { + var key = indexerSettings.ToJson(); + var parserSettings = _settingsCache.Get(key, () => DetectParserSettings(indexerSettings), TimeSpan.FromDays(7)); + + if (parserSettings.UseEZTVFormat) + { + return new EzrssTorrentRssParser(); + } + + return new TorrentRssParser + { + UseGuidInfoUrl = false, + ParseSeedersInDescription = parserSettings.ParseSeedersInDescription, + + UseEnclosureUrl = parserSettings.UseEnclosureUrl, + UseEnclosureLength = parserSettings.UseEnclosureLength, + ParseSizeInDescription = parserSettings.ParseSizeInDescription, + SizeElementName = parserSettings.SizeElementName, + + DefaultReleaseSize = indexerSettings.DefaultReleaseSize + }; + } + + private TorrentRssIndexerParserSettings DetectParserSettings(TorrentRssIndexerSettings indexerSettings) + { + var settings = _torrentRssSettingsDetector.Detect(indexerSettings); + + if (settings == null) + { + throw new UnsupportedFeedException("Could not parse feed from {0}", indexerSettings.BaseUrl); + } + + return settings; + } + } +} diff --git a/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssSettingsDetector.cs b/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssSettingsDetector.cs new file mode 100644 index 000000000..919b0c338 --- /dev/null +++ b/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssSettingsDetector.cs @@ -0,0 +1,305 @@ +using System; +using System.IO; +using System.Linq; +using System.Xml; +using System.Xml.Linq; +using NLog; +using NzbDrone.Common.Extensions; +using NzbDrone.Common.Http; +using NzbDrone.Core.Indexers.Exceptions; +using NzbDrone.Core.IndexerSearch.Definitions; +using NzbDrone.Core.Parser.Model; + +namespace NzbDrone.Core.Indexers.Definitions.TorrentRss +{ + public interface ITorrentRssSettingsDetector + { + TorrentRssIndexerParserSettings Detect(TorrentRssIndexerSettings settings); + } + + public class TorrentRssSettingsDetector : ITorrentRssSettingsDetector + { + private const long ValidSizeThreshold = 2 * 1024 * 1024; + + private readonly IHttpClient _httpClient; + private readonly Logger _logger; + + public TorrentRssSettingsDetector(IHttpClient httpClient, Logger logger) + { + _httpClient = httpClient; + _logger = logger; + } + + public TorrentRssIndexerParserSettings Detect(TorrentRssIndexerSettings settings) + { + _logger.Debug("Evaluating TorrentRss feed '{0}'", settings.BaseUrl); + + try + { + var requestGenerator = new TorrentRssIndexerRequestGenerator { Settings = settings }; + var request = requestGenerator.GetSearchRequests(new BasicSearchCriteria()).GetAllTiers().First().First(); + + HttpResponse httpResponse; + + try + { + httpResponse = _httpClient.Execute(request.HttpRequest); + } + catch (Exception ex) + { + _logger.Warn(ex, "Unable to connect to indexer {0}: {1}", request.Url, ex.Message); + return null; + } + + var indexerResponse = new IndexerResponse(request, httpResponse); + + return GetParserSettings(indexerResponse, settings); + } + catch (Exception ex) + { + ex.WithData("FeedUrl", settings.BaseUrl); + throw; + } + } + + private TorrentRssIndexerParserSettings GetParserSettings(IndexerResponse response, TorrentRssIndexerSettings indexerSettings) + { + var settings = GetEzrssParserSettings(response, indexerSettings); + + if (settings != null) + { + return settings; + } + + settings = GetGenericTorrentRssParserSettings(response, indexerSettings); + + if (settings != null) + { + return settings; + } + + return null; + } + + private TorrentRssIndexerParserSettings GetEzrssParserSettings(IndexerResponse response, TorrentRssIndexerSettings indexerSettings) + { + if (!IsEZTVFeed(response)) + { + return null; + } + + _logger.Trace("Feed has Ezrss schema"); + + var parser = new EzrssTorrentRssParser(); + var releases = ParseResponse(parser, response); + + try + { + ValidateReleases(releases, indexerSettings); + ValidateReleaseSize(releases, indexerSettings); + + _logger.Debug("Feed was parseable by Ezrss Parser"); + return new TorrentRssIndexerParserSettings + { + UseEZTVFormat = true + }; + } + catch (Exception ex) + { + _logger.Trace(ex, "Feed wasn't parsable by Ezrss Parser"); + return null; + } + } + + private TorrentRssIndexerParserSettings GetGenericTorrentRssParserSettings(IndexerResponse response, TorrentRssIndexerSettings indexerSettings) + { + var parser = new TorrentRssParser + { + UseEnclosureUrl = true, + UseEnclosureLength = true, + ParseSeedersInDescription = true + }; + + var item = parser.GetItems(response).FirstOrDefault(); + if (item == null) + { + throw new UnsupportedFeedException("Empty feed, cannot check if feed is parsable."); + } + + var settings = new TorrentRssIndexerParserSettings() + { + UseEnclosureUrl = true, + UseEnclosureLength = true, + ParseSeedersInDescription = true + }; + + if (item.Element("enclosure") == null) + { + parser.UseEnclosureUrl = settings.UseEnclosureUrl = false; + } + + var releases = ParseResponse(parser, response); + ValidateReleases(releases, indexerSettings); + + if (!releases.Any(v => v.Seeders.HasValue)) + { + _logger.Trace("Feed doesn't have Seeders in Description, disabling option."); + parser.ParseSeedersInDescription = settings.ParseSeedersInDescription = false; + } + + if (!releases.Any(r => r.Size < ValidSizeThreshold)) + { + _logger.Trace("Feed has valid size in enclosure."); + return settings; + } + + parser.UseEnclosureLength = settings.UseEnclosureLength = false; + + foreach (var sizeElementName in new[] { "size", "Size" }) + { + parser.SizeElementName = settings.SizeElementName = sizeElementName; + + releases = ParseResponse(parser, response); + ValidateReleases(releases, indexerSettings); + + if (!releases.Any(r => r.Size < ValidSizeThreshold)) + { + _logger.Trace("Feed has valid size in Size element."); + return settings; + } + } + + parser.SizeElementName = settings.SizeElementName = null; + parser.ParseSizeInDescription = settings.ParseSizeInDescription = true; + + releases = ParseResponse(parser, response); + ValidateReleases(releases, indexerSettings); + + if (releases.Count(r => r.Size >= ValidSizeThreshold) > releases.Length / 2) + { + if (releases.Any(r => r.Size < ValidSizeThreshold)) + { + _logger.Debug("Feed {0} contains very small releases.", response.Request.Url); + } + + _logger.Trace("Feed has valid size in description."); + return settings; + } + + parser.ParseSizeInDescription = settings.ParseSizeInDescription = false; + + _logger.Debug("Feed doesn't have release size."); + + releases = ParseResponse(parser, response); + ValidateReleases(releases, indexerSettings); + ValidateReleaseSize(releases, indexerSettings); + + return settings; + } + + private bool IsEZTVFeed(IndexerResponse response) + { + var content = XmlCleaner.ReplaceEntities(response.Content); + content = XmlCleaner.ReplaceUnicode(content); + + using var xmlTextReader = XmlReader.Create(new StringReader(content), new XmlReaderSettings { DtdProcessing = DtdProcessing.Parse, ValidationType = ValidationType.None, IgnoreComments = true, XmlResolver = null }); + var document = XDocument.Load(xmlTextReader); + + // Check Namespace + if (document.Root == null) + { + throw new InvalidDataException("Could not parse IndexerResponse into XML."); + } + + var ns = document.Root.GetNamespaceOfPrefix("torrent"); + if (ns == "http://xmlns.ezrss.it/0.1/") + { + _logger.Trace("Identified feed as EZTV compatible by EZTV Namespace"); + return true; + } + + // Check DTD in DocType + if (document.DocumentType != null && document.DocumentType.SystemId == "http://xmlns.ezrss.it/0.1/dtd/") + { + _logger.Trace("Identified feed as EZTV compatible by EZTV DTD"); + return true; + } + + // Check namespaces + if (document.Descendants().Any(v => v.GetDefaultNamespace().NamespaceName == "http://xmlns.ezrss.it/0.1/")) + { + _logger.Trace("Identified feed as EZTV compatible by EZTV Namespace"); + return true; + } + + return false; + } + + private TorrentInfo[] ParseResponse(IParseIndexerResponse parser, IndexerResponse response) + { + try + { + var releases = parser.ParseResponse(response).Cast().ToArray(); + return releases; + } + catch (Exception ex) + { + _logger.Debug(ex, "Unable to parse indexer feed: " + ex.Message); + throw new UnsupportedFeedException("Unable to parse indexer: " + ex.Message); + } + } + + private void ValidateReleases(TorrentInfo[] releases, TorrentRssIndexerSettings indexerSettings) + { + if (releases == null || releases.Empty()) + { + throw new UnsupportedFeedException("Empty feed, cannot check if feed is parsable."); + } + + var torrentInfo = releases.First(); + + _logger.Trace("TorrentInfo: \n{0}", torrentInfo.ToString("L")); + + if (releases.Any(r => r.Title.IsNullOrWhiteSpace())) + { + throw new UnsupportedFeedException("Feed contains releases without title."); + } + + if (releases.Any(r => !IsValidDownloadUrl(r.DownloadUrl))) + { + throw new UnsupportedFeedException("Failed to find a valid download url in the feed."); + } + + var total = releases.Where(v => v.Guid != null).Select(v => v.Guid).ToArray(); + var distinct = total.Distinct().ToArray(); + + if (distinct.Length != total.Length) + { + throw new UnsupportedFeedException("Feed contains releases with same guid, rejecting malformed rss feed."); + } + } + + private void ValidateReleaseSize(TorrentInfo[] releases, TorrentRssIndexerSettings indexerSettings) + { + if (!indexerSettings.AllowZeroSize && releases.Any(r => r.Size == 0)) + { + throw new UnsupportedFeedException("Feed doesn't contain the release content size."); + } + + if (releases.Any(r => r.Size != 0 && r.Size < ValidSizeThreshold)) + { + throw new UnsupportedFeedException("Size of one or more releases lower than {0}, feed must contain release content size.", ValidSizeThreshold.SizeSuffix()); + } + } + + private static bool IsValidDownloadUrl(string url) + { + if (url.IsNullOrWhiteSpace()) + { + return false; + } + + return url.StartsWith("magnet:") || url.StartsWith("http:") || url.StartsWith("https:"); + } + } +} diff --git a/src/NzbDrone.Core/Indexers/IndexerFactory.cs b/src/NzbDrone.Core/Indexers/IndexerFactory.cs index 9bb810805..f76b0389f 100644 --- a/src/NzbDrone.Core/Indexers/IndexerFactory.cs +++ b/src/NzbDrone.Core/Indexers/IndexerFactory.cs @@ -177,9 +177,10 @@ namespace NzbDrone.Core.Indexers } var definitions = provider.DefaultDefinitions - .Where(v => v.Name != null && v.Name != nameof(Cardigann) && v.Name != nameof(Newznab.Newznab) && v.Name != nameof(Torznab.Torznab)); + .Where(v => v.Name != null && v.Name != nameof(Cardigann) && v.Name != nameof(Newznab.Newznab) && v.Name != nameof(Torznab.Torznab)) + .Cast(); - foreach (IndexerDefinition definition in definitions) + foreach (var definition in definitions) { SetProviderCharacteristics(provider, definition); yield return definition; diff --git a/src/NzbDrone.Core/Indexers/RssParser.cs b/src/NzbDrone.Core/Indexers/RssParser.cs index 6994bb626..db3231831 100644 --- a/src/NzbDrone.Core/Indexers/RssParser.cs +++ b/src/NzbDrone.Core/Indexers/RssParser.cs @@ -206,7 +206,7 @@ namespace NzbDrone.Core.Indexers if (dateString.IsNullOrWhiteSpace()) { - throw new UnsupportedFeedException("Rss feed must have a pubDate element with a valid publish date."); + throw new UnsupportedFeedException("Each item in the RSS feed must have a pubDate element with a valid publish date."); } return XElementExtensions.ParseDate(dateString); @@ -273,26 +273,26 @@ namespace NzbDrone.Core.Indexers protected virtual RssEnclosure[] GetEnclosures(XElement item) { var enclosures = item.Elements("enclosure") - .Select(v => - { - try - { - return new RssEnclosure - { - Url = v.Attribute("url").Value, - Type = v.Attribute("type").Value, - Length = (long)v.Attribute("length") - }; - } - catch (Exception e) - { - _logger.Warn(e, "Failed to get enclosure for: {0}", item.Title()); - } + .Select(v => + { + try + { + return new RssEnclosure + { + Url = v.Attribute("url")?.Value, + Type = v.Attribute("type")?.Value, + Length = v.Attribute("length")?.Value?.ParseInt64() ?? 0 + }; + } + catch (Exception e) + { + _logger.Warn(e, "Failed to get enclosure for: {0}", item.Title()); + } - return null; - }) - .Where(v => v != null) - .ToArray(); + return null; + }) + .Where(v => v != null) + .ToArray(); return enclosures; } diff --git a/src/NzbDrone.Core/Indexers/TorrentRssParser.cs b/src/NzbDrone.Core/Indexers/TorrentRssParser.cs index 5efe5fd64..4563c7ab3 100644 --- a/src/NzbDrone.Core/Indexers/TorrentRssParser.cs +++ b/src/NzbDrone.Core/Indexers/TorrentRssParser.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using System.Text.RegularExpressions; using System.Xml.Linq; using MonoTorrent; @@ -9,12 +10,30 @@ namespace NzbDrone.Core.Indexers { public class TorrentRssParser : RssParser { + // Use to sum/calculate Peers as Leechers+Seeders + public bool CalculatePeersAsSum { get; set; } + + // Use the specified element name to determine the Infohash + public string InfoHashElementName { get; set; } + // Parse various seeder/leecher/peers formats in the description element to determine number of seeders. public bool ParseSeedersInDescription { get; set; } - // Use the specified element name to determine the size + // Use the specified element name to determine the Peers + public string PeersElementName { get; set; } + + // Use the specified element name to determine the Seeds + public string SeedsElementName { get; set; } + + // Use the specified element name to determine the Size public string SizeElementName { get; set; } + // Use the specified element name to determine the Magnet link + public string MagnetElementName { get; set; } + + // Default size for when release sizes aren't available + public double? DefaultReleaseSize { get; set; } + public TorrentRssParser() { PreferredEnclosureMimeTypes = TorrentEnclosureMimeTypes; @@ -40,14 +59,28 @@ namespace NzbDrone.Core.Indexers result.InfoHash = GetInfoHash(item); result.MagnetUrl = GetMagnetUrl(item); result.Seeders = GetSeeders(item); - result.Peers = GetPeers(item); + + if (CalculatePeersAsSum) + { + result.Peers = GetPeers(item) + result.Seeders; + } + else + { + result.Peers = GetPeers(item); + } return result; } protected virtual string GetInfoHash(XElement item) { + if (InfoHashElementName.IsNotNullOrWhiteSpace()) + { + return item.FindDecendants(InfoHashElementName).FirstOrDefault().Value; + } + var magnetUrl = GetMagnetUrl(item); + if (magnetUrl.IsNotNullOrWhiteSpace()) { try @@ -64,10 +97,21 @@ namespace NzbDrone.Core.Indexers protected virtual string GetMagnetUrl(XElement item) { - var downloadUrl = GetDownloadUrl(item); - if (downloadUrl.IsNotNullOrWhiteSpace() && downloadUrl.StartsWith("magnet:")) + if (MagnetElementName.IsNotNullOrWhiteSpace()) { - return downloadUrl; + var magnetURL = item.FindDecendants(MagnetElementName).FirstOrDefault().Value; + if (magnetURL.IsNotNullOrWhiteSpace() && magnetURL.StartsWith("magnet:")) + { + return magnetURL; + } + } + else + { + var downloadUrl = GetDownloadUrl(item); + if (downloadUrl.IsNotNullOrWhiteSpace() && downloadUrl.StartsWith("magnet:")) + { + return downloadUrl; + } } return null; @@ -75,6 +119,8 @@ namespace NzbDrone.Core.Indexers protected virtual int? GetSeeders(XElement item) { + // safe to always use the element if it's present (and valid) + // fall back to description if ParseSeedersInDescription is enabled if (ParseSeedersInDescription && item.Element("description") != null) { var matchSeeders = ParseSeedersRegex.Match(item.Element("description").Value); @@ -93,6 +139,12 @@ namespace NzbDrone.Core.Indexers } } + var seeds = item.FindDecendants(SeedsElementName).SingleOrDefault(); + if (seeds != null) + { + return (int)seeds; + } + return null; } @@ -116,6 +168,12 @@ namespace NzbDrone.Core.Indexers } } + if (PeersElementName.IsNotNullOrWhiteSpace()) + { + var itempeers = item.FindDecendants(PeersElementName).SingleOrDefault(); + return int.Parse(itempeers.Value); + } + return null; } @@ -124,12 +182,18 @@ namespace NzbDrone.Core.Indexers var size = base.GetSize(item); if (size == 0 && SizeElementName.IsNotNullOrWhiteSpace()) { - if (item.Element(SizeElementName) != null) + var itemsize = item.FindDecendants(SizeElementName).SingleOrDefault(); + if (itemsize != null) { - size = ParseSize(item.Element(SizeElementName).Value, true); + size = ParseSize(itemsize.Value, true); } } + if (size == 0 && DefaultReleaseSize is > 0) + { + return (long)(DefaultReleaseSize * 1024f * 1024f); + } + return size; } From aaba5b749977ccbd7c489fd44fb4e3a5eb7321f2 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 7 Jun 2023 05:55:13 +0300 Subject: [PATCH 0048/1128] Add help link to finding cookies guide --- .../Definitions/Gazelle/GazelleUserPassOrCookieSettings.cs | 2 +- .../Definitions/TorrentRss/TorrentRssIndexerSettings.cs | 2 +- .../Indexers/Settings/CookieTorrentBaseSettings.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/Gazelle/GazelleUserPassOrCookieSettings.cs b/src/NzbDrone.Core/Indexers/Definitions/Gazelle/GazelleUserPassOrCookieSettings.cs index 9413d897d..ca3c62e5d 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Gazelle/GazelleUserPassOrCookieSettings.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Gazelle/GazelleUserPassOrCookieSettings.cs @@ -21,7 +21,7 @@ public class GazelleUserPassOrCookieSettings : GazelleSettings { private static readonly GazelleUserPassOrCookieValidator Validator = new (); - [FieldDefinition(4, Label = "Cookie", HelpText = "Use the Cookie field only if 2FA is enabled for your account, leave it empty otherwise.", Privacy = PrivacyLevel.Password)] + [FieldDefinition(4, Label = "Cookie", HelpText = "Use the Cookie field only if 2FA is enabled for your account, leave it empty otherwise.", HelpLink = "https://wiki.servarr.com/useful-tools#finding-cookies", Privacy = PrivacyLevel.Password)] public string Cookie { get; set; } public override NzbDroneValidationResult Validate() diff --git a/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexerSettings.cs b/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexerSettings.cs index a0525135b..902163cc1 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexerSettings.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexerSettings.cs @@ -28,7 +28,7 @@ namespace NzbDrone.Core.Indexers.Definitions.TorrentRss [FieldDefinition(0, Label = "Full RSS Feed URL", HelpTextWarning = "To sync to your apps you will need to include the 8000(Other) in the Sync Categories", HelpLink = "https://wiki.servarr.com/en/prowlarr/faq#can-i-add-any-generic-torrent-rss-feed")] public string BaseUrl { get; set; } - [FieldDefinition(1, Label = "Cookie", HelpText = "If your site requires a login cookie to access the RSS, you'll have to retrieve it via a browser.")] + [FieldDefinition(1, Label = "Cookie", HelpText = "If your site requires a login cookie to access the RSS, you'll have to retrieve it via a browser.", HelpLink = "https://wiki.servarr.com/useful-tools#finding-cookies")] public string Cookie { get; set; } [FieldDefinition(2, Type = FieldType.Checkbox, Label = "Allow Zero Size", HelpText="Enabling this will allow you to use feeds that don't specify release size, but be careful, size related checks will not be performed.")] diff --git a/src/NzbDrone.Core/Indexers/Settings/CookieTorrentBaseSettings.cs b/src/NzbDrone.Core/Indexers/Settings/CookieTorrentBaseSettings.cs index c261a305f..4198550d1 100644 --- a/src/NzbDrone.Core/Indexers/Settings/CookieTorrentBaseSettings.cs +++ b/src/NzbDrone.Core/Indexers/Settings/CookieTorrentBaseSettings.cs @@ -22,7 +22,7 @@ namespace NzbDrone.Core.Indexers.Settings Cookie = ""; } - [FieldDefinition(2, Label = "Cookie", HelpText = "Site Cookie", Privacy = PrivacyLevel.Password)] + [FieldDefinition(2, Label = "Cookie", HelpText = "Site Cookie", HelpLink = "https://wiki.servarr.com/useful-tools#finding-cookies", Privacy = PrivacyLevel.Password)] public string Cookie { get; set; } public override NzbDroneValidationResult Validate() From 72ab2b34c4283fd96542cf1d12d2207e67928173 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 7 Jun 2023 08:20:14 +0300 Subject: [PATCH 0049/1128] Cleanse /Users for Mac users --- .../CleanseLogMessageFixture.cs | 1 + .../Instrumentation/CleanseLogMessage.cs | 100 +++++++++--------- 2 files changed, 51 insertions(+), 50 deletions(-) diff --git a/src/NzbDrone.Common.Test/InstrumentationTests/CleanseLogMessageFixture.cs b/src/NzbDrone.Common.Test/InstrumentationTests/CleanseLogMessageFixture.cs index 8f2b4a4eb..ea46c3990 100644 --- a/src/NzbDrone.Common.Test/InstrumentationTests/CleanseLogMessageFixture.cs +++ b/src/NzbDrone.Common.Test/InstrumentationTests/CleanseLogMessageFixture.cs @@ -79,6 +79,7 @@ namespace NzbDrone.Common.Test.InstrumentationTests // Deluge [TestCase(@",{""download_location"": ""C:\Users\\mySecret mySecret\\Downloads""}")] [TestCase(@",{""download_location"": ""/home/mySecret/Downloads""}")] + [TestCase(@",{""download_location"": ""/Users/mySecret/Downloads""}")] [TestCase(@"auth.login(""mySecret"")")] // Download Station diff --git a/src/NzbDrone.Common/Instrumentation/CleanseLogMessage.cs b/src/NzbDrone.Common/Instrumentation/CleanseLogMessage.cs index fc74a68e0..7484e937b 100644 --- a/src/NzbDrone.Common/Instrumentation/CleanseLogMessage.cs +++ b/src/NzbDrone.Common/Instrumentation/CleanseLogMessage.cs @@ -9,61 +9,61 @@ namespace NzbDrone.Common.Instrumentation { private static readonly Regex[] CleansingRules = { - // Url - new Regex(@"(?<=[?&: ;])(apikey|api_key|(?:(?:access|api)[-_]?)?token|pass(?:key|wd)?|auth|authkey|user|u?id|api|[a-z_]*apikey|account|pid|pwd)=(?[^&=""]+?)(?=[ ""&=]|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase), - new Regex(@"(?<=[?& ;])[^=]*?(_?(?[^&=]+?)(?= |&|$|;)", RegexOptions.Compiled | RegexOptions.IgnoreCase), - new Regex(@"rss\.torrentleech\.org/(?!rss)(?[0-9a-z]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase), - new Regex(@"rss\.torrentleech\.org/rss/download/[0-9]+/(?[0-9a-z]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase), - new Regex(@"iptorrents\.com/[/a-z0-9?&;]*?(?:[?&;](u|tp)=(?[^&=;]+?))+(?= |;|&|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase), - new Regex(@"/fetch/[a-z0-9]{32}/(?[a-z0-9]{32})", RegexOptions.Compiled), - new Regex(@"getnzb.*?(?<=\?|&)(r)=(?[^&=]+?)(?= |&|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase), - new Regex(@"\b(\w*)?(_?(?[^&=]+?)(?= |&|$|;)", RegexOptions.Compiled | RegexOptions.IgnoreCase), - new Regex(@"(?<=authkey = "")(?[^&=]+?)(?="")", RegexOptions.Compiled | RegexOptions.IgnoreCase), - new Regex(@"(?<=beyond-hd\.[a-z]+/api/torrents/)(?[^&=][a-z0-9]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase), - new Regex(@"(?<=beyond-hd\.[a-z]+/torrent/download/[\w\d-]+[.]\d+[.])(?[a-z0-9]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase), + // Url + new (@"(?<=[?&: ;])(apikey|api_key|(?:(?:access|api)[-_]?)?token|pass(?:key|wd)?|auth|authkey|user|u?id|api|[a-z_]*apikey|account|pid|pwd)=(?[^&=""]+?)(?=[ ""&=]|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase), + new (@"(?<=[?& ;])[^=]*?(_?(?[^&=]+?)(?= |&|$|;)", RegexOptions.Compiled | RegexOptions.IgnoreCase), + new (@"rss\.torrentleech\.org/(?!rss)(?[0-9a-z]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase), + new (@"rss\.torrentleech\.org/rss/download/[0-9]+/(?[0-9a-z]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase), + new (@"iptorrents\.com/[/a-z0-9?&;]*?(?:[?&;](u|tp)=(?[^&=;]+?))+(?= |;|&|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase), + new (@"/fetch/[a-z0-9]{32}/(?[a-z0-9]{32})", RegexOptions.Compiled), + new (@"getnzb.*?(?<=\?|&)(r)=(?[^&=]+?)(?= |&|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase), + new (@"\b(\w*)?(_?(?[^&=]+?)(?= |&|$|;)", RegexOptions.Compiled | RegexOptions.IgnoreCase), + new (@"(?<=authkey = "")(?[^&=]+?)(?="")", RegexOptions.Compiled | RegexOptions.IgnoreCase), + new (@"(?<=beyond-hd\.[a-z]+/api/torrents/)(?[^&=][a-z0-9]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase), + new (@"(?<=beyond-hd\.[a-z]+/torrent/download/[\w\d-]+[.]\d+[.])(?[a-z0-9]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase), - // UNIT3D - new Regex(@"(?<=[a-z0-9-]+\.[a-z]+/torrent/download/\d+\.)(?[^&=][a-z0-9]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase), + // UNIT3D + new (@"(?<=[a-z0-9-]+\.[a-z]+/torrent/download/\d+\.)(?[^&=][a-z0-9]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase), - // Path - new Regex(@"""C:\\Users\\(?[^\""]+?)(\\|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase), - new Regex(@"""/home/(?[^/""]+?)(/|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase), + // Path + new (@"""C:\\Users\\(?[^\""]+?)(\\|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase), + new (@"""/(home|Users)/(?[^/""]+?)(/|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase), - // Trackers Announce Keys; Designed for Qbit Json; should work for all in theory - new Regex(@"announce(\.php)?(/|%2f|%3fpasskey%3d)(?[a-z0-9]{16,})|(?[a-z0-9]{16,})(/|%2f)announce"), + // Trackers Announce Keys; Designed for Qbit Json; should work for all in theory + new (@"announce(\.php)?(/|%2f|%3fpasskey%3d)(?[a-z0-9]{16,})|(?[a-z0-9]{16,})(/|%2f)announce"), - // NzbGet - new Regex(@"""Name""\s*:\s*""[^""]*(username|password)""\s*,\s*""Value""\s*:\s*""(?[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase), + // NzbGet + new (@"""Name""\s*:\s*""[^""]*(username|password)""\s*,\s*""Value""\s*:\s*""(?[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase), - // Sabnzbd - new Regex(@"""[^""]*(username|password|api_?key|nzb_key)""\s*:\s*""(?[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase), - new Regex(@"""email_(account|to|from|pwd)""\s*:\s*""(?[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase), + // Sabnzbd + new (@"""[^""]*(username|password|api_?key|nzb_key)""\s*:\s*""(?[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase), + new (@"""email_(account|to|from|pwd)""\s*:\s*""(?[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase), - // uTorrent - new Regex(@"\[""[a-z._]*(username|password)"",\d,""(?[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase), - new Regex(@"\[""(boss_key|boss_key_salt|proxy\.proxy)"",\d,""(?[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase), + // uTorrent + new (@"\[""[a-z._]*(username|password)"",\d,""(?[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase), + new (@"\[""(boss_key|boss_key_salt|proxy\.proxy)"",\d,""(?[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase), - // Deluge - new Regex(@"auth.login\(""(?[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase), + // Deluge + new (@"auth.login\(""(?[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase), - // BroadcastheNet (;torrent_pass|torrents_notify_ is for MTV) - new Regex(@"""?method""?\s*:\s*""(getTorrents)"",\s*""?params""?\s*:\s*\[\s*""(?[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase), - new Regex(@"getTorrents\(""(?[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase), - new Regex(@"(?<=\?|&|;|=)(authkey|torrent_pass|torrents_notify)[_=](?[^&=]+?)(?=""|&|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase), + // BroadcastheNet (;torrent_pass|torrents_notify_ is for MTV) + new (@"""?method""?\s*:\s*""(getTorrents)"",\s*""?params""?\s*:\s*\[\s*""(?[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase), + new (@"getTorrents\(""(?[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase), + new (@"(?<=\?|&|;|=)(authkey|torrent_pass|torrents_notify)[_=](?[^&=]+?)(?=""|&|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase), - // Plex - new Regex(@"(?<=\?|&)(X-Plex-Client-Identifier|X-Plex-Token)=(?[^&=]+?)(?= |&|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase), + // Plex + new (@"(?<=\?|&)(X-Plex-Client-Identifier|X-Plex-Token)=(?[^&=]+?)(?= |&|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase), - // Indexer Responses - new Regex(@"(?:avistaz|exoticaz|cinemaz|privatehd)\.[a-z]{2,3}/rss/download/(?[^&=]+?)/(?[^&=]+?)\.torrent", RegexOptions.Compiled | RegexOptions.IgnoreCase), - new Regex(@"(?:animebytes)\.[a-z]{2,3}/torrent/[0-9]+/download/(?[^&=]+?)[""]", RegexOptions.Compiled | RegexOptions.IgnoreCase), - new Regex(@",""info_hash"":""(?[^&=]+?)"",", RegexOptions.Compiled | RegexOptions.IgnoreCase), - new Regex(@"""token"":""(?[^&=]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase), - new Regex(@",""pass[- _]?key"":""(?[^&=]+?)"",", RegexOptions.Compiled | RegexOptions.IgnoreCase), - new Regex(@",""rss[- _]?key"":""(?[^&=]+?)"",", RegexOptions.Compiled | RegexOptions.IgnoreCase), + // Indexer Responses + new (@"(?:avistaz|exoticaz|cinemaz|privatehd)\.[a-z]{2,3}/rss/download/(?[^&=]+?)/(?[^&=]+?)\.torrent", RegexOptions.Compiled | RegexOptions.IgnoreCase), + new (@"(?:animebytes)\.[a-z]{2,3}/torrent/[0-9]+/download/(?[^&=]+?)[""]", RegexOptions.Compiled | RegexOptions.IgnoreCase), + new (@",""info_hash"":""(?[^&=]+?)"",", RegexOptions.Compiled | RegexOptions.IgnoreCase), + new (@"""token"":""(?[^&=]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase), + new (@",""pass[- _]?key"":""(?[^&=]+?)"",", RegexOptions.Compiled | RegexOptions.IgnoreCase), + new (@",""rss[- _]?key"":""(?[^&=]+?)"",", RegexOptions.Compiled | RegexOptions.IgnoreCase), }; - private static readonly Regex CleanseRemoteIPRegex = new Regex(@"(?:Auth-\w+(? + { + var value = m.Value; + foreach (var capture in m.Groups["secret"].Captures.OfType().Reverse()) { - var value = m.Value; - foreach (var capture in m.Groups["secret"].Captures.OfType().Reverse()) - { - value = value.Replace(capture.Index - m.Index, capture.Length, "(removed)"); - } + value = value.Replace(capture.Index - m.Index, capture.Length, "(removed)"); + } - return value; - }); + return value; + }); } message = CleanseRemoteIPRegex.Replace(message, CleanseRemoteIP); From e012eda0cf363a735fbc615f4992d59ef476de48 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 8 Jun 2023 00:23:58 +0300 Subject: [PATCH 0050/1128] Use the default IndexerCapabilities for TorrentRssIndexer --- .../Indexers/Definitions/TorrentRss/TorrentRssIndexer.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexer.cs b/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexer.cs index a9ccb4f32..717409395 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexer.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexer.cs @@ -79,10 +79,7 @@ namespace NzbDrone.Core.Indexers.Definitions.TorrentRss private IndexerCapabilities SetCapabilities() { - var caps = new IndexerCapabilities - { - SearchParams = new List(), - }; + var caps = new IndexerCapabilities(); caps.Categories.AddCategoryMapping(1, NewznabStandardCategory.Other); From a522796798d18dbd24856e7c7a6405e3f44238af Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 8 Jun 2023 16:45:14 +0300 Subject: [PATCH 0051/1128] Fixed: (Apps) Change the default sync level to Full Sync --- src/NzbDrone.Core/Applications/ApplicationBase.cs | 2 +- src/NzbDrone.Core/Applications/ApplicationDefinition.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NzbDrone.Core/Applications/ApplicationBase.cs b/src/NzbDrone.Core/Applications/ApplicationBase.cs index 82fb56d86..f516fddf1 100644 --- a/src/NzbDrone.Core/Applications/ApplicationBase.cs +++ b/src/NzbDrone.Core/Applications/ApplicationBase.cs @@ -47,7 +47,7 @@ namespace NzbDrone.Core.Applications yield return new ApplicationDefinition { Name = GetType().Name, - SyncLevel = ApplicationSyncLevel.AddOnly, + SyncLevel = ApplicationSyncLevel.FullSync, Implementation = GetType().Name, Settings = config }; diff --git a/src/NzbDrone.Core/Applications/ApplicationDefinition.cs b/src/NzbDrone.Core/Applications/ApplicationDefinition.cs index 3160898f1..ed01daffc 100644 --- a/src/NzbDrone.Core/Applications/ApplicationDefinition.cs +++ b/src/NzbDrone.Core/Applications/ApplicationDefinition.cs @@ -6,6 +6,6 @@ namespace NzbDrone.Core.Applications { public ApplicationSyncLevel SyncLevel { get; set; } - public override bool Enable => SyncLevel == ApplicationSyncLevel.AddOnly || SyncLevel == ApplicationSyncLevel.FullSync; + public override bool Enable => SyncLevel is ApplicationSyncLevel.AddOnly or ApplicationSyncLevel.FullSync; } } From 3a4c8db98c41454cfa3706b036ce11707a8d76b2 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 8 Jun 2023 17:52:37 +0300 Subject: [PATCH 0052/1128] Add all search types in TorrentRssIndexer For apps who don't support all categories with normal search, eg. Sonarr --- .../TorrentRss/TorrentRssIndexer.cs | 20 ++++++++++++++++++- .../TorrentRssIndexerRequestGenerator.cs | 13 ++++++++---- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexer.cs b/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexer.cs index 717409395..c971f28e9 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexer.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexer.cs @@ -79,7 +79,25 @@ namespace NzbDrone.Core.Indexers.Definitions.TorrentRss private IndexerCapabilities SetCapabilities() { - var caps = new IndexerCapabilities(); + var caps = new IndexerCapabilities + { + TvSearchParams = new List + { + TvSearchParam.Q + }, + MovieSearchParams = new List + { + MovieSearchParam.Q + }, + MusicSearchParams = new List + { + MusicSearchParam.Q + }, + BookSearchParams = new List + { + BookSearchParam.Q + } + }; caps.Categories.AddCategoryMapping(1, NewznabStandardCategory.Other); diff --git a/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexerRequestGenerator.cs b/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexerRequestGenerator.cs index 715e1ecf1..58ffb97ff 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexerRequestGenerator.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexerRequestGenerator.cs @@ -12,25 +12,30 @@ namespace NzbDrone.Core.Indexers.Definitions.TorrentRss public virtual IndexerPageableRequestChain GetSearchRequests(MovieSearchCriteria searchCriteria) { - return new IndexerPageableRequestChain(); + return BuildPageableRssRequests(searchCriteria); } public virtual IndexerPageableRequestChain GetSearchRequests(MusicSearchCriteria searchCriteria) { - return new IndexerPageableRequestChain(); + return BuildPageableRssRequests(searchCriteria); } public virtual IndexerPageableRequestChain GetSearchRequests(TvSearchCriteria searchCriteria) { - return new IndexerPageableRequestChain(); + return BuildPageableRssRequests(searchCriteria); } public virtual IndexerPageableRequestChain GetSearchRequests(BookSearchCriteria searchCriteria) { - return new IndexerPageableRequestChain(); + return BuildPageableRssRequests(searchCriteria); } public virtual IndexerPageableRequestChain GetSearchRequests(BasicSearchCriteria searchCriteria) + { + return BuildPageableRssRequests(searchCriteria); + } + + private IndexerPageableRequestChain BuildPageableRssRequests(SearchCriteriaBase searchCriteria) { var pageableRequests = new IndexerPageableRequestChain(); From c4bb1ba69ab35295cb99bdc02c0b0227e8ce31ad Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 6 Jun 2023 18:36:19 +0300 Subject: [PATCH 0053/1128] Catch JsonReaderException when parsing JSON in Cardigann --- .../Definitions/Cardigann/CardigannParser.cs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannParser.cs b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannParser.cs index 2513898b6..cf8fc3b67 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannParser.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannParser.cs @@ -6,6 +6,7 @@ using System.Net; using AngleSharp.Dom; using AngleSharp.Html.Parser; using AngleSharp.Xml.Parser; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; using NLog; using NzbDrone.Common.Extensions; @@ -64,7 +65,7 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann var searchUrlUri = new Uri(request.Url.FullUri); - if (request.SearchPath.Response != null && request.SearchPath.Response.Type.Equals("json")) + if (request.SearchPath.Response is { Type: "json" }) { if (request.SearchPath.Response != null && request.SearchPath.Response.NoResultsMessage != null && @@ -73,7 +74,18 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann return releases; } - var parsedJson = JToken.Parse(results); + JToken parsedJson; + + try + { + parsedJson = JToken.Parse(results); + } + catch (JsonReaderException ex) + { + _logger.Error(ex, "Unable to parse JSON response from indexer"); + + throw new IndexerException(indexerResponse, "Error Parsing Json Response"); + } if (parsedJson == null) { From a1081cc554a7764531e3c1441be2c9713bdbf7fe Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 1 Jun 2023 22:54:29 +0300 Subject: [PATCH 0054/1128] Bump NLog to 5.2.0 --- src/Directory.Build.props | 2 +- src/NzbDrone.Common/Prowlarr.Common.csproj | 4 ++-- src/NzbDrone.Core/Instrumentation/DatabaseTarget.cs | 11 +++++++---- src/NzbDrone.Core/Prowlarr.Core.csproj | 2 +- 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 +- 10 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index a26dd842a..a926a45d4 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -109,7 +109,7 @@ - + diff --git a/src/NzbDrone.Common/Prowlarr.Common.csproj b/src/NzbDrone.Common/Prowlarr.Common.csproj index e5475de4e..4cbb90d63 100644 --- a/src/NzbDrone.Common/Prowlarr.Common.csproj +++ b/src/NzbDrone.Common/Prowlarr.Common.csproj @@ -8,8 +8,8 @@ - - + + diff --git a/src/NzbDrone.Core/Instrumentation/DatabaseTarget.cs b/src/NzbDrone.Core/Instrumentation/DatabaseTarget.cs index 971d939d4..e33cebc4d 100644 --- a/src/NzbDrone.Core/Instrumentation/DatabaseTarget.cs +++ b/src/NzbDrone.Core/Instrumentation/DatabaseTarget.cs @@ -33,22 +33,25 @@ namespace NzbDrone.Core.Instrumentation LogManager.Configuration.AddTarget("DbLogger", target); LogManager.Configuration.LoggingRules.Add(Rule); - LogManager.ConfigurationReloaded += OnLogManagerOnConfigurationReloaded; + LogManager.ConfigurationChanged += OnLogManagerOnConfigurationChanged; LogManager.ReconfigExistingLoggers(); } public void UnRegister() { - LogManager.ConfigurationReloaded -= OnLogManagerOnConfigurationReloaded; + LogManager.ConfigurationChanged -= OnLogManagerOnConfigurationChanged; LogManager.Configuration.RemoveTarget("DbLogger"); LogManager.Configuration.LoggingRules.Remove(Rule); LogManager.ReconfigExistingLoggers(); Dispose(); } - private void OnLogManagerOnConfigurationReloaded(object sender, LoggingConfigurationReloadedEventArgs args) + private void OnLogManagerOnConfigurationChanged(object sender, LoggingConfigurationChangedEventArgs args) { - Register(); + if (args.ActivatedConfiguration != null) + { + Register(); + } } public LoggingRule Rule { get; set; } diff --git a/src/NzbDrone.Core/Prowlarr.Core.csproj b/src/NzbDrone.Core/Prowlarr.Core.csproj index 4632eb940..66b260791 100644 --- a/src/NzbDrone.Core/Prowlarr.Core.csproj +++ b/src/NzbDrone.Core/Prowlarr.Core.csproj @@ -17,7 +17,7 @@ - + diff --git a/src/NzbDrone.Host/Prowlarr.Host.csproj b/src/NzbDrone.Host/Prowlarr.Host.csproj index 026e521c6..7d6846b56 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 5ed567e15..87e84af7d 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 909d94853..aefe37fed 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 f690fcf0f..e4407e1cd 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 55b761157..49878d538 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 9d9bcbb95..39bf131f8 100644 --- a/src/Prowlarr.Http/Prowlarr.Http.csproj +++ b/src/Prowlarr.Http/Prowlarr.Http.csproj @@ -5,7 +5,7 @@ - + From f0d9b43480003e9cc3362a185a9d1cb7000abec3 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 30 May 2023 06:39:51 +0300 Subject: [PATCH 0055/1128] Add some API attributes --- src/Prowlarr.Api.V1/Commands/CommandController.cs | 1 + src/Prowlarr.Api.V1/Config/ConfigController.cs | 1 + src/Prowlarr.Api.V1/Config/HostConfigController.cs | 3 +++ src/Prowlarr.Api.V1/Config/UiConfigController.cs | 2 ++ src/Prowlarr.Api.V1/CustomFilters/CustomFilterController.cs | 2 ++ src/Prowlarr.Api.V1/FileSystem/FileSystemController.cs | 2 ++ src/Prowlarr.Api.V1/Health/HealthController.cs | 1 + .../Indexers/IndexerDefaultCategoriesController.cs | 1 + src/Prowlarr.Api.V1/Indexers/IndexerEditorController.cs | 2 ++ src/Prowlarr.Api.V1/Indexers/IndexerStatsController.cs | 1 + src/Prowlarr.Api.V1/Indexers/IndexerStatusController.cs | 2 ++ src/Prowlarr.Api.V1/Logs/LogController.cs | 1 + src/Prowlarr.Api.V1/Logs/LogFileControllerBase.cs | 3 +++ src/Prowlarr.Api.V1/Profiles/App/AppProfileController.cs | 2 ++ src/Prowlarr.Api.V1/Profiles/App/AppProfileSchemaModule.cs | 1 + src/Prowlarr.Api.V1/ProviderControllerBase.cs | 5 +++++ src/Prowlarr.Api.V1/Search/SearchController.cs | 6 ++++++ src/Prowlarr.Api.V1/System/Backup/BackupController.cs | 1 + src/Prowlarr.Api.V1/System/SystemController.cs | 3 +++ src/Prowlarr.Api.V1/System/Tasks/TaskController.cs | 1 + src/Prowlarr.Api.V1/Tags/TagController.cs | 5 +++++ src/Prowlarr.Api.V1/Tags/TagDetailsController.cs | 1 + src/Prowlarr.Api.V1/Update/UpdateController.cs | 1 + src/Prowlarr.Http/REST/RestController.cs | 1 + 24 files changed, 49 insertions(+) diff --git a/src/Prowlarr.Api.V1/Commands/CommandController.cs b/src/Prowlarr.Api.V1/Commands/CommandController.cs index 076121f5a..cbca618a3 100644 --- a/src/Prowlarr.Api.V1/Commands/CommandController.cs +++ b/src/Prowlarr.Api.V1/Commands/CommandController.cs @@ -48,6 +48,7 @@ namespace Prowlarr.Api.V1.Commands } [RestPostById] + [Consumes("application/json")] [Produces("application/json")] public ActionResult StartCommand(CommandResource commandResource) { diff --git a/src/Prowlarr.Api.V1/Config/ConfigController.cs b/src/Prowlarr.Api.V1/Config/ConfigController.cs index f6a001e10..120a69352 100644 --- a/src/Prowlarr.Api.V1/Config/ConfigController.cs +++ b/src/Prowlarr.Api.V1/Config/ConfigController.cs @@ -33,6 +33,7 @@ namespace Prowlarr.Api.V1.Config } [RestPutById] + [Consumes("application/json")] [Produces("application/json")] public virtual ActionResult SaveConfig(TResource resource) { diff --git a/src/Prowlarr.Api.V1/Config/HostConfigController.cs b/src/Prowlarr.Api.V1/Config/HostConfigController.cs index 12fcfda3a..9e3a82498 100644 --- a/src/Prowlarr.Api.V1/Config/HostConfigController.cs +++ b/src/Prowlarr.Api.V1/Config/HostConfigController.cs @@ -87,6 +87,7 @@ namespace Prowlarr.Api.V1.Config } [HttpGet] + [Produces("application/json")] public HostConfigResource GetHostConfig() { var resource = HostConfigResourceMapper.ToResource(_configFileProvider, _configService); @@ -103,6 +104,8 @@ namespace Prowlarr.Api.V1.Config } [RestPutById] + [Consumes("application/json")] + [Produces("application/json")] public ActionResult SaveHostConfig(HostConfigResource resource) { var dictionary = resource.GetType() diff --git a/src/Prowlarr.Api.V1/Config/UiConfigController.cs b/src/Prowlarr.Api.V1/Config/UiConfigController.cs index eda73e967..e6ddb073a 100644 --- a/src/Prowlarr.Api.V1/Config/UiConfigController.cs +++ b/src/Prowlarr.Api.V1/Config/UiConfigController.cs @@ -19,6 +19,8 @@ namespace Prowlarr.Api.V1.Config } [RestPutById] + [Consumes("application/json")] + [Produces("application/json")] public override ActionResult SaveConfig(UiConfigResource resource) { var dictionary = resource.GetType() diff --git a/src/Prowlarr.Api.V1/CustomFilters/CustomFilterController.cs b/src/Prowlarr.Api.V1/CustomFilters/CustomFilterController.cs index e5aca3c85..b4a578c09 100644 --- a/src/Prowlarr.Api.V1/CustomFilters/CustomFilterController.cs +++ b/src/Prowlarr.Api.V1/CustomFilters/CustomFilterController.cs @@ -30,6 +30,7 @@ namespace Prowlarr.Api.V1.CustomFilters } [RestPostById] + [Consumes("application/json")] [Produces("application/json")] public ActionResult AddCustomFilter(CustomFilterResource resource) { @@ -39,6 +40,7 @@ namespace Prowlarr.Api.V1.CustomFilters } [RestPutById] + [Consumes("application/json")] [Produces("application/json")] public ActionResult UpdateCustomFilter(CustomFilterResource resource) { diff --git a/src/Prowlarr.Api.V1/FileSystem/FileSystemController.cs b/src/Prowlarr.Api.V1/FileSystem/FileSystemController.cs index 154ce3990..0834887ac 100644 --- a/src/Prowlarr.Api.V1/FileSystem/FileSystemController.cs +++ b/src/Prowlarr.Api.V1/FileSystem/FileSystemController.cs @@ -18,12 +18,14 @@ namespace Prowlarr.Api.V1.FileSystem } [HttpGet] + [Produces("application/json")] public IActionResult GetContents(string path, bool includeFiles = false, bool allowFoldersWithoutTrailingSlashes = false) { return Ok(_fileSystemLookupService.LookupContents(path, includeFiles, allowFoldersWithoutTrailingSlashes)); } [HttpGet("type")] + [Produces("application/json")] public object GetEntityType(string path) { if (_diskProvider.FileExists(path)) diff --git a/src/Prowlarr.Api.V1/Health/HealthController.cs b/src/Prowlarr.Api.V1/Health/HealthController.cs index 9c562214d..27fe886aa 100644 --- a/src/Prowlarr.Api.V1/Health/HealthController.cs +++ b/src/Prowlarr.Api.V1/Health/HealthController.cs @@ -22,6 +22,7 @@ namespace Prowlarr.Api.V1.Health _healthCheckService = healthCheckService; } + [NonAction] public override HealthResource GetResourceById(int id) { throw new NotImplementedException(); diff --git a/src/Prowlarr.Api.V1/Indexers/IndexerDefaultCategoriesController.cs b/src/Prowlarr.Api.V1/Indexers/IndexerDefaultCategoriesController.cs index 6e8478c81..3c5c0b43e 100644 --- a/src/Prowlarr.Api.V1/Indexers/IndexerDefaultCategoriesController.cs +++ b/src/Prowlarr.Api.V1/Indexers/IndexerDefaultCategoriesController.cs @@ -8,6 +8,7 @@ namespace NzbDrone.Api.V1.Indexers public class IndexerDefaultCategoriesController : Controller { [HttpGet] + [Produces("application/json")] public IndexerCategory[] GetAll() { return NewznabStandardCategory.ParentCats; diff --git a/src/Prowlarr.Api.V1/Indexers/IndexerEditorController.cs b/src/Prowlarr.Api.V1/Indexers/IndexerEditorController.cs index bf1471e84..cb60d36f4 100644 --- a/src/Prowlarr.Api.V1/Indexers/IndexerEditorController.cs +++ b/src/Prowlarr.Api.V1/Indexers/IndexerEditorController.cs @@ -22,6 +22,7 @@ namespace Prowlarr.Api.V1.Indexers } [HttpPut] + [Consumes("application/json")] public IActionResult SaveAll(IndexerEditorResource resource) { var indexersToUpdate = _indexerFactory.AllProviders(false).Select(x => (IndexerDefinition)x.Definition).Where(d => resource.IndexerIds.Contains(d.Id)); @@ -71,6 +72,7 @@ namespace Prowlarr.Api.V1.Indexers } [HttpDelete] + [Consumes("application/json")] public object DeleteIndexers([FromBody] IndexerEditorResource resource) { _indexerFactory.Delete(resource.IndexerIds); diff --git a/src/Prowlarr.Api.V1/Indexers/IndexerStatsController.cs b/src/Prowlarr.Api.V1/Indexers/IndexerStatsController.cs index 7bd3c47b7..0e352506c 100644 --- a/src/Prowlarr.Api.V1/Indexers/IndexerStatsController.cs +++ b/src/Prowlarr.Api.V1/Indexers/IndexerStatsController.cs @@ -16,6 +16,7 @@ namespace Prowlarr.Api.V1.Indexers } [HttpGet] + [Produces("application/json")] public IndexerStatsResource GetAll(DateTime? startDate, DateTime? endDate) { var statsStartDate = startDate ?? DateTime.MinValue; diff --git a/src/Prowlarr.Api.V1/Indexers/IndexerStatusController.cs b/src/Prowlarr.Api.V1/Indexers/IndexerStatusController.cs index d6452f3a9..566be187f 100644 --- a/src/Prowlarr.Api.V1/Indexers/IndexerStatusController.cs +++ b/src/Prowlarr.Api.V1/Indexers/IndexerStatusController.cs @@ -23,12 +23,14 @@ namespace Prowlarr.Api.V1.Indexers _indexerStatusService = indexerStatusService; } + [NonAction] public override IndexerStatusResource GetResourceById(int id) { throw new NotImplementedException(); } [HttpGet] + [Produces("application/json")] public List GetAll() { return _indexerStatusService.GetBlockedProviders().ToResource(); diff --git a/src/Prowlarr.Api.V1/Logs/LogController.cs b/src/Prowlarr.Api.V1/Logs/LogController.cs index 047c37b7e..3f0c6df52 100644 --- a/src/Prowlarr.Api.V1/Logs/LogController.cs +++ b/src/Prowlarr.Api.V1/Logs/LogController.cs @@ -17,6 +17,7 @@ namespace Prowlarr.Api.V1.Logs } [HttpGet] + [Produces("application/json")] public PagingResource GetLogs() { var pagingResource = Request.ReadPagingResourceFromRequest(); diff --git a/src/Prowlarr.Api.V1/Logs/LogFileControllerBase.cs b/src/Prowlarr.Api.V1/Logs/LogFileControllerBase.cs index b5414beb9..54ed7d1c9 100644 --- a/src/Prowlarr.Api.V1/Logs/LogFileControllerBase.cs +++ b/src/Prowlarr.Api.V1/Logs/LogFileControllerBase.cs @@ -26,6 +26,7 @@ namespace Prowlarr.Api.V1.Logs } [HttpGet] + [Produces("application/json")] public List GetLogFilesResponse() { var result = new List(); @@ -51,6 +52,8 @@ namespace Prowlarr.Api.V1.Logs } [HttpGet(@"{filename:regex([[-.a-zA-Z0-9]]+?\.txt)}")] + [Produces("text/plain")] + [ProducesResponseType(typeof(IActionResult), 200)] public IActionResult GetLogFileResponse(string filename) { LogManager.Flush(); diff --git a/src/Prowlarr.Api.V1/Profiles/App/AppProfileController.cs b/src/Prowlarr.Api.V1/Profiles/App/AppProfileController.cs index 586b2ca9f..0b4b7ae4f 100644 --- a/src/Prowlarr.Api.V1/Profiles/App/AppProfileController.cs +++ b/src/Prowlarr.Api.V1/Profiles/App/AppProfileController.cs @@ -20,6 +20,7 @@ namespace Prowlarr.Api.V1.Profiles.App } [RestPostById] + [Consumes("application/json")] [Produces("application/json")] public ActionResult Create(AppProfileResource resource) { @@ -37,6 +38,7 @@ namespace Prowlarr.Api.V1.Profiles.App } [RestPutById] + [Consumes("application/json")] [Produces("application/json")] public ActionResult Update(AppProfileResource resource) { diff --git a/src/Prowlarr.Api.V1/Profiles/App/AppProfileSchemaModule.cs b/src/Prowlarr.Api.V1/Profiles/App/AppProfileSchemaModule.cs index 9383d795f..7cdbda0ed 100644 --- a/src/Prowlarr.Api.V1/Profiles/App/AppProfileSchemaModule.cs +++ b/src/Prowlarr.Api.V1/Profiles/App/AppProfileSchemaModule.cs @@ -15,6 +15,7 @@ namespace Prowlarr.Api.V1.Profiles.App } [HttpGet] + [Produces("application/json")] public AppProfileResource GetSchema() { var qualityProfile = _profileService.GetDefaultProfile(string.Empty); diff --git a/src/Prowlarr.Api.V1/ProviderControllerBase.cs b/src/Prowlarr.Api.V1/ProviderControllerBase.cs index 52b931956..9edfe1642 100644 --- a/src/Prowlarr.Api.V1/ProviderControllerBase.cs +++ b/src/Prowlarr.Api.V1/ProviderControllerBase.cs @@ -58,6 +58,7 @@ namespace Prowlarr.Api.V1 } [RestPostById] + [Consumes("application/json")] [Produces("application/json")] public ActionResult CreateProvider([FromBody] TProviderResource providerResource, [FromQuery] bool forceSave = false) { @@ -74,6 +75,7 @@ namespace Prowlarr.Api.V1 } [RestPutById] + [Consumes("application/json")] [Produces("application/json")] public ActionResult UpdateProvider([FromBody] TProviderResource providerResource, [FromQuery] bool forceSave = false) { @@ -135,6 +137,7 @@ namespace Prowlarr.Api.V1 [SkipValidation(true, false)] [HttpPost("test")] + [Consumes("application/json")] public object Test([FromBody] TProviderResource providerResource) { var providerDefinition = GetDefinition(providerResource, true, true, true); @@ -168,6 +171,8 @@ namespace Prowlarr.Api.V1 [SkipValidation] [HttpPost("action/{name}")] + [Consumes("application/json")] + [Produces("application/json")] public IActionResult RequestAction(string name, [FromBody] TProviderResource resource) { var providerDefinition = GetDefinition(resource, false, false, false); diff --git a/src/Prowlarr.Api.V1/Search/SearchController.cs b/src/Prowlarr.Api.V1/Search/SearchController.cs index 8ffd81a71..a0deb14ca 100644 --- a/src/Prowlarr.Api.V1/Search/SearchController.cs +++ b/src/Prowlarr.Api.V1/Search/SearchController.cs @@ -45,12 +45,15 @@ namespace Prowlarr.Api.V1.Search _remoteReleaseCache = cacheManager.GetCache(GetType(), "remoteReleases"); } + [NonAction] public override ReleaseResource GetResourceById(int id) { throw new NotImplementedException(); } [HttpPost] + [Consumes("application/json")] + [Produces("application/json")] public ActionResult GrabRelease(ReleaseResource release) { ValidateResource(release); @@ -82,6 +85,8 @@ namespace Prowlarr.Api.V1.Search } [HttpPost("bulk")] + [Consumes("application/json")] + [Produces("application/json")] public ActionResult GrabReleases(List releases) { var source = Request.GetSource(); @@ -114,6 +119,7 @@ namespace Prowlarr.Api.V1.Search } [HttpGet] + [Produces("application/json")] public Task> GetAll([FromQuery] SearchResource payload) { return GetSearchReleases(payload); diff --git a/src/Prowlarr.Api.V1/System/Backup/BackupController.cs b/src/Prowlarr.Api.V1/System/Backup/BackupController.cs index 15f8b5889..bcb236652 100644 --- a/src/Prowlarr.Api.V1/System/Backup/BackupController.cs +++ b/src/Prowlarr.Api.V1/System/Backup/BackupController.cs @@ -32,6 +32,7 @@ namespace Prowlarr.Api.V1.System.Backup } [HttpGet] + [Produces("application/json")] public List GetBackupFiles() { var backups = _backupService.GetBackups(); diff --git a/src/Prowlarr.Api.V1/System/SystemController.cs b/src/Prowlarr.Api.V1/System/SystemController.cs index 3c53b6cad..e5ffb9996 100644 --- a/src/Prowlarr.Api.V1/System/SystemController.cs +++ b/src/Prowlarr.Api.V1/System/SystemController.cs @@ -54,6 +54,7 @@ namespace Prowlarr.Api.V1.System } [HttpGet("status")] + [Produces("application/json")] public SystemResource GetStatus() { return new SystemResource @@ -93,6 +94,7 @@ namespace Prowlarr.Api.V1.System } [HttpGet("routes")] + [Produces("application/json")] public IActionResult GetRoutes() { using (var sw = new StringWriter()) @@ -104,6 +106,7 @@ namespace Prowlarr.Api.V1.System } [HttpGet("routes/duplicate")] + [Produces("application/json")] public object DuplicateRoutes() { return _detector.GetDuplicateEndpoints(_endpointData); diff --git a/src/Prowlarr.Api.V1/System/Tasks/TaskController.cs b/src/Prowlarr.Api.V1/System/Tasks/TaskController.cs index 428f78566..b4999f263 100644 --- a/src/Prowlarr.Api.V1/System/Tasks/TaskController.cs +++ b/src/Prowlarr.Api.V1/System/Tasks/TaskController.cs @@ -23,6 +23,7 @@ namespace Prowlarr.Api.V1.System.Tasks } [HttpGet] + [Produces("application/json")] public List GetAll() { return _taskManager.GetAll() diff --git a/src/Prowlarr.Api.V1/Tags/TagController.cs b/src/Prowlarr.Api.V1/Tags/TagController.cs index 554355feb..740fb9741 100644 --- a/src/Prowlarr.Api.V1/Tags/TagController.cs +++ b/src/Prowlarr.Api.V1/Tags/TagController.cs @@ -28,18 +28,23 @@ namespace Prowlarr.Api.V1.Tags } [HttpGet] + [Produces("application/json")] public List GetAll() { return _tagService.All().ToResource(); } [RestPostById] + [Consumes("application/json")] + [Produces("application/json")] public ActionResult Create(TagResource resource) { return Created(_tagService.Add(resource.ToModel()).Id); } [RestPutById] + [Consumes("application/json")] + [Produces("application/json")] public ActionResult Update(TagResource resource) { _tagService.Update(resource.ToModel()); diff --git a/src/Prowlarr.Api.V1/Tags/TagDetailsController.cs b/src/Prowlarr.Api.V1/Tags/TagDetailsController.cs index 2c927dcf0..c37b91452 100644 --- a/src/Prowlarr.Api.V1/Tags/TagDetailsController.cs +++ b/src/Prowlarr.Api.V1/Tags/TagDetailsController.cs @@ -22,6 +22,7 @@ namespace Prowlarr.Api.V1.Tags } [HttpGet] + [Produces("application/json")] public List GetAll() { return _tagService.Details().ToResource(); diff --git a/src/Prowlarr.Api.V1/Update/UpdateController.cs b/src/Prowlarr.Api.V1/Update/UpdateController.cs index 5c9b362bf..077a6f6f8 100644 --- a/src/Prowlarr.Api.V1/Update/UpdateController.cs +++ b/src/Prowlarr.Api.V1/Update/UpdateController.cs @@ -21,6 +21,7 @@ namespace Prowlarr.Api.V1.Update } [HttpGet] + [Produces("application/json")] public List GetRecentUpdates() { var resources = _recentUpdateProvider.GetRecentUpdatePackages() diff --git a/src/Prowlarr.Http/REST/RestController.cs b/src/Prowlarr.Http/REST/RestController.cs index d1d07576e..3ec48b75f 100644 --- a/src/Prowlarr.Http/REST/RestController.cs +++ b/src/Prowlarr.Http/REST/RestController.cs @@ -46,6 +46,7 @@ namespace Prowlarr.Http.REST } [RestGetById] + [Produces("application/json")] public abstract TResource GetResourceById(int id); public override void OnActionExecuting(ActionExecutingContext context) From 5187460298ce3633526cb7c0e876f4f510b5352d Mon Sep 17 00:00:00 2001 From: Servarr Date: Fri, 9 Jun 2023 01:22:43 +0000 Subject: [PATCH 0056/1128] Automated API Docs update --- src/Prowlarr.Api.V1/openapi.json | 898 +------------------------------ 1 file changed, 20 insertions(+), 878 deletions(-) diff --git a/src/Prowlarr.Api.V1/openapi.json b/src/Prowlarr.Api.V1/openapi.json index 3123f761c..9bf5074f3 100644 --- a/src/Prowlarr.Api.V1/openapi.json +++ b/src/Prowlarr.Api.V1/openapi.json @@ -66,20 +66,10 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ApplicationResource" - } - }, "application/json": { "schema": { "$ref": "#/components/schemas/ApplicationResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ApplicationResource" - } } } } @@ -113,16 +103,6 @@ "schema": { "$ref": "#/components/schemas/ApplicationResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ApplicationResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/ApplicationResource" - } } } }, @@ -202,16 +182,6 @@ "schema": { "$ref": "#/components/schemas/ApplicationResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ApplicationResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/ApplicationResource" - } } } }, @@ -262,16 +232,6 @@ "schema": { "$ref": "#/components/schemas/ApplicationResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ApplicationResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/ApplicationResource" - } } } }, @@ -315,16 +275,6 @@ "schema": { "$ref": "#/components/schemas/ApplicationResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ApplicationResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/ApplicationResource" - } } } }, @@ -346,16 +296,6 @@ "schema": { "$ref": "#/components/schemas/AppProfileResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/AppProfileResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/AppProfileResource" - } } } }, @@ -435,16 +375,6 @@ "schema": { "$ref": "#/components/schemas/AppProfileResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/AppProfileResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/AppProfileResource" - } } } }, @@ -589,14 +519,6 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/BackupResource" - } - } - }, "application/json": { "schema": { "type": "array", @@ -604,14 +526,6 @@ "$ref": "#/components/schemas/BackupResource" } } - }, - "text/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/BackupResource" - } - } } } } @@ -696,20 +610,10 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/CommandResource" - } - }, "application/json": { "schema": { "$ref": "#/components/schemas/CommandResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/CommandResource" - } } } } @@ -748,16 +652,6 @@ "schema": { "$ref": "#/components/schemas/CommandResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/CommandResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/CommandResource" - } } } }, @@ -815,20 +709,10 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/CustomFilterResource" - } - }, "application/json": { "schema": { "$ref": "#/components/schemas/CustomFilterResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/CustomFilterResource" - } } } } @@ -854,16 +738,6 @@ "schema": { "$ref": "#/components/schemas/CustomFilterResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/CustomFilterResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/CustomFilterResource" - } } } }, @@ -933,16 +807,6 @@ "schema": { "$ref": "#/components/schemas/CustomFilterResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/CustomFilterResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/CustomFilterResource" - } } } }, @@ -981,16 +845,6 @@ "schema": { "$ref": "#/components/schemas/DevelopmentConfigResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/DevelopmentConfigResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/DevelopmentConfigResource" - } } } }, @@ -1026,20 +880,10 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/DevelopmentConfigResource" - } - }, "application/json": { "schema": { "$ref": "#/components/schemas/DevelopmentConfigResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/DevelopmentConfigResource" - } } } } @@ -1085,20 +929,10 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/DownloadClientResource" - } - }, "application/json": { "schema": { "$ref": "#/components/schemas/DownloadClientResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/DownloadClientResource" - } } } } @@ -1132,16 +966,6 @@ "schema": { "$ref": "#/components/schemas/DownloadClientResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/DownloadClientResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/DownloadClientResource" - } } } }, @@ -1221,16 +1045,6 @@ "schema": { "$ref": "#/components/schemas/DownloadClientResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/DownloadClientResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/DownloadClientResource" - } } } }, @@ -1281,16 +1095,6 @@ "schema": { "$ref": "#/components/schemas/DownloadClientResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/DownloadClientResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/DownloadClientResource" - } } } }, @@ -1334,16 +1138,6 @@ "schema": { "$ref": "#/components/schemas/DownloadClientResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/DownloadClientResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/DownloadClientResource" - } } } }, @@ -1374,20 +1168,10 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/DownloadClientConfigResource" - } - }, "application/json": { "schema": { "$ref": "#/components/schemas/DownloadClientConfigResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/DownloadClientConfigResource" - } } } } @@ -1413,16 +1197,6 @@ "schema": { "$ref": "#/components/schemas/DownloadClientConfigResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/DownloadClientConfigResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/DownloadClientConfigResource" - } } } }, @@ -1517,46 +1291,6 @@ } } }, - "/api/v1/health/{id}": { - "get": { - "tags": [ - "Health" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - } - ], - "responses": { - "200": { - "description": "Success", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/HealthResource" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/HealthResource" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/HealthResource" - } - } - } - } - } - } - }, "/api/v1/health": { "get": { "tags": [ @@ -1696,20 +1430,10 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/HostConfigResource" - } - }, "application/json": { "schema": { "$ref": "#/components/schemas/HostConfigResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/HostConfigResource" - } } } } @@ -1735,16 +1459,6 @@ "schema": { "$ref": "#/components/schemas/HostConfigResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/HostConfigResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/HostConfigResource" - } } } }, @@ -1752,20 +1466,10 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/HostConfigResource" - } - }, "application/json": { "schema": { "$ref": "#/components/schemas/HostConfigResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/HostConfigResource" - } } } } @@ -1781,20 +1485,10 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/HostConfigResource" - } - }, "application/json": { "schema": { "$ref": "#/components/schemas/HostConfigResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/HostConfigResource" - } } } } @@ -1821,20 +1515,10 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/IndexerResource" - } - }, "application/json": { "schema": { "$ref": "#/components/schemas/IndexerResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/IndexerResource" - } } } } @@ -1868,16 +1552,6 @@ "schema": { "$ref": "#/components/schemas/IndexerResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/IndexerResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/IndexerResource" - } } } }, @@ -1957,16 +1631,6 @@ "schema": { "$ref": "#/components/schemas/IndexerResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/IndexerResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/IndexerResource" - } } } }, @@ -2017,16 +1681,6 @@ "schema": { "$ref": "#/components/schemas/IndexerResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/IndexerResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/IndexerResource" - } } } }, @@ -2070,16 +1724,6 @@ "schema": { "$ref": "#/components/schemas/IndexerResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/IndexerResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/IndexerResource" - } } } }, @@ -2099,14 +1743,6 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/IndexerCategory" - } - } - }, "application/json": { "schema": { "type": "array", @@ -2114,14 +1750,6 @@ "$ref": "#/components/schemas/IndexerCategory" } } - }, - "text/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/IndexerCategory" - } - } } } } @@ -2139,16 +1767,6 @@ "schema": { "$ref": "#/components/schemas/IndexerEditorResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/IndexerEditorResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/IndexerEditorResource" - } } } }, @@ -2168,16 +1786,6 @@ "schema": { "$ref": "#/components/schemas/IndexerEditorResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/IndexerEditorResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/IndexerEditorResource" - } } } }, @@ -2208,20 +1816,10 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/IndexerProxyResource" - } - }, "application/json": { "schema": { "$ref": "#/components/schemas/IndexerProxyResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/IndexerProxyResource" - } } } } @@ -2255,16 +1853,6 @@ "schema": { "$ref": "#/components/schemas/IndexerProxyResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/IndexerProxyResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/IndexerProxyResource" - } } } }, @@ -2344,16 +1932,6 @@ "schema": { "$ref": "#/components/schemas/IndexerProxyResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/IndexerProxyResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/IndexerProxyResource" - } } } }, @@ -2404,16 +1982,6 @@ "schema": { "$ref": "#/components/schemas/IndexerProxyResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/IndexerProxyResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/IndexerProxyResource" - } } } }, @@ -2457,16 +2025,6 @@ "schema": { "$ref": "#/components/schemas/IndexerProxyResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/IndexerProxyResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/IndexerProxyResource" - } } } }, @@ -2504,60 +2062,10 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/IndexerStatsResource" - } - }, "application/json": { "schema": { "$ref": "#/components/schemas/IndexerStatsResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/IndexerStatsResource" - } - } - } - } - } - } - }, - "/api/v1/indexerstatus/{id}": { - "get": { - "tags": [ - "IndexerStatus" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - } - ], - "responses": { - "200": { - "description": "Success", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/IndexerStatusResource" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/IndexerStatusResource" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/IndexerStatusResource" - } } } } @@ -2573,14 +2081,6 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/IndexerStatusResource" - } - } - }, "application/json": { "schema": { "type": "array", @@ -2588,14 +2088,6 @@ "$ref": "#/components/schemas/IndexerStatusResource" } } - }, - "text/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/IndexerStatusResource" - } - } } } } @@ -2657,20 +2149,10 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/LogResourcePagingResource" - } - }, "application/json": { "schema": { "$ref": "#/components/schemas/LogResourcePagingResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/LogResourcePagingResource" - } } } } @@ -2686,14 +2168,6 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/LogFileResource" - } - } - }, "application/json": { "schema": { "type": "array", @@ -2701,14 +2175,6 @@ "$ref": "#/components/schemas/LogFileResource" } } - }, - "text/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/LogFileResource" - } - } } } } @@ -2733,7 +2199,14 @@ ], "responses": { "200": { - "description": "Success" + "description": "Success", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/IActionResult" + } + } + } } } } @@ -3290,20 +2763,10 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/NotificationResource" - } - }, "application/json": { "schema": { "$ref": "#/components/schemas/NotificationResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/NotificationResource" - } } } } @@ -3337,16 +2800,6 @@ "schema": { "$ref": "#/components/schemas/NotificationResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/NotificationResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/NotificationResource" - } } } }, @@ -3426,16 +2879,6 @@ "schema": { "$ref": "#/components/schemas/NotificationResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/NotificationResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/NotificationResource" - } } } }, @@ -3486,16 +2929,6 @@ "schema": { "$ref": "#/components/schemas/NotificationResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/NotificationResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/NotificationResource" - } } } }, @@ -3539,16 +2972,6 @@ "schema": { "$ref": "#/components/schemas/NotificationResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/NotificationResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/NotificationResource" - } } } }, @@ -3587,60 +3010,10 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/AppProfileResource" - } - }, "application/json": { "schema": { "$ref": "#/components/schemas/AppProfileResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/AppProfileResource" - } - } - } - } - } - } - }, - "/api/v1/search/{id}": { - "get": { - "tags": [ - "Search" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - } - ], - "responses": { - "200": { - "description": "Success", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ReleaseResource" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/ReleaseResource" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ReleaseResource" - } } } } @@ -3658,16 +3031,6 @@ "schema": { "$ref": "#/components/schemas/ReleaseResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ReleaseResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/ReleaseResource" - } } } }, @@ -3675,20 +3038,10 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ReleaseResource" - } - }, "application/json": { "schema": { "$ref": "#/components/schemas/ReleaseResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ReleaseResource" - } } } } @@ -3756,14 +3109,6 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ReleaseResource" - } - } - }, "application/json": { "schema": { "type": "array", @@ -3771,14 +3116,6 @@ "$ref": "#/components/schemas/ReleaseResource" } } - }, - "text/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ReleaseResource" - } - } } } } @@ -3799,22 +3136,6 @@ "$ref": "#/components/schemas/ReleaseResource" } } - }, - "text/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ReleaseResource" - } - } - }, - "application/*+json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ReleaseResource" - } - } } } }, @@ -3822,20 +3143,10 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ReleaseResource" - } - }, "application/json": { "schema": { "$ref": "#/components/schemas/ReleaseResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ReleaseResource" - } } } } @@ -3919,20 +3230,10 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/SystemResource" - } - }, "application/json": { "schema": { "$ref": "#/components/schemas/SystemResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/SystemResource" - } } } } @@ -4007,20 +3308,10 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/TagResource" - } - }, "application/json": { "schema": { "$ref": "#/components/schemas/TagResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/TagResource" - } } } } @@ -4046,16 +3337,6 @@ "schema": { "$ref": "#/components/schemas/TagResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/TagResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/TagResource" - } } } }, @@ -4063,20 +3344,10 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/TagResource" - } - }, "application/json": { "schema": { "$ref": "#/components/schemas/TagResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/TagResource" - } } } } @@ -4113,14 +3384,6 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/TagResource" - } - } - }, "application/json": { "schema": { "type": "array", @@ -4128,14 +3391,6 @@ "$ref": "#/components/schemas/TagResource" } } - }, - "text/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/TagResource" - } - } } } } @@ -4151,16 +3406,6 @@ "schema": { "$ref": "#/components/schemas/TagResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/TagResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/TagResource" - } } } }, @@ -4168,20 +3413,10 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/TagResource" - } - }, "application/json": { "schema": { "$ref": "#/components/schemas/TagResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/TagResource" - } } } } @@ -4208,20 +3443,10 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/TagDetailsResource" - } - }, "application/json": { "schema": { "$ref": "#/components/schemas/TagDetailsResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/TagDetailsResource" - } } } } @@ -4237,14 +3462,6 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/TagDetailsResource" - } - } - }, "application/json": { "schema": { "type": "array", @@ -4252,14 +3469,6 @@ "$ref": "#/components/schemas/TagDetailsResource" } } - }, - "text/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/TagDetailsResource" - } - } } } } @@ -4275,14 +3484,6 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/TaskResource" - } - } - }, "application/json": { "schema": { "type": "array", @@ -4290,14 +3491,6 @@ "$ref": "#/components/schemas/TaskResource" } } - }, - "text/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/TaskResource" - } - } } } } @@ -4324,20 +3517,10 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/TaskResource" - } - }, "application/json": { "schema": { "$ref": "#/components/schemas/TaskResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/TaskResource" - } } } } @@ -4365,16 +3548,6 @@ "schema": { "$ref": "#/components/schemas/UiConfigResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/UiConfigResource" - } - }, - "application/*+json": { - "schema": { - "$ref": "#/components/schemas/UiConfigResource" - } } } }, @@ -4410,20 +3583,10 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/UiConfigResource" - } - }, "application/json": { "schema": { "$ref": "#/components/schemas/UiConfigResource" } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/UiConfigResource" - } } } } @@ -4458,14 +3621,6 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/UpdateResource" - } - } - }, "application/json": { "schema": { "type": "array", @@ -4473,14 +3628,6 @@ "$ref": "#/components/schemas/UpdateResource" } } - }, - "text/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/UpdateResource" - } - } } } } @@ -4496,14 +3643,6 @@ "200": { "description": "Success", "content": { - "text/plain": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/LogFileResource" - } - } - }, "application/json": { "schema": { "type": "array", @@ -4511,14 +3650,6 @@ "$ref": "#/components/schemas/LogFileResource" } } - }, - "text/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/LogFileResource" - } - } } } } @@ -4543,7 +3674,14 @@ ], "responses": { "200": { - "description": "Success" + "description": "Success", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/IActionResult" + } + } + } } } } @@ -5461,6 +4599,10 @@ }, "additionalProperties": false }, + "IActionResult": { + "type": "object", + "additionalProperties": false + }, "IndexerCapabilityResource": { "type": "object", "properties": { From 0b610ff9c80384ebbe74775a9c2b560cd21f1ede Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 9 Jun 2023 17:28:52 +0300 Subject: [PATCH 0057/1128] Cleanse messages for TL 24h RSS feed links --- .../InstrumentationTests/CleanseLogMessageFixture.cs | 4 +++- src/NzbDrone.Common/Instrumentation/CleanseLogMessage.cs | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/NzbDrone.Common.Test/InstrumentationTests/CleanseLogMessageFixture.cs b/src/NzbDrone.Common.Test/InstrumentationTests/CleanseLogMessageFixture.cs index ea46c3990..d7c3c9106 100644 --- a/src/NzbDrone.Common.Test/InstrumentationTests/CleanseLogMessageFixture.cs +++ b/src/NzbDrone.Common.Test/InstrumentationTests/CleanseLogMessageFixture.cs @@ -10,7 +10,9 @@ namespace NzbDrone.Common.Test.InstrumentationTests // Indexer Urls [TestCase(@"https://iptorrents.com/torrents/rss?u=mySecret;tp=mySecret;l5;download")] [TestCase(@"http://rss.torrentleech.org/mySecret")] - [TestCase(@"http://rss.torrentleech.org/rss/download/12345/01233210/filename.torrent")] + [TestCase(@"https://rss24h.torrentleech.org/mySecret")] + [TestCase(@"http://rss.torrentleech.org/rss/download/12345/01233210/file.name-RLSGRP.torrent")] + [TestCase(@"https://www.torrentleech.org/rss/download/12345/01233210/file.name-RLSGRP.torrent")] [TestCase(@"http://www.bitmetv.org/rss.php?uid=mySecret&passkey=mySecret")] [TestCase(@"https://rss.omgwtfnzbs.org/rss-search.php?catid=19,20&user=sonarr&api=mySecret&eng=1")] [TestCase(@"https://dognzb.cr/fetch/2b51db35e1912ffc138825a12b9933d2/2b51db35e1910123321025a12b9933d2")] diff --git a/src/NzbDrone.Common/Instrumentation/CleanseLogMessage.cs b/src/NzbDrone.Common/Instrumentation/CleanseLogMessage.cs index 7484e937b..13d7e935d 100644 --- a/src/NzbDrone.Common/Instrumentation/CleanseLogMessage.cs +++ b/src/NzbDrone.Common/Instrumentation/CleanseLogMessage.cs @@ -12,8 +12,8 @@ namespace NzbDrone.Common.Instrumentation // Url new (@"(?<=[?&: ;])(apikey|api_key|(?:(?:access|api)[-_]?)?token|pass(?:key|wd)?|auth|authkey|user|u?id|api|[a-z_]*apikey|account|pid|pwd)=(?[^&=""]+?)(?=[ ""&=]|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase), new (@"(?<=[?& ;])[^=]*?(_?(?[^&=]+?)(?= |&|$|;)", RegexOptions.Compiled | RegexOptions.IgnoreCase), - new (@"rss\.torrentleech\.org/(?!rss)(?[0-9a-z]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase), - new (@"rss\.torrentleech\.org/rss/download/[0-9]+/(?[0-9a-z]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase), + new (@"rss(24h)?\.torrentleech\.org/(?!rss)(?[0-9a-z]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase), + new (@"torrentleech\.org/rss/download/[0-9]+/(?[0-9a-z]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase), new (@"iptorrents\.com/[/a-z0-9?&;]*?(?:[?&;](u|tp)=(?[^&=;]+?))+(?= |;|&|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase), new (@"/fetch/[a-z0-9]{32}/(?[a-z0-9]{32})", RegexOptions.Compiled), new (@"getnzb.*?(?<=\?|&)(r)=(?[^&=]+?)(?= |&|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase), From 7cb465787edd4221b0fe315180ac71ad0656d191 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 31 May 2023 04:00:52 +0300 Subject: [PATCH 0058/1128] Use more specific styling for kinds in ProgressBar (cherry picked from commit dd31c913d2a974d95f3be251714ce749cfd99a72) --- frontend/src/Components/ProgressBar.css | 64 ++++++++++++------------- frontend/src/Components/ProgressBar.js | 4 +- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/frontend/src/Components/ProgressBar.css b/frontend/src/Components/ProgressBar.css index 81510545a..d6f9069c0 100644 --- a/frontend/src/Components/ProgressBar.css +++ b/frontend/src/Components/ProgressBar.css @@ -16,6 +16,38 @@ box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); color: var(--white); transition: width 0.6s ease; + + &.primary { + background-color: var(--primaryColor); + } + + &.danger { + background-color: var(--dangerColor); + + &:global(.colorImpaired) { + background: repeating-linear-gradient(90deg, color(var(--dangerColor) shade(5%)), color(var(--dangerColor) shade(5%)) 5px, color(var(--dangerColor) shade(15%)) 5px, color(var(--dangerColor) shade(15%)) 10px); + } + } + + &.success { + background-color: var(--successColor); + } + + &.purple { + background-color: var(--purple); + } + + &.warning { + background-color: var(--warningColor); + + &:global(.colorImpaired) { + background: repeating-linear-gradient(45deg, var(--warningColor), var(--warningColor) 5px, color(var(--warningColor) tint(15%)) 5px, color(var(--warningColor) tint(15%)) 10px); + } + } + + &.info { + background-color: var(--infoColor); + } } .frontTextContainer { @@ -41,38 +73,6 @@ cursor: default; } -.primary { - background-color: var(--primaryColor); -} - -.danger { - background-color: var(--dangerColor); - - &:global(.colorImpaired) { - background: repeating-linear-gradient(90deg, color(var(--dangerColor) shade(5%)), color(var(--dangerColor) shade(5%)) 5px, color(var(--dangerColor) shade(15%)) 5px, color(var(--dangerColor) shade(15%)) 10px); - } -} - -.success { - background-color: var(--successColor); -} - -.purple { - background-color: var(--purple); -} - -.warning { - background-color: var(--warningColor); - - &:global(.colorImpaired) { - background: repeating-linear-gradient(45deg, var(--warningColor), var(--warningColor) 5px, color(var(--warningColor) tint(15%)) 5px, color(var(--warningColor) tint(15%)) 10px); - } -} - -.info { - background-color: var(--infoColor); -} - .small { height: $progressBarSmallHeight; diff --git a/frontend/src/Components/ProgressBar.js b/frontend/src/Components/ProgressBar.js index 8d8eef38c..0cf04da46 100644 --- a/frontend/src/Components/ProgressBar.js +++ b/frontend/src/Components/ProgressBar.js @@ -38,7 +38,7 @@ function ProgressBar(props) { { showText && width ?
@@ -67,7 +67,7 @@ function ProgressBar(props) { { showText ?
Date: Sat, 10 Jun 2023 23:32:06 +0300 Subject: [PATCH 0059/1128] Fixed: (FreeboxDownload) Set seed limits in client --- .../FreeboxDownload/FreeboxDownloadProxy.cs | 20 +++++++---- .../FreeboxDownloadSettings.cs | 4 +-- .../FreeboxDownload/TorrentFreeboxDownload.cs | 33 +++++++++++-------- 3 files changed, 34 insertions(+), 23 deletions(-) diff --git a/src/NzbDrone.Core/Download/Clients/FreeboxDownload/FreeboxDownloadProxy.cs b/src/NzbDrone.Core/Download/Clients/FreeboxDownload/FreeboxDownloadProxy.cs index 1c40a3832..ae952e2b9 100644 --- a/src/NzbDrone.Core/Download/Clients/FreeboxDownload/FreeboxDownloadProxy.cs +++ b/src/NzbDrone.Core/Download/Clients/FreeboxDownload/FreeboxDownloadProxy.cs @@ -14,8 +14,8 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload public interface IFreeboxDownloadProxy { void Authenticate(FreeboxDownloadSettings settings); - string AddTaskFromUrl(string url, string directory, bool addPaused, bool addFirst, FreeboxDownloadSettings settings); - string AddTaskFromFile(string fileName, byte[] fileContent, string directory, bool addPaused, bool addFirst, FreeboxDownloadSettings settings); + string AddTaskFromUrl(string url, string directory, bool addPaused, bool addFirst, double? seedRatio, FreeboxDownloadSettings settings); + string AddTaskFromFile(string fileName, byte[] fileContent, string directory, bool addPaused, bool addFirst, double? seedRatio, FreeboxDownloadSettings settings); void DeleteTask(string id, bool deleteData, FreeboxDownloadSettings settings); FreeboxDownloadConfiguration GetDownloadConfiguration(FreeboxDownloadSettings settings); List GetTasks(FreeboxDownloadSettings settings); @@ -46,7 +46,7 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload } } - public string AddTaskFromUrl(string url, string directory, bool addPaused, bool addFirst, FreeboxDownloadSettings settings) + public string AddTaskFromUrl(string url, string directory, bool addPaused, bool addFirst, double? seedRatio, FreeboxDownloadSettings settings) { var request = BuildRequest(settings).Resource("/downloads/add").Post(); request.Headers.ContentType = "application/x-www-form-urlencoded"; @@ -60,12 +60,12 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload var response = ProcessRequest(request.Build(), settings); - SetTorrentSettings(response.Result.Id, addPaused, addFirst, settings); + SetTorrentSettings(response.Result.Id, addPaused, addFirst, seedRatio, settings); return response.Result.Id; } - public string AddTaskFromFile(string fileName, byte[] fileContent, string directory, bool addPaused, bool addFirst, FreeboxDownloadSettings settings) + public string AddTaskFromFile(string fileName, byte[] fileContent, string directory, bool addPaused, bool addFirst, double? seedRatio, FreeboxDownloadSettings settings) { var request = BuildRequest(settings).Resource("/downloads/add").Post(); @@ -78,7 +78,7 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload var response = ProcessRequest(request.Build(), settings); - SetTorrentSettings(response.Result.Id, addPaused, addFirst, settings); + SetTorrentSettings(response.Result.Id, addPaused, addFirst, seedRatio, settings); return response.Result.Id; } @@ -118,7 +118,7 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload return $"{settings.Host}:{settings.AppId}:{settings.AppToken}"; } - private void SetTorrentSettings(string id, bool addPaused, bool addFirst, FreeboxDownloadSettings settings) + private void SetTorrentSettings(string id, bool addPaused, bool addFirst, double? seedRatio, FreeboxDownloadSettings settings) { var request = BuildRequest(settings).Resource("/downloads/" + id).Build(); @@ -136,6 +136,12 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload body.Add("queue_pos", "1"); } + if (seedRatio != null) + { + // 0 means unlimited seeding + body.Add("stop_ratio", seedRatio); + } + if (body.Count == 0) { return; diff --git a/src/NzbDrone.Core/Download/Clients/FreeboxDownload/FreeboxDownloadSettings.cs b/src/NzbDrone.Core/Download/Clients/FreeboxDownload/FreeboxDownloadSettings.cs index 3810f8e7e..ee0fff8e1 100644 --- a/src/NzbDrone.Core/Download/Clients/FreeboxDownload/FreeboxDownloadSettings.cs +++ b/src/NzbDrone.Core/Download/Clients/FreeboxDownload/FreeboxDownloadSettings.cs @@ -36,7 +36,7 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload public class FreeboxDownloadSettings : IProviderConfig { - private static readonly FreeboxDownloadSettingsValidator Validator = new FreeboxDownloadSettingsValidator(); + private static readonly FreeboxDownloadSettingsValidator Validator = new (); public FreeboxDownloadSettings() { @@ -73,7 +73,7 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload [FieldDefinition(8, Label = "Priority", Type = FieldType.Select, SelectOptions = typeof(FreeboxDownloadPriority), HelpText = "Priority to use when grabbing")] public int Priority { get; set; } - [FieldDefinition(10, Label = "Add Paused", Type = FieldType.Checkbox)] + [FieldDefinition(9, Label = "Add Paused", Type = FieldType.Checkbox)] public bool AddPaused { get; set; } public NzbDroneValidationResult Validate() diff --git a/src/NzbDrone.Core/Download/Clients/FreeboxDownload/TorrentFreeboxDownload.cs b/src/NzbDrone.Core/Download/Clients/FreeboxDownload/TorrentFreeboxDownload.cs index 8f23e93b6..cec808592 100644 --- a/src/NzbDrone.Core/Download/Clients/FreeboxDownload/TorrentFreeboxDownload.cs +++ b/src/NzbDrone.Core/Download/Clients/FreeboxDownload/TorrentFreeboxDownload.cs @@ -1,12 +1,10 @@ -using System.Collections.Generic; -using System.Linq; +using System.Collections.Generic; using System.Text.RegularExpressions; using FluentValidation.Results; using NLog; using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; using NzbDrone.Core.Configuration; -using NzbDrone.Core.Download.Clients.FreeboxDownload.Responses; using NzbDrone.Core.Indexers; using NzbDrone.Core.Parser.Model; @@ -28,20 +26,15 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload } public override string Name => "Freebox Download"; - public override bool SupportsCategories => true; - protected IEnumerable GetTorrents() - { - return _proxy.GetTasks(Settings).Where(v => v.Type.ToLower() == FreeboxDownloadTaskType.Bt.ToString().ToLower()); - } - protected override string AddFromMagnetLink(TorrentInfo release, string hash, string magnetLink) { return _proxy.AddTaskFromUrl(magnetLink, GetDownloadDirectory(release).EncodeBase64(), ToBePaused(), ToBeQueuedFirst(), + GetSeedRatio(release), Settings); } @@ -52,6 +45,7 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload GetDownloadDirectory(release).EncodeBase64(), ToBePaused(), ToBeQueuedFirst(), + GetSeedRatio(release), Settings); } @@ -61,6 +55,7 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload GetDownloadDirectory(release).EncodeBase64(), ToBePaused(), ToBeQueuedFirst(), + GetSeedRatio(release), Settings); } @@ -108,16 +103,21 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload var destDir = _proxy.GetDownloadConfiguration(Settings).DecodedDownloadDirectory.TrimEnd('/'); - if (Settings.Category.IsNotNullOrWhiteSpace()) - { - var category = GetCategoryForRelease(release) ?? Settings.Category; + var category = GetCategoryForRelease(release) ?? Settings.Category; + if (category.IsNotNullOrWhiteSpace()) + { destDir = $"{destDir}/{category}"; } return destDir; } + private bool ToBePaused() + { + return Settings.AddPaused; + } + private bool ToBeQueuedFirst() { if (Settings.Priority == (int)FreeboxDownloadPriority.First) @@ -128,9 +128,14 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload return false; } - private bool ToBePaused() + private double? GetSeedRatio(TorrentInfo release) { - return Settings.AddPaused; + if (release.SeedConfiguration == null || release.SeedConfiguration.Ratio == null) + { + return null; + } + + return release.SeedConfiguration.Ratio.Value * 100; } } } From 48cd1d9f6b55c71f42fab14871f14d7b15f4ed41 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 11 Jun 2023 01:54:13 +0300 Subject: [PATCH 0060/1128] Reset ContentSummary on redirect in HttpClient --- src/NzbDrone.Common/Http/HttpClient.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/NzbDrone.Common/Http/HttpClient.cs b/src/NzbDrone.Common/Http/HttpClient.cs index ffbe8f4d1..a1e6f0243 100644 --- a/src/NzbDrone.Common/Http/HttpClient.cs +++ b/src/NzbDrone.Common/Http/HttpClient.cs @@ -91,6 +91,7 @@ namespace NzbDrone.Common.Http { request.Method = HttpMethod.Get; request.ContentData = null; + request.ContentSummary = null; } // Save to add to final response From 419cce53f7483df06bc2ca1897c04b9f2e2b6966 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 11 Jun 2023 03:01:42 +0300 Subject: [PATCH 0061/1128] Fixed: (Transmission) Set seed limits in client --- .../Clients/Transmission/TransmissionBase.cs | 44 +------------------ .../Transmission/TransmissionConfig.cs | 2 +- .../Transmission/TransmissionException.cs | 2 +- .../Transmission/TransmissionPriority.cs | 2 +- .../Clients/Transmission/TransmissionProxy.cs | 4 +- .../Transmission/TransmissionResponse.cs | 2 +- .../Transmission/TransmissionTorrent.cs | 4 +- .../Transmission/TransmissionTorrentStatus.cs | 2 +- .../Download/Clients/Vuze/Vuze.cs | 2 +- 9 files changed, 12 insertions(+), 52 deletions(-) diff --git a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionBase.cs b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionBase.cs index 5ed105d77..6e723a32a 100644 --- a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionBase.cs +++ b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionBase.cs @@ -26,51 +26,11 @@ namespace NzbDrone.Core.Download.Clients.Transmission _proxy = proxy; } - protected bool HasReachedSeedLimit(TransmissionTorrent torrent, double? ratio, Lazy config) - { - var isStopped = torrent.Status == TransmissionTorrentStatus.Stopped; - var isSeeding = torrent.Status == TransmissionTorrentStatus.Seeding; - - if (torrent.SeedRatioMode == 1) - { - if (isStopped && ratio.HasValue && ratio >= torrent.SeedRatioLimit) - { - return true; - } - } - else if (torrent.SeedRatioMode == 0) - { - if (isStopped && config.Value.SeedRatioLimited && ratio >= config.Value.SeedRatioLimit) - { - return true; - } - } - - // Transmission doesn't support SeedTimeLimit, use/abuse seed idle limit, but only if it was set per-torrent. - if (torrent.SeedIdleMode == 1) - { - if ((isStopped || isSeeding) && torrent.SecondsSeeding > torrent.SeedIdleLimit * 60) - { - return true; - } - } - else if (torrent.SeedIdleMode == 0) - { - // The global idle limit is a real idle limit, if it's configured then 'Stopped' is enough. - if (isStopped && config.Value.IdleSeedingLimitEnabled) - { - return true; - } - } - - return false; - } - protected override string AddFromMagnetLink(TorrentInfo release, string hash, string magnetLink) { _proxy.AddTorrentFromUrl(magnetLink, GetDownloadDirectory(), Settings); + _proxy.SetTorrentSeedingConfiguration(hash, release.SeedConfiguration, Settings); - //_proxy.SetTorrentSeedingConfiguration(hash, release.SeedConfiguration, Settings); if (Settings.Priority == (int)TransmissionPriority.First) { _proxy.MoveTorrentToTopInQueue(hash, Settings); @@ -82,8 +42,8 @@ namespace NzbDrone.Core.Download.Clients.Transmission protected override string AddFromTorrentFile(TorrentInfo release, string hash, string filename, byte[] fileContent) { _proxy.AddTorrentFromData(fileContent, GetDownloadDirectory(), Settings); + _proxy.SetTorrentSeedingConfiguration(hash, release.SeedConfiguration, Settings); - //_proxy.SetTorrentSeedingConfiguration(hash, release.SeedConfiguration, Settings); if (Settings.Priority == (int)TransmissionPriority.First) { _proxy.MoveTorrentToTopInQueue(hash, Settings); diff --git a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionConfig.cs b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionConfig.cs index 1b96ca6d3..e987259a9 100644 --- a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionConfig.cs +++ b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionConfig.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json; +using Newtonsoft.Json; namespace NzbDrone.Core.Download.Clients.Transmission { diff --git a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionException.cs b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionException.cs index 3b91b4ce3..fe1b01759 100644 --- a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionException.cs +++ b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionException.cs @@ -1,4 +1,4 @@ -namespace NzbDrone.Core.Download.Clients.Transmission +namespace NzbDrone.Core.Download.Clients.Transmission { public class TransmissionException : DownloadClientException { diff --git a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionPriority.cs b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionPriority.cs index 1cf99c501..d896909b3 100644 --- a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionPriority.cs +++ b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionPriority.cs @@ -1,4 +1,4 @@ -namespace NzbDrone.Core.Download.Clients.Transmission +namespace NzbDrone.Core.Download.Clients.Transmission { public enum TransmissionPriority { diff --git a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionProxy.cs b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionProxy.cs index 1172b600a..2c2334f44 100644 --- a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionProxy.cs +++ b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionProxy.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Net; using Newtonsoft.Json.Linq; @@ -141,7 +141,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission private TransmissionResponse GetSessionVariables(TransmissionSettings settings) { - // Retrieve transmission information such as the default download directory, bandwith throttling and seed ratio. + // Retrieve transmission information such as the default download directory, bandwidth throttling and seed ratio. return ProcessRequest("session-get", null, settings); } diff --git a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionResponse.cs b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionResponse.cs index 5d16754b7..68dc7f4d2 100644 --- a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionResponse.cs +++ b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionResponse.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace NzbDrone.Core.Download.Clients.Transmission { diff --git a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionTorrent.cs b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionTorrent.cs index 3abb5d4e8..70ab8a3b9 100644 --- a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionTorrent.cs +++ b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionTorrent.cs @@ -1,4 +1,4 @@ -namespace NzbDrone.Core.Download.Clients.Transmission +namespace NzbDrone.Core.Download.Clients.Transmission { public class TransmissionTorrent { @@ -9,7 +9,7 @@ public long TotalSize { get; set; } public long LeftUntilDone { get; set; } public bool IsFinished { get; set; } - public int Eta { get; set; } + public long Eta { get; set; } public TransmissionTorrentStatus Status { get; set; } public int SecondsDownloading { get; set; } public int SecondsSeeding { get; set; } diff --git a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionTorrentStatus.cs b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionTorrentStatus.cs index 13e40f04e..f4683bd1b 100644 --- a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionTorrentStatus.cs +++ b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionTorrentStatus.cs @@ -1,4 +1,4 @@ -namespace NzbDrone.Core.Download.Clients.Transmission +namespace NzbDrone.Core.Download.Clients.Transmission { public enum TransmissionTorrentStatus { diff --git a/src/NzbDrone.Core/Download/Clients/Vuze/Vuze.cs b/src/NzbDrone.Core/Download/Clients/Vuze/Vuze.cs index 107b299cb..79f5df0e4 100644 --- a/src/NzbDrone.Core/Download/Clients/Vuze/Vuze.cs +++ b/src/NzbDrone.Core/Download/Clients/Vuze/Vuze.cs @@ -27,7 +27,7 @@ namespace NzbDrone.Core.Download.Clients.Vuze // - A multi-file torrent is downloaded in a job folder and 'outputPath' points to that directory directly. // - A single-file torrent is downloaded in the root folder and 'outputPath' poinst to that root folder. // We have to make sure the return value points to the job folder OR file. - if (outputPath == default || outputPath.FileName == torrent.Name || torrent.FileCount > 1) + if (outputPath.FileName == torrent.Name || torrent.FileCount > 1) { _logger.Trace("Vuze output directory: {0}", outputPath); } From 31c2917bad63a817b932a6fe298616a72ac3771d Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 8 Jun 2023 00:29:48 +0300 Subject: [PATCH 0062/1128] Fixed: (Indexers) Allow RSS searches in HttpIndexerBase --- .../Definitions/TorrentRss/TorrentRssIndexer.cs | 2 ++ src/NzbDrone.Core/Indexers/HttpIndexerBase.cs | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexer.cs b/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexer.cs index c971f28e9..a151d5525 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexer.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexer.cs @@ -15,6 +15,8 @@ namespace NzbDrone.Core.Indexers.Definitions.TorrentRss public override string Description => "Generic RSS Feed containing torrents"; public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Public; + public override bool SupportsRss => true; + public override bool SupportsSearch => false; public override int PageSize => 0; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs b/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs index 81c6f396a..6d7f91ece 100644 --- a/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs +++ b/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs @@ -56,7 +56,7 @@ namespace NzbDrone.Core.Indexers public override Task Fetch(MovieSearchCriteria searchCriteria) { - if (!SupportsSearch) + if (!SupportsSearch && !SupportsRss) { return Task.FromResult(new IndexerPageableQueryResult()); } @@ -71,7 +71,7 @@ namespace NzbDrone.Core.Indexers public override Task Fetch(MusicSearchCriteria searchCriteria) { - if (!SupportsSearch) + if (!SupportsSearch && !SupportsRss) { return Task.FromResult(new IndexerPageableQueryResult()); } @@ -86,7 +86,7 @@ namespace NzbDrone.Core.Indexers public override Task Fetch(TvSearchCriteria searchCriteria) { - if (!SupportsSearch) + if (!SupportsSearch && !SupportsRss) { return Task.FromResult(new IndexerPageableQueryResult()); } @@ -101,7 +101,7 @@ namespace NzbDrone.Core.Indexers public override Task Fetch(BookSearchCriteria searchCriteria) { - if (!SupportsSearch) + if (!SupportsSearch && !SupportsRss) { return Task.FromResult(new IndexerPageableQueryResult()); } @@ -116,7 +116,7 @@ namespace NzbDrone.Core.Indexers public override Task Fetch(BasicSearchCriteria searchCriteria) { - if (!SupportsSearch) + if (!SupportsSearch && !SupportsRss) { return Task.FromResult(new IndexerPageableQueryResult()); } From 7b551a0af1d23b7fcee42ee278a184d5620c36ab Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 11 Jun 2023 07:42:41 +0300 Subject: [PATCH 0063/1128] Update Anidub description --- src/NzbDrone.Core/Indexers/Definitions/Anidub.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/Anidub.cs b/src/NzbDrone.Core/Indexers/Definitions/Anidub.cs index b52d11b3c..4581abd29 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Anidub.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Anidub.cs @@ -25,7 +25,7 @@ namespace NzbDrone.Core.Indexers.Definitions { public override string Name => "Anidub"; public override string[] IndexerUrls => new[] { "https://tr.anidub.com/" }; - public override string Description => "Anidub is russian anime voiceover group and eponymous anime tracker."; + public override string Description => "Anidub is RUSSIAN anime voiceover group and eponymous anime tracker."; public override string Language => "ru-RU"; public override Encoding Encoding => Encoding.UTF8; public override DownloadProtocol Protocol => DownloadProtocol.Torrent; From 9042525f227cb0fc048a533d47715f88ac07ff7c Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 11 Jun 2023 09:33:46 +0300 Subject: [PATCH 0064/1128] Bump version to 1.6.1 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 5e6790a2e..bad7ece7e 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.6.0' + majorVersion: '1.6.1' minorVersion: $[counter('minorVersion', 1)] prowlarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(prowlarrVersion)' From e658e3fe487cb14ae6641c8b723454badfa8659b Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 12 Jun 2023 03:08:57 +0300 Subject: [PATCH 0065/1128] Fixed: (Cardigann) Skip duplicated GET requests --- .../Cardigann/CardigannRequestGenerator.cs | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannRequestGenerator.cs b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannRequestGenerator.cs index 814799752..17b1a2283 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannRequestGenerator.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannRequestGenerator.cs @@ -1073,9 +1073,9 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann variables[".Query.Keywords"] = string.Join(" ", keywordTokens); variables[".Keywords"] = ApplyFilters((string)variables[".Query.Keywords"], search.Keywordsfilters, variables); - // TODO: prepare queries first and then send them parallel - var searchPaths = search.Paths; - foreach (var searchPath in searchPaths) + var searchUrls = new List(); + + foreach (var searchPath in search.Paths) { variables[".Categories"] = mappedCategories; @@ -1158,14 +1158,20 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann } } - if (method == HttpMethod.Get) + if (method == HttpMethod.Get && queryCollection.Count > 0) { - if (queryCollection.Count > 0) - { - searchUrl += "?" + queryCollection.GetQueryString(_encoding); - } + searchUrl += "?" + queryCollection.GetQueryString(_encoding); } + if (method == HttpMethod.Get && searchUrls.Contains(searchUrl)) + { + _logger.Trace("Skip duplicated request {0}", searchUrl); + + continue; + } + + searchUrls.Add(searchUrl); + _logger.Debug($"Adding request: {searchUrl}"); var requestBuilder = new HttpRequestBuilder(searchUrl) From b98f9a945de995f2248cd46f78cc643f8bf802f3 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 14 Jun 2023 04:11:26 +0300 Subject: [PATCH 0066/1128] Fix use of TmdbId in NewznabRequestGenerator --- .../Indexers/Definitions/Newznab/NewznabRequestGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/Newznab/NewznabRequestGenerator.cs b/src/NzbDrone.Core/Indexers/Definitions/Newznab/NewznabRequestGenerator.cs index 297488721..0ce17321e 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Newznab/NewznabRequestGenerator.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Newznab/NewznabRequestGenerator.cs @@ -129,7 +129,7 @@ namespace NzbDrone.Core.Indexers.Newznab if (searchCriteria.TmdbId.HasValue && capabilities.TvSearchTvdbAvailable) { - parameters.Set("tmdbid", searchCriteria.TvdbId.Value.ToString()); + parameters.Set("tmdbid", searchCriteria.TmdbId.Value.ToString()); } if (searchCriteria.ImdbId.IsNotNullOrWhiteSpace() && capabilities.TvSearchImdbAvailable) From 83166fb0b5e445093e599b0ff95cbbc5b1aa9173 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 14 Jun 2023 07:11:50 +0300 Subject: [PATCH 0067/1128] Allow array of string as value in EnhancedSelectInput --- frontend/src/Components/Form/EnhancedSelectInput.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/Components/Form/EnhancedSelectInput.js b/frontend/src/Components/Form/EnhancedSelectInput.js index 4df54092c..cc4215025 100644 --- a/frontend/src/Components/Form/EnhancedSelectInput.js +++ b/frontend/src/Components/Form/EnhancedSelectInput.js @@ -578,7 +578,7 @@ EnhancedSelectInput.propTypes = { className: PropTypes.string, disabledClassName: PropTypes.string, name: PropTypes.string.isRequired, - value: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.arrayOf(PropTypes.number)]).isRequired, + value: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.arrayOf(PropTypes.string), PropTypes.arrayOf(PropTypes.number)]).isRequired, values: PropTypes.arrayOf(PropTypes.object).isRequired, isDisabled: PropTypes.bool.isRequired, isFetching: PropTypes.bool.isRequired, From 4561859c2b3e8edf5ffab994f72ec8f97aca8c53 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 14 Jun 2023 10:03:02 +0300 Subject: [PATCH 0068/1128] Fixed: (UI) Case-insensitive sorting for add indexer modal --- frontend/src/Indexer/Add/AddIndexerModalContent.js | 2 +- frontend/src/Store/Actions/indexerActions.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/Indexer/Add/AddIndexerModalContent.js b/frontend/src/Indexer/Add/AddIndexerModalContent.js index e5db3a937..04db2878b 100644 --- a/frontend/src/Indexer/Add/AddIndexerModalContent.js +++ b/frontend/src/Indexer/Add/AddIndexerModalContent.js @@ -26,7 +26,7 @@ const columns = [ isVisible: true }, { - name: 'name', + name: 'sortName', label: translate('Name'), isSortable: true, isVisible: true diff --git a/frontend/src/Store/Actions/indexerActions.js b/frontend/src/Store/Actions/indexerActions.js index a30d6a73a..8a05011b4 100644 --- a/frontend/src/Store/Actions/indexerActions.js +++ b/frontend/src/Store/Actions/indexerActions.js @@ -41,7 +41,7 @@ export const defaultState = { isFetching: false, isPopulated: false, error: null, - sortKey: 'name', + sortKey: 'sortName', sortDirection: sortDirections.ASCENDING, items: [] } From 46d930e903eceb2b2deffbf77f5c49ced47bbc6c Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 16 Jun 2023 00:06:11 +0300 Subject: [PATCH 0069/1128] Apply template text to switch cases in Cardigann --- .../Indexers/Definitions/Cardigann/CardigannBase.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannBase.cs b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannBase.cs index 8802ce47b..28675ec54 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannBase.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannBase.cs @@ -169,7 +169,7 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann { if (selection.Matches(@case.Key) || QuerySelector(selection, @case.Key) != null) { - value = @case.Value; + value = ApplyGoTemplateText(@case.Value, variables); break; } } @@ -178,7 +178,7 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann { if (required) { - throw new Exception(string.Format("None of the case selectors \"{0}\" matched {1}", string.Join(",", selector.Case), selection.ToHtmlPretty())); + throw new Exception($"None of the case selectors \"{string.Join(",", selector.Case)}\" matched {selection.ToHtmlPretty()}"); } return null; @@ -249,11 +249,11 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann if (selector.Case != null) { - foreach (var jcase in selector.Case) + foreach (var @case in selector.Case) { - if (value.Equals(jcase.Key) || jcase.Key.Equals("*")) + if ((value != null && value.Equals(@case.Key)) || @case.Key.Equals("*")) { - value = jcase.Value; + value = ApplyGoTemplateText(@case.Value, variables); break; } } @@ -262,7 +262,7 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann { if (required) { - throw new Exception(string.Format("None of the case selectors \"{0}\" matched {1}", string.Join(",", selector.Case), parentObj.ToString())); + throw new Exception($"None of the case selectors \"{string.Join(",", selector.Case)}\" matched {parentObj}"); } return null; From a3ccc3d0cf531de11f268d19f229ee0e97d6db51 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 16 Jun 2023 02:34:36 +0300 Subject: [PATCH 0070/1128] Close database connections in housekeeping tasks --- .../CleanupOrphanedApplicationStatus.cs | 13 ++++++------- .../CleanupOrphanedDownloadClientStatus.cs | 13 ++++++------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedApplicationStatus.cs b/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedApplicationStatus.cs index 86e4cd2a5..3c5d91ca1 100644 --- a/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedApplicationStatus.cs +++ b/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedApplicationStatus.cs @@ -14,14 +14,13 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers public void Clean() { - var mapper = _database.OpenConnection(); - + using var mapper = _database.OpenConnection(); mapper.Execute(@"DELETE FROM ""ApplicationStatus"" - WHERE ""Id"" IN ( - SELECT ""ApplicationStatus"".""Id"" FROM ""ApplicationStatus"" - LEFT OUTER JOIN ""Applications"" - ON ""ApplicationStatus"".""ProviderId"" = ""Applications"".""Id"" - WHERE ""Applications"".""Id"" IS NULL)"); + WHERE ""Id"" IN ( + SELECT ""ApplicationStatus"".""Id"" FROM ""ApplicationStatus"" + LEFT OUTER JOIN ""Applications"" + ON ""ApplicationStatus"".""ProviderId"" = ""Applications"".""Id"" + WHERE ""Applications"".""Id"" IS NULL)"); } } } diff --git a/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedDownloadClientStatus.cs b/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedDownloadClientStatus.cs index 5a6af9fd8..fe1adfbd6 100644 --- a/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedDownloadClientStatus.cs +++ b/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedDownloadClientStatus.cs @@ -14,14 +14,13 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers public void Clean() { - var mapper = _database.OpenConnection(); - + using var mapper = _database.OpenConnection(); mapper.Execute(@"DELETE FROM ""DownloadClientStatus"" - WHERE ""Id"" IN ( - SELECT ""DownloadClientStatus"".""Id"" FROM ""DownloadClientStatus"" - LEFT OUTER JOIN ""DownloadClients"" - ON ""DownloadClientStatus"".""ProviderId"" = ""DownloadClients"".""Id"" - WHERE ""DownloadClients"".""Id"" IS NULL)"); + WHERE ""Id"" IN ( + SELECT ""DownloadClientStatus"".""Id"" FROM ""DownloadClientStatus"" + LEFT OUTER JOIN ""DownloadClients"" + ON ""DownloadClientStatus"".""ProviderId"" = ""DownloadClients"".""Id"" + WHERE ""DownloadClients"".""Id"" IS NULL)"); } } } From d21debe77f27e43cd807ba67e700fda4351eb6a8 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 16 Jun 2023 02:39:31 +0300 Subject: [PATCH 0071/1128] Convert to 'using' declaration in Housekeeping Tasks --- .../Housekeepers/CleanupAdditionalUsers.cs | 12 ++++---- .../CleanupOrphanedHistoryItems.cs | 16 +++++------ .../CleanupOrphanedIndexerStatus.cs | 16 +++++------ .../Housekeepers/CleanupUnusedTags.cs | 28 +++++++++---------- .../FixFutureRunScheduledTasks.cs | 12 ++++---- 5 files changed, 37 insertions(+), 47 deletions(-) diff --git a/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupAdditionalUsers.cs b/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupAdditionalUsers.cs index 8b36317ec..0f525a278 100644 --- a/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupAdditionalUsers.cs +++ b/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupAdditionalUsers.cs @@ -14,13 +14,11 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers public void Clean() { - using (var mapper = _database.OpenConnection()) - { - mapper.Execute(@"DELETE FROM ""Users"" - WHERE ""Id"" NOT IN ( - SELECT ""Id"" FROM ""Users"" - LIMIT 1)"); - } + using var mapper = _database.OpenConnection(); + mapper.Execute(@"DELETE FROM ""Users"" + WHERE ""Id"" NOT IN ( + SELECT ""Id"" FROM ""Users"" + LIMIT 1)"); } } } diff --git a/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedHistoryItems.cs b/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedHistoryItems.cs index e6d8d789d..571304073 100644 --- a/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedHistoryItems.cs +++ b/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedHistoryItems.cs @@ -19,15 +19,13 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers private void CleanupOrphanedByIndexer() { - using (var mapper = _database.OpenConnection()) - { - mapper.Execute(@"DELETE FROM ""History"" - WHERE ""Id"" IN ( - SELECT ""History"".""Id"" FROM ""History"" - LEFT OUTER JOIN ""Indexers"" - ON ""History"".""IndexerId"" = ""Indexers"".""Id"" - WHERE ""Indexers"".""Id"" IS NULL)"); - } + using var mapper = _database.OpenConnection(); + mapper.Execute(@"DELETE FROM ""History"" + WHERE ""Id"" IN ( + SELECT ""History"".""Id"" FROM ""History"" + LEFT OUTER JOIN ""Indexers"" + ON ""History"".""IndexerId"" = ""Indexers"".""Id"" + WHERE ""Indexers"".""Id"" IS NULL)"); } } } diff --git a/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedIndexerStatus.cs b/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedIndexerStatus.cs index 059f059e4..9486641b5 100644 --- a/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedIndexerStatus.cs +++ b/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedIndexerStatus.cs @@ -14,15 +14,13 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers public void Clean() { - using (var mapper = _database.OpenConnection()) - { - mapper.Execute(@"DELETE FROM ""IndexerStatus"" - WHERE ""Id"" IN ( - SELECT ""IndexerStatus"".""Id"" FROM ""IndexerStatus"" - LEFT OUTER JOIN ""Indexers"" - ON ""IndexerStatus"".""ProviderId"" = ""Indexers"".""Id"" - WHERE ""Indexers"".""Id"" IS NULL)"); - } + using var mapper = _database.OpenConnection(); + mapper.Execute(@"DELETE FROM ""IndexerStatus"" + WHERE ""Id"" IN ( + SELECT ""IndexerStatus"".""Id"" FROM ""IndexerStatus"" + LEFT OUTER JOIN ""Indexers"" + ON ""IndexerStatus"".""ProviderId"" = ""Indexers"".""Id"" + WHERE ""Indexers"".""Id"" IS NULL)"); } } } diff --git a/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupUnusedTags.cs b/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupUnusedTags.cs index 1df062918..1ad3f91f1 100644 --- a/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupUnusedTags.cs +++ b/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupUnusedTags.cs @@ -17,23 +17,21 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers public void Clean() { - using (var mapper = _database.OpenConnection()) + using var mapper = _database.OpenConnection(); + var usedTags = new[] { "Notifications", "IndexerProxies", "Indexers", "Applications" } + .SelectMany(v => GetUsedTags(v, mapper)) + .Distinct() + .ToArray(); + + if (usedTags.Length > 0) { - var usedTags = new[] { "Notifications", "IndexerProxies", "Indexers", "Applications" } - .SelectMany(v => GetUsedTags(v, mapper)) - .Distinct() - .ToArray(); + var usedTagsList = string.Join(",", usedTags.Select(d => d.ToString()).ToArray()); - if (usedTags.Length > 0) - { - var usedTagsList = string.Join(",", usedTags.Select(d => d.ToString()).ToArray()); - - mapper.Execute($"DELETE FROM \"Tags\" WHERE NOT \"Id\" IN ({usedTagsList})"); - } - else - { - mapper.Execute($"DELETE FROM \"Tags\""); - } + mapper.Execute($"DELETE FROM \"Tags\" WHERE NOT \"Id\" IN ({usedTagsList})"); + } + else + { + mapper.Execute("DELETE FROM \"Tags\""); } } diff --git a/src/NzbDrone.Core/Housekeeping/Housekeepers/FixFutureRunScheduledTasks.cs b/src/NzbDrone.Core/Housekeeping/Housekeepers/FixFutureRunScheduledTasks.cs index 6b45ed0c4..62704c023 100644 --- a/src/NzbDrone.Core/Housekeeping/Housekeepers/FixFutureRunScheduledTasks.cs +++ b/src/NzbDrone.Core/Housekeeping/Housekeepers/FixFutureRunScheduledTasks.cs @@ -24,13 +24,11 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers _logger.Debug("Not running scheduled task last execution cleanup during debug"); } - using (var mapper = _database.OpenConnection()) - { - mapper.Execute(@"UPDATE ""ScheduledTasks"" - SET ""LastExecution"" = @time - WHERE ""LastExecution"" > @time", - new { time = DateTime.UtcNow }); - } + using var mapper = _database.OpenConnection(); + mapper.Execute(@"UPDATE ""ScheduledTasks"" + SET ""LastExecution"" = @time + WHERE ""LastExecution"" > @time", + new { time = DateTime.UtcNow }); } } } From ef0f8e25fd1d97240b5a18747207d6beb39a3d64 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 13 Jun 2023 06:41:06 +0300 Subject: [PATCH 0072/1128] Sort limits in IndexerCapabilities --- src/NzbDrone.Core/Indexers/IndexerCapabilities.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/IndexerCapabilities.cs b/src/NzbDrone.Core/Indexers/IndexerCapabilities.cs index cec5f59db..cec80e194 100644 --- a/src/NzbDrone.Core/Indexers/IndexerCapabilities.cs +++ b/src/NzbDrone.Core/Indexers/IndexerCapabilities.cs @@ -455,10 +455,10 @@ namespace NzbDrone.Core.Indexers new XElement("caps", new XElement("server", new XAttribute("title", "Prowlarr")), - LimitsMax != null || LimitsDefault != null ? + LimitsDefault != null || LimitsMax != null ? new XElement("limits", - LimitsMax != null ? new XAttribute("max", LimitsMax) : null, - LimitsDefault != null ? new XAttribute("default", LimitsDefault) : null) + LimitsDefault != null ? new XAttribute("default", LimitsDefault) : null, + LimitsMax != null ? new XAttribute("max", LimitsMax) : null) : null, new XElement("searching", new XElement("search", From 119164f72942b4ef4d38d07c777c57d1301cebd9 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 13 Jun 2023 06:41:57 +0300 Subject: [PATCH 0073/1128] Show indexer privacy in search results --- src/NzbDrone.Core/IndexerSearch/NewznabResults.cs | 8 ++++++-- src/NzbDrone.Core/Indexers/IndexerBase.cs | 1 + src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs | 1 + 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/NzbDrone.Core/IndexerSearch/NewznabResults.cs b/src/NzbDrone.Core/IndexerSearch/NewznabResults.cs index 9943d3d82..2845b8972 100644 --- a/src/NzbDrone.Core/IndexerSearch/NewznabResults.cs +++ b/src/NzbDrone.Core/IndexerSearch/NewznabResults.cs @@ -76,8 +76,12 @@ namespace NzbDrone.Core.IndexerSearch select new XElement("item", new XElement("title", RemoveInvalidXMLChars(r.Title)), new XElement("description", RemoveInvalidXMLChars(r.Description)), - new XElement("guid", r.Guid), // GUID and (Link or Magnet) are mandatory - new XElement("prowlarrindexer", new XAttribute("id", r.IndexerId), r.Indexer), + new XElement("guid", r.Guid), // GUID and (Link or Magnet) are mandatory + new XElement( + "prowlarrindexer", + new XAttribute("id", r.IndexerId), + new XAttribute("type", r.IndexerPrivacy switch { IndexerPrivacy.Private => "private", IndexerPrivacy.Public => "public", _ => "semi-private" }), + r.Indexer), r.InfoUrl == null ? null : new XElement("comments", r.InfoUrl), r.PublishDate == DateTime.MinValue ? new XElement("pubDate", XmlDateFormat(DateTime.Now)) : new XElement("pubDate", XmlDateFormat(r.PublishDate)), new XElement("size", r.Size), diff --git a/src/NzbDrone.Core/Indexers/IndexerBase.cs b/src/NzbDrone.Core/Indexers/IndexerBase.cs index 8164c0345..e16f6b342 100644 --- a/src/NzbDrone.Core/Indexers/IndexerBase.cs +++ b/src/NzbDrone.Core/Indexers/IndexerBase.cs @@ -128,6 +128,7 @@ namespace NzbDrone.Core.Indexers c.IndexerId = Definition.Id; c.Indexer = Definition.Name; c.DownloadProtocol = Protocol; + c.IndexerPrivacy = ((IndexerDefinition)Definition).Privacy; c.IndexerPriority = ((IndexerDefinition)Definition).Priority; if (Protocol == DownloadProtocol.Torrent) diff --git a/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs b/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs index 22827f43c..7d8c83d50 100644 --- a/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs +++ b/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs @@ -25,6 +25,7 @@ namespace NzbDrone.Core.Parser.Model public int IndexerId { get; set; } public string Indexer { get; set; } public int IndexerPriority { get; set; } + public IndexerPrivacy IndexerPrivacy { get; set; } public DownloadProtocol DownloadProtocol { get; set; } public int? Grabs { get; set; } public int? Files { get; set; } From 51e33740b0586ce28ee53246d72a4100b59087c3 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 17 Jun 2023 01:08:06 +0300 Subject: [PATCH 0074/1128] Update import path in CategoryLabel --- frontend/src/Search/Table/CategoryLabel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/Search/Table/CategoryLabel.js b/frontend/src/Search/Table/CategoryLabel.js index 80ca3a61d..5c076c521 100644 --- a/frontend/src/Search/Table/CategoryLabel.js +++ b/frontend/src/Search/Table/CategoryLabel.js @@ -1,8 +1,8 @@ import PropTypes from 'prop-types'; import React from 'react'; import Label from 'Components/Label'; +import Tooltip from 'Components/Tooltip/Tooltip'; import { kinds, tooltipPositions } from 'Helpers/Props'; -import Tooltip from '../../Components/Tooltip/Tooltip'; function CategoryLabel({ categories }) { const sortedCategories = categories.filter((cat) => cat.name !== undefined).sort((c) => c.id); From 0ff0fe2e68f3abf7b8e4d6bf0c1e9dee4eb68227 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 17 Jun 2023 02:08:40 +0300 Subject: [PATCH 0075/1128] Prevent NullRef when deleting missing backups --- .../System/Backup/BackupController.cs | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/Prowlarr.Api.V1/System/Backup/BackupController.cs b/src/Prowlarr.Api.V1/System/Backup/BackupController.cs index bcb236652..927026805 100644 --- a/src/Prowlarr.Api.V1/System/Backup/BackupController.cs +++ b/src/Prowlarr.Api.V1/System/Backup/BackupController.cs @@ -20,7 +20,7 @@ namespace Prowlarr.Api.V1.System.Backup private readonly IAppFolderInfo _appFolderInfo; private readonly IDiskProvider _diskProvider; - private static readonly List ValidExtensions = new List { ".zip", ".db", ".xml" }; + private static readonly List ValidExtensions = new () { ".zip", ".db", ".xml" }; public BackupController(IBackupService backupService, IAppFolderInfo appFolderInfo, @@ -38,22 +38,28 @@ namespace Prowlarr.Api.V1.System.Backup var backups = _backupService.GetBackups(); return backups.Select(b => new BackupResource - { - Id = GetBackupId(b), - Name = b.Name, - Path = $"/backup/{b.Type.ToString().ToLower()}/{b.Name}", - Type = b.Type, - Size = b.Size, - Time = b.Time - }) - .OrderByDescending(b => b.Time) - .ToList(); + { + Id = GetBackupId(b), + Name = b.Name, + Path = $"/backup/{b.Type.ToString().ToLower()}/{b.Name}", + Type = b.Type, + Size = b.Size, + Time = b.Time + }) + .OrderByDescending(b => b.Time) + .ToList(); } [RestDeleteById] public void DeleteBackup(int id) { var backup = GetBackup(id); + + if (backup == null) + { + throw new NotFoundException(); + } + var path = GetBackupPath(backup); if (!_diskProvider.FileExists(path)) From 4a81630073baa9989168f342c5296eac1cf71a02 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sun, 27 Feb 2022 00:17:40 -0800 Subject: [PATCH 0076/1128] Fixed: Clearing logs not updating UI once complete (cherry picked from commit 56b3acddc9f50f59c78c03ca072fe802752b88a7) --- frontend/src/System/Events/LogsTableConnector.js | 9 ++++++++- .../src/System/Logs/Files/LogFilesConnector.js | 15 ++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/frontend/src/System/Events/LogsTableConnector.js b/frontend/src/System/Events/LogsTableConnector.js index 20e6eafbf..a717cba15 100644 --- a/frontend/src/System/Events/LogsTableConnector.js +++ b/frontend/src/System/Events/LogsTableConnector.js @@ -96,7 +96,14 @@ class LogsTableConnector extends Component { }; onClearLogsPress = () => { - this.props.executeCommand({ name: commandNames.CLEAR_LOGS }); + this.props.executeCommand({ + name: commandNames.CLEAR_LOGS, + commandFinished: this.onCommandFinished + }); + }; + + onCommandFinished = () => { + this.props.gotoLogsFirstPage(); }; // diff --git a/frontend/src/System/Logs/Files/LogFilesConnector.js b/frontend/src/System/Logs/Files/LogFilesConnector.js index 03d958b33..98a55f32f 100644 --- a/frontend/src/System/Logs/Files/LogFilesConnector.js +++ b/frontend/src/System/Logs/Files/LogFilesConnector.js @@ -50,12 +50,6 @@ class LogFilesConnector extends Component { this.props.fetchLogFiles(); } - componentDidUpdate(prevProps) { - if (prevProps.deleteFilesExecuting && !this.props.deleteFilesExecuting) { - this.props.fetchLogFiles(); - } - } - // // Listeners @@ -64,7 +58,14 @@ class LogFilesConnector extends Component { }; onDeleteFilesPress = () => { - this.props.executeCommand({ name: commandNames.DELETE_LOG_FILES }); + this.props.executeCommand({ + name: commandNames.DELETE_LOG_FILES, + commandFinished: this.onCommandFinished + }); + }; + + onCommandFinished = () => { + this.props.fetchLogFiles(); }; // From 40a932cd2830d2d49b5bb3df630057af09f5e138 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 17 Jun 2023 02:09:28 +0300 Subject: [PATCH 0077/1128] Improved page loading errors --- frontend/src/Components/Page/PageSectionContent.js | 4 +++- frontend/src/History/History.js | 11 ++++++----- frontend/src/Indexer/Stats/Stats.js | 5 +++-- frontend/src/Search/SearchIndex.js | 7 ++++--- .../src/Settings/Development/DevelopmentSettings.js | 7 ++++--- frontend/src/Settings/General/GeneralSettings.js | 5 +++-- frontend/src/Settings/UI/UISettings.js | 7 ++++--- frontend/src/System/Backup/Backups.js | 11 ++++++----- frontend/src/System/Events/LogsTable.js | 7 ++++--- frontend/src/System/Logs/Files/LogFiles.js | 6 +++--- frontend/src/System/Updates/Updates.js | 5 +++-- src/NzbDrone.Core/Localization/Core/en.json | 1 + 12 files changed, 44 insertions(+), 32 deletions(-) diff --git a/frontend/src/Components/Page/PageSectionContent.js b/frontend/src/Components/Page/PageSectionContent.js index 774b88669..2cef9eef1 100644 --- a/frontend/src/Components/Page/PageSectionContent.js +++ b/frontend/src/Components/Page/PageSectionContent.js @@ -1,6 +1,8 @@ import PropTypes from 'prop-types'; import React from 'react'; +import Alert from 'Components/Alert'; import LoadingIndicator from 'Components/Loading/LoadingIndicator'; +import { kinds } from 'Helpers/Props'; function PageSectionContent(props) { const { @@ -17,7 +19,7 @@ function PageSectionContent(props) { ); } else if (!isFetching && !!error) { return ( -
{errorMessage}
+ {errorMessage} ); } else if (isPopulated && !error) { return ( diff --git a/frontend/src/History/History.js b/frontend/src/History/History.js index fa33beffc..c26a8e7ae 100644 --- a/frontend/src/History/History.js +++ b/frontend/src/History/History.js @@ -1,5 +1,6 @@ import PropTypes from 'prop-types'; import React, { Component } from 'react'; +import Alert from 'Components/Alert'; import LoadingIndicator from 'Components/Loading/LoadingIndicator'; import FilterMenu from 'Components/Menu/FilterMenu'; import ConfirmModal from 'Components/Modal/ConfirmModal'; @@ -121,9 +122,9 @@ class History extends Component { { !isFetchingAny && hasError && -
+ {translate('UnableToLoadHistory')} -
+ } { @@ -131,9 +132,9 @@ class History extends Component { // wait for the episodes to populate because they are never coming. isPopulated && !hasError && !items.length && -
- No history found -
+ + {translate('NoHistoryFound')} + } { diff --git a/frontend/src/Indexer/Stats/Stats.js b/frontend/src/Indexer/Stats/Stats.js index 80f5fd17f..73bc8ac34 100644 --- a/frontend/src/Indexer/Stats/Stats.js +++ b/frontend/src/Indexer/Stats/Stats.js @@ -1,5 +1,6 @@ import PropTypes from 'prop-types'; import React from 'react'; +import Alert from 'Components/Alert'; import BarChart from 'Components/Chart/BarChart'; import DoughnutChart from 'Components/Chart/DoughnutChart'; import StackedBarChart from 'Components/Chart/StackedBarChart'; @@ -178,9 +179,9 @@ function Stats(props) { { !isFetching && !!error && -
+ {getErrorMessage(error, 'Failed to load indexer stats from API')} -
+ } { diff --git a/frontend/src/Search/SearchIndex.js b/frontend/src/Search/SearchIndex.js index 012dc48da..ef4663428 100644 --- a/frontend/src/Search/SearchIndex.js +++ b/frontend/src/Search/SearchIndex.js @@ -1,6 +1,7 @@ import _ from 'lodash'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; +import Alert from 'Components/Alert'; import LoadingIndicator from 'Components/Loading/LoadingIndicator'; import PageContent from 'Components/Page/PageContent'; import PageContentBody from 'Components/Page/PageContentBody'; @@ -10,7 +11,7 @@ import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton'; import PageToolbarSection from 'Components/Page/Toolbar/PageToolbarSection'; import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator'; import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper'; -import { align, icons, sortDirections } from 'Helpers/Props'; +import { align, icons, kinds, sortDirections } from 'Helpers/Props'; import NoIndexer from 'Indexer/NoIndexer'; import * as keyCodes from 'Utilities/Constants/keyCodes'; import getErrorMessage from 'Utilities/Object/getErrorMessage'; @@ -309,9 +310,9 @@ class SearchIndex extends Component { { !isFetching && !!error && -
+ {getErrorMessage(error, 'Failed to load search results from API')} -
+ } { diff --git a/frontend/src/Settings/Development/DevelopmentSettings.js b/frontend/src/Settings/Development/DevelopmentSettings.js index 7c25e2c68..128055ba8 100644 --- a/frontend/src/Settings/Development/DevelopmentSettings.js +++ b/frontend/src/Settings/Development/DevelopmentSettings.js @@ -1,5 +1,6 @@ import PropTypes from 'prop-types'; import React, { Component } from 'react'; +import Alert from 'Components/Alert'; import FieldSet from 'Components/FieldSet'; import Form from 'Components/Form/Form'; import FormGroup from 'Components/Form/FormGroup'; @@ -8,7 +9,7 @@ import FormLabel from 'Components/Form/FormLabel'; import LoadingIndicator from 'Components/Loading/LoadingIndicator'; import PageContent from 'Components/Page/PageContent'; import PageContentBody from 'Components/Page/PageContentBody'; -import { inputTypes } from 'Helpers/Props'; +import { inputTypes, kinds } from 'Helpers/Props'; import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector'; import translate from 'Utilities/String/translate'; @@ -49,9 +50,9 @@ class DevelopmentSettings extends Component { { !isFetching && error && -
+ {translate('UnableToLoadDevelopmentSettings')} -
+ } { diff --git a/frontend/src/Settings/General/GeneralSettings.js b/frontend/src/Settings/General/GeneralSettings.js index 38bb08f75..60159c126 100644 --- a/frontend/src/Settings/General/GeneralSettings.js +++ b/frontend/src/Settings/General/GeneralSettings.js @@ -1,6 +1,7 @@ import _ from 'lodash'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; +import Alert from 'Components/Alert'; import Form from 'Components/Form/Form'; import LoadingIndicator from 'Components/Loading/LoadingIndicator'; import ConfirmModal from 'Components/Modal/ConfirmModal'; @@ -123,9 +124,9 @@ class GeneralSettings extends Component { { !isFetching && error && -
+ {translate('UnableToLoadGeneralSettings')} -
+ } { diff --git a/frontend/src/Settings/UI/UISettings.js b/frontend/src/Settings/UI/UISettings.js index 83443cd72..614fd2fe0 100644 --- a/frontend/src/Settings/UI/UISettings.js +++ b/frontend/src/Settings/UI/UISettings.js @@ -1,5 +1,6 @@ import PropTypes from 'prop-types'; import React, { Component } from 'react'; +import Alert from 'Components/Alert'; import FieldSet from 'Components/FieldSet'; import Form from 'Components/Form/Form'; import FormGroup from 'Components/Form/FormGroup'; @@ -8,7 +9,7 @@ import FormLabel from 'Components/Form/FormLabel'; import LoadingIndicator from 'Components/Loading/LoadingIndicator'; import PageContent from 'Components/Page/PageContent'; import PageContentBody from 'Components/Page/PageContentBody'; -import { inputTypes } from 'Helpers/Props'; +import { inputTypes, kinds } from 'Helpers/Props'; import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector'; import themes from 'Styles/Themes'; import titleCase from 'Utilities/String/titleCase'; @@ -80,9 +81,9 @@ class UISettings extends Component { { !isFetching && error && -
+ {translate('UnableToLoadUISettings')} -
+ } { diff --git a/frontend/src/System/Backup/Backups.js b/frontend/src/System/Backup/Backups.js index 7a5e399d0..4f9cd0483 100644 --- a/frontend/src/System/Backup/Backups.js +++ b/frontend/src/System/Backup/Backups.js @@ -1,5 +1,6 @@ import PropTypes from 'prop-types'; import React, { Component } from 'react'; +import Alert from 'Components/Alert'; import LoadingIndicator from 'Components/Loading/LoadingIndicator'; import PageContent from 'Components/Page/PageContent'; import PageContentBody from 'Components/Page/PageContentBody'; @@ -8,7 +9,7 @@ import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton'; import PageToolbarSection from 'Components/Page/Toolbar/PageToolbarSection'; import Table from 'Components/Table/Table'; import TableBody from 'Components/Table/TableBody'; -import { icons } from 'Helpers/Props'; +import { icons, kinds } from 'Helpers/Props'; import translate from 'Utilities/String/translate'; import BackupRow from './BackupRow'; import RestoreBackupModalConnector from './RestoreBackupModalConnector'; @@ -107,16 +108,16 @@ class Backups extends Component { { !isFetching && !!error && -
+ {translate('UnableToLoadBackups')} -
+ } { noBackups && -
+ {translate('NoBackupsAreAvailable')} -
+ } { diff --git a/frontend/src/System/Events/LogsTable.js b/frontend/src/System/Events/LogsTable.js index 8d781afee..cdf815a2f 100644 --- a/frontend/src/System/Events/LogsTable.js +++ b/frontend/src/System/Events/LogsTable.js @@ -1,5 +1,6 @@ import PropTypes from 'prop-types'; import React from 'react'; +import Alert from 'Components/Alert'; import LoadingIndicator from 'Components/Loading/LoadingIndicator'; import FilterMenu from 'Components/Menu/FilterMenu'; import PageContent from 'Components/Page/PageContent'; @@ -11,7 +12,7 @@ import Table from 'Components/Table/Table'; import TableBody from 'Components/Table/TableBody'; import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper'; import TablePager from 'Components/Table/TablePager'; -import { align, icons } from 'Helpers/Props'; +import { align, icons, kinds } from 'Helpers/Props'; import translate from 'Utilities/String/translate'; import LogsTableRow from './LogsTableRow'; @@ -82,9 +83,9 @@ function LogsTable(props) { { isPopulated && !error && !items.length && -
+ No events found -
+ } { diff --git a/frontend/src/System/Logs/Files/LogFiles.js b/frontend/src/System/Logs/Files/LogFiles.js index 295fb36cd..1db261a82 100644 --- a/frontend/src/System/Logs/Files/LogFiles.js +++ b/frontend/src/System/Logs/Files/LogFiles.js @@ -11,7 +11,7 @@ import PageToolbarSection from 'Components/Page/Toolbar/PageToolbarSection'; import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator'; import Table from 'Components/Table/Table'; import TableBody from 'Components/Table/TableBody'; -import { icons } from 'Helpers/Props'; +import { icons, kinds } from 'Helpers/Props'; import translate from 'Utilities/String/translate'; import LogsNavMenu from '../LogsNavMenu'; import LogFilesTableRow from './LogFilesTableRow'; @@ -118,9 +118,9 @@ class LogFiles extends Component { { !isFetching && !items.length && -
+ {translate('NoLogFiles')} -
+ } diff --git a/frontend/src/System/Updates/Updates.js b/frontend/src/System/Updates/Updates.js index c17ec1e6c..6a933cf2f 100644 --- a/frontend/src/System/Updates/Updates.js +++ b/frontend/src/System/Updates/Updates.js @@ -1,6 +1,7 @@ import _ from 'lodash'; import PropTypes from 'prop-types'; import React, { Component, Fragment } from 'react'; +import Alert from 'Components/Alert'; import Icon from 'Components/Icon'; import Label from 'Components/Label'; import SpinnerButton from 'Components/Link/SpinnerButton'; @@ -61,9 +62,9 @@ class Updates extends Component { { noUpdates && -
+ {translate('NoUpdatesAreAvailable')} -
+ } { diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index 052aa2443..9a058fe1a 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -276,6 +276,7 @@ "NoBackupsAreAvailable": "No backups are available", "NoChange": "No Change", "NoChanges": "No Changes", + "NoHistoryFound": "No history found", "NoLeaveIt": "No, Leave It", "NoLinks": "No Links", "NoLogFiles": "No log files", From 8a891d07cfb0daab8a2d3e476c4906eeedd7ce64 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 17 Jun 2023 14:22:35 +0300 Subject: [PATCH 0078/1128] Test eligibility of the first request in AvistazBase --- .../Indexers/Definitions/Avistaz/AvistazBase.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/Avistaz/AvistazBase.cs b/src/NzbDrone.Core/Indexers/Definitions/Avistaz/AvistazBase.cs index 9a4fed9ad..0074f9c5b 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Avistaz/AvistazBase.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Avistaz/AvistazBase.cs @@ -93,12 +93,10 @@ namespace NzbDrone.Core.Indexers.Definitions.Avistaz var jsonResponse = new HttpResponse(ex.Response); return new ValidationFailure(string.Empty, jsonResponse.Resource?.Message ?? "Unauthorized request to indexer"); } - else - { - _logger.Warn(ex, "Unable to connect to indexer"); - return new ValidationFailure(string.Empty, "Unable to connect to indexer, check the log above the ValidationFailure for more details. " + ex.Message); - } + _logger.Warn(ex, "Unable to connect to indexer"); + + return new ValidationFailure(string.Empty, "Unable to connect to indexer, check the log above the ValidationFailure for more details. " + ex.Message); } catch (Exception ex) { @@ -107,7 +105,7 @@ namespace NzbDrone.Core.Indexers.Definitions.Avistaz return new ValidationFailure(string.Empty, "Unable to connect to indexer, check the log above the ValidationFailure for more details"); } - return null; + return await base.TestConnection(); } private async Task GetToken() From 56eb58aed111169de33b18d91ec21dc834df3812 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 18 Jun 2023 07:01:38 +0300 Subject: [PATCH 0079/1128] Bump version to 1.6.2 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index bad7ece7e..a56bb7b3b 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.6.1' + majorVersion: '1.6.2' minorVersion: $[counter('minorVersion', 1)] prowlarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(prowlarrVersion)' From f0915638f309403af08255b47587b66375bfd2d6 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 15 Jun 2023 07:50:24 +0300 Subject: [PATCH 0080/1128] New: (Apps) Sync Anime Standard Search with Sonarr Fixes #998 Closes #1732 --- src/NzbDrone.Core/Applications/Sonarr/Sonarr.cs | 9 +++++++-- src/NzbDrone.Core/Applications/Sonarr/SonarrIndexer.cs | 6 +++++- src/NzbDrone.Core/Applications/Sonarr/SonarrSettings.cs | 3 +++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/NzbDrone.Core/Applications/Sonarr/Sonarr.cs b/src/NzbDrone.Core/Applications/Sonarr/Sonarr.cs index 3b27b419d..4f43b58c5 100644 --- a/src/NzbDrone.Core/Applications/Sonarr/Sonarr.cs +++ b/src/NzbDrone.Core/Applications/Sonarr/Sonarr.cs @@ -183,12 +183,12 @@ namespace NzbDrone.Core.Applications.Sonarr { var cacheKey = $"{Settings.BaseUrl}"; var schemas = _schemaCache.Get(cacheKey, () => _sonarrV3Proxy.GetIndexerSchema(Settings), TimeSpan.FromDays(7)); - var syncFields = new List { "baseUrl", "apiPath", "apiKey", "categories", "animeCategories", "minimumSeeders", "seedCriteria.seedRatio", "seedCriteria.seedTime", "seedCriteria.seasonPackSeedTime" }; + var syncFields = new List { "baseUrl", "apiPath", "apiKey", "categories", "animeCategories", "animeStandardFormatSearch", "minimumSeeders", "seedCriteria.seedRatio", "seedCriteria.seedTime", "seedCriteria.seasonPackSeedTime" }; if (id == 0) { // Ensuring backward compatibility with older versions on first sync - syncFields.AddRange(new List { "animeStandardFormatSearch", "additionalParameters" }); + syncFields.AddRange(new List { "additionalParameters" }); } var newznab = schemas.First(i => i.Implementation == "Newznab"); @@ -218,6 +218,11 @@ namespace NzbDrone.Core.Applications.Sonarr sonarrIndexer.Fields.FirstOrDefault(x => x.Name == "categories").Value = JArray.FromObject(indexer.Capabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray())); sonarrIndexer.Fields.FirstOrDefault(x => x.Name == "animeCategories").Value = JArray.FromObject(indexer.Capabilities.Categories.SupportedCategories(Settings.AnimeSyncCategories.ToArray())); + if (sonarrIndexer.Fields.Any(x => x.Name == "animeStandardFormatSearch")) + { + sonarrIndexer.Fields.FirstOrDefault(x => x.Name == "animeStandardFormatSearch").Value = Settings.SyncAnimeStandardFormatSearch; + } + if (indexer.Protocol == DownloadProtocol.Torrent) { sonarrIndexer.Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value = ((ITorrentIndexerSettings)indexer.Settings).TorrentBaseSettings.AppMinimumSeeders ?? indexer.AppProfile.Value.MinimumSeeders; diff --git a/src/NzbDrone.Core/Applications/Sonarr/SonarrIndexer.cs b/src/NzbDrone.Core/Applications/Sonarr/SonarrIndexer.cs index e3dffaed0..03c4376c4 100644 --- a/src/NzbDrone.Core/Applications/Sonarr/SonarrIndexer.cs +++ b/src/NzbDrone.Core/Applications/Sonarr/SonarrIndexer.cs @@ -38,6 +38,10 @@ namespace NzbDrone.Core.Applications.Sonarr var otherApiPath = other.Fields.FirstOrDefault(x => x.Name == "apiPath")?.Value == null ? null : other.Fields.FirstOrDefault(x => x.Name == "apiPath").Value; var apiPathCompare = apiPath.Equals(otherApiPath); + var animeStandardFormatSearch = Fields.FirstOrDefault(x => x.Name == "animeStandardFormatSearch")?.Value == null ? null : (bool?)Convert.ToBoolean(Fields.FirstOrDefault(x => x.Name == "animeStandardFormatSearch").Value); + var otherAnimeStandardFormatSearch = other.Fields.FirstOrDefault(x => x.Name == "animeStandardFormatSearch")?.Value == null ? null : (bool?)Convert.ToBoolean(other.Fields.FirstOrDefault(x => x.Name == "animeStandardFormatSearch").Value); + var animeStandardFormatSearchCompare = animeStandardFormatSearch == otherAnimeStandardFormatSearch; + var minimumSeeders = Fields.FirstOrDefault(x => x.Name == "minimumSeeders")?.Value == null ? null : (int?)Convert.ToInt32(Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value); var otherMinimumSeeders = other.Fields.FirstOrDefault(x => x.Name == "minimumSeeders")?.Value == null ? null : (int?)Convert.ToInt32(other.Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value); var minimumSeedersCompare = minimumSeeders == otherMinimumSeeders; @@ -61,7 +65,7 @@ namespace NzbDrone.Core.Applications.Sonarr other.Implementation == Implementation && other.Priority == Priority && other.Id == Id && - apiKey && apiPathCompare && baseUrl && cats && animeCats && minimumSeedersCompare && seedRatioCompare && seedTimeCompare && seasonSeedTimeCompare; + apiKey && apiPathCompare && baseUrl && cats && animeCats && animeStandardFormatSearchCompare && minimumSeedersCompare && seedRatioCompare && seedTimeCompare && seasonSeedTimeCompare; } } } diff --git a/src/NzbDrone.Core/Applications/Sonarr/SonarrSettings.cs b/src/NzbDrone.Core/Applications/Sonarr/SonarrSettings.cs index 84b9ff9c6..92669b94e 100644 --- a/src/NzbDrone.Core/Applications/Sonarr/SonarrSettings.cs +++ b/src/NzbDrone.Core/Applications/Sonarr/SonarrSettings.cs @@ -43,6 +43,9 @@ namespace NzbDrone.Core.Applications.Sonarr [FieldDefinition(4, Label = "Anime Sync Categories", Type = FieldType.Select, SelectOptions = typeof(NewznabCategoryFieldConverter), Advanced = true, HelpText = "Only Indexers that support these categories will be synced")] public IEnumerable AnimeSyncCategories { get; set; } + [FieldDefinition(5, Label = "Sync Anime Standard Format Search", Type = FieldType.Checkbox, Advanced = true, HelpText = "Sync also searching for anime using the standard numbering")] + public bool SyncAnimeStandardFormatSearch { get; set; } + public NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); From 0155ff60fd0d3590b4729befec914a1e886b211d Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 15 Jun 2023 05:09:27 +0300 Subject: [PATCH 0081/1128] Map Cardigann capabilities from meta definition --- .../Definitions/Cardigann/Cardigann.cs | 52 ++++++++++++++++++- .../Definitions/Cardigann/CardigannMetaDef.cs | 3 +- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/Cardigann.cs b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/Cardigann.cs index 9254f9775..e4504dc91 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/Cardigann.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/Cardigann.cs @@ -166,7 +166,7 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann SupportsSearch = SupportsSearch, SupportsRedirect = SupportsRedirect, SupportsPagination = SupportsPagination, - Capabilities = new IndexerCapabilities(), + Capabilities = ParseCardigannCapabilities(definition), ExtraFields = settings }; } @@ -238,5 +238,55 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann return null; } + + private IndexerCapabilities ParseCardigannCapabilities(CardigannMetaDefinition definition) + { + var capabilities = new IndexerCapabilities(); + + if (definition.Caps == null) + { + return capabilities; + } + + capabilities.ParseCardigannSearchModes(definition.Caps.Modes); + capabilities.SupportsRawSearch = definition.Caps.Allowrawsearch; + + if (definition.Caps.Categories != null && definition.Caps.Categories.Any()) + { + foreach (var category in definition.Caps.Categories) + { + var cat = NewznabStandardCategory.GetCatByName(category.Value); + + if (cat == null) + { + continue; + } + + capabilities.Categories.AddCategoryMapping(category.Key, cat); + } + } + + if (definition.Caps.Categorymappings != null && definition.Caps.Categorymappings.Any()) + { + foreach (var categoryMapping in definition.Caps.Categorymappings) + { + IndexerCategory torznabCat = null; + + if (categoryMapping.cat != null) + { + torznabCat = NewznabStandardCategory.GetCatByName(categoryMapping.cat); + + if (torznabCat == null) + { + continue; + } + } + + capabilities.Categories.AddCategoryMapping(categoryMapping.id, torznabCat, categoryMapping.desc); + } + } + + return capabilities; + } } } diff --git a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannMetaDef.cs b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannMetaDef.cs index b252d2674..62286591c 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannMetaDef.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannMetaDef.cs @@ -19,7 +19,8 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann public List Links { get; set; } public List Legacylinks { get; set; } public List Settings { get; set; } - public string Sha { get; set; } public LoginBlock Login { get; set; } + public CapabilitiesBlock Caps { get; set; } + public string Sha { get; set; } } } From 4e03ebadc490b1df6158aea3396ee007bf2adc50 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 14 Jun 2023 07:13:33 +0300 Subject: [PATCH 0082/1128] New: (UI) Add filter by categories in add indexer modal Fixes #872 Closes #1731 --- .../Indexer/Add/AddIndexerModalContent.css | 1 + .../src/Indexer/Add/AddIndexerModalContent.js | 50 ++++++++++++++++--- src/NzbDrone.Core/Localization/Core/en.json | 1 + 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/frontend/src/Indexer/Add/AddIndexerModalContent.css b/frontend/src/Indexer/Add/AddIndexerModalContent.css index 38c00ad82..e9ad94b8f 100644 --- a/frontend/src/Indexer/Add/AddIndexerModalContent.css +++ b/frontend/src/Indexer/Add/AddIndexerModalContent.css @@ -40,6 +40,7 @@ flex: 1; flex-direction: column; margin-right: 12px; + max-width: 50%; } .filterContainer:last-child { diff --git a/frontend/src/Indexer/Add/AddIndexerModalContent.js b/frontend/src/Indexer/Add/AddIndexerModalContent.js index 04db2878b..9d36ae4e7 100644 --- a/frontend/src/Indexer/Add/AddIndexerModalContent.js +++ b/frontend/src/Indexer/Add/AddIndexerModalContent.js @@ -2,6 +2,7 @@ import PropTypes from 'prop-types'; import React, { Component } from 'react'; import Alert from 'Components/Alert'; import EnhancedSelectInput from 'Components/Form/EnhancedSelectInput'; +import NewznabCategorySelectInputConnector from 'Components/Form/NewznabCategorySelectInputConnector'; import TextInput from 'Components/Form/TextInput'; import Button from 'Components/Link/Button'; import LoadingIndicator from 'Components/Loading/LoadingIndicator'; @@ -89,7 +90,8 @@ class AddIndexerModalContent extends Component { filter: '', filterProtocols: [], filterLanguages: [], - filterPrivacyLevels: [] + filterPrivacyLevels: [], + filterCategories: [] }; } @@ -121,7 +123,13 @@ class AddIndexerModalContent extends Component { .map((language) => ({ key: language, value: language })); const filteredIndexers = indexers.filter((indexer) => { - const { filter, filterProtocols, filterLanguages, filterPrivacyLevels } = this.state; + const { + filter, + filterProtocols, + filterLanguages, + filterPrivacyLevels, + filterCategories + } = this.state; if (!indexer.name.toLowerCase().includes(filter.toLocaleLowerCase()) && !indexer.description.toLowerCase().includes(filter.toLocaleLowerCase())) { return false; @@ -139,6 +147,18 @@ class AddIndexerModalContent extends Component { return false; } + if (filterCategories.length) { + const { categories = [] } = indexer.capabilities || {}; + const flat = ({ id, subCategories = [] }) => [id, ...subCategories.flatMap(flat)]; + const flatCategories = categories + .filter((item) => item.id < 100000) + .flatMap(flat); + + if (!filterCategories.every((item) => flatCategories.includes(item))) { + return false; + } + } + return true; }); @@ -165,7 +185,7 @@ class AddIndexerModalContent extends Component {
- +
- +
- + this.setState({ filterPrivacyLevels: value })} />
+ +
+ + this.setState({ filterCategories: value })} + /> +
: null } { - error ?
{errorMessage}
: null + error ? {errorMessage} : null } { isPopulated && !!indexers.length ? @@ -237,6 +266,15 @@ class AddIndexerModalContent extends Component { : null } + { + isPopulated && !!indexers.length && !filteredIndexers.length ? + + {translate('NoIndexersFound')} + : + null + } diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index 9a058fe1a..0f9f525c9 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -277,6 +277,7 @@ "NoChange": "No Change", "NoChanges": "No Changes", "NoHistoryFound": "No history found", + "NoIndexersFound": "No indexers found", "NoLeaveIt": "No, Leave It", "NoLinks": "No Links", "NoLogFiles": "No log files", From d1ba208243ca84b0a2b21716cc067991c564acde Mon Sep 17 00:00:00 2001 From: Bakerboy448 <55419169+bakerboy448@users.noreply.github.com> Date: Tue, 16 May 2023 19:22:24 -0500 Subject: [PATCH 0083/1128] Fixed: (HttpIndexerBase) Better HTTP error handling --- src/NzbDrone.Common/Http/HttpResponse.cs | 2 + src/NzbDrone.Core/Indexers/HttpIndexerBase.cs | 59 +++++++++++++++---- 2 files changed, 48 insertions(+), 13 deletions(-) diff --git a/src/NzbDrone.Common/Http/HttpResponse.cs b/src/NzbDrone.Common/Http/HttpResponse.cs index a6c9f7f86..2931867fb 100644 --- a/src/NzbDrone.Common/Http/HttpResponse.cs +++ b/src/NzbDrone.Common/Http/HttpResponse.cs @@ -63,6 +63,8 @@ namespace NzbDrone.Common.Http public bool HasHttpError => (int)StatusCode >= 400; + public bool HasHttpServerError => (int)StatusCode >= 500; + public bool HasHttpRedirect => StatusCode == HttpStatusCode.Moved || StatusCode == HttpStatusCode.Found || StatusCode == HttpStatusCode.SeeOther || diff --git a/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs b/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs index 6d7f91ece..2a1151a6e 100644 --- a/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs +++ b/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs @@ -264,6 +264,7 @@ namespace NzbDrone.Core.Indexers var releases = new List(); var result = new IndexerPageableQueryResult(); var url = string.Empty; + var minimumBackoff = TimeSpan.FromHours(1); try { @@ -317,8 +318,7 @@ namespace NzbDrone.Core.Indexers } catch (WebException webException) { - if (webException.Status == WebExceptionStatus.NameResolutionFailure || - webException.Status == WebExceptionStatus.ConnectFailure) + if (webException.Status is WebExceptionStatus.NameResolutionFailure or WebExceptionStatus.ConnectFailure) { _indexerStatusService.RecordConnectionFailure(Definition.Id); } @@ -341,7 +341,7 @@ namespace NzbDrone.Core.Indexers { result.Queries.Add(new IndexerQueryResult { Response = ex.Response }); - var retryTime = ex.RetryAfter != TimeSpan.Zero ? ex.RetryAfter : TimeSpan.FromHours(1); + var retryTime = ex.RetryAfter != TimeSpan.Zero ? ex.RetryAfter : minimumBackoff; _indexerStatusService.RecordFailure(Definition.Id, retryTime); _logger.Warn("Request Limit reached for {0}. Disabled for {1}", this, retryTime); @@ -350,13 +350,21 @@ namespace NzbDrone.Core.Indexers { result.Queries.Add(new IndexerQueryResult { Response = ex.Response }); _indexerStatusService.RecordFailure(Definition.Id); - _logger.Warn("{0} {1}", this, ex.Message); + + if (ex.Response.HasHttpServerError) + { + _logger.Warn("Unable to connect to {0} at [{1}]. Indexer's server is unavailable. Try again later. {2}", this, url, ex.Message); + } + else + { + _logger.Warn("{0} {1}", this, ex.Message); + } } catch (RequestLimitReachedException ex) { result.Queries.Add(new IndexerQueryResult { Response = ex.Response.HttpResponse }); - _indexerStatusService.RecordFailure(Definition.Id, TimeSpan.FromHours(1)); - _logger.Warn("API Request Limit reached for {0}", this); + _indexerStatusService.RecordFailure(Definition.Id, minimumBackoff); + _logger.Warn("Request Limit reached for {0}. Disabled for {1}", this, minimumBackoff); } catch (IndexerAuthException ex) { @@ -494,7 +502,7 @@ namespace NzbDrone.Core.Indexers var response = await _httpClient.ExecuteProxiedAsync(request.HttpRequest, Definition); - // Check reponse to see if auth is needed, if needed try again + // Check response to see if auth is needed, if needed try again if (CheckIfLoginNeeded(response)) { _logger.Trace("Attempting to re-auth based on indexer search response"); @@ -507,6 +515,11 @@ namespace NzbDrone.Core.Indexers response = await _httpClient.ExecuteProxiedAsync(request.HttpRequest, Definition); } + if (CloudFlareDetectionService.IsCloudflareProtected(response)) + { + throw new CloudFlareProtectionException(response); + } + // Throw common http errors here before we try to parse if (response.HasHttpError && (request.HttpRequest.SuppressHttpErrorStatusCodes == null || !request.HttpRequest.SuppressHttpErrorStatusCodes.Contains(response.StatusCode))) { @@ -519,11 +532,11 @@ namespace NzbDrone.Core.Indexers { throw new TooManyRequestsException(request.HttpRequest, response); } - } - if (CloudFlareDetectionService.IsCloudflareProtected(response)) - { - throw new CloudFlareProtectionException(response); + if (response.HasHttpServerError) + { + throw new HttpException(request.HttpRequest, response); + } } UpdateCookies(request.HttpRequest.Cookies, DateTime.Now.AddDays(30)); @@ -594,9 +607,9 @@ namespace NzbDrone.Core.Indexers } catch (IndexerAuthException ex) { - _logger.Warn("Indexer returned result for RSS URL, Credentials appears to be invalid: " + ex.Message); + _logger.Warn("Indexer returned result for RSS URL, Credentials appears to be invalid. Response: " + ex.Message); - return new ValidationFailure("", ex.Message); + return new ValidationFailure("", "Indexer returned result for RSS URL, Credentials appears to be invalid. Response: " + ex.Message); } catch (RequestLimitReachedException ex) { @@ -629,6 +642,11 @@ namespace NzbDrone.Core.Indexers _logger.Warn(ex, "Unable to connect to indexer"); + if (ex.Response.HasHttpServerError) + { + return new ValidationFailure(string.Empty, "Unable to connect to indexer, indexer's server is unavailable. Try again later. " + ex.Message); + } + return new ValidationFailure(string.Empty, "Unable to connect to indexer, check the log above the ValidationFailure for more details. " + ex.Message); } catch (HttpRequestException ex) @@ -643,6 +661,21 @@ namespace NzbDrone.Core.Indexers return new ValidationFailure(string.Empty, "Unable to connect to indexer, possibly due to a timeout. Try again or check your network settings. " + ex.Message); } + catch (WebException webException) + { + _logger.Warn("Unable to connect to indexer."); + + if (webException.Status is WebExceptionStatus.NameResolutionFailure or WebExceptionStatus.ConnectFailure) + { + return new ValidationFailure(string.Empty, "Unable to connect to indexer connection failure. Check your connection to the indexer's server and DNS." + webException.Message); + } + + if (webException.Message.Contains("502") || webException.Message.Contains("503") || + webException.Message.Contains("504") || webException.Message.Contains("timed out")) + { + return new ValidationFailure(string.Empty, "Unable to connect to indexer, indexer's server is unavailable. Try again later. " + webException.Message); + } + } catch (Exception ex) { _logger.Warn(ex, "Unable to connect to indexer"); From 75ff2f41d37ad28969fa25fd4eba75032e6d9477 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 18 Jun 2023 09:37:33 +0300 Subject: [PATCH 0084/1128] Update description for freeleech only in BakaBT --- src/NzbDrone.Core/Indexers/Definitions/BakaBT.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/BakaBT.cs b/src/NzbDrone.Core/Indexers/Definitions/BakaBT.cs index 38eb4b5a5..5c63960e1 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/BakaBT.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/BakaBT.cs @@ -413,7 +413,7 @@ namespace NzbDrone.Core.Indexers.Definitions FreeleechOnly = false; } - [FieldDefinition(4, Label = "Freeleech Only", Type = FieldType.Checkbox, HelpText = "Search freeleech torrents only")] + [FieldDefinition(4, Label = "Freeleech Only", Type = FieldType.Checkbox, HelpText = "Show freeleech torrents only")] public bool FreeleechOnly { get; set; } [FieldDefinition(5, Label = "Add Romaji Title", Type = FieldType.Checkbox, HelpText = "Add releases for Romaji Title")] From 0c9eae244aab9e0f338aef77e249014166bbc4ec Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 18 Jun 2023 15:45:04 +0300 Subject: [PATCH 0085/1128] Add `skip ci` to API docs update commit --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index a56bb7b3b..eccc6737b 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1003,7 +1003,7 @@ stages: git add . if git status | grep -q modified then - git commit -am 'Automated API Docs update' + git commit -am 'Automated API Docs update [skip ci]' git push -f --set-upstream origin api-docs curl -X POST -H "Authorization: token ${GITHUBTOKEN}" -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/prowlarr/prowlarr/pulls -d '{"head":"api-docs","base":"develop","title":"Update API docs"}' else From 427802a50e49c1ae37290f20bfc21a26707af752 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 18 Jun 2023 15:46:43 +0300 Subject: [PATCH 0086/1128] Update status translations for Indexer index --- frontend/src/Indexer/Index/Table/IndexerStatusCell.tsx | 2 +- frontend/src/Store/Actions/indexerIndexActions.js | 2 +- src/NzbDrone.Core/Localization/Core/en.json | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/frontend/src/Indexer/Index/Table/IndexerStatusCell.tsx b/frontend/src/Indexer/Index/Table/IndexerStatusCell.tsx index 5b26956e3..7a5f5cc10 100644 --- a/frontend/src/Indexer/Index/Table/IndexerStatusCell.tsx +++ b/frontend/src/Indexer/Index/Table/IndexerStatusCell.tsx @@ -43,7 +43,7 @@ function IndexerStatusCell(props: IndexerStatusCellProps) { className={styles.statusIcon} kind={enabled ? enableKind : kinds.DEFAULT} name={enabled ? enableIcon : icons.BLOCKLIST} - title={enabled ? enableTitle : translate('EnabledIndexerIsDisabled')} + title={enabled ? enableTitle : translate('Disabled')} /> } {status ? ( diff --git a/frontend/src/Store/Actions/indexerIndexActions.js b/frontend/src/Store/Actions/indexerIndexActions.js index cb0d0b480..91a4be981 100644 --- a/frontend/src/Store/Actions/indexerIndexActions.js +++ b/frontend/src/Store/Actions/indexerIndexActions.js @@ -36,7 +36,7 @@ export const defaultState = { columns: [ { name: 'status', - columnLabel: translate('ReleaseStatus'), + columnLabel: translate('IndexerStatus'), isSortable: true, isVisible: true, isModifiable: false diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index 0f9f525c9..1c316e9e0 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -222,6 +222,7 @@ "IndexerRss": "Indexer Rss", "IndexerSettingsSummary": "Configure various global Indexer settings including Proxies.", "IndexerSite": "Indexer Site", + "IndexerStatus": "Indexer Status", "IndexerStatusCheckAllClientMessage": "All indexers are unavailable due to failures", "IndexerStatusCheckSingleClientMessage": "Indexers unavailable due to failures: {0}", "IndexerTagsHelpText": "Use tags to specify Indexer Proxies or which apps the indexer is synced to. Applications without 1 or more matching Indexer Tags will not be synced to.", From f0c5d8ceea1526fcefa15e27a7c93478f153e4e6 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 19 Jun 2023 04:08:01 +0300 Subject: [PATCH 0087/1128] Minor refactoring in Cardigann definition --- .../Definitions/Cardigann/Cardigann.cs | 6 ++-- .../Definitions/Cardigann/CardigannBase.cs | 28 +++++++++++-------- .../Cardigann/CardigannDefinition.cs | 6 ++-- ...nMetaDef.cs => CardigannMetaDefinition.cs} | 0 src/NzbDrone.Core/Indexers/IndexerFactory.cs | 20 ++++++------- 5 files changed, 30 insertions(+), 30 deletions(-) rename src/NzbDrone.Core/Indexers/Definitions/Cardigann/{CardigannMetaDef.cs => CardigannMetaDefinition.cs} (100%) diff --git a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/Cardigann.cs b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/Cardigann.cs index e4504dc91..7a65db937 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/Cardigann.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/Cardigann.cs @@ -272,9 +272,9 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann { IndexerCategory torznabCat = null; - if (categoryMapping.cat != null) + if (categoryMapping.Cat != null) { - torznabCat = NewznabStandardCategory.GetCatByName(categoryMapping.cat); + torznabCat = NewznabStandardCategory.GetCatByName(categoryMapping.Cat); if (torznabCat == null) { @@ -282,7 +282,7 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann } } - capabilities.Categories.AddCategoryMapping(categoryMapping.id, torznabCat, categoryMapping.desc); + capabilities.Categories.AddCategoryMapping(categoryMapping.Id, torznabCat, categoryMapping.Desc); } } diff --git a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannBase.cs b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannBase.cs index 28675ec54..ba718d875 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannBase.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannBase.cs @@ -26,8 +26,8 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann protected virtual string SiteLink { get; private set; } - protected readonly IndexerCapabilitiesCategories _categories = new IndexerCapabilitiesCategories(); - protected readonly List _defaultCategories = new List(); + protected readonly IndexerCapabilitiesCategories _categories = new (); + protected readonly List _defaultCategories = new (); protected readonly string[] OptionalFields = new string[] { "imdb", "imdbid", "tmdbid", "rageid", "tvdbid", "tvmazeid", "traktid", "doubanid", "poster", "banner", "description", "genre" }; @@ -65,14 +65,16 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann SiteLink = definition.Links.First(); - if (_definition.Caps.Categories != null) + if (_definition.Caps.Categories != null && _definition.Caps.Categories.Any()) { foreach (var category in _definition.Caps.Categories) { var cat = NewznabStandardCategory.GetCatByName(category.Value); + if (cat == null) { - _logger.Error(string.Format("CardigannIndexer ({0}): invalid Torznab category for id {1}: {2}", _definition.Id, category.Key, category.Value)); + _logger.Error("CardigannIndexer ({0}): invalid Torznab category for id {1}: {2}", _definition.Id, category.Key, category.Value); + continue; } @@ -80,27 +82,29 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann } } - if (_definition.Caps.Categorymappings != null) + if (_definition.Caps.Categorymappings != null && _definition.Caps.Categorymappings.Any()) { - foreach (var categorymapping in _definition.Caps.Categorymappings) + foreach (var categoryMapping in _definition.Caps.Categorymappings) { IndexerCategory torznabCat = null; - if (categorymapping.cat != null) + if (categoryMapping.Cat != null) { - torznabCat = NewznabStandardCategory.GetCatByName(categorymapping.cat); + torznabCat = NewznabStandardCategory.GetCatByName(categoryMapping.Cat); + if (torznabCat == null) { - _logger.Error(string.Format("CardigannIndexer ({0}): invalid Torznab category for id {1}: {2}", _definition.Id, categorymapping.id, categorymapping.cat)); + _logger.Error("CardigannIndexer ({0}): invalid Torznab category for id {1}: {2}", _definition.Id, categoryMapping.Id, categoryMapping.Cat); + continue; } } - _categories.AddCategoryMapping(categorymapping.id, torznabCat, categorymapping.desc); + _categories.AddCategoryMapping(categoryMapping.Id, torznabCat, categoryMapping.Desc); - if (categorymapping.Default) + if (categoryMapping.Default) { - _defaultCategories.Add(categorymapping.id); + _defaultCategories.Add(categoryMapping.Id); } } } diff --git a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannDefinition.cs b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannDefinition.cs index 9ada719c1..8a3ac62cf 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannDefinition.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannDefinition.cs @@ -66,9 +66,9 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann public class CategorymappingBlock { - public string id { get; set; } - public string cat { get; set; } - public string desc { get; set; } + public string Id { get; set; } + public string Cat { get; set; } + public string Desc { get; set; } public bool Default { get; set; } } diff --git a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannMetaDef.cs b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannMetaDefinition.cs similarity index 100% rename from src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannMetaDef.cs rename to src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannMetaDefinition.cs diff --git a/src/NzbDrone.Core/Indexers/IndexerFactory.cs b/src/NzbDrone.Core/Indexers/IndexerFactory.cs index f76b0389f..fdf413c46 100644 --- a/src/NzbDrone.Core/Indexers/IndexerFactory.cs +++ b/src/NzbDrone.Core/Indexers/IndexerFactory.cs @@ -58,7 +58,7 @@ namespace NzbDrone.Core.Indexers catch { // Skip indexer if we fail in Cardigann mapping - _logger.Debug("Indexer {0} has no definition", definition.Name); + _logger.Debug("Indexer '{0}' has no definition", definition.Name); } } @@ -127,7 +127,7 @@ namespace NzbDrone.Core.Indexers private void MapCardigannCategories(IndexerDefinition def, CardigannDefinition defFile) { - if (defFile.Caps.Categories != null) + if (defFile.Caps.Categories != null && defFile.Caps.Categories.Any()) { foreach (var category in defFile.Caps.Categories) { @@ -142,27 +142,23 @@ namespace NzbDrone.Core.Indexers } } - if (defFile.Caps.Categorymappings != null) + if (defFile.Caps.Categorymappings != null && defFile.Caps.Categorymappings.Any()) { - foreach (var categorymapping in defFile.Caps.Categorymappings) + foreach (var categoryMapping in defFile.Caps.Categorymappings) { IndexerCategory torznabCat = null; - if (categorymapping.cat != null) + if (categoryMapping.Cat != null) { - torznabCat = NewznabStandardCategory.GetCatByName(categorymapping.cat); + torznabCat = NewznabStandardCategory.GetCatByName(categoryMapping.Cat); + if (torznabCat == null) { continue; } } - def.Capabilities.Categories.AddCategoryMapping(categorymapping.id, torznabCat, categorymapping.desc); - - //if (categorymapping.Default) - //{ - // DefaultCategories.Add(categorymapping.id); - //} + def.Capabilities.Categories.AddCategoryMapping(categoryMapping.Id, torznabCat, categoryMapping.Desc); } } } From 4b8906ea62ca7a74c4d0f2aee3892e8049c10a7e Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 19 Jun 2023 04:16:40 +0300 Subject: [PATCH 0088/1128] Cleanup redundant DownloadProtocol in indexers --- src/NzbDrone.Core/Indexers/Definitions/Anidex.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/Anidub.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/AnimeBytes.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/AnimeTorrents.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/Animedia.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/Anthelion.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/AudioBookBay.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/Avistaz/AvistazBase.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/BB.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/BakaBT.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/BeyondHD.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/BinSearch.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/BitHDTV.cs | 1 - .../Indexers/Definitions/BroadcastheNet/BroadcastheNet.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/Cardigann/Cardigann.cs | 2 -- src/NzbDrone.Core/Indexers/Definitions/FileList/FileList.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/FunFile.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/Gazelle/GazelleBase.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/GazelleGames.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/HDBits/HDBits.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/HDSpace.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/HDTorrents.cs | 1 - .../Indexers/Definitions/Headphones/Headphones.cs | 2 -- src/NzbDrone.Core/Indexers/Definitions/IPTorrents.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/ImmortalSeed.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/Libble.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/MoreThanTV.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/MyAnonamouse.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/Nebulance.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/Newznab/Newznab.cs | 4 ---- src/NzbDrone.Core/Indexers/Definitions/NorBits.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/NzbIndex.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/Orpheus.cs | 1 - .../Indexers/Definitions/PassThePopcorn/PassThePopcorn.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/PirateTheNet.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/PixelHD.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/PornoLab.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/PreToMe.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/Rarbg/Rarbg.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/Redacted.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/RevolutionTT.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/RuTracker.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/SceneHD.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/SceneTime.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/SecretCinema.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/Shazbat.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/Shizaproject.cs | 1 - .../Indexers/Definitions/SpeedApp/SpeedAppBase.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/SpeedCD.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/SubsPlease.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/TVVault.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/Toloka.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/TorrentBytes.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/TorrentDay.cs | 1 - .../Indexers/Definitions/TorrentPotato/TorrentPotato.cs | 1 - .../Indexers/Definitions/TorrentRss/TorrentRssIndexer.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/TorrentSyndikat.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/TorrentsCSV.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/Torznab/Torznab.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/UNIT3D/Unit3dBase.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/Uniotaku.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/XSpeeds.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/Xthor/Xthor.cs | 1 - src/NzbDrone.Core/Indexers/Definitions/ZonaQ.cs | 1 - src/NzbDrone.Core/Indexers/TorrentIndexerBase.cs | 2 ++ src/NzbDrone.Core/Indexers/UsenetIndexerBase.cs | 2 ++ 66 files changed, 4 insertions(+), 69 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/Definitions/Anidex.cs b/src/NzbDrone.Core/Indexers/Definitions/Anidex.cs index c2065f119..6e3f9fe98 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Anidex.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Anidex.cs @@ -27,7 +27,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Description => "Anidex is a Public torrent tracker and indexer, primarily for English fansub groups of anime"; public override string Language => "en-US"; public override Encoding Encoding => Encoding.UTF8; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Public; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/Anidub.cs b/src/NzbDrone.Core/Indexers/Definitions/Anidub.cs index 4581abd29..5c6588c9d 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Anidub.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Anidub.cs @@ -28,7 +28,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Description => "Anidub is RUSSIAN anime voiceover group and eponymous anime tracker."; public override string Language => "ru-RU"; public override Encoding Encoding => Encoding.UTF8; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.SemiPrivate; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/AnimeBytes.cs b/src/NzbDrone.Core/Indexers/Definitions/AnimeBytes.cs index 8a4c6de88..54f3f4f83 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/AnimeBytes.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/AnimeBytes.cs @@ -35,7 +35,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Description => "AnimeBytes (AB) is the largest private torrent tracker that specialises in anime and anime-related content."; public override string Language => "en-US"; public override Encoding Encoding => Encoding.UTF8; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); public override TimeSpan RateLimit => TimeSpan.FromSeconds(4); diff --git a/src/NzbDrone.Core/Indexers/Definitions/AnimeTorrents.cs b/src/NzbDrone.Core/Indexers/Definitions/AnimeTorrents.cs index 730cedc0c..5a3c8fc3c 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/AnimeTorrents.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/AnimeTorrents.cs @@ -24,7 +24,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Name => "AnimeTorrents"; public override string[] IndexerUrls => new[] { "https://animetorrents.me/" }; public override string Description => "Definitive source for anime and manga"; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override bool SupportsPagination => true; public override TimeSpan RateLimit => TimeSpan.FromSeconds(4); diff --git a/src/NzbDrone.Core/Indexers/Definitions/Animedia.cs b/src/NzbDrone.Core/Indexers/Definitions/Animedia.cs index 487dee4d5..e40b6e40e 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Animedia.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Animedia.cs @@ -24,7 +24,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Description => "Animedia is RUSSIAN anime voiceover group and eponymous anime tracker."; public override string Language => "ru-RU"; public override Encoding Encoding => Encoding.UTF8; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Public; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/Anthelion.cs b/src/NzbDrone.Core/Indexers/Definitions/Anthelion.cs index 429c24cd2..10138d441 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Anthelion.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Anthelion.cs @@ -28,7 +28,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Description => "A movies tracker"; public override string Language => "en-US"; public override Encoding Encoding => Encoding.UTF8; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/AudioBookBay.cs b/src/NzbDrone.Core/Indexers/Definitions/AudioBookBay.cs index 98f999375..8c72753de 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/AudioBookBay.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/AudioBookBay.cs @@ -59,7 +59,6 @@ public class AudioBookBay : TorrentIndexerBase }; public override string Description => "AudioBook Bay (ABB) is a public Torrent Tracker for AUDIOBOOKS"; public override string Language => "en-US"; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Public; public override int PageSize => 15; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/Avistaz/AvistazBase.cs b/src/NzbDrone.Core/Indexers/Definitions/Avistaz/AvistazBase.cs index 0074f9c5b..dd200f5b9 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Avistaz/AvistazBase.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Avistaz/AvistazBase.cs @@ -12,7 +12,6 @@ namespace NzbDrone.Core.Indexers.Definitions.Avistaz { public abstract class AvistazBase : TorrentIndexerBase { - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override bool SupportsRss => true; public override bool SupportsSearch => true; public override bool SupportsPagination => true; diff --git a/src/NzbDrone.Core/Indexers/Definitions/BB.cs b/src/NzbDrone.Core/Indexers/Definitions/BB.cs index e2af8fd29..4a8bf08bb 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/BB.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/BB.cs @@ -28,7 +28,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Description => "BB is a Private Torrent Tracker for 0DAY / GENERAL"; public override string Language => "en-US"; public override Encoding Encoding => Encoding.UTF8; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/BakaBT.cs b/src/NzbDrone.Core/Indexers/Definitions/BakaBT.cs index 5c63960e1..d8b4acd72 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/BakaBT.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/BakaBT.cs @@ -28,7 +28,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string[] IndexerUrls => new[] { "https://bakabt.me/" }; public override string Description => "Anime Community"; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/BeyondHD.cs b/src/NzbDrone.Core/Indexers/Definitions/BeyondHD.cs index b1e46428d..5847a1639 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/BeyondHD.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/BeyondHD.cs @@ -28,7 +28,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string[] IndexerUrls => new string[] { "https://beyond-hd.me/" }; public override string Description => "BeyondHD (BHD) is a Private Torrent Tracker for HD MOVIES / TV"; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/BinSearch.cs b/src/NzbDrone.Core/Indexers/Definitions/BinSearch.cs index 5258d7c83..93540972f 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/BinSearch.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/BinSearch.cs @@ -26,7 +26,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Description => "The binary Usenet search engine"; public override string Language => "en-US"; public override Encoding Encoding => Encoding.UTF8; - public override DownloadProtocol Protocol => DownloadProtocol.Usenet; public override IndexerPrivacy Privacy => IndexerPrivacy.Public; public override bool SupportsRss => false; public override bool SupportsPagination => true; diff --git a/src/NzbDrone.Core/Indexers/Definitions/BitHDTV.cs b/src/NzbDrone.Core/Indexers/Definitions/BitHDTV.cs index 7ff683bae..f579be009 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/BitHDTV.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/BitHDTV.cs @@ -25,7 +25,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Description => "BIT-HDTV - Home of High Definition"; public override string Language => "en-US"; public override Encoding Encoding => Encoding.GetEncoding("iso-8859-1"); - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/BroadcastheNet/BroadcastheNet.cs b/src/NzbDrone.Core/Indexers/Definitions/BroadcastheNet/BroadcastheNet.cs index 596810d7f..22c3cbb28 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/BroadcastheNet/BroadcastheNet.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/BroadcastheNet/BroadcastheNet.cs @@ -11,7 +11,6 @@ namespace NzbDrone.Core.Indexers.BroadcastheNet public override string Name => "BroadcasTheNet"; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override bool SupportsRss => true; public override bool SupportsSearch => true; public override bool SupportsPagination => true; diff --git a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/Cardigann.cs b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/Cardigann.cs index 7a65db937..9f6bf21a4 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/Cardigann.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/Cardigann.cs @@ -24,8 +24,6 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann public override string Name => "Cardigann"; public override string[] IndexerUrls => new string[] { "" }; public override string Description => ""; - - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; // Page size is different per indexer, setting to 1 ensures we don't break out of paging logic diff --git a/src/NzbDrone.Core/Indexers/Definitions/FileList/FileList.cs b/src/NzbDrone.Core/Indexers/Definitions/FileList/FileList.cs index 7d7121675..34552cb98 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/FileList/FileList.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/FileList/FileList.cs @@ -15,7 +15,6 @@ public class FileList : TorrentIndexerBase }; public override string[] LegacyUrls => new[] { "https://filelist.io" }; public override string Description => "FileList (FL) is a ROMANIAN Private Torrent Tracker for 0DAY / GENERAL"; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override bool SupportsRss => true; public override bool SupportsSearch => true; diff --git a/src/NzbDrone.Core/Indexers/Definitions/FunFile.cs b/src/NzbDrone.Core/Indexers/Definitions/FunFile.cs index 4d7a8bdc7..2ae1886a4 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/FunFile.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/FunFile.cs @@ -26,7 +26,6 @@ public class FunFile : TorrentIndexerBase public override string Description => "FunFile is a general tracker"; public override string Language => "en-US"; public override Encoding Encoding => Encoding.GetEncoding("iso-8859-1"); - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/Gazelle/GazelleBase.cs b/src/NzbDrone.Core/Indexers/Definitions/Gazelle/GazelleBase.cs index 82b6d5e5c..711b2e152 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Gazelle/GazelleBase.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Gazelle/GazelleBase.cs @@ -13,7 +13,6 @@ namespace NzbDrone.Core.Indexers.Definitions.Gazelle; public abstract class GazelleBase : TorrentIndexerBase where TSettings : GazelleSettings, new() { - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override string[] IndexerUrls => new[] { "" }; protected virtual string LoginUrl => Settings.BaseUrl + "login.php"; public override bool SupportsRss => true; diff --git a/src/NzbDrone.Core/Indexers/Definitions/GazelleGames.cs b/src/NzbDrone.Core/Indexers/Definitions/GazelleGames.cs index aa86fd331..4abc47005 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/GazelleGames.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/GazelleGames.cs @@ -28,7 +28,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Description => "GazelleGames (GGn) is a Private Torrent Tracker for GAMES"; public override string Language => "en-US"; public override Encoding Encoding => Encoding.UTF8; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/HDBits/HDBits.cs b/src/NzbDrone.Core/Indexers/Definitions/HDBits/HDBits.cs index 3446636e0..f5064a055 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/HDBits/HDBits.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/HDBits/HDBits.cs @@ -11,7 +11,6 @@ namespace NzbDrone.Core.Indexers.Definitions.HDBits public override string[] IndexerUrls => new[] { "https://hdbits.org/" }; public override string[] LegacyUrls => new[] { "https://hdbits.org" }; public override string Description => "Best HD Tracker"; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); public override bool SupportsRedirect => true; diff --git a/src/NzbDrone.Core/Indexers/Definitions/HDSpace.cs b/src/NzbDrone.Core/Indexers/Definitions/HDSpace.cs index 6d43ff37a..2cd58c40f 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/HDSpace.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/HDSpace.cs @@ -26,7 +26,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Description => "HD-Space (HDS) is a Private Torrent Tracker for HD MOVIES / TV"; public override string Language => "en-US"; public override Encoding Encoding => Encoding.UTF8; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/HDTorrents.cs b/src/NzbDrone.Core/Indexers/Definitions/HDTorrents.cs index 398f5af58..6819b2dcf 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/HDTorrents.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/HDTorrents.cs @@ -32,7 +32,6 @@ namespace NzbDrone.Core.Indexers.Definitions "https://hd-torrents.me/", }; public override string Description => "HD-Torrents is a private torrent website with HD torrents and strict rules on their content."; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/Headphones/Headphones.cs b/src/NzbDrone.Core/Indexers/Definitions/Headphones/Headphones.cs index e0ecb4a70..c2e66ae08 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Headphones/Headphones.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Headphones/Headphones.cs @@ -14,8 +14,6 @@ namespace NzbDrone.Core.Indexers.Headphones public class Headphones : UsenetIndexerBase { public override string Name => "Headphones VIP"; - - public override DownloadProtocol Protocol => DownloadProtocol.Usenet; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override string[] IndexerUrls => new string[] { "https://indexer.codeshy.com" }; public override string Description => "A Private Usenet indexer for music"; diff --git a/src/NzbDrone.Core/Indexers/Definitions/IPTorrents.cs b/src/NzbDrone.Core/Indexers/Definitions/IPTorrents.cs index 534dc9881..3e8294e4b 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/IPTorrents.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/IPTorrents.cs @@ -38,7 +38,6 @@ namespace NzbDrone.Core.Indexers.Definitions "https://ipt.world/" }; public override string Description => "IPTorrents (IPT) is a Private Torrent Tracker for 0DAY / GENERAL."; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override bool SupportsPagination => true; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/ImmortalSeed.cs b/src/NzbDrone.Core/Indexers/Definitions/ImmortalSeed.cs index b4ceb0137..b75160742 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/ImmortalSeed.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/ImmortalSeed.cs @@ -25,7 +25,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Name => "ImmortalSeed"; public override string[] IndexerUrls => new[] { "https://immortalseed.me/" }; public override string Description => "ImmortalSeed (iS) is a Private Torrent Tracker for MOVIES / TV / GENERAL"; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); public override TimeSpan RateLimit => TimeSpan.FromSeconds(5); diff --git a/src/NzbDrone.Core/Indexers/Definitions/Libble.cs b/src/NzbDrone.Core/Indexers/Definitions/Libble.cs index 1f0305568..457320616 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Libble.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Libble.cs @@ -31,7 +31,6 @@ public class Libble : TorrentIndexerBase private string LoginUrl => Settings.BaseUrl + "login.php"; public override string Language => "en-US"; public override Encoding Encoding => Encoding.UTF8; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override bool SupportsPagination => true; public override int PageSize => 50; diff --git a/src/NzbDrone.Core/Indexers/Definitions/MoreThanTV.cs b/src/NzbDrone.Core/Indexers/Definitions/MoreThanTV.cs index 29f434c3c..f86fe2535 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/MoreThanTV.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/MoreThanTV.cs @@ -26,7 +26,6 @@ public class MoreThanTV : TorrentIndexerBase public override string Name => "MoreThanTV"; public override string[] IndexerUrls => new[] { "https://www.morethantv.me/" }; public override string Description => "Private torrent tracker for TV / MOVIES"; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); public override bool FollowRedirect => true; diff --git a/src/NzbDrone.Core/Indexers/Definitions/MyAnonamouse.cs b/src/NzbDrone.Core/Indexers/Definitions/MyAnonamouse.cs index 5d4c03fbd..b9bb49601 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/MyAnonamouse.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/MyAnonamouse.cs @@ -30,7 +30,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Name => "MyAnonamouse"; public override string[] IndexerUrls => new[] { "https://www.myanonamouse.net/" }; public override string Description => "MyAnonaMouse (MAM) is a large ebook and audiobook tracker."; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override bool SupportsPagination => true; public override int PageSize => 100; diff --git a/src/NzbDrone.Core/Indexers/Definitions/Nebulance.cs b/src/NzbDrone.Core/Indexers/Definitions/Nebulance.cs index 7058032da..c2459dcfb 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Nebulance.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Nebulance.cs @@ -27,7 +27,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Description => "Nebulance (NBL) is a ratioless Private Torrent Tracker for TV"; public override string Language => "en-US"; public override Encoding Encoding => Encoding.UTF8; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override bool SupportsRedirect => true; public override bool SupportsPagination => true; diff --git a/src/NzbDrone.Core/Indexers/Definitions/Newznab/Newznab.cs b/src/NzbDrone.Core/Indexers/Definitions/Newznab/Newznab.cs index b5ce1ffe6..29d5b757f 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Newznab/Newznab.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Newznab/Newznab.cs @@ -23,12 +23,8 @@ namespace NzbDrone.Core.Indexers.Newznab public override bool FollowRedirect => true; public override bool SupportsRedirect => true; public override bool SupportsPagination => true; - - public override DownloadProtocol Protocol => DownloadProtocol.Usenet; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; - public override IndexerCapabilities Capabilities { get => GetCapabilitiesFromSettings(); protected set => base.Capabilities = value; } - public override int PageSize => _capabilitiesProvider.GetCapabilities(Settings, Definition).LimitsDefault.Value; public override IIndexerRequestGenerator GetRequestGenerator() diff --git a/src/NzbDrone.Core/Indexers/Definitions/NorBits.cs b/src/NzbDrone.Core/Indexers/Definitions/NorBits.cs index 470e819ec..49f913fa7 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/NorBits.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/NorBits.cs @@ -29,7 +29,6 @@ public class NorBits : TorrentIndexerBase 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 DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/NzbIndex.cs b/src/NzbDrone.Core/Indexers/Definitions/NzbIndex.cs index 45df8e91a..bf57c1ca3 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/NzbIndex.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/NzbIndex.cs @@ -25,7 +25,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Name => "NZBIndex"; public override string[] IndexerUrls => new[] { "https://nzbindex.com/" }; public override string Description => "A Usenet Indexer"; - public override DownloadProtocol Protocol => DownloadProtocol.Usenet; public override IndexerPrivacy Privacy => IndexerPrivacy.SemiPrivate; public override bool SupportsPagination => true; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/Orpheus.cs b/src/NzbDrone.Core/Indexers/Definitions/Orpheus.cs index 011764f64..3944bdd1b 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Orpheus.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Orpheus.cs @@ -26,7 +26,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Name => "Orpheus"; public override string[] IndexerUrls => new[] { "https://orpheus.network/" }; public override string Description => "Orpheus (APOLLO) is a Private Torrent Tracker for MUSIC"; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); public override bool SupportsRedirect => true; diff --git a/src/NzbDrone.Core/Indexers/Definitions/PassThePopcorn/PassThePopcorn.cs b/src/NzbDrone.Core/Indexers/Definitions/PassThePopcorn/PassThePopcorn.cs index 8c98f35bf..afe891a5d 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/PassThePopcorn/PassThePopcorn.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/PassThePopcorn/PassThePopcorn.cs @@ -10,7 +10,6 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn public override string Name => "PassThePopcorn"; public override string[] IndexerUrls => new[] { "https://passthepopcorn.me" }; public override string Description => "PassThePopcorn (PTP) is a Private site for MOVIES / TV"; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override bool SupportsRss => true; public override bool SupportsSearch => true; diff --git a/src/NzbDrone.Core/Indexers/Definitions/PirateTheNet.cs b/src/NzbDrone.Core/Indexers/Definitions/PirateTheNet.cs index 13dfeea9e..e1f7a4ab2 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/PirateTheNet.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/PirateTheNet.cs @@ -26,7 +26,6 @@ public class PirateTheNet : TorrentIndexerBase public override string[] IndexerUrls => new[] { "https://piratethenet.org/" }; public override string[] LegacyUrls => new[] { "http://piratethenet.org/" }; public override string Description => "PirateTheNet (PTN) is a ratioless movie tracker."; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); private string LoginUrl => Settings.BaseUrl + "takelogin.php"; diff --git a/src/NzbDrone.Core/Indexers/Definitions/PixelHD.cs b/src/NzbDrone.Core/Indexers/Definitions/PixelHD.cs index 83173fc1b..29c315403 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/PixelHD.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/PixelHD.cs @@ -28,7 +28,6 @@ public class PixelHD : TorrentIndexerBase public override string Description => "PixelHD (PxHD) is a ratioless Private Torrent Tracker for HD .MP4 MOVIES / TV"; public override string Language => "en-US"; public override Encoding Encoding => Encoding.UTF8; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/PornoLab.cs b/src/NzbDrone.Core/Indexers/Definitions/PornoLab.cs index ea9188fe3..1eb5c74dd 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/PornoLab.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/PornoLab.cs @@ -28,7 +28,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Description => "PornoLab is a Semi-Private Russian site for Adult content"; public override string Language => "ru-RU"; public override Encoding Encoding => Encoding.GetEncoding("windows-1251"); - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.SemiPrivate; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/PreToMe.cs b/src/NzbDrone.Core/Indexers/Definitions/PreToMe.cs index 7b0f767f0..3a533809f 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/PreToMe.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/PreToMe.cs @@ -29,7 +29,6 @@ public class PreToMe : TorrentIndexerBase public override string Description => "PreToMe is a ratioless 0Day/General tracker."; public override string Language => "en-US"; public override Encoding Encoding => Encoding.GetEncoding("iso-8859-1"); - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/Rarbg/Rarbg.cs b/src/NzbDrone.Core/Indexers/Definitions/Rarbg/Rarbg.cs index 6437c9ba6..f24d9dee5 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Rarbg/Rarbg.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Rarbg/Rarbg.cs @@ -27,7 +27,6 @@ namespace NzbDrone.Core.Indexers.Definitions.Rarbg public override string[] IndexerUrls => new[] { "https://torrentapi.org/" }; public override string[] LegacyUrls => new[] { "https://torrentapi.org" }; public override string Description => "RARBG is a Public torrent site for MOVIES / TV / GENERAL"; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Public; public override IndexerCapabilities Capabilities => SetCapabilities(); public override TimeSpan RateLimit => TimeSpan.FromSeconds(7); diff --git a/src/NzbDrone.Core/Indexers/Definitions/Redacted.cs b/src/NzbDrone.Core/Indexers/Definitions/Redacted.cs index 4bbc42ecf..03d701acf 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Redacted.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Redacted.cs @@ -26,7 +26,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Name => "Redacted"; public override string[] IndexerUrls => new[] { "https://redacted.ch/" }; public override string Description => "REDActed (Aka.PassTheHeadPhones) is one of the most well-known music trackers."; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); public override bool SupportsRedirect => true; diff --git a/src/NzbDrone.Core/Indexers/Definitions/RevolutionTT.cs b/src/NzbDrone.Core/Indexers/Definitions/RevolutionTT.cs index b966a599f..acc798305 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/RevolutionTT.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/RevolutionTT.cs @@ -26,7 +26,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string[] IndexerUrls => new[] { "https://revolutiontt.me/" }; public override string Description => "The Revolution has begun"; private string LoginUrl => Settings.BaseUrl + "takelogin.php"; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/RuTracker.cs b/src/NzbDrone.Core/Indexers/Definitions/RuTracker.cs index 8ee671f71..b8973adf1 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/RuTracker.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/RuTracker.cs @@ -33,7 +33,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Description => "RuTracker is a Semi-Private Russian torrent site with a thriving file-sharing community"; public override string Language => "ru-RU"; public override Encoding Encoding => Encoding.GetEncoding("windows-1251"); - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.SemiPrivate; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/SceneHD.cs b/src/NzbDrone.Core/Indexers/Definitions/SceneHD.cs index c83d8a3ae..e554c4d33 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/SceneHD.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/SceneHD.cs @@ -28,7 +28,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Description => "SceneHD is Private site for HD TV / MOVIES"; public override string Language => "en-US"; public override Encoding Encoding => Encoding.UTF8; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/SceneTime.cs b/src/NzbDrone.Core/Indexers/Definitions/SceneTime.cs index 19cc98b00..d11660fc4 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/SceneTime.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/SceneTime.cs @@ -26,7 +26,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Description => "Always on time"; public override string Language => "en-US"; public override Encoding Encoding => Encoding.UTF8; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/SecretCinema.cs b/src/NzbDrone.Core/Indexers/Definitions/SecretCinema.cs index 9e338e769..c18111bd6 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/SecretCinema.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/SecretCinema.cs @@ -20,7 +20,6 @@ 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 DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/Shazbat.cs b/src/NzbDrone.Core/Indexers/Definitions/Shazbat.cs index 2748810f7..23e721094 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Shazbat.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Shazbat.cs @@ -30,7 +30,6 @@ public class Shazbat : TorrentIndexerBase public override string Description => "Shazbat is a PRIVATE Torrent Tracker with highly curated TV content"; public override string Language => "en-US"; public override Encoding Encoding => Encoding.UTF8; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); public override TimeSpan RateLimit => TimeSpan.FromSeconds(5.1); diff --git a/src/NzbDrone.Core/Indexers/Definitions/Shizaproject.cs b/src/NzbDrone.Core/Indexers/Definitions/Shizaproject.cs index 817d81aa7..4d4c6fdfb 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Shizaproject.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Shizaproject.cs @@ -24,7 +24,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Description => "Shizaproject is russian anime voiceover group and eponymous anime tracker."; public override string Language => "ru-RU"; public override Encoding Encoding => Encoding.UTF8; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Public; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/SpeedApp/SpeedAppBase.cs b/src/NzbDrone.Core/Indexers/Definitions/SpeedApp/SpeedAppBase.cs index abbab8399..e1e878160 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/SpeedApp/SpeedAppBase.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/SpeedApp/SpeedAppBase.cs @@ -29,7 +29,6 @@ namespace NzbDrone.Core.Indexers.Definitions { private string LoginUrl => Settings.BaseUrl + "api/login"; public override Encoding Encoding => Encoding.UTF8; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override bool SupportsPagination => true; public override int PageSize => 100; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/SpeedCD.cs b/src/NzbDrone.Core/Indexers/Definitions/SpeedCD.cs index 64677d88a..24a01763b 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/SpeedCD.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/SpeedCD.cs @@ -33,7 +33,6 @@ public class SpeedCD : TorrentIndexerBase public override string Description => "Your home now!"; public override string Language => "en-US"; public override Encoding Encoding => Encoding.UTF8; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override bool SupportsPagination => true; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/SubsPlease.cs b/src/NzbDrone.Core/Indexers/Definitions/SubsPlease.cs index 97ed41f7c..47cef2fd7 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/SubsPlease.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/SubsPlease.cs @@ -28,7 +28,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Language => "en-US"; public override string Description => "SubsPlease - A better HorribleSubs/Erai replacement"; public override Encoding Encoding => Encoding.UTF8; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Public; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/TVVault.cs b/src/NzbDrone.Core/Indexers/Definitions/TVVault.cs index c9711c59e..d388cd6b7 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/TVVault.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/TVVault.cs @@ -30,7 +30,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Description => "TV-Vault is a very unique tracker dedicated for old TV shows, TV movies and documentaries."; public override string Language => "en-US"; public override Encoding Encoding => Encoding.UTF8; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); public override TimeSpan RateLimit => TimeSpan.FromSeconds(5); diff --git a/src/NzbDrone.Core/Indexers/Definitions/Toloka.cs b/src/NzbDrone.Core/Indexers/Definitions/Toloka.cs index 15fe81c99..c7960dbfd 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Toloka.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Toloka.cs @@ -26,7 +26,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Description => "Toloka.to is a Semi-Private Ukrainian torrent site with a thriving file-sharing community"; public override string Language => "uk-UA"; public override Encoding Encoding => Encoding.UTF8; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.SemiPrivate; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/TorrentBytes.cs b/src/NzbDrone.Core/Indexers/Definitions/TorrentBytes.cs index 0bdd6265f..45d920611 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/TorrentBytes.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/TorrentBytes.cs @@ -27,7 +27,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Description => "A decade of TorrentBytes"; public override string Language => "en-US"; public override Encoding Encoding => Encoding.GetEncoding("iso-8859-1"); - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/TorrentDay.cs b/src/NzbDrone.Core/Indexers/Definitions/TorrentDay.cs index 81d900f74..34fc9a2dd 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/TorrentDay.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/TorrentDay.cs @@ -32,7 +32,6 @@ namespace NzbDrone.Core.Indexers.Definitions "https://td.workisboring.net/" }; public override string Description => "TorrentDay (TD) is a Private site for TV / MOVIES / GENERAL"; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/TorrentPotato/TorrentPotato.cs b/src/NzbDrone.Core/Indexers/Definitions/TorrentPotato/TorrentPotato.cs index 4ee35349e..ad989d1e7 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/TorrentPotato/TorrentPotato.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/TorrentPotato/TorrentPotato.cs @@ -11,7 +11,6 @@ namespace NzbDrone.Core.Indexers.Definitions.TorrentPotato public override string[] IndexerUrls => new[] { "http://127.0.0.1" }; public override string Description => "A JSON based torrent provider previously developed for CouchPotato"; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override TimeSpan RateLimit => TimeSpan.FromSeconds(2); diff --git a/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexer.cs b/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexer.cs index a151d5525..fff80eba4 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexer.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/TorrentRss/TorrentRssIndexer.cs @@ -13,7 +13,6 @@ namespace NzbDrone.Core.Indexers.Definitions.TorrentRss public override string Name => "Torrent RSS Feed"; public override string[] IndexerUrls => new[] { "" }; public override string Description => "Generic RSS Feed containing torrents"; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Public; public override bool SupportsRss => true; public override bool SupportsSearch => false; diff --git a/src/NzbDrone.Core/Indexers/Definitions/TorrentSyndikat.cs b/src/NzbDrone.Core/Indexers/Definitions/TorrentSyndikat.cs index 4555282d5..6cd9dc8ae 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/TorrentSyndikat.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/TorrentSyndikat.cs @@ -26,7 +26,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Description => "A German general tracker"; public override string Language => "de-DE"; public override Encoding Encoding => Encoding.UTF8; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/TorrentsCSV.cs b/src/NzbDrone.Core/Indexers/Definitions/TorrentsCSV.cs index cfe1a884a..2a159c278 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/TorrentsCSV.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/TorrentsCSV.cs @@ -22,7 +22,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Language => "en-US"; public override string Description => "Torrents.csv is a self-hostable open source torrent search engine and database"; public override Encoding Encoding => Encoding.UTF8; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Public; public override IndexerCapabilities Capabilities => SetCapabilities(); public override bool SupportsRss => false; diff --git a/src/NzbDrone.Core/Indexers/Definitions/Torznab/Torznab.cs b/src/NzbDrone.Core/Indexers/Definitions/Torznab/Torznab.cs index 702d3ca0c..8d9941ed0 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Torznab/Torznab.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Torznab/Torznab.cs @@ -24,7 +24,6 @@ namespace NzbDrone.Core.Indexers.Torznab public override bool SupportsRedirect => true; public override bool SupportsPagination => true; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override int PageSize => _capabilitiesProvider.GetCapabilities(Settings, Definition).LimitsDefault.Value; diff --git a/src/NzbDrone.Core/Indexers/Definitions/UNIT3D/Unit3dBase.cs b/src/NzbDrone.Core/Indexers/Definitions/UNIT3D/Unit3dBase.cs index d833a8183..65a6cdc55 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/UNIT3D/Unit3dBase.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/UNIT3D/Unit3dBase.cs @@ -6,7 +6,6 @@ namespace NzbDrone.Core.Indexers.Definitions.UNIT3D { public abstract class Unit3dBase : TorrentIndexerBase { - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override string[] IndexerUrls => new string[] { "" }; public override bool SupportsRss => true; public override bool SupportsSearch => true; diff --git a/src/NzbDrone.Core/Indexers/Definitions/Uniotaku.cs b/src/NzbDrone.Core/Indexers/Definitions/Uniotaku.cs index d2ee6c405..0909f5ddb 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Uniotaku.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Uniotaku.cs @@ -25,7 +25,6 @@ public class Uniotaku : TorrentIndexerBase public override string[] IndexerUrls => new[] { "https://tracker.uniotaku.com/" }; public override string Description => "UniOtaku is a BRAZILIAN Semi-Private Torrent Tracker for ANIME"; public override string Language => "pt-BR"; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.SemiPrivate; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/Definitions/XSpeeds.cs b/src/NzbDrone.Core/Indexers/Definitions/XSpeeds.cs index e41816543..0c6e32d61 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/XSpeeds.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/XSpeeds.cs @@ -24,7 +24,6 @@ public class XSpeeds : TorrentIndexerBase public override string Name => "XSpeeds"; public override string[] IndexerUrls => new[] { "https://www.xspeeds.eu/" }; public override string Description => "XSpeeds (XS) is a Private Torrent Tracker for MOVIES / TV / GENERAL"; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); private string LandingUrl => Settings.BaseUrl + "login.php"; diff --git a/src/NzbDrone.Core/Indexers/Definitions/Xthor/Xthor.cs b/src/NzbDrone.Core/Indexers/Definitions/Xthor/Xthor.cs index 26b019360..45abc8463 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Xthor/Xthor.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Xthor/Xthor.cs @@ -15,7 +15,6 @@ namespace NzbDrone.Core.Indexers.Definitions.Xthor public override string Language => "fr-FR"; public override string Description => "Xthor is a general Private torrent site"; public override Encoding Encoding => Encoding.GetEncoding("windows-1252"); - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override TimeSpan RateLimit => TimeSpan.FromSeconds(2.5); diff --git a/src/NzbDrone.Core/Indexers/Definitions/ZonaQ.cs b/src/NzbDrone.Core/Indexers/Definitions/ZonaQ.cs index 4e8104116..799fc12fe 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/ZonaQ.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/ZonaQ.cs @@ -34,7 +34,6 @@ namespace NzbDrone.Core.Indexers.Definitions public override string Description => "ZonaQ is a SPANISH Private Torrent Tracker for MOVIES / TV"; public override string Language => "es-ES"; public override Encoding Encoding => Encoding.UTF8; - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerCapabilities Capabilities => SetCapabilities(); diff --git a/src/NzbDrone.Core/Indexers/TorrentIndexerBase.cs b/src/NzbDrone.Core/Indexers/TorrentIndexerBase.cs index aabf2c101..f727ef2f1 100644 --- a/src/NzbDrone.Core/Indexers/TorrentIndexerBase.cs +++ b/src/NzbDrone.Core/Indexers/TorrentIndexerBase.cs @@ -9,6 +9,8 @@ namespace NzbDrone.Core.Indexers public abstract class TorrentIndexerBase : HttpIndexerBase where TSettings : IIndexerSettings, new() { + public override DownloadProtocol Protocol => DownloadProtocol.Torrent; + protected TorrentIndexerBase(IIndexerHttpClient httpClient, IEventAggregator eventAggregator, IIndexerStatusService indexerStatusService, IConfigService configService, Logger logger) : base(httpClient, eventAggregator, indexerStatusService, configService, logger) { diff --git a/src/NzbDrone.Core/Indexers/UsenetIndexerBase.cs b/src/NzbDrone.Core/Indexers/UsenetIndexerBase.cs index b40d8fba8..7089d6d79 100644 --- a/src/NzbDrone.Core/Indexers/UsenetIndexerBase.cs +++ b/src/NzbDrone.Core/Indexers/UsenetIndexerBase.cs @@ -10,6 +10,8 @@ namespace NzbDrone.Core.Indexers { private readonly IValidateNzbs _nzbValidationService; + public override DownloadProtocol Protocol => DownloadProtocol.Usenet; + protected UsenetIndexerBase(IIndexerHttpClient httpClient, IEventAggregator eventAggregator, IIndexerStatusService indexerStatusService, IConfigService configService, IValidateNzbs nzbValidationService, Logger logger) : base(httpClient, eventAggregator, indexerStatusService, configService, logger) { From e2e65627eee141e53748c0f3c479bfead7adfcd1 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 19 Jun 2023 14:31:37 +0300 Subject: [PATCH 0089/1128] Fix typo `botton` to `bottom` --- frontend/src/Components/Form/AutoSuggestInput.js | 2 +- frontend/src/Components/Form/EnhancedSelectInput.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/Components/Form/AutoSuggestInput.js b/frontend/src/Components/Form/AutoSuggestInput.js index 34ec7530b..42a24e4d7 100644 --- a/frontend/src/Components/Form/AutoSuggestInput.js +++ b/frontend/src/Components/Form/AutoSuggestInput.js @@ -104,7 +104,7 @@ class AutoSuggestInput extends Component { const windowHeight = window.innerHeight; - if ((/^botton/).test(data.placement)) { + if ((/^bottom/).test(data.placement)) { data.styles.maxHeight = windowHeight - bottom; } else { data.styles.maxHeight = top; diff --git a/frontend/src/Components/Form/EnhancedSelectInput.js b/frontend/src/Components/Form/EnhancedSelectInput.js index cc4215025..a85b9ef6c 100644 --- a/frontend/src/Components/Form/EnhancedSelectInput.js +++ b/frontend/src/Components/Form/EnhancedSelectInput.js @@ -144,7 +144,7 @@ class EnhancedSelectInput extends Component { const windowHeight = window.innerHeight; - if ((/^botton/).test(data.placement)) { + if ((/^bottom/).test(data.placement)) { data.styles.maxHeight = windowHeight - bottom; } else { data.styles.maxHeight = top; From acfdb5bae3257d1394d4958c01df68ee5f4b7947 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 19 Jun 2023 12:59:59 +0300 Subject: [PATCH 0090/1128] New: (UI) Show disabled indexers as disabled options in search page --- .../src/Components/Form/IndexersSelectInputConnector.js | 9 +++++---- frontend/src/Styles/Themes/dark.js | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/frontend/src/Components/Form/IndexersSelectInputConnector.js b/frontend/src/Components/Form/IndexersSelectInputConnector.js index bc411d5cc..e7cca1feb 100644 --- a/frontend/src/Components/Form/IndexersSelectInputConnector.js +++ b/frontend/src/Components/Form/IndexersSelectInputConnector.js @@ -12,7 +12,7 @@ function createMapStateToProps() { (state) => state.indexers, (value, indexers) => { const values = []; - const groupedIndexers = _(indexers.items).groupBy((x) => x.protocol).map((val, key) => ({ protocol: key, indexers: val })).value(); + const groupedIndexers = _.map(_.groupBy(indexers.items, 'protocol'), (val, key) => ({ protocol: key, indexers: val })); groupedIndexers.forEach((element) => { values.push({ @@ -21,10 +21,11 @@ function createMapStateToProps() { }); if (element.indexers && element.indexers.length > 0) { - element.indexers.forEach((subCat) => { + element.indexers.forEach((indexer) => { values.push({ - key: subCat.id, - value: subCat.name, + key: indexer.id, + value: indexer.name, + isDisabled: !indexer.enable, parentKey: element.protocol === 'usenet' ? -1 : -2 }); }); diff --git a/frontend/src/Styles/Themes/dark.js b/frontend/src/Styles/Themes/dark.js index fa93d7c68..657568982 100644 --- a/frontend/src/Styles/Themes/dark.js +++ b/frontend/src/Styles/Themes/dark.js @@ -162,7 +162,7 @@ module.exports = { inputHoverBackgroundColor: 'rgba(255, 255, 255, 0.20)', inputSelectedBackgroundColor: 'rgba(255, 255, 255, 0.05)', advancedFormLabelColor: '#ff902b', - disabledCheckInputColor: '#ddd', + disabledCheckInputColor: '#999', disabledInputColor: '#808080', // From 9a4c23797a98286d04652a3551bfe8205e870d72 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 19 Jun 2023 13:01:04 +0300 Subject: [PATCH 0091/1128] Display error when search failed due to all indexers being disabled --- .../IndexerSearch/ReleaseSearchService.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/NzbDrone.Core/IndexerSearch/ReleaseSearchService.cs b/src/NzbDrone.Core/IndexerSearch/ReleaseSearchService.cs index a98a981f3..38f9d56cf 100644 --- a/src/NzbDrone.Core/IndexerSearch/ReleaseSearchService.cs +++ b/src/NzbDrone.Core/IndexerSearch/ReleaseSearchService.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Threading.Tasks; using NLog; using NzbDrone.Common.Instrumentation.Extensions; +using NzbDrone.Core.Exceptions; using NzbDrone.Core.Indexers; using NzbDrone.Core.Indexers.Events; using NzbDrone.Core.IndexerSearch.Definitions; @@ -157,15 +158,22 @@ namespace NzbDrone.Core.IndexerSearch { var indexers = _indexerFactory.Enabled(); - if (criteriaBase.IndexerIds != null && criteriaBase.IndexerIds.Count > 0) + if (criteriaBase.IndexerIds is { Count: > 0 }) { indexers = indexers.Where(i => criteriaBase.IndexerIds.Contains(i.Definition.Id) || (criteriaBase.IndexerIds.Contains(-1) && i.Protocol == DownloadProtocol.Usenet) || (criteriaBase.IndexerIds.Contains(-2) && i.Protocol == DownloadProtocol.Torrent)) .ToList(); + + if (indexers.Count == 0) + { + _logger.Debug("Search failed due to all selected indexers being unavailable: {0}", string.Join(", ", criteriaBase.IndexerIds)); + + throw new SearchFailedException("Search failed due to all selected indexers being unavailable"); + } } - if (criteriaBase.Categories != null && criteriaBase.Categories.Length > 0) + if (criteriaBase.Categories is { Length: > 0 }) { //Only query supported indexers indexers = indexers.Where(i => ((IndexerDefinition)i.Definition).Capabilities.Categories.SupportedCategories(criteriaBase.Categories).Any()).ToList(); @@ -173,6 +181,7 @@ namespace NzbDrone.Core.IndexerSearch if (indexers.Count == 0) { _logger.Debug("All provided categories are unsupported by selected indexers: {0}", string.Join(", ", criteriaBase.Categories)); + return Array.Empty(); } } From e60fe05ee0fdae3eca13ca0c693a542517019e2a Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 20 Jun 2023 05:20:26 +0300 Subject: [PATCH 0092/1128] Revert "Fix typo `botton` to `bottom`" This reverts commit e2e65627eee141e53748c0f3c479bfead7adfcd1. --- frontend/src/Components/Form/AutoSuggestInput.js | 2 +- frontend/src/Components/Form/EnhancedSelectInput.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/Components/Form/AutoSuggestInput.js b/frontend/src/Components/Form/AutoSuggestInput.js index 42a24e4d7..34ec7530b 100644 --- a/frontend/src/Components/Form/AutoSuggestInput.js +++ b/frontend/src/Components/Form/AutoSuggestInput.js @@ -104,7 +104,7 @@ class AutoSuggestInput extends Component { const windowHeight = window.innerHeight; - if ((/^bottom/).test(data.placement)) { + if ((/^botton/).test(data.placement)) { data.styles.maxHeight = windowHeight - bottom; } else { data.styles.maxHeight = top; diff --git a/frontend/src/Components/Form/EnhancedSelectInput.js b/frontend/src/Components/Form/EnhancedSelectInput.js index a85b9ef6c..cc4215025 100644 --- a/frontend/src/Components/Form/EnhancedSelectInput.js +++ b/frontend/src/Components/Form/EnhancedSelectInput.js @@ -144,7 +144,7 @@ class EnhancedSelectInput extends Component { const windowHeight = window.innerHeight; - if ((/^bottom/).test(data.placement)) { + if ((/^botton/).test(data.placement)) { data.styles.maxHeight = windowHeight - bottom; } else { data.styles.maxHeight = top; From d4cdeac69af4afd7060ccce1c80fb2e915280122 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 20 Jun 2023 07:21:35 +0300 Subject: [PATCH 0093/1128] Fixed: (Cardigann) Definitions with category mapping `Other` to use 8000 (Other) --- src/NzbDrone.Core/Indexers/NewznabStandardCategory.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/NewznabStandardCategory.cs b/src/NzbDrone.Core/Indexers/NewznabStandardCategory.cs index 3b979a546..bc72b836c 100644 --- a/src/NzbDrone.Core/Indexers/NewznabStandardCategory.cs +++ b/src/NzbDrone.Core/Indexers/NewznabStandardCategory.cs @@ -103,9 +103,6 @@ namespace NzbDrone.Core.Indexers public static readonly IndexerCategory[] AllCats = { - ZedOther, - ZedOtherHashed, - ZedOtherMisc, Console, ConsoleNDS, ConsolePSP, @@ -176,7 +173,10 @@ namespace NzbDrone.Core.Indexers BooksForeign, Other, OtherMisc, - OtherHashed + OtherHashed, + ZedOther, + ZedOtherHashed, + ZedOtherMisc }; static NewznabStandardCategory() From 04cf0612754ded4a9b25f279232d41e4f5c580ec Mon Sep 17 00:00:00 2001 From: Shivam Dua Date: Tue, 20 Jun 2023 10:03:34 +0530 Subject: [PATCH 0094/1128] Fixed: (UI) Add New Indexer button on search page when no indexers are present Add missing listeners and components to make add indexer button work on search page when no indexers are present --- frontend/src/Search/SearchIndex.js | 37 ++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/frontend/src/Search/SearchIndex.js b/frontend/src/Search/SearchIndex.js index ef4663428..4faa598a2 100644 --- a/frontend/src/Search/SearchIndex.js +++ b/frontend/src/Search/SearchIndex.js @@ -12,6 +12,8 @@ import PageToolbarSection from 'Components/Page/Toolbar/PageToolbarSection'; import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator'; import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper'; import { align, icons, kinds, sortDirections } from 'Helpers/Props'; +import AddIndexerModal from 'Indexer/Add/AddIndexerModal'; +import EditIndexerModalConnector from 'Indexer/Edit/EditIndexerModalConnector'; import NoIndexer from 'Indexer/NoIndexer'; import * as keyCodes from 'Utilities/Constants/keyCodes'; import getErrorMessage from 'Utilities/Object/getErrorMessage'; @@ -54,7 +56,9 @@ class SearchIndex extends Component { lastToggled: null, allSelected: false, allUnselected: false, - selectedState: {} + selectedState: {}, + isAddIndexerModalOpen: false, + isEditIndexerModalOpen: false }; } @@ -181,6 +185,22 @@ class SearchIndex extends Component { // // Listeners + onAddIndexerPress = () => { + this.setState({ isAddIndexerModalOpen: true }); + }; + + onAddIndexerModalClose = () => { + this.setState({ isAddIndexerModalOpen: false }); + }; + + onAddIndexerSelectIndexer = () => { + this.setState({ isEditIndexerModalOpen: true }); + }; + + onEditIndexerModalClose = () => { + this.setState({ isEditIndexerModalOpen: false }); + }; + onJumpBarItemPress = (jumpToCharacter) => { this.setState({ jumpToCharacter }); }; @@ -252,7 +272,9 @@ class SearchIndex extends Component { jumpToCharacter, selectedState, allSelected, - allUnselected + allUnselected, + isAddIndexerModalOpen, + isEditIndexerModalOpen } = this.state; const selectedIndexerIds = this.getSelectedIds(); @@ -348,6 +370,17 @@ class SearchIndex extends Component { !error && !isFetching && hasIndexers && !items.length && } + + + + { From 15e7cc7ea81c23aaf3be48195f5d4e6b05e37101 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 13 Jun 2023 07:28:32 +0300 Subject: [PATCH 0095/1128] New: (UI) Show indexer categories in info modal --- .../Indexer/Info/IndexerInfoModalContent.tsx | 53 +++++++++++++++++++ src/NzbDrone.Core/Localization/Core/en.json | 1 + 2 files changed, 54 insertions(+) diff --git a/frontend/src/Indexer/Info/IndexerInfoModalContent.tsx b/frontend/src/Indexer/Info/IndexerInfoModalContent.tsx index 5249e980a..71a609485 100644 --- a/frontend/src/Indexer/Info/IndexerInfoModalContent.tsx +++ b/frontend/src/Indexer/Info/IndexerInfoModalContent.tsx @@ -13,6 +13,10 @@ import ModalBody from 'Components/Modal/ModalBody'; import ModalContent from 'Components/Modal/ModalContent'; import ModalFooter from 'Components/Modal/ModalFooter'; import ModalHeader from 'Components/Modal/ModalHeader'; +import TableRowCell from 'Components/Table/Cells/TableRowCell'; +import Table from 'Components/Table/Table'; +import TableBody from 'Components/Table/TableBody'; +import TableRow from 'Components/Table/TableRow'; import TagListConnector from 'Components/TagListConnector'; import { kinds } from 'Helpers/Props'; import DeleteIndexerModal from 'Indexer/Delete/DeleteIndexerModal'; @@ -149,6 +153,7 @@ function IndexerInfoModalContent(props: IndexerInfoModalContentProps) {
+
@@ -237,6 +242,54 @@ function IndexerInfoModalContent(props: IndexerInfoModalContentProps) {
+ + {capabilities.categories !== null && + capabilities.categories.length > 0 ? ( +
+ + {capabilities.categories + .sort((a, b) => a.id - b.id) + .map((category) => { + return ( + + + {category.id} + {category.name} + + {category.subCategories !== null && + category.subCategories.length > 0 + ? category.subCategories + .sort((a, b) => a.id - b.id) + .map((subCategory) => { + return ( + + {subCategory.id} + + {subCategory.name} + + + ); + }) + : null} + + ); + })} +
+
+ ) : null}