Fixed: Added /transmission/ part to UrlBase in Transmission settings making it configurable.
fixes #556
This commit is contained in:
parent
fb02499823
commit
dc91fa0206
|
@ -27,24 +27,23 @@ namespace NzbDrone.Api.Config
|
||||||
GetResourceById = GetHostConfig;
|
GetResourceById = GetHostConfig;
|
||||||
UpdateResource = SaveHostConfig;
|
UpdateResource = SaveHostConfig;
|
||||||
|
|
||||||
SharedValidator.RuleFor(c => c.Branch).NotEmpty().WithMessage("Branch name is required, 'master' is the default");
|
SharedValidator.RuleFor(c => c.BindAddress)
|
||||||
|
.ValidIp4Address()
|
||||||
|
.NotListenAllIp4Address()
|
||||||
|
.When(c => c.BindAddress != "*");
|
||||||
|
|
||||||
SharedValidator.RuleFor(c => c.Port).ValidPort();
|
SharedValidator.RuleFor(c => c.Port).ValidPort();
|
||||||
|
|
||||||
|
SharedValidator.RuleFor(c => c.UrlBase).ValidUrlBase();
|
||||||
|
|
||||||
SharedValidator.RuleFor(c => c.Username).NotEmpty().When(c => c.AuthenticationMethod != AuthenticationType.None);
|
SharedValidator.RuleFor(c => c.Username).NotEmpty().When(c => c.AuthenticationMethod != AuthenticationType.None);
|
||||||
SharedValidator.RuleFor(c => c.Password).NotEmpty().When(c => c.AuthenticationMethod != AuthenticationType.None);
|
SharedValidator.RuleFor(c => c.Password).NotEmpty().When(c => c.AuthenticationMethod != AuthenticationType.None);
|
||||||
|
|
||||||
SharedValidator.RuleFor(c => c.SslPort).ValidPort().When(c => c.EnableSsl);
|
SharedValidator.RuleFor(c => c.SslPort).ValidPort().When(c => c.EnableSsl);
|
||||||
SharedValidator.RuleFor(c => c.SslCertHash).NotEmpty().When(c => c.EnableSsl && OsInfo.IsWindows);
|
SharedValidator.RuleFor(c => c.SslCertHash).NotEmpty().When(c => c.EnableSsl && OsInfo.IsWindows);
|
||||||
|
|
||||||
|
SharedValidator.RuleFor(c => c.Branch).NotEmpty().WithMessage("Branch name is required, 'master' is the default");
|
||||||
SharedValidator.RuleFor(c => c.UpdateScriptPath).IsValidPath().When(c => c.UpdateMechanism == UpdateMechanism.Script);
|
SharedValidator.RuleFor(c => c.UpdateScriptPath).IsValidPath().When(c => c.UpdateMechanism == UpdateMechanism.Script);
|
||||||
|
|
||||||
SharedValidator.RuleFor(c => c.BindAddress)
|
|
||||||
.ValidIp4Address()
|
|
||||||
.NotListenAllIp4Address()
|
|
||||||
.When(c => c.BindAddress != "*");
|
|
||||||
|
|
||||||
SharedValidator.RuleFor(c => c.UrlBase)
|
|
||||||
.ValidUrlBase();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private HostConfigResource GetHostConfig()
|
private HostConfigResource GetHostConfig()
|
||||||
|
|
|
@ -9,7 +9,7 @@ using NzbDrone.Core.Test.Framework;
|
||||||
namespace NzbDrone.Core.Test.Datastore.Migration
|
namespace NzbDrone.Core.Test.Datastore.Migration
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class disable_eztv : MigrationTest<Core.Datastore.Migration.disable_eztv>
|
public class disable_eztvFixture : MigrationTest<Core.Datastore.Migration.disable_eztv>
|
||||||
{
|
{
|
||||||
[Test]
|
[Test]
|
||||||
public void should_disable_rss_for_eztv()
|
public void should_disable_rss_for_eztv()
|
|
@ -10,7 +10,7 @@ using NzbDrone.Core.Tv;
|
||||||
namespace NzbDrone.Core.Test.Datastore.Migration
|
namespace NzbDrone.Core.Test.Datastore.Migration
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class dedupe_tags : MigrationTest<Core.Datastore.Migration.dedupe_tags>
|
public class dedupe_tagsFixture : MigrationTest<Core.Datastore.Migration.dedupe_tags>
|
||||||
{
|
{
|
||||||
[Test]
|
[Test]
|
||||||
public void should_not_fail_if_series_tags_are_null()
|
public void should_not_fail_if_series_tags_are_null()
|
||||||
|
|
|
@ -11,7 +11,7 @@ using NzbDrone.Core.Test.Framework;
|
||||||
namespace NzbDrone.Core.Test.Datastore.Migration
|
namespace NzbDrone.Core.Test.Datastore.Migration
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class move_dot_prefix_to_transmission_category : MigrationTest<Core.Datastore.Migration.move_dot_prefix_to_transmission_category>
|
public class move_dot_prefix_to_transmission_categoryFixture : MigrationTest<Core.Datastore.Migration.move_dot_prefix_to_transmission_category>
|
||||||
{
|
{
|
||||||
[Test]
|
[Test]
|
||||||
public void should_not_fail_if_no_transmission()
|
public void should_not_fail_if_no_transmission()
|
||||||
|
|
|
@ -8,7 +8,7 @@ using NzbDrone.Core.Test.Framework;
|
||||||
namespace NzbDrone.Core.Test.Datastore.Migration
|
namespace NzbDrone.Core.Test.Datastore.Migration
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class update_quality_minmax_size : MigrationTest<Core.Datastore.Migration.update_quality_minmax_size>
|
public class update_quality_minmax_sizeFixture : MigrationTest<Core.Datastore.Migration.update_quality_minmax_size>
|
||||||
{
|
{
|
||||||
[Test]
|
[Test]
|
||||||
public void should_not_fail_if_empty()
|
public void should_not_fail_if_empty()
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common.Serializer;
|
||||||
|
using NzbDrone.Core.Download;
|
||||||
|
using NzbDrone.Core.Download.Clients.Deluge;
|
||||||
|
using NzbDrone.Core.Download.Clients.Sabnzbd;
|
||||||
|
using NzbDrone.Core.Download.Clients.Transmission;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using System.Drawing;
|
||||||
|
namespace NzbDrone.Core.Test.Datastore.Migration
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class expand_transmission_urlbaseFixture : MigrationTest<Core.Datastore.Migration.expand_transmission_urlbase>
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void should_not_fail_if_no_transmission()
|
||||||
|
{
|
||||||
|
WithTestDb(c =>
|
||||||
|
{
|
||||||
|
c.Insert.IntoTable("DownloadClients").Row(new
|
||||||
|
{
|
||||||
|
Enable = 1,
|
||||||
|
Name = "Deluge",
|
||||||
|
Implementation = "Deluge",
|
||||||
|
Settings = new DelugeSettings
|
||||||
|
{
|
||||||
|
Host = "127.0.0.1",
|
||||||
|
TvCategory = "abc",
|
||||||
|
UrlBase = "/my/"
|
||||||
|
}.ToJson(),
|
||||||
|
ConfigContract = "DelugeSettings"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
var items = Mocker.Resolve<DownloadClientRepository>().All();
|
||||||
|
|
||||||
|
items.Should().HaveCount(1);
|
||||||
|
|
||||||
|
items.First().Settings.As<DelugeSettings>().UrlBase.Should().Be("/my/");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_be_updated_for_transmission()
|
||||||
|
{
|
||||||
|
WithTestDb(c =>
|
||||||
|
{
|
||||||
|
c.Insert.IntoTable("DownloadClients").Row(new
|
||||||
|
{
|
||||||
|
Enable = 1,
|
||||||
|
Name = "Trans",
|
||||||
|
Implementation = "Transmission",
|
||||||
|
Settings = new TransmissionSettings
|
||||||
|
{
|
||||||
|
Host = "127.0.0.1",
|
||||||
|
TvCategory = "abc",
|
||||||
|
UrlBase = null
|
||||||
|
}.ToJson(),
|
||||||
|
ConfigContract = "TransmissionSettings"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
var items = Mocker.Resolve<DownloadClientRepository>().All();
|
||||||
|
|
||||||
|
items.Should().HaveCount(1);
|
||||||
|
|
||||||
|
items.First().Settings.As<TransmissionSettings>().UrlBase.Should().Be("/transmission/");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_be_append_to_existing_urlbase()
|
||||||
|
{
|
||||||
|
WithTestDb(c =>
|
||||||
|
{
|
||||||
|
c.Insert.IntoTable("DownloadClients").Row(new
|
||||||
|
{
|
||||||
|
Enable = 1,
|
||||||
|
Name = "Trans",
|
||||||
|
Implementation = "Transmission",
|
||||||
|
Settings = new TransmissionSettings
|
||||||
|
{
|
||||||
|
Host = "127.0.0.1",
|
||||||
|
TvCategory = "abc",
|
||||||
|
UrlBase = "/my/url/"
|
||||||
|
}.ToJson(),
|
||||||
|
ConfigContract = "TransmissionSettings"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
var items = Mocker.Resolve<DownloadClientRepository>().All();
|
||||||
|
|
||||||
|
items.Should().HaveCount(1);
|
||||||
|
|
||||||
|
items.First().Settings.As<TransmissionSettings>().UrlBase.Should().Be("/my/url/transmission/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -118,9 +118,10 @@
|
||||||
<Compile Include="Datastore\MappingExtentionFixture.cs" />
|
<Compile Include="Datastore\MappingExtentionFixture.cs" />
|
||||||
<Compile Include="Datastore\MarrDataLazyLoadingFixture.cs" />
|
<Compile Include="Datastore\MarrDataLazyLoadingFixture.cs" />
|
||||||
<Compile Include="Datastore\Migration\071_unknown_quality_in_profileFixture.cs" />
|
<Compile Include="Datastore\Migration\071_unknown_quality_in_profileFixture.cs" />
|
||||||
<Compile Include="Datastore\Migration\074_disable_eztv.cs" />
|
<Compile Include="Datastore\Migration\074_disable_eztvFixture.cs" />
|
||||||
<Compile Include="Datastore\Migration\072_history_grabIdFixture.cs" />
|
<Compile Include="Datastore\Migration\072_history_grabIdFixture.cs" />
|
||||||
<Compile Include="Datastore\Migration\070_delay_profileFixture.cs" />
|
<Compile Include="Datastore\Migration\070_delay_profileFixture.cs" />
|
||||||
|
<Compile Include="Datastore\Migration\085_expand_transmission_urlbaseFixture.cs" />
|
||||||
<Compile Include="Datastore\Migration\084_update_quality_minmax_sizeFixture.cs" />
|
<Compile Include="Datastore\Migration\084_update_quality_minmax_sizeFixture.cs" />
|
||||||
<Compile Include="Datastore\Migration\081_move_dot_prefix_to_transmission_categoryFixture.cs" />
|
<Compile Include="Datastore\Migration\081_move_dot_prefix_to_transmission_categoryFixture.cs" />
|
||||||
<Compile Include="Datastore\Migration\079_dedupe_tagsFixture.cs" />
|
<Compile Include="Datastore\Migration\079_dedupe_tagsFixture.cs" />
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.Linq;
|
||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Common.Extensions;
|
||||||
|
using NzbDrone.Common.Serializer;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(85)]
|
||||||
|
public class expand_transmission_urlbase : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Execute.WithConnection(UpdateTransmissionSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateTransmissionSettings(IDbConnection conn, IDbTransaction tran)
|
||||||
|
{
|
||||||
|
using (var cmd = conn.CreateCommand())
|
||||||
|
{
|
||||||
|
cmd.Transaction = tran;
|
||||||
|
cmd.CommandText = "SELECT Id, Settings FROM DownloadClients WHERE Implementation = 'Transmission'";
|
||||||
|
|
||||||
|
using (var reader = cmd.ExecuteReader())
|
||||||
|
{
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
var id = reader.GetInt32(0);
|
||||||
|
var settingsJson = reader.GetString(1);
|
||||||
|
|
||||||
|
var settings = Json.Deserialize<Dictionary<string, object>>(settingsJson);
|
||||||
|
|
||||||
|
var urlBase = settings.GetValueOrDefault("urlBase", "") as string;
|
||||||
|
|
||||||
|
if (urlBase.IsNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
settings["urlBase"] = "/transmission/";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
settings["urlBase"] = string.Format("/{0}/transmission/", urlBase.Trim('/'));
|
||||||
|
}
|
||||||
|
|
||||||
|
using (var updateCmd = conn.CreateCommand())
|
||||||
|
{
|
||||||
|
updateCmd.Transaction = tran;
|
||||||
|
updateCmd.CommandText = "UPDATE DownloadClients SET Settings = ? WHERE Id = ?";
|
||||||
|
updateCmd.AddParameter(settings.ToJson());
|
||||||
|
updateCmd.AddParameter(id);
|
||||||
|
|
||||||
|
updateCmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -260,15 +260,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
{
|
{
|
||||||
var protocol = settings.UseSsl ? "https" : "http";
|
var protocol = settings.UseSsl ? "https" : "http";
|
||||||
|
|
||||||
String url;
|
var url = String.Format(@"{0}://{1}:{2}/{3}/rpc", protocol, settings.Host, settings.Port, settings.UrlBase.Trim('/'));
|
||||||
if (!settings.UrlBase.IsNullOrWhiteSpace())
|
|
||||||
{
|
|
||||||
url = String.Format(@"{0}://{1}:{2}/{3}/transmission/rpc", protocol, settings.Host, settings.Port, settings.UrlBase.Trim('/'));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
url = String.Format(@"{0}://{1}:{2}/transmission/rpc", protocol, settings.Host, settings.Port);
|
|
||||||
}
|
|
||||||
|
|
||||||
var restClient = RestClientFactory.BuildClient(url);
|
var restClient = RestClientFactory.BuildClient(url);
|
||||||
restClient.FollowRedirects = false;
|
restClient.FollowRedirects = false;
|
||||||
|
|
|
@ -13,6 +13,8 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
RuleFor(c => c.Host).ValidHost();
|
RuleFor(c => c.Host).ValidHost();
|
||||||
RuleFor(c => c.Port).GreaterThan(0);
|
RuleFor(c => c.Port).GreaterThan(0);
|
||||||
|
|
||||||
|
RuleFor(c => c.UrlBase).ValidUrlBase();
|
||||||
|
|
||||||
RuleFor(c => c.TvCategory).Matches(@"^\.?[-a-z]*$").WithMessage("Allowed characters a-z and -");
|
RuleFor(c => c.TvCategory).Matches(@"^\.?[-a-z]*$").WithMessage("Allowed characters a-z and -");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +27,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
{
|
{
|
||||||
Host = "localhost";
|
Host = "localhost";
|
||||||
Port = 9091;
|
Port = 9091;
|
||||||
|
UrlBase = "/transmission/";
|
||||||
}
|
}
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "Host", Type = FieldType.Textbox)]
|
[FieldDefinition(0, Label = "Host", Type = FieldType.Textbox)]
|
||||||
|
@ -33,7 +36,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
[FieldDefinition(1, Label = "Port", Type = FieldType.Textbox)]
|
[FieldDefinition(1, Label = "Port", Type = FieldType.Textbox)]
|
||||||
public Int32 Port { get; set; }
|
public Int32 Port { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(2, Label = "Url Base", Type = FieldType.Textbox, Advanced = true, HelpText = "Adds a prefix to the transmission rpc url, see http://[host]:[port]/[urlBase]/transmission/rpc")]
|
[FieldDefinition(2, 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/'")]
|
||||||
public String UrlBase { get; set; }
|
public String UrlBase { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(3, Label = "Username", Type = FieldType.Textbox)]
|
[FieldDefinition(3, Label = "Username", Type = FieldType.Textbox)]
|
||||||
|
|
|
@ -253,6 +253,7 @@
|
||||||
<Compile Include="Datastore\Migration\074_disable_eztv.cs" />
|
<Compile Include="Datastore\Migration\074_disable_eztv.cs" />
|
||||||
<Compile Include="Datastore\Migration\073_clear_ratings.cs" />
|
<Compile Include="Datastore\Migration\073_clear_ratings.cs" />
|
||||||
<Compile Include="Datastore\Migration\077_add_add_options_to_series.cs" />
|
<Compile Include="Datastore\Migration\077_add_add_options_to_series.cs" />
|
||||||
|
<Compile Include="Datastore\Migration\085_expand_transmission_urlbase.cs" />
|
||||||
<Compile Include="Datastore\Migration\081_move_dot_prefix_to_transmission_category.cs" />
|
<Compile Include="Datastore\Migration\081_move_dot_prefix_to_transmission_category.cs" />
|
||||||
<Compile Include="Datastore\Migration\079_dedupe_tags.cs" />
|
<Compile Include="Datastore\Migration\079_dedupe_tags.cs" />
|
||||||
<Compile Include="Datastore\Migration\070_delay_profile.cs" />
|
<Compile Include="Datastore\Migration\070_delay_profile.cs" />
|
||||||
|
|
|
@ -34,6 +34,11 @@ namespace NzbDrone.Core.Validation
|
||||||
return ruleBuilder.SetValidator(new RegularExpressionValidator("^https?://[-a-z0-9.]+", RegexOptions.IgnoreCase)).WithMessage("must be valid URL that starts with http(s)://");
|
return ruleBuilder.SetValidator(new RegularExpressionValidator("^https?://[-a-z0-9.]+", RegexOptions.IgnoreCase)).WithMessage("must be valid URL that starts with http(s)://");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IRuleBuilderOptions<T, string> ValidUrlBase<T>(this IRuleBuilder<T, string> ruleBuilder)
|
||||||
|
{
|
||||||
|
return ruleBuilder.SetValidator(new RegularExpressionValidator(@"^(?!\/?https?://[-a-z0-9.]+)", RegexOptions.IgnoreCase)).WithMessage("Must be a valid URL path (ie: '/sonarr')");
|
||||||
|
}
|
||||||
|
|
||||||
public static IRuleBuilderOptions<T, int> ValidPort<T>(this IRuleBuilder<T, int> ruleBuilder)
|
public static IRuleBuilderOptions<T, int> ValidPort<T>(this IRuleBuilder<T, int> ruleBuilder)
|
||||||
{
|
{
|
||||||
return ruleBuilder.SetValidator(new InclusiveBetweenValidator(1, 65535))
|
return ruleBuilder.SetValidator(new InclusiveBetweenValidator(1, 65535))
|
||||||
|
@ -62,10 +67,5 @@ namespace NzbDrone.Core.Validation
|
||||||
{
|
{
|
||||||
return ruleBuilder.WithState(v => NzbDroneValidationState.Warning);
|
return ruleBuilder.WithState(v => NzbDroneValidationState.Warning);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IRuleBuilderOptions<T, string> ValidUrlBase<T>(this IRuleBuilder<T, string> ruleBuilder)
|
|
||||||
{
|
|
||||||
return ruleBuilder.SetValidator(new RegularExpressionValidator(@"^(?!\/?https?://[-a-z0-9.]+)", RegexOptions.IgnoreCase)).WithMessage("Must be a valid URL path (ie: '/sonarr')");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue