Translate Download Clients on the backend
This commit is contained in:
parent
3d05913534
commit
48b12f5b00
|
@ -1,6 +1,9 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
|
using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Core.Annotations;
|
using NzbDrone.Core.Annotations;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Test.Common;
|
using NzbDrone.Test.Common;
|
||||||
using Sonarr.Http.ClientSchema;
|
using Sonarr.Http.ClientSchema;
|
||||||
|
|
||||||
|
@ -9,6 +12,16 @@ namespace NzbDrone.Api.Test.ClientSchemaTests
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class SchemaBuilderFixture : TestBase
|
public class SchemaBuilderFixture : TestBase
|
||||||
{
|
{
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<ILocalizationService>()
|
||||||
|
.Setup(s => s.GetLocalizedString(It.IsAny<string>(), It.IsAny<Dictionary<string, object>>()))
|
||||||
|
.Returns<string, Dictionary<string, object>>((s, d) => s);
|
||||||
|
|
||||||
|
SchemaBuilder.Initialize(Mocker.Container);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_field_for_every_property()
|
public void should_return_field_for_every_property()
|
||||||
{
|
{
|
||||||
|
|
|
@ -320,7 +320,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.HadoukenTests
|
||||||
|
|
||||||
var result = Subject.Test();
|
var result = Subject.Test();
|
||||||
|
|
||||||
result.Errors.First().ErrorMessage.Should().Be("Old Hadouken client with unsupported API, need 5.1 or higher");
|
result.Errors.Count.Should().Be(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,23 @@ namespace NzbDrone.Core.Annotations
|
||||||
public string RequestAction { get; set; }
|
public string RequestAction { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
|
||||||
|
public class FieldTokenAttribute : Attribute
|
||||||
|
{
|
||||||
|
public FieldTokenAttribute(TokenField field, string label = "", string token = "", object value = null)
|
||||||
|
{
|
||||||
|
Label = label;
|
||||||
|
Field = field;
|
||||||
|
Token = token;
|
||||||
|
Value = value?.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Label { get; set; }
|
||||||
|
public TokenField Field { get; set; }
|
||||||
|
public string Token { get; set; }
|
||||||
|
public string Value { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public class FieldSelectOption
|
public class FieldSelectOption
|
||||||
{
|
{
|
||||||
public int Value { get; set; }
|
public int Value { get; set; }
|
||||||
|
@ -85,4 +102,11 @@ namespace NzbDrone.Core.Annotations
|
||||||
ApiKey,
|
ApiKey,
|
||||||
UserName
|
UserName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum TokenField
|
||||||
|
{
|
||||||
|
Label,
|
||||||
|
HelpText,
|
||||||
|
HelpTextWarning
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
@ -27,8 +28,9 @@ namespace NzbDrone.Core.Download.Clients.Aria2
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
Logger logger)
|
Logger logger,
|
||||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger)
|
ILocalizationService localizationService)
|
||||||
|
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger, localizationService)
|
||||||
{
|
{
|
||||||
_proxy = proxy;
|
_proxy = proxy;
|
||||||
}
|
}
|
||||||
|
@ -233,14 +235,19 @@ namespace NzbDrone.Core.Download.Clients.Aria2
|
||||||
|
|
||||||
if (new Version(version) < new Version("1.34.0"))
|
if (new Version(version) < new Version("1.34.0"))
|
||||||
{
|
{
|
||||||
return new ValidationFailure(string.Empty, "Aria2 version should be at least 1.34.0. Version reported is {0}", version);
|
return new ValidationFailure(string.Empty,
|
||||||
|
_localizationService.GetLocalizedString("DownloadClientValidationErrorVersion",
|
||||||
|
new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "clientName", "Aria2" }, { "requiredVersion", "1.34.0" }, { "reportedVersion", version }
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, "Failed to test Aria2");
|
_logger.Error(ex, "Failed to test Aria2");
|
||||||
|
|
||||||
return new NzbDroneValidationFailure("Host", "Unable to connect to Aria2")
|
return new NzbDroneValidationFailure("Host", _localizationService.GetLocalizedString("DownloadClientValidationUnableToConnect", new Dictionary<string, object> { { "clientName", "Aria2" } }))
|
||||||
{
|
{
|
||||||
DetailedDescription = ex.Message
|
DetailedDescription = ex.Message
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,13 +32,13 @@ namespace NzbDrone.Core.Download.Clients.Aria2
|
||||||
[FieldDefinition(1, Label = "Port", Type = FieldType.Number)]
|
[FieldDefinition(1, Label = "Port", Type = FieldType.Number)]
|
||||||
public int Port { get; set; }
|
public int Port { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(2, Label = "XML RPC Path", Type = FieldType.Textbox)]
|
[FieldDefinition(2, Label = "XmlRpcPath", Type = FieldType.Textbox)]
|
||||||
public string RpcPath { get; set; }
|
public string RpcPath { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(3, Label = "Use SSL", Type = FieldType.Checkbox)]
|
[FieldDefinition(3, Label = "UseSsl", Type = FieldType.Checkbox)]
|
||||||
public bool UseSsl { get; set; }
|
public bool UseSsl { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(4, Label = "Secret token", Type = FieldType.Password, Privacy = PrivacyLevel.Password)]
|
[FieldDefinition(4, Label = "SecretToken", Type = FieldType.Password, Privacy = PrivacyLevel.Password)]
|
||||||
public string SecretToken { get; set; }
|
public string SecretToken { get; set; }
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
|
|
|
@ -8,6 +8,7 @@ using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
using NzbDrone.Core.Organizer;
|
using NzbDrone.Core.Organizer;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
@ -29,8 +30,9 @@ namespace NzbDrone.Core.Download.Clients.Blackhole
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
Logger logger)
|
Logger logger,
|
||||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger)
|
ILocalizationService localizationService)
|
||||||
|
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger, localizationService)
|
||||||
{
|
{
|
||||||
_scanWatchFolder = scanWatchFolder;
|
_scanWatchFolder = scanWatchFolder;
|
||||||
|
|
||||||
|
@ -79,7 +81,7 @@ namespace NzbDrone.Core.Download.Clients.Blackhole
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Name => "Torrent Blackhole";
|
public override string Name => _localizationService.GetLocalizedString("TorrentBlackhole");
|
||||||
|
|
||||||
public override IEnumerable<DownloadClientItem> GetItems()
|
public override IEnumerable<DownloadClientItem> GetItems()
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,23 +28,24 @@ namespace NzbDrone.Core.Download.Clients.Blackhole
|
||||||
|
|
||||||
private static readonly TorrentBlackholeSettingsValidator Validator = new TorrentBlackholeSettingsValidator();
|
private static readonly TorrentBlackholeSettingsValidator Validator = new TorrentBlackholeSettingsValidator();
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "Torrent Folder", Type = FieldType.Path, HelpText = "Folder in which Sonarr will store the .torrent file")]
|
[FieldDefinition(0, Label = "TorrentBlackholeTorrentFolder", Type = FieldType.Path, HelpText = "BlackholeFolderHelpText")]
|
||||||
|
[FieldToken(TokenField.HelpText, "TorrentBlackholeTorrentFolder", "extension", ".torrent")]
|
||||||
public string TorrentFolder { get; set; }
|
public string TorrentFolder { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(1, Label = "Watch Folder", Type = FieldType.Path, HelpText = "Folder from which Sonarr should import completed downloads")]
|
[FieldDefinition(1, Label = "BlackholeWatchFolder", Type = FieldType.Path, HelpText = "BlackholeWatchFolderHelpText")]
|
||||||
public string WatchFolder { get; set; }
|
public string WatchFolder { get; set; }
|
||||||
|
|
||||||
[DefaultValue(false)]
|
[DefaultValue(false)]
|
||||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
|
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
|
||||||
[FieldDefinition(2, Label = "Save Magnet Files", Type = FieldType.Checkbox, HelpText = "Save the magnet link if no .torrent file is available (only useful if the download client supports magnets saved to a file)")]
|
[FieldDefinition(2, Label = "TorrentBlackholeSaveMagnetFiles", Type = FieldType.Checkbox, HelpText = "TorrentBlackholeSaveMagnetFilesHelpText")]
|
||||||
public bool SaveMagnetFiles { get; set; }
|
public bool SaveMagnetFiles { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(3, Label = "Save Magnet Files", Type = FieldType.Textbox, HelpText = "Extension to use for magnet links, defaults to '.magnet'")]
|
[FieldDefinition(3, Label = "TorrentBlackholeSaveMagnetFilesExtension", Type = FieldType.Textbox, HelpText = "TorrentBlackholeSaveMagnetFilesExtensionHelpText")]
|
||||||
public string MagnetFileExtension { get; set; }
|
public string MagnetFileExtension { get; set; }
|
||||||
|
|
||||||
[DefaultValue(false)]
|
[DefaultValue(false)]
|
||||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
|
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
|
||||||
[FieldDefinition(4, Label = "Read Only", Type = FieldType.Checkbox, HelpText = "Instead of moving files this will instruct Sonarr to Copy or Hardlink (depending on settings/system configuration)")]
|
[FieldDefinition(4, Label = "TorrentBlackholeSaveMagnetFilesReadOnly", Type = FieldType.Checkbox, HelpText = "TorrentBlackholeSaveMagnetFilesReadOnlyHelpText")]
|
||||||
public bool ReadOnly { get; set; }
|
public bool ReadOnly { get; set; }
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
|
|
|
@ -7,6 +7,7 @@ using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Organizer;
|
using NzbDrone.Core.Organizer;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
@ -25,8 +26,9 @@ namespace NzbDrone.Core.Download.Clients.Blackhole
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
IValidateNzbs nzbValidationService,
|
IValidateNzbs nzbValidationService,
|
||||||
Logger logger)
|
Logger logger,
|
||||||
: base(httpClient, configService, diskProvider, remotePathMappingService, nzbValidationService, logger)
|
ILocalizationService localizationService)
|
||||||
|
: base(httpClient, configService, diskProvider, remotePathMappingService, nzbValidationService, logger, localizationService)
|
||||||
{
|
{
|
||||||
_scanWatchFolder = scanWatchFolder;
|
_scanWatchFolder = scanWatchFolder;
|
||||||
|
|
||||||
|
@ -51,7 +53,7 @@ namespace NzbDrone.Core.Download.Clients.Blackhole
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Name => "Usenet Blackhole";
|
public override string Name => _localizationService.GetLocalizedString("UsenetBlackhole");
|
||||||
|
|
||||||
public override IEnumerable<DownloadClientItem> GetItems()
|
public override IEnumerable<DownloadClientItem> GetItems()
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,10 +19,11 @@ namespace NzbDrone.Core.Download.Clients.Blackhole
|
||||||
{
|
{
|
||||||
private static readonly UsenetBlackholeSettingsValidator Validator = new UsenetBlackholeSettingsValidator();
|
private static readonly UsenetBlackholeSettingsValidator Validator = new UsenetBlackholeSettingsValidator();
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "Nzb Folder", Type = FieldType.Path, HelpText = "Folder in which Sonarr will store the .nzb file")]
|
[FieldDefinition(0, Label = "UsenetBlackholeNzbFolder", Type = FieldType.Path, HelpText = "BlackholeFolderHelpText")]
|
||||||
|
[FieldToken(TokenField.HelpText, "UsenetBlackholeNzbFolder", "extension", ".nzb")]
|
||||||
public string NzbFolder { get; set; }
|
public string NzbFolder { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(1, Label = "Watch Folder", Type = FieldType.Path, HelpText = "Folder from which Sonarr should import completed downloads")]
|
[FieldDefinition(1, Label = "BlackholeWatchFolder", Type = FieldType.Path, HelpText = "BlackholeWatchFolderHelpText")]
|
||||||
public string WatchFolder { get; set; }
|
public string WatchFolder { get; set; }
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
|
|
|
@ -8,6 +8,7 @@ using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
@ -25,8 +26,9 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
Logger logger)
|
Logger logger,
|
||||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger)
|
ILocalizationService localizationService)
|
||||||
|
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger, localizationService)
|
||||||
{
|
{
|
||||||
_proxy = proxy;
|
_proxy = proxy;
|
||||||
}
|
}
|
||||||
|
@ -155,7 +157,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
||||||
if (torrent.State == DelugeTorrentStatus.Error)
|
if (torrent.State == DelugeTorrentStatus.Error)
|
||||||
{
|
{
|
||||||
item.Status = DownloadItemStatus.Warning;
|
item.Status = DownloadItemStatus.Warning;
|
||||||
item.Message = "Deluge is reporting an error";
|
item.Message = _localizationService.GetLocalizedString("DownloadClientDelugeTorrentStateError");
|
||||||
}
|
}
|
||||||
else if (torrent.IsFinished && torrent.State != DelugeTorrentStatus.Checking)
|
else if (torrent.IsFinished && torrent.State != DelugeTorrentStatus.Checking)
|
||||||
{
|
{
|
||||||
|
@ -248,7 +250,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
||||||
{
|
{
|
||||||
_logger.Error(ex, ex.Message);
|
_logger.Error(ex, ex.Message);
|
||||||
|
|
||||||
return new NzbDroneValidationFailure("Password", "Authentication failed");
|
return new NzbDroneValidationFailure("Password", _localizationService.GetLocalizedString("DownloadClientValidationAuthenticationFailure"));
|
||||||
}
|
}
|
||||||
catch (WebException ex)
|
catch (WebException ex)
|
||||||
{
|
{
|
||||||
|
@ -256,29 +258,29 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
||||||
switch (ex.Status)
|
switch (ex.Status)
|
||||||
{
|
{
|
||||||
case WebExceptionStatus.ConnectFailure:
|
case WebExceptionStatus.ConnectFailure:
|
||||||
return new NzbDroneValidationFailure("Host", "Unable to connect")
|
return new NzbDroneValidationFailure("Host", _localizationService.GetLocalizedString("DownloadClientValidationUnableToConnect", new Dictionary<string, object> { { "clientName", Name } }))
|
||||||
{
|
{
|
||||||
DetailedDescription = "Please verify the hostname and port."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientValidationUnableToConnectDetail")
|
||||||
};
|
};
|
||||||
case WebExceptionStatus.ConnectionClosed:
|
case WebExceptionStatus.ConnectionClosed:
|
||||||
return new NzbDroneValidationFailure("UseSsl", "Verify SSL settings")
|
return new NzbDroneValidationFailure("UseSsl", _localizationService.GetLocalizedString("DownloadClientValidationVerifySsl"))
|
||||||
{
|
{
|
||||||
DetailedDescription = "Please verify your SSL configuration on both Deluge and Sonarr."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientValidationVerifySslDetail", new Dictionary<string, object> { { "clientName", Name } })
|
||||||
};
|
};
|
||||||
case WebExceptionStatus.SecureChannelFailure:
|
case WebExceptionStatus.SecureChannelFailure:
|
||||||
return new NzbDroneValidationFailure("UseSsl", "Unable to connect through SSL")
|
return new NzbDroneValidationFailure("UseSsl", _localizationService.GetLocalizedString("DownloadClientValidationSslConnectFailure"))
|
||||||
{
|
{
|
||||||
DetailedDescription = "Sonarr is unable to connect to Deluge using SSL. This problem could be computer related. Please try to configure both Sonarr and Deluge to not use SSL."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientValidationSslConnectFailureDetail", new Dictionary<string, object> { { "clientName", Name } })
|
||||||
};
|
};
|
||||||
default:
|
default:
|
||||||
return new NzbDroneValidationFailure(string.Empty, "Unknown exception: " + ex.Message);
|
return new NzbDroneValidationFailure(string.Empty, _localizationService.GetLocalizedString("DownloadClientValidationUnknownException", new Dictionary<string, object> { { "exception", ex.Message } }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, "Failed to test connection");
|
_logger.Error(ex, "Failed to test connection");
|
||||||
|
|
||||||
return new NzbDroneValidationFailure("Host", "Unable to connect to Deluge")
|
return new NzbDroneValidationFailure("Host", _localizationService.GetLocalizedString("DownloadClientValidationUnableToConnect", new Dictionary<string, object> { { "clientName", Name } }))
|
||||||
{
|
{
|
||||||
DetailedDescription = ex.Message
|
DetailedDescription = ex.Message
|
||||||
};
|
};
|
||||||
|
@ -298,9 +300,9 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
||||||
|
|
||||||
if (!enabledPlugins.Contains("Label"))
|
if (!enabledPlugins.Contains("Label"))
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure("TvCategory", "Label plugin not activated")
|
return new NzbDroneValidationFailure("TvCategory", _localizationService.GetLocalizedString("DownloadClientDelugeValidationLabelPluginInactive"))
|
||||||
{
|
{
|
||||||
DetailedDescription = "You must have the Label plugin enabled in Deluge to use categories."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientDelugeValidationLabelPluginInactiveDetail", new Dictionary<string, object> { { "clientName", Name } })
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,9 +315,9 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
||||||
|
|
||||||
if (!labels.Contains(Settings.TvCategory))
|
if (!labels.Contains(Settings.TvCategory))
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure("TvCategory", "Configuration of label failed")
|
return new NzbDroneValidationFailure("TvCategory", _localizationService.GetLocalizedString("DownloadClientDelugeValidationLabelPluginFailure"))
|
||||||
{
|
{
|
||||||
DetailedDescription = "Sonarr was unable to add the label to Deluge."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientDelugeValidationLabelPluginFailureDetail", new Dictionary<string, object> { { "clientName", Name } })
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -327,9 +329,9 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
||||||
|
|
||||||
if (!labels.Contains(Settings.TvImportedCategory))
|
if (!labels.Contains(Settings.TvImportedCategory))
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure("TvImportedCategory", "Configuration of label failed")
|
return new NzbDroneValidationFailure("TvImportedCategory", _localizationService.GetLocalizedString("DownloadClientDelugeValidationLabelPluginFailure"))
|
||||||
{
|
{
|
||||||
DetailedDescription = "Sonarr was unable to add the label to Deluge."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientDelugeValidationLabelPluginFailureDetail", new Dictionary<string, object> { { "clientName", Name } })
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -346,7 +348,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, "Unable to get torrents");
|
_logger.Error(ex, "Unable to get torrents");
|
||||||
return new NzbDroneValidationFailure(string.Empty, "Failed to get the list of torrents: " + ex.Message);
|
return new NzbDroneValidationFailure(string.Empty, _localizationService.GetLocalizedString("DownloadClientValidationTestTorrents", new Dictionary<string, object> { { "exceptionMessage", ex.Message } }));
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -35,28 +35,30 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
||||||
[FieldDefinition(1, Label = "Port", Type = FieldType.Textbox)]
|
[FieldDefinition(1, Label = "Port", Type = FieldType.Textbox)]
|
||||||
public int Port { get; set; }
|
public int Port { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(2, Label = "Use SSL", Type = FieldType.Checkbox, HelpText = "Use secure connection when connecting to Deluge")]
|
[FieldDefinition(2, Label = "UseSsl", Type = FieldType.Checkbox, HelpText = "DownloadClientSettingsUseSslHelpText")]
|
||||||
|
[FieldToken(TokenField.HelpText, "UseSsl", "clientName", "Deluge")]
|
||||||
public bool UseSsl { get; set; }
|
public bool UseSsl { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(3, Label = "Url Base", Type = FieldType.Textbox, Advanced = true, HelpText = "Adds a prefix to the deluge json url, see http://[host]:[port]/[urlBase]/json")]
|
[FieldDefinition(3, Label = "UrlBase", Type = FieldType.Textbox, Advanced = true, HelpText = "DownloadClientDelugeSettingsUrlBaseHelpText")]
|
||||||
|
[FieldToken(TokenField.HelpText, "UrlBase", "url", "http://[host]:[port]/[urlBase]/json")]
|
||||||
public string UrlBase { get; set; }
|
public string UrlBase { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(4, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password)]
|
[FieldDefinition(4, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password)]
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(5, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Sonarr avoids conflicts with unrelated non-Sonarr downloads. Using a category is optional, but strongly recommended.")]
|
[FieldDefinition(5, Label = "Category", Type = FieldType.Textbox, HelpText = "DownloadClientSettingsCategoryHelpText")]
|
||||||
public string TvCategory { get; set; }
|
public string TvCategory { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(6, Label = "Post-Import Category", Type = FieldType.Textbox, Advanced = true, HelpText = "Category for Sonarr to set after it has imported the download. Sonarr will not remove torrents in that category even if seeding finished. Leave blank to keep same category.")]
|
[FieldDefinition(6, Label = "PostImportCategory", Type = FieldType.Textbox, Advanced = true, HelpText = "DownloadClientSettingsPostImportCategoryHelpText")]
|
||||||
public string TvImportedCategory { get; set; }
|
public string TvImportedCategory { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(7, Label = "Recent Priority", Type = FieldType.Select, SelectOptions = typeof(DelugePriority), HelpText = "Priority to use when grabbing episodes that aired within the last 14 days")]
|
[FieldDefinition(7, Label = "DownloadClientSettingsRecentPriority", Type = FieldType.Select, SelectOptions = typeof(DelugePriority), HelpText = "DownloadClientSettingsRecentPriorityHelpText")]
|
||||||
public int RecentTvPriority { get; set; }
|
public int RecentTvPriority { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(8, Label = "Older Priority", Type = FieldType.Select, SelectOptions = typeof(DelugePriority), HelpText = "Priority to use when grabbing episodes that aired over 14 days ago")]
|
[FieldDefinition(8, Label = "DownloadClientSettingsOlderPriority", Type = FieldType.Select, SelectOptions = typeof(DelugePriority), HelpText = "DownloadClientSettingsOlderPriorityHelpText")]
|
||||||
public int OlderTvPriority { get; set; }
|
public int OlderTvPriority { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(9, Label = "Add Paused", Type = FieldType.Checkbox)]
|
[FieldDefinition(9, Label = "DownloadClientSettingsAddPaused", Type = FieldType.Checkbox)]
|
||||||
public bool AddPaused { get; set; }
|
public bool AddPaused { get; set; }
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
|
|
|
@ -36,7 +36,8 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
|
||||||
[FieldDefinition(1, Label = "Port", Type = FieldType.Textbox)]
|
[FieldDefinition(1, Label = "Port", Type = FieldType.Textbox)]
|
||||||
public int Port { get; set; }
|
public int Port { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(2, Label = "Use SSL", Type = FieldType.Checkbox, HelpText = "Use secure connection when connecting to Download Station")]
|
[FieldDefinition(2, Label = "UseSsl", Type = FieldType.Checkbox, HelpText = "DownloadClientSettingsUseSslHelpText")]
|
||||||
|
[FieldToken(TokenField.HelpText, "UseSsl", "clientName", "Download Station")]
|
||||||
public bool UseSsl { get; set; }
|
public bool UseSsl { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(3, Label = "Username", Type = FieldType.Textbox, Privacy = PrivacyLevel.UserName)]
|
[FieldDefinition(3, Label = "Username", Type = FieldType.Textbox, Privacy = PrivacyLevel.UserName)]
|
||||||
|
@ -45,10 +46,10 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
|
||||||
[FieldDefinition(4, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password)]
|
[FieldDefinition(4, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password)]
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(5, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Sonarr avoids conflicts with unrelated non-Sonarr downloads. Using a category is optional, but strongly recommended.. Creates a [category] subdirectory in the output directory.")]
|
[FieldDefinition(5, Label = "Category", Type = FieldType.Textbox, HelpText = "DownloadClientSettingsCategorySubFolderHelpText")]
|
||||||
public string TvCategory { get; set; }
|
public string TvCategory { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(6, Label = "Directory", Type = FieldType.Textbox, HelpText = "Optional shared folder to put downloads into, leave blank to use the default Download Station location")]
|
[FieldDefinition(6, Label = "Directory", Type = FieldType.Textbox, HelpText = "DownloadClientDownloadStationSettingsDirectory")]
|
||||||
public string TvDirectory { get; set; }
|
public string TvDirectory { get; set; }
|
||||||
|
|
||||||
public DownloadStationSettings()
|
public DownloadStationSettings()
|
||||||
|
|
|
@ -10,6 +10,7 @@ using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Download.Clients.DownloadStation.Proxies;
|
using NzbDrone.Core.Download.Clients.DownloadStation.Proxies;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
@ -36,8 +37,9 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
Logger logger)
|
Logger logger,
|
||||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger)
|
ILocalizationService localizationService)
|
||||||
|
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger, localizationService)
|
||||||
{
|
{
|
||||||
_dsInfoProxy = dsInfoProxy;
|
_dsInfoProxy = dsInfoProxy;
|
||||||
_dsTaskProxySelector = dsTaskProxySelector;
|
_dsTaskProxySelector = dsTaskProxySelector;
|
||||||
|
@ -48,7 +50,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
|
||||||
|
|
||||||
public override string Name => "Download Station";
|
public override string Name => "Download Station";
|
||||||
|
|
||||||
public override ProviderMessage Message => new ProviderMessage("Sonarr is unable to connect to Download Station if 2-Factor Authentication is enabled on your DSM account", ProviderMessageType.Warning);
|
public override ProviderMessage Message => new ProviderMessage(_localizationService.GetLocalizedString("DownloadClientDownloadStationProviderMessage"), ProviderMessageType.Warning);
|
||||||
|
|
||||||
private IDownloadStationTaskProxy DsTaskProxy => _dsTaskProxySelector.GetProxy(Settings);
|
private IDownloadStationTaskProxy DsTaskProxy => _dsTaskProxySelector.GetProxy(Settings);
|
||||||
|
|
||||||
|
@ -222,7 +224,9 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
|
||||||
{
|
{
|
||||||
if (torrent.Status == DownloadStationTaskStatus.Extracting)
|
if (torrent.Status == DownloadStationTaskStatus.Extracting)
|
||||||
{
|
{
|
||||||
return $"Extracting: {int.Parse(torrent.StatusExtra["unzip_progress"])}%";
|
return _localizationService.GetLocalizedString("DownloadStationStatusExtracting",
|
||||||
|
new Dictionary<string, object>
|
||||||
|
{ { "progress", int.Parse(torrent.StatusExtra["unzip_progress"]) } });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (torrent.Status == DownloadStationTaskStatus.Error)
|
if (torrent.Status == DownloadStationTaskStatus.Error)
|
||||||
|
@ -308,9 +312,9 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
|
||||||
|
|
||||||
if (downloadDir == null)
|
if (downloadDir == null)
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure(nameof(Settings.TvDirectory), "No default destination")
|
return new NzbDroneValidationFailure(nameof(Settings.TvDirectory), "DownloadClientDownloadStationValidationNoDefaultDestination")
|
||||||
{
|
{
|
||||||
DetailedDescription = $"You must login into your Diskstation as {Settings.Username} and manually set it up into DownloadStation settings under BT/HTTP/FTP/NZB -> Location."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientDownloadStationValidationNoDefaultDestinationDetail", new Dictionary<string, object> { { "username", Settings.Username } })
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,17 +329,17 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
|
||||||
|
|
||||||
if (folderInfo.Additional == null)
|
if (folderInfo.Additional == null)
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure(fieldName, $"Shared folder does not exist")
|
return new NzbDroneValidationFailure(fieldName, _localizationService.GetLocalizedString("DownloadClientDownloadStationValidationSharedFolderMissing"))
|
||||||
{
|
{
|
||||||
DetailedDescription = $"The Diskstation does not have a Shared Folder with the name '{sharedFolder}', are you sure you specified it correctly?"
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientDownloadStationValidationSharedFolderMissingDetail", new Dictionary<string, object> { { "sharedFolder", sharedFolder } })
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!folderInfo.IsDir)
|
if (!folderInfo.IsDir)
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure(fieldName, $"Folder does not exist")
|
return new NzbDroneValidationFailure(fieldName, _localizationService.GetLocalizedString("DownloadClientDownloadStationValidationFolderMissing"))
|
||||||
{
|
{
|
||||||
DetailedDescription = $"The folder '{downloadDir}' does not exist, it must be created manually inside the Shared Folder '{sharedFolder}'."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientDownloadStationValidationFolderMissingDetail", new Dictionary<string, object> { { "downloadDir", downloadDir }, { "sharedFolder", sharedFolder } })
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -351,7 +355,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, "Error testing Torrent Download Station");
|
_logger.Error(ex, "Error testing Torrent Download Station");
|
||||||
return new NzbDroneValidationFailure(string.Empty, $"Unknown exception: {ex.Message}");
|
return new NzbDroneValidationFailure(string.Empty, _localizationService.GetLocalizedString("DownloadClientValidationUnknownException", new Dictionary<string, object> { { "exception", ex.Message } }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,9 +368,9 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
|
||||||
catch (DownloadClientAuthenticationException ex)
|
catch (DownloadClientAuthenticationException ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, ex.Message);
|
_logger.Error(ex, ex.Message);
|
||||||
return new NzbDroneValidationFailure("Username", "Authentication failure")
|
return new NzbDroneValidationFailure("Username", _localizationService.GetLocalizedString("DownloadClientValidationAuthenticationFailure"))
|
||||||
{
|
{
|
||||||
DetailedDescription = $"Please verify your username and password. Also verify if the host running Sonarr isn't blocked from accessing {Name} by WhiteList limitations in the {Name} configuration."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientValidationAuthenticationFailureDetail", new Dictionary<string, object> { { "clientName", Name } })
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
catch (WebException ex)
|
catch (WebException ex)
|
||||||
|
@ -375,19 +379,19 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
|
||||||
|
|
||||||
if (ex.Status == WebExceptionStatus.ConnectFailure)
|
if (ex.Status == WebExceptionStatus.ConnectFailure)
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure("Host", "Unable to connect")
|
return new NzbDroneValidationFailure("Host", _localizationService.GetLocalizedString("DownloadClientValidationUnableToConnect", new Dictionary<string, object> { { "clientName", Name } }))
|
||||||
{
|
{
|
||||||
DetailedDescription = "Please verify the hostname and port."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientValidationUnableToConnectDetail")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return new NzbDroneValidationFailure(string.Empty, $"Unknown exception: {ex.Message}");
|
return new NzbDroneValidationFailure(string.Empty, _localizationService.GetLocalizedString("DownloadClientValidationUnknownException", new Dictionary<string, object> { { "exception", ex.Message } }));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, "Error testing Torrent Download Station");
|
_logger.Error(ex, "Error testing Torrent Download Station");
|
||||||
|
|
||||||
return new NzbDroneValidationFailure("Host", "Unable to connect to Torrent Download Station")
|
return new NzbDroneValidationFailure("Host", _localizationService.GetLocalizedString("DownloadClientValidationUnableToConnect", new Dictionary<string, object> { { "clientName", Name } }))
|
||||||
{
|
{
|
||||||
DetailedDescription = ex.Message
|
DetailedDescription = ex.Message
|
||||||
};
|
};
|
||||||
|
@ -402,7 +406,12 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
|
||||||
|
|
||||||
if (info.MinVersion > 2 || info.MaxVersion < 2)
|
if (info.MinVersion > 2 || info.MaxVersion < 2)
|
||||||
{
|
{
|
||||||
return new ValidationFailure(string.Empty, $"Download Station API version not supported, should be at least 2. It supports from {info.MinVersion} to {info.MaxVersion}");
|
return new ValidationFailure(string.Empty,
|
||||||
|
_localizationService.GetLocalizedString("DownloadClientDownloadStationValidationApiVersion",
|
||||||
|
new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "requiredVersion", 2 }, { "minVersion", info.MinVersion }, { "maxVersion", info.MaxVersion }
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -417,7 +426,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure(string.Empty, $"Failed to get the list of torrents: {ex.Message}");
|
return new NzbDroneValidationFailure(string.Empty, _localizationService.GetLocalizedString("DownloadClientValidationTestTorrents", new Dictionary<string, object> { { "exceptionMessage", ex.Message } }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Download.Clients.DownloadStation.Proxies;
|
using NzbDrone.Core.Download.Clients.DownloadStation.Proxies;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
@ -34,8 +35,9 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
IValidateNzbs nzbValidationService,
|
IValidateNzbs nzbValidationService,
|
||||||
Logger logger)
|
Logger logger,
|
||||||
: base(httpClient, configService, diskProvider, remotePathMappingService, nzbValidationService, logger)
|
ILocalizationService localizationService)
|
||||||
|
: base(httpClient, configService, diskProvider, remotePathMappingService, nzbValidationService, logger, localizationService)
|
||||||
{
|
{
|
||||||
_dsInfoProxy = dsInfoProxy;
|
_dsInfoProxy = dsInfoProxy;
|
||||||
_dsTaskProxySelector = dsTaskProxySelector;
|
_dsTaskProxySelector = dsTaskProxySelector;
|
||||||
|
@ -46,7 +48,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
|
||||||
|
|
||||||
public override string Name => "Download Station";
|
public override string Name => "Download Station";
|
||||||
|
|
||||||
public override ProviderMessage Message => new ProviderMessage("Sonarr is unable to connect to Download Station if 2-Factor Authentication is enabled on your DSM account", ProviderMessageType.Warning);
|
public override ProviderMessage Message => new ProviderMessage(_localizationService.GetLocalizedString("DownloadClientDownloadStationProviderMessage"), ProviderMessageType.Warning);
|
||||||
|
|
||||||
private IDownloadStationTaskProxy DsTaskProxy => _dsTaskProxySelector.GetProxy(Settings);
|
private IDownloadStationTaskProxy DsTaskProxy => _dsTaskProxySelector.GetProxy(Settings);
|
||||||
|
|
||||||
|
@ -213,9 +215,9 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
|
||||||
|
|
||||||
if (downloadDir == null)
|
if (downloadDir == null)
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure(nameof(Settings.TvDirectory), "No default destination")
|
return new NzbDroneValidationFailure(nameof(Settings.TvDirectory), "DownloadClientDownloadStationValidationNoDefaultDestination")
|
||||||
{
|
{
|
||||||
DetailedDescription = $"You must login into your Diskstation as {Settings.Username} and manually set it up into DownloadStation settings under BT/HTTP/FTP/NZB -> Location."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientDownloadStationValidationNoDefaultDestinationDetail", new Dictionary<string, object> { { "username", Settings.Username } })
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,17 +232,17 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
|
||||||
|
|
||||||
if (folderInfo.Additional == null)
|
if (folderInfo.Additional == null)
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure(fieldName, $"Shared folder does not exist")
|
return new NzbDroneValidationFailure(fieldName, _localizationService.GetLocalizedString("DownloadClientDownloadStationValidationSharedFolderMissing"))
|
||||||
{
|
{
|
||||||
DetailedDescription = $"The Diskstation does not have a Shared Folder with the name '{sharedFolder}', are you sure you specified it correctly?"
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientDownloadStationValidationSharedFolderMissingDetail", new Dictionary<string, object> { { "sharedFolder", sharedFolder } })
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!folderInfo.IsDir)
|
if (!folderInfo.IsDir)
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure(fieldName, $"Folder does not exist")
|
return new NzbDroneValidationFailure(fieldName, _localizationService.GetLocalizedString("DownloadClientDownloadStationValidationFolderMissing"))
|
||||||
{
|
{
|
||||||
DetailedDescription = $"The folder '{downloadDir}' does not exist, it must be created manually inside the Shared Folder '{sharedFolder}'."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientDownloadStationValidationFolderMissingDetail", new Dictionary<string, object> { { "downloadDir", downloadDir }, { "sharedFolder", sharedFolder } })
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -256,7 +258,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, "Error testing Usenet Download Station");
|
_logger.Error(ex, "Error testing Usenet Download Station");
|
||||||
return new NzbDroneValidationFailure(string.Empty, $"Unknown exception: {ex.Message}");
|
return new NzbDroneValidationFailure(string.Empty, _localizationService.GetLocalizedString("DownloadClientValidationUnknownException", new Dictionary<string, object> { { "exception", ex.Message } }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,9 +271,9 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
|
||||||
catch (DownloadClientAuthenticationException ex)
|
catch (DownloadClientAuthenticationException ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, ex.Message);
|
_logger.Error(ex, ex.Message);
|
||||||
return new NzbDroneValidationFailure("Username", "Authentication failure")
|
return new NzbDroneValidationFailure("Username", _localizationService.GetLocalizedString("DownloadClientValidationAuthenticationFailure"))
|
||||||
{
|
{
|
||||||
DetailedDescription = $"Please verify your username and password. Also verify if the host running Sonarr isn't blocked from accessing {Name} by WhiteList limitations in the {Name} configuration."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientValidationAuthenticationFailureDetail", new Dictionary<string, object> { { "clientName", Name } })
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
catch (WebException ex)
|
catch (WebException ex)
|
||||||
|
@ -280,19 +282,19 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
|
||||||
|
|
||||||
if (ex.Status == WebExceptionStatus.ConnectFailure)
|
if (ex.Status == WebExceptionStatus.ConnectFailure)
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure("Host", "Unable to connect")
|
return new NzbDroneValidationFailure("Host", _localizationService.GetLocalizedString("DownloadClientValidationUnableToConnect", new Dictionary<string, object> { { "clientName", Name } }))
|
||||||
{
|
{
|
||||||
DetailedDescription = "Please verify the hostname and port."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientValidationUnableToConnectDetail")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return new NzbDroneValidationFailure(string.Empty, "Unknown exception: " + ex.Message);
|
return new NzbDroneValidationFailure(string.Empty, _localizationService.GetLocalizedString("DownloadClientValidationUnknownException", new Dictionary<string, object> { { "exception", ex.Message } }));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, "Error testing Torrent Download Station");
|
_logger.Error(ex, "Error testing Torrent Download Station");
|
||||||
|
|
||||||
return new NzbDroneValidationFailure("Host", "Unable to connect to Usenet Download Station")
|
return new NzbDroneValidationFailure("Host", _localizationService.GetLocalizedString("DownloadClientValidationUnableToConnect", new Dictionary<string, object> { { "clientName", Name } }))
|
||||||
{
|
{
|
||||||
DetailedDescription = ex.Message
|
DetailedDescription = ex.Message
|
||||||
};
|
};
|
||||||
|
@ -307,7 +309,12 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
|
||||||
|
|
||||||
if (info.MinVersion > 2 || info.MaxVersion < 2)
|
if (info.MinVersion > 2 || info.MaxVersion < 2)
|
||||||
{
|
{
|
||||||
return new ValidationFailure(string.Empty, $"Download Station API version not supported, should be at least 2. It supports from {info.MinVersion} to {info.MaxVersion}");
|
return new ValidationFailure(string.Empty,
|
||||||
|
_localizationService.GetLocalizedString("DownloadClientDownloadStationValidationApiVersion",
|
||||||
|
new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "requiredVersion", 2 }, { "minVersion", info.MinVersion }, { "maxVersion", info.MaxVersion }
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -319,7 +326,9 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
|
||||||
{
|
{
|
||||||
if (task.Status == DownloadStationTaskStatus.Extracting)
|
if (task.Status == DownloadStationTaskStatus.Extracting)
|
||||||
{
|
{
|
||||||
return $"Extracting: {int.Parse(task.StatusExtra["unzip_progress"])}%";
|
return _localizationService.GetLocalizedString("DownloadStationStatusExtracting",
|
||||||
|
new Dictionary<string, object>
|
||||||
|
{ { "progress", int.Parse(task.StatusExtra["unzip_progress"]) } });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (task.Status == DownloadStationTaskStatus.Error)
|
if (task.Status == DownloadStationTaskStatus.Error)
|
||||||
|
@ -398,7 +407,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure(string.Empty, "Failed to get the list of NZBs: " + ex.Message);
|
return new NzbDroneValidationFailure(string.Empty, _localizationService.GetLocalizedString("DownloadClientValidationTestNzbs", new Dictionary<string, object> { { "exceptionMessage", ex.Message } }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Download.Clients.Flood.Models;
|
using NzbDrone.Core.Download.Clients.Flood.Models;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
@ -28,8 +29,9 @@ namespace NzbDrone.Core.Download.Clients.Flood
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
Logger logger)
|
Logger logger,
|
||||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger)
|
ILocalizationService localizationService)
|
||||||
|
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger, localizationService)
|
||||||
{
|
{
|
||||||
_proxy = proxy;
|
_proxy = proxy;
|
||||||
_downloadSeedConfigProvider = downloadSeedConfigProvider;
|
_downloadSeedConfigProvider = downloadSeedConfigProvider;
|
||||||
|
@ -81,7 +83,7 @@ namespace NzbDrone.Core.Download.Clients.Flood
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Name => "Flood";
|
public override string Name => "Flood";
|
||||||
public override ProviderMessage Message => new ProviderMessage("Sonarr will handle automatic removal of torrents based on the current seed criteria in Settings -> Indexers", ProviderMessageType.Info);
|
public override ProviderMessage Message => new ProviderMessage(_localizationService.GetLocalizedString("DownloadClientFloodSettingsRemovalInfo"), ProviderMessageType.Info);
|
||||||
|
|
||||||
protected override string AddFromTorrentFile(RemoteEpisode remoteEpisode, string hash, string filename, byte[] fileContent)
|
protected override string AddFromTorrentFile(RemoteEpisode remoteEpisode, string hash, string filename, byte[] fileContent)
|
||||||
{
|
{
|
||||||
|
|
|
@ -40,10 +40,12 @@ namespace NzbDrone.Core.Download.Clients.Flood
|
||||||
[FieldDefinition(1, Label = "Port", Type = FieldType.Textbox)]
|
[FieldDefinition(1, Label = "Port", Type = FieldType.Textbox)]
|
||||||
public int Port { get; set; }
|
public int Port { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(2, Label = "Use SSL", Type = FieldType.Checkbox, HelpText = "Use secure connection when connecting to Flood")]
|
[FieldDefinition(2, Label = "UseSsl", Type = FieldType.Checkbox, HelpText = "DownloadClientSettingsUseSslHelpText")]
|
||||||
|
[FieldToken(TokenField.HelpText, "UseSsl", "clientName", "Flood")]
|
||||||
public bool UseSsl { get; set; }
|
public bool UseSsl { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(3, Label = "Url Base", Type = FieldType.Textbox, HelpText = "Optionally adds a prefix to Flood API, such as [protocol]://[host]:[port]/[urlBase]api")]
|
[FieldDefinition(3, Label = "UrlBase", Type = FieldType.Textbox, HelpText = "DownloadClientFloodSettingsUrlBaseHelpText")]
|
||||||
|
[FieldToken(TokenField.HelpText, "UrlBase", "url", "[protocol]://[host]:[port]/[urlBase]/api")]
|
||||||
public string UrlBase { get; set; }
|
public string UrlBase { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(4, Label = "Username", Type = FieldType.Textbox, Privacy = PrivacyLevel.UserName)]
|
[FieldDefinition(4, Label = "Username", Type = FieldType.Textbox, Privacy = PrivacyLevel.UserName)]
|
||||||
|
@ -52,19 +54,19 @@ namespace NzbDrone.Core.Download.Clients.Flood
|
||||||
[FieldDefinition(5, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password)]
|
[FieldDefinition(5, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password)]
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(6, Label = "Destination", Type = FieldType.Textbox, HelpText = "Manually specifies download destination")]
|
[FieldDefinition(6, Label = "Destination", Type = FieldType.Textbox, HelpText = "DownloadClientSettingsDestinationHelpText")]
|
||||||
public string Destination { get; set; }
|
public string Destination { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(7, Label = "Tags", Type = FieldType.Tag, HelpText = "Initial tags of a download. To be recognized, a download must have all initial tags. This avoids conflicts with unrelated downloads.")]
|
[FieldDefinition(7, Label = "Tags", Type = FieldType.Tag, HelpText = "DownloadClientFloodSettingsTagsHelpText")]
|
||||||
public IEnumerable<string> Tags { get; set; }
|
public IEnumerable<string> Tags { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(8, Label = "Post-Import Tags", Type = FieldType.Tag, HelpText = "Appends tags after a download is imported.", Advanced = true)]
|
[FieldDefinition(8, Label = "DownloadClientFloodSettingsPostImportTags", Type = FieldType.Tag, HelpText = "DownloadClientFloodSettingsPostImportTagsHelpText", Advanced = true)]
|
||||||
public IEnumerable<string> PostImportTags { get; set; }
|
public IEnumerable<string> PostImportTags { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(9, Label = "Additional Tags", Type = FieldType.Select, SelectOptions = typeof(AdditionalTags), HelpText = "Adds properties of media as tags. Hints are examples.", Advanced = true)]
|
[FieldDefinition(9, Label = "DownloadClientFloodSettingsAdditionalTags", Type = FieldType.Select, SelectOptions = typeof(AdditionalTags), HelpText = "DownloadClientFloodSettingsAdditionalTagsHelpText", Advanced = true)]
|
||||||
public IEnumerable<int> AdditionalTags { get; set; }
|
public IEnumerable<int> AdditionalTags { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(10, Label = "Start on Add", Type = FieldType.Checkbox)]
|
[FieldDefinition(10, Label = "DownloadClientFloodSettingsStartOnAdd", Type = FieldType.Checkbox)]
|
||||||
public bool StartOnAdd { get; set; }
|
public bool StartOnAdd { get; set; }
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
|
|
|
@ -46,37 +46,42 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload
|
||||||
ApiUrl = "/api/v1/";
|
ApiUrl = "/api/v1/";
|
||||||
}
|
}
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "Host", Type = FieldType.Textbox, HelpText = "Hostname or host IP address of the Freebox, defaults to 'mafreebox.freebox.fr' (will only work if on same network)")]
|
[FieldDefinition(0, Label = "Host", Type = FieldType.Textbox, HelpText = "DownloadClientFreeboxSettingsHostHelpText")]
|
||||||
|
[FieldToken(TokenField.HelpText, "Host", "url", "mafreebox.freebox.fr")]
|
||||||
public string Host { get; set; }
|
public string Host { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(1, Label = "Port", Type = FieldType.Textbox, HelpText = "Port used to access Freebox interface, defaults to '443'")]
|
[FieldDefinition(1, Label = "Port", Type = FieldType.Textbox, HelpText = "DownloadClientFreeboxSettingsPortHelpText")]
|
||||||
|
[FieldToken(TokenField.HelpText, "Port", "port", 443)]
|
||||||
public int Port { get; set; }
|
public int Port { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(2, Label = "Use SSL", Type = FieldType.Checkbox, HelpText = "Use secured connection when connecting to Freebox API")]
|
[FieldDefinition(2, Label = "UseSsl", Type = FieldType.Checkbox, HelpText = "DownloadClientSettingsUseSslHelpText")]
|
||||||
|
[FieldToken(TokenField.HelpText, "UseSsl", "clientName", "Freebox API")]
|
||||||
public bool UseSsl { get; set; }
|
public bool UseSsl { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(3, Label = "API URL", Type = FieldType.Textbox, Advanced = true, HelpText = "Define Freebox API base URL with API version, eg http://[host]:[port]/[api_base_url]/[api_version]/, defaults to '/api/v1/'")]
|
[FieldDefinition(3, Label = "DownloadClientFreeboxSettingsApiUrl", Type = FieldType.Textbox, Advanced = true, HelpText = "DownloadClientFreeboxSettingsApiUrlHelpText")]
|
||||||
|
[FieldToken(TokenField.HelpText, "DownloadClientFreeboxSettingsApiUrl", "url", "http://[host]:[port]/[api_base_url]/[api_version]/")]
|
||||||
|
[FieldToken(TokenField.HelpText, "DownloadClientFreeboxSettingsApiUrl", "defaultApiUrl", "/api/v1/")]
|
||||||
public string ApiUrl { get; set; }
|
public string ApiUrl { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(4, Label = "App ID", Type = FieldType.Textbox, HelpText = "App ID given when creating access to Freebox API (ie 'app_id')")]
|
[FieldDefinition(4, Label = "DownloadClientFreeboxSettingsAppId", Type = FieldType.Textbox, HelpText = "DownloadClientFreeboxSettingsAppIdHelpText")]
|
||||||
public string AppId { get; set; }
|
public string AppId { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(5, Label = "App Token", Type = FieldType.Password, Privacy = PrivacyLevel.Password, HelpText = "App token retrieved when creating access to Freebox API (ie 'app_token')")]
|
[FieldDefinition(5, Label = "DownloadClientFreeboxSettingsAppToken", Type = FieldType.Password, Privacy = PrivacyLevel.Password, HelpText = "DownloadClientFreeboxSettingsAppTokenHelpText")]
|
||||||
public string AppToken { get; set; }
|
public string AppToken { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(6, Label = "Destination Directory", Type = FieldType.Textbox, Advanced = true, HelpText = "Optional location to put downloads in, leave blank to use the default Freebox download location")]
|
[FieldDefinition(6, Label = "Destination", Type = FieldType.Textbox, Advanced = true, HelpText = "DownloadClientSettingsDestinationHelpText")]
|
||||||
public string DestinationDirectory { get; set; }
|
public string DestinationDirectory { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(7, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Sonarr avoids conflicts with unrelated non-Sonarr downloads (will create a [category] subdirectory in the output directory)")]
|
[FieldDefinition(7, Label = "Category", Type = FieldType.Textbox, HelpText = "DownloadClientSettingsCategorySubFolderHelpText")]
|
||||||
public string Category { get; set; }
|
public string Category { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(8, Label = "Recent Priority", Type = FieldType.Select, SelectOptions = typeof(FreeboxDownloadPriority), HelpText = "Priority to use when grabbing episodes that aired within the last 14 days")]
|
[FieldDefinition(8, Label = "DownloadClientSettingsRecentPriority", Type = FieldType.Select, SelectOptions = typeof(FreeboxDownloadPriority), HelpText = "DownloadClientSettingsRecentPriorityHelpText")]
|
||||||
public int RecentPriority { get; set; }
|
public int RecentPriority { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(9, Label = "Older Priority", Type = FieldType.Select, SelectOptions = typeof(FreeboxDownloadPriority), HelpText = "Priority to use when grabbing episodes that aired over 14 days ago")]
|
[FieldDefinition(9, Label = "DownloadClientSettingsOlderPriority", Type = FieldType.Select, SelectOptions = typeof(FreeboxDownloadPriority), HelpText = "DownloadClientSettingsOlderPriorityHelpText")]
|
||||||
public int OlderPriority { get; set; }
|
public int OlderPriority { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(10, Label = "Add Paused", Type = FieldType.Checkbox)]
|
[FieldDefinition(10, Label = "DownloadClientSettingsAddPaused", Type = FieldType.Checkbox)]
|
||||||
public bool AddPaused { get; set; }
|
public bool AddPaused { get; set; }
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
|
|
|
@ -8,6 +8,7 @@ using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Download.Clients.FreeboxDownload.Responses;
|
using NzbDrone.Core.Download.Clients.FreeboxDownload.Responses;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
@ -24,8 +25,9 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
Logger logger)
|
Logger logger,
|
||||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger)
|
ILocalizationService localizationService)
|
||||||
|
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger, localizationService)
|
||||||
{
|
{
|
||||||
_proxy = proxy;
|
_proxy = proxy;
|
||||||
}
|
}
|
||||||
|
@ -108,8 +110,9 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload
|
||||||
|
|
||||||
case FreeboxDownloadTaskStatus.Unknown:
|
case FreeboxDownloadTaskStatus.Unknown:
|
||||||
default: // new status in API? default to downloading
|
default: // new status in API? default to downloading
|
||||||
item.Message = "Unknown download state: " + torrent.Status;
|
item.Message = _localizationService.GetLocalizedString("UnknownDownloadState",
|
||||||
_logger.Info(item.Message);
|
new Dictionary<string, object> { { "state", torrent.Status } });
|
||||||
|
_logger.Info($"Unknown download state: {torrent.Status}");
|
||||||
item.Status = DownloadItemStatus.Downloading;
|
item.Status = DownloadItemStatus.Downloading;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Download.Clients.Hadouken.Models;
|
using NzbDrone.Core.Download.Clients.Hadouken.Models;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
@ -24,8 +25,9 @@ namespace NzbDrone.Core.Download.Clients.Hadouken
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
Logger logger)
|
Logger logger,
|
||||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger)
|
ILocalizationService localizationService)
|
||||||
|
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger, localizationService)
|
||||||
{
|
{
|
||||||
_proxy = proxy;
|
_proxy = proxy;
|
||||||
}
|
}
|
||||||
|
@ -159,18 +161,20 @@ namespace NzbDrone.Core.Download.Clients.Hadouken
|
||||||
if (version < new Version("5.1"))
|
if (version < new Version("5.1"))
|
||||||
{
|
{
|
||||||
return new ValidationFailure(string.Empty,
|
return new ValidationFailure(string.Empty,
|
||||||
"Old Hadouken client with unsupported API, need 5.1 or higher");
|
_localizationService.GetLocalizedString("DownloadClientValidationErrorVersion",
|
||||||
|
new Dictionary<string, object>
|
||||||
|
{ { "clientName", Name }, { "requiredVersion", "5.1" }, { "reportedVersion", version } }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (DownloadClientAuthenticationException ex)
|
catch (DownloadClientAuthenticationException ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, ex.Message);
|
_logger.Error(ex, ex.Message);
|
||||||
|
|
||||||
return new NzbDroneValidationFailure("Password", "Authentication failed");
|
return new NzbDroneValidationFailure("Password", _localizationService.GetLocalizedString("DownloadClientValidationAuthenticationFailure"));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure("Host", "Unable to connect to Hadouken")
|
return new NzbDroneValidationFailure("Host", _localizationService.GetLocalizedString("DownloadClientValidationUnableToConnect"))
|
||||||
{
|
{
|
||||||
DetailedDescription = ex.Message
|
DetailedDescription = ex.Message
|
||||||
};
|
};
|
||||||
|
@ -188,7 +192,7 @@ namespace NzbDrone.Core.Download.Clients.Hadouken
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, ex.Message);
|
_logger.Error(ex, ex.Message);
|
||||||
return new NzbDroneValidationFailure(string.Empty, "Failed to get the list of torrents: " + ex.Message);
|
return new NzbDroneValidationFailure(string.Empty, _localizationService.GetLocalizedString("DownloadClientValidationTestTorrents", new Dictionary<string, object> { { "exceptionMessage", ex.Message } }));
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -39,10 +39,13 @@ namespace NzbDrone.Core.Download.Clients.Hadouken
|
||||||
[FieldDefinition(1, Label = "Port", Type = FieldType.Textbox)]
|
[FieldDefinition(1, Label = "Port", Type = FieldType.Textbox)]
|
||||||
public int Port { get; set; }
|
public int Port { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(2, Label = "Use SSL", Type = FieldType.Checkbox, HelpText = "Use secure connection when connecting to Hadouken")]
|
[FieldDefinition(2, Label = "UseSsl", Type = FieldType.Checkbox, HelpText = "DownloadClientSettingsUseSslHelpText")]
|
||||||
|
[FieldToken(TokenField.HelpText, "UseSsl", "clientName", "Hadouken")]
|
||||||
public bool UseSsl { get; set; }
|
public bool UseSsl { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(3, Label = "Url Base", Type = FieldType.Textbox, Advanced = true, HelpText = "Adds a prefix to the Hadouken url, e.g. http://[host]:[port]/[urlBase]/api")]
|
[FieldDefinition(3, Label = "UrlBase", Type = FieldType.Textbox, Advanced = true, HelpText = "DownloadClientSettingsUrlBaseHelpText")]
|
||||||
|
[FieldToken(TokenField.HelpText, "UrlBase", "clientName", "Hadouken")]
|
||||||
|
[FieldToken(TokenField.HelpText, "UrlBase", "url", "http://[host]:[port]/[urlBase]/api")]
|
||||||
public string UrlBase { get; set; }
|
public string UrlBase { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(4, Label = "Username", Type = FieldType.Textbox, Privacy = PrivacyLevel.UserName)]
|
[FieldDefinition(4, Label = "Username", Type = FieldType.Textbox, Privacy = PrivacyLevel.UserName)]
|
||||||
|
@ -51,7 +54,7 @@ namespace NzbDrone.Core.Download.Clients.Hadouken
|
||||||
[FieldDefinition(5, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password)]
|
[FieldDefinition(5, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password)]
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(6, Label = "Category", Type = FieldType.Textbox)]
|
[FieldDefinition(6, Label = "Category", Type = FieldType.Textbox, HelpText = "DownloadClientSettingsCategoryHelpText")]
|
||||||
public string Category { get; set; }
|
public string Category { get; set; }
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
|
|
|
@ -8,6 +8,7 @@ using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
using NzbDrone.Core.Validation;
|
using NzbDrone.Core.Validation;
|
||||||
|
@ -24,8 +25,9 @@ namespace NzbDrone.Core.Download.Clients.NzbVortex
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
IValidateNzbs nzbValidationService,
|
IValidateNzbs nzbValidationService,
|
||||||
Logger logger)
|
Logger logger,
|
||||||
: base(httpClient, configService, diskProvider, remotePathMappingService, nzbValidationService, logger)
|
ILocalizationService localizationService)
|
||||||
|
: base(httpClient, configService, diskProvider, remotePathMappingService, nzbValidationService, logger, localizationService)
|
||||||
{
|
{
|
||||||
_proxy = proxy;
|
_proxy = proxy;
|
||||||
}
|
}
|
||||||
|
@ -162,7 +164,7 @@ namespace NzbDrone.Core.Download.Clients.NzbVortex
|
||||||
{
|
{
|
||||||
_logger.Error(ex, "Unable to connect to NZBVortex");
|
_logger.Error(ex, "Unable to connect to NZBVortex");
|
||||||
|
|
||||||
return new NzbDroneValidationFailure("Host", "Unable to connect to NZBVortex")
|
return new NzbDroneValidationFailure("Host", _localizationService.GetLocalizedString("DownloadClientValidationUnableToConnect", new Dictionary<string, object> { { "clientName", Name } }))
|
||||||
{
|
{
|
||||||
DetailedDescription = ex.Message
|
DetailedDescription = ex.Message
|
||||||
};
|
};
|
||||||
|
@ -180,13 +182,16 @@ namespace NzbDrone.Core.Download.Clients.NzbVortex
|
||||||
|
|
||||||
if (version.Major < 2 || (version.Major == 2 && version.Minor < 3))
|
if (version.Major < 2 || (version.Major == 2 && version.Minor < 3))
|
||||||
{
|
{
|
||||||
return new ValidationFailure("Host", "NZBVortex needs to be updated");
|
return new ValidationFailure("Host",
|
||||||
|
_localizationService.GetLocalizedString("DownloadClientValidationErrorVersion",
|
||||||
|
new Dictionary<string, object>
|
||||||
|
{ { "clientName", Name }, { "requiredVersion", "2.3" }, { "reportedVersion", version } }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, "Unable to connect to NZBVortex");
|
_logger.Error(ex, "Unable to connect to NZBVortex");
|
||||||
return new ValidationFailure("Host", "Unable to connect to NZBVortex");
|
return new NzbDroneValidationFailure("Host", _localizationService.GetLocalizedString("DownloadClientValidationUnableToConnect", new Dictionary<string, object> { { "clientName", Name } }));
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -200,7 +205,7 @@ namespace NzbDrone.Core.Download.Clients.NzbVortex
|
||||||
}
|
}
|
||||||
catch (NzbVortexAuthenticationException)
|
catch (NzbVortexAuthenticationException)
|
||||||
{
|
{
|
||||||
return new ValidationFailure("ApiKey", "API Key Incorrect");
|
return new ValidationFailure("ApiKey", _localizationService.GetLocalizedString("DownloadClientValidationApiKeyIncorrect"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -214,9 +219,9 @@ namespace NzbDrone.Core.Download.Clients.NzbVortex
|
||||||
{
|
{
|
||||||
if (Settings.TvCategory.IsNotNullOrWhiteSpace())
|
if (Settings.TvCategory.IsNotNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure("TvCategory", "Group does not exist")
|
return new NzbDroneValidationFailure("TvCategory", _localizationService.GetLocalizedString("DownloadClientValidationGroupMissing"))
|
||||||
{
|
{
|
||||||
DetailedDescription = "The Group you entered doesn't exist in NzbVortex. Go to NzbVortex to create it."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientValidationGroupMissingDetail", new Dictionary<string, object> { { "clientName", Name } })
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -243,7 +248,7 @@ namespace NzbDrone.Core.Download.Clients.NzbVortex
|
||||||
|
|
||||||
if (filesResponse.Count > 1)
|
if (filesResponse.Count > 1)
|
||||||
{
|
{
|
||||||
var message = string.Format("Download contains multiple files and is not in a job folder: {0}", outputPath);
|
var message = _localizationService.GetLocalizedString("DownloadClientNzbVortexMultipleFilesMessage", new Dictionary<string, object> { { "outputPath", outputPath } });
|
||||||
|
|
||||||
queueItem.Status = DownloadItemStatus.Warning;
|
queueItem.Status = DownloadItemStatus.Warning;
|
||||||
queueItem.Message = message;
|
queueItem.Message = message;
|
||||||
|
|
|
@ -42,19 +42,21 @@ namespace NzbDrone.Core.Download.Clients.NzbVortex
|
||||||
[FieldDefinition(1, Label = "Port", Type = FieldType.Textbox)]
|
[FieldDefinition(1, Label = "Port", Type = FieldType.Textbox)]
|
||||||
public int Port { get; set; }
|
public int Port { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(2, Label = "Url Base", Type = FieldType.Textbox, Advanced = true, HelpText = "Adds a prefix to the NZBVortex url, e.g. http://[host]:[port]/[urlBase]/api")]
|
[FieldDefinition(2, Label = "UrlBase", Type = FieldType.Textbox, Advanced = true, HelpText = "DownloadClientSettingsUrlBaseHelpText")]
|
||||||
|
[FieldToken(TokenField.HelpText, "UrlBase", "clientName", "NZBVortex")]
|
||||||
|
[FieldToken(TokenField.HelpText, "UrlBase", "url", "http://[host]:[port]/[urlBase]/api")]
|
||||||
public string UrlBase { get; set; }
|
public string UrlBase { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(3, Label = "API Key", Type = FieldType.Textbox, Privacy = PrivacyLevel.ApiKey)]
|
[FieldDefinition(3, Label = "ApiKey", Type = FieldType.Textbox, Privacy = PrivacyLevel.ApiKey)]
|
||||||
public string ApiKey { get; set; }
|
public string ApiKey { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(4, Label = "Group", Type = FieldType.Textbox, HelpText = "Adding a category specific to Sonarr avoids conflicts with unrelated non-Sonarr downloads. Using a category is optional, but strongly recommended.")]
|
[FieldDefinition(4, Label = "Group", Type = FieldType.Textbox, HelpText = "DownloadClientSettingsCategoryHelpText")]
|
||||||
public string TvCategory { get; set; }
|
public string TvCategory { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(5, Label = "Recent Priority", Type = FieldType.Select, SelectOptions = typeof(NzbVortexPriority), HelpText = "Priority to use when grabbing episodes that aired within the last 14 days")]
|
[FieldDefinition(5, Label = "DownloadClientSettingsRecentPriority", Type = FieldType.Select, SelectOptions = typeof(NzbVortexPriority), HelpText = "DownloadClientSettingsRecentPriorityHelpText")]
|
||||||
public int RecentTvPriority { get; set; }
|
public int RecentTvPriority { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(6, Label = "Older Priority", Type = FieldType.Select, SelectOptions = typeof(NzbVortexPriority), HelpText = "Priority to use when grabbing episodes that aired over 14 days ago")]
|
[FieldDefinition(6, Label = "DownloadClientSettingsOlderPriority", Type = FieldType.Select, SelectOptions = typeof(NzbVortexPriority), HelpText = "DownloadClientSettingsOlderPriorityHelpText")]
|
||||||
public int OlderTvPriority { get; set; }
|
public int OlderTvPriority { get; set; }
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
|
|
|
@ -10,6 +10,7 @@ using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Exceptions;
|
using NzbDrone.Core.Exceptions;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
using NzbDrone.Core.Validation;
|
using NzbDrone.Core.Validation;
|
||||||
|
@ -28,8 +29,9 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
IValidateNzbs nzbValidationService,
|
IValidateNzbs nzbValidationService,
|
||||||
Logger logger)
|
Logger logger,
|
||||||
: base(httpClient, configService, diskProvider, remotePathMappingService, nzbValidationService, logger)
|
ILocalizationService localizationService)
|
||||||
|
: base(httpClient, configService, diskProvider, remotePathMappingService, nzbValidationService, logger, localizationService)
|
||||||
{
|
{
|
||||||
_proxy = proxy;
|
_proxy = proxy;
|
||||||
}
|
}
|
||||||
|
@ -124,7 +126,13 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||||
historyItem.TotalSize = MakeInt64(item.FileSizeHi, item.FileSizeLo);
|
historyItem.TotalSize = MakeInt64(item.FileSizeHi, item.FileSizeLo);
|
||||||
historyItem.OutputPath = _remotePathMappingService.RemapRemoteToLocal(Settings.Host, new OsPath(itemDir));
|
historyItem.OutputPath = _remotePathMappingService.RemapRemoteToLocal(Settings.Host, new OsPath(itemDir));
|
||||||
historyItem.Category = item.Category;
|
historyItem.Category = item.Category;
|
||||||
historyItem.Message = $"PAR Status: {item.ParStatus} - Unpack Status: {item.UnpackStatus} - Move Status: {item.MoveStatus} - Script Status: {item.ScriptStatus} - Delete Status: {item.DeleteStatus} - Mark Status: {item.MarkStatus}";
|
historyItem.Message = _localizationService.GetLocalizedString("NzbgetHistoryItemMessage",
|
||||||
|
new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "parStatus", item.ParStatus }, { "unpackStatus", item.UnpackStatus },
|
||||||
|
{ "moveStatus", item.MoveStatus }, { "scriptStaus", item.ScriptStatus },
|
||||||
|
{ "deleteStatus", item.DeleteStatus }, { "markStatus", item.MarkStatus }
|
||||||
|
});
|
||||||
historyItem.Status = DownloadItemStatus.Completed;
|
historyItem.Status = DownloadItemStatus.Completed;
|
||||||
historyItem.RemainingTime = TimeSpan.Zero;
|
historyItem.RemainingTime = TimeSpan.Zero;
|
||||||
historyItem.CanMoveFiles = true;
|
historyItem.CanMoveFiles = true;
|
||||||
|
@ -270,18 +278,23 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||||
|
|
||||||
if (Version.Parse(version) < Version.Parse("12.0"))
|
if (Version.Parse(version) < Version.Parse("12.0"))
|
||||||
{
|
{
|
||||||
return new ValidationFailure(string.Empty, "Nzbget version too low, need 12.0 or higher");
|
return new ValidationFailure(string.Empty,
|
||||||
|
_localizationService.GetLocalizedString("DownloadClientValidationErrorVersion",
|
||||||
|
new Dictionary<string, object>
|
||||||
|
{ { "clientName", Name }, { "requiredVersion", "12.0" }, { "reportedVersion", version } }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
if (ex.Message.ContainsIgnoreCase("Authentication failed"))
|
if (ex.Message.ContainsIgnoreCase("Authentication failed"))
|
||||||
{
|
{
|
||||||
return new ValidationFailure("Username", "Authentication failed");
|
return new ValidationFailure("Username", _localizationService.GetLocalizedString("DownloadClientValidationAuthenticationFailure"));
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Error(ex, "Unable to connect to NZBGet");
|
_logger.Error(ex, "Unable to connect to NZBGet");
|
||||||
return new ValidationFailure("Host", "Unable to connect to NZBGet");
|
return new ValidationFailure("Host",
|
||||||
|
_localizationService.GetLocalizedString("DownloadClientValidationUnableToConnect",
|
||||||
|
new Dictionary<string, object> { { "clientName", Name } }));
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -294,10 +307,10 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||||
|
|
||||||
if (!Settings.TvCategory.IsNullOrWhiteSpace() && !categories.Any(v => v.Name == Settings.TvCategory))
|
if (!Settings.TvCategory.IsNullOrWhiteSpace() && !categories.Any(v => v.Name == Settings.TvCategory))
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure("TvCategory", "Category does not exist")
|
return new NzbDroneValidationFailure("TvCategory", _localizationService.GetLocalizedString("DownloadClientValidationCategoryMissing"))
|
||||||
{
|
{
|
||||||
InfoLink = _proxy.GetBaseUrl(Settings),
|
InfoLink = _proxy.GetBaseUrl(Settings),
|
||||||
DetailedDescription = "The Category your entered doesn't exist in NzbGet. Go to NzbGet to create it."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientValidationCategoryMissingDetail", new Dictionary<string, object> { { "clientName", Name } })
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,18 +324,18 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||||
var keepHistory = config.GetValueOrDefault("KeepHistory", "7");
|
var keepHistory = config.GetValueOrDefault("KeepHistory", "7");
|
||||||
if (!int.TryParse(keepHistory, NumberStyles.None, CultureInfo.InvariantCulture, out var 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")
|
return new NzbDroneValidationFailure(string.Empty, _localizationService.GetLocalizedString("DownloadClientNzbgetValidationKeepHistoryZero"))
|
||||||
{
|
{
|
||||||
InfoLink = _proxy.GetBaseUrl(Settings),
|
InfoLink = _proxy.GetBaseUrl(Settings),
|
||||||
DetailedDescription = "NzbGet setting KeepHistory is set to 0. Which prevents Sonarr from seeing completed downloads."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientNzbgetValidationKeepHistoryZeroDetail")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else if (value > 25000)
|
else if (value > 25000)
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure(string.Empty, "NzbGet setting KeepHistory should be less than 25000")
|
return new NzbDroneValidationFailure(string.Empty, _localizationService.GetLocalizedString("DownloadClientNzbgetValidationKeepHistoryOverMax"))
|
||||||
{
|
{
|
||||||
InfoLink = _proxy.GetBaseUrl(Settings),
|
InfoLink = _proxy.GetBaseUrl(Settings),
|
||||||
DetailedDescription = "NzbGet setting KeepHistory is set too high."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientNzbgetValidationKeepHistoryOverMaxDetail")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,10 +40,13 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||||
[FieldDefinition(1, Label = "Port", Type = FieldType.Textbox)]
|
[FieldDefinition(1, Label = "Port", Type = FieldType.Textbox)]
|
||||||
public int Port { get; set; }
|
public int Port { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(2, Label = "Use SSL", Type = FieldType.Checkbox, HelpText = "Use secure connection when connecting to NZBGet")]
|
[FieldDefinition(2, Label = "UseSsl", Type = FieldType.Checkbox, HelpText = "DownloadClientSettingsUseSslHelpText")]
|
||||||
|
[FieldToken(TokenField.HelpText, "UseSsl", "clientName", "NZBGet")]
|
||||||
public bool UseSsl { get; set; }
|
public bool UseSsl { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(3, Label = "Url Base", Type = FieldType.Textbox, Advanced = true, HelpText = "Adds a prefix to the nzbget url, e.g. http://[host]:[port]/[urlBase]/jsonrpc")]
|
[FieldDefinition(3, Label = "UrlBase", Type = FieldType.Textbox, Advanced = true, HelpText = "DownloadClientSettingsUrlBaseHelpText")]
|
||||||
|
[FieldToken(TokenField.HelpText, "UrlBase", "clientName", "NZBGet")]
|
||||||
|
[FieldToken(TokenField.HelpText, "UrlBase", "url", "http://[host]:[port]/[urlBase]/jsonrpc")]
|
||||||
public string UrlBase { get; set; }
|
public string UrlBase { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(4, Label = "Username", Type = FieldType.Textbox, Privacy = PrivacyLevel.UserName)]
|
[FieldDefinition(4, Label = "Username", Type = FieldType.Textbox, Privacy = PrivacyLevel.UserName)]
|
||||||
|
@ -52,16 +55,16 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||||
[FieldDefinition(5, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password)]
|
[FieldDefinition(5, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password)]
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(6, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Sonarr avoids conflicts with unrelated non-Sonarr downloads. Using a category is optional, but strongly recommended.")]
|
[FieldDefinition(6, Label = "Category", Type = FieldType.Textbox, HelpText = "DownloadClientSettingsCategoryHelpText")]
|
||||||
public string TvCategory { get; set; }
|
public string TvCategory { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(7, Label = "Recent Priority", Type = FieldType.Select, SelectOptions = typeof(NzbgetPriority), HelpText = "Priority to use when grabbing episodes that aired within the last 14 days")]
|
[FieldDefinition(7, Label = "DownloadClientSettingsRecentPriority", Type = FieldType.Select, SelectOptions = typeof(NzbgetPriority), HelpText = "DownloadClientSettingsRecentPriorityHelpText")]
|
||||||
public int RecentTvPriority { get; set; }
|
public int RecentTvPriority { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(8, Label = "Older Priority", Type = FieldType.Select, SelectOptions = typeof(NzbgetPriority), HelpText = "Priority to use when grabbing episodes that aired over 14 days ago")]
|
[FieldDefinition(8, Label = "DownloadClientSettingsOlderPriority", Type = FieldType.Select, SelectOptions = typeof(NzbgetPriority), HelpText = "DownloadClientSettingsOlderPriorityHelpText")]
|
||||||
public int OlderTvPriority { get; set; }
|
public int OlderTvPriority { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(9, Label = "Add Paused", Type = FieldType.Checkbox, HelpText = "This option requires at least NzbGet version 16.0")]
|
[FieldDefinition(9, Label = "DownloadClientSettingsAddPaused", Type = FieldType.Checkbox, HelpText = "DownloadClientNzbgetSettingsAddPausedHelpText")]
|
||||||
public bool AddPaused { get; set; }
|
public bool AddPaused { get; set; }
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
|
|
|
@ -9,6 +9,7 @@ using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Organizer;
|
using NzbDrone.Core.Organizer;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
@ -23,8 +24,9 @@ namespace NzbDrone.Core.Download.Clients.Pneumatic
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
Logger logger)
|
Logger logger,
|
||||||
: base(configService, diskProvider, remotePathMappingService, logger)
|
ILocalizationService localizationService)
|
||||||
|
: base(configService, diskProvider, remotePathMappingService, logger, localizationService)
|
||||||
{
|
{
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,10 @@ namespace NzbDrone.Core.Download.Clients.Pneumatic
|
||||||
{
|
{
|
||||||
private static readonly PneumaticSettingsValidator Validator = new PneumaticSettingsValidator();
|
private static readonly PneumaticSettingsValidator Validator = new PneumaticSettingsValidator();
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "Nzb Folder", Type = FieldType.Path, HelpText = "This folder will need to be reachable from XBMC")]
|
[FieldDefinition(0, Label = "DownloadClientPneumaticSettingsNzbFolder", Type = FieldType.Path, HelpText = "DownloadClientPneumaticSettingsNzbFolderHelpText")]
|
||||||
public string NzbFolder { get; set; }
|
public string NzbFolder { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(1, Label = "Strm Folder", Type = FieldType.Path, HelpText = ".strm files in this folder will be import by drone")]
|
[FieldDefinition(1, Label = "DownloadClientPneumaticSettingsStrmFolder", Type = FieldType.Path, HelpText = "DownloadClientPneumaticSettingsStrmFolderHelpText")]
|
||||||
public string StrmFolder { get; set; }
|
public string StrmFolder { get; set; }
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
|
|
|
@ -9,6 +9,7 @@ using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
@ -34,8 +35,9 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
ICacheManager cacheManager,
|
ICacheManager cacheManager,
|
||||||
Logger logger)
|
Logger logger,
|
||||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger)
|
ILocalizationService localizationService)
|
||||||
|
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger, localizationService)
|
||||||
{
|
{
|
||||||
_proxySelector = proxySelector;
|
_proxySelector = proxySelector;
|
||||||
|
|
||||||
|
@ -241,7 +243,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||||
{
|
{
|
||||||
case "error": // some error occurred, applies to paused torrents, warning so failed download handling isn't triggered
|
case "error": // some error occurred, applies to paused torrents, warning so failed download handling isn't triggered
|
||||||
item.Status = DownloadItemStatus.Warning;
|
item.Status = DownloadItemStatus.Warning;
|
||||||
item.Message = "qBittorrent is reporting an error";
|
item.Message = _localizationService.GetLocalizedString("DownloadClientQbittorrentTorrentStateError");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "pausedDL": // torrent is paused and has NOT finished downloading
|
case "pausedDL": // torrent is paused and has NOT finished downloading
|
||||||
|
@ -266,24 +268,24 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||||
|
|
||||||
case "stalledDL": // torrent is being downloaded, but no connection were made
|
case "stalledDL": // torrent is being downloaded, but no connection were made
|
||||||
item.Status = DownloadItemStatus.Warning;
|
item.Status = DownloadItemStatus.Warning;
|
||||||
item.Message = "The download is stalled with no connections";
|
item.Message = _localizationService.GetLocalizedString("DownloadClientQbittorrentTorrentStateStalled");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "missingFiles": // torrent is missing files
|
case "missingFiles": // torrent is missing files
|
||||||
item.Status = DownloadItemStatus.Warning;
|
item.Status = DownloadItemStatus.Warning;
|
||||||
item.Message = "The download is missing files";
|
item.Message = _localizationService.GetLocalizedString("DownloadClientQbittorrentTorrentStateMissingFiles");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "metaDL": // torrent magnet is being downloaded
|
case "metaDL": // torrent magnet is being downloaded
|
||||||
if (config.DhtEnabled)
|
if (config.DhtEnabled)
|
||||||
{
|
{
|
||||||
item.Status = DownloadItemStatus.Queued;
|
item.Status = DownloadItemStatus.Queued;
|
||||||
item.Message = "qBittorrent is downloading metadata";
|
item.Message = _localizationService.GetLocalizedString("DownloadClientQbittorrentTorrentStateMetadata");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
item.Status = DownloadItemStatus.Warning;
|
item.Status = DownloadItemStatus.Warning;
|
||||||
item.Message = "qBittorrent cannot resolve magnet link with DHT disabled";
|
item.Message = _localizationService.GetLocalizedString("DownloadClientQbittorrentTorrentStateDhtDisabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -296,8 +298,8 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: // new status in API? default to downloading
|
default: // new status in API? default to downloading
|
||||||
item.Message = "Unknown download state: " + torrent.State;
|
item.Message = _localizationService.GetLocalizedString("DownloadClientQbittorrentTorrentStateUnknown", new Dictionary<string, object> { { "state", torrent.State } });
|
||||||
_logger.Info(item.Message);
|
_logger.Info($"Unknown download state: {torrent.State}");
|
||||||
item.Status = DownloadItemStatus.Downloading;
|
item.Status = DownloadItemStatus.Downloading;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -311,7 +313,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
item.Status = DownloadItemStatus.Warning;
|
item.Status = DownloadItemStatus.Warning;
|
||||||
item.Message = "Unable to Import. Path matches client base download directory, it's possible 'Keep top-level folder' is disabled for this torrent or 'Torrent Content Layout' is NOT set to 'Original' or 'Create Subfolder'?";
|
item.Message = _localizationService.GetLocalizedString("DownloadClientQbittorrentTorrentStatePathError");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,29 +417,30 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||||
if (version < Version.Parse("1.5"))
|
if (version < Version.Parse("1.5"))
|
||||||
{
|
{
|
||||||
// API version 5 introduced the "save_path" property in /query/torrents
|
// API version 5 introduced the "save_path" property in /query/torrents
|
||||||
return new NzbDroneValidationFailure("Host", "Unsupported client version")
|
return new NzbDroneValidationFailure("Host", _localizationService.GetLocalizedString("DownloadClientValidationErrorVersion",
|
||||||
{
|
new Dictionary<string, object>
|
||||||
DetailedDescription = "Please upgrade to qBittorrent version 3.2.4 or higher."
|
{
|
||||||
};
|
{ "clientName", Name }, { "requiredVersion", "3.2.4" }, { "reportedVersion", version }
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
else if (version < Version.Parse("1.6"))
|
else if (version < Version.Parse("1.6"))
|
||||||
{
|
{
|
||||||
// API version 6 introduced support for labels
|
// API version 6 introduced support for labels
|
||||||
if (Settings.TvCategory.IsNotNullOrWhiteSpace())
|
if (Settings.TvCategory.IsNotNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure("Category", "Category is not supported")
|
return new NzbDroneValidationFailure("Category", _localizationService.GetLocalizedString("DownloadClientQbittorrentValidationCategoryUnsupported"))
|
||||||
{
|
{
|
||||||
DetailedDescription = "Labels are not supported until qBittorrent version 3.3.0. Please upgrade or try again with an empty Category."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientQbittorrentValidationCategoryUnsupportedDetail")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Settings.TvCategory.IsNullOrWhiteSpace())
|
else if (Settings.TvCategory.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
// warn if labels are supported, but category is not provided
|
// warn if labels are supported, but category is not provided
|
||||||
return new NzbDroneValidationFailure("TvCategory", "Category is recommended")
|
return new NzbDroneValidationFailure("TvCategory", _localizationService.GetLocalizedString("DownloadClientQbittorrentValidationCategoryRecommended"))
|
||||||
{
|
{
|
||||||
IsWarning = true,
|
IsWarning = true,
|
||||||
DetailedDescription = "Sonarr will not attempt to import completed downloads without a category."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientQbittorrentValidationCategoryRecommendedDetail")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,18 +448,18 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||||
var config = Proxy.GetConfig(Settings);
|
var config = Proxy.GetConfig(Settings);
|
||||||
if ((config.MaxRatioEnabled || config.MaxSeedingTimeEnabled) && (config.MaxRatioAction == QBittorrentMaxRatioAction.Remove || config.MaxRatioAction == QBittorrentMaxRatioAction.DeleteFiles))
|
if ((config.MaxRatioEnabled || config.MaxSeedingTimeEnabled) && (config.MaxRatioAction == QBittorrentMaxRatioAction.Remove || config.MaxRatioAction == QBittorrentMaxRatioAction.DeleteFiles))
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure(string.Empty, "qBittorrent is configured to remove torrents when they reach their Share Ratio Limit")
|
return new NzbDroneValidationFailure(string.Empty, _localizationService.GetLocalizedString("DownloadClientQbittorrentValidationRemovesAtRatioLimit"))
|
||||||
{
|
{
|
||||||
DetailedDescription = "Sonarr will be unable to perform Completed Download Handling as configured. You can fix this in qBittorrent ('Tools -> Options...' in the menu) by changing 'Options -> BitTorrent -> Share Ratio Limiting' from 'Remove them' to 'Pause them'."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientQbittorrentValidationRemovesAtRatioLimitDetail")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (DownloadClientAuthenticationException ex)
|
catch (DownloadClientAuthenticationException ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, ex.Message);
|
_logger.Error(ex, ex.Message);
|
||||||
return new NzbDroneValidationFailure("Username", "Authentication failure")
|
return new NzbDroneValidationFailure("Username", _localizationService.GetLocalizedString("DownloadClientValidationAuthenticationFailure"))
|
||||||
{
|
{
|
||||||
DetailedDescription = "Please verify your username and password."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientValidationAuthenticationFailureDetail", new Dictionary<string, object> { { "clientName", Name } })
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
catch (WebException ex)
|
catch (WebException ex)
|
||||||
|
@ -464,19 +467,19 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||||
_logger.Error(ex, "Unable to connect to qBittorrent");
|
_logger.Error(ex, "Unable to connect to qBittorrent");
|
||||||
if (ex.Status == WebExceptionStatus.ConnectFailure)
|
if (ex.Status == WebExceptionStatus.ConnectFailure)
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure("Host", "Unable to connect")
|
return new NzbDroneValidationFailure("Host", _localizationService.GetLocalizedString("DownloadClientValidationUnableToConnect", new Dictionary<string, object> { { "clientName", Name } }))
|
||||||
{
|
{
|
||||||
DetailedDescription = "Please verify the hostname and port."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientValidationUnableToConnectDetail")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return new NzbDroneValidationFailure(string.Empty, "Unknown exception: " + ex.Message);
|
return new NzbDroneValidationFailure(string.Empty, _localizationService.GetLocalizedString("DownloadClientValidationUnknownException", new Dictionary<string, object> { { "exception", ex.Message } }));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, "Unable to test qBittorrent");
|
_logger.Error(ex, "Unable to test qBittorrent");
|
||||||
|
|
||||||
return new NzbDroneValidationFailure("Host", "Unable to connect to qBittorrent")
|
return new NzbDroneValidationFailure("Host", _localizationService.GetLocalizedString("DownloadClientValidationUnableToConnect", new Dictionary<string, object> { { "clientName", Name } }))
|
||||||
{
|
{
|
||||||
DetailedDescription = ex.Message
|
DetailedDescription = ex.Message
|
||||||
};
|
};
|
||||||
|
@ -508,9 +511,9 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||||
|
|
||||||
if (!labels.ContainsKey(Settings.TvCategory))
|
if (!labels.ContainsKey(Settings.TvCategory))
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure("TvCategory", "Configuration of label failed")
|
return new NzbDroneValidationFailure("TvCategory", _localizationService.GetLocalizedString("DownloadClientQbittorrentValidationCategoryAddFailure"))
|
||||||
{
|
{
|
||||||
DetailedDescription = "Sonarr was unable to add the label to qBittorrent."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientQbittorrentValidationCategoryAddFailureDetail")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -522,9 +525,9 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||||
|
|
||||||
if (!labels.ContainsKey(Settings.TvImportedCategory))
|
if (!labels.ContainsKey(Settings.TvImportedCategory))
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure("TvImportedCategory", "Configuration of label failed")
|
return new NzbDroneValidationFailure("TvImportedCategory", _localizationService.GetLocalizedString("DownloadClientQbittorrentValidationCategoryAddFailure"))
|
||||||
{
|
{
|
||||||
DetailedDescription = "Sonarr was unable to add the label to qBittorrent."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientQbittorrentValidationCategoryAddFailureDetail")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -550,18 +553,24 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||||
{
|
{
|
||||||
if (!recentPriorityDefault)
|
if (!recentPriorityDefault)
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure(nameof(Settings.RecentTvPriority), "Queueing not enabled") { DetailedDescription = "Torrent Queueing is not enabled in your qBittorrent settings. Enable it in qBittorrent or select 'Last' as priority." };
|
return new NzbDroneValidationFailure(nameof(Settings.RecentTvPriority), _localizationService.GetLocalizedString("DownloadClientQbittorrentValidationQueueingNotEnabled"))
|
||||||
|
{
|
||||||
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientQbittorrentValidationQueueingNotEnabledDetail")
|
||||||
|
};
|
||||||
}
|
}
|
||||||
else if (!olderPriorityDefault)
|
else if (!olderPriorityDefault)
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure(nameof(Settings.OlderTvPriority), "Queueing not enabled") { DetailedDescription = "Torrent Queueing is not enabled in your qBittorrent settings. Enable it in qBittorrent or select 'Last' as priority." };
|
return new NzbDroneValidationFailure(nameof(Settings.OlderTvPriority), _localizationService.GetLocalizedString("DownloadClientQbittorrentValidationQueueingNotEnabled"))
|
||||||
|
{
|
||||||
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientQbittorrentValidationQueueingNotEnabledDetail")
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, "Failed to test qBittorrent");
|
_logger.Error(ex, "Failed to test qBittorrent");
|
||||||
return new NzbDroneValidationFailure(string.Empty, "Unknown exception: " + ex.Message);
|
return new NzbDroneValidationFailure(string.Empty, _localizationService.GetLocalizedString("DownloadClientValidationUnknownException", new Dictionary<string, object> { { "exception", ex.Message } }));
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -576,7 +585,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, "Failed to get torrents");
|
_logger.Error(ex, "Failed to get torrents");
|
||||||
return new NzbDroneValidationFailure(string.Empty, "Failed to get the list of torrents: " + ex.Message);
|
return new NzbDroneValidationFailure(string.Empty, _localizationService.GetLocalizedString("DownloadClientValidationTestTorrents", new Dictionary<string, object> { { "exceptionMessage", ex.Message } }));
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -36,10 +36,12 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||||
[FieldDefinition(1, Label = "Port", Type = FieldType.Textbox)]
|
[FieldDefinition(1, Label = "Port", Type = FieldType.Textbox)]
|
||||||
public int Port { get; set; }
|
public int Port { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(2, Label = "Use SSL", Type = FieldType.Checkbox, HelpText = "Use a secure connection. See Options -> Web UI -> 'Use HTTPS instead of HTTP' in qBittorrent.")]
|
[FieldDefinition(2, Label = "UseSsl", Type = FieldType.Checkbox, HelpText = "DownloadClientQbittorrentSettingsUseSslHelpText")]
|
||||||
public bool UseSsl { get; set; }
|
public bool UseSsl { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(3, Label = "Url Base", Type = FieldType.Textbox, Advanced = true, HelpText = "Adds a prefix to the qBittorrent url, e.g. http://[host]:[port]/[urlBase]/api")]
|
[FieldDefinition(3, Label = "UrlBase", Type = FieldType.Textbox, Advanced = true, HelpText = "DownloadClientSettingsUrlBaseHelpText")]
|
||||||
|
[FieldToken(TokenField.HelpText, "UrlBase", "clientName", "qBittorrent")]
|
||||||
|
[FieldToken(TokenField.HelpText, "UrlBase", "url", "http://[host]:[port]/[urlBase]/api")]
|
||||||
public string UrlBase { get; set; }
|
public string UrlBase { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(4, Label = "Username", Type = FieldType.Textbox, Privacy = PrivacyLevel.UserName)]
|
[FieldDefinition(4, Label = "Username", Type = FieldType.Textbox, Privacy = PrivacyLevel.UserName)]
|
||||||
|
@ -48,25 +50,25 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||||
[FieldDefinition(5, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password)]
|
[FieldDefinition(5, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password)]
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(6, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Sonarr avoids conflicts with unrelated non-Sonarr downloads. Using a category is optional, but strongly recommended.")]
|
[FieldDefinition(6, Label = "Category", Type = FieldType.Textbox, HelpText = "DownloadClientSettingsCategoryHelpText")]
|
||||||
public string TvCategory { get; set; }
|
public string TvCategory { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(7, Label = "Post-Import Category", Type = FieldType.Textbox, Advanced = true, HelpText = "Category for Sonarr to set after it has imported the download. Sonarr will not remove the torrent if seeding has finished. Leave blank to keep same category.")]
|
[FieldDefinition(7, Label = "PostImportCategory", Type = FieldType.Textbox, Advanced = true, HelpText = "DownloadClientSettingsPostImportCategoryHelpText")]
|
||||||
public string TvImportedCategory { get; set; }
|
public string TvImportedCategory { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(8, Label = "Recent Priority", Type = FieldType.Select, SelectOptions = typeof(QBittorrentPriority), HelpText = "Priority to use when grabbing episodes that aired within the last 14 days")]
|
[FieldDefinition(8, Label = "DownloadClientSettingsRecentPriority", Type = FieldType.Select, SelectOptions = typeof(QBittorrentPriority), HelpText = "DownloadClientSettingsRecentPriorityHelpText")]
|
||||||
public int RecentTvPriority { get; set; }
|
public int RecentTvPriority { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(9, Label = "Older Priority", Type = FieldType.Select, SelectOptions = typeof(QBittorrentPriority), HelpText = "Priority to use when grabbing episodes that aired over 14 days ago")]
|
[FieldDefinition(9, Label = "DownloadClientSettingsOlderPriority", Type = FieldType.Select, SelectOptions = typeof(QBittorrentPriority), HelpText = "DownloadClientSettingsOlderPriorityHelpText")]
|
||||||
public int OlderTvPriority { get; set; }
|
public int OlderTvPriority { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(10, Label = "Initial State", Type = FieldType.Select, SelectOptions = typeof(QBittorrentState), HelpText = "Initial state for torrents added to qBittorrent. Note that Forced Torrents do not abide by seed restrictions")]
|
[FieldDefinition(10, Label = "DownloadClientSettingsInitialState", Type = FieldType.Select, SelectOptions = typeof(QBittorrentState), HelpText = "DownloadClientQbittorrentSettingsInitialStateHelpText")]
|
||||||
public int InitialState { get; set; }
|
public int InitialState { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(11, Label = "Sequential Order", Type = FieldType.Checkbox, HelpText = "Download in sequential order (qBittorrent 4.1.0+)")]
|
[FieldDefinition(11, Label = "DownloadClientQbittorrentSettingsSequentialOrder", Type = FieldType.Checkbox, HelpText = "DownloadClientQbittorrentSettingsSequentialOrderHelpText")]
|
||||||
public bool SequentialOrder { get; set; }
|
public bool SequentialOrder { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(12, Label = "First and Last First", Type = FieldType.Checkbox, HelpText = "Download first and last pieces first (qBittorrent 4.1.0+)")]
|
[FieldDefinition(12, Label = "DownloadClientQbittorrentSettingsFirstAndLastFirst", Type = FieldType.Checkbox, HelpText = "DownloadClientQbittorrentSettingsFirstAndLastFirstHelpText")]
|
||||||
public bool FirstAndLast { get; set; }
|
public bool FirstAndLast { get; set; }
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
|
|
|
@ -10,6 +10,7 @@ using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Exceptions;
|
using NzbDrone.Core.Exceptions;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
using NzbDrone.Core.Validation;
|
using NzbDrone.Core.Validation;
|
||||||
|
@ -26,8 +27,9 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
IValidateNzbs nzbValidationService,
|
IValidateNzbs nzbValidationService,
|
||||||
Logger logger)
|
Logger logger,
|
||||||
: base(httpClient, configService, diskProvider, remotePathMappingService, nzbValidationService, logger)
|
ILocalizationService localizationService)
|
||||||
|
: base(httpClient, configService, diskProvider, remotePathMappingService, nzbValidationService, logger, localizationService)
|
||||||
{
|
{
|
||||||
_proxy = proxy;
|
_proxy = proxy;
|
||||||
}
|
}
|
||||||
|
@ -381,15 +383,15 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||||
|
|
||||||
if (version == null)
|
if (version == null)
|
||||||
{
|
{
|
||||||
return new ValidationFailure("Version", "Unknown Version: " + rawVersion);
|
return new ValidationFailure("Version", _localizationService.GetLocalizedString("DownloadClientSabnzbdValidationUnknownVersion", new Dictionary<string, object> { { "rawVersion", rawVersion ?? "" } }));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rawVersion.Equals("develop", StringComparison.InvariantCultureIgnoreCase))
|
if (rawVersion.Equals("develop", StringComparison.InvariantCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure("Version", "Sabnzbd develop version, assuming version 3.0.0 or higher.")
|
return new NzbDroneValidationFailure("Version", _localizationService.GetLocalizedString("DownloadClientSabnzbdValidationDevelopVersion"))
|
||||||
{
|
{
|
||||||
IsWarning = true,
|
IsWarning = true,
|
||||||
DetailedDescription = "Sonarr may not be able to support new features added to SABnzbd when running develop versions."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientSabnzbdValidationDevelopVersionDetail")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,12 +405,17 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ValidationFailure("Version", "Version 0.7.0+ is required, but found: " + version);
|
return new ValidationFailure("Version",
|
||||||
|
_localizationService.GetLocalizedString("DownloadClientValidationErrorVersion",
|
||||||
|
new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "clientName", Name }, { "requiredVersion", "0.7.0" }, { "reportedVersion", version }
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, ex.Message);
|
_logger.Error(ex, ex.Message);
|
||||||
return new NzbDroneValidationFailure("Host", "Unable to connect to SABnzbd")
|
return new NzbDroneValidationFailure("Host", _localizationService.GetLocalizedString("DownloadClientValidationUnableToConnect", new Dictionary<string, object> { { "clientName", Name } }))
|
||||||
{
|
{
|
||||||
DetailedDescription = ex.Message
|
DetailedDescription = ex.Message
|
||||||
};
|
};
|
||||||
|
@ -425,12 +432,12 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||||
{
|
{
|
||||||
if (ex.Message.ContainsIgnoreCase("API Key Incorrect"))
|
if (ex.Message.ContainsIgnoreCase("API Key Incorrect"))
|
||||||
{
|
{
|
||||||
return new ValidationFailure("APIKey", "API Key Incorrect");
|
return new ValidationFailure("APIKey", _localizationService.GetLocalizedString("DownloadClientValidationApiKeyIncorrect"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ex.Message.ContainsIgnoreCase("API Key Required"))
|
if (ex.Message.ContainsIgnoreCase("API Key Required"))
|
||||||
{
|
{
|
||||||
return new ValidationFailure("APIKey", "API Key Required");
|
return new ValidationFailure("APIKey", _localizationService.GetLocalizedString("DownloadClientValidationApiKeyRequired"));
|
||||||
}
|
}
|
||||||
|
|
||||||
throw;
|
throw;
|
||||||
|
@ -444,10 +451,10 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||||
var config = _proxy.GetConfig(Settings);
|
var config = _proxy.GetConfig(Settings);
|
||||||
if (config.Misc.pre_check && !HasVersion(1, 1))
|
if (config.Misc.pre_check && !HasVersion(1, 1))
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure("", "Disable 'Check before download' option in Sabnbzd")
|
return new NzbDroneValidationFailure("", _localizationService.GetLocalizedString("DownloadClientSabnzbdValidationCheckBeforeDownload"))
|
||||||
{
|
{
|
||||||
InfoLink = _proxy.GetBaseUrl(Settings, "config/switches/"),
|
InfoLink = _proxy.GetBaseUrl(Settings, "config/switches/"),
|
||||||
DetailedDescription = "Using Check before download affects Sonarr ability to track new downloads. Also Sabnzbd recommends 'Abort jobs that cannot be completed' instead since it's more effective."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientSabnzbdValidationCheckBeforeDownloadDetail")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -463,10 +470,10 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||||
{
|
{
|
||||||
if (category.Dir.EndsWith("*"))
|
if (category.Dir.EndsWith("*"))
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure("TvCategory", "Enable Job folders")
|
return new NzbDroneValidationFailure("TvCategory", _localizationService.GetLocalizedString("DownloadClientSabnzbdValidationEnableJobFolders"))
|
||||||
{
|
{
|
||||||
InfoLink = _proxy.GetBaseUrl(Settings, "config/categories/"),
|
InfoLink = _proxy.GetBaseUrl(Settings, "config/categories/"),
|
||||||
DetailedDescription = "Sonarr prefers each download to have a separate folder. With * appended to the Folder/Path Sabnzbd will not create these job folders. Go to Sabnzbd to fix it."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientSabnzbdValidationEnableJobFoldersDetail")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -474,10 +481,10 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||||
{
|
{
|
||||||
if (!Settings.TvCategory.IsNullOrWhiteSpace())
|
if (!Settings.TvCategory.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure("TvCategory", "Category does not exist")
|
return new NzbDroneValidationFailure("TvCategory", _localizationService.GetLocalizedString("DownloadClientValidationCategoryMissing"))
|
||||||
{
|
{
|
||||||
InfoLink = _proxy.GetBaseUrl(Settings, "config/categories/"),
|
InfoLink = _proxy.GetBaseUrl(Settings, "config/categories/"),
|
||||||
DetailedDescription = "The Category your entered doesn't exist in Sabnzbd. Go to Sabnzbd to create it."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientValidationCategoryMissingDetail", new Dictionary<string, object> { { "clientName", Name } })
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -485,37 +492,37 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||||
// New in SABnzbd 4.1, but on older versions this will be empty and not apply
|
// New in SABnzbd 4.1, but on older versions this will be empty and not apply
|
||||||
if (config.Sorters.Any(s => s.is_active && ContainsCategory(s.sort_cats, Settings.TvCategory)))
|
if (config.Sorters.Any(s => s.is_active && ContainsCategory(s.sort_cats, Settings.TvCategory)))
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure("TvCategory", "Disable TV Sorting")
|
return new NzbDroneValidationFailure("TvCategory", _localizationService.GetLocalizedString("DownloadClientSabnzbdValidationEnableDisableTvSorting"))
|
||||||
{
|
{
|
||||||
InfoLink = _proxy.GetBaseUrl(Settings, "config/sorting/"),
|
InfoLink = _proxy.GetBaseUrl(Settings, "config/sorting/"),
|
||||||
DetailedDescription = "You must disable sorting for the category Sonarr uses to prevent import issues. Go to Sabnzbd to fix it."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientSabnzbdValidationEnableDisableTvSortingDetail")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.Misc.enable_tv_sorting && ContainsCategory(config.Misc.tv_categories, Settings.TvCategory))
|
if (config.Misc.enable_tv_sorting && ContainsCategory(config.Misc.tv_categories, Settings.TvCategory))
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure("TvCategory", "Disable TV Sorting")
|
return new NzbDroneValidationFailure("TvCategory", _localizationService.GetLocalizedString("DownloadClientSabnzbdValidationEnableDisableTvSorting"))
|
||||||
{
|
{
|
||||||
InfoLink = _proxy.GetBaseUrl(Settings, "config/sorting/"),
|
InfoLink = _proxy.GetBaseUrl(Settings, "config/sorting/"),
|
||||||
DetailedDescription = "You must disable Sabnzbd TV Sorting for the category Sonarr uses to prevent import issues. Go to Sabnzbd to fix it."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientSabnzbdValidationEnableDisableTvSortingDetail")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.Misc.enable_movie_sorting && ContainsCategory(config.Misc.movie_categories, Settings.TvCategory))
|
if (config.Misc.enable_movie_sorting && ContainsCategory(config.Misc.movie_categories, Settings.TvCategory))
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure("TvCategory", "Disable Movie Sorting")
|
return new NzbDroneValidationFailure("TvCategory", _localizationService.GetLocalizedString("DownloadClientSabnzbdValidationEnableDisableMovieSorting"))
|
||||||
{
|
{
|
||||||
InfoLink = _proxy.GetBaseUrl(Settings, "config/sorting/"),
|
InfoLink = _proxy.GetBaseUrl(Settings, "config/sorting/"),
|
||||||
DetailedDescription = "You must disable Sabnzbd Movie Sorting for the category Sonarr uses to prevent import issues. Go to Sabnzbd to fix it."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientSabnzbdValidationEnableDisableMovieSortingDetail")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.Misc.enable_date_sorting && ContainsCategory(config.Misc.date_categories, Settings.TvCategory))
|
if (config.Misc.enable_date_sorting && ContainsCategory(config.Misc.date_categories, Settings.TvCategory))
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure("TvCategory", "Disable Date Sorting")
|
return new NzbDroneValidationFailure("TvCategory", _localizationService.GetLocalizedString("DownloadClientSabnzbdValidationEnableDisableDateSorting"))
|
||||||
{
|
{
|
||||||
InfoLink = _proxy.GetBaseUrl(Settings, "config/sorting/"),
|
InfoLink = _proxy.GetBaseUrl(Settings, "config/sorting/"),
|
||||||
DetailedDescription = "You must disable Sabnzbd Date Sorting for the category Sonarr uses to prevent import issues. Go to Sabnzbd to fix it."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientSabnzbdValidationEnableDisableDateSortingDetail")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,13 +51,16 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||||
[FieldDefinition(1, Label = "Port", Type = FieldType.Textbox)]
|
[FieldDefinition(1, Label = "Port", Type = FieldType.Textbox)]
|
||||||
public int Port { get; set; }
|
public int Port { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(2, Label = "Use SSL", Type = FieldType.Checkbox, HelpText = "Use secure connection when connecting to Sabnzbd")]
|
[FieldDefinition(2, Label = "UseSsl", Type = FieldType.Checkbox, HelpText = "DownloadClientSettingsUseSslHelpText")]
|
||||||
|
[FieldToken(TokenField.HelpText, "UseSsl", "clientName", "Sabnzbd")]
|
||||||
public bool UseSsl { get; set; }
|
public bool UseSsl { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(3, Label = "Url Base", Type = FieldType.Textbox, Advanced = true, HelpText = "Adds a prefix to the Sabnzbd url, e.g. http://[host]:[port]/[urlBase]/api")]
|
[FieldDefinition(3, Label = "UrlBase", Type = FieldType.Textbox, Advanced = true, HelpText = "DownloadClientSettingsUrlBaseHelpText")]
|
||||||
|
[FieldToken(TokenField.HelpText, "UrlBase", "clientName", "Sabnzbd")]
|
||||||
|
[FieldToken(TokenField.HelpText, "UrlBase", "url", "http://[host]:[port]/[urlBase]/api")]
|
||||||
public string UrlBase { get; set; }
|
public string UrlBase { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(4, Label = "API Key", Type = FieldType.Textbox, Privacy = PrivacyLevel.ApiKey)]
|
[FieldDefinition(4, Label = "ApiKey", Type = FieldType.Textbox, Privacy = PrivacyLevel.ApiKey)]
|
||||||
public string ApiKey { get; set; }
|
public string ApiKey { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(5, Label = "Username", Type = FieldType.Textbox, Privacy = PrivacyLevel.UserName)]
|
[FieldDefinition(5, Label = "Username", Type = FieldType.Textbox, Privacy = PrivacyLevel.UserName)]
|
||||||
|
@ -66,13 +69,13 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||||
[FieldDefinition(6, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password)]
|
[FieldDefinition(6, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password)]
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(7, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Sonarr avoids conflicts with unrelated non-Sonarr downloads. Using a category is optional, but strongly recommended.")]
|
[FieldDefinition(7, Label = "Category", Type = FieldType.Textbox, HelpText = "DownloadClientSettingsCategoryHelpText")]
|
||||||
public string TvCategory { get; set; }
|
public string TvCategory { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(8, Label = "Recent Priority", Type = FieldType.Select, SelectOptions = typeof(SabnzbdPriority), HelpText = "Priority to use when grabbing episodes that aired within the last 14 days")]
|
[FieldDefinition(8, Label = "DownloadClientSettingsRecentPriority", Type = FieldType.Select, SelectOptions = typeof(SabnzbdPriority), HelpText = "DownloadClientSettingsRecentPriorityHelpText")]
|
||||||
public int RecentTvPriority { get; set; }
|
public int RecentTvPriority { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(9, Label = "Older Priority", Type = FieldType.Select, SelectOptions = typeof(SabnzbdPriority), HelpText = "Priority to use when grabbing episodes that aired over 14 days ago")]
|
[FieldDefinition(9, Label = "DownloadClientSettingsOlderPriority", Type = FieldType.Select, SelectOptions = typeof(SabnzbdPriority), HelpText = "DownloadClientSettingsOlderPriorityHelpText")]
|
||||||
public int OlderTvPriority { get; set; }
|
public int OlderTvPriority { get; set; }
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
|
||||||
|
@ -18,8 +20,9 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
Logger logger)
|
Logger logger,
|
||||||
: base(proxy, torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger)
|
ILocalizationService localizationService)
|
||||||
|
: base(proxy, torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger, localizationService)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +37,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
|
|
||||||
if (version < new Version(2, 40))
|
if (version < new Version(2, 40))
|
||||||
{
|
{
|
||||||
return new ValidationFailure(string.Empty, "Transmission version not supported, should be 2.40 or higher.");
|
return new ValidationFailure(string.Empty, _localizationService.GetLocalizedString("DownloadClientValidationErrorVersion", new Dictionary<string, object> { { "clientName", Name }, { "requiredVersion", "2.40" }, { "reportedVersion", version } }));
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -7,6 +7,7 @@ using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
@ -24,8 +25,9 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
Logger logger)
|
Logger logger,
|
||||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger)
|
ILocalizationService localizationService)
|
||||||
|
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger, localizationService)
|
||||||
{
|
{
|
||||||
_proxy = proxy;
|
_proxy = proxy;
|
||||||
}
|
}
|
||||||
|
@ -270,16 +272,16 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
catch (DownloadClientAuthenticationException ex)
|
catch (DownloadClientAuthenticationException ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, ex.Message);
|
_logger.Error(ex, ex.Message);
|
||||||
return new NzbDroneValidationFailure("Username", "Authentication failure")
|
return new NzbDroneValidationFailure("Username", _localizationService.GetLocalizedString("DownloadClientValidationAuthenticationFailure"))
|
||||||
{
|
{
|
||||||
DetailedDescription = string.Format("Please verify your username and password. Also verify if the host running Sonarr isn't blocked from accessing {0} by WhiteList limitations in the {0} configuration.", Name)
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientValidationAuthenticationFailureDetail", new Dictionary<string, object> { { "clientName", Name } })
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
catch (DownloadClientUnavailableException ex)
|
catch (DownloadClientUnavailableException ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, ex.Message);
|
_logger.Error(ex, ex.Message);
|
||||||
|
|
||||||
return new NzbDroneValidationFailure("Host", "Unable to connect to Transmission")
|
return new NzbDroneValidationFailure("Host", _localizationService.GetLocalizedString("DownloadClientValidationUnableToConnect", new Dictionary<string, object> { { "clientName", Name } }))
|
||||||
{
|
{
|
||||||
DetailedDescription = ex.Message
|
DetailedDescription = ex.Message
|
||||||
};
|
};
|
||||||
|
@ -288,7 +290,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
{
|
{
|
||||||
_logger.Error(ex, "Failed to test");
|
_logger.Error(ex, "Failed to test");
|
||||||
|
|
||||||
return new NzbDroneValidationFailure(string.Empty, "Unknown exception: " + ex.Message);
|
return new NzbDroneValidationFailure(string.Empty, _localizationService.GetLocalizedString("DownloadClientValidationUnknownException", new Dictionary<string, object> { { "exception", ex.Message } }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,7 +305,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, "Failed to get torrents");
|
_logger.Error(ex, "Failed to get torrents");
|
||||||
return new NzbDroneValidationFailure(string.Empty, "Failed to get the list of torrents: " + ex.Message);
|
return new NzbDroneValidationFailure(string.Empty, _localizationService.GetLocalizedString("DownloadClientValidationTestTorrents", new Dictionary<string, object> { { "exceptionMessage", ex.Message } }));
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -41,10 +41,15 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
[FieldDefinition(1, Label = "Port", Type = FieldType.Textbox)]
|
[FieldDefinition(1, Label = "Port", Type = FieldType.Textbox)]
|
||||||
public int Port { get; set; }
|
public int Port { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(2, Label = "Use SSL", Type = FieldType.Checkbox, HelpText = "Use secure connection when connecting to Transmission")]
|
[FieldDefinition(2, Label = "UseSsl", Type = FieldType.Checkbox, HelpText = "DownloadClientSettingsUseSslHelpText")]
|
||||||
|
[FieldToken(TokenField.HelpText, "UseSsl", "clientName", "Transmission")]
|
||||||
public bool UseSsl { get; set; }
|
public bool UseSsl { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(3, Label = "Url Base", Type = FieldType.Textbox, Advanced = true, HelpText = "Adds a prefix to the transmission rpc url, eg http://[host]:[port]/[urlBase]/rpc, defaults to '/transmission/'")]
|
[FieldDefinition(3, Label = "UrlBase", Type = FieldType.Textbox, Advanced = true, HelpText = "Adds a prefix to the transmission rpc url, eg http://[host]:[port]/[urlBase]/rpc, defaults to '/transmission/'")]
|
||||||
|
[FieldToken(TokenField.HelpText, "UrlBase", "clientName", "Transmission")]
|
||||||
|
[FieldToken(TokenField.HelpText, "UrlBase", "url", "http://[host]:[port]/[urlBase]/rpc")]
|
||||||
|
[FieldToken(TokenField.HelpText, "UrlBase", "defaultUrl", "/transmission/")]
|
||||||
|
|
||||||
public string UrlBase { get; set; }
|
public string UrlBase { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(4, Label = "Username", Type = FieldType.Textbox, Privacy = PrivacyLevel.UserName)]
|
[FieldDefinition(4, Label = "Username", Type = FieldType.Textbox, Privacy = PrivacyLevel.UserName)]
|
||||||
|
@ -53,19 +58,19 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
[FieldDefinition(5, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password)]
|
[FieldDefinition(5, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password)]
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(6, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Sonarr avoids conflicts with unrelated non-Sonarr downloads. Using a category is optional, but strongly recommended.. Creates a [category] subdirectory in the output directory.")]
|
[FieldDefinition(6, Label = "Category", Type = FieldType.Textbox, HelpText = "DownloadClientSettingsCategorySubFolderHelpText")]
|
||||||
public string TvCategory { get; set; }
|
public string TvCategory { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(7, Label = "Directory", Type = FieldType.Textbox, Advanced = true, HelpText = "Optional location to put downloads in, leave blank to use the default Transmission location")]
|
[FieldDefinition(7, Label = "Directory", Type = FieldType.Textbox, Advanced = true, HelpText = "DownloadClientTransmissionSettingsDirectoryHelpText")]
|
||||||
public string TvDirectory { get; set; }
|
public string TvDirectory { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(8, Label = "Recent Priority", Type = FieldType.Select, SelectOptions = typeof(TransmissionPriority), HelpText = "Priority to use when grabbing episodes that aired within the last 14 days")]
|
[FieldDefinition(8, Label = "DownloadClientSettingsRecentPriority", Type = FieldType.Select, SelectOptions = typeof(TransmissionPriority), HelpText = "DownloadClientSettingsRecentPriorityHelpText")]
|
||||||
public int RecentTvPriority { get; set; }
|
public int RecentTvPriority { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(9, Label = "Older Priority", Type = FieldType.Select, SelectOptions = typeof(TransmissionPriority), HelpText = "Priority to use when grabbing episodes that aired over 14 days ago")]
|
[FieldDefinition(9, Label = "DownloadClientSettingsOlderPriority", Type = FieldType.Select, SelectOptions = typeof(TransmissionPriority), HelpText = "DownloadClientSettingsOlderPriorityHelpText")]
|
||||||
public int OlderTvPriority { get; set; }
|
public int OlderTvPriority { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(10, Label = "Add Paused", Type = FieldType.Checkbox)]
|
[FieldDefinition(10, Label = "DownloadClientSettingsAddPaused", Type = FieldType.Checkbox)]
|
||||||
public bool AddPaused { get; set; }
|
public bool AddPaused { get; set; }
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
|
|
|
@ -4,6 +4,7 @@ using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Download.Clients.Transmission;
|
using NzbDrone.Core.Download.Clients.Transmission;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
|
||||||
|
@ -19,8 +20,9 @@ namespace NzbDrone.Core.Download.Clients.Vuze
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
Logger logger)
|
Logger logger,
|
||||||
: base(proxy, torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger)
|
ILocalizationService localizationService)
|
||||||
|
: base(proxy, torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger, localizationService)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +59,7 @@ namespace NzbDrone.Core.Download.Clients.Vuze
|
||||||
if (!int.TryParse(versionString, out var 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.");
|
return new ValidationFailure(string.Empty, _localizationService.GetLocalizedString("DownloadClientVuzeValidationErrorVersion"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Download.Clients.rTorrent;
|
using NzbDrone.Core.Download.Clients.rTorrent;
|
||||||
using NzbDrone.Core.Exceptions;
|
using NzbDrone.Core.Exceptions;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
@ -34,8 +35,9 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
IDownloadSeedConfigProvider downloadSeedConfigProvider,
|
IDownloadSeedConfigProvider downloadSeedConfigProvider,
|
||||||
IRTorrentDirectoryValidator rTorrentDirectoryValidator,
|
IRTorrentDirectoryValidator rTorrentDirectoryValidator,
|
||||||
Logger logger)
|
Logger logger,
|
||||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger)
|
ILocalizationService localizationService)
|
||||||
|
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger, localizationService)
|
||||||
{
|
{
|
||||||
_proxy = proxy;
|
_proxy = proxy;
|
||||||
_rTorrentDirectoryValidator = rTorrentDirectoryValidator;
|
_rTorrentDirectoryValidator = rTorrentDirectoryValidator;
|
||||||
|
@ -115,7 +117,7 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||||
|
|
||||||
public override string Name => "rTorrent";
|
public override string Name => "rTorrent";
|
||||||
|
|
||||||
public override ProviderMessage Message => new ProviderMessage($"rTorrent will not pause torrents when they meet the seed criteria. Sonarr will handle automatic removal of torrents based on the current seed criteria in Settings->Indexers only when Remove Completed is enabled. After importing it will also set \"{_imported_view}\" as an rTorrent view, which can be used in rTorrent scripts to customize behavior.", ProviderMessageType.Info);
|
public override ProviderMessage Message => new ProviderMessage(_localizationService.GetLocalizedString("DownloadClientRTorrentProviderMessage", new Dictionary<string, object> { { "importedView", _imported_view } }), ProviderMessageType.Info);
|
||||||
|
|
||||||
public override IEnumerable<DownloadClientItem> GetItems()
|
public override IEnumerable<DownloadClientItem> GetItems()
|
||||||
{
|
{
|
||||||
|
@ -250,14 +252,19 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||||
|
|
||||||
if (new Version(version) < new Version("0.9.0"))
|
if (new Version(version) < new Version("0.9.0"))
|
||||||
{
|
{
|
||||||
return new ValidationFailure(string.Empty, "rTorrent version should be at least 0.9.0. Version reported is {0}", version);
|
return new ValidationFailure(string.Empty,
|
||||||
|
_localizationService.GetLocalizedString("DownloadClientValidationErrorVersion",
|
||||||
|
new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "clientName", Name }, { "requiredVersion", "0.9.0" }, { "reportedVersion", version }
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, "Failed to test rTorrent");
|
_logger.Error(ex, "Failed to test rTorrent");
|
||||||
|
|
||||||
return new NzbDroneValidationFailure("Host", "Unable to connect to rTorrent")
|
return new NzbDroneValidationFailure("Host", _localizationService.GetLocalizedString("DownloadClientValidationUnableToConnect", new Dictionary<string, object> { { "clientName", Name } }))
|
||||||
{
|
{
|
||||||
DetailedDescription = ex.Message
|
DetailedDescription = ex.Message
|
||||||
};
|
};
|
||||||
|
@ -275,7 +282,7 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, "Failed to get torrents");
|
_logger.Error(ex, "Failed to get torrents");
|
||||||
return new NzbDroneValidationFailure(string.Empty, "Failed to get the list of torrents: " + ex.Message);
|
return new NzbDroneValidationFailure(string.Empty, _localizationService.GetLocalizedString("DownloadClientValidationTestTorrents", new Dictionary<string, object> { { "exceptionMessage", ex.Message } }));
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -37,10 +37,13 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||||
[FieldDefinition(1, Label = "Port", Type = FieldType.Textbox)]
|
[FieldDefinition(1, Label = "Port", Type = FieldType.Textbox)]
|
||||||
public int Port { get; set; }
|
public int Port { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(2, Label = "Use SSL", Type = FieldType.Checkbox, HelpText = "Use secure connection when connecting to rTorrent")]
|
[FieldDefinition(2, Label = "UseSsl", Type = FieldType.Checkbox, HelpText = "DownloadClientSettingsUseSslHelpText")]
|
||||||
|
[FieldToken(TokenField.HelpText, "UseSsl", "clientName", "rTorrent")]
|
||||||
public bool UseSsl { get; set; }
|
public bool UseSsl { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(3, Label = "Url Path", Type = FieldType.Textbox, HelpText = "Path to the XMLRPC endpoint, see http(s)://[host]:[port]/[urlPath]. This is usually RPC2 or [path to ruTorrent]/plugins/rpc/rpc.php when using ruTorrent.")]
|
[FieldDefinition(3, Label = "DownloadClientRTorrentSettingsUrlPath", Type = FieldType.Textbox, HelpText = "DownloadClientRTorrentSettingsUrlPathHelpText")]
|
||||||
|
[FieldToken(TokenField.HelpText, "DownloadClientRTorrentSettingsUrlPath", "url", "http(s)://[host]:[port]/[urlPath]")]
|
||||||
|
[FieldToken(TokenField.HelpText, "DownloadClientRTorrentSettingsUrlPath", "url2", "/plugins/rpc/rpc.php")]
|
||||||
public string UrlBase { get; set; }
|
public string UrlBase { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(4, Label = "Username", Type = FieldType.Textbox, Privacy = PrivacyLevel.UserName)]
|
[FieldDefinition(4, Label = "Username", Type = FieldType.Textbox, Privacy = PrivacyLevel.UserName)]
|
||||||
|
@ -49,22 +52,22 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||||
[FieldDefinition(5, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password)]
|
[FieldDefinition(5, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password)]
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(6, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Sonarr avoids conflicts with unrelated non-Sonarr downloads. Using a category is optional, but strongly recommended.")]
|
[FieldDefinition(6, Label = "Category", Type = FieldType.Textbox, HelpText = "DownloadClientSettingsCategoryHelpText")]
|
||||||
public string TvCategory { get; set; }
|
public string TvCategory { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(7, Label = "Post-Import Category", Type = FieldType.Textbox, Advanced = true, HelpText = "Category for Sonarr to set after it has imported the download. Sonarr will not remove the torrent if seeding has finished. Leave blank to keep same category.")]
|
[FieldDefinition(7, Label = "PostImportCategory", Type = FieldType.Textbox, Advanced = true, HelpText = "DownloadClientSettingsPostImportCategoryHelpText")]
|
||||||
public string TvImportedCategory { get; set; }
|
public string TvImportedCategory { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(8, Label = "Directory", Type = FieldType.Textbox, Advanced = true, HelpText = "Optional location to put downloads in, leave blank to use the default rTorrent location")]
|
[FieldDefinition(8, Label = "Directory", Type = FieldType.Textbox, Advanced = true, HelpText = "DownloadClientRTorrentSettingsDirectoryHelpText")]
|
||||||
public string TvDirectory { get; set; }
|
public string TvDirectory { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(9, Label = "Recent Priority", Type = FieldType.Select, SelectOptions = typeof(RTorrentPriority), HelpText = "Priority to use when grabbing episodes that aired within the last 14 days")]
|
[FieldDefinition(9, Label = "DownloadClientSettingsRecentPriority", Type = FieldType.Select, SelectOptions = typeof(RTorrentPriority), HelpText = "DownloadClientSettingsRecentPriorityHelpText")]
|
||||||
public int RecentTvPriority { get; set; }
|
public int RecentTvPriority { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(10, Label = "Older Priority", Type = FieldType.Select, SelectOptions = typeof(RTorrentPriority), HelpText = "Priority to use when grabbing episodes that aired over 14 days ago")]
|
[FieldDefinition(10, Label = "DownloadClientSettingsOlderPriority", Type = FieldType.Select, SelectOptions = typeof(RTorrentPriority), HelpText = "DownloadClientSettingsOlderPriorityHelpText")]
|
||||||
public int OlderTvPriority { get; set; }
|
public int OlderTvPriority { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(11, Label = "Add Stopped", Type = FieldType.Checkbox, HelpText = "Enabling will add torrents and magnets to rTorrent in a stopped state. This may break magnet files.")]
|
[FieldDefinition(11, Label = "DownloadClientRTorrentSettingsAddStopped", Type = FieldType.Checkbox, HelpText = "DownloadClientRTorrentSettingsAddStoppedHelpText")]
|
||||||
public bool AddStopped { get; set; }
|
public bool AddStopped { get; set; }
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
|
|
|
@ -9,6 +9,7 @@ using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
@ -28,8 +29,9 @@ namespace NzbDrone.Core.Download.Clients.UTorrent
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
Logger logger)
|
Logger logger,
|
||||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger)
|
ILocalizationService localizationService)
|
||||||
|
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger, localizationService)
|
||||||
{
|
{
|
||||||
_proxy = proxy;
|
_proxy = proxy;
|
||||||
|
|
||||||
|
@ -141,7 +143,7 @@ namespace NzbDrone.Core.Download.Clients.UTorrent
|
||||||
if (torrent.Status.HasFlag(UTorrentTorrentStatus.Error))
|
if (torrent.Status.HasFlag(UTorrentTorrentStatus.Error))
|
||||||
{
|
{
|
||||||
item.Status = DownloadItemStatus.Warning;
|
item.Status = DownloadItemStatus.Warning;
|
||||||
item.Message = "uTorrent is reporting an error";
|
item.Message = _localizationService.GetLocalizedString("DownloadClientUTorrentTorrentStateError");
|
||||||
}
|
}
|
||||||
else if (torrent.Status.HasFlag(UTorrentTorrentStatus.Loaded) &&
|
else if (torrent.Status.HasFlag(UTorrentTorrentStatus.Loaded) &&
|
||||||
torrent.Status.HasFlag(UTorrentTorrentStatus.Checked) && torrent.Remaining == 0 && torrent.Progress == 1.0)
|
torrent.Status.HasFlag(UTorrentTorrentStatus.Checked) && torrent.Remaining == 0 && torrent.Progress == 1.0)
|
||||||
|
@ -264,15 +266,20 @@ namespace NzbDrone.Core.Download.Clients.UTorrent
|
||||||
|
|
||||||
if (version < 25406)
|
if (version < 25406)
|
||||||
{
|
{
|
||||||
return new ValidationFailure(string.Empty, "Old uTorrent client with unsupported API, need 3.0 or higher");
|
return new ValidationFailure(string.Empty,
|
||||||
|
_localizationService.GetLocalizedString("DownloadClientValidationErrorVersion",
|
||||||
|
new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "clientName", Name }, { "requiredVersion", "3.0" }, { "reportedVersion", version }
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (DownloadClientAuthenticationException ex)
|
catch (DownloadClientAuthenticationException ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, ex.Message);
|
_logger.Error(ex, ex.Message);
|
||||||
return new NzbDroneValidationFailure("Username", "Authentication failure")
|
return new NzbDroneValidationFailure("Username", _localizationService.GetLocalizedString("DownloadClientValidationAuthenticationFailure"))
|
||||||
{
|
{
|
||||||
DetailedDescription = "Please verify your username and password."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientValidationAuthenticationFailureDetail", new Dictionary<string, object> { { "clientName", Name } })
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
catch (WebException ex)
|
catch (WebException ex)
|
||||||
|
@ -280,19 +287,19 @@ namespace NzbDrone.Core.Download.Clients.UTorrent
|
||||||
_logger.Error(ex, "Unable to connect to uTorrent");
|
_logger.Error(ex, "Unable to connect to uTorrent");
|
||||||
if (ex.Status == WebExceptionStatus.ConnectFailure)
|
if (ex.Status == WebExceptionStatus.ConnectFailure)
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationFailure("Host", "Unable to connect")
|
return new NzbDroneValidationFailure("Host", _localizationService.GetLocalizedString("DownloadClientValidationUnableToConnect", new Dictionary<string, object> { { "clientName", Name } }))
|
||||||
{
|
{
|
||||||
DetailedDescription = "Please verify the hostname and port."
|
DetailedDescription = _localizationService.GetLocalizedString("DownloadClientValidationUnableToConnectDetail")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return new NzbDroneValidationFailure(string.Empty, "Unknown exception: " + ex.Message);
|
return new NzbDroneValidationFailure(string.Empty, _localizationService.GetLocalizedString("DownloadClientValidationUnknownException", new Dictionary<string, object> { { "exception", ex.Message } }));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, "Failed to test uTorrent");
|
_logger.Error(ex, "Failed to test uTorrent");
|
||||||
|
|
||||||
return new NzbDroneValidationFailure("Host", "Unable to connect to uTorrent")
|
return new NzbDroneValidationFailure("Host", _localizationService.GetLocalizedString("DownloadClientValidationUnableToConnect", new Dictionary<string, object> { { "clientName", Name } }))
|
||||||
{
|
{
|
||||||
DetailedDescription = ex.Message
|
DetailedDescription = ex.Message
|
||||||
};
|
};
|
||||||
|
@ -310,7 +317,7 @@ namespace NzbDrone.Core.Download.Clients.UTorrent
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, "Failed to get torrents");
|
_logger.Error(ex, "Failed to get torrents");
|
||||||
return new NzbDroneValidationFailure(string.Empty, "Failed to get the list of torrents: " + ex.Message);
|
return new NzbDroneValidationFailure(string.Empty, _localizationService.GetLocalizedString("DownloadClientValidationTestTorrents", new Dictionary<string, object> { { "exceptionMessage", ex.Message } }));
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -34,10 +34,13 @@ namespace NzbDrone.Core.Download.Clients.UTorrent
|
||||||
[FieldDefinition(1, Label = "Port", Type = FieldType.Textbox)]
|
[FieldDefinition(1, Label = "Port", Type = FieldType.Textbox)]
|
||||||
public int Port { get; set; }
|
public int Port { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(2, Label = "Use SSL", Type = FieldType.Checkbox, HelpText = "Use secure connection when connecting to uTorrent")]
|
[FieldDefinition(2, Label = "UseSsl", Type = FieldType.Checkbox, HelpText = "DownloadClientSettingsUseSslHelpText")]
|
||||||
|
[FieldToken(TokenField.HelpText, "UseSsl", "clientName", "uTorrent")]
|
||||||
public bool UseSsl { get; set; }
|
public bool UseSsl { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(3, Label = "Url Base", Type = FieldType.Textbox, Advanced = true, HelpText = "Adds a prefix to the uTorrent url, e.g. http://[host]:[port]/[urlBase]/api")]
|
[FieldDefinition(3, Label = "UrlBase", Type = FieldType.Textbox, Advanced = true, HelpText = "DownloadClientSettingsUrlBaseHelpText")]
|
||||||
|
[FieldToken(TokenField.HelpText, "UrlBase", "clientName", "uTorrent")]
|
||||||
|
[FieldToken(TokenField.HelpText, "UrlBase", "url", "http://[host]:[port]/[urlBase]/api")]
|
||||||
public string UrlBase { get; set; }
|
public string UrlBase { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(4, Label = "Username", Type = FieldType.Textbox, Privacy = PrivacyLevel.UserName)]
|
[FieldDefinition(4, Label = "Username", Type = FieldType.Textbox, Privacy = PrivacyLevel.UserName)]
|
||||||
|
@ -46,19 +49,20 @@ namespace NzbDrone.Core.Download.Clients.UTorrent
|
||||||
[FieldDefinition(5, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password)]
|
[FieldDefinition(5, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password)]
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(6, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Sonarr avoids conflicts with unrelated non-Sonarr downloads. Using a category is optional, but strongly recommended.")]
|
[FieldDefinition(6, Label = "Category", Type = FieldType.Textbox, HelpText = "DownloadClientSettingsCategoryHelpText")]
|
||||||
public string TvCategory { get; set; }
|
public string TvCategory { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(7, Label = "Post-Import Category", Type = FieldType.Textbox, Advanced = true, HelpText = "Category for Sonarr to set after it has imported the download. Sonarr will not remove the torrent if seeding has finished. Leave blank to keep same category.")]
|
[FieldDefinition(7, Label = "PostImportCategory", Type = FieldType.Textbox, Advanced = true, HelpText = "DownloadClientSettingsPostImportCategoryHelpText")]
|
||||||
public string TvImportedCategory { get; set; }
|
public string TvImportedCategory { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(8, Label = "Recent Priority", Type = FieldType.Select, SelectOptions = typeof(UTorrentPriority), HelpText = "Priority to use when grabbing episodes that aired within the last 14 days")]
|
[FieldDefinition(8, Label = "DownloadClientSettingsRecentPriority", Type = FieldType.Select, SelectOptions = typeof(UTorrentPriority), HelpText = "DownloadClientSettingsRecentPriorityHelpText")]
|
||||||
public int RecentTvPriority { get; set; }
|
public int RecentTvPriority { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(9, Label = "Older Priority", Type = FieldType.Select, SelectOptions = typeof(UTorrentPriority), HelpText = "Priority to use when grabbing episodes that aired over 14 days ago")]
|
[FieldDefinition(9, Label = "DownloadClientSettingsOlderPriority", Type = FieldType.Select, SelectOptions = typeof(UTorrentPriority), HelpText = "DownloadClientSettingsOlderPriorityHelpText")]
|
||||||
public int OlderTvPriority { get; set; }
|
public int OlderTvPriority { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(10, Label = "Initial State", Type = FieldType.Select, SelectOptions = typeof(UTorrentState), HelpText = "Initial state for torrents added to uTorrent")]
|
[FieldDefinition(10, Label = "DownloadClientSettingsInitialState", Type = FieldType.Select, SelectOptions = typeof(UTorrentState), HelpText = "DownloadClientSettingsInitialStateHelpText")]
|
||||||
|
[FieldToken(TokenField.HelpText, "DownloadClientSettingsInitialState", "clientName", "uTorrent")]
|
||||||
public int IntialState { get; set; }
|
public int IntialState { get; set; }
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
|
|
|
@ -6,6 +6,7 @@ using NLog;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
@ -20,6 +21,7 @@ namespace NzbDrone.Core.Download
|
||||||
protected readonly IDiskProvider _diskProvider;
|
protected readonly IDiskProvider _diskProvider;
|
||||||
protected readonly IRemotePathMappingService _remotePathMappingService;
|
protected readonly IRemotePathMappingService _remotePathMappingService;
|
||||||
protected readonly Logger _logger;
|
protected readonly Logger _logger;
|
||||||
|
protected readonly ILocalizationService _localizationService;
|
||||||
|
|
||||||
public abstract string Name { get; }
|
public abstract string Name { get; }
|
||||||
|
|
||||||
|
@ -41,12 +43,14 @@ namespace NzbDrone.Core.Download
|
||||||
protected DownloadClientBase(IConfigService configService,
|
protected DownloadClientBase(IConfigService configService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
Logger logger)
|
Logger logger,
|
||||||
|
ILocalizationService localizationService)
|
||||||
{
|
{
|
||||||
_configService = configService;
|
_configService = configService;
|
||||||
_diskProvider = diskProvider;
|
_diskProvider = diskProvider;
|
||||||
_remotePathMappingService = remotePathMappingService;
|
_remotePathMappingService = remotePathMappingService;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
_localizationService = localizationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
|
|
|
@ -9,6 +9,7 @@ using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Exceptions;
|
using NzbDrone.Core.Exceptions;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
using NzbDrone.Core.Organizer;
|
using NzbDrone.Core.Organizer;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
@ -24,12 +25,13 @@ namespace NzbDrone.Core.Download
|
||||||
protected readonly ITorrentFileInfoReader _torrentFileInfoReader;
|
protected readonly ITorrentFileInfoReader _torrentFileInfoReader;
|
||||||
|
|
||||||
protected TorrentClientBase(ITorrentFileInfoReader torrentFileInfoReader,
|
protected TorrentClientBase(ITorrentFileInfoReader torrentFileInfoReader,
|
||||||
IHttpClient httpClient,
|
IHttpClient httpClient,
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
Logger logger)
|
Logger logger,
|
||||||
: base(configService, diskProvider, remotePathMappingService, logger)
|
ILocalizationService localizationService)
|
||||||
|
: base(configService, diskProvider, remotePathMappingService, logger, localizationService)
|
||||||
{
|
{
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
_torrentFileInfoReader = torrentFileInfoReader;
|
_torrentFileInfoReader = torrentFileInfoReader;
|
||||||
|
|
|
@ -6,6 +6,7 @@ using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Exceptions;
|
using NzbDrone.Core.Exceptions;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Organizer;
|
using NzbDrone.Core.Organizer;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
@ -24,8 +25,9 @@ namespace NzbDrone.Core.Download
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
IValidateNzbs nzbValidationService,
|
IValidateNzbs nzbValidationService,
|
||||||
Logger logger)
|
Logger logger,
|
||||||
: base(configService, diskProvider, remotePathMappingService, logger)
|
ILocalizationService localizationService)
|
||||||
|
: base(configService, diskProvider, remotePathMappingService, logger, localizationService)
|
||||||
{
|
{
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
_nzbValidationService = nzbValidationService;
|
_nzbValidationService = nzbValidationService;
|
||||||
|
|
|
@ -139,6 +139,9 @@
|
||||||
"BeforeUpdate": "Before update",
|
"BeforeUpdate": "Before update",
|
||||||
"BindAddress": "Bind Address",
|
"BindAddress": "Bind Address",
|
||||||
"BindAddressHelpText": "Valid IP address, localhost or '*' for all interfaces",
|
"BindAddressHelpText": "Valid IP address, localhost or '*' for all interfaces",
|
||||||
|
"BlackholeFolderHelpText": "Folder in which {appName} will store the {extension} file",
|
||||||
|
"BlackholeWatchFolder": "Watch Folder",
|
||||||
|
"BlackholeWatchFolderHelpText": "Folder from which {appName} should import completed downloads",
|
||||||
"Blocklist": "Blocklist",
|
"Blocklist": "Blocklist",
|
||||||
"BlocklistLoadError": "Unable to load blocklist",
|
"BlocklistLoadError": "Unable to load blocklist",
|
||||||
"BlocklistRelease": "Blocklist Release",
|
"BlocklistRelease": "Blocklist Release",
|
||||||
|
@ -171,6 +174,7 @@
|
||||||
"Cancel": "Cancel",
|
"Cancel": "Cancel",
|
||||||
"CancelPendingTask": "Are you sure you want to cancel this pending task?",
|
"CancelPendingTask": "Are you sure you want to cancel this pending task?",
|
||||||
"CancelProcessing": "Cancel Processing",
|
"CancelProcessing": "Cancel Processing",
|
||||||
|
"Category": "Category",
|
||||||
"CertificateValidation": "Certificate Validation",
|
"CertificateValidation": "Certificate Validation",
|
||||||
"CertificateValidationHelpText": "Change how strict HTTPS certification validation is. Do not change unless you understand the risks.",
|
"CertificateValidationHelpText": "Change how strict HTTPS certification validation is. Do not change unless you understand the risks.",
|
||||||
"Certification": "Certification",
|
"Certification": "Certification",
|
||||||
|
@ -339,11 +343,13 @@
|
||||||
"DeletedReasonMissingFromDisk": "{appName} was unable to find the file on disk so the file was unlinked from the episode in the database",
|
"DeletedReasonMissingFromDisk": "{appName} was unable to find the file on disk so the file was unlinked from the episode in the database",
|
||||||
"DeletedReasonUpgrade": "File was deleted to import an upgrade",
|
"DeletedReasonUpgrade": "File was deleted to import an upgrade",
|
||||||
"DeletedSeriesDescription": "Series was deleted from TheTVDB",
|
"DeletedSeriesDescription": "Series was deleted from TheTVDB",
|
||||||
|
"Destination": "Destination",
|
||||||
"DestinationPath": "Destination Path",
|
"DestinationPath": "Destination Path",
|
||||||
"DestinationRelativePath": "Destination Relative Path",
|
"DestinationRelativePath": "Destination Relative Path",
|
||||||
"DetailedProgressBar": "Detailed Progress Bar",
|
"DetailedProgressBar": "Detailed Progress Bar",
|
||||||
"DetailedProgressBarHelpText": "Show text on progress bar",
|
"DetailedProgressBarHelpText": "Show text on progress bar",
|
||||||
"Details": "Details",
|
"Details": "Details",
|
||||||
|
"Directory": "Directory",
|
||||||
"Disabled": "Disabled",
|
"Disabled": "Disabled",
|
||||||
"DisabledForLocalAddresses": "Disabled for Local Addresses",
|
"DisabledForLocalAddresses": "Disabled for Local Addresses",
|
||||||
"Discord": "Discord",
|
"Discord": "Discord",
|
||||||
|
@ -360,14 +366,136 @@
|
||||||
"DownloadClient": "Download Client",
|
"DownloadClient": "Download Client",
|
||||||
"DownloadClientCheckNoneAvailableHealthCheckMessage": "No download client is available",
|
"DownloadClientCheckNoneAvailableHealthCheckMessage": "No download client is available",
|
||||||
"DownloadClientCheckUnableToCommunicateWithHealthCheckMessage": "Unable to communicate with {downloadClientName}. {errorMessage}",
|
"DownloadClientCheckUnableToCommunicateWithHealthCheckMessage": "Unable to communicate with {downloadClientName}. {errorMessage}",
|
||||||
|
"DownloadClientDelugeSettingsUrlBaseHelpText": "Adds a prefix to the deluge json url, see {url}",
|
||||||
|
"DownloadClientDelugeTorrentStateError": "Deluge is reporting an error",
|
||||||
|
"DownloadClientDelugeValidationLabelPluginFailure": "Configuration of label failed",
|
||||||
|
"DownloadClientDelugeValidationLabelPluginFailureDetail": "{appName} was unable to add the label to {clientName}.",
|
||||||
|
"DownloadClientDelugeValidationLabelPluginInactive": "Label plugin not activated",
|
||||||
|
"DownloadClientDelugeValidationLabelPluginInactiveDetail": "You must have the Label plugin enabled in {clientName} to use categories.",
|
||||||
|
"DownloadClientDownloadStationProviderMessage": "{appName} is unable to connect to Download Station if 2-Factor Authentication is enabled on your DSM account",
|
||||||
|
"DownloadClientDownloadStationSettingsDirectory": "Optional shared folder to put downloads into, leave blank to use the default Download Station location",
|
||||||
|
"DownloadClientDownloadStationValidationApiVersion": "Download Station API version not supported, should be at least {requiredVersion}. It supports from {minVersion} to {maxVersion}",
|
||||||
|
"DownloadClientDownloadStationValidationFolderMissing": "Folder does not exist",
|
||||||
|
"DownloadClientDownloadStationValidationFolderMissingDetail": "The folder '{downloadDir}' does not exist, it must be created manually inside the Shared Folder '{sharedFolder}'.",
|
||||||
|
"DownloadClientDownloadStationValidationNoDefaultDestination": "No default destination",
|
||||||
|
"DownloadClientDownloadStationValidationNoDefaultDestinationDetail": "You must login into your Diskstation as {username} and manually set it up into DownloadStation settings under BT/HTTP/FTP/NZB -> Location.",
|
||||||
|
"DownloadClientDownloadStationValidationSharedFolderMissing": "Shared folder does not exist",
|
||||||
|
"DownloadClientDownloadStationValidationSharedFolderMissingDetail": "The Diskstation does not have a Shared Folder with the name '{sharedFolder}', are you sure you specified it correctly?",
|
||||||
|
"DownloadClientFloodSettingsAdditionalTags": "Additional Tags",
|
||||||
|
"DownloadClientFloodSettingsAdditionalTagsHelpText": "Adds properties of media as tags. Hints are examples.",
|
||||||
|
"DownloadClientFloodSettingsPostImportTags": "Post-Import Tags",
|
||||||
|
"DownloadClientFloodSettingsPostImportTagsHelpText": "Appends tags after a download is imported.",
|
||||||
|
"DownloadClientFloodSettingsRemovalInfo": "{appName} will handle automatic removal of torrents based on the current seed criteria in Settings -> Indexers",
|
||||||
|
"DownloadClientFloodSettingsStartOnAdd": "Start on Add",
|
||||||
|
"DownloadClientFloodSettingsTagsHelpText": "Initial tags of a download. To be recognized, a download must have all initial tags. This avoids conflicts with unrelated downloads.",
|
||||||
|
"DownloadClientFloodSettingsUrlBaseHelpText": "Adds a prefix to the Flood API, such as {url}",
|
||||||
|
"DownloadClientFreeboxApiError": "Freebox API returned error: {errorDescription}",
|
||||||
|
"DownloadClientFreeboxAuthenticationError": "Authentication to Freebox API failed. Reason: {errorDescription}",
|
||||||
|
"DownloadClientFreeboxNotLoggedIn": "Not logged in",
|
||||||
|
"DownloadClientFreeboxSettingsApiUrl": "API URL",
|
||||||
|
"DownloadClientFreeboxSettingsApiUrlHelpText": "Define Freebox API base URL with API version, eg '{url}', defaults to '{defaultApiUrl}'",
|
||||||
|
"DownloadClientFreeboxSettingsAppId": "App ID",
|
||||||
|
"DownloadClientFreeboxSettingsAppIdHelpText": "App ID given when creating access to Freebox API (ie 'app_id')",
|
||||||
|
"DownloadClientFreeboxSettingsAppToken": "App Token",
|
||||||
|
"DownloadClientFreeboxSettingsAppTokenHelpText": "App token retrieved when creating access to Freebox API (ie 'app_token')",
|
||||||
|
"DownloadClientFreeboxSettingsHostHelpText": "Hostname or host IP address of the Freebox, defaults to '{url}' (will only work if on same network)",
|
||||||
|
"DownloadClientFreeboxSettingsPortHelpText": "Port used to access Freebox interface, defaults to '{port}'",
|
||||||
|
"DownloadClientFreeboxUnableToReachFreebox": "Unable to reach Freebox API. Verify 'Host', 'Port' or 'Use SSL' settings. (Error: {exceptionMessage})",
|
||||||
|
"DownloadClientFreeboxUnableToReachFreeboxApi": "Unable to reach Freebox API. Verify 'API URL' setting for base URL and version.",
|
||||||
|
"DownloadClientNzbVortexMultipleFilesMessage": "Download contains multiple files and is not in a job folder: {outputPath}",
|
||||||
|
"DownloadClientNzbgetSettingsAddPausedHelpText": "This option requires at least NzbGet version 16.0",
|
||||||
|
"DownloadClientNzbgetValidationKeepHistoryOverMax": "NzbGet setting KeepHistory should be less than 25000",
|
||||||
|
"DownloadClientNzbgetValidationKeepHistoryOverMaxDetail": "NzbGet setting KeepHistory is set too high.",
|
||||||
|
"DownloadClientNzbgetValidationKeepHistoryZero": "NzbGet setting KeepHistory should be greater than 0",
|
||||||
|
"DownloadClientNzbgetValidationKeepHistoryZeroDetail": "NzbGet setting KeepHistory is set to 0. Which prevents {appName} from seeing completed downloads.",
|
||||||
"DownloadClientOptionsLoadError": "Unable to load download client options",
|
"DownloadClientOptionsLoadError": "Unable to load download client options",
|
||||||
|
"DownloadClientPneumaticSettingsNzbFolder": "Nzb Folder",
|
||||||
|
"DownloadClientPneumaticSettingsNzbFolderHelpText": "This folder will need to be reachable from XBMC",
|
||||||
|
"DownloadClientPneumaticSettingsStrmFolder": "Strm Folder",
|
||||||
|
"DownloadClientPneumaticSettingsStrmFolderHelpText": ".strm files in this folder will be import by drone",
|
||||||
|
"DownloadClientQbittorrentSettingsFirstAndLastFirst": "First and Last First",
|
||||||
|
"DownloadClientQbittorrentSettingsFirstAndLastFirstHelpText": "Download first and last pieces first (qBittorrent 4.1.0+)",
|
||||||
|
"DownloadClientQbittorrentSettingsInitialStateHelpText": "Initial state for torrents added to qBittorrent. Note that Forced Torrents do not abide by seed restrictions",
|
||||||
|
"DownloadClientQbittorrentSettingsSequentialOrder": "Sequential Order",
|
||||||
|
"DownloadClientQbittorrentSettingsSequentialOrderHelpText": "Download in sequential order (qBittorrent 4.1.0+)",
|
||||||
|
"DownloadClientQbittorrentSettingsUseSslHelpText": "Use a secure connection. See Options -> Web UI -> 'Use HTTPS instead of HTTP' in qBittorrent.",
|
||||||
|
"DownloadClientQbittorrentTorrentStateDhtDisabled": "qBittorrent cannot resolve magnet link with DHT disabled",
|
||||||
|
"DownloadClientQbittorrentTorrentStateError": "qBittorrent is reporting an error",
|
||||||
|
"DownloadClientQbittorrentTorrentStateMetadata": "qBittorrent is downloading metadata",
|
||||||
|
"DownloadClientQbittorrentTorrentStatePathError": "Unable to Import. Path matches client base download directory, it's possible 'Keep top-level folder' is disabled for this torrent or 'Torrent Content Layout' is NOT set to 'Original' or 'Create Subfolder'?",
|
||||||
|
"DownloadClientQbittorrentTorrentStateStalled": "The download is stalled with no connections",
|
||||||
|
"DownloadClientQbittorrentTorrentStateUnknown": "Unknown download state: {state}",
|
||||||
|
"DownloadClientQbittorrentValidationCategoryAddFailure": "Configuration of category failed",
|
||||||
|
"DownloadClientQbittorrentValidationCategoryAddFailureDetail": "{appName} was unable to add the label to qBittorrent.",
|
||||||
|
"DownloadClientQbittorrentValidationCategoryRecommended": "Category is recommended",
|
||||||
|
"DownloadClientQbittorrentValidationCategoryRecommendedDetail": "{appName} will not attempt to import completed downloads without a category.",
|
||||||
|
"DownloadClientQbittorrentValidationCategoryUnsupported": "Category is not supported",
|
||||||
|
"DownloadClientQbittorrentValidationCategoryUnsupportedDetail": "Categories are not supported until qBittorrent version 3.3.0. Please upgrade or try again with an empty Category.",
|
||||||
|
"DownloadClientQbittorrentValidationQueueingNotEnabled": "Queueing Not Enabled",
|
||||||
|
"DownloadClientQbittorrentValidationQueueingNotEnabledDetail": "Torrent Queueing is not enabled in your qBittorrent settings. Enable it in qBittorrent or select 'Last' as priority.",
|
||||||
|
"DownloadClientQbittorrentValidationRemovesAtRatioLimit": "qBittorrent is configured to remove torrents when they reach their Share Ratio Limit",
|
||||||
|
"DownloadClientQbittorrentValidationRemovesAtRatioLimitDetail": "{appName} will be unable to perform Completed Download Handling as configured. You can fix this in qBittorrent ('Tools -> Options...' in the menu) by changing 'Options -> BitTorrent -> Share Ratio Limiting' from 'Remove them' to 'Pause them'",
|
||||||
|
"DownloadClientRTorrentProviderMessage": "rTorrent will not pause torrents when they meet the seed criteria. {appName} will handle automatic removal of torrents based on the current seed criteria in Settings->Indexers only when Remove Completed is enabled. After importing it will also set {importedView} as an rTorrent view, which can be used in rTorrent scripts to customize behavior.",
|
||||||
|
"DownloadClientRTorrentSettingsAddStopped": "Add Stopped",
|
||||||
|
"DownloadClientRTorrentSettingsAddStoppedHelpText": "Enabling will add torrents and magnets to rTorrent in a stopped state. This may break magnet files.",
|
||||||
|
"DownloadClientRTorrentSettingsDirectoryHelpText": "Optional location to put downloads in, leave blank to use the default rTorrent location",
|
||||||
|
"DownloadClientRTorrentSettingsUrlPath": "Url Path",
|
||||||
|
"DownloadClientRTorrentSettingsUrlPathHelpText": "Path to the XMLRPC endpoint, see {url}. This is usually RPC2 or [path to ruTorrent]{url2} when using ruTorrent.",
|
||||||
"DownloadClientRemovesCompletedDownloadsHealthCheckMessage": "Download client {downloadClientName} is set to remove completed downloads. This can result in downloads being removed from your client before {appName} can import them.",
|
"DownloadClientRemovesCompletedDownloadsHealthCheckMessage": "Download client {downloadClientName} is set to remove completed downloads. This can result in downloads being removed from your client before {appName} can import them.",
|
||||||
"DownloadClientRootFolderHealthCheckMessage": "Download client {downloadClientName} places downloads in the root folder {rootFolderPath}. You should not download to a root folder.",
|
"DownloadClientRootFolderHealthCheckMessage": "Download client {downloadClientName} places downloads in the root folder {rootFolderPath}. You should not download to a root folder.",
|
||||||
|
"DownloadClientSabnzbdValidationCheckBeforeDownload": "Disable 'Check before download' option in Sabnbzd",
|
||||||
|
"DownloadClientSabnzbdValidationCheckBeforeDownloadDetail": "Using 'Check before download' affects {appName} ability to track new downloads. Also Sabnzbd recommends 'Abort jobs that cannot be completed' instead since it's more effective.",
|
||||||
|
"DownloadClientSabnzbdValidationDevelopVersion": "Sabnzbd develop version, assuming version 3.0.0 or higher.",
|
||||||
|
"DownloadClientSabnzbdValidationDevelopVersionDetail": "{appName} may not be able to support new features added to SABnzbd when running develop versions.",
|
||||||
|
"DownloadClientSabnzbdValidationEnableDisableDateSorting": "Disable Date Sorting",
|
||||||
|
"DownloadClientSabnzbdValidationEnableDisableDateSortingDetail": "You must disable Date sorting for the category {appName} uses to prevent import issues. Go to Sabnzbd to fix it.",
|
||||||
|
"DownloadClientSabnzbdValidationEnableDisableMovieSorting": "Disable Movie Sorting",
|
||||||
|
"DownloadClientSabnzbdValidationEnableDisableMovieSortingDetail": "You must disable Movie sorting for the category {appName} uses to prevent import issues. Go to Sabnzbd to fix it.",
|
||||||
|
"DownloadClientSabnzbdValidationEnableDisableTvSorting": "Disable TV Sorting",
|
||||||
|
"DownloadClientSabnzbdValidationEnableDisableTvSortingDetail": "You must disable TV sorting for the category {appName} uses to prevent import issues. Go to Sabnzbd to fix it.",
|
||||||
|
"DownloadClientSabnzbdValidationEnableJobFolders": "Enable Job folders",
|
||||||
|
"DownloadClientSabnzbdValidationEnableJobFoldersDetail": "{appName} prefers each download to have a separate folder. With * appended to the Folder/Path Sabnzbd will not create these job folders. Go to Sabnzbd to fix it.",
|
||||||
|
"DownloadClientSabnzbdValidationUnknownVersion": "Unknown Version: {rawVersion}",
|
||||||
"DownloadClientSettings": "Download Client Settings",
|
"DownloadClientSettings": "Download Client Settings",
|
||||||
|
"DownloadClientSettingsAddPaused": "Add Paused",
|
||||||
|
"DownloadClientSettingsCategoryHelpText": "Adding a category specific to {appName} avoids conflicts with unrelated non-{appName} downloads. Using a category is optional, but strongly recommended.",
|
||||||
|
"DownloadClientSettingsCategorySubFolderHelpText": "Adding a category specific to {appName} avoids conflicts with unrelated non-{appName} downloads. Using a category is optional, but strongly recommended. Creates a [category] subdirectory in the output directory.",
|
||||||
|
"DownloadClientSettingsDestinationHelpText": "Manually specifies download destination, leave blank to use the default",
|
||||||
|
"DownloadClientSettingsInitialState": "Initial State",
|
||||||
|
"DownloadClientSettingsInitialStateHelpText": "Initial state for torrents added to {clientName}",
|
||||||
|
"DownloadClientSettingsOlderPriority": "Older Priority",
|
||||||
|
"DownloadClientSettingsOlderPriorityHelpText": "Priority to use when grabbing episodes that aired over 14 days ago",
|
||||||
|
"DownloadClientSettingsPostImportCategoryHelpText": "Category for {appName} to set after it has imported the download. {appName} will not remove torrents in that category even if seeding finished. Leave blank to keep same category.",
|
||||||
|
"DownloadClientSettingsRecentPriority": "Recent Priority",
|
||||||
|
"DownloadClientSettingsRecentPriorityHelpText": "Priority to use when grabbing episodes that aired within the last 14 days",
|
||||||
|
"DownloadClientSettingsUrlBaseHelpText": "Adds a prefix to the {clientName} url, such as {url}",
|
||||||
|
"DownloadClientSettingsUseSslHelpText": "Use secure connection when connection to {clientName}",
|
||||||
"DownloadClientSortingHealthCheckMessage": "Download client {downloadClientName} has {sortingMode} sorting enabled for {appName}'s category. You should disable sorting in your download client to avoid import issues.",
|
"DownloadClientSortingHealthCheckMessage": "Download client {downloadClientName} has {sortingMode} sorting enabled for {appName}'s category. You should disable sorting in your download client to avoid import issues.",
|
||||||
"DownloadClientStatusAllClientHealthCheckMessage": "All download clients are unavailable due to failures",
|
"DownloadClientStatusAllClientHealthCheckMessage": "All download clients are unavailable due to failures",
|
||||||
"DownloadClientStatusSingleClientHealthCheckMessage": "Download clients unavailable due to failures: {downloadClientNames}",
|
"DownloadClientStatusSingleClientHealthCheckMessage": "Download clients unavailable due to failures: {downloadClientNames}",
|
||||||
"DownloadClientTagHelpText": "Only use this download client for series with at least one matching tag. Leave blank to use with all series.",
|
"DownloadClientTagHelpText": "Only use this download client for series with at least one matching tag. Leave blank to use with all series.",
|
||||||
|
"DownloadClientTransmissionSettingsDirectoryHelpText": "Optional location to put downloads in, leave blank to use the default Transmission location",
|
||||||
|
"DownloadClientTransmissionSettingsUrlBaseHelpText": "Adds a prefix to the {clientName} rpc url, eg {url}, defaults to '{defaultUrl}'",
|
||||||
|
"DownloadClientUTorrentTorrentStateError": "uTorrent is reporting an error",
|
||||||
|
"DownloadClientValidationApiKeyIncorrect": "API Key Incorrect",
|
||||||
|
"DownloadClientValidationApiKeyRequired": "API Key Required",
|
||||||
|
"DownloadClientValidationAuthenticationFailure": "Authentication Failure",
|
||||||
|
"DownloadClientValidationAuthenticationFailureDetail": "Please verify your username and password. Also verify if the host running {appName} isn't blocked from accessing {clientName} by WhiteList limitations in the {clientName} configuration.",
|
||||||
|
"DownloadClientValidationCategoryMissing": "Category does not exist",
|
||||||
|
"DownloadClientValidationCategoryMissingDetail": "The category you entered doesn't exist in {clientName}. Create it in {clientName} first.",
|
||||||
|
"DownloadClientValidationErrorVersion": "{clientName} version should be at least {requiredVersion}. Version reported is {reportedVersion}",
|
||||||
|
"DownloadClientValidationGroupMissing": "Group does not exist",
|
||||||
|
"DownloadClientValidationGroupMissingDetail": "The group you entered doesn't exist in {clientName}. Create it in {clientName} first.",
|
||||||
|
"DownloadClientValidationSslConnectFailure": "Unable to connect through SSL",
|
||||||
|
"DownloadClientValidationSslConnectFailureDetail": "{appName} is unable to connect to {clientName} using SSL. This problem could be computer related. Please try to configure both {appName} and {clientName} to not use SSL.",
|
||||||
|
"DownloadClientValidationTestNzbs": "Failed to get the list of NZBs: {exceptionMessage}",
|
||||||
|
"DownloadClientValidationTestTorrents": "Failed to get the list of torrents: {exceptionMessage}",
|
||||||
|
"DownloadClientValidationUnableToConnect": "Unable to connect to {clientName}",
|
||||||
|
"DownloadClientValidationUnableToConnectDetail": "Please verify the hostname and port.",
|
||||||
|
"DownloadClientValidationUnknownException": "Unknown exception: {exception}",
|
||||||
|
"DownloadClientValidationVerifySsl": "Verify SSL settings",
|
||||||
|
"DownloadClientValidationVerifySslDetail": "Please verify your SSL configuration on both {clientName} and {appName}",
|
||||||
|
"DownloadClientVuzeValidationErrorVersion": "Protocol version not supported, use Vuze 5.0.0.0 or higher with Vuze Web Remote plugin.",
|
||||||
"DownloadClients": "Download Clients",
|
"DownloadClients": "Download Clients",
|
||||||
"DownloadClientsLoadError": "Unable to load download clients",
|
"DownloadClientsLoadError": "Unable to load download clients",
|
||||||
"DownloadClientsSettingsSummary": "Download clients, download handling and remote path mappings",
|
"DownloadClientsSettingsSummary": "Download clients, download handling and remote path mappings",
|
||||||
|
@ -379,6 +507,7 @@
|
||||||
"DownloadPropersAndRepacksHelpText": "Whether or not to automatically upgrade to Propers/Repacks",
|
"DownloadPropersAndRepacksHelpText": "Whether or not to automatically upgrade to Propers/Repacks",
|
||||||
"DownloadPropersAndRepacksHelpTextCustomFormat": "Use 'Do not Prefer' to sort by custom format score over Propers/Repacks",
|
"DownloadPropersAndRepacksHelpTextCustomFormat": "Use 'Do not Prefer' to sort by custom format score over Propers/Repacks",
|
||||||
"DownloadPropersAndRepacksHelpTextWarning": "Use custom formats for automatic upgrades to Propers/Repacks",
|
"DownloadPropersAndRepacksHelpTextWarning": "Use custom formats for automatic upgrades to Propers/Repacks",
|
||||||
|
"DownloadStationStatusExtracting": "Extracting: {progress}%",
|
||||||
"DownloadWarning": "Download warning: {warningMessage}",
|
"DownloadWarning": "Download warning: {warningMessage}",
|
||||||
"Downloaded": "Downloaded",
|
"Downloaded": "Downloaded",
|
||||||
"Downloading": "Downloading",
|
"Downloading": "Downloading",
|
||||||
|
@ -887,6 +1016,7 @@
|
||||||
"NotificationTriggersHelpText": "Select which events should trigger this notification",
|
"NotificationTriggersHelpText": "Select which events should trigger this notification",
|
||||||
"NotificationsLoadError": "Unable to load Notifications",
|
"NotificationsLoadError": "Unable to load Notifications",
|
||||||
"NotificationsTagsHelpText": "Only send notifications for series with at least one matching tag",
|
"NotificationsTagsHelpText": "Only send notifications for series with at least one matching tag",
|
||||||
|
"NzbgetHistoryItemMessage": "PAR Status: {parStatus} - Unpack Status: {unpackStatus} - Move Status: {moveStatus} - Script Status: {scriptStatus} - Delete Status: {deleteStatus} - Mark Status: {markStatus}",
|
||||||
"Ok": "Ok",
|
"Ok": "Ok",
|
||||||
"OnApplicationUpdate": "On Application Update",
|
"OnApplicationUpdate": "On Application Update",
|
||||||
"OnEpisodeFileDelete": "On Episode File Delete",
|
"OnEpisodeFileDelete": "On Episode File Delete",
|
||||||
|
@ -956,6 +1086,7 @@
|
||||||
"Permissions": "Permissions",
|
"Permissions": "Permissions",
|
||||||
"Port": "Port",
|
"Port": "Port",
|
||||||
"PortNumber": "Port Number",
|
"PortNumber": "Port Number",
|
||||||
|
"PostImportCategory": "Post-Import Category",
|
||||||
"PosterOptions": "Poster Options",
|
"PosterOptions": "Poster Options",
|
||||||
"PosterSize": "Poster Size",
|
"PosterSize": "Poster Size",
|
||||||
"Posters": "Posters",
|
"Posters": "Posters",
|
||||||
|
@ -1202,6 +1333,7 @@
|
||||||
"SeasonPremiere": "Season Premiere",
|
"SeasonPremiere": "Season Premiere",
|
||||||
"SeasonPremieresOnly": "Season Premieres Only",
|
"SeasonPremieresOnly": "Season Premieres Only",
|
||||||
"Seasons": "Seasons",
|
"Seasons": "Seasons",
|
||||||
|
"SecretToken": "Secret Token",
|
||||||
"Security": "Security",
|
"Security": "Security",
|
||||||
"Seeders": "Seeders",
|
"Seeders": "Seeders",
|
||||||
"SelectAll": "Select All",
|
"SelectAll": "Select All",
|
||||||
|
@ -1379,6 +1511,14 @@
|
||||||
"ToggleMonitoredToUnmonitored": "Monitored, click to unmonitor",
|
"ToggleMonitoredToUnmonitored": "Monitored, click to unmonitor",
|
||||||
"ToggleUnmonitoredToMonitored": "Unmonitored, click to monitor",
|
"ToggleUnmonitoredToMonitored": "Unmonitored, click to monitor",
|
||||||
"Tomorrow": "Tomorrow",
|
"Tomorrow": "Tomorrow",
|
||||||
|
"TorrentBlackhole": "Torrent Blackhole",
|
||||||
|
"TorrentBlackholeSaveMagnetFiles": "Save Magnet Files",
|
||||||
|
"TorrentBlackholeSaveMagnetFilesExtension": "Save Magnet Files Extension",
|
||||||
|
"TorrentBlackholeSaveMagnetFilesExtensionHelpText": "Extension to use for magnet links, defaults to '.magnet'",
|
||||||
|
"TorrentBlackholeSaveMagnetFilesHelpText": "Save the magnet link if no .torrent file is available (only useful if the download client supports magnets saved to a file)",
|
||||||
|
"TorrentBlackholeSaveMagnetFilesReadOnly": "Read Only",
|
||||||
|
"TorrentBlackholeSaveMagnetFilesReadOnlyHelpText": "Instead of moving files this will instruct {appName} to Copy or Hardlink (depending on settings/system configuration)",
|
||||||
|
"TorrentBlackholeTorrentFolder": "Torrent Folder",
|
||||||
"TorrentDelay": "Torrent Delay",
|
"TorrentDelay": "Torrent Delay",
|
||||||
"TorrentDelayHelpText": "Delay in minutes to wait before grabbing a torrent",
|
"TorrentDelayHelpText": "Delay in minutes to wait before grabbing a torrent",
|
||||||
"TorrentDelayTime": "Torrent Delay: {torrentDelay}",
|
"TorrentDelayTime": "Torrent Delay: {torrentDelay}",
|
||||||
|
@ -1415,6 +1555,7 @@
|
||||||
"Underscore": "Underscore",
|
"Underscore": "Underscore",
|
||||||
"Ungroup": "Ungroup",
|
"Ungroup": "Ungroup",
|
||||||
"Unknown": "Unknown",
|
"Unknown": "Unknown",
|
||||||
|
"UnknownDownloadState": "Unknown download state: {state}",
|
||||||
"UnknownEventTooltip": "Unknown event",
|
"UnknownEventTooltip": "Unknown event",
|
||||||
"Unlimited": "Unlimited",
|
"Unlimited": "Unlimited",
|
||||||
"UnmappedFilesOnly": "Unmapped Files Only",
|
"UnmappedFilesOnly": "Unmapped Files Only",
|
||||||
|
@ -1459,7 +1600,10 @@
|
||||||
"UseProxy": "Use Proxy",
|
"UseProxy": "Use Proxy",
|
||||||
"UseSeasonFolder": "Use Season Folder",
|
"UseSeasonFolder": "Use Season Folder",
|
||||||
"UseSeasonFolderHelpText": "Sort episodes into season folders",
|
"UseSeasonFolderHelpText": "Sort episodes into season folders",
|
||||||
|
"UseSsl": "Use SSL",
|
||||||
"Usenet": "Usenet",
|
"Usenet": "Usenet",
|
||||||
|
"UsenetBlackhole": "Usenet Blackhole",
|
||||||
|
"UsenetBlackholeNzbFolder": "Nzb Folder",
|
||||||
"UsenetDelay": "Usenet Delay",
|
"UsenetDelay": "Usenet Delay",
|
||||||
"UsenetDelayHelpText": "Delay in minutes to wait before grabbing a release from Usenet",
|
"UsenetDelayHelpText": "Delay in minutes to wait before grabbing a release from Usenet",
|
||||||
"UsenetDelayTime": "Usenet Delay: {usenetDelay}",
|
"UsenetDelayTime": "Usenet Delay: {usenetDelay}",
|
||||||
|
@ -1485,6 +1629,7 @@
|
||||||
"Wiki": "Wiki",
|
"Wiki": "Wiki",
|
||||||
"WithFiles": "With Files",
|
"WithFiles": "With Files",
|
||||||
"WouldYouLikeToRestoreBackup": "Would you like to restore the backup '{name}'?",
|
"WouldYouLikeToRestoreBackup": "Would you like to restore the backup '{name}'?",
|
||||||
|
"XmlRpcPath": "XML RPC Path",
|
||||||
"Year": "Year",
|
"Year": "Year",
|
||||||
"Yes": "Yes",
|
"Yes": "Yes",
|
||||||
"YesCancel": "Yes, Cancel",
|
"YesCancel": "Yes, Cancel",
|
||||||
|
|
|
@ -22,6 +22,7 @@ using NzbDrone.Common.Instrumentation;
|
||||||
using NzbDrone.Common.Instrumentation.Extensions;
|
using NzbDrone.Common.Instrumentation.Extensions;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Datastore.Extensions;
|
using NzbDrone.Core.Datastore.Extensions;
|
||||||
|
using Sonarr.Http.ClientSchema;
|
||||||
using LogLevel = Microsoft.Extensions.Logging.LogLevel;
|
using LogLevel = Microsoft.Extensions.Logging.LogLevel;
|
||||||
|
|
||||||
using PostgresOptions = NzbDrone.Core.Datastore.PostgresOptions;
|
using PostgresOptions = NzbDrone.Core.Datastore.PostgresOptions;
|
||||||
|
@ -145,6 +146,8 @@ namespace NzbDrone.Host
|
||||||
.AddNzbDroneLogger()
|
.AddNzbDroneLogger()
|
||||||
.AddDatabase()
|
.AddDatabase()
|
||||||
.AddStartupContext(context);
|
.AddStartupContext(context);
|
||||||
|
|
||||||
|
SchemaBuilder.Initialize(c);
|
||||||
})
|
})
|
||||||
.ConfigureServices(services =>
|
.ConfigureServices(services =>
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
@ -7,7 +9,6 @@ using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
using NzbDrone.Core.Indexers.Newznab;
|
using NzbDrone.Core.Indexers.Newznab;
|
||||||
using NzbDrone.Test.Common;
|
using NzbDrone.Test.Common;
|
||||||
using NzbDrone.Test.Common.Datastore;
|
using NzbDrone.Test.Common.Datastore;
|
||||||
using Sonarr.Http.ClientSchema;
|
|
||||||
|
|
||||||
namespace NzbDrone.Integration.Test
|
namespace NzbDrone.Integration.Test
|
||||||
{
|
{
|
||||||
|
@ -50,17 +51,20 @@ namespace NzbDrone.Integration.Test
|
||||||
// Make sure tasks have been initialized so the config put below doesn't cause errors
|
// Make sure tasks have been initialized so the config put below doesn't cause errors
|
||||||
WaitForCompletion(() => Tasks.All().SelectList(x => x.TaskName).Contains("RssSync"));
|
WaitForCompletion(() => Tasks.All().SelectList(x => x.TaskName).Contains("RssSync"));
|
||||||
|
|
||||||
Indexers.Post(new Sonarr.Api.V3.Indexers.IndexerResource
|
var indexer = Indexers.Schema().FirstOrDefault(i => i.Implementation == nameof(Newznab));
|
||||||
|
|
||||||
|
if (indexer == null)
|
||||||
{
|
{
|
||||||
EnableRss = false,
|
throw new NullReferenceException("Expected valid indexer schema, found null");
|
||||||
EnableInteractiveSearch = false,
|
}
|
||||||
EnableAutomaticSearch = false,
|
|
||||||
ConfigContract = nameof(NewznabSettings),
|
indexer.EnableRss = false;
|
||||||
Implementation = nameof(Newznab),
|
indexer.EnableInteractiveSearch = false;
|
||||||
Name = "NewznabTest",
|
indexer.EnableAutomaticSearch = false;
|
||||||
Protocol = Core.Indexers.DownloadProtocol.Usenet,
|
indexer.ConfigContract = nameof(NewznabSettings);
|
||||||
Fields = SchemaBuilder.ToSchema(new NewznabSettings())
|
indexer.Implementation = nameof(Newznab);
|
||||||
});
|
indexer.Name = "NewznabTest";
|
||||||
|
indexer.Protocol = Core.Indexers.DownloadProtocol.Usenet;
|
||||||
|
|
||||||
// Change Console Log Level to Debug so we get more details.
|
// Change Console Log Level to Debug so we get more details.
|
||||||
var config = HostConfig.Get(1);
|
var config = HostConfig.Get(1);
|
||||||
|
|
|
@ -23,6 +23,8 @@ namespace NzbDrone.Test.Common.AutoMoq
|
||||||
SetupAutoMoqer(CreateTestContainer(new Container()));
|
SetupAutoMoqer(CreateTestContainer(new Container()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IContainer Container => _container;
|
||||||
|
|
||||||
public virtual T Resolve<T>()
|
public virtual T Resolve<T>()
|
||||||
{
|
{
|
||||||
var result = _container.Resolve<T>();
|
var result = _container.Resolve<T>();
|
||||||
|
|
|
@ -3,11 +3,13 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using DryIoc;
|
||||||
using NzbDrone.Common.EnsureThat;
|
using NzbDrone.Common.EnsureThat;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Reflection;
|
using NzbDrone.Common.Reflection;
|
||||||
using NzbDrone.Common.Serializer;
|
using NzbDrone.Common.Serializer;
|
||||||
using NzbDrone.Core.Annotations;
|
using NzbDrone.Core.Annotations;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
|
|
||||||
namespace Sonarr.Http.ClientSchema
|
namespace Sonarr.Http.ClientSchema
|
||||||
{
|
{
|
||||||
|
@ -15,6 +17,12 @@ namespace Sonarr.Http.ClientSchema
|
||||||
{
|
{
|
||||||
private const string PRIVATE_VALUE = "********";
|
private const string PRIVATE_VALUE = "********";
|
||||||
private static Dictionary<Type, FieldMapping[]> _mappings = new Dictionary<Type, FieldMapping[]>();
|
private static Dictionary<Type, FieldMapping[]> _mappings = new Dictionary<Type, FieldMapping[]>();
|
||||||
|
private static ILocalizationService _localizationService;
|
||||||
|
|
||||||
|
public static void Initialize(IContainer container)
|
||||||
|
{
|
||||||
|
_localizationService = container.Resolve<ILocalizationService>();
|
||||||
|
}
|
||||||
|
|
||||||
public static List<Field> ToSchema(object model)
|
public static List<Field> ToSchema(object model)
|
||||||
{
|
{
|
||||||
|
@ -107,13 +115,27 @@ namespace Sonarr.Http.ClientSchema
|
||||||
if (propertyInfo.PropertyType.IsSimpleType())
|
if (propertyInfo.PropertyType.IsSimpleType())
|
||||||
{
|
{
|
||||||
var fieldAttribute = property.Item2;
|
var fieldAttribute = property.Item2;
|
||||||
|
|
||||||
|
var label = fieldAttribute.Label.IsNotNullOrWhiteSpace()
|
||||||
|
? _localizationService.GetLocalizedString(fieldAttribute.Label,
|
||||||
|
GetTokens(type, fieldAttribute.Label, TokenField.Label))
|
||||||
|
: fieldAttribute.Label;
|
||||||
|
var helpText = fieldAttribute.HelpText.IsNotNullOrWhiteSpace()
|
||||||
|
? _localizationService.GetLocalizedString(fieldAttribute.HelpText,
|
||||||
|
GetTokens(type, fieldAttribute.Label, TokenField.HelpText))
|
||||||
|
: fieldAttribute.HelpText;
|
||||||
|
var helpTextWarning = fieldAttribute.HelpTextWarning.IsNotNullOrWhiteSpace()
|
||||||
|
? _localizationService.GetLocalizedString(fieldAttribute.HelpTextWarning,
|
||||||
|
GetTokens(type, fieldAttribute.Label, TokenField.HelpTextWarning))
|
||||||
|
: fieldAttribute.HelpTextWarning;
|
||||||
|
|
||||||
var field = new Field
|
var field = new Field
|
||||||
{
|
{
|
||||||
Name = prefix + GetCamelCaseName(propertyInfo.Name),
|
Name = prefix + GetCamelCaseName(propertyInfo.Name),
|
||||||
Label = fieldAttribute.Label,
|
Label = label,
|
||||||
Unit = fieldAttribute.Unit,
|
Unit = fieldAttribute.Unit,
|
||||||
HelpText = fieldAttribute.HelpText,
|
HelpText = helpText,
|
||||||
HelpTextWarning = fieldAttribute.HelpTextWarning,
|
HelpTextWarning = helpTextWarning,
|
||||||
HelpLink = fieldAttribute.HelpLink,
|
HelpLink = fieldAttribute.HelpLink,
|
||||||
Order = fieldAttribute.Order,
|
Order = fieldAttribute.Order,
|
||||||
Advanced = fieldAttribute.Advanced,
|
Advanced = fieldAttribute.Advanced,
|
||||||
|
@ -173,6 +195,24 @@ namespace Sonarr.Http.ClientSchema
|
||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Dictionary<string, object> GetTokens(Type type, string label, TokenField field)
|
||||||
|
{
|
||||||
|
var tokens = new Dictionary<string, object>();
|
||||||
|
|
||||||
|
foreach (var propertyInfo in type.GetProperties())
|
||||||
|
{
|
||||||
|
foreach (var attribute in propertyInfo.GetCustomAttributes(true))
|
||||||
|
{
|
||||||
|
if (attribute is FieldTokenAttribute fieldTokenAttribute && fieldTokenAttribute.Field == field && fieldTokenAttribute.Label == label)
|
||||||
|
{
|
||||||
|
tokens.Add(fieldTokenAttribute.Token, fieldTokenAttribute.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
private static List<SelectOption> GetSelectOptions(Type selectOptions)
|
private static List<SelectOption> GetSelectOptions(Type selectOptions)
|
||||||
{
|
{
|
||||||
if (selectOptions.IsEnum)
|
if (selectOptions.IsEnum)
|
||||||
|
|
Loading…
Reference in New Issue