New: Seed Settings Sync

This commit is contained in:
Qstick committed 2022-05-10 19:32:05 -05:00
1 parent af50a1d3a8
commit e90a796b27
29 files changed
+288 -24

No files matched your search

@@ -5,6 +5,7 @@ namespace NzbDrone.Common.Cloud
public interface IProwlarrCloudRequestBuilder
{
IHttpRequestBuilderFactory Services { get; }
IHttpRequestBuilderFactory Releases { get; }
}
public class ProwlarrCloudRequestBuilder : IProwlarrCloudRequestBuilder
@@ -13,8 +14,13 @@ public ProwlarrCloudRequestBuilder()
{
Services = new HttpRequestBuilder("https://prowlarr.servarr.com/v1/")
.CreateFactory();
Releases = new HttpRequestBuilder("https://releases.servarr.com/v1/")
.CreateFactory();
}
public IHttpRequestBuilderFactory Services { get; private set; }
public IHttpRequestBuilderFactory Releases { get; private set; }
}
}
@@ -183,6 +183,13 @@ private LidarrIndexer BuildLidarrIndexer(IndexerDefinition indexer, DownloadProt
lidarrIndexer.Fields.FirstOrDefault(x => x.Name == "apiKey").Value = _configFileProvider.ApiKey;
lidarrIndexer.Fields.FirstOrDefault(x => x.Name == "categories").Value = JArray.FromObject(indexer.Capabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()));
if (indexer.Protocol == DownloadProtocol.Torrent)
{
lidarrIndexer.Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value = indexer.AppProfile.Value.MinimumSeeders;
lidarrIndexer.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value = ((ITorrentIndexerSettings)indexer.Settings).TorrentBaseSettings.SeedRatio;
lidarrIndexer.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value = ((ITorrentIndexerSettings)indexer.Settings).TorrentBaseSettings.SeedTime;
}
return lidarrIndexer;
}
}
@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
@@ -31,6 +32,18 @@ public bool Equals(LidarrIndexer other)
var apiKey = (string)Fields.FirstOrDefault(x => x.Name == "apiKey").Value == (string)other.Fields.FirstOrDefault(x => x.Name == "apiKey").Value;
var cats = JToken.DeepEquals((JArray)Fields.FirstOrDefault(x => x.Name == "categories").Value, (JArray)other.Fields.FirstOrDefault(x => x.Name == "categories").Value);
var minimumSeeders = Fields.FirstOrDefault(x => x.Name == "minimumSeeders")?.Value == null ? null : (int?)Convert.ToInt32(Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value);
var otherMinimumSeeders = other.Fields.FirstOrDefault(x => x.Name == "minimumSeeders")?.Value == null ? null : (int?)Convert.ToInt32(other.Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value);
var minimumSeedersCompare = minimumSeeders == otherMinimumSeeders;
var seedTime = Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime")?.Value == null ? null : (int?)Convert.ToInt32(Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value);
var otherSeedTime = other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime")?.Value == null ? null : (int?)Convert.ToInt32(other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value);
var seedTimeCompare = seedTime == otherSeedTime;
var seedRatio = Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio")?.Value == null ? null : (double?)Convert.ToDouble(Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value);
var otherSeedRatio = other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio")?.Value == null ? null : (double?)Convert.ToDouble(other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value);
var seedRatioCompare = seedRatio == otherSeedRatio;
return other.EnableRss == EnableRss &&
other.EnableAutomaticSearch == EnableAutomaticSearch &&
other.EnableInteractiveSearch == EnableInteractiveSearch &&
@@ -38,7 +51,7 @@ public bool Equals(LidarrIndexer other)
other.Implementation == Implementation &&
other.Priority == Priority &&
other.Id == Id &&
apiKey && apiPath && baseUrl && cats;
apiKey && apiPath && baseUrl && cats && minimumSeedersCompare && seedRatioCompare && seedTimeCompare;
}
}
}
@@ -183,6 +183,13 @@ private RadarrIndexer BuildRadarrIndexer(IndexerDefinition indexer, DownloadProt
radarrIndexer.Fields.FirstOrDefault(x => x.Name == "apiKey").Value = _configFileProvider.ApiKey;
radarrIndexer.Fields.FirstOrDefault(x => x.Name == "categories").Value = JArray.FromObject(indexer.Capabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()));
if (indexer.Protocol == DownloadProtocol.Torrent)
{
radarrIndexer.Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value = indexer.AppProfile.Value.MinimumSeeders;
radarrIndexer.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value = ((ITorrentIndexerSettings)indexer.Settings).TorrentBaseSettings.SeedRatio;
radarrIndexer.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value = ((ITorrentIndexerSettings)indexer.Settings).TorrentBaseSettings.SeedTime;
}
return radarrIndexer;
}
}
@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
@@ -31,6 +32,18 @@ public bool Equals(RadarrIndexer other)
var apiKey = (string)Fields.FirstOrDefault(x => x.Name == "apiKey").Value == (string)other.Fields.FirstOrDefault(x => x.Name == "apiKey").Value;
var cats = JToken.DeepEquals((JArray)Fields.FirstOrDefault(x => x.Name == "categories").Value, (JArray)other.Fields.FirstOrDefault(x => x.Name == "categories").Value);
var minimumSeeders = Fields.FirstOrDefault(x => x.Name == "minimumSeeders")?.Value == null ? null : (int?)Convert.ToInt32(Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value);
var otherMinimumSeeders = other.Fields.FirstOrDefault(x => x.Name == "minimumSeeders")?.Value == null ? null : (int?)Convert.ToInt32(other.Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value);
var minimumSeedersCompare = minimumSeeders == otherMinimumSeeders;
var seedTime = Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime")?.Value == null ? null : (int?)Convert.ToInt32(Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value);
var otherSeedTime = other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime")?.Value == null ? null : (int?)Convert.ToInt32(other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value);
var seedTimeCompare = seedTime == otherSeedTime;
var seedRatio = Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio")?.Value == null ? null : (double?)Convert.ToDouble(Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value);
var otherSeedRatio = other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio")?.Value == null ? null : (double?)Convert.ToDouble(other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value);
var seedRatioCompare = seedRatio == otherSeedRatio;
return other.EnableRss == EnableRss &&
other.EnableAutomaticSearch == EnableAutomaticSearch &&
other.EnableInteractiveSearch == EnableInteractiveSearch &&
@@ -38,7 +51,7 @@ public bool Equals(RadarrIndexer other)
other.Implementation == Implementation &&
other.Priority == Priority &&
other.Id == Id &&
apiKey && apiPath && baseUrl && cats;
apiKey && apiPath && baseUrl && cats && minimumSeedersCompare && seedRatioCompare && seedTimeCompare;
}
}
}
@@ -183,6 +183,13 @@ private ReadarrIndexer BuildReadarrIndexer(IndexerDefinition indexer, DownloadPr
readarrIndexer.Fields.FirstOrDefault(x => x.Name == "apiKey").Value = _configFileProvider.ApiKey;
readarrIndexer.Fields.FirstOrDefault(x => x.Name == "categories").Value = JArray.FromObject(indexer.Capabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()));
if (indexer.Protocol == DownloadProtocol.Torrent)
{
readarrIndexer.Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value = indexer.AppProfile.Value.MinimumSeeders;
readarrIndexer.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value = ((ITorrentIndexerSettings)indexer.Settings).TorrentBaseSettings.SeedRatio;
readarrIndexer.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value = ((ITorrentIndexerSettings)indexer.Settings).TorrentBaseSettings.SeedTime;
}
return readarrIndexer;
}
}
@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
@@ -31,6 +32,18 @@ public bool Equals(ReadarrIndexer other)
var apiKey = (string)Fields.FirstOrDefault(x => x.Name == "apiKey").Value == (string)other.Fields.FirstOrDefault(x => x.Name == "apiKey").Value;
var cats = JToken.DeepEquals((JArray)Fields.FirstOrDefault(x => x.Name == "categories").Value, (JArray)other.Fields.FirstOrDefault(x => x.Name == "categories").Value);
var minimumSeeders = Fields.FirstOrDefault(x => x.Name == "minimumSeeders")?.Value == null ? null : (int?)Convert.ToInt32(Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value);
var otherMinimumSeeders = other.Fields.FirstOrDefault(x => x.Name == "minimumSeeders")?.Value == null ? null : (int?)Convert.ToInt32(other.Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value);
var minimumSeedersCompare = minimumSeeders == otherMinimumSeeders;
var seedTime = Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime")?.Value == null ? null : (int?)Convert.ToInt32(Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value);
var otherSeedTime = other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime")?.Value == null ? null : (int?)Convert.ToInt32(other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value);
var seedTimeCompare = seedTime == otherSeedTime;
var seedRatio = Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio")?.Value == null ? null : (double?)Convert.ToDouble(Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value);
var otherSeedRatio = other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio")?.Value == null ? null : (double?)Convert.ToDouble(other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value);
var seedRatioCompare = seedRatio == otherSeedRatio;
return other.EnableRss == EnableRss &&
other.EnableAutomaticSearch == EnableAutomaticSearch &&
other.EnableInteractiveSearch == EnableInteractiveSearch &&
@@ -38,7 +51,7 @@ public bool Equals(ReadarrIndexer other)
other.Implementation == Implementation &&
other.Priority == Priority &&
other.Id == Id &&
apiKey && apiPath && baseUrl && cats;
apiKey && apiPath && baseUrl && cats && minimumSeedersCompare && seedRatioCompare && seedTimeCompare;
}
}
}
@@ -184,6 +184,13 @@ private SonarrIndexer BuildSonarrIndexer(IndexerDefinition indexer, DownloadProt
sonarrIndexer.Fields.FirstOrDefault(x => x.Name == "categories").Value = JArray.FromObject(indexer.Capabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()));
sonarrIndexer.Fields.FirstOrDefault(x => x.Name == "animeCategories").Value = JArray.FromObject(indexer.Capabilities.Categories.SupportedCategories(Settings.AnimeSyncCategories.ToArray()));
if (indexer.Protocol == DownloadProtocol.Torrent)
{
sonarrIndexer.Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value = indexer.AppProfile.Value.MinimumSeeders;
sonarrIndexer.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value = ((ITorrentIndexerSettings)indexer.Settings).TorrentBaseSettings.SeedRatio;
sonarrIndexer.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value = ((ITorrentIndexerSettings)indexer.Settings).TorrentBaseSettings.SeedTime;
}
return sonarrIndexer;
}
}
@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
@@ -32,6 +33,18 @@ public bool Equals(SonarrIndexer other)
var cats = JToken.DeepEquals((JArray)Fields.FirstOrDefault(x => x.Name == "categories").Value, (JArray)other.Fields.FirstOrDefault(x => x.Name == "categories").Value);
var animeCats = JToken.DeepEquals((JArray)Fields.FirstOrDefault(x => x.Name == "animeCategories").Value, (JArray)other.Fields.FirstOrDefault(x => x.Name == "animeCategories").Value);
var minimumSeeders = Fields.FirstOrDefault(x => x.Name == "minimumSeeders")?.Value == null ? null : (int?)Convert.ToInt32(Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value);
var otherMinimumSeeders = other.Fields.FirstOrDefault(x => x.Name == "minimumSeeders")?.Value == null ? null : (int?)Convert.ToInt32(other.Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value);
var minimumSeedersCompare = minimumSeeders == otherMinimumSeeders;
var seedTime = Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime")?.Value == null ? null : (int?)Convert.ToInt32(Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value);
var otherSeedTime = other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime")?.Value == null ? null : (int?)Convert.ToInt32(other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value);
var seedTimeCompare = seedTime == otherSeedTime;
var seedRatio = Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio")?.Value == null ? null : (double?)Convert.ToDouble(Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value);
var otherSeedRatio = other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio")?.Value == null ? null : (double?)Convert.ToDouble(other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value);
var seedRatioCompare = seedRatio == otherSeedRatio;
return other.EnableRss == EnableRss &&
other.EnableAutomaticSearch == EnableAutomaticSearch &&
other.EnableInteractiveSearch == EnableInteractiveSearch &&
@@ -39,7 +52,7 @@ public bool Equals(SonarrIndexer other)
other.Implementation == Implementation &&
other.Priority == Priority &&
other.Id == Id &&
apiKey && apiPath && baseUrl && cats && animeCats;
apiKey && apiPath && baseUrl && cats && animeCats && minimumSeedersCompare && seedRatioCompare && seedTimeCompare;
}
}
}
@@ -183,6 +183,13 @@ private WhisparrIndexer BuildWhisparrIndexer(IndexerDefinition indexer, Download
whisparrIndexer.Fields.FirstOrDefault(x => x.Name == "apiKey").Value = _configFileProvider.ApiKey;
whisparrIndexer.Fields.FirstOrDefault(x => x.Name == "categories").Value = JArray.FromObject(indexer.Capabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()));
if (indexer.Protocol == DownloadProtocol.Torrent)
{
whisparrIndexer.Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value = indexer.AppProfile.Value.MinimumSeeders;
whisparrIndexer.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value = ((ITorrentIndexerSettings)indexer.Settings).TorrentBaseSettings.SeedRatio;
whisparrIndexer.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value = ((ITorrentIndexerSettings)indexer.Settings).TorrentBaseSettings.SeedTime;
}
return whisparrIndexer;
}
}
@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
@@ -31,6 +32,18 @@ public bool Equals(WhisparrIndexer other)
var apiKey = (string)Fields.FirstOrDefault(x => x.Name == "apiKey").Value == (string)other.Fields.FirstOrDefault(x => x.Name == "apiKey").Value;
var cats = JToken.DeepEquals((JArray)Fields.FirstOrDefault(x => x.Name == "categories").Value, (JArray)other.Fields.FirstOrDefault(x => x.Name == "categories").Value);
var minimumSeeders = Fields.FirstOrDefault(x => x.Name == "minimumSeeders")?.Value == null ? null : (int?)Convert.ToInt32(Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value);
var otherMinimumSeeders = other.Fields.FirstOrDefault(x => x.Name == "minimumSeeders")?.Value == null ? null : (int?)Convert.ToInt32(other.Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value);
var minimumSeedersCompare = minimumSeeders == otherMinimumSeeders;
var seedTime = Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime")?.Value == null ? null : (int?)Convert.ToInt32(Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value);
var otherSeedTime = other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime")?.Value == null ? null : (int?)Convert.ToInt32(other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value);
var seedTimeCompare = seedTime == otherSeedTime;
var seedRatio = Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio")?.Value == null ? null : (double?)Convert.ToDouble(Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value);
var otherSeedRatio = other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio")?.Value == null ? null : (double?)Convert.ToDouble(other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value);
var seedRatioCompare = seedRatio == otherSeedRatio;
return other.EnableRss == EnableRss &&
other.EnableAutomaticSearch == EnableAutomaticSearch &&
other.EnableInteractiveSearch == EnableInteractiveSearch &&
@@ -38,7 +51,7 @@ public bool Equals(WhisparrIndexer other)
other.Implementation == Implementation &&
other.Priority == Priority &&
other.Id == Id &&
apiKey && apiPath && baseUrl && cats;
apiKey && apiPath && baseUrl && cats && minimumSeedersCompare && seedRatioCompare && seedTimeCompare;
}
}
}
@@ -0,0 +1,15 @@
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(18)]
public class minimum_seeders : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Alter.Table("AppSyncProfiles")
.AddColumn("MinimumSeeders").AsInt32().NotNullable().WithDefaultValue(1);
}
}
}
@@ -0,0 +1,48 @@
using System.Linq;
using System.Net.Http;
using NzbDrone.Common.Cloud;
using NzbDrone.Common.Http;
using NzbDrone.Common.Serializer;
using NzbDrone.Core.Analytics;
using NzbDrone.Core.Indexers.Events;
using NzbDrone.Core.Messaging.Events;
namespace NzbDrone.Core.IndexerSearch
{
public class ReleaseAnalyticsService : IHandleAsync<IndexerQueryEvent>
{
private readonly IHttpClient _httpClient;
private readonly IHttpRequestBuilderFactory _requestBuilder;
private readonly IAnalyticsService _analyticsService;
public ReleaseAnalyticsService(IHttpClient httpClient, IProwlarrCloudRequestBuilder requestBuilder, IAnalyticsService analyticsService)
{
_analyticsService = analyticsService;
_requestBuilder = requestBuilder.Releases;
_httpClient = httpClient;
}
public void HandleAsync(IndexerQueryEvent message)
{
if (_analyticsService.IsEnabled)
{
var request = _requestBuilder.Create().Resource("release/push").Build();
request.Method = HttpMethod.Post;
request.Headers.ContentType = "application/json";
request.SuppressHttpError = true;
var body = message.QueryResult.Releases.Select(x => new
{
Title = x.Title,
Categories = x.Categories.Where(c => c.Id < 10000).Select(c => c.Id),
Protocol = x.DownloadProtocol.ToString(),
Size = x.Size,
PublishDate = x.PublishDate
});
request.SetContent(body.ToJson());
_httpClient.Post(request);
}
}
}
}
@@ -2,6 +2,7 @@
using System.Text.RegularExpressions;
using FluentValidation;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Indexers.Newznab;
using NzbDrone.Core.Validation;
@@ -36,7 +37,7 @@ public TorznabSettingsValidator()
}
}
public class TorznabSettings : NewznabSettings
public class TorznabSettings : NewznabSettings, ITorrentIndexerSettings
{
private static readonly TorznabSettingsValidator Validator = new TorznabSettingsValidator();
@@ -44,6 +45,9 @@ public TorznabSettings()
{
}
[FieldDefinition(3)]
public IndexerTorrentBaseSettings TorrentBaseSettings { get; set; } = new IndexerTorrentBaseSettings();
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NzbDrone.Core.Indexers
{
public interface ITorrentIndexerSettings : IIndexerSettings
{
IndexerTorrentBaseSettings TorrentBaseSettings { get; set; }
}
}
@@ -0,0 +1,47 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Indexers
{
public class IndexerTorrentSettingsValidator : AbstractValidator<IndexerTorrentBaseSettings>
{
public IndexerTorrentSettingsValidator(double seedRatioMinimum = 0.0, int seedTimeMinimum = 0, int seasonPackSeedTimeMinimum = 0)
{
RuleFor(c => c.SeedRatio).GreaterThan(0.0)
.When(c => c.SeedRatio.HasValue)
.AsWarning().WithMessage("Should be greater than zero");
RuleFor(c => c.SeedTime).GreaterThan(0)
.When(c => c.SeedTime.HasValue)
.AsWarning().WithMessage("Should be greater than zero");
if (seedRatioMinimum != 0.0)
{
RuleFor(c => c.SeedRatio).GreaterThanOrEqualTo(seedRatioMinimum)
.When(c => c.SeedRatio > 0.0)
.AsWarning()
.WithMessage($"Under {seedRatioMinimum} leads to H&R");
}
if (seedTimeMinimum != 0)
{
RuleFor(c => c.SeedTime).GreaterThanOrEqualTo(seedTimeMinimum)
.When(c => c.SeedTime > 0)
.AsWarning()
.WithMessage($"Under {seedTimeMinimum} leads to H&R");
}
}
}
public class IndexerTorrentBaseSettings
{
private static readonly IndexerTorrentSettingsValidator Validator = new IndexerTorrentSettingsValidator();
[FieldDefinition(1, Type = FieldType.Textbox, Label = "Seed Ratio", HelpText = "The ratio a torrent should reach before stopping, empty is app's default", Advanced = true)]
public double? SeedRatio { get; set; }
[FieldDefinition(2, Type = FieldType.Number, Label = "Seed Time", HelpText = "The time a torrent should be seeded before stopping, empty is app's default", Advanced = true)]
public int? SeedTime { get; set; }
}
}
@@ -4,7 +4,7 @@
namespace NzbDrone.Core.Indexers.Settings
{
public class CookieTorrentBaseSettings : IIndexerSettings
public class CookieTorrentBaseSettings : ITorrentIndexerSettings
{
public class CookieBaseSettingsValidator : AbstractValidator<CookieTorrentBaseSettings>
{
@@ -30,6 +30,9 @@ public CookieTorrentBaseSettings()
[FieldDefinition(3)]
public IndexerBaseSettings BaseSettings { get; set; } = new IndexerBaseSettings();
[FieldDefinition(4)]
public IndexerTorrentBaseSettings TorrentBaseSettings { get; set; } = new IndexerTorrentBaseSettings();
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
@@ -8,7 +8,7 @@ public class NoAuthSettingsValidator : AbstractValidator<NoAuthTorrentBaseSettin
{
}
public class NoAuthTorrentBaseSettings : IIndexerSettings
public class NoAuthTorrentBaseSettings : ITorrentIndexerSettings
{
private static readonly NoAuthSettingsValidator Validator = new NoAuthSettingsValidator();
@@ -18,6 +18,9 @@ public class NoAuthTorrentBaseSettings : IIndexerSettings
[FieldDefinition(2)]
public IndexerBaseSettings BaseSettings { get; set; } = new IndexerBaseSettings();
[FieldDefinition(3)]
public IndexerTorrentBaseSettings TorrentBaseSettings { get; set; } = new IndexerTorrentBaseSettings();
public virtual NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
@@ -4,7 +4,7 @@
namespace NzbDrone.Core.Indexers.Settings
{
public class UserPassTorrentBaseSettings : IIndexerSettings
public class UserPassTorrentBaseSettings : ITorrentIndexerSettings
{
public class UserPassBaseSettingsValidator : AbstractValidator<UserPassTorrentBaseSettings>
{
@@ -35,6 +35,9 @@ public UserPassTorrentBaseSettings()
[FieldDefinition(4)]
public IndexerBaseSettings BaseSettings { get; set; } = new IndexerBaseSettings();
[FieldDefinition(5)]
public IndexerTorrentBaseSettings TorrentBaseSettings { get; set; } = new IndexerTorrentBaseSettings();
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
+6 -4
View File
@@ -3,7 +3,6 @@
"AcceptConfirmationModal": "Accept Confirmation Modal",
"Actions": "Actions",
"Add": "Add",
"AddAppProfile": "Add App Sync Profile",
"AddDownloadClient": "Add Download Client",
"AddDownloadClientToProwlarr": "Adding a download client allows Prowlarr to send releases direct from the UI while doing a manual search.",
"Added": "Added",
@@ -13,6 +12,7 @@
"AddingTag": "Adding tag",
"AddNewIndexer": "Add New Indexer",
"AddRemoveOnly": "Add and Remove Only",
"AddSyncProfile": "Add Sync Profile",
"AddToDownloadClient": "Add release to download client",
"Age": "Age",
"All": "All",
@@ -32,10 +32,8 @@
"ApplyTagsHelpTexts2": "Add: Add the tags the existing list of tags",
"ApplyTagsHelpTexts3": "Remove: Remove the entered tags",
"ApplyTagsHelpTexts4": "Replace: Replace the tags with the entered tags (enter no tags to clear all tags)",
"AppProfile": "App Profile",
"AppProfileDeleteConfirm": "Are you sure you want to delete {0}?",
"AppProfileInUse": "App Profile in Use",
"AppProfiles": "App Profiles",
"AppProfileSelectHelpText": "App profiles are used to control RSS, Automatic Search and Interactive Search settings on application sync",
"Apps": "Apps",
"AppSettingsSummary": "Applications and settings to configure how Prowlarr interacts with your PVR programs",
@@ -119,8 +117,8 @@
"DownloadClientStatusCheckAllClientMessage": "All download clients are unavailable due to failures",
"DownloadClientStatusCheckSingleClientMessage": "Download clients unavailable due to failures: {0}",
"Edit": "Edit",
"EditAppProfile": "Edit App Profile",
"EditIndexer": "Edit Indexer",
"EditSyncProfile": "Edit Sync Profile",
"Enable": "Enable",
"EnableAutomaticSearch": "Enable Automatic Search",
"EnableAutomaticSearchHelpText": "Will be used when automatic searches are performed via the UI or by Prowlarr",
@@ -222,6 +220,8 @@
"Mechanism": "Mechanism",
"Message": "Message",
"MIA": "MIA",
"MinimumSeeders": "Minimum Seeders",
"MinimumSeedersHelpText": "Minimum seeders required by the Appliction for the indexer to grab",
"Mode": "Mode",
"MoreInfo": "More Info",
"MovieIndexScrollBottom": "Movie Index: Scroll Bottom",
@@ -372,6 +372,8 @@
"SyncLevel": "Sync Level",
"SyncLevelAddRemove": "Add and Remove Only: When indexers are added or removed from Prowlarr, it will update this remote app.",
"SyncLevelFull": "Full Sync: Will keep this app's indexers fully in sync. Changes made to indexers in Prowlarr are then synced to this app. Any change made to indexers remotely within this app will be overridden by Prowlarr on the next sync.",
"SyncProfile": "Sync Profile",
"SyncProfiles": "Sync Profiles",
"System": "System",
"SystemTimeCheckMessage": "System time is off by more than 1 day. Scheduled tasks may not run correctly until the time is corrected",
"TableOptions": "Table Options",
@@ -8,5 +8,6 @@ public class AppSyncProfile : ModelBase
public bool EnableRss { get; set; }
public bool EnableAutomaticSearch { get; set; }
public bool EnableInteractiveSearch { get; set; }
public int MinimumSeeders { get; set; }
}
}
@@ -88,7 +88,8 @@ public AppSyncProfile GetDefaultProfile(string name)
Name = name,
EnableAutomaticSearch = true,
EnableInteractiveSearch = true,
EnableRss = true
EnableRss = true,
MinimumSeeders = 1
};
return qualityProfile;
@@ -11,6 +11,7 @@ public class AppProfileResource : RestResource
public bool EnableRss { get; set; }
public bool EnableInteractiveSearch { get; set; }
public bool EnableAutomaticSearch { get; set; }
public int MinimumSeeders { get; set; }
}
public static class ProfileResourceMapper
@@ -28,7 +29,8 @@ public static AppProfileResource ToResource(this AppSyncProfile model)
Name = model.Name,
EnableRss = model.EnableRss,
EnableInteractiveSearch = model.EnableInteractiveSearch,
EnableAutomaticSearch = model.EnableAutomaticSearch
EnableAutomaticSearch = model.EnableAutomaticSearch,
MinimumSeeders = model.MinimumSeeders
};
}
@@ -45,7 +47,8 @@ public static AppSyncProfile ToModel(this AppProfileResource resource)
Name = resource.Name,
EnableRss = resource.EnableRss,
EnableInteractiveSearch = resource.EnableInteractiveSearch,
EnableAutomaticSearch = resource.EnableAutomaticSearch
EnableAutomaticSearch = resource.EnableAutomaticSearch,
MinimumSeeders = resource.MinimumSeeders
};
}