Compare commits

..

24 Commits

Author SHA1 Message Date
Weblate
52a49e6a34 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Discover999 <13189912235@163.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: ZijiYu <ziji.yu@stonybrook.edu>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_CN/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_Hans/
Translation: Servarr/Prowlarr
2025-05-11 00:07:11 +03:00
Bogdan
a7d99f351c Fixed: Parsing user agents without a version
Fixes #2392
2025-05-11 00:05:29 +03:00
Bogdan
b0212dd780 Add hourly limits as defaults for PTP 2025-05-10 11:55:11 +03:00
Bogdan
c8f5099423 Use the thrown exception in http timeout handling 2025-05-09 15:58:02 +03:00
Bogdan
5cc4c3f302 Bump version to 1.36.1 2025-05-04 21:06:28 +03:00
Bogdan
c0d2cb42e9 Fixed: (PTP) Sorting releases by time added 2025-05-01 17:06:17 +03:00
Bogdan
8081f13052 Clean logging messages in AppriseProxy 2025-05-01 12:12:47 +03:00
Bogdan
84b672e617 Fixed: Sync indexers to apps only if search is available 2025-05-01 01:34:09 +03:00
Bogdan
ed586c2d72 Update fixture file for PTP 2025-05-01 00:30:55 +03:00
Bogdan
233176e321 Improve error message when BHD's API responds with HTML 2025-04-30 22:12:30 +03:00
Bogdan
d1e3390bae Fixed: (PTP) Category mapping for search results 2025-04-30 22:12:30 +03:00
Bogdan
1cd60c7a40 Bump version to 1.36.0 2025-04-30 14:03:05 +03:00
Bogdan
c61cfcd312 Avoid logging the whole response in the exception when not finding JSON selectors in Cardigann 2025-04-30 12:36:34 +03:00
Weblate
5eb4d112ca Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Weblate <noreply-mt-weblate@weblate.org>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/nb_NO/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/uk/
Translation: Servarr/Prowlarr
2025-04-29 11:05:21 +03:00
Mark McDowall
70f2361d69 Improve messaging when NZB contains invalid XML
(cherry picked from commit 728df146ada115a367bf1ce808482a4625e6098d)
2025-04-29 10:58:31 +03:00
Bogdan
1d6babaa15 Bump caniuse db 2025-04-29 10:23:51 +03:00
Bogdan
0427add8d0 Bump core-js to 3.41 2025-04-29 10:23:15 +03:00
Bogdan
010c2b836d Clean up formatted strings in log messages 2025-04-29 10:16:59 +03:00
Bogdan
22c4c1fc9a Pass messages with arguments to NLog in LoggerExtensions
(cherry picked from commit 9683b0af35220bb0af801779a06d73feaeba809a)
2025-04-29 10:14:32 +03:00
Bogdan
d5f6cc94b8 Fixed: (PTP) TV search capabilities removed 2025-04-29 10:04:40 +03:00
Bogdan
411e96ef2a New: Redirect enabled by default when adding new usenet indexers 2025-04-28 21:52:09 +03:00
Bogdan
2b0e52ebca Update default log level message 2025-04-27 21:22:37 +03:00
Bogdan
c6fa26ca7b Bump version to 1.35.1 2025-04-27 11:48:50 +03:00
blu3
c85f170d41 Bump license year 2025-04-23 11:34:19 +03:00
35 changed files with 325 additions and 103 deletions

View File

@@ -78,6 +78,6 @@ Thank you to [<img src="https://resources.jetbrains.com/storage/products/company
### License
- [GNU GPL v3](http://www.gnu.org/licenses/gpl.html)
- Copyright 2010-2024
- Copyright 2010-2025
Icon Credit - [Box vector created by freepik - www.freepik.com](https://www.freepik.com/vectors/box)

View File

@@ -9,7 +9,7 @@ variables:
testsFolder: './_tests'
yarnCacheFolder: $(Pipeline.Workspace)/.yarn
nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages
majorVersion: '1.35.0'
majorVersion: '1.36.1'
minorVersion: $[counter('minorVersion', 1)]
prowlarrVersion: '$(majorVersion).$(minorVersion)'
buildName: '$(Build.SourceBranchName).$(prowlarrVersion)'

View File

@@ -170,7 +170,7 @@ module.exports = (env) => {
loose: true,
debug: false,
useBuiltIns: 'entry',
corejs: '3.39'
corejs: '3.41'
}
]
]

View File

@@ -104,7 +104,7 @@
"babel-loader": "9.2.1",
"babel-plugin-inline-classnames": "2.0.1",
"babel-plugin-transform-react-remove-prop-types": "0.4.24",
"core-js": "3.39.0",
"core-js": "3.41.0",
"css-loader": "6.7.3",
"css-modules-typescript-loader": "4.0.1",
"eslint": "8.57.1",

View File

@@ -16,6 +16,8 @@ namespace NzbDrone.Common.Test.Http
[TestCase("Readarr/1.0.0.2300 (ubuntu 20.04)", "Readarr")]
[TestCase("Sonarr/3.0.6.9999 (ubuntu 20.04)", "Sonarr")]
[TestCase("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36", "Other")]
[TestCase("appbrr", "appbrr")]
[TestCase(" appbrr ", "appbrr")]
public void should_parse_user_agent(string userAgent, string parsedAgent)
{
UserAgentParser.ParseSource(userAgent).Should().Be(parsedAgent);

View File

@@ -167,7 +167,7 @@ namespace NzbDrone.Common.Http.Dispatchers
}
catch (OperationCanceledException ex) when (cts.IsCancellationRequested)
{
throw new WebException("Http request timed out", ex.InnerException, WebExceptionStatus.Timeout, null);
throw new WebException("Http request timed out", ex, WebExceptionStatus.Timeout, null);
}
}

View File

@@ -1,15 +1,16 @@
using System;
using System.Text.RegularExpressions;
namespace NzbDrone.Common.Http
{
public static class UserAgentParser
{
private static readonly Regex AppSourceRegex = new Regex(@"(?<agent>[a-z0-9]*)\/.*(?:\(.*\))?",
private static readonly Regex AppSourceRegex = new (@"^(?<agent>[a-z0-9]+)(?:\/.+(?:\(.*\))?|$)",
RegexOptions.IgnoreCase | RegexOptions.Compiled);
public static string SimplifyUserAgent(string userAgent)
{
if (userAgent == null || userAgent.StartsWith("Mozilla/5.0"))
if (userAgent == null || userAgent.StartsWith("Mozilla/5.0", StringComparison.Ordinal))
{
return null;
}
@@ -19,14 +20,9 @@ namespace NzbDrone.Common.Http
public static string ParseSource(string userAgent)
{
var match = AppSourceRegex.Match(SimplifyUserAgent(userAgent) ?? string.Empty);
var match = AppSourceRegex.Match(SimplifyUserAgent(userAgent?.Trim()) ?? string.Empty);
if (match.Groups["agent"].Success)
{
return match.Groups["agent"].Value;
}
return "Other";
return match.Groups["agent"].Success ? match.Groups["agent"].Value : "Other";
}
}
}

View File

@@ -4,27 +4,27 @@ namespace NzbDrone.Common.Instrumentation.Extensions
{
public static class LoggerExtensions
{
[MessageTemplateFormatMethod("message")]
public static void ProgressInfo(this Logger logger, string message, params object[] args)
{
var formattedMessage = string.Format(message, args);
LogProgressMessage(logger, LogLevel.Info, formattedMessage);
LogProgressMessage(logger, LogLevel.Info, message, args);
}
[MessageTemplateFormatMethod("message")]
public static void ProgressDebug(this Logger logger, string message, params object[] args)
{
var formattedMessage = string.Format(message, args);
LogProgressMessage(logger, LogLevel.Debug, formattedMessage);
LogProgressMessage(logger, LogLevel.Debug, message, args);
}
[MessageTemplateFormatMethod("message")]
public static void ProgressTrace(this Logger logger, string message, params object[] args)
{
var formattedMessage = string.Format(message, args);
LogProgressMessage(logger, LogLevel.Trace, formattedMessage);
LogProgressMessage(logger, LogLevel.Trace, message, args);
}
private static void LogProgressMessage(Logger logger, LogLevel level, string message)
private static void LogProgressMessage(Logger logger, LogLevel level, string message, object[] parameters)
{
var logEvent = new LogEventInfo(level, logger.Name, message);
var logEvent = new LogEventInfo(level, logger.Name, null, message, parameters);
logEvent.Properties.Add("Status", "");
logger.Log(logEvent);

File diff suppressed because one or more lines are too long

View File

@@ -121,9 +121,16 @@ namespace NzbDrone.Core.Applications.Lidarr
{
var indexerCapabilities = GetIndexerCapabilities(indexer);
if (!indexerCapabilities.MusicSearchAvailable)
{
_logger.Debug("Skipping add for indexer {0} [{1}] due to missing music search support by the indexer", indexer.Name, indexer.Id);
return;
}
if (indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Empty())
{
_logger.Trace("Skipping add for indexer {0} [{1}] due to no app Sync Categories supported by the indexer", indexer.Name, indexer.Id);
_logger.Debug("Skipping add for indexer {0} [{1}] due to no app Sync Categories supported by the indexer", indexer.Name, indexer.Id);
return;
}
@@ -178,7 +185,7 @@ namespace NzbDrone.Core.Applications.Lidarr
{
_logger.Debug("Syncing remote indexer with current settings");
if (indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
if (indexerCapabilities.MusicSearchAvailable && indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
{
// Retain user fields not-affiliated with Prowlarr
lidarrIndexer.Fields.AddRange(remoteIndexer.Fields.Where(f => lidarrIndexer.Fields.All(s => s.Name != f.Name)));
@@ -204,7 +211,7 @@ namespace NzbDrone.Core.Applications.Lidarr
{
_appIndexerMapService.Delete(indexerMapping.Id);
if (indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
if (indexerCapabilities.MusicSearchAvailable && indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
{
_logger.Debug("Remote indexer not found, re-adding {0} [{1}] to Lidarr", indexer.Name, indexer.Id);
lidarrIndexer.Id = 0;

View File

@@ -121,9 +121,16 @@ namespace NzbDrone.Core.Applications.Radarr
{
var indexerCapabilities = GetIndexerCapabilities(indexer);
if (!indexerCapabilities.MovieSearchAvailable)
{
_logger.Debug("Skipping add for indexer {0} [{1}] due to missing movie search support by the indexer", indexer.Name, indexer.Id);
return;
}
if (indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Empty())
{
_logger.Trace("Skipping add for indexer {0} [{1}] due to no app Sync Categories supported by the indexer", indexer.Name, indexer.Id);
_logger.Debug("Skipping add for indexer {0} [{1}] due to no app Sync Categories supported by the indexer", indexer.Name, indexer.Id);
return;
}
@@ -176,7 +183,7 @@ namespace NzbDrone.Core.Applications.Radarr
if (!radarrIndexer.Equals(remoteIndexer) || forceSync)
{
if (indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
if (indexerCapabilities.MovieSearchAvailable && indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
{
// Retain user fields not-affiliated with Prowlarr
radarrIndexer.Fields.AddRange(remoteIndexer.Fields.Where(f => radarrIndexer.Fields.All(s => s.Name != f.Name)));
@@ -202,7 +209,7 @@ namespace NzbDrone.Core.Applications.Radarr
{
_appIndexerMapService.Delete(indexerMapping.Id);
if (indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
if (indexerCapabilities.MovieSearchAvailable && indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
{
_logger.Debug("Remote indexer not found, re-adding {0} [{1}] to Radarr", indexer.Name, indexer.Id);
radarrIndexer.Id = 0;

View File

@@ -121,9 +121,16 @@ namespace NzbDrone.Core.Applications.Readarr
{
var indexerCapabilities = GetIndexerCapabilities(indexer);
if (!indexerCapabilities.BookSearchAvailable)
{
_logger.Debug("Skipping add for indexer {0} [{1}] due to missing book search support by the indexer", indexer.Name, indexer.Id);
return;
}
if (indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Empty())
{
_logger.Trace("Skipping add for indexer {0} [{1}] due to no app Sync Categories supported by the indexer", indexer.Name, indexer.Id);
_logger.Debug("Skipping add for indexer {0} [{1}] due to no app Sync Categories supported by the indexer", indexer.Name, indexer.Id);
return;
}
@@ -178,7 +185,7 @@ namespace NzbDrone.Core.Applications.Readarr
{
_logger.Debug("Syncing remote indexer with current settings");
if (indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
if (indexerCapabilities.BookSearchAvailable && indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
{
// Retain user fields not-affiliated with Prowlarr
readarrIndexer.Fields.AddRange(remoteIndexer.Fields.Where(f => readarrIndexer.Fields.All(s => s.Name != f.Name)));
@@ -204,7 +211,7 @@ namespace NzbDrone.Core.Applications.Readarr
{
_appIndexerMapService.Delete(indexerMapping.Id);
if (indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
if (indexerCapabilities.BookSearchAvailable && indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
{
_logger.Debug("Remote indexer not found, re-adding {0} [{1}] to Readarr", indexer.Name, indexer.Id);
readarrIndexer.Id = 0;

View File

@@ -125,10 +125,17 @@ namespace NzbDrone.Core.Applications.Sonarr
{
var indexerCapabilities = GetIndexerCapabilities(indexer);
if (!indexerCapabilities.TvSearchAvailable)
{
_logger.Debug("Skipping add for indexer {0} [{1}] due to missing TV search support by the indexer", indexer.Name, indexer.Id);
return;
}
if (indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Empty() &&
indexerCapabilities.Categories.SupportedCategories(Settings.AnimeSyncCategories.ToArray()).Empty())
{
_logger.Trace("Skipping add for indexer {0} [{1}] due to no app Sync Categories supported by the indexer", indexer.Name, indexer.Id);
_logger.Debug("Skipping add for indexer {0} [{1}] due to no app Sync Categories supported by the indexer", indexer.Name, indexer.Id);
return;
}
@@ -183,7 +190,7 @@ namespace NzbDrone.Core.Applications.Sonarr
{
_logger.Debug("Syncing remote indexer with current settings");
if (indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any() || indexerCapabilities.Categories.SupportedCategories(Settings.AnimeSyncCategories.ToArray()).Any())
if (indexerCapabilities.TvSearchAvailable && (indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any() || indexerCapabilities.Categories.SupportedCategories(Settings.AnimeSyncCategories.ToArray()).Any()))
{
// Retain user fields not-affiliated with Prowlarr
sonarrIndexer.Fields.AddRange(remoteIndexer.Fields.Where(f => sonarrIndexer.Fields.All(s => s.Name != f.Name)));
@@ -210,7 +217,7 @@ namespace NzbDrone.Core.Applications.Sonarr
{
_appIndexerMapService.Delete(indexerMapping.Id);
if (indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any() || indexerCapabilities.Categories.SupportedCategories(Settings.AnimeSyncCategories.ToArray()).Any())
if (indexerCapabilities.TvSearchAvailable && (indexerCapabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any() || indexerCapabilities.Categories.SupportedCategories(Settings.AnimeSyncCategories.ToArray()).Any()))
{
_logger.Debug("Remote indexer not found, re-adding {0} [{1}] to Sonarr", indexer.Name, indexer.Id);
sonarrIndexer.Id = 0;

View File

@@ -1,3 +1,4 @@
using System;
using System.IO;
using System.Linq;
using System.Xml;
@@ -15,39 +16,53 @@ namespace NzbDrone.Core.Download
{
public void Validate(byte[] fileContent)
{
var reader = new StreamReader(new MemoryStream(fileContent));
using (var xmlTextReader = XmlReader.Create(reader, new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore, IgnoreComments = true }))
try
{
var xDoc = XDocument.Load(xmlTextReader);
var nzb = xDoc.Root;
var reader = new StreamReader(new MemoryStream(fileContent));
if (nzb == null)
using (var xmlTextReader = XmlReader.Create(reader,
new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore, IgnoreComments = true }))
{
throw new InvalidNzbException("Invalid NZB: No Root element");
}
var xDoc = XDocument.Load(xmlTextReader);
var nzb = xDoc.Root;
// nZEDb has an bug in their error reporting code spitting out invalid http status codes
if (nzb.Name.LocalName.Equals("error") &&
nzb.TryGetAttributeValue("code", out var code) &&
nzb.TryGetAttributeValue("description", out var description))
{
throw new InvalidNzbException("Invalid NZB: Contains indexer error: {0} - {1}", code, description);
}
if (nzb == null)
{
throw new InvalidNzbException("Invalid NZB: No Root element");
}
if (!nzb.Name.LocalName.Equals("nzb"))
{
throw new InvalidNzbException("Invalid NZB: Unexpected root element. Expected 'nzb' found '{0}'", nzb.Name.LocalName);
}
// nZEDb has a bug in their error reporting code spitting out invalid http status codes
if (nzb.Name.LocalName.Equals("error") &&
nzb.TryGetAttributeValue("code", out var code) &&
nzb.TryGetAttributeValue("description", out var description))
{
throw new InvalidNzbException("Invalid NZB: Contains indexer error: {0} - {1}", code, description);
}
var ns = nzb.Name.Namespace;
var files = nzb.Elements(ns + "file").ToList();
if (!nzb.Name.LocalName.Equals("nzb"))
{
throw new InvalidNzbException(
"Invalid NZB: Unexpected root element. Expected 'nzb' found '{0}'", nzb.Name.LocalName);
}
if (files.Empty())
{
throw new InvalidNzbException("Invalid NZB: No files");
var ns = nzb.Name.Namespace;
var files = nzb.Elements(ns + "file").ToList();
if (files.Empty())
{
throw new InvalidNzbException("Invalid NZB: No files");
}
}
}
catch (InvalidNzbException)
{
// Throw the original exception
throw;
}
catch (Exception ex)
{
throw new InvalidNzbException("Invalid NZB: Unable to parse", ex);
}
}
}
}

View File

@@ -255,6 +255,11 @@ namespace NzbDrone.Core.Indexers.Definitions
throw new IndexerException(indexerResponse, $"Unexpected response status {indexerHttpResponse.StatusCode} code from indexer request");
}
if (indexerHttpResponse.Headers.ContentType.Contains("text/html"))
{
throw new IndexerException(indexerResponse, $"Indexer responded with HTML content. {(indexerHttpResponse.Content.ContainsIgnoreCase("site maintenance") ? "Site is under maintenance." : "Site is likely blocked or unavailable.")}");
}
if (!indexerHttpResponse.Headers.ContentType.Contains(HttpAccept.Json.Value))
{
throw new IndexerException(indexerResponse, $"Unexpected response header {indexerHttpResponse.Headers.ContentType} from indexer request, expected {HttpAccept.Json.Value}");

View File

@@ -227,7 +227,9 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann
{
if (required)
{
throw new Exception($"Selector \"{selectorSelector}\" didn't match {parentObj.ToString(Formatting.None)}");
var jsonContent = parentObj.ToString(Formatting.None);
throw new Exception($"Selector \"{selectorSelector}\" didn't match JSON content").WithData("JsonContent", jsonContent[..Math.Min(jsonContent.Length, 5 * 1024)]);
}
return null;
@@ -260,7 +262,9 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann
{
if (required)
{
throw new Exception($"None of the case selectors \"{string.Join(",", selector.Case)}\" matched {parentObj.ToString(Formatting.None)}");
var jsonContent = parentObj.ToString(Formatting.None);
throw new Exception($"None of the case selectors \"{string.Join(",", selector.Case)}\" matched JSON content").WithData("JsonContent", jsonContent[..Math.Min(jsonContent.Length, 5 * 1024)]);
}
return null;
@@ -739,7 +743,7 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann
case "hexdump":
// this is mainly for debugging invisible special char related issues
var hexData = string.Join("", data.Select(c => c + "(" + ((int)c).ToString("X2") + ")"));
_logger.Debug(string.Format("CardigannIndexer ({0}): strdump: {1}", _definition.Id, hexData));
_logger.Debug("CardigannIndexer ({0}): strdump: {1}", _definition.Id, hexData);
break;
case "strdump":
// for debugging
@@ -915,7 +919,7 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann
break;
default:
_logger.Error(string.Format("CardigannIndexer ({0}): Unsupported selector: {1}", _definition.Id, rowSelector));
_logger.Error("CardigannIndexer ({0}): Unsupported selector: {1}", _definition.Id, rowSelector);
continue;
}
}

View File

@@ -226,7 +226,7 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann
{
results = ApplyFilters(results, search.Preprocessingfilters, variables);
searchResultDocument = searchResultParser.ParseDocument(results);
_logger.Trace(string.Format("CardigannIndexer ({0}): result after preprocessingfilters: {1}", _definition.Id, results));
_logger.Trace("CardigannIndexer ({0}): result after preprocessingfilters: {1}", _definition.Id, results);
}
var rowsSelector = ApplyGoTemplateText(search.Rows.Selector, variables);
@@ -241,7 +241,7 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann
{
results = ApplyFilters(results, search.Preprocessingfilters, variables);
searchResultDocument = searchResultParser.ParseDocument(results);
_logger.Trace(string.Format("CardigannIndexer ({0}): result after preprocessingfilters: {1}", _definition.Id, results));
_logger.Trace("CardigannIndexer ({0}): result after preprocessingfilters: {1}", _definition.Id, results);
}
var rowsSelector = ApplyGoTemplateText(search.Rows.Selector, variables);

View File

@@ -148,7 +148,8 @@ namespace NzbDrone.Core.Indexers.Newznab
SupportsSearch = SupportsSearch,
SupportsRedirect = SupportsRedirect,
SupportsPagination = SupportsPagination,
Capabilities = caps
Capabilities = caps,
Redirect = true
};
}

View File

@@ -36,7 +36,7 @@ namespace NzbDrone.Core.Indexers.Definitions.PassThePopcorn
public override IParseIndexerResponse GetParser()
{
return new PassThePopcornParser(Settings);
return new PassThePopcornParser(Settings, Capabilities.Categories);
}
private IndexerCapabilities SetCapabilities()
@@ -45,10 +45,6 @@ namespace NzbDrone.Core.Indexers.Definitions.PassThePopcorn
{
LimitsDefault = PageSize,
LimitsMax = PageSize,
TvSearchParams = new List<TvSearchParam>
{
TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep, TvSearchParam.ImdbId
},
MovieSearchParams = new List<MovieSearchParam>
{
MovieSearchParam.Q, MovieSearchParam.ImdbId

View File

@@ -14,6 +14,7 @@ namespace NzbDrone.Core.Indexers.Definitions.PassThePopcorn
public class PassThePopcornMovie
{
public string GroupId { get; set; }
public string CategoryId { get; set; }
public string Title { get; set; }
public string Year { get; set; }
public string Cover { get; set; }

View File

@@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using System.Net;
using System.Text.RegularExpressions;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Http;
using NzbDrone.Common.Serializer;
@@ -14,12 +13,12 @@ namespace NzbDrone.Core.Indexers.Definitions.PassThePopcorn
public class PassThePopcornParser : IParseIndexerResponse
{
private readonly PassThePopcornSettings _settings;
private readonly IndexerCapabilitiesCategories _categories;
private static Regex SeasonRegex => new (@"\bS\d{2,3}(E\d{2,3})?\b", RegexOptions.Compiled);
public PassThePopcornParser(PassThePopcornSettings settings)
public PassThePopcornParser(PassThePopcornSettings settings, IndexerCapabilitiesCategories categories)
{
_settings = settings;
_categories = categories;
}
public IList<ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
@@ -84,13 +83,6 @@ namespace NzbDrone.Core.Indexers.Definitions.PassThePopcorn
flags.Add(PassThePopcornFlag.Approved);
}
var categories = new List<IndexerCategory> { NewznabStandardCategory.Movies };
if (title != null && SeasonRegex.Match(title).Success)
{
categories.Add(NewznabStandardCategory.TV);
}
var uploadVolumeFactor = torrent.FreeleechType?.ToUpperInvariant() switch
{
"NEUTRAL LEECH" => 0,
@@ -104,7 +96,7 @@ namespace NzbDrone.Core.Indexers.Definitions.PassThePopcorn
Year = int.Parse(result.Year),
InfoUrl = GetInfoUrl(result.GroupId, id),
DownloadUrl = GetDownloadUrl(id, jsonResponse.AuthKey, jsonResponse.PassKey),
Categories = categories,
Categories = _categories.MapTrackerCatToNewznab(result.CategoryId),
Size = long.Parse(torrent.Size),
Grabs = int.Parse(torrent.Snatched),
Seeders = int.Parse(torrent.Seeders),

View File

@@ -78,6 +78,8 @@ namespace NzbDrone.Core.Indexers.Definitions.PassThePopcorn
{ "action", "advanced" },
{ "json", "noredirect" },
{ "grouping", "0" },
{ "order_by", "time" },
{ "order_way", "desc" },
{ "searchstr", searchTerm }
};

View File

@@ -18,6 +18,12 @@ namespace NzbDrone.Core.Indexers.Definitions.PassThePopcorn
{
private static readonly PassThePopcornSettingsValidator Validator = new ();
public PassThePopcornSettings()
{
BaseSettings.QueryLimit = 150;
BaseSettings.LimitsUnit = (int)IndexerLimitsUnit.Hour;
}
[FieldDefinition(2, Label = "IndexerSettingsApiUser", HelpText = "IndexerPassThePopcornSettingsApiUserHelpText", Privacy = PrivacyLevel.UserName)]
public string APIUser { get; set; }

View File

@@ -195,7 +195,7 @@ namespace NzbDrone.Core.Indexers
}
else if (settings.BaseUrl.IsNotNullOrWhiteSpace() && LegacyUrls.Contains(settings.BaseUrl))
{
_logger.Debug(string.Format("Changing legacy site link from {0} to {1}", settings.BaseUrl, defaultLink));
_logger.Debug("Changing legacy site link from {0} to {1}", settings.BaseUrl, defaultLink);
settings.BaseUrl = defaultLink;
}

View File

@@ -740,5 +740,72 @@
"SelectedCountOfCountReleases": "S'han seleccionat {selectedCount} de les versions {itemCount}",
"SettingsLogRotate": "Rotació del registre",
"AreYouSureYouWantToDeleteCategory": "Esteu segur que voleu suprimir la categoria assignada?",
"Book": "Llibre"
"Book": "Llibre",
"IndexerSettingsCookie": "Cookie",
"DownloadClientFreeboxSettingsAppIdHelpText": "ID d'aplicació indicat en crear accés a l'API de Freebox (ex: 'app_id')",
"DownloadClientFreeboxSettingsHostHelpText": "Nom d'amfitrió o adreça IP de l'amfitrió del Freebox, per defecte a '{url}' (només funcionarà si es troba a la mateixa xarxa)",
"DownloadClientFreeboxSettingsPortHelpText": "Port utilitzat per accedir a la interfície Freebox, per defecte a '{port}'",
"DownloadClientRTorrentSettingsUrlPath": "Camí de l'Url",
"IndexerHDBitsSettingsMediumsHelpText": "Si no s'especifica, s'utilitzen totes les opcions.",
"NotificationsEmailSettingsUseEncryptionHelpText": "Si s'ha de preferir l'ús de l'encriptatge si es configura al servidor, per utilitzar sempre l'encriptatge mitjançant SSL (només Port 465) o StartTLS (qualsevol altre port) o per no utilitzar mai l'encriptatge",
"DownloadClientQbittorrentSettingsFirstAndLastFirst": "Primer i últim",
"DownloadClientFloodSettingsTagsHelpText": "Etiquetes inicials d'una baixada. Per ser reconegut, una baixada ha de tenir totes les etiquetes inicials. Això evita conflictes amb baixades no relacionades.",
"DownloadClientQbittorrentSettingsSequentialOrder": "Ordre seqüencial",
"DownloadClientSettingsUseSslHelpText": "Usa una connexió segura quan es connecti a {clientName}",
"InstallMajorVersionUpdate": "Instal·la l'actualització",
"InstallMajorVersionUpdateMessageLink": "Si us plau, comproveu [{domain}]({url}) per a més informació.",
"OverrideGrabModalTitle": "Sobreescriu i Captura - {title}",
"SecretToken": "Testimoni secret",
"TorrentBlackholeSaveMagnetFilesExtension": "Desa l'extensió dels fitxers magnètics",
"FailedToFetchSettings": "No s'ha pogut recuperar la configuració",
"DownloadClientFreeboxSettingsApiUrlHelpText": "Defineix l'URL base de l'API de Freebox amb la versió de l'API, p. ex. '{url}', per defecte a '{defaultApiUrl}'",
"IndexerSettingsSeedTime": "Temps de la llavor",
"DownloadClientDownloadStationSettingsDirectoryHelpText": "Carpeta compartida opcional per posar les baixades, deixeu en blanc per utilitzar la ubicació predeterminada de l'estació de baixada",
"DownloadClientPneumaticSettingsNzbFolderHelpText": "Aquesta carpeta haurà de ser accessible des de XBMC",
"DownloadClientPneumaticSettingsStrmFolder": "Carpeta Strm",
"DownloadClientSettingsDestinationHelpText": "Especifica manualment la destinació de la baixada, deixeu-ho en blanc per a utilitzar el predeterminat",
"DownloadClientTransmissionSettingsUrlBaseHelpText": "Afegeix un prefix a l'URL rpc de {clientName}, ex. {url}, per defecte a {defaultUrl}",
"IndexerSettingsApiPathHelpText": "Camí a l'api, normalment {url}",
"LogSizeLimitHelpText": "Mida màxima del fitxer de registre en MB abans d'arxivar. Per defecte és 1MB.",
"IndexerNewznabSettingsAdditionalParametersHelpText": "Paràmetres addicionals de Newznab",
"InstallMajorVersionUpdateMessage": "Aquesta actualització instal·larà una nova versió principal i pot no ser compatible amb el vostre sistema. Esteu segur que voleu instal·lar aquesta actualització?",
"PackageVersionInfo": "{packageVersion} per {packageAuthor}",
"UpdaterLogFiles": "Fitxers de registre de l'actualitzador",
"NotificationsEmailSettingsUseEncryption": "Utilitza l'encriptatge",
"NotificationsTelegramSettingsIncludeAppNameHelpText": "Opcionalment prefixa el títol del missatge amb {appName} per diferenciar les notificacions de diferents aplicacions",
"DownloadClientSettingsInitialState": "Estat inicial",
"DownloadClientSettingsInitialStateHelpText": "Estat inicial dels torrents afegits a {clientName}",
"IndexerPassThePopcornSettingsApiUserHelpText": "Aquests paràmetres es troben a la configuració de seguretat de PassThePopcorn (Edita el perfil > Seguretat).",
"DownloadClientRTorrentSettingsUrlPathHelpText": "Camí al extrem XMLRPC, vegeu {url}. Normalment és RPC2 o [camí a ruTorrent]{url2} quan s'utilitza ruTorrent.",
"IndexerSettingsApiPath": "Camí de l'API",
"IndexerHDBitsSettingsCodecsHelpText": "Si no s'especifica, s'utilitzen totes les opcions.",
"IndexerSettingsApiUser": "Usuari de l'API",
"IndexerSettingsSeedTimeHelpText": "El temps en què s'ha de sembrar un torrent abans d'aturar-lo, el buit utilitza el valor per defecte del client de baixada",
"IndexerSettingsSeedRatio": "Ràtio de la llavor",
"IndexerSettingsSeedRatioHelpText": "Ràtio a la qual ha d'arribar un torrent abans d'aturar-se, buit utilitza el valor per defecte del client de baixada. La relació ha de ser com a mínim 1.0 i seguir les regles dels indexadors",
"IndexerSettingsAdditionalParameters": "Paràmetres addicionals",
"DownloadClientFloodSettingsAdditionalTagsHelpText": "Afegeix les propietats dels suports com a etiquetes. Els consells són exemples.",
"DownloadClientFloodSettingsUrlBaseHelpText": "Afegeix un prefix a l'API de Flood, com ara {url}",
"DownloadClientFreeboxSettingsAppToken": "Testimoni d'aplicació",
"DownloadClientNzbgetSettingsAddPausedHelpText": "Aquesta opció requereix com a mínim la versió 16.0 de NzbGet",
"DownloadClientPneumaticSettingsNzbFolder": "Carpeta Nzb",
"DownloadClientPneumaticSettingsStrmFolderHelpText": "Els fitxers .strm d'aquesta carpeta s'importaran amb el dron",
"DownloadClientQbittorrentSettingsFirstAndLastFirstHelpText": "Baixeu primer i primer les últimes peces (qBittorrent 4.1.0+)",
"DownloadClientQbittorrentSettingsSequentialOrderHelpText": "Baixada en ordre seqüencial (qBittorrent 4.1.0+)",
"LabelIsRequired": "L'etiqueta és necessària",
"NotificationsTelegramSettingsIncludeAppName": "Inclou {appName} al títol",
"TorrentBlackholeSaveMagnetFiles": "Desa els fitxers Magnet",
"TorrentBlackholeSaveMagnetFilesExtensionHelpText": "Extensió a utilitzar per als enllaços magnet, per defecte és '.magnet'",
"TorrentBlackholeSaveMagnetFilesHelpText": "Desa l'enllaç magnet si no hi ha cap fitxer .torrent disponible (només útil si el client de baixada admet magnets desats a un fitxer)",
"TorrentBlackholeTorrentFolder": "Carpeta torrent",
"UseSsl": "Usa SSL",
"UsenetBlackholeNzbFolder": "Carpeta Nzb",
"XmlRpcPath": "Camí RPC XML",
"DownloadClientRTorrentSettingsAddStopped": "Afegeix aturat",
"DownloadClientRTorrentSettingsAddStoppedHelpText": "En activar s'afegiran torrents i imants a rTorrent en un estat aturat. Això pot trencar els fitxers magnet.",
"DownloadClientFreeboxSettingsAppTokenHelpText": "S'ha recuperat el testimoni de l'aplicació en crear l'accés a l'API de Freebox (ex: 'app_token')",
"DownloadClientUTorrentProviderMessage": "uTorrent té un historial d'inclusió de criptominers, programari maliciós i anuncis, us animem a triar un client diferent.",
"DownloadClientQbittorrentSettingsInitialStateHelpText": "Estat inicial dels torrents afegits a qBittorrent. Tingueu en compte que els torrents forçats no compleixen amb les restriccions de llavors",
"LogSizeLimit": "Límit de la mida del registre",
"SelectDownloadClientModalTitle": "{modalTitle} - Seleccioneu el client de baixada"
}

View File

@@ -724,7 +724,7 @@
"TestAllApps": "Test All Apps",
"TestAllClients": "Test All Clients",
"TestAllIndexers": "Test All Indexers",
"TheLogLevelDefault": "The log level defaults to 'Info' and can be changed in [General Settings](/settings/general)",
"TheLogLevelDefault": "The log level defaults to 'Debug' and can be changed in [General Settings](/settings/general)",
"Theme": "Theme",
"ThemeHelpText": "Change Application UI Theme, 'Auto' Theme will use your OS Theme to set Light or Dark mode. Inspired by {inspiredBy}.",
"Time": "Time",

View File

@@ -710,7 +710,7 @@
"Logout": "Kirjaudu ulos",
"NoEventsFound": "Tapahtumia ei löytynyt",
"RestartReloadNote": "Huomioi: {appName} käynnistyy palautusprosessin aikana automaattisesti uudelleen.",
"TheLogLevelDefault": "Lokikirjauksen oletusarvoinen laajuus on \"Informatiivinen\". Laajuutta voidaan muuttaa [Yleisistä asetuksista](/settings/general).",
"TheLogLevelDefault": "Lokikirjauksen oletusarvoinen laajuus on \"Vianselvitys\". Laajuutta voidaan muuttaa [Yleisistä asetuksista](/settings/general).",
"UpdateAppDirectlyLoadError": "{appName}ia ei voida päivittää suoraan,",
"UpdaterLogFiles": "Päivittäjän lokitiedostot",
"WouldYouLikeToRestoreBackup": "Haluatko palauttaa varmuuskopion \"{name}\"?",
@@ -806,5 +806,6 @@
"IndexerPassThePopcornSettingsGoldenPopcornOnlyHelpText": "Etsi vain ns. kultaisella pocornilla merkittyjä julkaisuja.",
"IndexerSettingsFreeleechOnly": "Vain \"Freeleech\"",
"IndexerSettingsCookieHelpText": "Jos sivusto vaatii kirjautumisevästeen, on se noudettava selaimen avulla.",
"IndexerAvistazSettingsPasswordHelpText": "Sivuston salasana"
"IndexerAvistazSettingsPasswordHelpText": "Sivuston salasana",
"DownloadClientUTorrentProviderMessage": "Koska uTorrent on tullut tunnetuksi kryptolouhinnasta sekä haitta- ja mainossisällöstä, suosittelemme valitsemaan jonkin muun työkalun."
}

View File

@@ -161,5 +161,6 @@
"Discord": "Discord",
"AddCustomFilter": "Legg til eget filter",
"Clone": "Lukk",
"AddDownloadClientImplementation": "Ny Nedlastingsklient - {implementationName}"
"AddDownloadClientImplementation": "Ny Nedlastingsklient - {implementationName}",
"History": "Historikk"
}

View File

@@ -503,5 +503,10 @@
"UpdateAppDirectlyLoadError": "Não foi possível atualizar o {appName} diretamente,",
"InstallLatest": "Instalar o mais recente",
"CurrentlyInstalled": "Atualmente instalado",
"Mixed": "Corrigido"
"Mixed": "Corrigido",
"FailedToFetchSettings": "Falha ao obter as definições",
"FailedToFetchUpdates": "Falha a obter atualizações",
"External": "Externo",
"Categories": "Categorias",
"days": "dias"
}

View File

@@ -794,7 +794,7 @@
"LogFilesLocation": "Os arquivos de log estão localizados em: {location}",
"Logout": "Sair",
"NoEventsFound": "Nenhum evento encontrado",
"TheLogLevelDefault": "O nível de registro é padronizado como 'Info' e pode ser alterado em [Configurações Gerais](/settings/general)",
"TheLogLevelDefault": "O nível de log padrão é ' Debug ' e pode ser alterado em [ Configurações gerais](/ configurações/geral)",
"UpdateAppDirectlyLoadError": "Incapaz de atualizar o {appName} diretamente,",
"UpdaterLogFiles": "Arquivos de log do atualizador",
"WouldYouLikeToRestoreBackup": "Gostaria de restaurar o backup '{name}'?",

View File

@@ -544,7 +544,7 @@
"LogFilesLocation": "Log kayıtlarının bulunduğu konum: {location}",
"NoEventsFound": "Etkinlik bulunamadı",
"RestartReloadNote": "Not: {appName} geri yükleme işlemi sırasında otomatik olarak yeniden başlatılacak ve kullanıcı arayüzünü yeniden yükleyecektir.",
"TheLogLevelDefault": "Log seviyesi varsayılan olarak 'Bilgi' şeklindedir ve [Genel Ayarlar](/ayarlar/genel) bölümünden değiştirilebilir",
"TheLogLevelDefault": "Günlük düzeyi varsayılan olarak 'Hata Ayıklama'dır ve [Genel Ayarlar](/ayarlar/genel) bölümünden değiştirilebilir",
"UpdateAppDirectlyLoadError": "{appName} doğrudan güncellenemiyor,",
"DockerUpdater": "Güncellemeyi almak için docker konteynerini güncelleyin",
"FailedToFetchUpdates": "Güncellemeler alınamadı",

View File

@@ -449,5 +449,103 @@
"Author": "Автор",
"OnHealthRestoredHelpText": "При відновленні стану",
"IndexerHDBitsSettingsOriginsHelpText": "Якщо не вказано, використовуються всі параметри.",
"days": "дні(в)"
"days": "дні(в)",
"XmlRpcPath": "Шлях XML RPC",
"Directory": "Тека",
"DownloadClientFreeboxSettingsAppId": "ID додатку",
"DownloadClientQbittorrentSettingsFirstAndLastFirst": "Перше і останнє спочатку",
"FailedToFetchUpdates": "Не вдалося завантажити оновлення",
"OverrideGrabModalTitle": "Перевизначити та захопити - {title}",
"UpdaterLogFiles": "Файли журналу оновлення",
"UseSsl": "Використовувати SSL",
"WouldYouLikeToRestoreBackup": "Бажаєте відновити резервну копію '{name}'?",
"DownloadClientSettingsInitialState": "Початковий стан",
"Install": "Встановити",
"InstallMajorVersionUpdateMessage": "Це оновлення встановить нову основну версію і може бути несумісним з вашою системою. Ви впевнені, що хочете встановити це оновлення?",
"Logout": "Завершити сеанс",
"NoDownloadClientsFound": "Клієнти завантаження не знайдено",
"PackageVersionInfo": "{packageVersion} створено {packageAuthor}",
"SecretToken": "Таємний токен",
"DownloadClientFloodSettingsAdditionalTagsHelpText": "Додає властивості мультимедіа у вигляді тегів. Підказки є прикладами.",
"DownloadClientRTorrentSettingsUrlPathHelpText": "Шлях до кінцевої точки XMLRPC див. {url}. Зазвичай це RPC2 або [шлях до ruTorrent]{url2}, коли використовується ruTorrent.",
"DownloadClientSettingsAddPaused": "Додати призупинені",
"FailedToFetchSettings": "Не вдалося отримати налаштування",
"IndexerNewznabSettingsAdditionalParametersHelpText": "Додаткові параметри Newznab",
"DownloadClientPneumaticSettingsNzbFolderHelpText": "Ця тека повинна бути доступна з XBMC",
"DownloadClientPneumaticSettingsStrmFolder": "Тека STRM",
"DownloadClientPneumaticSettingsStrmFolderHelpText": "Файли .strm у цій теці будуть імпортовані дроном",
"InfoUrl": "URL-адреса інформації",
"DownloadClientUTorrentProviderMessage": "uTorrent має історію включення криптомайнерів, шкідливого програмного забезпечення та реклами. Ми наполегливо рекомендуємо вибрати інший клієнт.",
"EditSelectedDownloadClients": "Редагувати вибрані клієнти завантаження",
"IndexerHDBitsSettingsMediumsHelpText": "Якщо не вказано, використовуються всі параметри.",
"IndexerSettingsAdditionalParameters": "Додаткові параметри",
"IndexerSettingsCookie": "Cookie",
"InstallMajorVersionUpdateMessageLink": "Будь ласка, перевірте [{domain}]({url}) для отримання додаткової інформації.",
"InvalidUILanguage": "У вашому інтерфейсі встановлена недопустима мова. Виправте її та збережіть налаштування",
"LogFilesLocation": "Файли журналу знаходяться в: {location}",
"Menu": "Меню",
"OnHealthRestored": "При відновленні стану",
"PasswordConfirmation": "Підтвердження пароля",
"PreviouslyInstalled": "Раніше встановлений",
"LogSizeLimit": "Обмеження розміру журналу",
"LogSizeLimitHelpText": "Максимальний розмір файлу журналу в МБ перед архівацією. За замовчуванням - 1 МБ.",
"SelectDownloadClientModalTitle": "{modalTitle} - Вибрати клієнт завантаження",
"IndexerSettingsApiPath": "Шлях API",
"IndexerSettingsApiPathHelpText": "Шлях до API, зазвичай {url}",
"IndexerSettingsApiUser": "API Користувач",
"Implementation": "Реалізація",
"ManageDownloadClients": "Керування клієнтами завантаження",
"No": "Ні",
"IndexerSettingsSeedRatioHelpText": "Рейтинг, якого має досягти торрент перед зупинкою. Якщо порожньо — використовується значення за замовчуванням клієнта завантаження. Рейтинг має бути не менше 1,0 і відповідати правилам індексаторів",
"IndexerSettingsSeedTimeHelpText": "Час, протягом якого торрент має залишатися на роздачі перед зупинкою, якщо порожньо — використовується значення клієнта завантаження за замовчуванням",
"NotificationsTelegramSettingsIncludeAppName": "Включити {appName} у заголовок",
"NotificationsTelegramSettingsIncludeAppNameHelpText": "При необхідності додати до заголовка повідомлення префікс {appName}, щоб відрізняти сповіщення від різних додатків",
"DownloadClientQbittorrentSettingsContentLayout": "Макет контента",
"External": "Зовнішній",
"TorrentBlackholeTorrentFolder": "Тека торрента",
"Donate": "Задонатити",
"EditSelectedIndexers": "Редагувати вибраний індексатор",
"IndexerSettingsSeedTime": "Час сидіння",
"Label": "Мітка",
"LabelIsRequired": "Необхідна мітка",
"UsenetBlackholeNzbFolder": "Тека NZB",
"NoHistoryFound": "Історія не знайдена",
"NoIndexersFound": "Индексаторі не знайдено",
"DownloadClientNzbgetSettingsAddPausedHelpText": "Для роботи цього параметра потрібна версія NzbGet не нижче 16.0",
"DownloadClientPneumaticSettingsNzbFolder": "Тека NZB",
"IndexerHDBitsSettingsCodecsHelpText": "Якщо не вказано, використовуються всі параметри.",
"DefaultNameCopiedProfile": "{name} - Копіювати",
"Destination": "Місце призначення",
"DownloadClientFloodSettingsTagsHelpText": "Початкові теги завантаження. Щоб бути розпізнаним, завантаження повинно мати всі початкові теги. Це запобігає конфліктам з незв'язаними завантаженнями.",
"DownloadClientFreeboxSettingsAppIdHelpText": "ID програми, отримане під час створення доступу до Freebox API (наприклад, 'app_id')",
"DownloadClientFreeboxSettingsAppToken": "Токен додатку",
"DownloadClientFreeboxSettingsAppTokenHelpText": "Токен додатку, отриманий під час створення доступу до Freebox API (наприклад, 'app_token')",
"DownloadClientFreeboxSettingsHostHelpText": "Ім'я хоста або IP-адреса хоста Freebox, за замовчуванням — '{url}' (працює тільки якщо знаходиться в тій самій мережі)",
"DownloadClientFreeboxSettingsPortHelpText": "Порт, що використовується для доступу до інтерфейсу Freebox, за замовчуванням — '{port}'",
"DownloadClientQbittorrentSettingsInitialStateHelpText": "Початковий стан торрентів, доданих до qBittorrent. Зверніть увагу, що примусові торренти не дотримуються обмежень на роздачу",
"DownloadClientQbittorrentSettingsSequentialOrder": "Завантажувати послідовно",
"DownloadClientRTorrentSettingsAddStopped": "Додати зупинені",
"DownloadClientRTorrentSettingsAddStoppedHelpText": "Увімкнення додасть торренти та магнет-посилання в rTorrent у зупиненому стані. Це може призвести до пошкодження магнет-файлів.",
"DownloadClientRTorrentSettingsUrlPath": "URL-путь",
"NotificationsEmailSettingsUseEncryptionHelpText": "Виберіть режим шифрування: віддавати перевагу шифруванню, якщо воно налаштоване на сервері; завжди використовувати шифрування через SSL (тільки порт 465) або StartTLS (будь-який інший порт); ніколи не використовувати шифрування",
"DownloadClientFreeboxSettingsApiUrlHelpText": "Вкажіть базову URL-адресу Freebox API з версією API, наприклад, '{url}', за замовчуванням — '{defaultApiUrl}'",
"DownloadClientSettingsDestinationHelpText": "Ручне налаштування місця для завантаження, залиште порожнім для використання значення за замовчуванням",
"DownloadClientSettingsUseSslHelpText": "Використовувати захищене з'єднання при підключенні до {clientName}",
"HealthMessagesInfoBox": "Додаткову інформацію про причину появи цих повідомлень перевірки працездатності можна знайти, перейшовши за посиланням wiki (іконка книги) в кінці рядка або перевірити [журнали]({link}). Якщо у вас виникли труднощі з розумінням цих повідомлень, ви можете звернутися до нашої служби підтримки за посиланнями нижче.",
"IndexerDownloadClientHealthCheckMessage": "Індексатори з недопустимими клієнтами завантаження: {indexerNames}.",
"Episode": "Епізод",
"InstallMajorVersionUpdate": "Встановити оновлення",
"ManageClients": "Керування клієнтами",
"PrioritySettings": "Пріоритет: {0}",
"IndexerPassThePopcornSettingsApiUserHelpText": "Ці налаштування можна знайти в налаштуваннях безпеки вашого PassThePopcorn (Редагувати профіль > Безпека).",
"NotificationsEmailSettingsUseEncryption": "Використовувати шифрування",
"TorrentBlackholeSaveMagnetFiles": "Зберігати магнітні файли",
"TorrentBlackholeSaveMagnetFilesExtension": "Зберегти магнет-файли з розширенням",
"TorrentBlackholeSaveMagnetFilesExtensionHelpText": "Розширення для магнет-посилань, за замовчуванням '.magnet'",
"TorrentBlackholeSaveMagnetFilesHelpText": "Зберегти магнет-посилання, якщо файл .torrent недоступний (корисно тільки в разі, якщо клієнт завантаження підтримує магнет-посилання, збережені у файлі)",
"DownloadClientDelugeSettingsUrlBaseHelpText": "Додає префікс до URL-адреси json, {url}",
"DownloadClientTransmissionSettingsUrlBaseHelpText": "Додає префікс до URL-адреси RPC {clientName}, наприклад {url}, за замовчуванням — '{defaultUrl}'",
"IndexerSettingsSeedRatio": "Коефіцієнт роздачі",
"ManualGrab": "Захват вручну",
"StopSelecting": "Скасувати вибір"
}

View File

@@ -3,5 +3,7 @@
"Add": "添加",
"Analytics": "分析",
"Username": "用户名",
"AcceptConfirmationModal": "中文"
"AcceptConfirmationModal": "中文",
"Backup": "备份",
"BackupNow": "立即备份"
}

View File

@@ -91,7 +91,7 @@ namespace NzbDrone.Core.Notifications.Apprise
{
if (httpException.Response.StatusCode == HttpStatusCode.Unauthorized)
{
_logger.Error(ex, $"HTTP Auth credentials are invalid: {0}", ex.Message);
_logger.Error(ex, "HTTP Auth credentials are invalid: {0}", ex.Message);
return new ValidationFailure("AuthUsername", $"HTTP Auth credentials are invalid: {ex.Message}");
}
@@ -99,7 +99,7 @@ namespace NzbDrone.Core.Notifications.Apprise
{
var error = Json.Deserialize<AppriseError>(httpException.Response.Content);
_logger.Error(ex, $"Unable to send test message. Response from API: {0}", error.Error);
_logger.Error(ex, "Unable to send test message. Response from API: {0}", error.Error);
return new ValidationFailure(string.Empty, $"Unable to send test message. Response from API: {error.Error}");
}

View File

@@ -2260,9 +2260,9 @@ camelcase@^5.3.1:
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
caniuse-lite@^1.0.30001646, caniuse-lite@^1.0.30001663:
version "1.0.30001667"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001667.tgz#99fc5ea0d9c6e96897a104a8352604378377f949"
integrity sha512-7LTwJjcRkzKFmtqGsibMeuXmvFDfZq/nzIjnmgCGzKKRVzjD72selLDK1oPF/Oxzmt4fNcPvTDvGqSDG4tCALw==
version "1.0.30001715"
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001715.tgz"
integrity sha512-7ptkFGMm2OAOgvZpwgA4yjQ5SQbrNVGdRjzH0pBdy1Fasvcr+KAeECmbCAECzTuDuoX0FCY8KzUxjf9+9kfZEw==
chalk@^2.4.1, chalk@^2.4.2:
version "2.4.2"
@@ -2478,10 +2478,10 @@ core-js-compat@^3.38.0, core-js-compat@^3.38.1:
dependencies:
browserslist "^4.23.3"
core-js@3.39.0:
version "3.39.0"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.39.0.tgz#57f7647f4d2d030c32a72ea23a0555b2eaa30f83"
integrity sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==
core-js@3.41.0:
version "3.41.0"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.41.0.tgz#57714dafb8c751a6095d028a7428f1fb5834a776"
integrity sha512-SJ4/EHwS36QMJd6h/Rg+GyR4A5xE0FSI3eZ+iBVpfqf1x0eTSg1smWLHrA+2jQThZSh97fmSgFSU8B61nxosxA==
core-js@^2.4.0:
version "2.6.12"